extract arg quoting for iwndows
This commit is contained in:
parent
cca28d94a6
commit
e4c4b29805
3 changed files with 49 additions and 31 deletions
src
|
@ -146,6 +146,8 @@ extern bool CanAccessFile(const char *filename);
|
|||
/// Read the contents of a directory
|
||||
extern int ReadDataDirectory(const char *dirname, std::vector<FileList> &flp);
|
||||
|
||||
extern std::vector<std::string> QuoteArguments(std::vector<std::string> args);
|
||||
|
||||
//@}
|
||||
|
||||
#endif // !__IOLIB_H__
|
||||
|
|
|
@ -837,4 +837,46 @@ FileWriter *CreateFileWriter(const std::string &filename)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote arguments for usage in calls to system(), popen() and similar.
|
||||
* Really only needed on Windows, where all these calls just concatenate
|
||||
* all arguments with a space and pass the full string to the next process.
|
||||
*/
|
||||
std::vector<std::string> QuoteArguments(std::vector<std::string> args)
|
||||
{
|
||||
std::vector<std::string> outArgs;
|
||||
for (auto arg : args) {
|
||||
#ifdef WIN32
|
||||
if (!arg.empty() && arg.find_first_of(" \t\n\v\"") == std::string::npos) {
|
||||
outArgs.push_back(arg);
|
||||
} else {
|
||||
// Windows always needs argument quoting around arguments with spaces
|
||||
std::string ss = "\"";
|
||||
for (auto ch = arg.begin(); ; ch++) {
|
||||
int backslashes = 0;
|
||||
while (ch != arg.end() && *ch == '\\') {
|
||||
ch++;
|
||||
backslashes++;
|
||||
}
|
||||
if (ch == arg.end()) {
|
||||
ss.append(backslashes * 2, '\\');
|
||||
break;
|
||||
} else if (*ch == '"') {
|
||||
ss.append(backslashes * 2 + 1, '\\');
|
||||
ss.push_back(*ch);
|
||||
} else {
|
||||
ss.append(backslashes, '\\');
|
||||
ss.push_back(*ch);
|
||||
}
|
||||
}
|
||||
ss.push_back('"');
|
||||
outArgs.push_back(ss);
|
||||
}
|
||||
#else
|
||||
outArgs.push_back(arg);
|
||||
#endif
|
||||
}
|
||||
return outArgs;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -2158,38 +2158,12 @@ static int CclRestartStratagus(lua_State *l)
|
|||
break;
|
||||
}
|
||||
}
|
||||
int newArgc = OriginalArgv.size() + (insertRestartArgument ? 2 : 1);
|
||||
std::vector<std::string> quotedArgs = QuoteArguments(OriginalArgv);
|
||||
|
||||
int newArgc = quotedArgs.size() + (insertRestartArgument ? 2 : 1);
|
||||
char **argv = new char*[newArgc];
|
||||
for (unsigned int i = 0; i < OriginalArgv.size(); i++) {
|
||||
#ifdef WIN32
|
||||
if (!OriginalArgv[i].empty() && OriginalArgv[i].find_first_of(" \t\n\v\"") == std::string::npos) {
|
||||
argv[i] = const_cast<char*>(OriginalArgv[i].c_str());
|
||||
} else {
|
||||
// Windows always needs argument quoting around arguments with spaces
|
||||
std::string ss = "\"";
|
||||
for (auto ch = OriginalArgv[i].begin(); ; ch++) {
|
||||
int backslashes = 0;
|
||||
while (ch != OriginalArgv[i].end() && *ch == '\\') {
|
||||
ch++;
|
||||
backslashes++;
|
||||
}
|
||||
if (ch == OriginalArgv[i].end()) {
|
||||
ss.append(backslashes * 2, '\\');
|
||||
break;
|
||||
} else if (*ch == '"') {
|
||||
ss.append(backslashes * 2 + 1, '\\');
|
||||
ss.push_back(*ch);
|
||||
} else {
|
||||
ss.append(backslashes, '\\');
|
||||
ss.push_back(*ch);
|
||||
}
|
||||
}
|
||||
ss.push_back('"');
|
||||
argv[i] = strdup(ss.c_str());
|
||||
}
|
||||
#else
|
||||
argv[i] = const_cast<char*>(OriginalArgv[i].c_str());
|
||||
#endif
|
||||
for (unsigned int i = 0; i < quotedArgs.size(); i++) {
|
||||
argv[i] = const_cast<char*>(quotedArgs[i].c_str());
|
||||
}
|
||||
if (insertRestartArgument) {
|
||||
argv[newArgc - 2] = (char*)"-r";
|
||||
|
|
Loading…
Add table
Reference in a new issue