Skip to content

Commit

Permalink
Option parser: class for consuming a joined arg in addition to all re…
Browse files Browse the repository at this point in the history
…maining args

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266394 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
zmodem committed Apr 15, 2016
1 parent 486e8bb commit 9f34fd5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 1 deletion.
3 changes: 3 additions & 0 deletions include/llvm/Option/OptParser.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
// An option which consumes all remaining arguments if there are any.
def KIND_REMAINING_ARGS : OptionKind<"RemainingArgs">;
// An option which consumes an optional joined argument and any other remaining
// arguments.
def KIND_REMAINING_ARGS_JOINED : OptionKind<"RemainingArgsJoined">;

// Define the option flags.

Expand Down
2 changes: 2 additions & 0 deletions include/llvm/Option/Option.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Option {
JoinedClass,
SeparateClass,
RemainingArgsClass,
RemainingArgsJoinedClass,
CommaJoinedClass,
MultiArgClass,
JoinedOrSeparateClass,
Expand Down Expand Up @@ -150,6 +151,7 @@ class Option {
case MultiArgClass:
case JoinedOrSeparateClass:
case RemainingArgsClass:
case RemainingArgsJoinedClass:
return RenderSeparateStyle;
}
llvm_unreachable("Unexpected kind!");
Expand Down
2 changes: 1 addition & 1 deletion lib/Option/OptTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
break;

case Option::SeparateClass: case Option::JoinedOrSeparateClass:
case Option::RemainingArgsClass:
case Option::RemainingArgsClass: case Option::RemainingArgsJoinedClass:
Name += ' ';
// FALLTHROUGH
case Option::JoinedClass: case Option::CommaJoinedClass:
Expand Down
14 changes: 14 additions & 0 deletions lib/Option/Option.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void Option::print(raw_ostream &O) const {
P(JoinedOrSeparateClass);
P(JoinedAndSeparateClass);
P(RemainingArgsClass);
P(RemainingArgsJoinedClass);
#undef P
}

Expand Down Expand Up @@ -234,6 +235,19 @@ Arg *Option::accept(const ArgList &Args,
A->getValues().push_back(Args.getArgString(Index++));
return A;
}
case RemainingArgsJoinedClass: {
Arg *A = new Arg(UnaliasedOption, Spelling, Index);
if (ArgSize != strlen(Args.getArgString(Index))) {
// An inexact match means there is a joined arg.
A->getValues().push_back(Args.getArgString(Index) + ArgSize);
}
Index++;
while (Index < Args.getNumInputArgStrings() &&
Args.getArgString(Index) != nullptr)
A->getValues().push_back(Args.getArgString(Index++));
return A;
}

default:
llvm_unreachable("Invalid option kind!");
}
Expand Down
51 changes: 51 additions & 0 deletions unittests/Option/OptionParsingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,57 @@ TEST(Option, Slurp) {
EXPECT_EQ("foo", AL.getAllArgValues(OPT_Slurp)[2]);
}

TEST(Option, SlurpJoinedEmpty) {
TestOptTable T;
unsigned MAI, MAC;

const char *MyArgs[] = { "-A", "-slurpjoined" };
InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
EXPECT_TRUE(AL.hasArg(OPT_A));
EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 0U);
}

TEST(Option, SlurpJoinedOneJoined) {
TestOptTable T;
unsigned MAI, MAC;

const char *MyArgs[] = { "-A", "-slurpjoinedfoo" };
InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
EXPECT_TRUE(AL.hasArg(OPT_A));
EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 1U);
EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined)[0], "foo");
}

TEST(Option, SlurpJoinedAndSeparate) {
TestOptTable T;
unsigned MAI, MAC;

const char *MyArgs[] = { "-A", "-slurpjoinedfoo", "bar", "baz" };
InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
EXPECT_TRUE(AL.hasArg(OPT_A));
EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
}

TEST(Option, SlurpJoinedButSeparate) {
TestOptTable T;
unsigned MAI, MAC;

const char *MyArgs[] = { "-A", "-slurpjoined", "foo", "bar", "baz" };
InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
EXPECT_TRUE(AL.hasArg(OPT_A));
EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
}

TEST(Option, FlagAliasToJoined) {
TestOptTable T;
unsigned MAI, MAC;
Expand Down
2 changes: 2 additions & 0 deletions unittests/Option/Opts.td
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ def Joo : Flag<["-"], "Joo">, Alias<B>, AliasArgs<["bar"]>;
def K : Flag<["-"], "K">, Alias<B>;

def Slurp : Option<["-"], "slurp", KIND_REMAINING_ARGS>;

def SlurpJoined : Option<["-"], "slurpjoined", KIND_REMAINING_ARGS_JOINED>;

0 comments on commit 9f34fd5

Please sign in to comment.