[PowerPC] Optimize compares fed by ANDISo
[llvm-core.git] / unittests / Option / OptionParsingTest.cpp
blobeef21ab512094fc301ee7df1ed3283f16350df6c
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 //===----------------------------------------------------------------------===//
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"
16 using namespace llvm;
17 using namespace llvm::opt;
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, VALUES) \
23 OPT_##ID,
24 #include "Opts.inc"
25 LastOption
26 #undef OPTION
29 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
30 #include "Opts.inc"
31 #undef PREFIX
33 enum OptionFlags {
34 OptFlag1 = (1 << 4),
35 OptFlag2 = (1 << 5),
36 OptFlag3 = (1 << 6)
39 static const OptTable::Info InfoTable[] = {
40 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
41 HELPTEXT, METAVAR, VALUES) \
42 {PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, \
43 PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, VALUES},
44 #include "Opts.inc"
45 #undef OPTION
48 namespace {
49 class TestOptTable : public OptTable {
50 public:
51 TestOptTable(bool IgnoreCase = false)
52 : OptTable(InfoTable, IgnoreCase) {}
56 const char *Args[] = {
57 "-A",
58 "-Bhi",
59 "--C=desu",
60 "-C", "bye",
61 "-D,adena",
62 "-E", "apple", "bloom",
63 "-Fblarg",
64 "-F", "42",
65 "-Gchuu", "2"
68 TEST(Option, OptionParsing) {
69 TestOptTable T;
70 unsigned MAI, MAC;
71 InputArgList AL = T.ParseArgs(Args, MAI, MAC);
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));
82 // Check the values.
83 EXPECT_EQ("hi", AL.getLastArgValue(OPT_B));
84 EXPECT_EQ("bye", AL.getLastArgValue(OPT_C));
85 EXPECT_EQ("adena", AL.getLastArgValue(OPT_D));
86 std::vector<std::string> Es = AL.getAllArgValues(OPT_E);
87 EXPECT_EQ("apple", Es[0]);
88 EXPECT_EQ("bloom", Es[1]);
89 EXPECT_EQ("42", AL.getLastArgValue(OPT_F));
90 std::vector<std::string> Gs = AL.getAllArgValues(OPT_G);
91 EXPECT_EQ("chuu", Gs[0]);
92 EXPECT_EQ("2", Gs[1]);
94 // Check the help text.
95 std::string Help;
96 raw_string_ostream RSO(Help);
97 T.PrintHelp(RSO, "test", "title!");
98 EXPECT_NE(std::string::npos, Help.find("-A"));
100 // Test aliases.
101 auto Cs = AL.filtered(OPT_C);
102 ASSERT_NE(Cs.begin(), Cs.end());
103 EXPECT_EQ("desu", StringRef((*Cs.begin())->getValue()));
104 ArgStringList ASL;
105 (*Cs.begin())->render(AL, ASL);
106 ASSERT_EQ(2u, ASL.size());
107 EXPECT_EQ("-C", StringRef(ASL[0]));
108 EXPECT_EQ("desu", StringRef(ASL[1]));
111 TEST(Option, ParseWithFlagExclusions) {
112 TestOptTable T;
113 unsigned MAI, MAC;
115 // Exclude flag3 to avoid parsing as OPT_SLASH_C.
116 InputArgList AL = T.ParseArgs(Args, MAI, MAC,
117 /*FlagsToInclude=*/0,
118 /*FlagsToExclude=*/OptFlag3);
119 EXPECT_TRUE(AL.hasArg(OPT_A));
120 EXPECT_TRUE(AL.hasArg(OPT_C));
121 EXPECT_FALSE(AL.hasArg(OPT_SLASH_C));
123 // Exclude flag1 to avoid parsing as OPT_C.
124 AL = T.ParseArgs(Args, MAI, MAC,
125 /*FlagsToInclude=*/0,
126 /*FlagsToExclude=*/OptFlag1);
127 EXPECT_TRUE(AL.hasArg(OPT_B));
128 EXPECT_FALSE(AL.hasArg(OPT_C));
129 EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));
131 const char *NewArgs[] = { "/C", "foo", "--C=bar" };
132 AL = T.ParseArgs(NewArgs, MAI, MAC);
133 EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));
134 EXPECT_TRUE(AL.hasArg(OPT_C));
135 EXPECT_EQ("foo", AL.getLastArgValue(OPT_SLASH_C));
136 EXPECT_EQ("bar", AL.getLastArgValue(OPT_C));
139 TEST(Option, ParseAliasInGroup) {
140 TestOptTable T;
141 unsigned MAI, MAC;
143 const char *MyArgs[] = { "-I" };
144 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
145 EXPECT_TRUE(AL.hasArg(OPT_H));
148 TEST(Option, AliasArgs) {
149 TestOptTable T;
150 unsigned MAI, MAC;
152 const char *MyArgs[] = { "-J", "-Joo" };
153 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
154 EXPECT_TRUE(AL.hasArg(OPT_B));
155 EXPECT_EQ("foo", AL.getAllArgValues(OPT_B)[0]);
156 EXPECT_EQ("bar", AL.getAllArgValues(OPT_B)[1]);
159 TEST(Option, IgnoreCase) {
160 TestOptTable T(true);
161 unsigned MAI, MAC;
163 const char *MyArgs[] = { "-a", "-joo" };
164 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
165 EXPECT_TRUE(AL.hasArg(OPT_A));
166 EXPECT_TRUE(AL.hasArg(OPT_B));
169 TEST(Option, DoNotIgnoreCase) {
170 TestOptTable T;
171 unsigned MAI, MAC;
173 const char *MyArgs[] = { "-a", "-joo" };
174 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
175 EXPECT_FALSE(AL.hasArg(OPT_A));
176 EXPECT_FALSE(AL.hasArg(OPT_B));
179 TEST(Option, SlurpEmpty) {
180 TestOptTable T;
181 unsigned MAI, MAC;
183 const char *MyArgs[] = { "-A", "-slurp" };
184 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
185 EXPECT_TRUE(AL.hasArg(OPT_A));
186 EXPECT_TRUE(AL.hasArg(OPT_Slurp));
187 EXPECT_EQ(0U, AL.getAllArgValues(OPT_Slurp).size());
190 TEST(Option, Slurp) {
191 TestOptTable T;
192 unsigned MAI, MAC;
194 const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
195 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
196 EXPECT_EQ(AL.size(), 2U);
197 EXPECT_TRUE(AL.hasArg(OPT_A));
198 EXPECT_FALSE(AL.hasArg(OPT_B));
199 EXPECT_TRUE(AL.hasArg(OPT_Slurp));
200 EXPECT_EQ(3U, AL.getAllArgValues(OPT_Slurp).size());
201 EXPECT_EQ("-B", AL.getAllArgValues(OPT_Slurp)[0]);
202 EXPECT_EQ("--", AL.getAllArgValues(OPT_Slurp)[1]);
203 EXPECT_EQ("foo", AL.getAllArgValues(OPT_Slurp)[2]);
206 TEST(Option, SlurpJoinedEmpty) {
207 TestOptTable T;
208 unsigned MAI, MAC;
210 const char *MyArgs[] = { "-A", "-slurpjoined" };
211 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
212 EXPECT_TRUE(AL.hasArg(OPT_A));
213 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
214 EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 0U);
217 TEST(Option, SlurpJoinedOneJoined) {
218 TestOptTable T;
219 unsigned MAI, MAC;
221 const char *MyArgs[] = { "-A", "-slurpjoinedfoo" };
222 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
223 EXPECT_TRUE(AL.hasArg(OPT_A));
224 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
225 EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 1U);
226 EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined)[0], "foo");
229 TEST(Option, SlurpJoinedAndSeparate) {
230 TestOptTable T;
231 unsigned MAI, MAC;
233 const char *MyArgs[] = { "-A", "-slurpjoinedfoo", "bar", "baz" };
234 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
235 EXPECT_TRUE(AL.hasArg(OPT_A));
236 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
237 EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
238 EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
239 EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
240 EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
243 TEST(Option, SlurpJoinedButSeparate) {
244 TestOptTable T;
245 unsigned MAI, MAC;
247 const char *MyArgs[] = { "-A", "-slurpjoined", "foo", "bar", "baz" };
248 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
249 EXPECT_TRUE(AL.hasArg(OPT_A));
250 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
251 EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
252 EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
253 EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
254 EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
257 TEST(Option, FlagAliasToJoined) {
258 TestOptTable T;
259 unsigned MAI, MAC;
261 // Check that a flag alias provides an empty argument to a joined option.
262 const char *MyArgs[] = { "-K" };
263 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
264 EXPECT_EQ(AL.size(), 1U);
265 EXPECT_TRUE(AL.hasArg(OPT_B));
266 EXPECT_EQ(1U, AL.getAllArgValues(OPT_B).size());
267 EXPECT_EQ("", AL.getAllArgValues(OPT_B)[0]);
270 TEST(Option, FindNearest) {
271 TestOptTable T;
272 std::string Nearest;
274 // Options that are too short should not be considered
275 // "near" other short options.
276 EXPECT_GT(T.findNearest("-A", Nearest), 4U);
277 EXPECT_GT(T.findNearest("/C", Nearest), 4U);
278 EXPECT_GT(T.findNearest("--C=foo", Nearest), 4U);
280 // The nearest candidate should mirror the amount of prefix
281 // characters used in the original string.
282 EXPECT_EQ(1U, T.findNearest("-blorb", Nearest));
283 EXPECT_EQ(Nearest, "-blorp");
284 EXPECT_EQ(1U, T.findNearest("--blorm", Nearest));
285 EXPECT_EQ(Nearest, "--blorp");
286 EXPECT_EQ(1U, T.findNearest("-fjormp", Nearest));
287 EXPECT_EQ(Nearest, "--fjormp");
289 // The nearest candidate respects the prefix and value delimiter
290 // of the original string.
291 EXPECT_EQ(1U, T.findNearest("/framb:foo", Nearest));
292 EXPECT_EQ(Nearest, "/cramb:foo");
294 // Flags should be included and excluded as specified.
295 EXPECT_EQ(1U, T.findNearest("-doopf", Nearest, /*FlagsToInclude=*/OptFlag2));
296 EXPECT_EQ(Nearest, "-doopf2");
297 EXPECT_EQ(1U, T.findNearest("-doopf", Nearest,
298 /*FlagsToInclude=*/0,
299 /*FlagsToExclude=*/OptFlag2));
300 EXPECT_EQ(Nearest, "-doopf1");
303 TEST(DISABLED_Option, FindNearestFIXME) {
304 TestOptTable T;
305 std::string Nearest;
307 // FIXME: Options with joined values should not have those values considered
308 // when calculating distance. The test below would fail if run, but it should
309 // succeed.
310 EXPECT_EQ(1U, T.findNearest("--erbghFoo", Nearest));
311 EXPECT_EQ(Nearest, "--ermghFoo");