summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmArgumentParser.cxx20
-rw-r--r--Source/cmArgumentParser.h20
-rw-r--r--Tests/CMakeLib/testArgumentParser.cxx18
3 files changed, 55 insertions, 3 deletions
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index c997933..25d5c68 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -5,6 +5,9 @@
#include <algorithm>
#include "cmArgumentParserTypes.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
namespace ArgumentParser {
@@ -106,10 +109,27 @@ void Instance::FinishKeyword()
return;
}
if (this->ExpectValue) {
+ if (this->ParseResults != nullptr) {
+ this->ParseResults->AddKeywordError(this->Keyword,
+ " missing required value\n");
+ }
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
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index 0078c04..8fda8b7 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -6,6 +6,7 @@
#include <cassert>
#include <functional>
+#include <map>
#include <string>
#include <utility>
#include <vector>
@@ -20,12 +21,29 @@
template <typename Result>
class cmArgumentParser; // IWYU pragma: keep
+class cmMakefile;
+
namespace ArgumentParser {
class ParseResult
{
+ std::map<cm::string_view, std::string> KeywordErrors;
+
public:
- explicit operator bool() const { return true; }
+ explicit operator bool() const { return this->KeywordErrors.empty(); }
+
+ void AddKeywordError(cm::string_view key, cm::string_view text)
+
+ {
+ this->KeywordErrors[key] += text;
+ }
+
+ std::map<cm::string_view, std::string> const& GetKeywordErrors() const
+ {
+ return this->KeywordErrors;
+ }
+
+ bool MaybeReportError(cmMakefile& mf) const;
};
template <typename Result>
diff --git a/Tests/CMakeLib/testArgumentParser.cxx b/Tests/CMakeLib/testArgumentParser.cxx
index 054cfd5..f0ace50 100644
--- a/Tests/CMakeLib/testArgumentParser.cxx
+++ b/Tests/CMakeLib/testArgumentParser.cxx
@@ -3,7 +3,9 @@
#include <initializer_list>
#include <iostream>
+#include <map>
#include <string>
+#include <utility>
#include <vector>
#include <cm/optional>
@@ -69,6 +71,11 @@ bool verifyResult(Result const& result,
static std::vector<cm::string_view> const missing = { "STRING_1"_s,
"LIST_1"_s,
"LIST_4"_s };
+ static std::map<cm::string_view, std::string> const keywordErrors = {
+ { "STRING_1"_s, " missing required value\n" },
+ { "LIST_1"_s, " missing required value\n" },
+ { "LIST_4"_s, " missing required value\n" }
+ };
#define ASSERT_TRUE(x) \
do { \
@@ -78,7 +85,7 @@ bool verifyResult(Result const& result,
} \
} while (false)
- ASSERT_TRUE(result);
+ ASSERT_TRUE(!result);
ASSERT_TRUE(result.Option1);
ASSERT_TRUE(!result.Option2);
@@ -112,6 +119,13 @@ bool verifyResult(Result const& result,
ASSERT_TRUE(unparsedArguments[0] == "bar");
ASSERT_TRUE(keywordsMissingValue == missing);
+ ASSERT_TRUE(result.GetKeywordErrors().size() == keywordErrors.size());
+ for (auto const& ke : result.GetKeywordErrors()) {
+ auto const ki = keywordErrors.find(ke.first);
+ ASSERT_TRUE(ki != keywordErrors.end());
+ ASSERT_TRUE(ke.second == ki->second);
+ }
+
return true;
}
@@ -179,7 +193,7 @@ bool testArgumentParserStaticBool()
std::vector<cm::string_view> keywordsMissingValue;
Result result;
ASSERT_TRUE(parserStatic.Parse(result, args, &unparsedArguments,
- &keywordsMissingValue) == true);
+ &keywordsMissingValue) == false);
return verifyResult(result, unparsedArguments, keywordsMissingValue);
}