@@ -819,106 +819,62 @@ void ctkCommandLineParser::setStrictModeEnabled(bool strictMode)
819
819
this ->Internal ->StrictMode = strictMode;
820
820
}
821
821
822
+ #if defined (_WIN32)
822
823
// --------------------------------------------------------------------------
823
824
void ctkCommandLineParser::convertWindowsCommandLineToUnixArguments (
824
- const char * cmd_line, int * argc, char ***argv)
825
+ PWSTR cmd_line, int * argc, char *** argv)
825
826
{
826
827
if (!cmd_line || !argc || !argv)
827
828
{
828
829
return ;
829
830
}
831
+ *argc = 0 ;
832
+ *argv = nullptr ;
830
833
831
- // A space delimites an argument except when it is inside a quote
832
-
833
- (*argc) = 1 ;
834
-
835
- size_t cmd_line_len = strlen (cmd_line);
836
-
837
- size_t i;
838
- for (i = 0 ; i < cmd_line_len; i++)
839
- {
840
- while (isspace (cmd_line[i]) && i < cmd_line_len)
841
- {
842
- i++;
843
- }
844
- if (i < cmd_line_len)
845
- {
846
- if (cmd_line[i] == ' \" ' )
847
- {
848
- i++;
849
- while (cmd_line[i] != ' \" ' && i < cmd_line_len)
850
- {
851
- i++;
852
- }
853
- (*argc)++;
854
- }
855
- else
856
- {
857
- while (!isspace (cmd_line[i]) && i < cmd_line_len)
858
- {
859
- i++;
860
- }
861
- (*argc)++;
862
- }
863
- }
864
- }
865
-
866
- (*argv) = new char * [(*argc) + 1 ];
867
- (*argv)[(*argc)] = NULL ;
868
-
869
- // Set the first arg to be the exec name
870
-
871
- (*argv)[0 ] = new char [1024 ];
872
- #ifdef _WIN32
873
- ::GetModuleFileName (0 , (*argv)[0], 1024);
874
- #else
875
- (*argv)[0 ][0 ] = ' \0 ' ;
876
- #endif
834
+ // Split the command line to separate arguments
835
+ int numArgs = 0 ;
836
+ LPWSTR* wideArgs = CommandLineToArgvW (cmd_line, &numArgs);
837
+ if (wideArgs == nullptr )
838
+ {
839
+ return ;
840
+ }
877
841
878
- // Allocate the others
842
+ // Allocate space for pointers in argv
843
+ (*argc) = numArgs + 1 ; // +1 because the first argument is the executable name
844
+ (*argv) = new char * [numArgs + 1 ];
845
+ for (int i = 0 ; i < numArgs + 1 ; i++)
846
+ {
847
+ (*argv)[i] = nullptr ;
848
+ }
879
849
880
- int j;
881
- for (j = 1 ; j < (*argc); j++)
850
+ // Convert each argument to UTF8 and save it in argv
851
+ for (int i = 0 ; i < numArgs; ++i)
852
+ {
853
+ BOOL lpUsedDefaultChar = false ;
854
+ // Get length
855
+ int utf8length = WideCharToMultiByte (CP_UTF8, 0 , wideArgs[i], -1 , NULL , 0 , NULL , &lpUsedDefaultChar);
856
+ char * utf8buffer = new char [utf8length + 1 ];
857
+ int retval = WideCharToMultiByte (CP_UTF8, 0 , wideArgs[i], -1 , utf8buffer, utf8length, NULL , &lpUsedDefaultChar);
858
+ if (!SUCCEEDED (retval))
882
859
{
883
- (*argv)[j] = new char [cmd_line_len + 10 ];
860
+ // set to empty string in case of encoding error
861
+ utf8buffer[0 ] = ' \0 ' ;
862
+ continue ;
884
863
}
864
+ utf8buffer[utf8length] = ' \0 ' ; // Make sure the string is null-terminated
865
+ (*argv)[i + 1 ] = utf8buffer; // +1 because the first argument is the executable name
866
+ }
885
867
886
- // Grab the args
887
-
888
- size_t pos;
889
- int argc_idx = 1 ;
890
-
891
- for (i = 0 ; i < cmd_line_len; i++)
892
- {
893
- while (isspace (cmd_line[i]) && i < cmd_line_len)
894
- {
895
- i++;
896
- }
897
- if (i < cmd_line_len)
898
- {
899
- if (cmd_line[i] == ' \" ' )
900
- {
901
- i++;
902
- pos = i;
903
- while (cmd_line[i] != ' \" ' && i < cmd_line_len)
904
- {
905
- i++;
906
- }
907
- memcpy ((*argv)[argc_idx], &cmd_line[pos], i - pos);
908
- (*argv)[argc_idx][i - pos] = ' \0 ' ;
909
- argc_idx++;
910
- }
911
- else
912
- {
913
- pos = i;
914
- while (!isspace (cmd_line[i]) && i < cmd_line_len)
915
- {
916
- i++;
917
- }
918
- memcpy ((*argv)[argc_idx], &cmd_line[pos], i - pos);
919
- (*argv)[argc_idx][i - pos] = ' \0 ' ;
920
- argc_idx++;
921
- }
922
- }
923
- }
868
+ LocalFree (wideArgs);
869
+
870
+ // Get the application name
871
+ wchar_t wideBuffer[MAX_PATH];
872
+ DWORD wideLength = GetModuleFileNameW (NULL , wideBuffer, MAX_PATH);
873
+ // Convert the wide string to UTF-8
874
+ int utf8length = WideCharToMultiByte (CP_UTF8, 0 , wideBuffer, wideLength, NULL , 0 , NULL , NULL );
875
+ char * utf8buffer = new char [utf8length + 1 ];
876
+ WideCharToMultiByte (CP_UTF8, 0 , wideBuffer, wideLength, utf8buffer, utf8length, NULL , NULL );
877
+ utf8buffer[utf8length] = ' \0 ' ; // Make sure the string is null-terminated
878
+ (*argv)[0 ] = utf8buffer;
924
879
}
880
+ #endif
0 commit comments