From 76eb733f3a1117b11266a05c29342671a79200e8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 29 Jul 2009 16:40:07 -0400 Subject: Separate Xcode flag escaping code from defines Generalize the core Xcode generator preprocessor flag escaping code to be useful for escaping all flags. --- Source/cmGlobalXCodeGenerator.cxx | 97 ++++++++++++++++++++++++++++----------- Source/cmGlobalXCodeGenerator.h | 4 ++ 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 6687066..0ca82e1 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -3126,48 +3126,89 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs, std::vector defines; cmSystemTools::ExpandListArgument(defines_list, defines); + // Store the definitions in the string. + this->AppendDefines(defs, defines, dflag); +} + +//---------------------------------------------------------------------------- +void +cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs, + std::vector const& defines, + bool dflag) +{ // GCC_PREPROCESSOR_DEFINITIONS is a space-separated list of definitions. - // We escape everything as follows: - // - Place each definition in single quotes '' + std::string def; + for(std::vector::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 backslash as \\\\ since it itself is an escape // Note that in the code below we need one more level of escapes for // C string syntax in this source file. - for(std::vector::const_iterator di = defines.begin(); - di != defines.end(); ++di) - { - std::string def; + // + // The final level of escaping is done when the string is stored + // into the project file by cmXCodeObject::PrintString. + if(quoteFlag) + { // Open single quote. - def += "'"; + flags += "'"; + } - // Add -D flag if requested. - if(dflag) + // Flag value with escaped quotes and backslashes. + for(const char* c = flag.c_str(); *c; ++c) + { + if(*c == '\'') { - def += "-D"; + flags += "\\\\'"; } - - // Escaped definition string. - for(const char* c = di->c_str(); *c; ++c) + else if(*c == '\\') { - if(*c == '\'') - { - def += "\\\\'"; - } - else if(*c == '\\') - { - def += "\\\\\\\\"; - } - else - { - def += *c; - } + flags += "\\\\\\\\"; } + else + { + flags += *c; + } + } + if(quoteFlag) + { // Close single quote. - def += "'"; - - defs.Add(def.c_str()); + flags += "'"; } } diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index e7bb20c..03082d2 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -183,6 +183,10 @@ private: void AppendDefines(BuildObjectListOrString& defs, const char* defines_list, bool dflag = false); + void AppendDefines(BuildObjectListOrString& defs, + std::vector const& defines, + bool dflag = false); + void AppendFlag(std::string& flags, std::string const& flag); protected: virtual const char* GetInstallTargetName() { return "install"; } -- cgit v0.12