123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmIDEOptions.h"
- #include "cmsys/String.h"
- #include <iterator>
- #include <string.h>
- #include "cmIDEFlagTable.h"
- #include "cmSystemTools.h"
- cmIDEOptions::cmIDEOptions()
- {
- this->DoingDefine = false;
- this->AllowDefine = true;
- this->DoingInclude = false;
- this->AllowSlash = false;
- this->DoingFollowing = 0;
- 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;
- }
- // If the last option was -I then this option is the include directory.
- if (this->DoingInclude) {
- this->DoingInclude = false;
- this->Includes.push_back(flag);
- return;
- }
- // If the last option expected a following value, this is it.
- if (this->DoingFollowing) {
- this->FlagMapUpdate(this->DoingFollowing, flag);
- this->DoingFollowing = 0;
- 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 for include directory.
- if (this->AllowInclude && flag[1] == 'I') {
- if (flag[2] == '\0') {
- // The next argument will have the include directory.
- this->DoingInclude = true;
- } else {
- // Store this include directory.
- this->Includes.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<int>(strlen(entry->commandFlag));
- if ((strncmp(flag + 1, entry->commandFlag, n) == 0 ||
- (entry->special & cmIDEFlagTable::CaseInsensitive &&
- cmsysString_strncasecmp(flag + 1, entry->commandFlag, n))) &&
- (!(entry->special & cmIDEFlagTable::UserRequired) ||
- static_cast<int>(strlen(flag + 1)) > n)) {
- this->FlagMapUpdate(entry, flag + n + 1);
- entry_found = true;
- }
- } else if (strcmp(flag + 1, entry->commandFlag) == 0 ||
- (entry->special & cmIDEFlagTable::CaseInsensitive &&
- cmsysString_strcasecmp(flag + 1, entry->commandFlag) == 0)) {
- if (entry->special & cmIDEFlagTable::UserFollowing) {
- // This flag expects a value in the following argument.
- this->DoingFollowing = entry;
- } else {
- // 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::FlagMapUpdate(cmIDEFlagTable const* entry,
- const char* new_value)
- {
- if (entry->special & cmIDEFlagTable::UserIgnored) {
- // Ignore the user-specified value.
- this->FlagMap[entry->IDEName] = entry->value;
- } else if (entry->special & cmIDEFlagTable::SemicolonAppendable) {
- this->FlagMap[entry->IDEName].push_back(new_value);
- } else if (entry->special & cmIDEFlagTable::SpaceAppendable) {
- this->FlagMap[entry->IDEName].append_with_space(new_value);
- } else {
- // Use the user-specified value.
- this->FlagMap[entry->IDEName] = new_value;
- }
- }
- 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::AddDefines(const std::vector<std::string>& defines)
- {
- this->Defines.insert(this->Defines.end(), defines.begin(), defines.end());
- }
- std::vector<std::string> const& cmIDEOptions::GetDefines() const
- {
- return this->Defines;
- }
- void cmIDEOptions::AddInclude(const std::string& include)
- {
- this->Includes.push_back(include);
- }
- void cmIDEOptions::AddIncludes(const char* includes)
- {
- if (includes) {
- // Expand the list of includes.
- cmSystemTools::ExpandListArgument(includes, this->Includes);
- }
- }
- void cmIDEOptions::AddIncludes(const std::vector<std::string>& includes)
- {
- this->Includes.insert(this->Includes.end(), includes.begin(),
- includes.end());
- }
- std::vector<std::string> const& cmIDEOptions::GetIncludes() const
- {
- return this->Includes;
- }
- void cmIDEOptions::AddFlag(std::string const& flag, std::string const& value)
- {
- this->FlagMap[flag] = value;
- }
- void cmIDEOptions::AddFlag(std::string const& flag,
- std::vector<std::string> const& value)
- {
- this->FlagMap[flag] = value;
- }
- void cmIDEOptions::AppendFlag(std::string const& flag,
- std::string const& value)
- {
- this->FlagMap[flag].push_back(value);
- }
- void cmIDEOptions::AppendFlag(std::string const& flag,
- std::vector<std::string> const& value)
- {
- FlagValue& fv = this->FlagMap[flag];
- std::copy(value.begin(), value.end(), std::back_inserter(fv));
- }
- void cmIDEOptions::AppendFlagString(std::string const& flag,
- std::string const& value)
- {
- this->FlagMap[flag].append_with_space(value);
- }
- void cmIDEOptions::RemoveFlag(std::string const& flag)
- {
- this->FlagMap.erase(flag);
- }
- bool cmIDEOptions::HasFlag(std::string const& flag) const
- {
- return this->FlagMap.find(flag) != this->FlagMap.end();
- }
- const char* cmIDEOptions::GetFlag(std::string const& flag) const
- {
- // This method works only for single-valued flags!
- std::map<std::string, FlagValue>::const_iterator i =
- this->FlagMap.find(flag);
- if (i != this->FlagMap.cend() && i->second.size() == 1) {
- return i->second[0].c_str();
- }
- return nullptr;
- }
|