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 void Option::removeArgument(const char *ArgStr) { 439 if (ArgStr[0]) { 440 assert(getOpts()[ArgStr] == this && "Arg not in map!"); 441 getOpts().erase(ArgStr); 442 } else if (getFormattingFlag() == Positional) { 443 vector<Option*>::iterator I = 444 std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this); 445 assert(I != getPositionalOpts().end() && "Arg not registered!"); 446 getPositionalOpts().erase(I); 447 } else if (getNumOccurancesFlag() == ConsumeAfter) { 448 assert(!getPositionalOpts().empty() && getPositionalOpts()[0] == this && 449 "Arg not registered correctly!"); 450 getPositionalOpts().erase(getPositionalOpts().begin()); 451 } 452 } 453 454 455 // getValueStr - Get the value description string, using "DefaultMsg" if nothing 456 // has been specified yet. 457 // 458 static const char *getValueStr(const Option &O, const char *DefaultMsg) { 459 if (O.ValueStr[0] == 0) return DefaultMsg; 460 return O.ValueStr; 461 } 462 463 //===----------------------------------------------------------------------===// 464 // cl::alias class implementation 465 // 466 467 // Return the width of the option tag for printing... 468 unsigned alias::getOptionWidth() const { 469 return std::strlen(ArgStr)+6; 470 } 471 472 // Print out the option for the alias... 473 void alias::printOptionInfo(unsigned GlobalWidth) const { 474 unsigned L = std::strlen(ArgStr); 475 cerr << " -" << ArgStr << string(GlobalWidth-L-6, ' ') << " - " 476 << HelpStr << "\n"; 477 } 478 479 480 481 //===----------------------------------------------------------------------===// 482 // Parser Implementation code... 483 // 484 485 // parser<bool> implementation 486 // 487 bool parser<bool>::parseImpl(Option &O, const string &Arg, bool &Value) { 488 if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || 489 Arg == "1") { 490 Value = true; 491 } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") { 492 Value = false; 493 } else { 494 return O.error(": '" + Arg + 495 "' is invalid value for boolean argument! Try 0 or 1"); 496 } 497 return false; 498 } 499 500 // Return the width of the option tag for printing... 501 unsigned parser<bool>::getOptionWidth(const Option &O) const { 502 return std::strlen(O.ArgStr)+6; 503 } 504 505 // printOptionInfo - Print out information about this option. The 506 // to-be-maintained width is specified. 507 // 508 void parser<bool>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{ 509 unsigned L = std::strlen(O.ArgStr); 510 cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ') << " - " 511 << O.HelpStr << "\n"; 512 } 513 514 515 516 // parser<int> implementation 517 // 518 bool parser<int>::parseImpl(Option &O, const string &Arg, int &Value) { 519 const char *ArgStart = Arg.c_str(); 520 char *End; 521 Value = (int)strtol(ArgStart, &End, 0); 522 if (*End != 0) 523 return O.error(": '" + Arg + "' value invalid for integer argument!"); 524 return false; 525 } 526 527 // Return the width of the option tag for printing... 528 unsigned parser<int>::getOptionWidth(const Option &O) const { 529 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "int"))+9; 530 } 531 532 // printOptionInfo - Print out information about this option. The 533 // to-be-maintained width is specified. 534 // 535 void parser<int>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{ 536 cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "int") << ">" 537 << string(GlobalWidth-getOptionWidth(O), ' ') << " - " 538 << O.HelpStr << "\n"; 539 } 540 541 542 // parser<double> implementation 543 // 544 bool parser<double>::parseImpl(Option &O, const string &Arg, double &Value) { 545 const char *ArgStart = Arg.c_str(); 546 char *End; 547 Value = strtod(ArgStart, &End); 548 if (*End != 0) 549 return O.error(": '" +Arg+ "' value invalid for floating point argument!"); 550 return false; 551 } 552 553 // Return the width of the option tag for printing... 554 unsigned parser<double>::getOptionWidth(const Option &O) const { 555 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "number"))+9; 556 } 557 558 // printOptionInfo - Print out information about this option. The 559 // to-be-maintained width is specified. 560 // 561 void parser<double>::printOptionInfo(const Option &O, 562 unsigned GlobalWidth) const{ 563 cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "number") << ">" 564 << string(GlobalWidth-getOptionWidth(O), ' ') 565 << " - " << O.HelpStr << "\n"; 566 } 567 568 569 // parser<string> implementation 570 // 571 572 // Return the width of the option tag for printing... 573 unsigned parser<string>::getOptionWidth(const Option &O) const { 574 return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "string"))+9; 575 } 576 577 // printOptionInfo - Print out information about this option. The 578 // to-be-maintained width is specified. 579 // 580 void parser<string>::printOptionInfo(const Option &O, 581 unsigned GlobalWidth) const{ 582 cerr << " -" << O.ArgStr << " <" << getValueStr(O, "string") << ">" 583 << string(GlobalWidth-getOptionWidth(O), ' ') 584 << " - " << O.HelpStr << "\n"; 585 } 586 587 // generic_parser_base implementation 588 // 589 590 // findOption - Return the option number corresponding to the specified 591 // argument string. If the option is not found, getNumOptions() is returned. 592 // 593 unsigned generic_parser_base::findOption(const char *Name) { 594 unsigned i = 0, e = getNumOptions(); 595 string N(Name); 596 597 while (i != e) 598 if (getOption(i) == N) 599 return i; 600 else 601 ++i; 602 return e; 603 } 604 605 606 // Return the width of the option tag for printing... 607 unsigned generic_parser_base::getOptionWidth(const Option &O) const { 608 if (O.hasArgStr()) { 609 unsigned Size = std::strlen(O.ArgStr)+6; 610 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 611 Size = std::max(Size, (unsigned)std::strlen(getOption(i))+8); 612 return Size; 613 } else { 614 unsigned BaseSize = 0; 615 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 616 BaseSize = std::max(BaseSize, (unsigned)std::strlen(getOption(i))+8); 617 return BaseSize; 618 } 619 } 620 621 // printOptionInfo - Print out information about this option. The 622 // to-be-maintained width is specified. 623 // 624 void generic_parser_base::printOptionInfo(const Option &O, 625 unsigned GlobalWidth) const { 626 if (O.hasArgStr()) { 627 unsigned L = std::strlen(O.ArgStr); 628 cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ') 629 << " - " << O.HelpStr << "\n"; 630 631 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 632 unsigned NumSpaces = GlobalWidth-strlen(getOption(i))-8; 633 cerr << " =" << getOption(i) << string(NumSpaces, ' ') << " - " 634 << getDescription(i) << "\n"; 635 } 636 } else { 637 if (O.HelpStr[0]) 638 cerr << " " << O.HelpStr << "\n"; 639 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 640 unsigned L = std::strlen(getOption(i)); 641 cerr << " -" << getOption(i) << string(GlobalWidth-L-8, ' ') << " - " 642 << getDescription(i) << "\n"; 643 } 644 } 645 } 646 647 648 //===----------------------------------------------------------------------===// 649 // --help and --help-hidden option implementation 650 // 651 namespace { 652 653 class HelpPrinter { 654 unsigned MaxArgLen; 655 const Option *EmptyArg; 656 const bool ShowHidden; 657 658 // isHidden/isReallyHidden - Predicates to be used to filter down arg lists. 659 inline static bool isHidden(pair<string, Option *> &OptPair) { 660 return OptPair.second->getOptionHiddenFlag() >= Hidden; 661 } 662 inline static bool isReallyHidden(pair<string, Option *> &OptPair) { 663 return OptPair.second->getOptionHiddenFlag() == ReallyHidden; 664 } 665 666 public: 667 HelpPrinter(bool showHidden) : ShowHidden(showHidden) { 668 EmptyArg = 0; 669 } 670 671 void operator=(bool Value) { 672 if (Value == false) return; 673 674 // Copy Options into a vector so we can sort them as we like... 675 vector<pair<string, Option*> > Options; 676 copy(getOpts().begin(), getOpts().end(), std::back_inserter(Options)); 677 678 // Eliminate Hidden or ReallyHidden arguments, depending on ShowHidden 679 Options.erase(std::remove_if(Options.begin(), Options.end(), 680 std::ptr_fun(ShowHidden ? isReallyHidden : isHidden)), 681 Options.end()); 682 683 // Eliminate duplicate entries in table (from enum flags options, f.e.) 684 { // Give OptionSet a scope 685 std::set<Option*> OptionSet; 686 for (unsigned i = 0; i != Options.size(); ++i) 687 if (OptionSet.count(Options[i].second) == 0) 688 OptionSet.insert(Options[i].second); // Add new entry to set 689 else 690 Options.erase(Options.begin()+i--); // Erase duplicate 691 } 692 693 if (ProgramOverview) 694 cerr << "OVERVIEW:" << ProgramOverview << "\n"; 695 696 cerr << "USAGE: " << ProgramName << " [options]"; 697 698 // Print out the positional options... 699 vector<Option*> &PosOpts = getPositionalOpts(); 700 Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists... 701 if (!PosOpts.empty() && PosOpts[0]->getNumOccurancesFlag() == ConsumeAfter) 702 CAOpt = PosOpts[0]; 703 704 for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) { 705 cerr << " " << PosOpts[i]->HelpStr; 706 switch (PosOpts[i]->getNumOccurancesFlag()) { 707 case Optional: cerr << "?"; break; 708 case ZeroOrMore: cerr << "*"; break; 709 case Required: break; 710 case OneOrMore: cerr << "+"; break; 711 case ConsumeAfter: 712 default: 713 assert(0 && "Unknown NumOccurances Flag Value!"); 714 } 715 } 716 717 // Print the consume after option info if it exists... 718 if (CAOpt) cerr << " " << CAOpt->HelpStr; 719 720 cerr << "\n\n"; 721 722 // Compute the maximum argument length... 723 MaxArgLen = 0; 724 for (unsigned i = 0, e = Options.size(); i != e; ++i) 725 MaxArgLen = std::max(MaxArgLen, Options[i].second->getOptionWidth()); 726 727 cerr << "OPTIONS:\n"; 728 for (unsigned i = 0, e = Options.size(); i != e; ++i) 729 Options[i].second->printOptionInfo(MaxArgLen); 730 731 // Halt the program if help information is printed 732 exit(1); 733 } 734 }; 735 736 737 738 // Define the two HelpPrinter instances that are used to print out help, or 739 // help-hidden... 740 // 741 HelpPrinter NormalPrinter(false); 742 HelpPrinter HiddenPrinter(true); 743 744 cl::opt<HelpPrinter, true, parser<bool> > 745 HOp("help", cl::desc("display available options (--help-hidden for more)"), 746 cl::location(NormalPrinter)); 747 748 cl::opt<HelpPrinter, true, parser<bool> > 749 HHOp("help-hidden", cl::desc("display all available options"), 750 cl::location(HiddenPrinter), cl::Hidden); 751 752 } // End anonymous namespace 753