1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
4 #include <initializer_list>
9 #include <cm/string_view>
10 #include <cmext/string_view>
12 #include "cmArgumentParser.h"
24 std::vector<std::string> List1;
25 std::vector<std::string> List2;
26 std::vector<std::string> List3;
28 std::vector<std::vector<std::string>> Multi1;
29 std::vector<std::vector<std::string>> Multi2;
30 std::vector<std::vector<std::string>> Multi3;
33 std::initializer_list<cm::string_view> const args = {
34 /* clang-format off */
36 "STRING_1", // string arg missing value
37 "STRING_2", "foo", "bar", // string arg + unparsed value
38 "LIST_1", // list arg missing values
39 "LIST_2", "foo", "bar", // list arg with 2 elems
40 "LIST_3", "bar", // list arg ...
41 "LIST_3", "foo", // ... with continuation
42 "MULTI_2", // multi list with 0 lists
43 "MULTI_3", "foo", "bar", // multi list with first list with two elems
44 "MULTI_3", "bar", "foo", // multi list with second list with two elems
48 bool verifyResult(Result const& result,
49 std::vector<std::string> const& unparsedArguments,
50 std::vector<std::string> const& keywordsMissingValue)
52 static std::vector<std::string> const foobar = { "foo", "bar" };
53 static std::vector<std::string> const barfoo = { "bar", "foo" };
54 static std::vector<std::string> const missing = { "STRING_1", "LIST_1" };
56 #define ASSERT_TRUE(x) \
59 std::cout << "ASSERT_TRUE(" #x ") failed on line " << __LINE__ << "\n"; \
64 ASSERT_TRUE(result.Option1);
65 ASSERT_TRUE(!result.Option2);
67 ASSERT_TRUE(result.String1.empty());
68 ASSERT_TRUE(result.String2 == "foo");
70 ASSERT_TRUE(result.List1.empty());
71 ASSERT_TRUE(result.List2 == foobar);
72 ASSERT_TRUE(result.List3 == barfoo);
74 ASSERT_TRUE(result.Multi1.empty());
75 ASSERT_TRUE(result.Multi2.size() == 1);
76 ASSERT_TRUE(result.Multi2[0].empty());
77 ASSERT_TRUE(result.Multi3.size() == 2);
78 ASSERT_TRUE(result.Multi3[0] == foobar);
79 ASSERT_TRUE(result.Multi3[1] == barfoo);
81 ASSERT_TRUE(unparsedArguments.size() == 1);
82 ASSERT_TRUE(unparsedArguments[0] == "bar");
83 ASSERT_TRUE(keywordsMissingValue == missing);
88 bool testArgumentParserDynamic()
91 std::vector<std::string> unparsedArguments;
92 std::vector<std::string> keywordsMissingValue;
94 cmArgumentParser<void>{}
95 .Bind("OPTION_1"_s, result.Option1)
96 .Bind("OPTION_2"_s, result.Option2)
97 .Bind("STRING_1"_s, result.String1)
98 .Bind("STRING_2"_s, result.String2)
99 .Bind("LIST_1"_s, result.List1)
100 .Bind("LIST_2"_s, result.List2)
101 .Bind("LIST_3"_s, result.List3)
102 .Bind("MULTI_1"_s, result.Multi1)
103 .Bind("MULTI_2"_s, result.Multi2)
104 .Bind("MULTI_3"_s, result.Multi3)
105 .Parse(args, &unparsedArguments, &keywordsMissingValue);
107 return verifyResult(result, unparsedArguments, keywordsMissingValue);
110 bool testArgumentParserStatic()
112 static auto const parser = //
113 cmArgumentParser<Result>{}
114 .Bind("OPTION_1"_s, &Result::Option1)
115 .Bind("OPTION_2"_s, &Result::Option2)
116 .Bind("STRING_1"_s, &Result::String1)
117 .Bind("STRING_2"_s, &Result::String2)
118 .Bind("LIST_1"_s, &Result::List1)
119 .Bind("LIST_2"_s, &Result::List2)
120 .Bind("LIST_3"_s, &Result::List3)
121 .Bind("MULTI_1"_s, &Result::Multi1)
122 .Bind("MULTI_2"_s, &Result::Multi2)
123 .Bind("MULTI_3"_s, &Result::Multi3);
125 std::vector<std::string> unparsedArguments;
126 std::vector<std::string> keywordsMissingValue;
127 Result const result =
128 parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
130 return verifyResult(result, unparsedArguments, keywordsMissingValue);
135 int testArgumentParser(int /*unused*/, char* /*unused*/ [])
137 if (!testArgumentParserDynamic()) {
138 std::cout << "While executing testArgumentParserDynamic().\n";
142 if (!testArgumentParserStatic()) {
143 std::cout << "While executing testArgumentParserStatic().\n";