From 1c209ac165cd2c25c632cdd238a9948c1651f907 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 23 Jul 2014 11:13:13 -0400 Subject: cmIDEOption: Store mapped flag values as a vector Some FlagMap entries are ;-lists. Store values as vector so that individual values may contain ';' characters. Delay the construction of the final ;-list until writing to the VS project file. With this approach the generated file may contain ;-separated values that contain encoded ';' characters. --- Source/cmIDEOptions.cxx | 27 +++++++++++-------------- Source/cmIDEOptions.h | 19 +++++++++++++++++- Source/cmVisualStudio10TargetGenerator.cxx | 32 ++++++++++++------------------ Source/cmVisualStudio10TargetGenerator.h | 3 ++- Source/cmVisualStudioGeneratorOptions.cxx | 24 +++++++++++++++++----- 5 files changed, 64 insertions(+), 41 deletions(-) diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx index 1f3c066..dfbece7 100644 --- a/Source/cmIDEOptions.cxx +++ b/Source/cmIDEOptions.cxx @@ -152,18 +152,7 @@ void cmIDEOptions::FlagMapUpdate(cmIDEFlagTable const* entry, } else if(entry->special & cmIDEFlagTable::SemicolonAppendable) { - std::map::iterator itr; - itr = this->FlagMap.find(entry->IDEName); - if(itr != this->FlagMap.end()) - { - // Append to old value (if present) with semicolons; - itr->second += ";"; - itr->second += new_value; - } - else - { - this->FlagMap[entry->IDEName] = new_value; - } + this->FlagMap[entry->IDEName].push_back(new_value); } else { @@ -200,6 +189,13 @@ void cmIDEOptions::AddFlag(const char* flag, const char* value) } //---------------------------------------------------------------------------- +void cmIDEOptions::AddFlag(const char* flag, + std::vector const& value) +{ + this->FlagMap[flag] = value; +} + +//---------------------------------------------------------------------------- void cmIDEOptions::RemoveFlag(const char* flag) { this->FlagMap.erase(flag); @@ -208,10 +204,11 @@ void cmIDEOptions::RemoveFlag(const char* flag) //---------------------------------------------------------------------------- const char* cmIDEOptions::GetFlag(const char* flag) { - std::map::iterator i = this->FlagMap.find(flag); - if(i != this->FlagMap.end()) + // This method works only for single-valued flags! + std::map::iterator i = this->FlagMap.find(flag); + if(i != this->FlagMap.end() && i->second.size() == 1) { - return i->second.c_str(); + return i->second[0].c_str(); } return 0; } diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h index e7749ec..313c003 100644 --- a/Source/cmIDEOptions.h +++ b/Source/cmIDEOptions.h @@ -29,6 +29,7 @@ public: void AddDefines(const char* defines); void AddDefines(const std::vector &defines); void AddFlag(const char* flag, const char* value); + void AddFlag(const char* flag, std::vector const& value); void RemoveFlag(const char* flag); const char* GetFlag(const char* flag); @@ -40,7 +41,23 @@ protected: // Then parse the command line flags specified in CMAKE_CXX_FLAGS // and CMAKE_C_FLAGS // and overwrite or add new values to this map - std::map FlagMap; + class FlagValue: public std::vector + { + typedef std::vector derived; + public: + FlagValue& operator=(std::string const& r) + { + this->resize(1); + this->operator[](0) = r; + return *this; + } + FlagValue& operator=(std::vector const& r) + { + this->derived::operator=(r); + return *this; + } + }; + std::map FlagMap; // Preprocessor definitions. std::vector Defines; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 35c48cf..2429e59 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1735,6 +1735,9 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) } // Replace spaces in libs with ; cmSystemTools::ReplaceString(libs, " ", ";"); + std::vector libVec; + cmSystemTools::ExpandListArgument(libs, libVec); + cmComputeLinkInformation* pcli = this->Target->GetLinkInformation(config.c_str()); if(!pcli) @@ -1746,27 +1749,21 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) } // add the libraries for the target to libs string cmComputeLinkInformation& cli = *pcli; - this->AddLibraries(cli, libs); - linkOptions.AddFlag("AdditionalDependencies", libs.c_str()); + this->AddLibraries(cli, libVec); + linkOptions.AddFlag("AdditionalDependencies", libVec); std::vector const& ldirs = cli.GetDirectories(); - const char* sep = ""; - std::string linkDirs; + std::vector linkDirs; for(std::vector::const_iterator d = ldirs.begin(); d != ldirs.end(); ++d) { // first just full path - linkDirs += sep; - linkDirs += *d; - sep = ";"; - linkDirs += sep; + linkDirs.push_back(*d); // next path with configuration type Debug, Release, etc - linkDirs += *d; - linkDirs += "/$(Configuration)"; - linkDirs += sep; + linkDirs.push_back(*d + "/$(Configuration)"); } - linkDirs += "%(AdditionalLibraryDirectories)"; - linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs.c_str()); + linkDirs.push_back("%(AdditionalLibraryDirectories)"); + linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs); std::string targetName; std::string targetNameSO; @@ -1866,11 +1863,10 @@ cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config) void cmVisualStudio10TargetGenerator::AddLibraries( cmComputeLinkInformation& cli, - std::string& libstring) + std::vector& libVec) { typedef cmComputeLinkInformation::ItemVector ItemVector; ItemVector libs = cli.GetItems(); - const char* sep = ";"; for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l) { if(l->IsPath) @@ -1880,14 +1876,12 @@ void cmVisualStudio10TargetGenerator::AddLibraries( cmLocalGenerator::START_OUTPUT, cmLocalGenerator::UNCHANGED); this->ConvertToWindowsSlash(path); - libstring += sep; - libstring += path; + libVec.push_back(path); } else if (!l->Target || l->Target->GetType() != cmTarget::INTERFACE_LIBRARY) { - libstring += sep; - libstring += l->Value; + libVec.push_back(l->Value); } } } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 6c92b57..7a329cb 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -90,7 +90,8 @@ private: void WriteGroups(); void WriteProjectReferences(); bool OutputSourceSpecificFlags(cmSourceFile const* source); - void AddLibraries(cmComputeLinkInformation& cli, std::string& libstring); + void AddLibraries(cmComputeLinkInformation& cli, + std::vector& libVec); void WriteLibOptions(std::string const& config); void WriteEvents(std::string const& configName); void WriteEvent(const char* name, diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 2cbf5db..f710780 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -301,7 +301,7 @@ cmVisualStudioGeneratorOptions { if(this->Version >= cmLocalVisualStudioGenerator::VS10) { - for(std::map::iterator m = this->FlagMap.begin(); + for(std::map::iterator m = this->FlagMap.begin(); m != this->FlagMap.end(); ++m) { fout << indent; @@ -317,20 +317,34 @@ cmVisualStudioGeneratorOptions { fout << "<" << m->first << ">"; } - fout << m->second; + const char* sep = ""; + for(std::vector::iterator i = m->second.begin(); + i != m->second.end(); ++i) + { + fout << sep << *i; + sep = ";"; + } if (m->first == "AdditionalIncludeDirectories") { - fout << ";%(AdditionalIncludeDirectories)"; + fout << sep << "%(AdditionalIncludeDirectories)"; } fout << "first << ">\n"; } } else { - for(std::map::iterator m = this->FlagMap.begin(); + for(std::map::iterator m = this->FlagMap.begin(); m != this->FlagMap.end(); ++m) { - fout << indent << m->first << "=\"" << m->second << "\"\n"; + fout << indent << m->first << "=\""; + const char* sep = ""; + for(std::vector::iterator i = m->second.begin(); + i != m->second.end(); ++i) + { + fout << sep << *i; + sep = ";"; + } + fout << "\"\n"; } } } -- cgit v0.12