#include "llvm/ADT/Twine.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
}
}
-Option::~Option() {
-}
-
-void Option::dump() const {
- llvm::errs() << "<";
+void Option::print(raw_ostream &O) const {
+ O << "<";
switch (getKind()) {
-#define P(N) case N: llvm::errs() << #N; break
+#define P(N) case N: O << #N; break
P(GroupClass);
P(InputClass);
P(UnknownClass);
P(MultiArgClass);
P(JoinedOrSeparateClass);
P(JoinedAndSeparateClass);
+ P(RemainingArgsClass);
#undef P
}
if (Info->Prefixes) {
- llvm::errs() << " Prefixes:[";
- for (const char * const *Pre = Info->Prefixes; *Pre != 0; ++Pre) {
- llvm::errs() << '"' << *Pre << (*(Pre + 1) == 0 ? "\"" : "\", ");
+ O << " Prefixes:[";
+ for (const char *const *Pre = Info->Prefixes; *Pre != nullptr; ++Pre) {
+ O << '"' << *Pre << (*(Pre + 1) == nullptr ? "\"" : "\", ");
}
- llvm::errs() << ']';
+ O << ']';
}
- llvm::errs() << " Name:\"" << getName() << '"';
+ O << " Name:\"" << getName() << '"';
const Option Group = getGroup();
if (Group.isValid()) {
- llvm::errs() << " Group:";
- Group.dump();
+ O << " Group:";
+ Group.print(O);
}
const Option Alias = getAlias();
if (Alias.isValid()) {
- llvm::errs() << " Alias:";
- Alias.dump();
+ O << " Alias:";
+ Alias.print(O);
}
if (getKind() == MultiArgClass)
- llvm::errs() << " NumArgs:" << getNumArgs();
+ O << " NumArgs:" << getNumArgs();
- llvm::errs() << ">\n";
+ O << ">\n";
}
+void Option::dump() const { print(dbgs()); }
+
bool Option::matches(OptSpecifier Opt) const {
// Aliases are never considered in matching, look through them.
const Option Alias = getAlias();
switch (getKind()) {
case FlagClass: {
if (ArgSize != strlen(Args.getArgString(Index)))
- return 0;
+ return nullptr;
Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
if (getAliasArgs()) {
Val += strlen(Val) + 1;
}
}
+
+ if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs())
+ // A Flag alias for a Joined option must provide an argument.
+ A->getValues().push_back("");
+
return A;
}
case JoinedClass: {
// Matches iff this is an exact match.
// FIXME: Avoid strlen.
if (ArgSize != strlen(Args.getArgString(Index)))
- return 0;
+ return nullptr;
Index += 2;
- if (Index > Args.getNumInputArgStrings())
- return 0;
+ if (Index > Args.getNumInputArgStrings() ||
+ Args.getArgString(Index - 1) == nullptr)
+ return nullptr;
return new Arg(UnaliasedOption, Spelling,
Index - 2, Args.getArgString(Index - 1));
// Matches iff this is an exact match.
// FIXME: Avoid strlen.
if (ArgSize != strlen(Args.getArgString(Index)))
- return 0;
+ return nullptr;
Index += 1 + getNumArgs();
if (Index > Args.getNumInputArgStrings())
- return 0;
+ return nullptr;
Arg *A = new Arg(UnaliasedOption, Spelling, Index - 1 - getNumArgs(),
Args.getArgString(Index - getNumArgs()));
// Otherwise it must be separate.
Index += 2;
- if (Index > Args.getNumInputArgStrings())
- return 0;
+ if (Index > Args.getNumInputArgStrings() ||
+ Args.getArgString(Index - 1) == nullptr)
+ return nullptr;
return new Arg(UnaliasedOption, Spelling,
Index - 2, Args.getArgString(Index - 1));
case JoinedAndSeparateClass:
// Always matches.
Index += 2;
- if (Index > Args.getNumInputArgStrings())
- return 0;
+ if (Index > Args.getNumInputArgStrings() ||
+ Args.getArgString(Index - 1) == nullptr)
+ return nullptr;
return new Arg(UnaliasedOption, Spelling, Index - 2,
Args.getArgString(Index - 2) + ArgSize,
Args.getArgString(Index - 1));
+ case RemainingArgsClass: {
+ // Matches iff this is an exact match.
+ // FIXME: Avoid strlen.
+ if (ArgSize != strlen(Args.getArgString(Index)))
+ return nullptr;
+ Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
+ while (Index < Args.getNumInputArgStrings() &&
+ Args.getArgString(Index) != nullptr)
+ A->getValues().push_back(Args.getArgString(Index++));
+ return A;
+ }
default:
llvm_unreachable("Invalid option kind!");
}