aboutsummaryrefslogtreecommitdiff
path: root/src/util/strings.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/strings.c')
-rw-r--r--src/util/strings.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/util/strings.c b/src/util/strings.c
index 11134f139..cc44767d6 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -32,6 +32,7 @@
32#include "gnunet_common.h" 32#include "gnunet_common.h"
33#include "gnunet_strings_lib.h" 33#include "gnunet_strings_lib.h"
34#include <unicase.h> 34#include <unicase.h>
35#include <unistr.h>
35 36
36#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) 37#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
37 38
@@ -1113,4 +1114,93 @@ GNUNET_STRINGS_to_address_ip (const char *addr,
1113 return GNUNET_STRINGS_to_address_ipv4 (addr, addrlen, (struct sockaddr_in *) r_buf); 1114 return GNUNET_STRINGS_to_address_ipv4 (addr, addrlen, (struct sockaddr_in *) r_buf);
1114} 1115}
1115 1116
1117/**
1118 * Makes a copy of argv that consists of a single memory chunk that can be
1119 * freed with a single call to GNUNET_free ();
1120 */
1121static char *const *
1122_make_continuous_arg_copy (int argc, char *const *argv)
1123{
1124 size_t argvsize = 0;
1125 int i;
1126 char **new_argv;
1127 char *p;
1128 for (i = 0; i < argc; i++)
1129 argvsize += strlen (argv[i]) + 1 + sizeof (char *);
1130 new_argv = GNUNET_malloc (argvsize + sizeof (char *));
1131 p = (char *) &new_argv[argc + 1];
1132 for (i = 0; i < argc; i++)
1133 {
1134 new_argv[i] = p;
1135 strcpy (p, argv[i]);
1136 p += strlen (argv[i]) + 1;
1137 }
1138 new_argv[argc] = NULL;
1139 return (char *const *) new_argv;
1140}
1141
1142/**
1143 * Returns utf-8 encoded arguments.
1144 * Does nothing (returns a copy of argc and argv) on any platform
1145 * other than W32.
1146 * Returned argv has u8argv[u8argc] == NULL.
1147 * Returned argv is a single memory block, and can be freed with a single
1148 * GNUNET_free () call.
1149 *
1150 * @param argc argc (as given by main())
1151 * @param argv argv (as given by main())
1152 * @param u8argc a location to store new argc in (though it's th same as argc)
1153 * @param u8argv a location to store new argv in
1154 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1155 */
1156int
1157GNUNET_STRINGS_get_utf8_args (int argc, char *const *argv, int *u8argc, char *const **u8argv)
1158{
1159#if WINDOWS
1160 wchar_t *wcmd;
1161 wchar_t **wargv;
1162 int wargc;
1163 int i;
1164 char **split_u8argv;
1165
1166 wcmd = GetCommandLineW ();
1167 if (NULL == wcmd)
1168 return GNUNET_SYSERR;
1169 wargv = CommandLineToArgvW (wcmd, &wargc);
1170 if (NULL == wargv)
1171 return GNUNET_SYSERR;
1172
1173 split_u8argv = GNUNET_malloc (argc * sizeof (char *));
1174
1175 for (i = 0; i < wargc; i++)
1176 {
1177 size_t strl;
1178 /* Hopefully it will allocate us NUL-terminated strings... */
1179 split_u8argv[i] = (char *) u16_to_u8 (wargv[i], wcslen (wargv[i]) + 1, NULL, &strl);
1180 if (split_u8argv == NULL)
1181 {
1182 int j;
1183 for (j = 0; j < i; j++)
1184 free (split_u8argv[j]);
1185 GNUNET_free (split_u8argv);
1186 LocalFree (wargv);
1187 return GNUNET_SYSERR;
1188 }
1189 }
1190
1191 *u8argv = _make_continuous_arg_copy (wargc, split_u8argv);
1192 *u8argc = wargc;
1193
1194 for (i = 0; i < wargc; i++)
1195 free (split_u8argv[i]);
1196 free (split_u8argv);
1197 return GNUNET_OK;
1198#else
1199 char *const *new_argv = (char *const *) _make_continuous_arg_copy (argc, argv);
1200 *u8argv = new_argv;
1201 *u8argc = argc;
1202 return GNUNET_OK;
1203#endif
1204}
1205
1116/* end of strings.c */ 1206/* end of strings.c */