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 // unless there is only one positional argument... 172 if (PositionalOpts.size() > 2) 173 ErrorParsing |= 174 Opt->error(" error - this positional option will never be matched, " 175 "because it does not Require a value, and a " 176 "cl::ConsumeAfter option is active!"); 177 } else if (UnboundedFound) { // This option does not "require" a value... 178 // Make sure this option is not specified after an option that eats all 179 // extra arguments, or this one will never get any! 180 // 181 ErrorParsing |= Opt->error(" error - option can never match, because " 182 "another positional argument will match an " 183 "unbounded number of values, and this option" 184 " does not require a value!"); 185 } 186 UnboundedFound |= EatsUnboundedNumberOfValues(Opt); 187 } 188 } 189 190 // PositionalVals - A vector of "positional" arguments we accumulate into to 191 // processes at the end... 192 // 193 vector<string> PositionalVals; 194 195 // Loop over all of the arguments... processing them. 196 bool DashDashFound = false; // Have we read '--'? 197 for (int i = 1; i < argc; ++i) { 198 Option *Handler = 0; 199 const char *Value = ""; 200 const char *ArgName = ""; 201 202 // Check to see if this is a positional argument. This argument is 203 // considered to be positional if it doesn't start with '-', if it is "-" 204 // itself, or if we have see "--" already. 205 // 206 if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { 207 // Positional argument! 208 if (!PositionalOpts.empty()) { 209 PositionalVals.push_back(argv[i]); 210 211 // All of the positional arguments have been fulfulled, give the rest to 212 // the consume after option... if it's specified... 213 // 214 if (PositionalVals.size() == NumPositionalRequired && 215 ConsumeAfterOpt != 0) { 216 for (++i; i < argc; ++i) 217 PositionalVals.push_back(argv[i]); 218 break; // Handle outside of the argument processing loop... 219 } 220 221 // Delay processing positional arguments until the end... 222 continue; 223 } 224 } else { // We start with a '-', must be an argument... 225 ArgName = argv[i]+1; 226 while (*ArgName == '-') ++ArgName; // Eat leading dashes 227 228 if (*ArgName == 0 && !DashDashFound) { // Is this the mythical "--"? 229 DashDashFound = true; // Yup, take note of that fact... 230 continue; // Don't try to process it as an argument iself. 231 } 232 233 const char *ArgNameEnd = ArgName; 234 while (*ArgNameEnd && *ArgNameEnd != '=') 235 ++ArgNameEnd; // Scan till end of argument name... 236 237 Value = ArgNameEnd; 238 if (*Value) // If we have an equals sign... 239 ++Value; // Advance to value... 240 241 if (*ArgName != 0) { 242 string RealName(ArgName, ArgNameEnd); 243 // Extract arg name part 244 map<string, Option*>::iterator I = Opts.find(RealName); 245 246 if (I == Opts.end() && !*Value && RealName.size() > 1) { 247 // Check to see if this "option" is really a prefixed or grouped 248 // argument... 249 // 250 unsigned Length = 0; 251 Option *PGOpt = getOptionPred(RealName, Length, isPrefixedOrGrouping); 252 253 // If the option is a prefixed option, then the value is simply the 254 // rest of the name... so fall through to later processing, by 255 // setting up the argument name flags and value fields. 256 // 257 if (PGOpt && PGOpt->getFormattingFlag() == cl::Prefix) { 258 ArgNameEnd = ArgName+Length; 259 Value = ArgNameEnd; 260 I = Opts.find(string(ArgName, ArgNameEnd)); 261 assert(I->second == PGOpt); 262 } else if (PGOpt) { 263 // This must be a grouped option... handle all of them now... 264 assert(isGrouping(PGOpt) && "Broken getOptionPred!"); 265 266 do { 267 // Move current arg name out of RealName into RealArgName... 268 string RealArgName(RealName.begin(), RealName.begin()+Length); 269 RealName.erase(RealName.begin(), RealName.begin()+Length); 270 271 // Because ValueRequired is an invalid flag for grouped arguments, 272 // we don't need to pass argc/argv in... 273 // 274 assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired && 275 "Option can not be cl::Grouping AND cl::ValueRequired!"); 276 int Dummy; 277 ErrorParsing |= ProvideOption(PGOpt, RealArgName.c_str(), "", 278 0, 0, Dummy); 279 280 // Get the next grouping option... 281 if (!RealName.empty()) 282 PGOpt = getOptionPred(RealName, Length, isGrouping); 283 } while (!RealName.empty() && PGOpt); 284 285 if (RealName.empty()) // Processed all of the options, move on 286 continue; // to the next argv[] value... 287 288 // If RealName is not empty, that means we did not match one of the 289 // options! This is an error. 290 // 291 I = Opts.end(); 292 } 293 } 294 295 Handler = I != Opts.end() ? I->second : 0; 296 } 297 } 298 299 if (Handler == 0) { 300 cerr << "Unknown command line argument '" << argv[i] << "'. Try: " 301 << argv[0] << " --help'\n"; 302 ErrorParsing = true; 303 continue; 304 } 305 306 ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i); 307 } 308 309 // Check and handle positional arguments now... 310 if (NumPositionalRequired > PositionalVals.size()) { 311 cerr << "Not enough positional command line arguments specified!\n"; 312 cerr << "Must specify at least " << NumPositionalRequired 313 << " positional arguments: See: " << argv[0] << " --help\n"; 314 ErrorParsing = true; 315 316 317 } else if (ConsumeAfterOpt == 0) { 318 // Positional args have already been handled if ConsumeAfter is specified... 319 unsigned ValNo = 0, NumVals = PositionalVals.size(); 320 for (unsigned i = 0, e = PositionalOpts.size(); i != e; ++i) { 321 if (RequiresValue(PositionalOpts[i])) { 322 ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]); 323 --NumPositionalRequired; // We fulfilled our duty... 324 } 325 326 // If we _can_ give this option more arguments, do so now, as long as we 327 // do not give it values that others need. 'Done' controls whether the 328 // option even _WANTS_ any more. 329 // 330 bool Done = PositionalOpts[i]->getNumOccurancesFlag() == cl::Required; 331 while (NumVals-ValNo > NumPositionalRequired && !Done) { 332 switch (PositionalOpts[i]->getNumOccurancesFlag()) { 333 case cl::Optional: 334 Done = true; // Optional arguments want _at most_ one value 335 // FALL THROUGH 336 case cl::ZeroOrMore: // Zero or more will take all they can get... 337 case cl::OneOrMore: // One or more will take all they can get... 338 ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]); 339 break; 340 default: 341 assert(0 && "Internal error, unexpected NumOccurances flag in " 342 "positional argument processing!"); 343 } 344 } 345 } 346 } else { 347 assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size()); 348 unsigned ValNo = 0; 349 for (unsigned j = 1, e = PositionalOpts.size(); j != e; ++j) 350 if (RequiresValue(PositionalOpts[j])) 351 ErrorParsing |= 352 ProvidePositionalOption(PositionalOpts[j], PositionalVals[ValNo++]); 353 354 // Handle over all of the rest of the arguments to the 355 // cl::ConsumeAfter command line option... 356 for (; ValNo != PositionalVals.size(); ++ValNo) 357 ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt, 358 PositionalVals[ValNo]); 359 } 360 361 // Loop over args and make sure all required args are specified! 362 for (map<string, Option*>::iterator I = Opts.begin(), 363 E = Opts.end(); I != E; ++I) { 364 switch (I->second->getNumOccurancesFlag()) { 365 case Required: 366 case OneOrMore: 367 if (I->second->getNumOccurances() == 0) { 368 I->second->error(" must be specified at least once!"); 369 ErrorParsing = true; 370 } 371 // Fall through 372 default: 373 break; 374 } 375 } 376 377 // Free all of the memory allocated to the map. Command line options may only 378 // be processed once! 379 Opts.clear(); 380 PositionalOpts.clear(); 381 382 // If we had an error processing our arguments, don't let the program execute 383 if (ErrorParsing) exit(1); 384 } 385 386 //===----------------------------------------------------------------------===// 387 // Option Base class implementation 388 // 389 390 bool Option::error(string Message, const char *ArgName = 0) { 391 if (ArgName == 0) ArgName = ArgStr; 392 if (ArgName[0] == 0) 393 cerr << HelpStr; // Be nice for positional arguments 394 else 395 cerr << "-" << ArgName; 396 cerr << " option" << Message << "\n"; 397 return true; 398 } 399 400 bool Option::addOccurance(const char *ArgName, const string &Value) { 401 NumOccurances++; // Increment the number of times we have been seen 402 403 switch (getNumOccurancesFlag()) { 404 case Optional: 405 if (NumOccurances > 1) 406 return error(": may only occur zero or one times!", ArgName); 407 break; 408 case Required: 409 if (NumOccurances > 1) 410 return error(": must occur exactly one time!", ArgName); 411 // Fall through 412 case OneOrMore: 413 case ZeroOrMore: 414 case ConsumeAfter: break; 415 default: return error(": bad num occurances flag value!"); 416 } 417 418 return handleOccurance(ArgName, Value); 419 } 420 421 // addArgument - Tell the system that this Option subclass will handle all 422 // occurances of -ArgStr on the command line. 423 // 424 void Option::addArgument(const char *ArgStr) { 425 if (ArgStr[0]) 426 AddArgument(ArgStr, this); 427 else if (getFormattingFlag() == Positional) 428 getPositionalOpts().push_back(this); 429 else if (getNumOccurancesFlag() == ConsumeAfter) { 430 assert((getPositionalOpts().empty() || 431 getPositionalOpts().front()->getNumOccurancesFlag() != ConsumeAfter) 432 && "Cannot specify more than one option with cl::ConsumeAfter " 433 "specified!"); 434 getPositionalOpts().insert(getPositionalOpts().begin(), this); 435 } 436 } 437 438 439 // getValueStr - Get the value description string, using "DefaultMsg" if nothing 440 // has been specified yet. 441 // 442 static const char *getValueStr(const Option &O, const char *DefaultMsg) { 443 if (O.ValueStr[0] == 0) return DefaultMsg; 444 return O.ValueStr; 445 } 446 447 //===----------------------------------------------------------------------===// 448 // cl::alias class implementation 449 // 450 451 // Return the width of the option tag for printing... 452 unsigned alias::getOptionWidth() const { 453 return std::strlen(ArgStr)+6; 454 } 455 456 // Print out the option for the alias... 457 void alias::printOptionInfo(unsigned GlobalWidth) const { 458 unsigned L = std::strlen(ArgStr); 459 cerr << " -" << ArgStr << string(GlobalWidth-L-6, ' ') << " - " 460 << HelpStr << "\n"; 461 } 462 463 464 465 //===----------------------------------------------------------------------===// 466 // Parser Implementation code... 467 // 468 469 // parser<bool> implementation 470 // 471 bool parser<bool>::parseImpl(Option &O, const string &Arg, bool &Value) { 472 if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || 473 Arg == "1") { 474 Value = true; 475 } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") { 476 Value = false; 477 } else { 478 return O.error(": '" + Arg + 479 "' is invalid value for boolean argument! Try 0 or 1"); 480 } 481 return false; 482 } 483 484 // Return the width of the option tag for printing... 485 unsigned parser<bool>::getOptionWidth(const Option &O) const { 486 return std::strlen(O.ArgStr)+6; 487 } 488 489 // printOptionInfo - Print out information about this option. The 490 // to-be-maintained width is specified. 491 // 492 void parser<bool>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{ 493 unsigned L = std::strlen(O.ArgStr); 494 cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ') << " - " 495 << O.HelpStr << "\n"; 496 } 497 498 499 500 // parser<int> implementation 501 // 502 bool parser<int>::parseImpl(Option &O, const string &Arg, int &Value) { 503 const char *ArgStart = Arg.c_str(); 504 char *End; 505 Value = (int)strtol(ArgStart, &End, 0); 506 if (*End != 0) 507 return O.error(": '" + Arg + "' value invalid for integer argument!"); 508 return false; 509 } 510 511 // Return the width of the option tag for printing... 512 unsigned parser<int>::getOptionWidth(const Option &O) const { 513 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "int"))+9; 514 } 515 516 // printOptionInfo - Print out information about this option. The 517 // to-be-maintained width is specified. 518 // 519 void parser<int>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{ 520 cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "int") << ">" 521 << string(GlobalWidth-getOptionWidth(O), ' ') << " - " 522 << O.HelpStr << "\n"; 523 } 524 525 526 // parser<double> implementation 527 // 528 bool parser<double>::parseImpl(Option &O, const string &Arg, double &Value) { 529 const char *ArgStart = Arg.c_str(); 530 char *End; 531 Value = strtod(ArgStart, &End); 532 if (*End != 0) 533 return O.error(": '" +Arg+ "' value invalid for floating point argument!"); 534 return false; 535 } 536 537 // Return the width of the option tag for printing... 538 unsigned parser<double>::getOptionWidth(const Option &O) const { 539 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "number"))+9; 540 } 541 542 // printOptionInfo - Print out information about this option. The 543 // to-be-maintained width is specified. 544 // 545 void parser<double>::printOptionInfo(const Option &O, 546 unsigned GlobalWidth) const{ 547 cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "number") << ">" 548 << string(GlobalWidth-getOptionWidth(O), ' ') 549 << " - " << O.HelpStr << "\n"; 550 } 551 552 553 // parser<string> implementation 554 // 555 556 // Return the width of the option tag for printing... 557 unsigned parser<string>::getOptionWidth(const Option &O) const { 558 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "string"))+9; 559 } 560 561 // printOptionInfo - Print out information about this option. The 562 // to-be-maintained width is specified. 563 // 564 void parser<string>::printOptionInfo(const Option &O, 565 unsigned GlobalWidth) const{ 566 cerr << " -" << O.ArgStr << " <" << getValueStr(O, "string") << ">" 567 << string(GlobalWidth-getOptionWidth(O), ' ') 568 << " - " << O.HelpStr << "\n"; 569 } 570 571 // generic_parser_base implementation 572 // 573 574 // Return the width of the option tag for printing... 575 unsigned generic_parser_base::getOptionWidth(const Option &O) const { 576 if (O.hasArgStr()) { 577 unsigned Size = std::strlen(O.ArgStr)+6; 578 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 579 Size = std::max(Size, (unsigned)std::strlen(getOption(i))+8); 580 return Size; 581 } else { 582 unsigned BaseSize = 0; 583 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 584 BaseSize = std::max(BaseSize, (unsigned)std::strlen(getOption(i))+8); 585 return BaseSize; 586 } 587 } 588 589 // printOptionInfo - Print out information about this option. The 590 // to-be-maintained width is specified. 591 // 592 void generic_parser_base::printOptionInfo(const Option &O, 593 unsigned GlobalWidth) const { 594 if (O.hasArgStr()) { 595 unsigned L = std::strlen(O.ArgStr); 596 cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ') 597 << " - " << O.HelpStr << "\n"; 598 599 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 600 unsigned NumSpaces = GlobalWidth-strlen(getOption(i))-8; 601 cerr << " =" << getOption(i) << string(NumSpaces, ' ') << " - " 602 << getDescription(i) << "\n"; 603 } 604 } else { 605 if (O.HelpStr[0]) 606 cerr << " " << O.HelpStr << "\n"; 607 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 608 unsigned L = std::strlen(getOption(i)); 609 cerr << " -" << getOption(i) << string(GlobalWidth-L-8, ' ') << " - " 610 << getDescription(i) << "\n"; 611 } 612 } 613 } 614 615 616 //===----------------------------------------------------------------------===// 617 // --help and --help-hidden option implementation 618 // 619 namespace { 620 621 class HelpPrinter { 622 unsigned MaxArgLen; 623 const Option *EmptyArg; 624 const bool ShowHidden; 625 626 // isHidden/isReallyHidden - Predicates to be used to filter down arg lists. 627 inline static bool isHidden(pair<string, Option *> &OptPair) { 628 return OptPair.second->getOptionHiddenFlag() >= Hidden; 629 } 630 inline static bool isReallyHidden(pair<string, Option *> &OptPair) { 631 return OptPair.second->getOptionHiddenFlag() == ReallyHidden; 632 } 633 634 public: 635 HelpPrinter(bool showHidden) : ShowHidden(showHidden) { 636 EmptyArg = 0; 637 } 638 639 void operator=(bool Value) { 640 if (Value == false) return; 641 642 // Copy Options into a vector so we can sort them as we like... 643 vector<pair<string, Option*> > Options; 644 copy(getOpts().begin(), getOpts().end(), std::back_inserter(Options)); 645 646 // Eliminate Hidden or ReallyHidden arguments, depending on ShowHidden 647 Options.erase(std::remove_if(Options.begin(), Options.end(), 648 std::ptr_fun(ShowHidden ? isReallyHidden : isHidden)), 649 Options.end()); 650 651 // Eliminate duplicate entries in table (from enum flags options, f.e.) 652 { // Give OptionSet a scope 653 std::set<Option*> OptionSet; 654 for (unsigned i = 0; i != Options.size(); ++i) 655 if (OptionSet.count(Options[i].second) == 0) 656 OptionSet.insert(Options[i].second); // Add new entry to set 657 else 658 Options.erase(Options.begin()+i--); // Erase duplicate 659 } 660 661 if (ProgramOverview) 662 cerr << "OVERVIEW:" << ProgramOverview << "\n"; 663 664 cerr << "USAGE: " << ProgramName << " [options]"; 665 666 // Print out the positional options... 667 vector<Option*> &PosOpts = getPositionalOpts(); 668 Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists... 669 if (!PosOpts.empty() && PosOpts[0]->getNumOccurancesFlag() == ConsumeAfter) 670 CAOpt = PosOpts[0]; 671 672 for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) { 673 cerr << " " << PosOpts[i]->HelpStr; 674 switch (PosOpts[i]->getNumOccurancesFlag()) { 675 case Optional: cerr << "?"; break; 676 case ZeroOrMore: cerr << "*"; break; 677 case Required: break; 678 case OneOrMore: cerr << "+"; break; 679 case ConsumeAfter: 680 default: 681 assert(0 && "Unknown NumOccurances Flag Value!"); 682 } 683 } 684 685 // Print the consume after option info if it exists... 686 if (CAOpt) cerr << " " << CAOpt->HelpStr; 687 688 cerr << "\n\n"; 689 690 // Compute the maximum argument length... 691 MaxArgLen = 0; 692 for (unsigned i = 0, e = Options.size(); i != e; ++i) 693 MaxArgLen = std::max(MaxArgLen, Options[i].second->getOptionWidth()); 694 695 cerr << "OPTIONS:\n"; 696 for (unsigned i = 0, e = Options.size(); i != e; ++i) 697 Options[i].second->printOptionInfo(MaxArgLen); 698 699 // Halt the program if help information is printed 700 exit(1); 701 } 702 }; 703 704 705 706 // Define the two HelpPrinter instances that are used to print out help, or 707 // help-hidden... 708 // 709 HelpPrinter NormalPrinter(false); 710 HelpPrinter HiddenPrinter(true); 711 712 cl::opt<HelpPrinter, true, parser<bool> > 713 HOp("help", cl::desc("display available options (--help-hidden for more)"), 714 cl::location(NormalPrinter)); 715 716 cl::opt<HelpPrinter, true, parser<bool> > 717 HHOp("help-hidden", cl::desc("display all available options"), 718 cl::location(HiddenPrinter), cl::Hidden); 719 720 } // End anonymous namespace 721