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