X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FOption%2FOptTable.cpp;h=dca02c17e5388c5cf25bf0399b565a53475ac135;hb=12af22e8cc217827cf4f118b0f5e4ebbda9925ae;hp=e7e83cc724e6f5f79b7bdff84c57c1060414fce8;hpb=055f4e99ffb32462db6fc62f9a306f2865acacb0;p=oota-llvm.git diff --git a/lib/Option/OptTable.cpp b/lib/Option/OptTable.cpp index e7e83cc724e..dca02c17e53 100644 --- a/lib/Option/OptTable.cpp +++ b/lib/Option/OptTable.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include +#include #include using namespace llvm; @@ -26,20 +27,26 @@ namespace opt { // with an exceptions. '\0' comes at the end of the alphabet instead of the // beginning (thus options precede any other options which prefix them). static int StrCmpOptionNameIgnoreCase(const char *A, const char *B) { - size_t I = strlen(A); - size_t J = strlen(B); - // If A and B are the same length, compare them ignoring case. - if (I == J) - return strcasecmp(A, B); - // A is shorter than B. In this case A is less than B only when it's - // lexicographically less than B. strncasecmp() == 0 means A is a prefix of B, - // which in turn means A should appear *after* B. - if (I < J) - return strncasecmp(A, B, I) < 0 ? -1 : 1; - // Otherwise, vice versa. - return strncasecmp(A, B, J) <= 0 ? -1 : 1; + const char *X = A, *Y = B; + char a = tolower(*A), b = tolower(*B); + while (a == b) { + if (a == '\0') + return 0; + + a = tolower(*++X); + b = tolower(*++Y); + } + + if (a == '\0') // A is a prefix of B. + return 1; + if (b == '\0') // B is a prefix of A. + return -1; + + // Otherwise lexicographic. + return (a < b) ? -1 : 1; } +#ifndef NDEBUG static int StrCmpOptionName(const char *A, const char *B) { if (int N = StrCmpOptionNameIgnoreCase(A, B)) return N; @@ -55,7 +62,7 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { for (const char * const *APre = A.Prefixes, * const *BPre = B.Prefixes; - *APre != 0 && *BPre != 0; ++APre, ++BPre) { + *APre != nullptr && *BPre != nullptr; ++APre, ++BPre){ if (int N = StrCmpOptionName(*APre, *BPre)) return N < 0; } @@ -66,14 +73,12 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { "Unexpected classes for options with same name."); return B.Kind == Option::JoinedClass; } +#endif // Support lower_bound between info and an option name. static inline bool operator<(const OptTable::Info &I, const char *Name) { return StrCmpOptionNameIgnoreCase(I.Name, Name) < 0; } -static inline bool operator<(const char *Name, const OptTable::Info &I) { - return StrCmpOptionNameIgnoreCase(Name, I.Name) < 0; -} } } @@ -131,7 +136,7 @@ OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos, for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions() + 1; i != e; ++i) { if (const char *const *P = getInfo(i).Prefixes) { - for (; *P != 0; ++P) { + for (; *P != nullptr; ++P) { PrefixesUnion.insert(*P); } } @@ -155,7 +160,7 @@ OptTable::~OptTable() { const Option OptTable::getOption(OptSpecifier Opt) const { unsigned id = Opt.getID(); if (id == 0) - return Option(0, 0); + return Option(nullptr, nullptr); assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID."); return Option(&getInfo(id), this); } @@ -170,22 +175,15 @@ static bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg) { return true; } -// Returns true if X starts with Y, ignoring case. -static bool startsWithIgnoreCase(StringRef X, StringRef Y) { - if (X.size() < Y.size()) - return false; - return X.substr(0, Y.size()).equals_lower(Y); -} - /// \returns Matched size. 0 means no match. static unsigned matchOption(const OptTable::Info *I, StringRef Str, bool IgnoreCase) { - for (const char * const *Pre = I->Prefixes; *Pre != 0; ++Pre) { + for (const char * const *Pre = I->Prefixes; *Pre != nullptr; ++Pre) { StringRef Prefix(*Pre); if (Str.startswith(Prefix)) { StringRef Rest = Str.substr(Prefix.size()); bool Matched = IgnoreCase - ? startsWithIgnoreCase(Rest, I->Name) + ? Rest.startswith_lower(I->Name) : Rest.startswith(I->Name); if (Matched) return Prefix.size() + StringRef(I->Name).size(); @@ -242,7 +240,7 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, // Otherwise, see if this argument was missing values. if (Prev != Index) - return 0; + return nullptr; } // If we failed to find an option and this arg started with /, then it's @@ -266,6 +264,11 @@ InputArgList *OptTable::ParseArgs(const char *const *ArgBegin, MissingArgIndex = MissingArgCount = 0; unsigned Index = 0, End = ArgEnd - ArgBegin; while (Index < End) { + // Ingore nullptrs, they are response file's EOL markers + if (Args->getArgString(Index) == nullptr) { + ++Index; + continue; + } // Ignore empty arguments (other things may still take them as arguments). StringRef Str = Args->getArgString(Index); if (Str == "") { @@ -302,7 +305,18 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) { llvm_unreachable("Invalid option with help text."); case Option::MultiArgClass: - llvm_unreachable("Cannot print metavar for this kind of option."); + if (const char *MetaVarName = Opts.getOptionMetaVar(Id)) { + // For MultiArgs, metavar is full list of all argument names. + Name += ' '; + Name += MetaVarName; + } + else { + // For MultiArgs, if metavar not supplied, print N times. + for (unsigned i=0, e=O.getNumArgs(); i< e; ++i) { + Name += " "; + } + } + break; case Option::FlagClass: break;