blob: b0418a71c78665b6d6d77fa1a5ec0e5950751d31 [file] [log] [blame]
Michael J. Spencer41ee0412012-12-05 00:29:32 +00001//===- 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
Reid Klecknerdd44a362013-07-19 18:05:13 +000010#include "llvm/ADT/STLExtras.h"
Michael J. Spencer41ee0412012-12-05 00:29:32 +000011#include "llvm/Option/Arg.h"
12#include "llvm/Option/ArgList.h"
13#include "llvm/Option/Option.h"
Michael J. Spencer41ee0412012-12-05 00:29:32 +000014#include "gtest/gtest.h"
15
16using namespace llvm;
17using namespace llvm::opt;
18
19enum ID {
20 OPT_INVALID = 0, // This is not an option ID.
Hans Wennborg5fdcf862013-07-31 22:44:41 +000021#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
Rui Ueyama8fb5a912013-08-28 20:04:31 +000022 HELPTEXT, METAVAR) OPT_##ID,
Michael J. Spencer41ee0412012-12-05 00:29:32 +000023#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
Reid Klecknerdd44a362013-07-19 18:05:13 +000032enum OptionFlags {
33 OptFlag1 = (1 << 4),
34 OptFlag2 = (1 << 5),
35 OptFlag3 = (1 << 6)
36};
37
Michael J. Spencer41ee0412012-12-05 00:29:32 +000038static const OptTable::Info InfoTable[] = {
Hans Wennborg5fdcf862013-07-31 22:44:41 +000039#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
Michael J. Spencer41ee0412012-12-05 00:29:32 +000040 HELPTEXT, METAVAR) \
41 { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
Hans Wennborg5fdcf862013-07-31 22:44:41 +000042 FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
Michael J. Spencer41ee0412012-12-05 00:29:32 +000043#include "Opts.inc"
44#undef OPTION
45};
46
47namespace {
48class TestOptTable : public OptTable {
49public:
Rui Ueyama8fb5a912013-08-28 20:04:31 +000050 TestOptTable(bool IgnoreCase = false)
Craig Topper8ea23902015-10-21 16:30:42 +000051 : OptTable(InfoTable, IgnoreCase) {}
Michael J. Spencer41ee0412012-12-05 00:29:32 +000052};
53}
54
55const 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
Reid Klecknerdd44a362013-07-19 18:05:13 +000067TEST(Option, OptionParsing) {
Michael J. Spencer41ee0412012-12-05 00:29:32 +000068 TestOptTable T;
69 unsigned MAI, MAC;
David Blaikiedb3d31d2015-06-22 22:06:37 +000070 InputArgList AL = T.ParseArgs(Args, MAI, MAC);
NAKAMURA Takumi07d2f3f2013-01-23 08:30:15 +000071
Michael J. Spencer41ee0412012-12-05 00:29:32 +000072 // Check they all exist.
David Blaikiedb3d31d2015-06-22 22:06:37 +000073 EXPECT_TRUE(AL.hasArg(OPT_A));
74 EXPECT_TRUE(AL.hasArg(OPT_B));
75 EXPECT_TRUE(AL.hasArg(OPT_C));
76 EXPECT_TRUE(AL.hasArg(OPT_D));
77 EXPECT_TRUE(AL.hasArg(OPT_E));
78 EXPECT_TRUE(AL.hasArg(OPT_F));
79 EXPECT_TRUE(AL.hasArg(OPT_G));
Michael J. Spencer41ee0412012-12-05 00:29:32 +000080
81 // Check the values.
Hans Wennborgc940f092016-04-15 00:23:15 +000082 EXPECT_EQ("hi", AL.getLastArgValue(OPT_B));
83 EXPECT_EQ("bye", AL.getLastArgValue(OPT_C));
84 EXPECT_EQ("adena", AL.getLastArgValue(OPT_D));
David Blaikiedb3d31d2015-06-22 22:06:37 +000085 std::vector<std::string> Es = AL.getAllArgValues(OPT_E);
Hans Wennborgc940f092016-04-15 00:23:15 +000086 EXPECT_EQ("apple", Es[0]);
87 EXPECT_EQ("bloom", Es[1]);
88 EXPECT_EQ("42", AL.getLastArgValue(OPT_F));
David Blaikiedb3d31d2015-06-22 22:06:37 +000089 std::vector<std::string> Gs = AL.getAllArgValues(OPT_G);
Hans Wennborgc940f092016-04-15 00:23:15 +000090 EXPECT_EQ("chuu", Gs[0]);
91 EXPECT_EQ("2", Gs[1]);
Michael J. Spencer41ee0412012-12-05 00:29:32 +000092
93 // Check the help text.
94 std::string Help;
95 raw_string_ostream RSO(Help);
96 T.PrintHelp(RSO, "test", "title!");
Hans Wennborgc940f092016-04-15 00:23:15 +000097 EXPECT_NE(std::string::npos, Help.find("-A"));
Michael J. Spencer41ee0412012-12-05 00:29:32 +000098
99 // Test aliases.
David Blaikiedb3d31d2015-06-22 22:06:37 +0000100 arg_iterator Cs = AL.filtered_begin(OPT_C);
Hans Wennborgc940f092016-04-15 00:23:15 +0000101 ASSERT_NE(AL.filtered_end(), Cs);
102 EXPECT_EQ("desu", StringRef((*Cs)->getValue()));
Michael J. Spencer41ee0412012-12-05 00:29:32 +0000103 ArgStringList ASL;
David Blaikiedb3d31d2015-06-22 22:06:37 +0000104 (*Cs)->render(AL, ASL);
Hans Wennborgc940f092016-04-15 00:23:15 +0000105 ASSERT_EQ(2u, ASL.size());
106 EXPECT_EQ("-C", StringRef(ASL[0]));
107 EXPECT_EQ("desu", StringRef(ASL[1]));
Michael J. Spencer41ee0412012-12-05 00:29:32 +0000108}
Reid Klecknerdd44a362013-07-19 18:05:13 +0000109
110TEST(Option, ParseWithFlagExclusions) {
111 TestOptTable T;
112 unsigned MAI, MAC;
Reid Klecknerdd44a362013-07-19 18:05:13 +0000113
114 // Exclude flag3 to avoid parsing as OPT_SLASH_C.
David Blaikiedb3d31d2015-06-22 22:06:37 +0000115 InputArgList AL = T.ParseArgs(Args, MAI, MAC,
116 /*FlagsToInclude=*/0,
117 /*FlagsToExclude=*/OptFlag3);
118 EXPECT_TRUE(AL.hasArg(OPT_A));
119 EXPECT_TRUE(AL.hasArg(OPT_C));
120 EXPECT_FALSE(AL.hasArg(OPT_SLASH_C));
Reid Klecknerdd44a362013-07-19 18:05:13 +0000121
122 // Exclude flag1 to avoid parsing as OPT_C.
David Blaikiedb3d31d2015-06-22 22:06:37 +0000123 AL = T.ParseArgs(Args, MAI, MAC,
124 /*FlagsToInclude=*/0,
125 /*FlagsToExclude=*/OptFlag1);
126 EXPECT_TRUE(AL.hasArg(OPT_B));
127 EXPECT_FALSE(AL.hasArg(OPT_C));
128 EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));
Reid Klecknerdd44a362013-07-19 18:05:13 +0000129
130 const char *NewArgs[] = { "/C", "foo", "--C=bar" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000131 AL = T.ParseArgs(NewArgs, MAI, MAC);
132 EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));
133 EXPECT_TRUE(AL.hasArg(OPT_C));
Hans Wennborgc940f092016-04-15 00:23:15 +0000134 EXPECT_EQ("foo", AL.getLastArgValue(OPT_SLASH_C));
135 EXPECT_EQ("bar", AL.getLastArgValue(OPT_C));
Reid Klecknerdd44a362013-07-19 18:05:13 +0000136}
Hans Wennborg31d6fd82013-07-22 16:18:13 +0000137
138TEST(Option, ParseAliasInGroup) {
139 TestOptTable T;
140 unsigned MAI, MAC;
141
142 const char *MyArgs[] = { "-I" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000143 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
144 EXPECT_TRUE(AL.hasArg(OPT_H));
Hans Wennborg31d6fd82013-07-22 16:18:13 +0000145}
Hans Wennborg5fdcf862013-07-31 22:44:41 +0000146
147TEST(Option, AliasArgs) {
148 TestOptTable T;
149 unsigned MAI, MAC;
150
151 const char *MyArgs[] = { "-J", "-Joo" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000152 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
153 EXPECT_TRUE(AL.hasArg(OPT_B));
Hans Wennborgc940f092016-04-15 00:23:15 +0000154 EXPECT_EQ("foo", AL.getAllArgValues(OPT_B)[0]);
155 EXPECT_EQ("bar", AL.getAllArgValues(OPT_B)[1]);
Hans Wennborg5fdcf862013-07-31 22:44:41 +0000156}
Hans Wennborgb8f34202013-08-02 21:20:27 +0000157
Rui Ueyama8fb5a912013-08-28 20:04:31 +0000158TEST(Option, IgnoreCase) {
159 TestOptTable T(true);
160 unsigned MAI, MAC;
161
162 const char *MyArgs[] = { "-a", "-joo" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000163 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
164 EXPECT_TRUE(AL.hasArg(OPT_A));
165 EXPECT_TRUE(AL.hasArg(OPT_B));
Rui Ueyama8fb5a912013-08-28 20:04:31 +0000166}
167
168TEST(Option, DoNotIgnoreCase) {
169 TestOptTable T;
170 unsigned MAI, MAC;
171
172 const char *MyArgs[] = { "-a", "-joo" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000173 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
174 EXPECT_FALSE(AL.hasArg(OPT_A));
175 EXPECT_FALSE(AL.hasArg(OPT_B));
Rui Ueyama8fb5a912013-08-28 20:04:31 +0000176}
177
Hans Wennborgd505fbf2013-08-13 21:09:50 +0000178TEST(Option, SlurpEmpty) {
179 TestOptTable T;
180 unsigned MAI, MAC;
181
182 const char *MyArgs[] = { "-A", "-slurp" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000183 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
184 EXPECT_TRUE(AL.hasArg(OPT_A));
185 EXPECT_TRUE(AL.hasArg(OPT_Slurp));
Hans Wennborgc940f092016-04-15 00:23:15 +0000186 EXPECT_EQ(0U, AL.getAllArgValues(OPT_Slurp).size());
Hans Wennborgd505fbf2013-08-13 21:09:50 +0000187}
188
189TEST(Option, Slurp) {
190 TestOptTable T;
191 unsigned MAI, MAC;
192
193 const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000194 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
195 EXPECT_EQ(AL.size(), 2U);
196 EXPECT_TRUE(AL.hasArg(OPT_A));
197 EXPECT_FALSE(AL.hasArg(OPT_B));
198 EXPECT_TRUE(AL.hasArg(OPT_Slurp));
Hans Wennborgc940f092016-04-15 00:23:15 +0000199 EXPECT_EQ(3U, AL.getAllArgValues(OPT_Slurp).size());
200 EXPECT_EQ("-B", AL.getAllArgValues(OPT_Slurp)[0]);
201 EXPECT_EQ("--", AL.getAllArgValues(OPT_Slurp)[1]);
202 EXPECT_EQ("foo", AL.getAllArgValues(OPT_Slurp)[2]);
Hans Wennborgd505fbf2013-08-13 21:09:50 +0000203}
Hans Wennborg8d8146f2015-05-04 18:00:13 +0000204
Hans Wennborg40cfde32016-04-15 00:23:30 +0000205TEST(Option, SlurpJoinedEmpty) {
206 TestOptTable T;
207 unsigned MAI, MAC;
208
209 const char *MyArgs[] = { "-A", "-slurpjoined" };
210 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
211 EXPECT_TRUE(AL.hasArg(OPT_A));
212 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
213 EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 0U);
214}
215
216TEST(Option, SlurpJoinedOneJoined) {
217 TestOptTable T;
218 unsigned MAI, MAC;
219
220 const char *MyArgs[] = { "-A", "-slurpjoinedfoo" };
221 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
222 EXPECT_TRUE(AL.hasArg(OPT_A));
223 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
224 EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 1U);
225 EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined)[0], "foo");
226}
227
228TEST(Option, SlurpJoinedAndSeparate) {
229 TestOptTable T;
230 unsigned MAI, MAC;
231
232 const char *MyArgs[] = { "-A", "-slurpjoinedfoo", "bar", "baz" };
233 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
234 EXPECT_TRUE(AL.hasArg(OPT_A));
235 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
236 EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
237 EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
238 EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
239 EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
240}
241
242TEST(Option, SlurpJoinedButSeparate) {
243 TestOptTable T;
244 unsigned MAI, MAC;
245
246 const char *MyArgs[] = { "-A", "-slurpjoined", "foo", "bar", "baz" };
247 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
248 EXPECT_TRUE(AL.hasArg(OPT_A));
249 EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
250 EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
251 EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
252 EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
253 EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
254}
255
Hans Wennborg8d8146f2015-05-04 18:00:13 +0000256TEST(Option, FlagAliasToJoined) {
257 TestOptTable T;
258 unsigned MAI, MAC;
259
260 // Check that a flag alias provides an empty argument to a joined option.
261 const char *MyArgs[] = { "-K" };
David Blaikiedb3d31d2015-06-22 22:06:37 +0000262 InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
263 EXPECT_EQ(AL.size(), 1U);
264 EXPECT_TRUE(AL.hasArg(OPT_B));
Hans Wennborgc940f092016-04-15 00:23:15 +0000265 EXPECT_EQ(1U, AL.getAllArgValues(OPT_B).size());
266 EXPECT_EQ("", AL.getAllArgValues(OPT_B)[0]);
Hans Wennborg8d8146f2015-05-04 18:00:13 +0000267}