]> granicus.if.org Git - clang/commitdiff
Factor out OptTable::ParseArgs, for parsing an entire argument vector.
authorDaniel Dunbar <daniel@zuster.org>
Thu, 19 Nov 2009 06:35:06 +0000 (06:35 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 19 Nov 2009 06:35:06 +0000 (06:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89327 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/OptTable.h
lib/Driver/Driver.cpp
lib/Driver/OptTable.cpp

index 46e3889d5de3263596b2dd2d1ad52e90db6cf9d1..faaeba69e2e6d25055d811b90cf0e288a02d6bae 100644 (file)
@@ -124,7 +124,7 @@ namespace options {
       return getInfo(id).MetaVar;
     }
 
-    /// parseOneArg - Parse a single argument; returning the new argument and
+    /// ParseOneArg - Parse a single argument; returning the new argument and
     /// updating Index.
     ///
     /// \param [in] [out] Index - The current parsing position in the argument
@@ -135,6 +135,27 @@ namespace options {
     /// (in which case Index still points at the conceptual next argument string
     /// to parse).
     Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
+
+    /// ParseArgs - Parse an list of arguments into an InputArgList.
+    ///
+    /// The resulting InputArgList will reference the strings in [ArgBegin,
+    /// ArgEnd), and their lifetime should extend past that of the returned
+    /// InputArgList.
+    ///
+    /// The only error that can occur in this routine is if an argument is
+    /// missing values; in this case \arg MissingArgCount will be non-zero.
+    ///
+    /// \param ArgBegin - The beginning of the argument vector.
+    /// \param ArgEnd - The end of the argument vector.
+    /// \param MissingArgIndex - On error, the index of the option which could
+    /// not be parsed.
+    /// \param MissingArgCount - On error, the number of missing options.
+    /// \return - An InputArgList; on error this will contain all the options
+    /// which could be parsed.
+    InputArgList *ParseArgs(const char **ArgBegin,
+                            const char **ArgEnd,
+                            unsigned &MissingArgIndex,
+                            unsigned &MissingArgCount) const;
   };
 }
 }
index bf9244f28286407fcfd9498a50f623c2ae91cbf6..b40dc27740d045b64f10339f24f3f684c95efc69 100644 (file)
@@ -76,40 +76,23 @@ Driver::~Driver() {
 InputArgList *Driver::ParseArgStrings(const char **ArgBegin,
                                       const char **ArgEnd) {
   llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
-  InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
+  unsigned MissingArgIndex, MissingArgCount;
+  InputArgList *Args = getOpts().ParseArgs(ArgBegin, ArgEnd,
+                                           MissingArgIndex, MissingArgCount);
 
-  // FIXME: Handle '@' args (or at least error on them).
-
-  unsigned Index = 0, End = ArgEnd - ArgBegin;
-  while (Index < End) {
-    // gcc's handling of empty arguments doesn't make sense, but this is not a
-    // common use case. :)
-    //
-    // We just ignore them here (note that other things may still take them as
-    // arguments).
-    if (Args->getArgString(Index)[0] == '\0') {
-      ++Index;
-      continue;
-    }
-
-    unsigned Prev = Index;
-    Arg *A = getOpts().ParseOneArg(*Args, Index);
-    assert(Index > Prev && "Parser failed to consume argument.");
-
-    // Check for missing argument error.
-    if (!A) {
-      assert(Index >= End && "Unexpected parser error.");
-      Diag(clang::diag::err_drv_missing_argument)
-        << Args->getArgString(Prev)
-        << (Index - Prev - 1);
-      break;
-    }
+  // Check for missing argument error.
+  if (MissingArgCount)
+    Diag(clang::diag::err_drv_missing_argument)
+      << Args->getArgString(MissingArgIndex) << MissingArgCount;
 
+  // Check for unsupported options.
+  for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
+       it != ie; ++it) {
+    Arg *A = *it;
     if (A->getOption().isUnsupported()) {
       Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args);
       continue;
     }
-    Args->append(A);
   }
 
   return Args;
index 890907b2a7300da22cbd9a221874ab27cdbbcff6..f68a1d8db77c1c2a4b908e400f808055459f879b 100644 (file)
@@ -220,3 +220,38 @@ Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
 
   return new PositionalArg(TheUnknownOption, Index++);
 }
+
+InputArgList *OptTable::ParseArgs(const char **ArgBegin, const char **ArgEnd,
+                                  unsigned &MissingArgIndex,
+                                  unsigned &MissingArgCount) const {
+  InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
+
+  // FIXME: Handle '@' args (or at least error on them).
+
+  MissingArgIndex = MissingArgCount = 0;
+  unsigned Index = 0, End = ArgEnd - ArgBegin;
+  while (Index < End) {
+    // Ignore empty arguments (other things may still take them as arguments).
+    if (Args->getArgString(Index)[0] == '\0') {
+      ++Index;
+      continue;
+    }
+
+    unsigned Prev = Index;
+    Arg *A = ParseOneArg(*Args, Index);
+    assert(Index > Prev && "Parser failed to consume argument.");
+
+    // Check for missing argument error.
+    if (!A) {
+      assert(Index >= End && "Unexpected parser error.");
+      assert(Index - Prev - 1 && "No missing arguments!");
+      MissingArgIndex = Prev;
+      MissingArgCount = Index - Prev - 1;
+      break;
+    }
+
+    Args->append(A);
+  }
+
+  return Args;
+}