From 5b85a581a88a56aed7ed7e16637b9d349629bdcf Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 29 Jul 2009 11:29:08 -0400 Subject: ENH: Separate option mapping from VS generators Split cmVisualStudioGeneratorOptions core functionality out into a base class cmIDEOptions. It will be useful for other generators. --- Source/CMakeLists.txt | 2 + Source/cmIDEOptions.cxx | 178 ++++++++++++++++++++++++++++++ Source/cmIDEOptions.h | 64 +++++++++++ Source/cmVisualStudioGeneratorOptions.cxx | 155 ++------------------------ Source/cmVisualStudioGeneratorOptions.h | 33 +----- 5 files changed, 261 insertions(+), 171 deletions(-) create mode 100644 Source/cmIDEOptions.cxx create mode 100644 Source/cmIDEOptions.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fed4d74..55048a3 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -296,6 +296,8 @@ IF (WIN32) cmGlobalVisualStudioGenerator.h cmGlobalWatcomWMakeGenerator.cxx cmIDEFlagTable.h + cmIDEOptions.cxx + cmIDEOptions.h cmLocalVisualStudio6Generator.cxx cmLocalVisualStudio6Generator.h cmLocalVisualStudio7Generator.cxx diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx new file mode 100644 index 0000000..c64eb93 --- /dev/null +++ b/Source/cmIDEOptions.cxx @@ -0,0 +1,178 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmIDEOptions.h" + +#include "cmSystemTools.h" + +//---------------------------------------------------------------------------- +cmIDEOptions::cmIDEOptions() +{ + this->DoingDefine = false; + this->AllowDefine = true; + this->AllowSlash = false; + for(int i=0; i < FlagTableCount; ++i) + { + this->FlagTable[i] = 0; + } +} + +//---------------------------------------------------------------------------- +cmIDEOptions::~cmIDEOptions() +{ +} + +//---------------------------------------------------------------------------- +void cmIDEOptions::HandleFlag(const char* flag) +{ + // If the last option was -D then this option is the definition. + if(this->DoingDefine) + { + this->DoingDefine = false; + this->Defines.push_back(flag); + return; + } + + // Look for known arguments. + if(flag[0] == '-' || (this->AllowSlash && flag[0] == '/')) + { + // Look for preprocessor definitions. + if(this->AllowDefine && flag[1] == 'D') + { + if(flag[2] == '\0') + { + // The next argument will have the definition. + this->DoingDefine = true; + } + else + { + // Store this definition. + this->Defines.push_back(flag+2); + } + return; + } + + // Look through the available flag tables. + bool flag_handled = false; + for(int i=0; i < FlagTableCount && this->FlagTable[i]; ++i) + { + if(this->CheckFlagTable(this->FlagTable[i], flag, flag_handled)) + { + return; + } + } + + // If any map entry handled the flag we are done. + if(flag_handled) + { + return; + } + } + + // This option is not known. Store it in the output flags. + this->StoreUnknownFlag(flag); +} + +//---------------------------------------------------------------------------- +bool cmIDEOptions::CheckFlagTable(cmIDEFlagTable const* table, + const char* flag, bool& flag_handled) +{ + // Look for an entry in the flag table matching this flag. + for(cmIDEFlagTable const* entry = table; entry->IDEName; ++entry) + { + bool entry_found = false; + if(entry->special & cmIDEFlagTable::UserValue) + { + // This flag table entry accepts a user-specified value. If + // the entry specifies UserRequired we must match only if a + // non-empty value is given. + int n = static_cast(strlen(entry->commandFlag)); + if(strncmp(flag+1, entry->commandFlag, n) == 0 && + (!(entry->special & cmIDEFlagTable::UserRequired) || + static_cast(strlen(flag+1)) > n)) + { + if(entry->special & cmIDEFlagTable::UserIgnored) + { + // Ignore the user-specified value. + this->FlagMap[entry->IDEName] = entry->value; + } + else if(entry->special & cmIDEFlagTable::SemicolonAppendable) + { + const char *new_value = flag+1+n; + + 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; + } + } + else + { + // Use the user-specified value. + this->FlagMap[entry->IDEName] = flag+1+n; + } + entry_found = true; + } + } + else if(strcmp(flag+1, entry->commandFlag) == 0) + { + // This flag table entry provides a fixed value. + this->FlagMap[entry->IDEName] = entry->value; + entry_found = true; + } + + // If the flag has been handled by an entry not requesting a + // search continuation we are done. + if(entry_found && !(entry->special & cmIDEFlagTable::Continue)) + { + return true; + } + + // If the entry was found the flag has been handled. + flag_handled = flag_handled || entry_found; + } + + return false; +} + +//---------------------------------------------------------------------------- +void cmIDEOptions::AddDefine(const std::string& def) +{ + this->Defines.push_back(def); +} + +//---------------------------------------------------------------------------- +void cmIDEOptions::AddDefines(const char* defines) +{ + if(defines) + { + // Expand the list of definitions. + cmSystemTools::ExpandListArgument(defines, this->Defines); + } +} + +//---------------------------------------------------------------------------- +void cmIDEOptions::AddFlag(const char* flag, const char* value) +{ + this->FlagMap[flag] = value; +} diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h new file mode 100644 index 0000000..adf6c38 --- /dev/null +++ b/Source/cmIDEOptions.h @@ -0,0 +1,64 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmIDEOptions_h +#define cmIDEOptions_h + +#include "cmStandardIncludes.h" +#include "cmIDEFlagTable.h" + +/** \class cmIDEOptions + * \brief Superclass for IDE option processing + */ +class cmIDEOptions +{ +public: + cmIDEOptions(); + virtual ~cmIDEOptions(); + + // Store definitions and flags. + void AddDefine(const std::string& define); + void AddDefines(const char* defines); + void AddFlag(const char* flag, const char* value); + +protected: + // create a map of xml tags to the values they should have in the output + // for example, "BufferSecurityCheck" = "TRUE" + // first fill this table with the values for the configuration + // Debug, Release, etc, + // 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; + + // Preprocessor definitions. + std::vector Defines; + + // Unrecognized flags that get no special handling. + cmStdString FlagString; + + bool DoingDefine; + bool AllowDefine; + bool AllowSlash; + enum { FlagTableCount = 16 }; + cmIDEFlagTable const* FlagTable[FlagTableCount]; + void HandleFlag(const char* flag); + bool CheckFlagTable(cmIDEFlagTable const* table, const char* flag, + bool& flag_handled); + virtual void StoreUnknownFlag(const char* flag) = 0; +}; + +#endif diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 7a57d90..051cc1f 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -31,10 +31,20 @@ cmVisualStudioGeneratorOptions cmVS7FlagTable const* table, cmVS7FlagTable const* extraTable, cmVisualStudio10TargetGenerator* g): + cmIDEOptions(), LocalGenerator(lg), Version(version), CurrentTool(tool), - DoingDefine(false), FlagTable(table), ExtraFlagTable(extraTable), TargetGenerator(g) { + // Store the given flag tables. + cmIDEFlagTable const** ft = this->FlagTable; + if(table) { *ft++ = table; } + if(extraTable) { *ft++ = extraTable; } + + // Preprocessor definitions are not allowed for linker tools. + this->AllowDefine = (tool != Linker); + + // Slash options are allowed for VS. + this->AllowSlash = true; } //---------------------------------------------------------------------------- @@ -85,30 +95,6 @@ void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose) } } -//---------------------------------------------------------------------------- -void cmVisualStudioGeneratorOptions::AddDefine(const std::string& def) -{ - this->Defines.push_back(def); -} - -//---------------------------------------------------------------------------- -void cmVisualStudioGeneratorOptions::AddDefines(const char* defines) -{ - if(defines) - { - // Expand the list of definitions. - cmSystemTools::ExpandListArgument(defines, this->Defines); - } -} - -//---------------------------------------------------------------------------- -void cmVisualStudioGeneratorOptions::AddFlag(const char* flag, - const char* value) -{ - this->FlagMap[flag] = value; -} - - bool cmVisualStudioGeneratorOptions::IsDebug() { return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end(); @@ -147,54 +133,8 @@ void cmVisualStudioGeneratorOptions::Parse(const char* flags) } //---------------------------------------------------------------------------- -void cmVisualStudioGeneratorOptions::HandleFlag(const char* flag) +void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag) { - // If the last option was -D then this option is the definition. - if(this->DoingDefine) - { - this->DoingDefine = false; - this->Defines.push_back(flag); - return; - } - - // Look for known arguments. - if(flag[0] == '-' || flag[0] == '/') - { - // Look for preprocessor definitions. - if(this->CurrentTool == Compiler && flag[1] == 'D') - { - if(flag[2] == '\0') - { - // The next argument will have the definition. - this->DoingDefine = true; - } - else - { - // Store this definition. - this->Defines.push_back(flag+2); - } - return; - } - - // Look through the available flag tables. - bool flag_handled = false; - if(this->FlagTable && - this->CheckFlagTable(this->FlagTable, flag, flag_handled)) - { - return; - } - if(this->ExtraFlagTable && - this->CheckFlagTable(this->ExtraFlagTable, flag, flag_handled)) - { - return; - } - - // If any map entry handled the flag we are done. - if(flag_handled) - { - return; - } - } // This option is not known. Store it in the output flags. this->FlagString += " "; this->FlagString += @@ -205,77 +145,6 @@ void cmVisualStudioGeneratorOptions::HandleFlag(const char* flag) } //---------------------------------------------------------------------------- -bool -cmVisualStudioGeneratorOptions -::CheckFlagTable(cmVS7FlagTable const* table, const char* flag, - bool& flag_handled) -{ - // Look for an entry in the flag table matching this flag. - for(cmVS7FlagTable const* entry = table; entry->IDEName; ++entry) - { - bool entry_found = false; - if(entry->special & cmVS7FlagTable::UserValue) - { - // This flag table entry accepts a user-specified value. If - // the entry specifies UserRequired we must match only if a - // non-empty value is given. - int n = static_cast(strlen(entry->commandFlag)); - if(strncmp(flag+1, entry->commandFlag, n) == 0 && - (!(entry->special & cmVS7FlagTable::UserRequired) || - static_cast(strlen(flag+1)) > n)) - { - if(entry->special & cmVS7FlagTable::UserIgnored) - { - // Ignore the user-specified value. - this->FlagMap[entry->IDEName] = entry->value; - } - else if(entry->special & cmVS7FlagTable::SemicolonAppendable) - { - const char *new_value = flag+1+n; - - 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; - } - } - else - { - // Use the user-specified value. - this->FlagMap[entry->IDEName] = flag+1+n; - } - entry_found = true; - } - } - else if(strcmp(flag+1, entry->commandFlag) == 0) - { - // This flag table entry provides a fixed value. - this->FlagMap[entry->IDEName] = entry->value; - entry_found = true; - } - - // If the flag has been handled by an entry not requesting a - // search continuation we are done. - if(entry_found && !(entry->special & cmVS7FlagTable::Continue)) - { - return true; - } - - // If the entry was found the flag has been handled. - flag_handled = flag_handled || entry_found; - } - - return false; -} - - void cmVisualStudioGeneratorOptions::SetConfiguration(const char* config) { this->Configuration = config; diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index 159c984..3899a74 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -19,13 +19,13 @@ #include "cmLocalGenerator.h" -#include "cmIDEFlagTable.h" +#include "cmIDEOptions.h" typedef cmIDEFlagTable cmVS7FlagTable; class cmVisualStudio10TargetGenerator; //---------------------------------------------------------------------------- -class cmVisualStudioGeneratorOptions +class cmVisualStudioGeneratorOptions: public cmIDEOptions { public: // Construct an options table for a given tool. @@ -51,11 +51,6 @@ public: // Store options for verbose builds. void SetVerboseMakefile(bool verbose); - // Store definitions and flags. - void AddDefine(const std::string& define); - void AddDefines(const char* defines); - void AddFlag(const char* flag, const char* value); - // Check for specific options. bool UsingUnicode(); @@ -73,29 +68,11 @@ private: cmLocalGenerator* LocalGenerator; int Version; - // create a map of xml tags to the values they should have in the output - // for example, "BufferSecurityCheck" = "TRUE" - // first fill this table with the values for the configuration - // Debug, Release, etc, - // 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; - - // Preprocessor definitions. - std::vector Defines; - - // Unrecognized flags that get no special handling. - cmStdString FlagString; std::string Configuration; - cmVisualStudio10TargetGenerator* TargetGenerator; Tool CurrentTool; - bool DoingDefine; - cmVS7FlagTable const* FlagTable; - cmVS7FlagTable const* ExtraFlagTable; - void HandleFlag(const char* flag); - bool CheckFlagTable(cmVS7FlagTable const* table, const char* flag, - bool& flag_handled); + cmVisualStudio10TargetGenerator* TargetGenerator; + + virtual void StoreUnknownFlag(const char* flag); }; #endif -- cgit v0.12