@@ -819,106 +819,62 @@ void ctkCommandLineParser::setStrictModeEnabled(bool strictMode)
819819 this ->Internal ->StrictMode = strictMode;
820820}
821821
822+ #if defined (_WIN32)
822823// --------------------------------------------------------------------------
823824void ctkCommandLineParser::convertWindowsCommandLineToUnixArguments (
824- const char * cmd_line, int * argc, char ***argv)
825+ PWSTR cmd_line, int * argc, char *** argv)
825826{
826827 if (!cmd_line || !argc || !argv)
827828 {
828829 return ;
829830 }
831+ *argc = 0 ;
832+ *argv = nullptr ;
830833
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+ }
877841
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+ }
879849
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))
882859 {
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 ;
884863 }
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+ }
885867
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;
924879 }
880+ #endif
0 commit comments