diff options
Diffstat (limited to 'Source/cmArgumentParser.cxx')
| -rw-r--r-- | Source/cmArgumentParser.cxx | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx index 4624f1c..25d5c68 100644 --- a/Source/cmArgumentParser.cxx +++ b/Source/cmArgumentParser.cxx @@ -4,9 +4,14 @@ #include <algorithm> +#include "cmArgumentParserTypes.h" +#include "cmMakefile.h" +#include "cmMessageType.h" +#include "cmStringAlgorithms.h" + namespace ArgumentParser { -auto ActionMap::Emplace(cm::string_view name, Action action) +auto KeywordActionMap::Emplace(cm::string_view name, KeywordAction action) -> std::pair<iterator, bool> { auto const it = @@ -19,7 +24,7 @@ auto ActionMap::Emplace(cm::string_view name, Action action) : std::make_pair(this->emplace(it, name, std::move(action)), true); } -auto ActionMap::Find(cm::string_view name) const -> const_iterator +auto KeywordActionMap::Find(cm::string_view name) const -> const_iterator { auto const it = std::lower_bound(this->begin(), this->end(), name, @@ -44,34 +49,44 @@ void Instance::Bind(std::string& val) this->ExpectValue = true; } -void Instance::Bind(StringList& val) +void Instance::Bind(Maybe<std::string>& val) +{ + this->CurrentString = &val; + this->CurrentList = nullptr; + this->ExpectValue = false; +} + +void Instance::Bind(MaybeEmpty<std::vector<std::string>>& val) +{ + this->CurrentString = nullptr; + this->CurrentList = &val; + this->ExpectValue = false; +} + +void Instance::Bind(NonEmpty<std::vector<std::string>>& val) { this->CurrentString = nullptr; this->CurrentList = &val; this->ExpectValue = true; } -void Instance::Bind(MultiStringList& val) +void Instance::Bind(std::vector<std::vector<std::string>>& val) { this->CurrentString = nullptr; this->CurrentList = (static_cast<void>(val.emplace_back()), &val.back()); this->ExpectValue = false; } -void Instance::Consume(cm::string_view arg, void* result, - std::vector<std::string>* unparsedArguments, - std::vector<std::string>* keywordsMissingValue, - std::vector<std::string>* parsedKeywords) +void Instance::Consume(cm::string_view arg) { - auto const it = this->Bindings.Find(arg); - if (it != this->Bindings.end()) { - if (parsedKeywords != nullptr) { - parsedKeywords->emplace_back(arg); - } - it->second(*this, result); - if (this->ExpectValue && keywordsMissingValue != nullptr) { - keywordsMissingValue->emplace_back(arg); + auto const it = this->Bindings.Keywords.Find(arg); + if (it != this->Bindings.Keywords.end()) { + this->FinishKeyword(); + this->Keyword = it->first; + if (this->ParsedKeywords != nullptr) { + this->ParsedKeywords->emplace_back(it->first); } + it->second(*this); return; } @@ -81,16 +96,40 @@ void Instance::Consume(cm::string_view arg, void* result, this->CurrentList = nullptr; } else if (this->CurrentList != nullptr) { this->CurrentList->emplace_back(arg); - } else if (unparsedArguments != nullptr) { - unparsedArguments->emplace_back(arg); + } else if (this->UnparsedArguments != nullptr) { + this->UnparsedArguments->emplace_back(arg); } + this->ExpectValue = false; +} + +void Instance::FinishKeyword() +{ + if (this->Keyword.empty()) { + return; + } if (this->ExpectValue) { - if (keywordsMissingValue != nullptr) { - keywordsMissingValue->pop_back(); + if (this->ParseResults != nullptr) { + this->ParseResults->AddKeywordError(this->Keyword, + " missing required value\n"); } - this->ExpectValue = false; + if (this->KeywordsMissingValue != nullptr) { + this->KeywordsMissingValue->emplace_back(this->Keyword); + } + } +} + +bool ParseResult::MaybeReportError(cmMakefile& mf) const +{ + if (*this) { + return false; + } + std::string e; + for (auto const& ke : this->KeywordErrors) { + e = cmStrCat(e, "Error after keyword \"", ke.first, "\":\n", ke.second); } + mf.IssueMessage(MessageType::FATAL_ERROR, e); + return true; } } // namespace ArgumentParser |
