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