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