Separate Xcode flag escaping code from defines
Generalize the core Xcode generator preprocessor flag escaping code to be useful for escaping all flags.
This commit is contained in:
parent
8ab2548d6c
commit
76eb733f3a
|
@ -3126,48 +3126,89 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
|
||||||
std::vector<std::string> defines;
|
std::vector<std::string> defines;
|
||||||
cmSystemTools::ExpandListArgument(defines_list, defines);
|
cmSystemTools::ExpandListArgument(defines_list, defines);
|
||||||
|
|
||||||
|
// Store the definitions in the string.
|
||||||
|
this->AppendDefines(defs, defines, dflag);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
|
||||||
|
std::vector<std::string> const& defines,
|
||||||
|
bool dflag)
|
||||||
|
{
|
||||||
// GCC_PREPROCESSOR_DEFINITIONS is a space-separated list of definitions.
|
// GCC_PREPROCESSOR_DEFINITIONS is a space-separated list of definitions.
|
||||||
// We escape everything as follows:
|
std::string def;
|
||||||
// - Place each definition in single quotes ''
|
for(std::vector<std::string>::const_iterator di = defines.begin();
|
||||||
|
di != defines.end(); ++di)
|
||||||
|
{
|
||||||
|
// Start with -D if requested.
|
||||||
|
def = dflag? "-D": "";
|
||||||
|
def += *di;
|
||||||
|
|
||||||
|
// Append the flag with needed escapes.
|
||||||
|
std::string tmp;
|
||||||
|
this->AppendFlag(tmp, def);
|
||||||
|
defs.Add(tmp.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
|
||||||
|
std::string const& flag)
|
||||||
|
{
|
||||||
|
// Short-circuit for an empty flag.
|
||||||
|
if(flag.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Separate from previous flags.
|
||||||
|
if(!flags.empty())
|
||||||
|
{
|
||||||
|
flags += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the flag needs quoting.
|
||||||
|
bool quoteFlag =
|
||||||
|
flag.find_first_of("`~!@#$%^&*()+={}[]|:;\"'<>,.? ") != flag.npos;
|
||||||
|
|
||||||
|
// We escape a flag as follows:
|
||||||
|
// - Place each flag in single quotes ''
|
||||||
// - Escape a single quote as \\'
|
// - Escape a single quote as \\'
|
||||||
// - Escape a backslash as \\\\ since it itself is an escape
|
// - Escape a backslash as \\\\ since it itself is an escape
|
||||||
// Note that in the code below we need one more level of escapes for
|
// Note that in the code below we need one more level of escapes for
|
||||||
// C string syntax in this source file.
|
// C string syntax in this source file.
|
||||||
for(std::vector<std::string>::const_iterator di = defines.begin();
|
//
|
||||||
di != defines.end(); ++di)
|
// The final level of escaping is done when the string is stored
|
||||||
|
// into the project file by cmXCodeObject::PrintString.
|
||||||
|
|
||||||
|
if(quoteFlag)
|
||||||
{
|
{
|
||||||
std::string def;
|
|
||||||
|
|
||||||
// Open single quote.
|
// Open single quote.
|
||||||
def += "'";
|
flags += "'";
|
||||||
|
}
|
||||||
|
|
||||||
// Add -D flag if requested.
|
// Flag value with escaped quotes and backslashes.
|
||||||
if(dflag)
|
for(const char* c = flag.c_str(); *c; ++c)
|
||||||
|
{
|
||||||
|
if(*c == '\'')
|
||||||
{
|
{
|
||||||
def += "-D";
|
flags += "\\\\'";
|
||||||
}
|
}
|
||||||
|
else if(*c == '\\')
|
||||||
// Escaped definition string.
|
|
||||||
for(const char* c = di->c_str(); *c; ++c)
|
|
||||||
{
|
{
|
||||||
if(*c == '\'')
|
flags += "\\\\\\\\";
|
||||||
{
|
|
||||||
def += "\\\\'";
|
|
||||||
}
|
|
||||||
else if(*c == '\\')
|
|
||||||
{
|
|
||||||
def += "\\\\\\\\";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
def += *c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags += *c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(quoteFlag)
|
||||||
|
{
|
||||||
// Close single quote.
|
// Close single quote.
|
||||||
def += "'";
|
flags += "'";
|
||||||
|
|
||||||
defs.Add(def.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,10 @@ private:
|
||||||
|
|
||||||
void AppendDefines(BuildObjectListOrString& defs, const char* defines_list,
|
void AppendDefines(BuildObjectListOrString& defs, const char* defines_list,
|
||||||
bool dflag = false);
|
bool dflag = false);
|
||||||
|
void AppendDefines(BuildObjectListOrString& defs,
|
||||||
|
std::vector<std::string> const& defines,
|
||||||
|
bool dflag = false);
|
||||||
|
void AppendFlag(std::string& flags, std::string const& flag);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const char* GetInstallTargetName() { return "install"; }
|
virtual const char* GetInstallTargetName() { return "install"; }
|
||||||
|
|
Loading…
Reference in New Issue