196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer//===--- OptTable.cpp - Option Table Implementation -----------------------===// 296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// 396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// The LLVM Compiler Infrastructure 496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// 596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// This file is distributed under the University of Illinois Open Source 696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// License. See LICENSE.TXT for details. 796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// 896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer//===----------------------------------------------------------------------===// 996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 1096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#include "llvm/Option/OptTable.h" 1196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#include "llvm/Option/Arg.h" 1296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#include "llvm/Option/ArgList.h" 1396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#include "llvm/Option/Option.h" 1496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#include "llvm/Support/ErrorHandling.h" 1558a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth#include "llvm/Support/raw_ostream.h" 1696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#include <algorithm> 1796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#include <map> 1896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 1996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerusing namespace llvm; 2096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerusing namespace llvm::opt; 2196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 2296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// Ordering on Info. The ordering is *almost* lexicographic, with two 2396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// exceptions. First, '\0' comes at the end of the alphabet instead of 2496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// the beginning (thus options precede any other options which prefix 2596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// them). Second, for options with the same name, the less permissive 2696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// version should come first; a Flag option should precede a Joined 2796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// option, for example. 2896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 2996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic int StrCmpOptionName(const char *A, const char *B) { 3096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer char a = *A, b = *B; 3196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer while (a == b) { 3296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (a == '\0') 3396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return 0; 3496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 3596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer a = *++A; 3696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer b = *++B; 3796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 3896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 3996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (a == '\0') // A is a prefix of B. 4096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return 1; 4196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (b == '\0') // B is a prefix of A. 4296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return -1; 4396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 4496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Otherwise lexicographic. 4596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return (a < b) ? -1 : 1; 4696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 4796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 4896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencernamespace llvm { 4996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencernamespace opt { 5096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 5196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) { 5296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (&A == &B) 5396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return false; 5496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 5596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (int N = StrCmpOptionName(A.Name, B.Name)) 5696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return N == -1; 5796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 5896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (const char * const *APre = A.Prefixes, 5996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer * const *BPre = B.Prefixes; 6096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer *APre != 0 && *BPre != 0; ++APre, ++BPre) { 6196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (int N = StrCmpOptionName(*APre, *BPre)) 6296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return N == -1; 6396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 6496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 6596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Names are the same, check that classes are in order; exactly one 6696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // should be joined, and it should succeed the other. 6796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert(((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) && 6896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer "Unexpected classes for options with same name."); 6996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return B.Kind == Option::JoinedClass; 7096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 7196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 7296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer// Support lower_bound between info and an option name. 7396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic inline bool operator<(const OptTable::Info &I, const char *Name) { 7496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return StrCmpOptionName(I.Name, Name) == -1; 7596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 7696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic inline bool operator<(const char *Name, const OptTable::Info &I) { 7796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return StrCmpOptionName(Name, I.Name) == -1; 7896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 7996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 8096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 8196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 8296a564f2beec8c1930f0640844eec433e03bbce8Michael J. SpencerOptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {} 8396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 8496a564f2beec8c1930f0640844eec433e03bbce8Michael J. SpencerOptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos) 8596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer : OptionInfos(_OptionInfos), 8696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer NumOptionInfos(_NumOptionInfos), 8796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer TheInputOptionID(0), 8896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer TheUnknownOptionID(0), 8996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer FirstSearchableIndex(0) 9096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer{ 9196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Explicitly zero initialize the error to work around a bug in array 9296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // value-initialization on MinGW with gcc 4.3.5. 9396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 9496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Find start of normal options. 9596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 9696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned Kind = getInfo(i + 1).Kind; 9796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Kind == Option::InputClass) { 9896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert(!TheInputOptionID && "Cannot have multiple input options!"); 9996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer TheInputOptionID = getInfo(i + 1).ID; 10096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } else if (Kind == Option::UnknownClass) { 10196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert(!TheUnknownOptionID && "Cannot have multiple unknown options!"); 10296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer TheUnknownOptionID = getInfo(i + 1).ID; 10396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } else if (Kind != Option::GroupClass) { 10496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer FirstSearchableIndex = i; 10596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer break; 10696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 10796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 10896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert(FirstSearchableIndex != 0 && "No searchable options?"); 10996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 11096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#ifndef NDEBUG 11196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Check that everything after the first searchable option is a 11296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // regular option class. 11396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (unsigned i = FirstSearchableIndex, e = getNumOptions(); i != e; ++i) { 11496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Option::OptionClass Kind = (Option::OptionClass) getInfo(i + 1).Kind; 11596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert((Kind != Option::InputClass && Kind != Option::UnknownClass && 11696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Kind != Option::GroupClass) && 11796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer "Special options should be defined first!"); 11896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 11996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 12096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Check that options are in order. 12196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions(); i != e; ++i){ 12296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (!(getInfo(i) < getInfo(i + 1))) { 12396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer getOption(i).dump(); 12496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer getOption(i + 1).dump(); 12596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer llvm_unreachable("Options are not in order!"); 12696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 12796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 12896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer#endif 12996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 13096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Build prefixes. 13196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions() + 1; 13296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer i != e; ++i) { 13396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (const char *const *P = getInfo(i).Prefixes) { 13496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (; *P != 0; ++P) { 13596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer PrefixesUnion.insert(*P); 13696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 13796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 13896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 13996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 14096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Build prefix chars. 14196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (llvm::StringSet<>::const_iterator I = PrefixesUnion.begin(), 14296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer E = PrefixesUnion.end(); I != E; ++I) { 14396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer StringRef Prefix = I->getKey(); 14496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (StringRef::const_iterator C = Prefix.begin(), CE = Prefix.end(); 14596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer C != CE; ++C) 14696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (std::find(PrefixChars.begin(), PrefixChars.end(), *C) 14796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer == PrefixChars.end()) 14896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer PrefixChars.push_back(*C); 14996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 15096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 15196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 15296a564f2beec8c1930f0640844eec433e03bbce8Michael J. SpencerOptTable::~OptTable() { 15396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 15496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 15596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerconst Option OptTable::getOption(OptSpecifier Opt) const { 15696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned id = Opt.getID(); 15796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (id == 0) 15896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return Option(0, 0); 15996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID."); 16096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return Option(&getInfo(id), this); 16196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 16296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 16396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg) { 16496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Arg == "-") 16596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return true; 16696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (llvm::StringSet<>::const_iterator I = Prefixes.begin(), 16796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer E = Prefixes.end(); I != E; ++I) 16896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Arg.startswith(I->getKey())) 16996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return false; 17096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return true; 17196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 17296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 17396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer/// \returns Matched size. 0 means no match. 17496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic unsigned matchOption(const OptTable::Info *I, StringRef Str) { 17596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (const char * const *Pre = I->Prefixes; *Pre != 0; ++Pre) { 17696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer StringRef Prefix(*Pre); 17796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Str.startswith(Prefix) && Str.substr(Prefix.size()).startswith(I->Name)) 17896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return Prefix.size() + StringRef(I->Name).size(); 17996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 18096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return 0; 18196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 18296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 183a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid KlecknerArg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index, 184a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner unsigned FlagsToInclude, 185a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner unsigned FlagsToExclude) const { 18696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned Prev = Index; 18796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const char *Str = Args.getArgString(Index); 18896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 18996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Anything that doesn't start with PrefixesUnion is an input, as is '-' 19096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // itself. 19196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (isInput(PrefixesUnion, Str)) 19296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return new Arg(getOption(TheInputOptionID), Str, Index++, Str); 19396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 19496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const Info *Start = OptionInfos + FirstSearchableIndex; 19596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const Info *End = OptionInfos + getNumOptions(); 19696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer StringRef Name = StringRef(Str).ltrim(PrefixChars); 19796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 19896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Search for the first next option which could be a prefix. 19996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Start = std::lower_bound(Start, End, Name.data()); 20096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 20196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Options are stored in sorted order, with '\0' at the end of the 20296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // alphabet. Since the only options which can accept a string must 20396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // prefix it, we iteratively search for the next option which could 20496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // be a prefix. 20596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // 20696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // FIXME: This is searching much more than necessary, but I am 20796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // blanking on the simplest way to make it fast. We can solve this 20896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // problem when we move to TableGen. 20996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (; Start != End; ++Start) { 21096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned ArgSize = 0; 21196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Scan for first option which is a proper prefix. 21296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (; Start != End; ++Start) 21396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if ((ArgSize = matchOption(Start, Str))) 21496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer break; 21596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Start == End) 21696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer break; 21796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 218a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner Option Opt(Start, this); 219a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner 220a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner if (FlagsToInclude && !Opt.hasFlag(FlagsToInclude)) 221a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner continue; 222a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner if (Opt.hasFlag(FlagsToExclude)) 223a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner continue; 224a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner 22596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // See if this option matches. 226a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner if (Arg *A = Opt.accept(Args, Index, ArgSize)) 22796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return A; 22896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 22996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Otherwise, see if this argument was missing values. 23096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Prev != Index) 23196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return 0; 23296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 23396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 234a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner // If we failed to find an option and this arg started with /, then it's 235a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner // probably an input path. 236a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner if (Str[0] == '/') 237a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner return new Arg(getOption(TheInputOptionID), Str, Index++, Str); 238a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner 23996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return new Arg(getOption(TheUnknownOptionID), Str, Index++, Str); 24096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 24196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 242a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid KlecknerInputArgList *OptTable::ParseArgs(const char *const *ArgBegin, 243a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner const char *const *ArgEnd, 24496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned &MissingArgIndex, 245a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner unsigned &MissingArgCount, 246a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner unsigned FlagsToInclude, 247a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner unsigned FlagsToExclude) const { 24896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer InputArgList *Args = new InputArgList(ArgBegin, ArgEnd); 24996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 25096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // FIXME: Handle '@' args (or at least error on them). 25196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 25296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer MissingArgIndex = MissingArgCount = 0; 25396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned Index = 0, End = ArgEnd - ArgBegin; 25496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer while (Index < End) { 25596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Ignore empty arguments (other things may still take them as arguments). 2566bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg StringRef Str = Args->getArgString(Index); 2576bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg if (Str == "") { 25896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer ++Index; 25996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer continue; 26096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 26196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 2626bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg if (Str == "--") { 2636bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg // Everything after -- is a filename. 2646bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg ++Index; 2656bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg 2666bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg assert(TheInputOptionID != 0 && "Invalid input option ID."); 2676bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg while (Index < End) { 2686bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg Args->append(new Arg(getOption(TheInputOptionID), 2696bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg Args->getArgString(Index), Index, 2706bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg Args->getArgString(Index))); 2716bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg ++Index; 2726bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg } 2736bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg break; 2746bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg } 2756bf104b165cec9c14dacf10bf3380eeb32c278d7Hans Wennborg 27696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned Prev = Index; 277a2549d382789fa33b5541708b2e4cf39e8bf56c9Reid Kleckner Arg *A = ParseOneArg(*Args, Index, FlagsToInclude, FlagsToExclude); 27896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert(Index > Prev && "Parser failed to consume argument."); 27996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 28096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Check for missing argument error. 28196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (!A) { 28296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert(Index >= End && "Unexpected parser error."); 28396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer assert(Index - Prev - 1 && "No missing arguments!"); 28496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer MissingArgIndex = Prev; 28596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer MissingArgCount = Index - Prev - 1; 28696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer break; 28796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 28896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 28996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Args->append(A); 29096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 29196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 29296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return Args; 29396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 29496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 29596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) { 29696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const Option O = Opts.getOption(Id); 29796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer std::string Name = O.getPrefixedName(); 29896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 29996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Add metavar, if used. 30096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer switch (O.getKind()) { 30196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer case Option::GroupClass: case Option::InputClass: case Option::UnknownClass: 30296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer llvm_unreachable("Invalid option with help text."); 30396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 30496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer case Option::MultiArgClass: 30596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer llvm_unreachable("Cannot print metavar for this kind of option."); 30696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 30796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer case Option::FlagClass: 30896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer break; 30996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 31096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer case Option::SeparateClass: case Option::JoinedOrSeparateClass: 31196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Name += ' '; 31296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // FALLTHROUGH 31396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer case Option::JoinedClass: case Option::CommaJoinedClass: 31496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer case Option::JoinedAndSeparateClass: 31596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (const char *MetaVarName = Opts.getOptionMetaVar(Id)) 31696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Name += MetaVarName; 31796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer else 31896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Name += "<value>"; 31996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer break; 32096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 32196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 32296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return Name; 32396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 32496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 32596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic void PrintHelpOptionList(raw_ostream &OS, StringRef Title, 32696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer std::vector<std::pair<std::string, 32796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const char*> > &OptionHelp) { 32896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS << Title << ":\n"; 32996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 33096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Find the maximum option length. 33196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned OptionFieldWidth = 0; 33296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) { 33396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Skip titles. 33496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (!OptionHelp[i].second) 33596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer continue; 33696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 33796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Limit the amount of padding we are willing to give up for alignment. 33896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned Length = OptionHelp[i].first.size(); 33996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Length <= 23) 34096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OptionFieldWidth = std::max(OptionFieldWidth, Length); 34196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 34296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 34396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const unsigned InitialPad = 2; 34496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) { 34596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const std::string &Option = OptionHelp[i].first; 34696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer int Pad = OptionFieldWidth - int(Option.size()); 34796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS.indent(InitialPad) << Option; 34896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 34996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Break on long option names. 35096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (Pad < 0) { 35196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS << "\n"; 35296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer Pad = OptionFieldWidth + InitialPad; 35396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 35496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS.indent(Pad + 1) << OptionHelp[i].second << '\n'; 35596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 35696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 35796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 35896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencerstatic const char *getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id) { 35996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned GroupID = Opts.getOptionGroupID(Id); 36096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 36196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // If not in a group, return the default help group. 36296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (!GroupID) 36396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return "OPTIONS"; 36496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 36596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Abuse the help text of the option groups to store the "help group" 36696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // name. 36796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // 36896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // FIXME: Split out option groups. 36996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (const char *GroupHelp = Opts.getOptionHelpText(GroupID)) 37096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return GroupHelp; 37196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 37296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Otherwise keep looking. 37396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer return getOptionHelpGroup(Opts, GroupID); 37496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 37596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 3761ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Klecknervoid OptTable::PrintHelp(raw_ostream &OS, const char *Name, const char *Title, 3771ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner bool ShowHidden) const { 3781ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner PrintHelp(OS, Name, Title, /*Include*/ 0, /*Exclude*/ 3791ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner (ShowHidden ? 0 : HelpHidden)); 3801ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner} 3811ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner 3821ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner 3831ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Klecknervoid OptTable::PrintHelp(raw_ostream &OS, const char *Name, const char *Title, 3841ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner unsigned FlagsToInclude, 3851ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner unsigned FlagsToExclude) const { 38696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS << "OVERVIEW: " << Title << "\n"; 38796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS << '\n'; 38896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS << "USAGE: " << Name << " [options] <inputs>\n"; 38996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS << '\n'; 39096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 39196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // Render help text into a map of group-name to a list of (option, help) 39296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // pairs. 39396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer typedef std::map<std::string, 39496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer std::vector<std::pair<std::string, const char*> > > helpmap_ty; 39596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer helpmap_ty GroupedOptionHelp; 39696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 39796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 39896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer unsigned Id = i + 1; 39996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 40096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer // FIXME: Split out option groups. 40196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (getOptionKind(Id) == Option::GroupClass) 40296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer continue; 40396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 4041ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner unsigned Flags = getInfo(Id).Flags; 4051ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner if (FlagsToInclude && !(Flags & FlagsToInclude)) 4061ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner continue; 4071ee21dc1e11abdc56102d0f54265af73f5468bf9Reid Kleckner if (Flags & FlagsToExclude) 40896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer continue; 40996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 41096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (const char *Text = getOptionHelpText(Id)) { 41196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const char *HelpGroup = getOptionHelpGroup(*this, Id); 41296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer const std::string &OptName = getOptionHelpName(*this, Id); 41396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer GroupedOptionHelp[HelpGroup].push_back(std::make_pair(OptName, Text)); 41496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 41596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 41696a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 41796a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer for (helpmap_ty::iterator it = GroupedOptionHelp .begin(), 41896a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer ie = GroupedOptionHelp.end(); it != ie; ++it) { 41996a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer if (it != GroupedOptionHelp .begin()) 42096a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS << "\n"; 42196a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer PrintHelpOptionList(OS, it->first, it->second); 42296a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer } 42396a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer 42496a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer OS.flush(); 42596a564f2beec8c1930f0640844eec433e03bbce8Michael J. Spencer} 426