From 9edf44644d47d00f8ad54ffcae9594198845d4b1 Mon Sep 17 00:00:00 2001 From: raphasampaio Date: Thu, 21 Nov 2024 13:33:42 -0300 Subject: [PATCH 1/6] Fix unicode arguments in windows --- src/embedding_wrapper.c | 20 +++++++++++++++++++- src/juliaconfig.jl | 3 +++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/embedding_wrapper.c b/src/embedding_wrapper.c index 18526873..3c5b663c 100644 --- a/src/embedding_wrapper.c +++ b/src/embedding_wrapper.c @@ -3,6 +3,10 @@ #include #include +#ifdef _WIN32 +#include +#endif + // Julia headers #include "julia.h" #include "uv.h" @@ -57,8 +61,22 @@ void set_depot_load_path(const char *root_dir) { // main function (windows UTF16 -> UTF8 argument conversion code copied from // julia's ui/repl.c) +#ifdef _WIN32 +int wmain(int argc, wchar_t *wargv[], wchar_t *envp[]) { + char **argv = (char**)malloc(sizeof(char*) * argc); + + for (int i = 0; i < argc; i++) { // write the command line to UTF8 + wchar_t *warg = wargv[i]; + size_t len = WideCharToMultiByte(CP_UTF8, 0, warg, -1, NULL, 0, NULL, NULL); + if (!len) return 1; + char *arg = (char*)alloca(len); + if (!WideCharToMultiByte(CP_UTF8, 0, warg, -1, arg, len, NULL, NULL)) return 1; + argv[i] = arg; + } +#else int main(int argc, char *argv[]) { - argv = uv_setup_args(argc, argv); // no-op on Windows + argv = uv_setup_args(argc, argv); +#endif // Find where eventual julia arguments start int program_argc = argc; diff --git a/src/juliaconfig.jl b/src/juliaconfig.jl index 0d6f2fb0..66eb1673 100644 --- a/src/juliaconfig.jl +++ b/src/juliaconfig.jl @@ -61,6 +61,9 @@ function cflags() if Sys.isunix() print(flags, " -fPIC") end + if Sys.iswindows() + print(flags, " -municode") + end return String(take!(flags)) end From d97f0d8c4010063212683cc314541162a5735957 Mon Sep 17 00:00:00 2001 From: raphasampaio Date: Thu, 21 Nov 2024 14:06:12 -0300 Subject: [PATCH 2/6] Fix --- src/embedding_wrapper.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/embedding_wrapper.c b/src/embedding_wrapper.c index 3c5b663c..6fb9b3cc 100644 --- a/src/embedding_wrapper.c +++ b/src/embedding_wrapper.c @@ -3,10 +3,6 @@ #include #include -#ifdef _WIN32 -#include -#endif - // Julia headers #include "julia.h" #include "uv.h" From ff5257a8dc60bf98e2d7822858dd2ea229cb9683 Mon Sep 17 00:00:00 2001 From: raphasampaio Date: Thu, 21 Nov 2024 14:58:58 -0300 Subject: [PATCH 3/6] Add tests --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index a02e20a0..4ead21bc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -140,7 +140,7 @@ end rm(joinpath(new_depot, "artifacts"); recursive=true, force=true) end # try app_path(app_name) = abspath(app_compiled_dir, "bin", app_name * (Sys.iswindows() ? ".exe" : "")) - app_output = read(`$(app_path("MyApp")) I get --args --julia-args --threads=3 --check-bounds=yes -O1`, String) + app_output = read(`$(app_path("MyApp")) I get --args áéíóú --julia-args --threads=3 --check-bounds=yes -O1`, String) # Check stdlib filtering if filter == true @@ -159,7 +159,7 @@ end # Check artifact gets run from the correct place @test occursin("HelloWorld artifact at $(realpath(app_compiled_dir))", app_output) # Check ARGS - @test occursin("""ARGS = ["I", "get", "--args"]""", app_output) + @test occursin("""ARGS = ["I", "get", "--args", "áéíóú"]""", app_output) # Check julia-args @test occursin("(Base.JLOptions()).opt_level = 1", app_output) @test occursin("(Base.JLOptions()).nthreads = 3", app_output) From 601bf9e040fc1eba595a03bb04eb736757a12467 Mon Sep 17 00:00:00 2001 From: raphasampaio Date: Thu, 21 Nov 2024 15:31:30 -0300 Subject: [PATCH 4/6] Add tests --- src/embedding_wrapper.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/embedding_wrapper.c b/src/embedding_wrapper.c index 6fb9b3cc..90f0b963 100644 --- a/src/embedding_wrapper.c +++ b/src/embedding_wrapper.c @@ -60,6 +60,7 @@ void set_depot_load_path(const char *root_dir) { #ifdef _WIN32 int wmain(int argc, wchar_t *wargv[], wchar_t *envp[]) { char **argv = (char**)malloc(sizeof(char*) * argc); + if (!argv) return 1; for (int i = 0; i < argc; i++) { // write the command line to UTF8 wchar_t *warg = wargv[i]; @@ -146,6 +147,10 @@ int main(int argc, char *argv[]) { } // Cleanup and gracefully exit +#ifdef _WIN32 + for (int i = 0; i < argc; i++) free(argv[i]); + free(argv); +#endif free(exe_path); jl_atexit_hook(retcode); return retcode; From eef9e676ad93ad7fc25df5bea7691b8e12cfcd2c Mon Sep 17 00:00:00 2001 From: raphasampaio Date: Thu, 21 Nov 2024 17:29:38 -0300 Subject: [PATCH 5/6] Update --- src/embedding_wrapper.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/embedding_wrapper.c b/src/embedding_wrapper.c index 90f0b963..d2f20164 100644 --- a/src/embedding_wrapper.c +++ b/src/embedding_wrapper.c @@ -66,7 +66,7 @@ int wmain(int argc, wchar_t *wargv[], wchar_t *envp[]) { wchar_t *warg = wargv[i]; size_t len = WideCharToMultiByte(CP_UTF8, 0, warg, -1, NULL, 0, NULL, NULL); if (!len) return 1; - char *arg = (char*)alloca(len); + char *arg = (char*)malloc(len); if (!WideCharToMultiByte(CP_UTF8, 0, warg, -1, arg, len, NULL, NULL)) return 1; argv[i] = arg; } @@ -147,10 +147,6 @@ int main(int argc, char *argv[]) { } // Cleanup and gracefully exit -#ifdef _WIN32 - for (int i = 0; i < argc; i++) free(argv[i]); - free(argv); -#endif free(exe_path); jl_atexit_hook(retcode); return retcode; From c0978e60a105b4d88eb03c6d06c247cc98a9b500 Mon Sep 17 00:00:00 2001 From: raphasampaio Date: Thu, 21 Nov 2024 22:15:10 -0300 Subject: [PATCH 6/6] Update --- src/embedding_wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/embedding_wrapper.c b/src/embedding_wrapper.c index d2f20164..3080ee81 100644 --- a/src/embedding_wrapper.c +++ b/src/embedding_wrapper.c @@ -59,14 +59,14 @@ void set_depot_load_path(const char *root_dir) { // julia's ui/repl.c) #ifdef _WIN32 int wmain(int argc, wchar_t *wargv[], wchar_t *envp[]) { - char **argv = (char**)malloc(sizeof(char*) * argc); + char **argv = (char **)malloc(sizeof(char *) * argc); if (!argv) return 1; for (int i = 0; i < argc; i++) { // write the command line to UTF8 wchar_t *warg = wargv[i]; size_t len = WideCharToMultiByte(CP_UTF8, 0, warg, -1, NULL, 0, NULL, NULL); if (!len) return 1; - char *arg = (char*)malloc(len); + char *arg = (char *)malloc(len); if (!WideCharToMultiByte(CP_UTF8, 0, warg, -1, arg, len, NULL, NULL)) return 1; argv[i] = arg; }