[Github-comments] [geany/geany] Provide utf-8 command line arguments on Windows (#1258)
Colomban Wendling
notifications at xxxxx
Wed Nov 9 09:04:01 UTC 2016
b4n requested changes on this pull request.
The idea seems good, and without having actually tested the PR I can confirm from other tests I did yetserday that the combination of `GetCommandLineW()` and `CommandLineToArgvW()` seems to work just fine.
> +{
+ int num_arg;
+ LPWSTR *szarglist = CommandLineToArgvW(GetCommandLineW(), &num_arg);
+ char **utf8argv = g_new0(char *, num_arg + 1);
+ int i = num_arg;
+ while(i)
+ {
+ i--;
+ utf8argv[i] = g_utf16_to_utf8((gunichar2 *)szarglist[i], -1, NULL, NULL, NULL);
+ }
+ *pargc = num_arg;
+ *pargv = utf8argv;
+ LocalFree(szarglist);
+}
+
+void win32_free_argv_made_in_utf8(gint argc, gchar **argv)
should actually use `g_strfreev()` as the `argv[]` array ends with a `NULL` element.
> @@ -1032,4 +1032,31 @@ gchar *win32_get_user_config_dir(void)
return g_build_filename(g_get_user_config_dir(), "geany", NULL);
}
+
+void win32_make_argc_and_argv_in_utf8(gint *pargc, gchar ***pargv)
+{
+ int num_arg;
+ LPWSTR *szarglist = CommandLineToArgvW(GetCommandLineW(), &num_arg);
+ char **utf8argv = g_new0(char *, num_arg + 1);
+ int i = num_arg;
+ while(i)
I'd prefer a `for()` loop like
```C
for (int i = 0; i < num_arg; i++)
utf8argv[i] = g_utf16_to_utf8((gunichar2 *)szarglist[i], -1, NULL, NULL, NULL);
```
> @@ -1032,4 +1032,31 @@ gchar *win32_get_user_config_dir(void)
return g_build_filename(g_get_user_config_dir(), "geany", NULL);
}
+
+void win32_make_argc_and_argv_in_utf8(gint *pargc, gchar ***pargv)
+{
+ int num_arg;
+ LPWSTR *szarglist = CommandLineToArgvW(GetCommandLineW(), &num_arg);
+ char **utf8argv = g_new0(char *, num_arg + 1);
+ int i = num_arg;
+ while(i)
+ {
+ i--;
+ utf8argv[i] = g_utf16_to_utf8((gunichar2 *)szarglist[i], -1, NULL, NULL, NULL);
Checking for error might be needed, as [Windows seems to allows invalid UTF-16 in filenames](https://en.wikipedia.org/wiki/UTF-8#WTF-8), and I'm afraid `g_utf16_to_utf8()` doesn't allow this.
Another solution might be a custom "broken UTF-16 to WTF-8" converter, like I played with in https://github.com/b4n/wtf8tools. It seems most places in GLib don't have problem with WTF8, as it's structurally fine and "just" encodes weird stuff.
Anyway, something should be done because only the last element of `argv[]` should ever be `NULL`, and I wouldn't be surprised it'd crash somewhere if it wasn't respected.
OK, this is a low-risk issue I guess (invalid UTF-16 filenames), but still a theoretically possible one.
> @@ -1032,4 +1032,31 @@ gchar *win32_get_user_config_dir(void)
return g_build_filename(g_get_user_config_dir(), "geany", NULL);
}
+
+void win32_make_argc_and_argv_in_utf8(gint *pargc, gchar ***pargv)
Agreed
> @@ -1231,6 +1230,9 @@ gint main_lib(gint argc, gchar **argv)
#endif
gtk_main();
+#ifdef G_OS_WIN32
+ win32_free_argv_made_in_utf8(argc, argv);
I'm not sure it's worth having a function which is a no-op on non-Windows just for not duplicating one guarding of a free; if we really don't want duplication here we find a way to only have one exit path :)
> @@ -1231,6 +1230,9 @@ gint main_lib(gint argc, gchar **argv)
#endif
gtk_main();
+#ifdef G_OS_WIN32
+ win32_free_argv_made_in_utf8(argc, argv);
Alternatively the conversion and freeing could be done in `main()` itself (from *main.c*), so `main_lib()` simply receives a nice argument list directly:
```C
int main(int argc, char **argv)
{
int ret;
#ifdef G_OS_WIN32
/* on Windows, get the Unicode argulment list and convert it to UTF-8 into argv[] */
LPWSTR *szarglist = CommandLineToArgvW(GetCommandLineW(), &argc);
argv = g_new(char *, argc + 1);
for (int i = 0; i < argc; i++)
argv[i] = g_utf16_to_utf8((gunichar2 *)szarglist[i], -1, NULL, NULL, NULL);
argv[argc] = NULL;
LocalFree(szarglist);
#endif
ret = main_lib(argc, argv);
#ifdef G_OS_WIN32
g_strfreev(argv);
#endif
return ret;
}
```
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/1258#pullrequestreview-7773217
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.geany.org/pipermail/github-comments/attachments/20161109/37f43408/attachment.html>
More information about the Github-comments
mailing list