forked from OSchip/llvm-project
Factor out OptTable::ParseArgs, for parsing an entire argument vector.
llvm-svn: 89327
This commit is contained in:
parent
2a6c92fcb6
commit
52ed5feee5
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue