xref: /minix3/external/bsd/llvm/dist/llvm/unittests/Option/OptionParsingTest.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
11f4a2713aSLionel Sambuc #include "llvm/Option/Arg.h"
12f4a2713aSLionel Sambuc #include "llvm/Option/ArgList.h"
13f4a2713aSLionel Sambuc #include "llvm/Option/Option.h"
14f4a2713aSLionel Sambuc #include "gtest/gtest.h"
15f4a2713aSLionel Sambuc 
16f4a2713aSLionel Sambuc using namespace llvm;
17f4a2713aSLionel Sambuc using namespace llvm::opt;
18f4a2713aSLionel Sambuc 
19f4a2713aSLionel Sambuc enum ID {
20f4a2713aSLionel Sambuc   OPT_INVALID = 0, // This is not an option ID.
21f4a2713aSLionel Sambuc #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
22f4a2713aSLionel Sambuc                HELPTEXT, METAVAR) OPT_##ID,
23f4a2713aSLionel Sambuc #include "Opts.inc"
24f4a2713aSLionel Sambuc   LastOption
25f4a2713aSLionel Sambuc #undef OPTION
26f4a2713aSLionel Sambuc };
27f4a2713aSLionel Sambuc 
28f4a2713aSLionel Sambuc #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
29f4a2713aSLionel Sambuc #include "Opts.inc"
30f4a2713aSLionel Sambuc #undef PREFIX
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc enum OptionFlags {
33f4a2713aSLionel Sambuc   OptFlag1 = (1 << 4),
34f4a2713aSLionel Sambuc   OptFlag2 = (1 << 5),
35f4a2713aSLionel Sambuc   OptFlag3 = (1 << 6)
36f4a2713aSLionel Sambuc };
37f4a2713aSLionel Sambuc 
38f4a2713aSLionel Sambuc static const OptTable::Info InfoTable[] = {
39f4a2713aSLionel Sambuc #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
40f4a2713aSLionel Sambuc                HELPTEXT, METAVAR)   \
41f4a2713aSLionel Sambuc   { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
42f4a2713aSLionel Sambuc     FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
43f4a2713aSLionel Sambuc #include "Opts.inc"
44f4a2713aSLionel Sambuc #undef OPTION
45f4a2713aSLionel Sambuc };
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc namespace {
48f4a2713aSLionel Sambuc class TestOptTable : public OptTable {
49f4a2713aSLionel Sambuc public:
TestOptTable(bool IgnoreCase=false)50f4a2713aSLionel Sambuc   TestOptTable(bool IgnoreCase = false)
51f4a2713aSLionel Sambuc     : OptTable(InfoTable, array_lengthof(InfoTable), IgnoreCase) {}
52f4a2713aSLionel Sambuc };
53f4a2713aSLionel Sambuc }
54f4a2713aSLionel Sambuc 
55f4a2713aSLionel Sambuc const char *Args[] = {
56f4a2713aSLionel Sambuc   "-A",
57f4a2713aSLionel Sambuc   "-Bhi",
58f4a2713aSLionel Sambuc   "--C=desu",
59f4a2713aSLionel Sambuc   "-C", "bye",
60f4a2713aSLionel Sambuc   "-D,adena",
61f4a2713aSLionel Sambuc   "-E", "apple", "bloom",
62f4a2713aSLionel Sambuc   "-Fblarg",
63f4a2713aSLionel Sambuc   "-F", "42",
64f4a2713aSLionel Sambuc   "-Gchuu", "2"
65f4a2713aSLionel Sambuc   };
66f4a2713aSLionel Sambuc 
TEST(Option,OptionParsing)67f4a2713aSLionel Sambuc TEST(Option, OptionParsing) {
68f4a2713aSLionel Sambuc   TestOptTable T;
69f4a2713aSLionel Sambuc   unsigned MAI, MAC;
70*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL(
71*0a6a1f1dSLionel Sambuc       T.ParseArgs(std::begin(Args), std::end(Args), MAI, MAC));
72f4a2713aSLionel Sambuc 
73f4a2713aSLionel Sambuc   // Check they all exist.
74f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_A));
75f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_B));
76f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_C));
77f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_D));
78f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_E));
79f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_F));
80f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_G));
81f4a2713aSLionel Sambuc 
82f4a2713aSLionel Sambuc   // Check the values.
83f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getLastArgValue(OPT_B), "hi");
84f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getLastArgValue(OPT_C), "bye");
85f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getLastArgValue(OPT_D), "adena");
86f4a2713aSLionel Sambuc   std::vector<std::string> Es = AL->getAllArgValues(OPT_E);
87f4a2713aSLionel Sambuc   EXPECT_EQ(Es[0], "apple");
88f4a2713aSLionel Sambuc   EXPECT_EQ(Es[1], "bloom");
89f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getLastArgValue(OPT_F), "42");
90f4a2713aSLionel Sambuc   std::vector<std::string> Gs = AL->getAllArgValues(OPT_G);
91f4a2713aSLionel Sambuc   EXPECT_EQ(Gs[0], "chuu");
92f4a2713aSLionel Sambuc   EXPECT_EQ(Gs[1], "2");
93f4a2713aSLionel Sambuc 
94f4a2713aSLionel Sambuc   // Check the help text.
95f4a2713aSLionel Sambuc   std::string Help;
96f4a2713aSLionel Sambuc   raw_string_ostream RSO(Help);
97f4a2713aSLionel Sambuc   T.PrintHelp(RSO, "test", "title!");
98f4a2713aSLionel Sambuc   EXPECT_NE(Help.find("-A"), std::string::npos);
99f4a2713aSLionel Sambuc 
100f4a2713aSLionel Sambuc   // Test aliases.
101f4a2713aSLionel Sambuc   arg_iterator Cs = AL->filtered_begin(OPT_C);
102f4a2713aSLionel Sambuc   ASSERT_NE(Cs, AL->filtered_end());
103f4a2713aSLionel Sambuc   EXPECT_EQ(StringRef((*Cs)->getValue()), "desu");
104f4a2713aSLionel Sambuc   ArgStringList ASL;
105f4a2713aSLionel Sambuc   (*Cs)->render(*AL, ASL);
106f4a2713aSLionel Sambuc   ASSERT_EQ(ASL.size(), 2u);
107f4a2713aSLionel Sambuc   EXPECT_EQ(StringRef(ASL[0]), "-C");
108f4a2713aSLionel Sambuc   EXPECT_EQ(StringRef(ASL[1]), "desu");
109f4a2713aSLionel Sambuc }
110f4a2713aSLionel Sambuc 
TEST(Option,ParseWithFlagExclusions)111f4a2713aSLionel Sambuc TEST(Option, ParseWithFlagExclusions) {
112f4a2713aSLionel Sambuc   TestOptTable T;
113f4a2713aSLionel Sambuc   unsigned MAI, MAC;
114*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL;
115f4a2713aSLionel Sambuc 
116f4a2713aSLionel Sambuc   // Exclude flag3 to avoid parsing as OPT_SLASH_C.
117*0a6a1f1dSLionel Sambuc   AL.reset(T.ParseArgs(std::begin(Args), std::end(Args), MAI, MAC,
118f4a2713aSLionel Sambuc                        /*FlagsToInclude=*/0,
119f4a2713aSLionel Sambuc                        /*FlagsToExclude=*/OptFlag3));
120f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_A));
121f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_C));
122f4a2713aSLionel Sambuc   EXPECT_FALSE(AL->hasArg(OPT_SLASH_C));
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc   // Exclude flag1 to avoid parsing as OPT_C.
125*0a6a1f1dSLionel Sambuc   AL.reset(T.ParseArgs(std::begin(Args), std::end(Args), MAI, MAC,
126f4a2713aSLionel Sambuc                        /*FlagsToInclude=*/0,
127f4a2713aSLionel Sambuc                        /*FlagsToExclude=*/OptFlag1));
128f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_B));
129f4a2713aSLionel Sambuc   EXPECT_FALSE(AL->hasArg(OPT_C));
130f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_SLASH_C));
131f4a2713aSLionel Sambuc 
132f4a2713aSLionel Sambuc   const char *NewArgs[] = { "/C", "foo", "--C=bar" };
133*0a6a1f1dSLionel Sambuc   AL.reset(T.ParseArgs(std::begin(NewArgs), std::end(NewArgs), MAI, MAC));
134f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_SLASH_C));
135f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_C));
136f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getLastArgValue(OPT_SLASH_C), "foo");
137f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getLastArgValue(OPT_C), "bar");
138f4a2713aSLionel Sambuc }
139f4a2713aSLionel Sambuc 
TEST(Option,ParseAliasInGroup)140f4a2713aSLionel Sambuc TEST(Option, ParseAliasInGroup) {
141f4a2713aSLionel Sambuc   TestOptTable T;
142f4a2713aSLionel Sambuc   unsigned MAI, MAC;
143f4a2713aSLionel Sambuc 
144f4a2713aSLionel Sambuc   const char *MyArgs[] = { "-I" };
145*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL(
146*0a6a1f1dSLionel Sambuc       T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
147f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_H));
148f4a2713aSLionel Sambuc }
149f4a2713aSLionel Sambuc 
TEST(Option,AliasArgs)150f4a2713aSLionel Sambuc TEST(Option, AliasArgs) {
151f4a2713aSLionel Sambuc   TestOptTable T;
152f4a2713aSLionel Sambuc   unsigned MAI, MAC;
153f4a2713aSLionel Sambuc 
154f4a2713aSLionel Sambuc   const char *MyArgs[] = { "-J", "-Joo" };
155*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL(
156*0a6a1f1dSLionel Sambuc       T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
157f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_B));
158f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getAllArgValues(OPT_B)[0], "foo");
159f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getAllArgValues(OPT_B)[1], "bar");
160f4a2713aSLionel Sambuc }
161f4a2713aSLionel Sambuc 
TEST(Option,IgnoreCase)162f4a2713aSLionel Sambuc TEST(Option, IgnoreCase) {
163f4a2713aSLionel Sambuc   TestOptTable T(true);
164f4a2713aSLionel Sambuc   unsigned MAI, MAC;
165f4a2713aSLionel Sambuc 
166f4a2713aSLionel Sambuc   const char *MyArgs[] = { "-a", "-joo" };
167*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL(
168*0a6a1f1dSLionel Sambuc       T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
169f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_A));
170f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_B));
171f4a2713aSLionel Sambuc }
172f4a2713aSLionel Sambuc 
TEST(Option,DoNotIgnoreCase)173f4a2713aSLionel Sambuc TEST(Option, DoNotIgnoreCase) {
174f4a2713aSLionel Sambuc   TestOptTable T;
175f4a2713aSLionel Sambuc   unsigned MAI, MAC;
176f4a2713aSLionel Sambuc 
177f4a2713aSLionel Sambuc   const char *MyArgs[] = { "-a", "-joo" };
178*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL(
179*0a6a1f1dSLionel Sambuc       T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
180f4a2713aSLionel Sambuc   EXPECT_FALSE(AL->hasArg(OPT_A));
181f4a2713aSLionel Sambuc   EXPECT_FALSE(AL->hasArg(OPT_B));
182f4a2713aSLionel Sambuc }
183f4a2713aSLionel Sambuc 
TEST(Option,SlurpEmpty)184f4a2713aSLionel Sambuc TEST(Option, SlurpEmpty) {
185f4a2713aSLionel Sambuc   TestOptTable T;
186f4a2713aSLionel Sambuc   unsigned MAI, MAC;
187f4a2713aSLionel Sambuc 
188f4a2713aSLionel Sambuc   const char *MyArgs[] = { "-A", "-slurp" };
189*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL(
190*0a6a1f1dSLionel Sambuc       T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
191f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_A));
192f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_Slurp));
193f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getAllArgValues(OPT_Slurp).size(), 0U);
194f4a2713aSLionel Sambuc }
195f4a2713aSLionel Sambuc 
TEST(Option,Slurp)196f4a2713aSLionel Sambuc TEST(Option, Slurp) {
197f4a2713aSLionel Sambuc   TestOptTable T;
198f4a2713aSLionel Sambuc   unsigned MAI, MAC;
199f4a2713aSLionel Sambuc 
200f4a2713aSLionel Sambuc   const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
201*0a6a1f1dSLionel Sambuc   std::unique_ptr<InputArgList> AL(
202*0a6a1f1dSLionel Sambuc       T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
203f4a2713aSLionel Sambuc   EXPECT_EQ(AL->size(), 2U);
204f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_A));
205f4a2713aSLionel Sambuc   EXPECT_FALSE(AL->hasArg(OPT_B));
206f4a2713aSLionel Sambuc   EXPECT_TRUE(AL->hasArg(OPT_Slurp));
207f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getAllArgValues(OPT_Slurp).size(), 3U);
208f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[0], "-B");
209f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[1], "--");
210f4a2713aSLionel Sambuc   EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[2], "foo");
211f4a2713aSLionel Sambuc }
212