@@ -819,106 +819,70 @@ 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
}
830
-
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
877
-
878
- // Allocate the others
879
-
880
- int j;
881
- for (j = 1 ; j < (*argc); j++)
831
+ *argc = 0 ;
832
+ *argv = nullptr ;
833
+
834
+ // Split the command line to separate arguments
835
+ int numArgs = 0 ;
836
+ LPWSTR* wideArgs = nullptr ;
837
+ // If cmd_line is an empty string then CommandLineToArgvW function returns the path to the current executable file,
838
+ // so we need to check if the string is empty.
839
+ if (lstrlenW (cmd_line) > 0 )
840
+ {
841
+ wideArgs = CommandLineToArgvW (cmd_line, &numArgs);
842
+ if (wideArgs == nullptr )
882
843
{
883
- (*argv)[j] = new char [cmd_line_len + 10 ] ;
844
+ return ;
884
845
}
846
+ }
885
847
886
- // Grab the args
887
-
888
- size_t pos;
889
- int argc_idx = 1 ;
848
+ // Allocate space for pointers in argv
849
+ (*argc) = numArgs + 1 ; // +1 because the first argument is the executable name
850
+ (*argv) = new char * [numArgs + 1 ];
851
+ for (int i = 0 ; i < numArgs + 1 ; i++)
852
+ {
853
+ (*argv)[i] = nullptr ;
854
+ }
890
855
891
- for (i = 0 ; i < cmd_line_len; i++)
856
+ if (wideArgs)
857
+ {
858
+ // Convert each argument to UTF8 and save it in argv
859
+ for (int i = 0 ; i < numArgs; ++i)
892
860
{
893
- while (isspace (cmd_line[i]) && i < cmd_line_len)
861
+ BOOL lpUsedDefaultChar = false ;
862
+ // Get length
863
+ int utf8length = WideCharToMultiByte (CP_UTF8, 0 , wideArgs[i], -1 , NULL , 0 , NULL , &lpUsedDefaultChar);
864
+ char * utf8buffer = new char [utf8length + 1 ];
865
+ int retval = WideCharToMultiByte (CP_UTF8, 0 , wideArgs[i], -1 , utf8buffer, utf8length, NULL , &lpUsedDefaultChar);
866
+ if (!SUCCEEDED (retval))
894
867
{
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
- }
868
+ // set to empty string in case of encoding error
869
+ utf8buffer[0 ] = ' \0 ' ;
870
+ continue ;
922
871
}
872
+ utf8buffer[utf8length] = ' \0 ' ; // Make sure the string is null-terminated
873
+ (*argv)[i + 1 ] = utf8buffer; // +1 because the first argument is the executable name
923
874
}
875
+ LocalFree (wideArgs);
876
+ }
877
+
878
+ // Get the application name
879
+ wchar_t wideBuffer[MAX_PATH];
880
+ DWORD wideLength = GetModuleFileNameW (NULL , wideBuffer, MAX_PATH);
881
+ // Convert the wide string to UTF-8
882
+ int utf8length = WideCharToMultiByte (CP_UTF8, 0 , wideBuffer, wideLength, NULL , 0 , NULL , NULL );
883
+ char * utf8buffer = new char [utf8length + 1 ];
884
+ WideCharToMultiByte (CP_UTF8, 0 , wideBuffer, wideLength, utf8buffer, utf8length, NULL , NULL );
885
+ utf8buffer[utf8length] = ' \0 ' ; // Make sure the string is null-terminated
886
+ (*argv)[0 ] = utf8buffer;
924
887
}
888
+ #endif
0 commit comments