[llvm-commits] [llvm] r62372 - in /llvm/trunk: docs/CommandLine.html include/llvm/Support/CommandLine.h lib/Support/CommandLine.cpp

Mikhail Glushenkov foldr at codedgers.com
Fri Jan 16 14:54:19 PST 2009


Author: foldr
Date: Fri Jan 16 16:54:19 2009
New Revision: 62372

URL: http://llvm.org/viewvc/llvm-project?rev=62372&view=rev
Log:
Support for multi-valued options in CommandLine

Makes possible to specify options that take multiple arguments (a-la
-sectalign on Darwin). See documentation for details.

Modified:
    llvm/trunk/docs/CommandLine.html
    llvm/trunk/include/llvm/Support/CommandLine.h
    llvm/trunk/lib/Support/CommandLine.cpp

Modified: llvm/trunk/docs/CommandLine.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandLine.html?rev=62372&r1=62371&r2=62372&view=diff

==============================================================================
--- llvm/trunk/docs/CommandLine.html (original)
+++ llvm/trunk/docs/CommandLine.html Fri Jan 16 16:54:19 2009
@@ -1146,6 +1146,17 @@
 this macro, the first argument is the enum value, the second is the flag name,
 and the second is the description.</li>
 
+<li><a name="cl::multi_val">The <b><tt>cl::multi_val</tt></b></a>
+attribute specifies that this option takes has multiple values
+(example: <tt>-sectalign segname sectname sectvalue</tt>). This
+attribute takes one unsigned argument - the number of values for the
+option. This attribute is valid only on <tt>cl::list</tt> options (and
+will fail with compile error if you try to use it with other option
+types). It is allowed to use all of the usual modifiers on
+multi-valued options (besides <tt>cl::ValueDisallowed</tt>,
+obviously).</li>
+
+
 </ol>
 
 You will get a compile time error if you try to use cl::values with a parser

Modified: llvm/trunk/include/llvm/Support/CommandLine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=62372&r1=62371&r2=62372&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/CommandLine.h (original)
+++ llvm/trunk/include/llvm/Support/CommandLine.h Fri Jan 16 16:54:19 2009
@@ -155,6 +155,7 @@
   int NumOccurrences;     // The number of times specified
   int Flags;              // Flags for the argument
   unsigned Position;      // Position of last occurrence of the option
+  unsigned AdditionalVals;// Greater than 0 for multi-valued option.
   Option *NextRegistered; // Singly linked list of registered options.
 public:
   const char *ArgStr;     // The argument string itself (ex: "help", "o")
@@ -179,6 +180,7 @@
     return Flags & MiscMask;
   }
   inline unsigned getPosition() const { return Position; }
+  inline unsigned getNumAdditionalVals() const { return AdditionalVals; }
 
   // hasArgStr - Return true if the argstr != ""
   bool hasArgStr() const { return ArgStr[0] != 0; }
@@ -206,11 +208,14 @@
 protected:
   explicit Option(unsigned DefaultFlags)
     : NumOccurrences(0), Flags(DefaultFlags | NormalFormatting), Position(0),
-      NextRegistered(0), ArgStr(""), HelpStr(""), ValueStr("") {
+      AdditionalVals(0), NextRegistered(0),
+      ArgStr(""), HelpStr(""), ValueStr("") {
     assert(getNumOccurrencesFlag() != 0 &&
            getOptionHiddenFlag() != 0 && "Not all default flags specified!");
   }
 
+  inline void setNumAdditionalVals(unsigned n)
+  { AdditionalVals = n; }
 public:
   // addArgument - Register this argument with the commandline system.
   //
@@ -231,7 +236,7 @@
   // addOccurrence - Wrapper around handleOccurrence that enforces Flags
   //
   bool addOccurrence(unsigned pos, const char *ArgName,
-                     const std::string &Value);
+                     const std::string &Value, bool MultiArg = false);
 
   // Prints option name followed by message.  Always returns true.
   bool error(std::string Message, const char *ArgName = 0);
@@ -1000,6 +1005,10 @@
     return Positions[optnum];
   }
 
+  void setNumAdditionalVals(unsigned n) {
+    Option::setNumAdditionalVals(n);
+  }
+
   // One option...
   template<class M0t>
   explicit list(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
@@ -1065,6 +1074,16 @@
   }
 };
 
+// multi_arg - Modifier to set the number of additional values.
+struct multi_val {
+  unsigned AdditionalVals;
+  explicit multi_val(unsigned N) : AdditionalVals(N) {}
+
+  template <typename D, typename S, typename P>
+  void apply(list<D, S, P> &L) const { L.setNumAdditionalVals(AdditionalVals); }
+};
+
+
 //===----------------------------------------------------------------------===//
 // bits_storage class
 

Modified: llvm/trunk/lib/Support/CommandLine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=62372&r1=62371&r2=62372&view=diff

==============================================================================
--- llvm/trunk/lib/Support/CommandLine.cpp (original)
+++ llvm/trunk/lib/Support/CommandLine.cpp Fri Jan 16 16:54:19 2009
@@ -172,6 +172,9 @@
 static inline bool ProvideOption(Option *Handler, const char *ArgName,
                                  const char *Value, int argc, char **argv,
                                  int &i) {
+  // Is this a multi-argument option?
+  unsigned NumAdditionalVals = Handler->getNumAdditionalVals();
+
   // Enforce value requirements
   switch (Handler->getValueExpectedFlag()) {
   case ValueRequired:
@@ -184,6 +187,10 @@
     }
     break;
   case ValueDisallowed:
+    if (NumAdditionalVals > 0)
+      return Handler->error(": multi-valued option specified"
+      " with ValueDisallowed modifier!");
+
     if (Value)
       return Handler->error(" does not allow a value! '" +
                             std::string(Value) + "' specified.");
@@ -198,8 +205,35 @@
     break;
   }
 
-  // Run the handler now!
-  return Handler->addOccurrence(i, ArgName, Value ? Value : "");
+  // If this isn't a multi-arg option, just run the handler.
+  if (NumAdditionalVals == 0) {
+    return Handler->addOccurrence(i, ArgName, Value ? Value : "");
+  }
+  // If it is, run the handle several times.
+  else {
+    bool MultiArg = false;
+
+    if (Value) {
+      if (Handler->addOccurrence(i, ArgName, Value, MultiArg))
+        return true;
+      --NumAdditionalVals;
+      MultiArg = true;
+    }
+
+    while (NumAdditionalVals > 0) {
+
+      if (i+1 < argc) {
+        Value = argv[++i];
+      } else {
+        return Handler->error(": not enough values!");
+      }
+      if (Handler->addOccurrence(i, ArgName, Value, MultiArg))
+        return true;
+      MultiArg = true;
+      --NumAdditionalVals;
+    }
+    return false;
+  }
 }
 
 static bool ProvidePositionalOption(Option *Handler, const std::string &Arg,
@@ -738,8 +772,10 @@
 }
 
 bool Option::addOccurrence(unsigned pos, const char *ArgName,
-                           const std::string &Value) {
-  NumOccurrences++;   // Increment the number of times we have been seen
+                           const std::string &Value,
+                           bool MultiArg) {
+  if (!MultiArg)
+    NumOccurrences++;   // Increment the number of times we have been seen
 
   switch (getNumOccurrencesFlag()) {
   case Optional:





More information about the llvm-commits mailing list