Skip to content

Commit 54cfc69

Browse files
committed
[CommandLine] Fix cl::ConsumeAfter support with more than one positional argument
Summary: Currently, cl::ConsumeAfter only works for the case that has exactly one positional argument. Without the fix, it skip fulfilling first positional argument and put that additional positional argument in interpreter arguments. Reviewers: bkramer, Mordante, rnk, lattner, beanz, craig.topper Reviewed By: rnk Subscribers: JosephTremoulet, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77242
1 parent 91c10f5 commit 54cfc69

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

llvm/lib/Support/CommandLine.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,9 +1581,9 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
15811581
} else {
15821582
assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());
15831583
unsigned ValNo = 0;
1584-
for (size_t j = 1, e = PositionalOpts.size(); j != e; ++j)
1585-
if (RequiresValue(PositionalOpts[j])) {
1586-
ErrorParsing |= ProvidePositionalOption(PositionalOpts[j],
1584+
for (size_t J = 0, E = PositionalOpts.size(); J != E; ++J)
1585+
if (RequiresValue(PositionalOpts[J])) {
1586+
ErrorParsing |= ProvidePositionalOption(PositionalOpts[J],
15871587
PositionalVals[ValNo].first,
15881588
PositionalVals[ValNo].second);
15891589
ValNo++;

llvm/unittests/Support/CommandLineTest.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,4 +1793,49 @@ static cl::bits<Enum> ExampleBits(
17931793
clEnumValN(Val1, "bits-val1", "The Val1 value"),
17941794
clEnumValN(Val1, "bits-val2", "The Val2 value")));
17951795

1796+
TEST(CommandLineTest, ConsumeAfterOnePositional) {
1797+
cl::ResetCommandLineParser();
1798+
1799+
// input [args]
1800+
StackOption<std::string, cl::opt<std::string>> Input(cl::Positional,
1801+
cl::Required);
1802+
StackOption<std::string, cl::list<std::string>> ExtraArgs(cl::ConsumeAfter);
1803+
1804+
const char *Args[] = {"prog", "input", "arg1", "arg2"};
1805+
1806+
std::string Errs;
1807+
raw_string_ostream OS(Errs);
1808+
EXPECT_TRUE(cl::ParseCommandLineOptions(4, Args, StringRef(), &OS));
1809+
OS.flush();
1810+
EXPECT_EQ("input", Input);
1811+
EXPECT_TRUE(ExtraArgs.size() == 2);
1812+
EXPECT_TRUE(ExtraArgs[0] == "arg1");
1813+
EXPECT_TRUE(ExtraArgs[1] == "arg2");
1814+
EXPECT_TRUE(Errs.empty());
1815+
}
1816+
1817+
TEST(CommandLineTest, ConsumeAfterTwoPositionals) {
1818+
cl::ResetCommandLineParser();
1819+
1820+
// input1 input2 [args]
1821+
StackOption<std::string, cl::opt<std::string>> Input1(cl::Positional,
1822+
cl::Required);
1823+
StackOption<std::string, cl::opt<std::string>> Input2(cl::Positional,
1824+
cl::Required);
1825+
StackOption<std::string, cl::list<std::string>> ExtraArgs(cl::ConsumeAfter);
1826+
1827+
const char *Args[] = {"prog", "input1", "input2", "arg1", "arg2"};
1828+
1829+
std::string Errs;
1830+
raw_string_ostream OS(Errs);
1831+
EXPECT_TRUE(cl::ParseCommandLineOptions(5, Args, StringRef(), &OS));
1832+
OS.flush();
1833+
EXPECT_EQ("input1", Input1);
1834+
EXPECT_EQ("input2", Input2);
1835+
EXPECT_TRUE(ExtraArgs.size() == 2);
1836+
EXPECT_TRUE(ExtraArgs[0] == "arg1");
1837+
EXPECT_TRUE(ExtraArgs[1] == "arg2");
1838+
EXPECT_TRUE(Errs.empty());
1839+
}
1840+
17961841
} // anonymous namespace

0 commit comments

Comments
 (0)