diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h --- a/llvm/include/llvm/Option/OptTable.h +++ b/llvm/include/llvm/Option/OptTable.h @@ -62,6 +62,7 @@ ArrayRef OptionInfos; bool IgnoreCase; bool GroupedShortOptions = false; + bool DashDashParsing = false; const char *EnvVar = nullptr; unsigned InputOptionID = 0; @@ -139,6 +140,10 @@ /// Support grouped short options. e.g. -ab represents -a -b. void setGroupedShortOptions(bool Value) { GroupedShortOptions = Value; } + /// Set whether "--" ends option parsing. E.g. -- -a -b gives two positional + /// input. + void setDashDashParsing(bool Value) { DashDashParsing = Value; } + /// Find possible value for given flags. This is used for shell /// autocompletion. /// diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -468,6 +468,16 @@ continue; } + // In DashDashParsing mode, the first "--" stops option scanning and makes + // all trailing arguments as positional. + if (DashDashParsing && Str == "--") { + while (++Index < End) { + Args.append(new Arg(getOption(InputOptionID), Str, Index, + Args.getArgString(Index))); + } + break; + } + unsigned Prev = Index; std::unique_ptr A = GroupedShortOptions ? parseOneArgGrouped(Args, Index) diff --git a/llvm/test/tools/llvm-strings/dash-filename.test b/llvm/test/tools/llvm-strings/dash-filename.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-strings/dash-filename.test @@ -0,0 +1,6 @@ +## Show that -- stops option scanning. + +RUN: rm -rf %t && mkdir %t && cd %t +RUN: echo abcd > -a +RUN: llvm-strings -f -- -a | FileCheck %s +CHECK: -a: abcd diff --git a/llvm/tools/llvm-strings/llvm-strings.cpp b/llvm/tools/llvm-strings/llvm-strings.cpp --- a/llvm/tools/llvm-strings/llvm-strings.cpp +++ b/llvm/tools/llvm-strings/llvm-strings.cpp @@ -62,6 +62,7 @@ public: StringsOptTable() : GenericOptTable(InfoTable) { setGroupedShortOptions(true); + setDashDashParsing(true); } }; } // namespace diff --git a/llvm/unittests/Option/OptionParsingTest.cpp b/llvm/unittests/Option/OptionParsingTest.cpp --- a/llvm/unittests/Option/OptionParsingTest.cpp +++ b/llvm/unittests/Option/OptionParsingTest.cpp @@ -391,6 +391,22 @@ EXPECT_TRUE(AL3.hasArg(OPT_Blorp)); } +TYPED_TEST(OptTableTest, ParseDashDash) { + TypeParam T; + T.setDashDashParsing(true); + unsigned MAI, MAC; + + const char *Args1[] = {"-A", "--", "-A", "--", "-B"}; + InputArgList AL = T.ParseArgs(Args1, MAI, MAC); + EXPECT_TRUE(AL.hasArg(OPT_A)); + EXPECT_FALSE(AL.hasArg(OPT_B)); + const std::vector Input = AL.getAllArgValues(OPT_INPUT); + ASSERT_EQ((size_t)3, Input.size()); + EXPECT_EQ("-A", Input[0]); + EXPECT_EQ("--", Input[1]); + EXPECT_EQ("-B", Input[2]); +} + TYPED_TEST(OptTableTest, UnknownOptions) { TypeParam T; unsigned MAI, MAC;