diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-11-19 06:35:06 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-11-19 06:35:06 +0000 |
commit | 847abaa62883b6c20005bdd3346ebbd44e46dbac (patch) | |
tree | b27934d88fedf88d4ef1fe9395246b3ee8ae7e3a | |
parent | c720a4d6a69b33bc69729ad269c251bd32215851 (diff) |
Factor out OptTable::ParseArgs, for parsing an entire argument vector.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89327 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Driver/OptTable.h | 23 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 39 | ||||
-rw-r--r-- | lib/Driver/OptTable.cpp | 35 |
3 files changed, 68 insertions, 29 deletions
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h index 46e3889d5d..faaeba69e2 100644 --- a/include/clang/Driver/OptTable.h +++ b/include/clang/Driver/OptTable.h @@ -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; }; } } diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index bf9244f282..b40dc27740 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -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; diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp index 890907b2a7..f68a1d8db7 100644 --- a/lib/Driver/OptTable.cpp +++ b/lib/Driver/OptTable.cpp @@ -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; +} |