BUG: Centralized generation of command line arguments in escaped form. This addresses bug#3786 for several platforms.

This commit is contained in:
Brad King 2006-09-21 15:14:06 -04:00
parent 0952a96485
commit 2459ceb076
8 changed files with 96 additions and 70 deletions

View File

@ -130,12 +130,12 @@ void cmGlobalVisualStudio8Generator::Generate()
std::string argH = "-H"; std::string argH = "-H";
argH += lg->Convert(mf->GetHomeDirectory(), argH += lg->Convert(mf->GetHomeDirectory(),
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL, true); cmLocalGenerator::UNCHANGED, true);
commandLine.push_back(argH); commandLine.push_back(argH);
std::string argB = "-B"; std::string argB = "-B";
argB += lg->Convert(mf->GetHomeOutputDirectory(), argB += lg->Convert(mf->GetHomeOutputDirectory(),
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL, true); cmLocalGenerator::UNCHANGED, true);
commandLine.push_back(argB); commandLine.push_back(argB);
cmCustomCommandLines commandLines; cmCustomCommandLines commandLines;
commandLines.push_back(commandLine); commandLines.push_back(commandLine);

View File

@ -28,6 +28,8 @@
#include "cmTest.h" #include "cmTest.h"
#include "cmake.h" #include "cmake.h"
#include <cmsys/System.h>
#include <ctype.h> // for isalpha #include <ctype.h> // for isalpha
cmLocalGenerator::cmLocalGenerator() cmLocalGenerator::cmLocalGenerator()
@ -1896,56 +1898,6 @@ void cmLocalGenerator::AppendFlags(std::string& flags,
} }
} }
//----------------------------------------------------------------------------
std::string
cmLocalGenerator::ConstructScript(const cmCustomCommandLines& commandLines,
const char* workingDirectory,
const char* newline)
{
// Store the script in a string.
std::string script;
if(workingDirectory)
{
script += "cd ";
script += this->Convert(workingDirectory, START_OUTPUT, SHELL);
script += newline;
}
// for visual studio IDE add extra stuff to the PATH
// if CMAKE_MSVCIDE_RUN_PATH is set.
if(this->Makefile->GetDefinition("MSVC_IDE"))
{
const char* extraPath =
this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
if(extraPath)
{
script += "set PATH=";
script += extraPath;
script += ";%PATH%";
script += newline;
}
}
// Write each command on a single line.
for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
cl != commandLines.end(); ++cl)
{
// Start with the command name.
const cmCustomCommandLine& commandLine = *cl;
script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
// Add the arguments.
for(unsigned int j=1;j < commandLine.size(); ++j)
{
script += " ";
script += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
}
// End the line.
script += newline;
}
return script;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string std::string
cmLocalGenerator::ConstructComment(const cmCustomCommand& cc, cmLocalGenerator::ConstructComment(const cmCustomCommand& cc,
@ -2289,3 +2241,29 @@ cmLocalGenerator
return (this->GlobalGenerator return (this->GlobalGenerator
->GetLanguageFromExtension(source.GetSourceExtension().c_str())); ->GetLanguageFromExtension(source.GetSourceExtension().c_str()));
} }
//----------------------------------------------------------------------------
std::string cmLocalGenerator::EscapeForShell(const char* str)
{
std::string result;
if(this->WindowsShell)
{
int size = cmsysSystem_Windows_ShellArgumentSize(str);
std::vector<char> arg(size);
cmsysSystem_Windows_ShellArgument(str, &arg[0]);
result = &arg[0];
}
else
{
for(const char* c = str; *c; ++c)
{
if(*c == '\\' || *c == '\'' || *c == '"' || *c == ';' ||
*c == '(' || *c == ')')
{
result += "\\";
}
result += *c;
}
}
return result;
}

View File

@ -202,10 +202,10 @@ public:
}; };
protected: protected:
/** Construct a script from the given list of command lines. */
std::string ConstructScript(const cmCustomCommandLines& commandLines, /** Escape the given string to be used as a command line argument in
const char* workingDirectory, the native build system shell. */
const char* newline = "\n"); std::string EscapeForShell(const char* str);
/** Construct a comment for a custom command. */ /** Construct a comment for a custom command. */
std::string ConstructComment(const cmCustomCommand& cc, std::string ConstructComment(const cmCustomCommand& cc,

View File

@ -931,16 +931,7 @@ cmLocalUnixMakefileGenerator3
for(unsigned int j=1; j < commandLine.size(); ++j) for(unsigned int j=1; j < commandLine.size(); ++j)
{ {
cmd += " "; cmd += " ";
bool forceOn = cmSystemTools::GetForceUnixPaths(); cmd += this->EscapeForShell(commandLine[j].c_str());
if(forceOn && this->WindowsShell)
{
cmSystemTools::SetForceUnixPaths(false);
}
cmd += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
if(forceOn && this->WindowsShell)
{
cmSystemTools::SetForceUnixPaths(true);
}
} }
commands1.push_back(cmd); commands1.push_back(cmd);
} }

View File

@ -223,12 +223,12 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
std::string args; std::string args;
args = "-H"; args = "-H";
args += this->Convert(this->Makefile->GetHomeDirectory(), args += this->Convert(this->Makefile->GetHomeDirectory(),
START_OUTPUT, SHELL, true); START_OUTPUT, UNCHANGED, true);
commandLine.push_back(args); commandLine.push_back(args);
args = "-B"; args = "-B";
args += args +=
this->Convert(this->Makefile->GetHomeOutputDirectory(), this->Convert(this->Makefile->GetHomeOutputDirectory(),
START_OUTPUT, SHELL, true); START_OUTPUT, UNCHANGED, true);
commandLine.push_back(args); commandLine.push_back(args);
std::string configFile = std::string configFile =

View File

@ -219,12 +219,12 @@ void cmLocalVisualStudio7Generator::AddVCProjBuildRule(cmTarget& tgt)
std::string args; std::string args;
args = "-H"; args = "-H";
args += this->Convert(this->Makefile->GetHomeDirectory(), args += this->Convert(this->Makefile->GetHomeDirectory(),
START_OUTPUT, SHELL, true); START_OUTPUT, UNCHANGED, true);
commandLine.push_back(args); commandLine.push_back(args);
args = "-B"; args = "-B";
args += args +=
this->Convert(this->Makefile->GetHomeOutputDirectory(), this->Convert(this->Makefile->GetHomeOutputDirectory(),
START_OUTPUT, SHELL, true); START_OUTPUT, UNCHANGED, true);
commandLine.push_back(args); commandLine.push_back(args);
std::string configFile = std::string configFile =

View File

@ -23,6 +23,7 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator() cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator()
{ {
this->WindowsShell = true;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -103,3 +104,53 @@ void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
} }
} }
} }
//----------------------------------------------------------------------------
std::string
cmLocalVisualStudioGenerator
::ConstructScript(const cmCustomCommandLines& commandLines,
const char* workingDirectory,
const char* newline)
{
// Store the script in a string.
std::string script;
if(workingDirectory)
{
script += "cd ";
script += this->Convert(workingDirectory, START_OUTPUT, SHELL);
script += newline;
}
// for visual studio IDE add extra stuff to the PATH
// if CMAKE_MSVCIDE_RUN_PATH is set.
if(this->Makefile->GetDefinition("MSVC_IDE"))
{
const char* extraPath =
this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
if(extraPath)
{
script += "set PATH=";
script += extraPath;
script += ";%PATH%";
script += newline;
}
}
// Write each command on a single line.
for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
cl != commandLines.end(); ++cl)
{
// Start with the command name.
const cmCustomCommandLine& commandLine = *cl;
script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
// Add the arguments.
for(unsigned int j=1;j < commandLine.size(); ++j)
{
script += " ";
script += this->EscapeForShell(commandLine[j].c_str());
}
// End the line.
script += newline;
}
return script;
}

View File

@ -35,6 +35,12 @@ public:
virtual ~cmLocalVisualStudioGenerator(); virtual ~cmLocalVisualStudioGenerator();
protected: protected:
/** Construct a script from the given list of command lines. */
std::string ConstructScript(const cmCustomCommandLines& commandLines,
const char* workingDirectory,
const char* newline = "\n");
// Safe object file name generation. // Safe object file name generation.
void ComputeObjectNameRequirements(std::vector<cmSourceGroup> const&); void ComputeObjectNameRequirements(std::vector<cmSourceGroup> const&);
bool SourceFileCompiles(const cmSourceFile* sf); bool SourceFileCompiles(const cmSourceFile* sf);