[PATCH] D152286: [Option] Support special argument "--"

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 6 09:43:52 PDT 2023


MaskRay created this revision.
MaskRay added reviewers: aaron.ballman, jhenderson, serge-sans-paille, t.p.northover.
Herald added a subscriber: hiraditya.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Many command line option implementations, including getopt_long and our
Support/CommandLine.cpp, support `--` as an end-of-option indicator. All
the trailing arguments are then treated as positional arguments.

Add this feature to LLVMOption and modify llvm-strings to utilize the feature as
an example. In the future, we probably should enable this feature by default and
exclude some tools that handle `DASH_DASH` differently (clang, clang-scan-deps,
etc. I suspect that many are workarounds for LLVMOption not supporting `--` as
a built-in feature).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152286

Files:
  llvm/include/llvm/Option/OptTable.h
  llvm/lib/Option/OptTable.cpp
  llvm/test/tools/llvm-strings/dash-filename.test
  llvm/tools/llvm-strings/llvm-strings.cpp
  llvm/unittests/Option/OptionParsingTest.cpp


Index: llvm/unittests/Option/OptionParsingTest.cpp
===================================================================
--- llvm/unittests/Option/OptionParsingTest.cpp
+++ 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<std::string> 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;
Index: llvm/tools/llvm-strings/llvm-strings.cpp
===================================================================
--- llvm/tools/llvm-strings/llvm-strings.cpp
+++ llvm/tools/llvm-strings/llvm-strings.cpp
@@ -62,6 +62,7 @@
 public:
   StringsOptTable() : GenericOptTable(InfoTable) {
     setGroupedShortOptions(true);
+    setDashDashParsing(true);
   }
 };
 } // namespace
Index: llvm/test/tools/llvm-strings/dash-filename.test
===================================================================
--- /dev/null
+++ 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
Index: llvm/lib/Option/OptTable.cpp
===================================================================
--- llvm/lib/Option/OptTable.cpp
+++ 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<Arg> A = GroupedShortOptions
                  ? parseOneArgGrouped(Args, Index)
Index: llvm/include/llvm/Option/OptTable.h
===================================================================
--- llvm/include/llvm/Option/OptTable.h
+++ llvm/include/llvm/Option/OptTable.h
@@ -62,6 +62,7 @@
   ArrayRef<Info> 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.
   ///


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D152286.528908.patch
Type: text/x-patch
Size: 3125 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230606/8d3f37e4/attachment.bin>


More information about the llvm-commits mailing list