CommandLine.h revision 331de23705a719514e37c211f327379688f81b0d
1//===- Support/CommandLine.h - Flexible Command line parser ------*- C++ -*--=// 2// 3// This class implements a command line argument processor that is useful when 4// creating a tool. It provides a simple, minimalistic interface that is easily 5// extensible and supports nonlocal (library) command line options. 6// 7// Note that rather than trying to figure out what this code does, you should 8// read the library documentation located in docs/CommandLine.html or looks at 9// the many example usages in tools/*/*.cpp 10// 11//===----------------------------------------------------------------------===// 12 13#ifndef LLVM_SUPPORT_COMMANDLINE_H 14#define LLVM_SUPPORT_COMMANDLINE_H 15 16#include <string> 17#include <vector> 18#include <utility> 19#include <stdarg.h> 20#include "boost/type_traits/object_traits.hpp" 21 22namespace cl { // Short namespace to make usage concise 23 24//===----------------------------------------------------------------------===// 25// ParseCommandLineOptions - Command line option processing entry point. 26// 27void cl::ParseCommandLineOptions(int &argc, char **argv, 28 const char *Overview = 0); 29 30//===----------------------------------------------------------------------===// 31// Flags permitted to be passed to command line arguments 32// 33 34enum NumOccurances { // Flags for the number of occurances allowed... 35 Optional = 0x01, // Zero or One occurance 36 ZeroOrMore = 0x02, // Zero or more occurances allowed 37 Required = 0x03, // One occurance required 38 OneOrMore = 0x04, // One or more occurances required 39 40 // ConsumeAfter - Indicates that this option is fed anything that follows the 41 // last positional argument required by the application (it is an error if 42 // there are zero positional arguments, and a ConsumeAfter option is used). 43 // Thus, for example, all arguments to LLI are processed until a filename is 44 // found. Once a filename is found, all of the succeeding arguments are 45 // passed, unprocessed, to the ConsumeAfter option. 46 // 47 ConsumeAfter = 0x05, 48 49 OccurancesMask = 0x07, 50}; 51 52enum ValueExpected { // Is a value required for the option? 53 ValueOptional = 0x08, // The value can oppear... or not 54 ValueRequired = 0x10, // The value is required to appear! 55 ValueDisallowed = 0x18, // A value may not be specified (for flags) 56 ValueMask = 0x18, 57}; 58 59enum OptionHidden { // Control whether -help shows this option 60 NotHidden = 0x20, // Option included in --help & --help-hidden 61 Hidden = 0x40, // -help doesn't, but --help-hidden does 62 ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg 63 HiddenMask = 0x60, 64}; 65 66// Formatting flags - This controls special features that the option might have 67// that cause it to be parsed differently... 68// 69// Prefix - This option allows arguments that are otherwise unrecognized to be 70// matched by options that are a prefix of the actual value. This is useful for 71// cases like a linker, where options are typically of the form '-lfoo' or 72// '-L../../include' where -l or -L are the actual flags. When prefix is 73// enabled, and used, the value for the flag comes from the suffix of the 74// argument. 75// 76// Grouping - With this option enabled, multiple letter options are allowed to 77// bunch together with only a single hyphen for the whole group. This allows 78// emulation of the behavior that ls uses for example: ls -la === ls -l -a 79// 80 81enum FormattingFlags { 82 NormalFormatting = 0x000, // Nothing special 83 Positional = 0x080, // Is a positional argument, no '-' required 84 Prefix = 0x100, // Can this option directly prefix its value? 85 Grouping = 0x180, // Can this option group with other options? 86 FormattingMask = 0x180, 87}; 88 89 90//===----------------------------------------------------------------------===// 91// Option Base class 92// 93class alias; 94class Option { 95 friend void cl::ParseCommandLineOptions(int &, char **, const char *, int); 96 friend class alias; 97 98 // handleOccurances - Overriden by subclasses to handle the value passed into 99 // an argument. Should return true if there was an error processing the 100 // argument and the program should exit. 101 // 102 virtual bool handleOccurance(const char *ArgName, const std::string &Arg) = 0; 103 104 virtual enum NumOccurances getNumOccurancesFlagDefault() const { 105 return Optional; 106 } 107 virtual enum ValueExpected getValueExpectedFlagDefault() const { 108 return ValueOptional; 109 } 110 virtual enum OptionHidden getOptionHiddenFlagDefault() const { 111 return NotHidden; 112 } 113 virtual enum FormattingFlags getFormattingFlagDefault() const { 114 return NormalFormatting; 115 } 116 117 int NumOccurances; // The number of times specified 118 int Flags; // Flags for the argument 119public: 120 const char *ArgStr; // The argument string itself (ex: "help", "o") 121 const char *HelpStr; // The descriptive text message for --help 122 const char *ValueStr; // String describing what the value of this option is 123 124 inline enum NumOccurances getNumOccurancesFlag() const { 125 int NO = Flags & OccurancesMask; 126 return NO ? (enum NumOccurances)NO : getNumOccurancesFlagDefault(); 127 } 128 inline enum ValueExpected getValueExpectedFlag() const { 129 int VE = Flags & ValueMask; 130 return VE ? (enum ValueExpected)VE : getValueExpectedFlagDefault(); 131 } 132 inline enum OptionHidden getOptionHiddenFlag() const { 133 int OH = Flags & HiddenMask; 134 return OH ? (enum OptionHidden)OH : getOptionHiddenFlagDefault(); 135 } 136 inline enum FormattingFlags getFormattingFlag() const { 137 int OH = Flags & FormattingMask; 138 return OH ? (enum FormattingFlags)OH : getFormattingFlagDefault(); 139 } 140 141 // hasArgStr - Return true if the argstr != "" 142 bool hasArgStr() const { return ArgStr[0] != 0; } 143 144 //-------------------------------------------------------------------------=== 145 // Accessor functions set by OptionModifiers 146 // 147 void setArgStr(const char *S) { ArgStr = S; } 148 void setDescription(const char *S) { HelpStr = S; } 149 void setValueStr(const char *S) { ValueStr = S; } 150 151 void setFlag(unsigned Flag, unsigned FlagMask) { 152 if (Flags & FlagMask) { 153 error(": Specified two settings for the same option!"); 154 exit(1); 155 } 156 157 Flags |= Flag; 158 } 159 160 void setNumOccurancesFlag(enum NumOccurances Val) { 161 setFlag(Val, OccurancesMask); 162 } 163 void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); } 164 void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); } 165 void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); } 166 167protected: 168 Option() : NumOccurances(0), Flags(0), 169 ArgStr(""), HelpStr(""), ValueStr("") {} 170 171public: 172 // addArgument - Tell the system that this Option subclass will handle all 173 // occurances of -ArgStr on the command line. 174 // 175 void addArgument(const char *ArgStr); 176 177 // Return the width of the option tag for printing... 178 virtual unsigned getOptionWidth() const = 0; 179 180 // printOptionInfo - Print out information about this option. The 181 // to-be-maintained width is specified. 182 // 183 virtual void printOptionInfo(unsigned GlobalWidth) const = 0; 184 185 // addOccurance - Wrapper around handleOccurance that enforces Flags 186 // 187 bool addOccurance(const char *ArgName, const std::string &Value); 188 189 // Prints option name followed by message. Always returns true. 190 bool error(std::string Message, const char *ArgName = 0); 191 192public: 193 inline int getNumOccurances() const { return NumOccurances; } 194 virtual ~Option() {} 195}; 196 197 198//===----------------------------------------------------------------------===// 199// Command line option modifiers that can be used to modify the behavior of 200// command line option parsers... 201// 202 203// desc - Modifier to set the description shown in the --help output... 204struct desc { 205 const char *Desc; 206 desc(const char *Str) : Desc(Str) {} 207 void apply(Option &O) const { O.setDescription(Desc); } 208}; 209 210// value_desc - Modifier to set the value description shown in the --help 211// output... 212struct value_desc { 213 const char *Desc; 214 value_desc(const char *Str) : Desc(Str) {} 215 void apply(Option &O) const { O.setValueStr(Desc); } 216}; 217 218 219// init - Specify a default (initial) value for the command line argument, if 220// the default constructor for the argument type does not give you what you 221// want. This is only valid on "opt" arguments, not on "list" arguments. 222// 223template<class Ty> 224struct initializer { 225 const Ty &Init; 226 initializer(const Ty &Val) : Init(Val) {} 227 228 template<class Opt> 229 void apply(Opt &O) const { O.setInitialValue(Init); } 230}; 231 232template<class Ty> 233initializer<Ty> init(const Ty &Val) { 234 return initializer<Ty>(Val); 235} 236 237 238// location - Allow the user to specify which external variable they want to 239// store the results of the command line argument processing into, if they don't 240// want to store it in the option itself. 241// 242template<class Ty> 243struct LocationClass { 244 Ty &Loc; 245 LocationClass(Ty &L) : Loc(L) {} 246 247 template<class Opt> 248 void apply(Opt &O) const { O.setLocation(O, Loc); } 249}; 250 251template<class Ty> 252LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); } 253 254 255//===----------------------------------------------------------------------===// 256// Enum valued command line option 257// 258#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, ENUMVAL, DESC 259#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, ENUMVAL, DESC 260 261// values - For custom data types, allow specifying a group of values together 262// as the values that go into the mapping that the option handler uses. Note 263// that the values list must always have a 0 at the end of the list to indicate 264// that the list has ended. 265// 266template<class DataType> 267class ValuesClass { 268 // Use a vector instead of a map, because the lists should be short, 269 // the overhead is less, and most importantly, it keeps them in the order 270 // inserted so we can print our option out nicely. 271 std::vector<std::pair<const char *, std::pair<int, const char *> > > Values; 272 void processValues(va_list Vals); 273public: 274 ValuesClass(const char *EnumName, DataType Val, const char *Desc, 275 va_list ValueArgs) { 276 // Insert the first value, which is required. 277 Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc))); 278 279 // Process the varargs portion of the values... 280 while (const char *EnumName = va_arg(ValueArgs, const char *)) { 281 DataType EnumVal = va_arg(ValueArgs, DataType); 282 const char *EnumDesc = va_arg(ValueArgs, const char *); 283 Values.push_back(std::make_pair(EnumName, // Add value to value map 284 std::make_pair(EnumVal, EnumDesc))); 285 } 286 } 287 288 template<class Opt> 289 void apply(Opt &O) const { 290 for (unsigned i = 0, e = Values.size(); i != e; ++i) 291 O.getParser().addLiteralOption(Values[i].first, Values[i].second.first, 292 Values[i].second.second); 293 } 294}; 295 296template<class DataType> 297ValuesClass<DataType> values(const char *Arg, DataType Val, const char *Desc, 298 ...) { 299 va_list ValueArgs; 300 va_start(ValueArgs, Desc); 301 ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); 302 va_end(ValueArgs); 303 return Vals; 304} 305 306 307//===----------------------------------------------------------------------===// 308// parser class - Parameterizable parser for different data types. By default, 309// known data types (string, int, bool) have specialized parsers, that do what 310// you would expect. The default parser, used for data types that are not 311// built-in, uses a mapping table to map specific options to values, which is 312// used, among other things, to handle enum types. 313 314//-------------------------------------------------- 315// generic_parser_base - This class holds all the non-generic code that we do 316// not need replicated for every instance of the generic parser. This also 317// allows us to put stuff into CommandLine.cpp 318// 319struct generic_parser_base { 320 virtual ~generic_parser_base() {} // Base class should have virtual-dtor 321 322 // getNumOptions - Virtual function implemented by generic subclass to 323 // indicate how many entries are in Values. 324 // 325 virtual unsigned getNumOptions() const = 0; 326 327 // getOption - Return option name N. 328 virtual const char *getOption(unsigned N) const = 0; 329 330 // getDescription - Return description N 331 virtual const char *getDescription(unsigned N) const = 0; 332 333 // Return the width of the option tag for printing... 334 virtual unsigned getOptionWidth(const Option &O) const; 335 336 // printOptionInfo - Print out information about this option. The 337 // to-be-maintained width is specified. 338 // 339 virtual void printOptionInfo(const Option &O, unsigned GlobalWidth) const; 340 341 void initialize(Option &O) { 342 // All of the modifiers for the option have been processed by now, so the 343 // argstr field should be stable, copy it down now. 344 // 345 hasArgStr = O.hasArgStr(); 346 347 // If there has been no argstr specified, that means that we need to add an 348 // argument for every possible option. This ensures that our options are 349 // vectored to us. 350 // 351 if (!hasArgStr) 352 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 353 O.addArgument(getOption(i)); 354 } 355 356 enum ValueExpected getValueExpectedFlagDefault() const { 357 // If there is an ArgStr specified, then we are of the form: 358 // 359 // -opt=O2 or -opt O2 or -optO2 360 // 361 // In which case, the value is required. Otherwise if an arg str has not 362 // been specified, we are of the form: 363 // 364 // -O2 or O2 or -la (where -l and -a are seperate options) 365 // 366 // If this is the case, we cannot allow a value. 367 // 368 if (hasArgStr) 369 return ValueRequired; 370 else 371 return ValueDisallowed; 372 } 373 374protected: 375 bool hasArgStr; 376}; 377 378// Default parser implementation - This implementation depends on having a 379// mapping of recognized options to values of some sort. In addition to this, 380// each entry in the mapping also tracks a help message that is printed with the 381// command line option for --help. Because this is a simple mapping parser, the 382// data type can be any unsupported type. 383// 384template <class DataType> 385class parser : public generic_parser_base { 386 std::vector<std::pair<const char *, 387 std::pair<DataType, const char *> > > Values; 388 389 // Implement virtual functions needed by generic_parser_base 390 unsigned getNumOptions() const { return Values.size(); } 391 const char *getOption(unsigned N) const { return Values[N].first; } 392 const char *getDescription(unsigned N) const { 393 return Values[N].second.second; 394 } 395 396public: 397 // Default implementation, requires user to populate it with values somehow. 398 template<class Opt> // parse - Return true on error. 399 bool parse(Opt &O, const char *ArgName, const string &Arg) { 400 string ArgVal; 401 if (hasArgStr) 402 ArgVal = Arg; 403 else 404 ArgVal = ArgName; 405 406 for (unsigned i = 0, e = Values.size(); i != e; ++i) 407 if (ArgVal == Values[i].first) { 408 O.addValue(Values[i].second.first); 409 return false; 410 } 411 412 return O.error(": Cannot find option named '" + ArgVal + "'!"); 413 } 414 415 // addLiteralOption - Add an entry to the mapping table... 416 template <class DT> 417 void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) { 418 Values.push_back(std::make_pair(Name, std::make_pair((DataType)V,HelpStr))); 419 } 420}; 421 422 423//-------------------------------------------------- 424// parser<bool> 425// 426template<> 427class parser<bool> { 428 static bool parseImpl(Option &O, const string &Arg, bool &Val); 429public: 430 431 template<class Opt> // parse - Return true on error. 432 bool parse(Opt &O, const char *ArgName, const string &Arg) { 433 bool Val; 434 bool Error = parseImpl(O, Arg, Val); 435 if (!Error) O.addValue(Val); 436 return Error; 437 } 438 439 enum ValueExpected getValueExpectedFlagDefault() const { 440 return ValueOptional; 441 } 442 443 void initialize(Option &O) {} 444 445 // Return the width of the option tag for printing... 446 virtual unsigned getOptionWidth(const Option &O) const; 447 448 // printOptionInfo - Print out information about this option. The 449 // to-be-maintained width is specified. 450 // 451 virtual void printOptionInfo(const Option &O, unsigned GlobalWidth) const; 452}; 453 454 455//-------------------------------------------------- 456// parser<int> 457// 458template<> 459class parser<int> { 460 static bool parseImpl(Option &O, const string &Arg, int &Val); 461public: 462 463 // parse - Return true on error. 464 template<class Opt> 465 bool parse(Opt &O, const char *ArgName, const string &Arg) { 466 int Val; 467 bool Error = parseImpl(O, Arg, Val); 468 if (!Error) O.addValue(Val); 469 return Error; 470 } 471 472 enum ValueExpected getValueExpectedFlagDefault() const { 473 return ValueRequired; 474 } 475 476 void initialize(Option &O) {} 477 478 // Return the width of the option tag for printing... 479 virtual unsigned getOptionWidth(const Option &O) const; 480 481 // printOptionInfo - Print out information about this option. The 482 // to-be-maintained width is specified. 483 // 484 virtual void printOptionInfo(const Option &O, unsigned GlobalWidth) const; 485}; 486 487 488//-------------------------------------------------- 489// parser<double> 490// 491template<> 492class parser<double> { 493 static bool parseImpl(Option &O, const string &Arg, double &Val); 494public: 495 496 // parse - Return true on error. 497 template<class Opt> 498 bool parse(Opt &O, const char *ArgName, const string &Arg) { 499 double Val; 500 bool Error = parseImpl(O, Arg, Val); 501 if (!Error) O.addValue(Val); 502 return Error; 503 } 504 505 enum ValueExpected getValueExpectedFlagDefault() const { 506 return ValueRequired; 507 } 508 509 void initialize(Option &O) {} 510 511 // Return the width of the option tag for printing... 512 virtual unsigned getOptionWidth(const Option &O) const; 513 514 // printOptionInfo - Print out information about this option. The 515 // to-be-maintained width is specified. 516 // 517 virtual void printOptionInfo(const Option &O, unsigned GlobalWidth) const; 518}; 519 520// Parser<float> is the same as parser<double> 521template<> struct parser<float> : public parser<double> {}; 522 523 524 525//-------------------------------------------------- 526// parser<string> 527// 528template<> 529struct parser<string> { 530 // parse - Return true on error. 531 template<class Opt> 532 bool parse(Opt &O, const char *ArgName, const string &Arg) { 533 O.addValue(Arg); 534 return false; 535 } 536 enum ValueExpected getValueExpectedFlagDefault() const { 537 return ValueRequired; 538 } 539 540 void initialize(Option &O) {} 541 542 // Return the width of the option tag for printing... 543 virtual unsigned getOptionWidth(const Option &O) const; 544 545 // printOptionInfo - Print out information about this option. The 546 // to-be-maintained width is specified. 547 // 548 virtual void printOptionInfo(const Option &O, unsigned GlobalWidth) const; 549}; 550 551 552 553//===----------------------------------------------------------------------===// 554// applicator class - This class is used because we must use partial 555// specialization to handle literal string arguments specially (const char* does 556// not correctly respond to the apply method). Because the syntax to use this 557// is a pain, we have the 'apply' method below to handle the nastiness... 558// 559template<class Mod> struct applicator { 560 template<class Opt> 561 static void opt(const Mod &M, Opt &O) { M.apply(O); } 562}; 563 564// Handle const char* as a special case... 565template<unsigned n> struct applicator<char[n]> { 566 template<class Opt> 567 static void opt(const char *Str, Opt &O) { O.setArgStr(Str); } 568}; 569template<> struct applicator<const char*> { 570 template<class Opt> 571 static void opt(const char *Str, Opt &O) { O.setArgStr(Str); } 572}; 573 574template<> struct applicator<NumOccurances> { 575 static void opt(NumOccurances NO, Option &O) { O.setNumOccurancesFlag(NO); } 576}; 577template<> struct applicator<ValueExpected> { 578 static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); } 579}; 580template<> struct applicator<OptionHidden> { 581 static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); } 582}; 583template<> struct applicator<FormattingFlags> { 584 static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); } 585}; 586 587// apply method - Apply a modifier to an option in a type safe way. 588template<class Mod, class Opt> 589void apply(const Mod &M, Opt *O) { 590 applicator<Mod>::opt(M, *O); 591} 592 593 594//===----------------------------------------------------------------------===// 595// opt_storage class 596 597// Default storage class definition: external storage. This implementation 598// assumes the user will specify a variable to store the data into with the 599// cl::location(x) modifier. 600// 601template<class DataType, bool ExternalStorage, bool isClass> 602class opt_storage { 603 DataType *Location; // Where to store the object... 604 605 void check() { 606 assert(Location != 0 && "cl::location(...) not specified for a command " 607 "line option with external storage!"); 608 } 609public: 610 opt_storage() : Location(0) {} 611 612 bool setLocation(Option &O, DataType &L) { 613 if (Location) 614 return O.error(": cl::location(x) specified more than once!"); 615 Location = &L; 616 return false; 617 } 618 619 template<class T> 620 void setValue(const T &V) { 621 check(); 622 *Location = V; 623 } 624 625 DataType &getValue() { check(); return *Location; } 626 const DataType &getValue() const { check(); return *Location; } 627}; 628 629 630// Define how to hold a class type object, such as a string. Since we can 631// inherit from a class, we do so. This makes us exactly compatible with the 632// object in all cases that it is used. 633// 634template<class DataType> 635struct opt_storage<DataType,false,true> : public DataType { 636 637 template<class T> 638 void setValue(const T &V) { DataType::operator=(V); } 639 640 DataType &getValue() { return *this; } 641 const DataType &getValue() const { return *this; } 642}; 643 644// Define a partial specialization to handle things we cannot inherit from. In 645// this case, we store an instance through containment, and overload operators 646// to get at the value. 647// 648template<class DataType> 649struct opt_storage<DataType, false, false> { 650 DataType Value; 651 652 // Make sure we initialize the value with the default constructor for the 653 // type. 654 opt_storage() : Value(DataType()) {} 655 656 template<class T> 657 void setValue(const T &V) { Value = V; } 658 DataType &getValue() { return Value; } 659 DataType getValue() const { return Value; } 660}; 661 662 663//===----------------------------------------------------------------------===// 664// opt - A scalar command line option. 665// 666template <class DataType, bool ExternalStorage = false, 667 class ParserClass = parser<DataType> > 668class opt : public Option, 669 public opt_storage<DataType, ExternalStorage, 670 ::boost::is_class<DataType>::value>{ 671 ParserClass Parser; 672 673 virtual bool handleOccurance(const char *ArgName, const std::string &Arg) { 674 return Parser.parse(*this, ArgName, Arg); 675 } 676 677 virtual enum ValueExpected getValueExpectedFlagDefault() const { 678 return Parser.getValueExpectedFlagDefault(); 679 } 680 681 // Forward printing stuff to the parser... 682 virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);} 683 virtual void printOptionInfo(unsigned GlobalWidth) const { 684 Parser.printOptionInfo(*this, GlobalWidth); 685 } 686 687 void done() { 688 addArgument(ArgStr); 689 Parser.initialize(*this); 690 } 691public: 692 // setInitialValue - Used by the cl::init modifier... 693 void setInitialValue(const DataType &V) { setValue(V); } 694 695 // addValue - Used by the parser to add a value to the option 696 template<class T> 697 void addValue(const T &V) { setValue(V); } 698 ParserClass &getParser() { return Parser; } 699 700 operator DataType() const { return getValue(); } 701 702 template<class T> 703 DataType &operator=(const T &Val) { setValue(Val); return getValue(); } 704 705 // One option... 706 template<class M0t> 707 opt(const M0t &M0) { 708 apply(M0, this); 709 done(); 710 } 711 712 // Two options... 713 template<class M0t, class M1t> 714 opt(const M0t &M0, const M1t &M1) { 715 apply(M0, this); apply(M1, this); 716 done(); 717 } 718 719 // Three options... 720 template<class M0t, class M1t, class M2t> 721 opt(const M0t &M0, const M1t &M1, const M2t &M2) { 722 apply(M0, this); apply(M1, this); apply(M2, this); 723 done(); 724 } 725 // Four options... 726 template<class M0t, class M1t, class M2t, class M3t> 727 opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) { 728 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 729 done(); 730 } 731 // Five options... 732 template<class M0t, class M1t, class M2t, class M3t, class M4t> 733 opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 734 const M4t &M4) { 735 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 736 apply(M4, this); 737 done(); 738 } 739 // Six options... 740 template<class M0t, class M1t, class M2t, class M3t, 741 class M4t, class M5t> 742 opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 743 const M4t &M4, const M5t &M5) { 744 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 745 apply(M4, this); apply(M5, this); 746 done(); 747 } 748 // Seven options... 749 template<class M0t, class M1t, class M2t, class M3t, 750 class M4t, class M5t, class M6t> 751 opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 752 const M4t &M4, const M5t &M5, const M6t &M6) { 753 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 754 apply(M4, this); apply(M5, this); apply(M6, this); 755 done(); 756 } 757 // Eight options... 758 template<class M0t, class M1t, class M2t, class M3t, 759 class M4t, class M5t, class M6t, class M7t> 760 opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 761 const M4t &M4, const M5t &M5, const M6t &M6, const M7t &M7) { 762 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 763 apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this); 764 done(); 765 } 766}; 767 768//===----------------------------------------------------------------------===// 769// list_storage class 770 771// Default storage class definition: external storage. This implementation 772// assumes the user will specify a variable to store the data into with the 773// cl::location(x) modifier. 774// 775template<class DataType, class StorageClass> 776class list_storage { 777 StorageClass *Location; // Where to store the object... 778 779public: 780 list_storage() : Location(0) {} 781 782 bool setLocation(Option &O, StorageClass &L) { 783 if (Location) 784 return O.error(": cl::location(x) specified more than once!"); 785 Location = &L; 786 return false; 787 } 788 789 template<class T> 790 void addValue(const T &V) { 791 assert(Location != 0 && "cl::location(...) not specified for a command " 792 "line option with external storage!"); 793 Location->push_back(V); 794 } 795}; 796 797 798// Define how to hold a class type object, such as a string. Since we can 799// inherit from a class, we do so. This makes us exactly compatible with the 800// object in all cases that it is used. 801// 802template<class DataType> 803struct list_storage<DataType, bool> : public std::vector<DataType> { 804 805 template<class T> 806 void addValue(const T &V) { push_back(V); } 807}; 808 809 810//===----------------------------------------------------------------------===// 811// list - A list of command line options. 812// 813template <class DataType, class Storage = bool, 814 class ParserClass = parser<DataType> > 815class list : public Option, public list_storage<DataType, Storage> { 816 ParserClass Parser; 817 818 virtual enum NumOccurances getNumOccurancesFlagDefault() const { 819 return ZeroOrMore; 820 } 821 virtual enum ValueExpected getValueExpectedFlagDefault() const { 822 return Parser.getValueExpectedFlagDefault(); 823 } 824 825 virtual bool handleOccurance(const char *ArgName, const std::string &Arg) { 826 return Parser.parse(*this, ArgName, Arg); 827 } 828 829 // Forward printing stuff to the parser... 830 virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);} 831 virtual void printOptionInfo(unsigned GlobalWidth) const { 832 Parser.printOptionInfo(*this, GlobalWidth); 833 } 834 835 void done() { 836 addArgument(ArgStr); 837 Parser.initialize(*this); 838 } 839public: 840 ParserClass &getParser() { return Parser; } 841 842 // One option... 843 template<class M0t> 844 list(const M0t &M0) { 845 apply(M0, this); 846 done(); 847 } 848 // Two options... 849 template<class M0t, class M1t> 850 list(const M0t &M0, const M1t &M1) { 851 apply(M0, this); apply(M1, this); 852 done(); 853 } 854 // Three options... 855 template<class M0t, class M1t, class M2t> 856 list(const M0t &M0, const M1t &M1, const M2t &M2) { 857 apply(M0, this); apply(M1, this); apply(M2, this); 858 done(); 859 } 860 // Four options... 861 template<class M0t, class M1t, class M2t, class M3t> 862 list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) { 863 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 864 done(); 865 } 866 // Five options... 867 template<class M0t, class M1t, class M2t, class M3t, class M4t> 868 list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 869 const M4t &M4) { 870 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 871 apply(M4, this); 872 done(); 873 } 874 // Six options... 875 template<class M0t, class M1t, class M2t, class M3t, 876 class M4t, class M5t> 877 list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 878 const M4t &M4, const M5t &M5) { 879 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 880 apply(M4, this); apply(M5, this); 881 done(); 882 } 883 // Seven options... 884 template<class M0t, class M1t, class M2t, class M3t, 885 class M4t, class M5t, class M6t> 886 list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 887 const M4t &M4, const M5t &M5, const M6t &M6) { 888 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 889 apply(M4, this); apply(M5, this); apply(M6, this); 890 done(); 891 } 892 // Eight options... 893 template<class M0t, class M1t, class M2t, class M3t, 894 class M4t, class M5t, class M6t, class M7t> 895 list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, 896 const M4t &M4, const M5t &M5, const M6t &M6, const M7t &M7) { 897 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 898 apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this); 899 done(); 900 } 901}; 902 903 904 905//===----------------------------------------------------------------------===// 906// Aliased command line option (alias this name to a preexisting name) 907// 908 909class alias : public Option { 910 Option *AliasFor; 911 virtual bool handleOccurance(const char *ArgName, const std::string &Arg) { 912 return AliasFor->handleOccurance(AliasFor->ArgStr, Arg); 913 } 914 // Aliases default to be hidden... 915 virtual enum OptionHidden getOptionHiddenFlagDefault() const {return Hidden;} 916 917 // Handle printing stuff... 918 virtual unsigned getOptionWidth() const; 919 virtual void printOptionInfo(unsigned GlobalWidth) const; 920 921 void done() { 922 if (!hasArgStr()) 923 error(": cl::alias must have argument name specified!"); 924 if (AliasFor == 0) 925 error(": cl::alias must have an cl::aliasopt(option) specified!"); 926 addArgument(ArgStr); 927 } 928public: 929 void setAliasFor(Option &O) { 930 if (AliasFor) 931 error(": cl::alias must only have one cl::aliasopt(...) specified!"); 932 AliasFor = &O; 933 } 934 935 // One option... 936 template<class M0t> 937 alias(const M0t &M0) : AliasFor(0) { 938 apply(M0, this); 939 done(); 940 } 941 // Two options... 942 template<class M0t, class M1t> 943 alias(const M0t &M0, const M1t &M1) : AliasFor(0) { 944 apply(M0, this); apply(M1, this); 945 done(); 946 } 947 // Three options... 948 template<class M0t, class M1t, class M2t> 949 alias(const M0t &M0, const M1t &M1, const M2t &M2) : AliasFor(0) { 950 apply(M0, this); apply(M1, this); apply(M2, this); 951 done(); 952 } 953 // Four options... 954 template<class M0t, class M1t, class M2t, class M3t> 955 alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) 956 : AliasFor(0) { 957 apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); 958 done(); 959 } 960}; 961 962// aliasfor - Modifier to set the option an alias aliases. 963struct aliasopt { 964 Option &Opt; 965 aliasopt(Option &O) : Opt(O) {} 966 void apply(alias &A) const { A.setAliasFor(Opt); } 967}; 968 969} // End namespace cl 970 971#endif 972