[m-rev.] for review: unicode command line arguments on windows

Peter Wang novalazy at gmail.com
Thu Dec 15 14:55:04 AEDT 2011


On Thu, 15 Dec 2011 14:02:44 +1100, Peter Wang <novalazy at gmail.com> wrote:
> On Thu, 15 Dec 2011 12:53:34 +1100 (EST), Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
> > 
> > argv[0] behaves oddly in if the name of the program is directory
> > qualified and some of the directory components are quoted.
> 
> Ugh.  I'll try __wgetmainargs instead.

Can you test this on MSVC?  I'd prefer not to be using this internal(?)
function but at least we wouldn't be the only ones:
http://www.google.com/codesearch#search/&q=__wgetmainargs&type=cs

--

Branches: main, 11.07

Use __wgetmainargs to get Unicode command-line arguments on Windows instead
of GetCommandLineW then parsing with CommandLineToArgvW. CommandLineToArgvW
has its own strange ideas about how command-lines should be parsed,
e.g. as discovered by Julien

    c:\> "c:\ws"\foo.exe

argv[0] is split into two:

    ["c:\ws", "\foo.exe"]

util/mkinit.c:
	As above.

diff --git a/util/mkinit.c b/util/mkinit.c
index 02721d4..044b574 100644
--- a/util/mkinit.c
+++ b/util/mkinit.c
@@ -540,16 +540,23 @@ static const char mercury_main_func[] =
     ** arguments to UTF-8.
     */
     "#ifdef MR_WIN32\n"
-    "static char **\n"
-    "mercury_win32_args(int *argc_ptr)\n"
+    "extern int __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *);\n"
+    "\n"
+    "static void\n"
+    "mercury_win32_args(int *argc_ret, char ***argv_ret)\n"
     "{\n"
-    "   LPWSTR  *wargv;\n"
+    "   int     argc;\n"
     "   char    **argv;\n"
+    "   wchar_t **wargv;\n"
+    "   wchar_t **wenv;\n"
+    "   int     start_info = 0;\n"
     "   int     i;\n"
     "\n"
-    "   wargv = CommandLineToArgvW(GetCommandLineW(), argc_ptr);\n"
-    "   argv = MR_GC_NEW_ARRAY(char *, (*argc_ptr + 1));\n"
-    "   for (i = 0; i < (*argc_ptr); i++) {\n"
+    "   if (__wgetmainargs(&argc, &wargv, &wenv, 0, &start_info) != 0) {\n"
+    "       return;\n"
+    "   }\n"
+    "   argv = MR_GC_NEW_ARRAY(char *, argc + 1);\n"
+    "   for (i = 0; i < argc; i++) {\n"
     "       int bytes = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,\n"
     "           NULL, 0, NULL, NULL);\n"
     "       argv[i] = MR_GC_malloc(bytes);\n"
@@ -557,8 +564,8 @@ static const char mercury_main_func[] =
     "           argv[i], bytes, NULL, NULL);\n"
     "   }\n"
     "   argv[i] = NULL;\n"
-    "   LocalFree(wargv);\n"
-    "   return argv;\n"
+    "   *argc_ret = argc;\n"
+    "   *argv_ret = argv;\n"
     "}\n"
     "#endif\n"
     "\n"
@@ -584,7 +591,7 @@ static const char main_func[] =
     "   old_break = sbrk(0);\n"
     "#endif\n"
     "#ifdef MR_WIN32\n"
-    "   argv = mercury_win32_args(&argc);\n"
+    "   mercury_win32_args(&argc, &argv);\n"
     "#endif\n"
     "   result = mercury_main(argc, argv);\n"
     "#ifdef MR_PROFILE_SBRK\n"

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list