diff options
author | Regina Pfeifer <regina@mailbox.org> | 2019-03-23 21:45:41 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2019-04-04 17:24:40 (GMT) |
commit | 9bddb03f318dd152b32c651354c9f1c30eb4d902 (patch) | |
tree | 4856a483aaeda513d930697f43116bd5c0b45832 /Source/cmParseArgumentsCommand.cxx | |
parent | 45edf1ad66a97e9083b37aeab18e33436df70b29 (diff) | |
download | CMake-9bddb03f318dd152b32c651354c9f1c30eb4d902.zip CMake-9bddb03f318dd152b32c651354c9f1c30eb4d902.tar.gz CMake-9bddb03f318dd152b32c651354c9f1c30eb4d902.tar.bz2 |
cmParseArgumentsCommand: Port to cmArgumentParser
Diffstat (limited to 'Source/cmParseArgumentsCommand.cxx')
-rw-r--r-- | Source/cmParseArgumentsCommand.cxx | 159 |
1 files changed, 45 insertions, 114 deletions
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index ab8d103..5213432 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -8,10 +8,12 @@ #include <utility> #include "cmAlgorithms.h" +#include "cmArgumentParser.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" #include "cmSystemTools.h" +#include "cm_string_view.hxx" class cmExecutionStatus; @@ -28,42 +30,43 @@ static std::string EscapeArg(const std::string& arg) return escapedArg; } -namespace { -enum insideValues +static std::string JoinList(std::vector<std::string> const& arg, bool escape) { - NONE, - SINGLE, - MULTI -}; + return escape ? cmJoin(cmMakeRange(arg).transform(EscapeArg), ";") + : cmJoin(cmMakeRange(arg), ";"); +} + +namespace { typedef std::map<std::string, bool> options_map; typedef std::map<std::string, std::string> single_map; typedef std::map<std::string, std::vector<std::string>> multi_map; typedef std::set<std::string> options_set; -} -// function to be called every time, a new key word was parsed or all -// parameters where parsed. -static void DetectKeywordsMissingValues(insideValues currentState, - const std::string& currentArgName, - int& argumentsFound, - options_set& keywordsMissingValues) +struct UserArgumentParser : public cmArgumentParser<void> { - if (currentState == SINGLE || - (currentState == MULTI && argumentsFound == 0)) { - keywordsMissingValues.insert(currentArgName); + template <typename T, typename H> + void Bind(std::vector<std::string> const& names, + std::map<std::string, T>& ref, H duplicateKey) + { + for (std::string const& key : names) { + auto const it = ref.emplace(key, T{}).first; + bool const inserted = this->cmArgumentParser<void>::Bind( + cm::string_view(it->first), it->second); + if (!inserted) { + duplicateKey(key); + } + } } +}; - argumentsFound = 0; -} +} // namespace -static void PassParsedArguments(const std::string& prefix, - cmMakefile& makefile, - const options_map& options, - const single_map& singleValArgs, - const multi_map& multiValArgs, - const std::vector<std::string>& unparsed, - const options_set& keywordsMissingValues) +static void PassParsedArguments( + const std::string& prefix, cmMakefile& makefile, const options_map& options, + const single_map& singleValArgs, const multi_map& multiValArgs, + const std::vector<std::string>& unparsed, + const options_set& keywordsMissingValues, bool parseFromArgV) { for (auto const& iter : options) { makefile.AddDefinition(prefix + iter.first, @@ -81,7 +84,7 @@ static void PassParsedArguments(const std::string& prefix, for (auto const& iter : multiValArgs) { if (!iter.second.empty()) { makefile.AddDefinition(prefix + iter.first, - cmJoin(cmMakeRange(iter.second), ";").c_str()); + JoinList(iter.second, parseFromArgV).c_str()); } else { makefile.RemoveDefinition(prefix + iter.first); } @@ -89,7 +92,7 @@ static void PassParsedArguments(const std::string& prefix, if (!unparsed.empty()) { makefile.AddDefinition(prefix + "UNPARSED_ARGUMENTS", - cmJoin(cmMakeRange(unparsed), ";").c_str()); + JoinList(unparsed, parseFromArgV).c_str()); } else { makefile.RemoveDefinition(prefix + "UNPARSED_ARGUMENTS"); } @@ -141,6 +144,8 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, // the first argument is the prefix const std::string prefix = (*argIter++) + "_"; + UserArgumentParser parser; + // define the result maps holding key/value pairs for // options, single values and multi values options_map options; @@ -150,45 +155,25 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, // anything else is put into a vector of unparsed strings std::vector<std::string> unparsed; - // remember already defined keywords - std::set<std::string> used_keywords; - const std::string dup_warning = "keyword defined more than once: "; + auto const duplicateKey = [this](std::string const& key) { + this->GetMakefile()->IssueMessage( + MessageType::WARNING, "keyword defined more than once: " + key); + }; // the second argument is a (cmake) list of options without argument std::vector<std::string> list; cmSystemTools::ExpandListArgument(*argIter++, list); - for (std::string const& iter : list) { - if (!used_keywords.insert(iter).second) { - this->GetMakefile()->IssueMessage(MessageType::WARNING, - dup_warning + iter); - } - options[iter]; // default initialize - } + parser.Bind(list, options, duplicateKey); // the third argument is a (cmake) list of single argument options list.clear(); cmSystemTools::ExpandListArgument(*argIter++, list); - for (std::string const& iter : list) { - if (!used_keywords.insert(iter).second) { - this->GetMakefile()->IssueMessage(MessageType::WARNING, - dup_warning + iter); - } - singleValArgs[iter]; // default initialize - } + parser.Bind(list, singleValArgs, duplicateKey); // the fourth argument is a (cmake) list of multi argument options list.clear(); cmSystemTools::ExpandListArgument(*argIter++, list); - for (std::string const& iter : list) { - if (!used_keywords.insert(iter).second) { - this->GetMakefile()->IssueMessage(MessageType::WARNING, - dup_warning + iter); - } - multiValArgs[iter]; // default initialize - } - - insideValues insideValues = NONE; - std::string currentArgName; + parser.Bind(list, multiValArgs, duplicateKey); list.clear(); if (!parseFromArgV) { @@ -223,68 +208,14 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, } } - options_set keywordsMissingValues; - int multiArgumentsFound = 0; - - // iterate over the arguments list and fill in the values where applicable - for (std::string const& arg : list) { - const options_map::iterator optIter = options.find(arg); - if (optIter != options.end()) { - DetectKeywordsMissingValues(insideValues, currentArgName, - multiArgumentsFound, keywordsMissingValues); - insideValues = NONE; - optIter->second = true; - continue; - } - - const single_map::iterator singleIter = singleValArgs.find(arg); - if (singleIter != singleValArgs.end()) { - DetectKeywordsMissingValues(insideValues, currentArgName, - multiArgumentsFound, keywordsMissingValues); - insideValues = SINGLE; - currentArgName = arg; - continue; - } - - const multi_map::iterator multiIter = multiValArgs.find(arg); - if (multiIter != multiValArgs.end()) { - DetectKeywordsMissingValues(insideValues, currentArgName, - multiArgumentsFound, keywordsMissingValues); - insideValues = MULTI; - currentArgName = arg; - continue; - } - - switch (insideValues) { - case SINGLE: - singleValArgs[currentArgName] = arg; - insideValues = NONE; - break; - case MULTI: - ++multiArgumentsFound; - if (parseFromArgV) { - multiValArgs[currentArgName].push_back(EscapeArg(arg)); - } else { - multiValArgs[currentArgName].push_back(arg); - } - break; - default: - multiArgumentsFound = 0; - - if (parseFromArgV) { - unparsed.push_back(EscapeArg(arg)); - } else { - unparsed.push_back(arg); - } - break; - } - } + std::vector<std::string> keywordsMissingValues; - DetectKeywordsMissingValues(insideValues, currentArgName, - multiArgumentsFound, keywordsMissingValues); + parser.Parse(list, &unparsed, &keywordsMissingValues); - PassParsedArguments(prefix, *this->Makefile, options, singleValArgs, - multiValArgs, unparsed, keywordsMissingValues); + PassParsedArguments( + prefix, *this->Makefile, options, singleValArgs, multiValArgs, unparsed, + options_set(keywordsMissingValues.begin(), keywordsMissingValues.end()), + parseFromArgV); return true; } |