[Mono-dev] [PATCH] Use Unicode argv on Windows

Robert Jordan robertj at gmx.net
Mon Mar 31 18:55:10 EDT 2008


Hi Kornél,

I understand why you fixed it this way, but I think that "fixing"
strenc.c would produce less #ifdef clutter and it also has the
nice side effect of not breaking the embedding API :)

It's just a matter of setting MONO_EXTERNAL_ENCODINGS=default_locale
either with g_setenv or SetEnvironmentVariable in mini.c:mini_init()
for PLATFORM_WIN32.

Robert

Kornél Pál wrote:
> Hi,
> 
> Currently mono.exe uses ANSI arguments that are encoded using system 
> default code page (ACP). Mono however uses UTF-8 and tries to convert 
> them using MONO_EXTERNAL_ENCODINGS.
> 
> This patch takes the Unicode (UTF-16) command line arguments and 
> converts them to UTF-8. This way there is no need to modify other code 
> to use UTF-16 and the arguments still are in Unicode.
> 
> I also made strenc.c non-Windows in this patch because 
> MONO_EXTERNAL_ENCODINGS should not be used on Windows at all as it uses 
> UTF-16 internally and if we really need UTF-8 then we should convert 
> from UTF-16 rather than from ACP.
> 
> I would prefer to move argument conversion using mono_utf8_from_external 
> to main.c as well that would make code more clean but that would require 
> mono_runtime_run_main being called with UTF-8 arguments. If that is 
> acceptable I'll include that modification in the patch as well.
> 
> Kornél Index: mono/mono/metadata/object.c
> ===================================================================
> --- mono/mono/metadata/object.c    (revision 99452)
> +++ mono/mono/metadata/object.c    (working copy)
> @@ -2671,6 +2671,9 @@
>                             basename,
>                             NULL);
> 
> +#ifdef PLATFORM_WIN32
> +        utf8_fullpath = fullpath;
> +#else
>         utf8_fullpath = mono_utf8_from_external (fullpath);
>         if(utf8_fullpath == NULL) {
>             /* Printing the arg text will cause glib to
> @@ -2684,19 +2687,27 @@
>         }
> 
>         g_free (fullpath);
> +#endif
>         g_free (basename);
>     } else {
> +#ifdef PLATFORM_WIN32
> +        utf8_fullpath = g_strdup (argv [0]);
> +#else
>         utf8_fullpath = mono_utf8_from_external (argv[0]);
>         if(utf8_fullpath == NULL) {
>             g_print ("\nCannot determine the text encoding for the 
> assembly location: %s\n", argv[0]);
>             g_print ("Please add the correct encoding to 
> MONO_EXTERNAL_ENCODINGS and try again.\n");
>             exit (-1);
>         }
> +#endif
>     }
> 
>     main_args [0] = utf8_fullpath;
> 
>     for (i = 1; i < argc; ++i) {
> +#ifdef PLATFORM_WIN32
> +        main_args [i] = g_strdup (argv [i]);
> +#else
>         gchar *utf8_arg;
> 
>         utf8_arg=mono_utf8_from_external (argv[i]);
> @@ -2708,20 +2719,27 @@
>         }
> 
>         main_args [i] = utf8_arg;
> +#endif
>     }
>     argc--;
>     argv++;
>     if (mono_method_signature (method)->param_count) {
>         args = (MonoArray*)mono_array_new (domain, 
> mono_defaults.string_class, argc);
>         for (i = 0; i < argc; ++i) {
> +#ifdef PLATFORM_WIN32
> +            gchar *str = argv [i];
> +#else
>             /* The encodings should all work, given that
>              * we've checked all these args for the
>              * main_args array.
>              */
>             gchar *str = mono_utf8_from_external (argv [i]);
> +#endif
>             MonoString *arg = mono_string_new (domain, str);
>             mono_array_setref (args, i, arg);
> +#ifndef PLATFORM_WIN32
>             g_free (str);
> +#endif
>         }
>     } else {
>         args = (MonoArray*)mono_array_new (domain, 
> mono_defaults.string_class, 0);
> Index: mono/mono/mini/main.c
> ===================================================================
> --- mono/mono/mini/main.c    (revision 99452)
> +++ mono/mono/mini/main.c    (working copy)
> @@ -1,8 +1,30 @@
> #include "mini.h"
> 
> +#ifdef PLATFORM_WIN32
> +
> int
> +main ()
> +{
> +    int argc;
> +    wchar_t** wargv = CommandLineToArgvW (GetCommandLine (), &argc);
> +    char** argv = g_new0 (char*, argc);
> +    int i;
> +
> +    for (i = 0; i < argc; ++i)
> +        argv [i] = g_utf16_to_utf8 (wargv [i], -1, NULL, NULL, NULL);
> +
> +    LocalFree (wargv);
> +
> +    return mono_main (argc, argv);
> +}
> +
> +#else
> +
> +int
> main (int argc, char* argv[])
> {
>     return mono_main (argc, argv);
> }
> 
> +#endif
> +
> Index: mono/mono/utils/strenc.c
> ===================================================================
> --- mono/mono/utils/strenc.c    (revision 99452)
> +++ mono/mono/utils/strenc.c    (working copy)
> @@ -7,6 +7,9 @@
>  * (C) 2003 Ximian, Inc.
>  */
> 
> +/* These methods should not be used on Windows as it uses UTF-16 
> internally. */
> +#ifndef PLATFORM_WIN32
> +
> #include <config.h>
> #include <glib.h>
> #include <string.h>
> @@ -214,3 +217,5 @@
>     return(utf8);
> }
> 
> +#endif
> +
> Index: mono/msvc/mono.def
> ===================================================================
> --- mono/msvc/mono.def    (revision 99452)
> +++ mono/msvc/mono.def    (working copy)
> @@ -711,10 +711,7 @@
> mono_type_stack_size
> mono_type_to_unmanaged
> mono_unhandled_exception
> -mono_unicode_from_external
> -mono_unicode_to_external
> mono_upgrade_remote_class_wrapper
> -mono_utf8_from_external
> mono_valloc
> mono_value_box
> mono_value_copy
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list



More information about the Mono-devel-list mailing list