1 //===-- CommandLine.cpp - Command line parser implementation --------------===// 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 could try 8 // reading the library documentation located in docs/CommandLine.html 9 // 10 //===----------------------------------------------------------------------===// 11 12 #include "Support/CommandLine.h" 13 #include "Support/STLExtras.h" 14 #include <algorithm> 15 #include <map> 16 #include <set> 17 #include <iostream> 18 19 using namespace cl; 20 using std::map; 21 using std::pair; 22 using std::vector; 23 using std::string; 24 using std::cerr; 25 26 //===----------------------------------------------------------------------===// 27 // Basic, shared command line option processing machinery... 28 // 29 30 // Return the global command line option vector. Making it a function scoped 31 // static ensures that it will be initialized correctly before its first use. 32 // 33 static map<string, Option*> &getOpts() { 34 static map<string,Option*> CommandLineOptions; 35 return CommandLineOptions; 36 } 37 38 static vector<Option*> &getPositionalOpts() { 39 static vector<Option*> Positional; 40 return Positional; 41 } 42 43 static void AddArgument(const string &ArgName, Option *Opt) { 44 if (getOpts().find(ArgName) != getOpts().end()) { 45 cerr << "CommandLine Error: Argument '" << ArgName 46 << "' defined more than once!\n"; 47 } else { 48 // Add argument to the argument map! 49 getOpts().insert(std::make_pair(ArgName, Opt)); 50 } 51 } 52 53 static const char *ProgramName = 0; 54 static const char *ProgramOverview = 0; 55 56 static inline bool ProvideOption(Option *Handler, const char *ArgName, 57 const char *Value, int argc, char **argv, 58 int &i) { 59 // Enforce value requirements 60 switch (Handler->getValueExpectedFlag()) { 61 case ValueRequired: 62 if (Value == 0 || *Value == 0) { // No value specified? 63 if (i+1 < argc) { // Steal the next argument, like for '-o filename' 64 Value = argv[++i]; 65 } else { 66 return Handler->error(" requires a value!"); 67 } 68 } 69 break; 70 case ValueDisallowed: 71 if (*Value != 0) 72 return Handler->error(" does not allow a value! '" + 73 string(Value) + "' specified."); 74 break; 75 case ValueOptional: break; 76 default: cerr << "Bad ValueMask flag! CommandLine usage error:" 77 << Handler->getValueExpectedFlag() << "\n"; abort(); 78 } 79 80 // Run the handler now! 81 return Handler->addOccurance(ArgName, Value); 82 } 83 84 static bool ProvidePositionalOption(Option *Handler, string &Arg) { 85 int Dummy; 86 return ProvideOption(Handler, "", Arg.c_str(), 0, 0, Dummy); 87 } 88 89 90 // Option predicates... 91 static inline bool isGrouping(const Option *O) { 92 return O->getFormattingFlag() == cl::Grouping; 93 } 94 static inline bool isPrefixedOrGrouping(const Option *O) { 95 return isGrouping(O) || O->getFormattingFlag() == cl::Prefix; 96 } 97 98 // getOptionPred - Check to see if there are any options that satisfy the 99 // specified predicate with names that are the prefixes in Name. This is 100 // checked by progressively stripping characters off of the name, checking to 101 // see if there options that satisfy the predicate. If we find one, return it, 102 // otherwise return null. 103 // 104 static Option *getOptionPred(std::string Name, unsigned &Length, 105 bool (*Pred)(const Option*)) { 106 107 map<string, Option*>::iterator I = getOpts().find(Name); 108 if (I != getOpts().end() && Pred(I->second)) { 109 Length = Name.length(); 110 return I->second; 111 } 112 113 if (Name.size() == 1) return 0; 114 do { 115 Name.erase(Name.end()-1, Name.end()); // Chop off the last character... 116 I = getOpts().find(Name); 117 118 // Loop while we haven't found an option and Name still has at least two 119 // characters in it (so that the next iteration will not be the empty 120 // string... 121 } while ((I == getOpts().end() || !Pred(I->second)) && Name.size() > 1); 122 123 if (I != getOpts().end() && Pred(I->second)) { 124 Length = Name.length(); 125 return I->second; // Found one! 126 } 127 return 0; // No option found! 128 } 129 130 static bool RequiresValue(const Option *O) { 131 return O->getNumOccurancesFlag() == cl::Required || 132 O->getNumOccurancesFlag() == cl::OneOrMore; 133 } 134 135 static bool EatsUnboundedNumberOfValues(const Option *O) { 136 return O->getNumOccurancesFlag() == cl::ZeroOrMore || 137 O->getNumOccurancesFlag() == cl::OneOrMore; 138 } 139 140 void cl::ParseCommandLineOptions(int &argc, char **argv, 141 const char *Overview = 0) { 142 assert((!getOpts().empty() || !getPositionalOpts().empty()) && 143 "No options specified, or ParseCommandLineOptions called more" 144 " than once!"); 145 ProgramName = argv[0]; // Save this away safe and snug 146 ProgramOverview = Overview; 147 bool ErrorParsing = false; 148 149 map<string, Option*> &Opts = getOpts(); 150 vector<Option*> &PositionalOpts = getPositionalOpts(); 151 152 // Check out the positional arguments to collect information about them. 153 unsigned NumPositionalRequired = 0; 154 Option *ConsumeAfterOpt = 0; 155 if (!PositionalOpts.empty()) { 156 if (PositionalOpts[0]->getNumOccurancesFlag() == cl::ConsumeAfter) { 157 assert(PositionalOpts.size() > 1 && 158 "Cannot specify cl::ConsumeAfter without a positional argument!"); 159 ConsumeAfterOpt = PositionalOpts[0]; 160 } 161 162 // Calculate how many positional values are _required_. 163 bool UnboundedFound = false; 164 for (unsigned i = ConsumeAfterOpt != 0, e = PositionalOpts.size(); 165 i != e; ++i) { 166 Option *Opt = PositionalOpts[i]; 167 if (RequiresValue(Opt)) 168 ++NumPositionalRequired; 169 else if (ConsumeAfterOpt) { 170 // ConsumeAfter cannot be combined with "optional" positional options 171 ErrorParsing |= 172 Opt->error(" error - this positional option will never be matched, " 173 "because it does not Require a value, and a " 174 "cl::ConsumeAfter option is active!"); 175 } else if (UnboundedFound) { // This option does not "require" a value... 176 // Make sure this option is not specified after an option that eats all 177 // extra arguments, or this one will never get any! 178 // 179 ErrorParsing |= Opt->error(" error - option can never match, because " 180 "another positional argument will match an " 181 "unbounded number of values, and this option" 182 " does not require a value!"); 183 } 184 UnboundedFound |= EatsUnboundedNumberOfValues(Opt); 185 } 186 } 187 188 // PositionalVals - A vector of "positional" arguments we accumulate into to 189 // processes at the end... 190 // 191 vector<string> PositionalVals; 192 193 // Loop over all of the arguments... processing them. 194 bool DashDashFound = false; // Have we read '--'? 195 for (int i = 1; i < argc; ++i) { 196 Option *Handler = 0; 197 const char *Value = ""; 198 const char *ArgName = ""; 199 200 // Check to see if this is a positional argument. This argument is 201 // considered to be positional if it doesn't start with '-', if it is "-" 202 // itself, or if we have see "--" already. 203 // 204 if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { 205 // Positional argument! 206 if (!PositionalOpts.empty()) { 207 PositionalVals.push_back(argv[i]); 208 209 // All of the positional arguments have been fulfulled, give the rest to 210 // the consume after option... if it's specified... 211 // 212 if (PositionalVals.size() == NumPositionalRequired && 213 ConsumeAfterOpt != 0) { 214 for (++i; i < argc; ++i) 215 PositionalVals.push_back(argv[i]); 216 break; // Handle outside of the argument processing loop... 217 } 218 219 // Delay processing positional arguments until the end... 220 continue; 221 } 222 } else { // We start with a '-', must be an argument... 223 ArgName = argv[i]+1; 224 while (*ArgName == '-') ++ArgName; // Eat leading dashes 225 226 if (*ArgName == 0 && !DashDashFound) { // Is this the mythical "--"? 227 DashDashFound = true; // Yup, take note of that fact... 228 continue; // Don't try to process it as an argument iself. 229 } 230 231 const char *ArgNameEnd = ArgName; 232 while (*ArgNameEnd && *ArgNameEnd != '=') 233 ++ArgNameEnd; // Scan till end of argument name... 234 235 Value = ArgNameEnd; 236 if (*Value) // If we have an equals sign... 237 ++Value; // Advance to value... 238 239 if (*ArgName != 0) { 240 string RealName(ArgName, ArgNameEnd); 241 // Extract arg name part 242 map<string, Option*>::iterator I = Opts.find(RealName); 243 244 if (I == Opts.end() && !*Value && RealName.size() > 1) { 245 // Check to see if this "option" is really a prefixed or grouped 246 // argument... 247 // 248 unsigned Length = 0; 249 Option *PGOpt = getOptionPred(RealName, Length, isPrefixedOrGrouping); 250 251 // If the option is a prefixed option, then the value is simply the 252 // rest of the name... so fall through to later processing, by 253 // setting up the argument name flags and value fields. 254 // 255 if (PGOpt && PGOpt->getFormattingFlag() == cl::Prefix) { 256 ArgNameEnd = ArgName+Length; 257 Value = ArgNameEnd; 258 I = Opts.find(string(ArgName, ArgNameEnd)); 259 assert(I->second == PGOpt); 260 } else if (PGOpt) { 261 // This must be a grouped option... handle all of them now... 262 assert(isGrouping(PGOpt) && "Broken getOptionPred!"); 263 264 do { 265 // Move current arg name out of RealName into RealArgName... 266 string RealArgName(RealName.begin(), RealName.begin()+Length); 267 RealName.erase(RealName.begin(), RealName.begin()+Length); 268 269 // Because ValueRequired is an invalid flag for grouped arguments, 270 // we don't need to pass argc/argv in... 271 // 272 assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired && 273 "Option can not be cl::Grouping AND cl::ValueRequired!"); 274 int Dummy; 275 ErrorParsing |= ProvideOption(PGOpt, RealArgName.c_str(), "", 276 0, 0, Dummy); 277 278 // Get the next grouping option... 279 if (!RealName.empty()) 280 PGOpt = getOptionPred(RealName, Length, isGrouping); 281 } while (!RealName.empty() && PGOpt); 282 283 if (RealName.empty()) // Processed all of the options, move on 284 continue; // to the next argv[] value... 285 286 // If RealName is not empty, that means we did not match one of the 287 // options! This is an error. 288 // 289 I = Opts.end(); 290 } 291 } 292 293 Handler = I != Opts.end() ? I->second : 0; 294 } 295 } 296 297 if (Handler == 0) { 298 cerr << "Unknown command line argument '" << argv[i] << "'. Try: " 299 << argv[0] << " --help'\n"; 300 ErrorParsing = true; 301 continue; 302 } 303 304 ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i); 305 } 306 307 // Check and handle positional arguments now... 308 if (NumPositionalRequired > PositionalVals.size()) { 309 cerr << "Not enough positional command line arguments specified!\n"; 310 cerr << "Must specify at least " << NumPositionalRequired 311 << " positional arguments: See: " << argv[0] << " --help\n"; 312 ErrorParsing = true; 313 314 315 } else if (ConsumeAfterOpt == 0) { 316 // Positional args have already been handled if ConsumeAfter is specified... 317 unsigned ValNo = 0, NumVals = PositionalVals.size(); 318 for (unsigned i = 0, e = PositionalOpts.size(); i != e; ++i) { 319 if (RequiresValue(PositionalOpts[i])) { 320 ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]); 321 --NumPositionalRequired; // We fulfilled our duty... 322 } 323 324 // If we _can_ give this option more arguments, do so now, as long as we 325 // do not give it values that others need. 'Done' controls whether the 326 // option even _WANTS_ any more. 327 // 328 bool Done = PositionalOpts[i]->getNumOccurancesFlag() == cl::Required; 329 while (NumVals-ValNo > NumPositionalRequired && !Done) { 330 switch (PositionalOpts[i]->getNumOccurancesFlag()) { 331 case cl::Optional: 332 Done = true; // Optional arguments want _at most_ one value 333 // FALL THROUGH 334 case cl::ZeroOrMore: // Zero or more will take all they can get... 335 case cl::OneOrMore: // One or more will take all they can get... 336 ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]); 337 break; 338 default: 339 assert(0 && "Internal error, unexpected NumOccurances flag in " 340 "positional argument processing!"); 341 } 342 } 343 } 344 } else { 345 assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size()); 346 unsigned ValNo = 0; 347 for (unsigned j = 1, e = PositionalOpts.size(); j != e; ++j) 348 if (RequiresValue(PositionalOpts[j])) 349 ErrorParsing |= 350 ProvidePositionalOption(PositionalOpts[j], PositionalVals[ValNo++]); 351 352 // Handle over all of the rest of the arguments to the 353 // cl::ConsumeAfter command line option... 354 for (; ValNo != PositionalVals.size(); ++ValNo) 355 ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt, 356 PositionalVals[ValNo]); 357 } 358 359 // Loop over args and make sure all required args are specified! 360 for (map<string, Option*>::iterator I = Opts.begin(), 361 E = Opts.end(); I != E; ++I) { 362 switch (I->second->getNumOccurancesFlag()) { 363 case Required: 364 case OneOrMore: 365 if (I->second->getNumOccurances() == 0) { 366 I->second->error(" must be specified at least once!"); 367 ErrorParsing = true; 368 } 369 // Fall through 370 default: 371 break; 372 } 373 } 374 375 // Free all of the memory allocated to the map. Command line options may only 376 // be processed once! 377 Opts.clear(); 378 PositionalOpts.clear(); 379 380 // If we had an error processing our arguments, don't let the program execute 381 if (ErrorParsing) exit(1); 382 } 383 384 //===----------------------------------------------------------------------===// 385 // Option Base class implementation 386 // 387 388 bool Option::error(string Message, const char *ArgName = 0) { 389 if (ArgName == 0) ArgName = ArgStr; 390 if (ArgName[0] == 0) 391 cerr << HelpStr; // Be nice for positional arguments 392 else 393 cerr << "-" << ArgName; 394 cerr << " option" << Message << "\n"; 395 return true; 396 } 397 398 bool Option::addOccurance(const char *ArgName, const string &Value) { 399 NumOccurances++; // Increment the number of times we have been seen 400 401 switch (getNumOccurancesFlag()) { 402 case Optional: 403 if (NumOccurances > 1) 404 return error(": may only occur zero or one times!", ArgName); 405 break; 406 case Required: 407 if (NumOccurances > 1) 408 return error(": must occur exactly one time!", ArgName); 409 // Fall through 410 case OneOrMore: 411 case ZeroOrMore: 412 case ConsumeAfter: break; 413 default: return error(": bad num occurances flag value!"); 414 } 415 416 return handleOccurance(ArgName, Value); 417 } 418 419 // addArgument - Tell the system that this Option subclass will handle all 420 // occurances of -ArgStr on the command line. 421 // 422 void Option::addArgument(const char *ArgStr) { 423 if (ArgStr[0]) 424 AddArgument(ArgStr, this); 425 else if (getFormattingFlag() == Positional) 426 getPositionalOpts().push_back(this); 427 else if (getNumOccurancesFlag() == ConsumeAfter) { 428 assert((getPositionalOpts().empty() || 429 getPositionalOpts().front()->getNumOccurancesFlag() != ConsumeAfter) 430 && "Cannot specify more than one option with cl::ConsumeAfter " 431 "specified!"); 432 getPositionalOpts().insert(getPositionalOpts().begin(), this); 433 } 434 } 435 436 437 // getValueStr - Get the value description string, using "DefaultMsg" if nothing 438 // has been specified yet. 439 // 440 static const char *getValueStr(const Option &O, const char *DefaultMsg) { 441 if (O.ValueStr[0] == 0) return DefaultMsg; 442 return O.ValueStr; 443 } 444 445 //===----------------------------------------------------------------------===// 446 // cl::alias class implementation 447 // 448 449 // Return the width of the option tag for printing... 450 unsigned alias::getOptionWidth() const { 451 return std::strlen(ArgStr)+6; 452 } 453 454 // Print out the option for the alias... 455 void alias::printOptionInfo(unsigned GlobalWidth) const { 456 unsigned L = std::strlen(ArgStr); 457 cerr << " -" << ArgStr << string(GlobalWidth-L-6, ' ') << " - " 458 << HelpStr << "\n"; 459 } 460 461 462 463 //===----------------------------------------------------------------------===// 464 // Parser Implementation code... 465 // 466 467 // parser<bool> implementation 468 // 469 bool parser<bool>::parseImpl(Option &O, const string &Arg, bool &Value) { 470 if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || 471 Arg == "1") { 472 Value = true; 473 } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") { 474 Value = false; 475 } else { 476 return O.error(": '" + Arg + 477 "' is invalid value for boolean argument! Try 0 or 1"); 478 } 479 return false; 480 } 481 482 // Return the width of the option tag for printing... 483 unsigned parser<bool>::getOptionWidth(const Option &O) const { 484 return std::strlen(O.ArgStr)+6; 485 } 486 487 // printOptionInfo - Print out information about this option. The 488 // to-be-maintained width is specified. 489 // 490 void parser<bool>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{ 491 unsigned L = std::strlen(O.ArgStr); 492 cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ') << " - " 493 << O.HelpStr << "\n"; 494 } 495 496 497 498 // parser<int> implementation 499 // 500 bool parser<int>::parseImpl(Option &O, const string &Arg, int &Value) { 501 const char *ArgStart = Arg.c_str(); 502 char *End; 503 Value = (int)strtol(ArgStart, &End, 0); 504 if (*End != 0) 505 return O.error(": '" + Arg + "' value invalid for integer argument!"); 506 return false; 507 } 508 509 // Return the width of the option tag for printing... 510 unsigned parser<int>::getOptionWidth(const Option &O) const { 511 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "int"))+9; 512 } 513 514 // printOptionInfo - Print out information about this option. The 515 // to-be-maintained width is specified. 516 // 517 void parser<int>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{ 518 cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "int") << ">" 519 << string(GlobalWidth-getOptionWidth(O), ' ') << " - " 520 << O.HelpStr << "\n"; 521 } 522 523 524 // parser<double> implementation 525 // 526 bool parser<double>::parseImpl(Option &O, const string &Arg, double &Value) { 527 const char *ArgStart = Arg.c_str(); 528 char *End; 529 Value = strtod(ArgStart, &End); 530 if (*End != 0) 531 return O.error(": '" +Arg+ "' value invalid for floating point argument!"); 532 return false; 533 } 534 535 // Return the width of the option tag for printing... 536 unsigned parser<double>::getOptionWidth(const Option &O) const { 537 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "number"))+9; 538 } 539 540 // printOptionInfo - Print out information about this option. The 541 // to-be-maintained width is specified. 542 // 543 void parser<double>::printOptionInfo(const Option &O, 544 unsigned GlobalWidth) const{ 545 cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "number") << ">" 546 << string(GlobalWidth-getOptionWidth(O), ' ') 547 << " - " << O.HelpStr << "\n"; 548 } 549 550 551 // parser<string> implementation 552 // 553 554 // Return the width of the option tag for printing... 555 unsigned parser<string>::getOptionWidth(const Option &O) const { 556 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "string"))+9; 557 } 558 559 // printOptionInfo - Print out information about this option. The 560 // to-be-maintained width is specified. 561 // 562 void parser<string>::printOptionInfo(const Option &O, 563 unsigned GlobalWidth) const{ 564 cerr << " -" << O.ArgStr << " <" << getValueStr(O, "string") << ">" 565 << string(GlobalWidth-getOptionWidth(O), ' ') 566 << " - " << O.HelpStr << "\n"; 567 } 568 569 // generic_parser_base implementation 570 // 571 572 // Return the width of the option tag for printing... 573 unsigned generic_parser_base::getOptionWidth(const Option &O) const { 574 if (O.hasArgStr()) { 575 unsigned Size = std::strlen(O.ArgStr)+6; 576 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 577 Size = std::max(Size, (unsigned)std::strlen(getOption(i))+8); 578 return Size; 579 } else { 580 unsigned BaseSize = 0; 581 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 582 BaseSize = std::max(BaseSize, (unsigned)std::strlen(getOption(i))+8); 583 return BaseSize; 584 } 585 } 586 587 // printOptionInfo - Print out information about this option. The 588 // to-be-maintained width is specified. 589 // 590 void generic_parser_base::printOptionInfo(const Option &O, 591 unsigned GlobalWidth) const { 592 if (O.hasArgStr()) { 593 unsigned L = std::strlen(O.ArgStr); 594 cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ') 595 << " - " << O.HelpStr << "\n"; 596 597 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 598 unsigned NumSpaces = GlobalWidth-strlen(getOption(i))-8; 599 cerr << " =" << getOption(i) << string(NumSpaces, ' ') << " - " 600 << getDescription(i) << "\n"; 601 } 602 } else { 603 if (O.HelpStr[0]) 604 cerr << " " << O.HelpStr << "\n"; 605 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 606 unsigned L = std::strlen(getOption(i)); 607 cerr << " -" << getOption(i) << string(GlobalWidth-L-8, ' ') << " - " 608 << getDescription(i) << "\n"; 609 } 610 } 611 } 612 613 614 //===----------------------------------------------------------------------===// 615 // --help and --help-hidden option implementation 616 // 617 namespace { 618 619 class HelpPrinter { 620 unsigned MaxArgLen; 621 const Option *EmptyArg; 622 const bool ShowHidden; 623 624 // isHidden/isReallyHidden - Predicates to be used to filter down arg lists. 625 inline static bool isHidden(pair<string, Option *> &OptPair) { 626 return OptPair.second->getOptionHiddenFlag() >= Hidden; 627 } 628 inline static bool isReallyHidden(pair<string, Option *> &OptPair) { 629 return OptPair.second->getOptionHiddenFlag() == ReallyHidden; 630 } 631 632 public: 633 HelpPrinter(bool showHidden) : ShowHidden(showHidden) { 634 EmptyArg = 0; 635 } 636 637 void operator=(bool Value) { 638 if (Value == false) return; 639 640 // Copy Options into a vector so we can sort them as we like... 641 vector<pair<string, Option*> > Options; 642 copy(getOpts().begin(), getOpts().end(), std::back_inserter(Options)); 643 644 // Eliminate Hidden or ReallyHidden arguments, depending on ShowHidden 645 Options.erase(std::remove_if(Options.begin(), Options.end(), 646 std::ptr_fun(ShowHidden ? isReallyHidden : isHidden)), 647 Options.end()); 648 649 // Eliminate duplicate entries in table (from enum flags options, f.e.) 650 { // Give OptionSet a scope 651 std::set<Option*> OptionSet; 652 for (unsigned i = 0; i != Options.size(); ++i) 653 if (OptionSet.count(Options[i].second) == 0) 654 OptionSet.insert(Options[i].second); // Add new entry to set 655 else 656 Options.erase(Options.begin()+i--); // Erase duplicate 657 } 658 659 if (ProgramOverview) 660 cerr << "OVERVIEW:" << ProgramOverview << "\n"; 661 662 cerr << "USAGE: " << ProgramName << " [options]"; 663 664 // Print out the positional options... 665 vector<Option*> &PosOpts = getPositionalOpts(); 666 Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists... 667 if (!PosOpts.empty() && PosOpts[0]->getNumOccurancesFlag() == ConsumeAfter) 668 CAOpt = PosOpts[0]; 669 670 for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) { 671 cerr << " " << PosOpts[i]->HelpStr; 672 switch (PosOpts[i]->getNumOccurancesFlag()) { 673 case Optional: cerr << "?"; break; 674 case ZeroOrMore: cerr << "*"; break; 675 case Required: break; 676 case OneOrMore: cerr << "+"; break; 677 case ConsumeAfter: 678 default: 679 assert(0 && "Unknown NumOccurances Flag Value!"); 680 } 681 } 682 683 // Print the consume after option info if it exists... 684 if (CAOpt) cerr << " " << CAOpt->HelpStr; 685 686 cerr << "\n\n"; 687 688 // Compute the maximum argument length... 689 MaxArgLen = 0; 690 for (unsigned i = 0, e = Options.size(); i != e; ++i) 691 MaxArgLen = std::max(MaxArgLen, Options[i].second->getOptionWidth()); 692 693 cerr << "OPTIONS:\n"; 694 for (unsigned i = 0, e = Options.size(); i != e; ++i) 695 Options[i].second->printOptionInfo(MaxArgLen); 696 697 // Halt the program if help information is printed 698 exit(1); 699 } 700 }; 701 702 703 704 // Define the two HelpPrinter instances that are used to print out help, or 705 // help-hidden... 706 // 707 HelpPrinter NormalPrinter(false); 708 HelpPrinter HiddenPrinter(true); 709 710 cl::opt<HelpPrinter, true, parser<bool> > 711 HOp("help", cl::desc("display available options (--help-hidden for more)"), 712 cl::location(NormalPrinter)); 713 714 cl::opt<HelpPrinter, true, parser<bool> > 715 HHOp("help-hidden", cl::desc("display all available options"), 716 cl::location(HiddenPrinter), cl::Hidden); 717 718 } // End anonymous namespace 719