diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h index dd1c80fb3..a654b703e 100644 --- a/code/nel/include/nel/misc/common.h +++ b/code/nel/include/nel/misc/common.h @@ -378,6 +378,10 @@ std::string getCommandOutput(const std::string &command); /// Authorized characters in names are A-Z, a-z, 0-9 and _ std::string expandEnvironmentVariables(const std::string &s); +/// Functions to convert a string with arguments to array or array to string (will espace strings with spaces) +bool explodeArguments(const std::string &str, std::vector &args); +std::string joinArguments(const std::vector &args); + /// This function kills a program using his pid (on unix, it uses the kill() POSIX function) bool killProgram(uint32 pid); diff --git a/code/nel/src/misc/cmd_args.cpp b/code/nel/src/misc/cmd_args.cpp index 647bac008..65aae5769 100644 --- a/code/nel/src/misc/cmd_args.cpp +++ b/code/nel/src/misc/cmd_args.cpp @@ -202,42 +202,13 @@ bool CCmdArgs::parse(const std::string &args) wchar_t str[4096]; uint len = GetModuleFileNameW(NULL, str, 4096); + // first argument should be full path to executable if (len && len < 4096) argv.push_back(wideToUtf8(str)); #endif - std::string::size_type pos1 = 0, pos2 = 0; - - do - { - // Look for the first non space character - pos1 = args.find_first_not_of (" ", pos2); - if(pos1 == std::string::npos) break; - - // Look for the first space or " - pos2 = args.find_first_of (" \"", pos1); - if(pos2 != std::string::npos) - { - // " ? - if(args[pos2] == '"') - { - // Look for the final \" - pos2 = args.find_first_of ("\"", pos2+1); - if(pos2 != std::string::npos) - { - // Look for the first space - pos2 = args.find_first_of (" ", pos2+1); - } - } - } - - // Compute the size of the string to extract - std::string::difference_type length = (pos2 != std::string::npos) ? pos2-pos1 : std::string::npos; - - std::string tmp = args.substr (pos1, length); - argv.push_back (tmp); - } - while(pos2 != std::string::npos); + // convert string with arguments to array + explodeArguments(args, argv); return parse(argv); } diff --git a/code/nel/src/misc/common.cpp b/code/nel/src/misc/common.cpp index c71688174..1050db638 100644 --- a/code/nel/src/misc/common.cpp +++ b/code/nel/src/misc/common.cpp @@ -851,15 +851,7 @@ bool launchProgram(const std::string &programName, const std::string &arguments, // convert one arg into several args vector args; - string::size_type pos1 = 0, pos2 = 0; - do - { - pos1 = arguments.find_first_not_of (" ", pos2); - if (pos1 == string::npos) break; - pos2 = arguments.find_first_of (" ", pos1); - args.push_back (arguments.substr (pos1, pos2-pos1)); - } - while (pos2 != string::npos); + explodeArguments(arguments, args); // Store the size of each arg vector argv(args.size()+2); @@ -1039,6 +1031,75 @@ std::string expandEnvironmentVariables(const std::string &s) return ret; } +bool explodeArguments(const std::string &str, std::vector &args) +{ + if (str.empty()) return false; + + std::string::size_type pos1 = 0, pos2 = 0; + + do + { + // Look for the first non space character + pos1 = str.find_first_not_of (" ", pos2); + if (pos1 == std::string::npos) break; + + // Look for the first space or " + pos2 = str.find_first_of (" \"", pos1); + if (pos2 != std::string::npos) + { + // " ? + if (str[pos2] == '"') + { + // Look for the final \" + pos2 = str.find_first_of ("\"", pos2+1); + if (pos2 != std::string::npos) + { + // Look for the first space + pos2 = str.find_first_of (" ", pos2+1); + } + } + } + + // Compute the size of the string to extract + std::string::difference_type length = (pos2 != std::string::npos) ? pos2-pos1 : std::string::npos; + + std::string tmp = str.substr (pos1, length); + + // remove escape " from argument + if (tmp.length() > 1 && tmp[0] == '"' && tmp[tmp.length()-1] == '"') tmp = tmp.substr(1, tmp.length()-2); + + args.push_back (tmp); + } + while(pos2 != std::string::npos); + + return true; +} + +std::string joinArguments(const std::vector &args) +{ + std::string res; + + for(uint i = 0, len = (uint)args.size(); i < len; ++i) + { + const std::string &arg = args[i]; + + // prepend space + if (!res.empty()) res += " "; + + // escape only if spaces or empty argument + if (arg.empty() || arg.find(' ') != std::string::npos) + { + res += "\"" + arg + "\""; + } + else + { + res += arg; + } + } + + return res; +} + /* * Display the bits (with 0 and 1) composing a byte (from right to left) */