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 <algorithm> 14 #include <map> 15 #include <set> 16 #include <iostream> 17 18 using namespace cl; 19 20 //===----------------------------------------------------------------------===// 21 // Basic, shared command line option processing machinery... 22 // 23 24 // Return the global command line option vector. Making it a function scoped 25 // static ensures that it will be initialized correctly before its first use. 26 // 27 static std::map<std::string, Option*> *CommandLineOptions = 0; 28 static std::map<std::string, Option*> &getOpts() { 29 if (CommandLineOptions == 0) 30 CommandLineOptions = new std::map<std::string,Option*>(); 31 return *CommandLineOptions; 32 } 33 34 static Option *getOption(const std::string &Str) { 35 if (CommandLineOptions == 0) return 0; 36 std::map<std::string,Option*>::iterator I = CommandLineOptions->find(Str); 37 return I != CommandLineOptions->end() ? I->second : 0; 38 } 39 40 static std::vector<Option*> &getPositionalOpts() { 41 static std::vector<Option*> Positional; 42 return Positional; 43 } 44 45 static void AddArgument(const char *ArgName, Option *Opt) { 46 if (getOption(ArgName)) { 47 std::cerr << "CommandLine Error: Argument '" << ArgName 48 << "' defined more than once!\n"; 49 } else { 50 // Add argument to the argument map! 51 getOpts()[ArgName] = Opt; 52 } 53 } 54 55 // RemoveArgument - It's possible that the argument is no longer in the map if 56 // options have already been processed and the map has been deleted! 57 // 58 static void RemoveArgument(const char *ArgName, Option *Opt) { 59 if (CommandLineOptions == 0) return; 60 assert(getOption(ArgName) == Opt && "Arg not in map!"); 61 CommandLineOptions->erase(ArgName); 62 if (CommandLineOptions->empty()) { 63 delete CommandLineOptions; 64 CommandLineOptions = 0; 65 } 66 } 67 68 static const char *ProgramName = 0; 69 static const char *ProgramOverview = 0; 70 71 static inline bool ProvideOption(Option *Handler, const char *ArgName, 72 const char *Value, int argc, char **argv, 73 int &i) { 74 // Enforce value requirements 75 switch (Handler->getValueExpectedFlag()) { 76 case ValueRequired: 77 if (Value == 0 || *Value == 0) { // No value specified? 78 if (i+1 < argc) { // Steal the next argument, like for '-o filename' 79 Value = argv[++i]; 80 } else { 81 return Handler->error(" requires a value!"); 82 } 83 } 84 break; 85 case ValueDisallowed: 86 if (*Value != 0) 87 return Handler->error(" does not allow a value! '" + 88 std::string(Value) + "' specified."); 89 break; 90 case ValueOptional: break; 91 default: std::cerr << "Bad ValueMask flag! CommandLine usage error:" 92 << Handler->getValueExpectedFlag() << "\n"; abort(); 93 } 94 95 // Run the handler now! 96 return Handler->addOccurrence(ArgName, Value); 97 } 98 99 static bool ProvidePositionalOption(Option *Handler, const std::string &Arg) { 100 int Dummy; 101 return ProvideOption(Handler, Handler->ArgStr, Arg.c_str(), 0, 0, Dummy); 102 } 103 104 105 // Option predicates... 106 static inline bool isGrouping(const Option *O) { 107 return O->getFormattingFlag() == cl::Grouping; 108 } 109 static inline bool isPrefixedOrGrouping(const Option *O) { 110 return isGrouping(O) || O->getFormattingFlag() == cl::Prefix; 111 } 112 113 // getOptionPred - Check to see if there are any options that satisfy the 114 // specified predicate with names that are the prefixes in Name. This is 115 // checked by progressively stripping characters off of the name, checking to 116 // see if there options that satisfy the predicate. If we find one, return it, 117 // otherwise return null. 118 // 119 static Option *getOptionPred(std::string Name, unsigned &Length, 120 bool (*Pred)(const Option*)) { 121 122 Option *Op = getOption(Name); 123 if (Op && Pred(Op)) { 124 Length = Name.length(); 125 return Op; 126 } 127 128 if (Name.size() == 1) return 0; 129 do { 130 Name.erase(Name.end()-1, Name.end()); // Chop off the last character... 131 Op = getOption(Name); 132 133 // Loop while we haven't found an option and Name still has at least two 134 // characters in it (so that the next iteration will not be the empty 135 // string... 136 } while ((Op == 0 || !Pred(Op)) && Name.size() > 1); 137 138 if (Op && Pred(Op)) { 139 Length = Name.length(); 140 return Op; // Found one! 141 } 142 return 0; // No option found! 143 } 144 145 static bool RequiresValue(const Option *O) { 146 return O->getNumOccurrencesFlag() == cl::Required || 147 O->getNumOccurrencesFlag() == cl::OneOrMore; 148 } 149 150 static bool EatsUnboundedNumberOfValues(const Option *O) { 151 return O->getNumOccurrencesFlag() == cl::ZeroOrMore || 152 O->getNumOccurrencesFlag() == cl::OneOrMore; 153 } 154 155 /// ParseCStringVector - Break INPUT up wherever one or more 156 /// whitespace characters are found, and store the resulting tokens in 157 /// OUTPUT. The tokens stored in OUTPUT are dynamically allocated 158 /// using strdup (), so it is the caller's responsibility to free () 159 /// them later. 160 /// 161 static void ParseCStringVector (std::vector<char *> &output, 162 const char *input) { 163 // Characters which will be treated as token separators: 164 static const char *delims = " \v\f\t\r\n"; 165 166 std::string work (input); 167 // Skip past any delims at head of input string. 168 size_t pos = work.find_first_not_of (delims); 169 // If the string consists entirely of delims, then exit early. 170 if (pos == std::string::npos) return; 171 // Otherwise, jump forward to beginning of first word. 172 work = work.substr (pos); 173 // Find position of first delimiter. 174 pos = work.find_first_of (delims); 175 176 while (!work.empty() && pos != std::string::npos) { 177 // Everything from 0 to POS is the next word to copy. 178 output.push_back (strdup (work.substr (0,pos).c_str ())); 179 // Is there another word in the string? 180 size_t nextpos = work.find_first_not_of (delims, pos + 1); 181 if (nextpos != std::string::npos) { 182 // Yes? Then remove delims from beginning ... 183 work = work.substr (work.find_first_not_of (delims, pos + 1)); 184 // and find the end of the word. 185 pos = work.find_first_of (delims); 186 } else { 187 // No? (Remainder of string is delims.) End the loop. 188 work = ""; 189 pos = std::string::npos; 190 } 191 } 192 193 // If `input' ended with non-delim char, then we'll get here with 194 // the last word of `input' in `work'; copy it now. 195 if (!work.empty ()) { 196 output.push_back (strdup (work.c_str ())); 197 } 198 } 199 200 /// ParseEnvironmentOptions - An alternative entry point to the 201 /// CommandLine library, which allows you to read the program's name 202 /// from the caller (as PROGNAME) and its command-line arguments from 203 /// an environment variable (whose name is given in ENVVAR). 204 /// 205 void cl::ParseEnvironmentOptions (const char *progName, const char *envVar, 206 const char *Overview) { 207 // Check args. 208 assert (progName && "Program name not specified"); 209 assert (envVar && "Environment variable name missing"); 210 211 // Get the environment variable they want us to parse options out of. 212 const char *envValue = getenv (envVar); 213 if (!envValue) 214 return; 215 216 // Get program's "name", which we wouldn't know without the caller 217 // telling us. 218 std::vector<char *> newArgv; 219 newArgv.push_back (strdup (progName)); 220 221 // Parse the value of the environment variable into a "command line" 222 // and hand it off to ParseCommandLineOptions(). 223 ParseCStringVector (newArgv, envValue); 224 int newArgc = newArgv.size (); 225 ParseCommandLineOptions (newArgc, &newArgv[0], Overview); 226 227 // Free all the strdup()ed strings. 228 for (std::vector<char *>::iterator i = newArgv.begin (), e = newArgv.end (); 229 i != e; ++i) { 230 free (*i); 231 } 232 } 233 234 void cl::ParseCommandLineOptions(int &argc, char **argv, 235 const char *Overview) { 236 assert((!getOpts().empty() || !getPositionalOpts().empty()) && 237 "No options specified, or ParseCommandLineOptions called more" 238 " than once!"); 239 ProgramName = argv[0]; // Save this away safe and snug 240 ProgramOverview = Overview; 241 bool ErrorParsing = false; 242 243 std::map<std::string, Option*> &Opts = getOpts(); 244 std::vector<Option*> &PositionalOpts = getPositionalOpts(); 245 246 // Check out the positional arguments to collect information about them. 247 unsigned NumPositionalRequired = 0; 248 Option *ConsumeAfterOpt = 0; 249 if (!PositionalOpts.empty()) { 250 if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) { 251 assert(PositionalOpts.size() > 1 && 252 "Cannot specify cl::ConsumeAfter without a positional argument!"); 253 ConsumeAfterOpt = PositionalOpts[0]; 254 } 255 256 // Calculate how many positional values are _required_. 257 bool UnboundedFound = false; 258 for (unsigned i = ConsumeAfterOpt != 0, e = PositionalOpts.size(); 259 i != e; ++i) { 260 Option *Opt = PositionalOpts[i]; 261 if (RequiresValue(Opt)) 262 ++NumPositionalRequired; 263 else if (ConsumeAfterOpt) { 264 // ConsumeAfter cannot be combined with "optional" positional options 265 // unless there is only one positional argument... 266 if (PositionalOpts.size() > 2) 267 ErrorParsing |= 268 Opt->error(" error - this positional option will never be matched, " 269 "because it does not Require a value, and a " 270 "cl::ConsumeAfter option is active!"); 271 } else if (UnboundedFound && !Opt->ArgStr[0]) { 272 // This option does not "require" a value... Make sure this option is 273 // not specified after an option that eats all extra arguments, or this 274 // one will never get any! 275 // 276 ErrorParsing |= Opt->error(" error - option can never match, because " 277 "another positional argument will match an " 278 "unbounded number of values, and this option" 279 " does not require a value!"); 280 } 281 UnboundedFound |= EatsUnboundedNumberOfValues(Opt); 282 } 283 } 284 285 // PositionalVals - A vector of "positional" arguments we accumulate into to 286 // processes at the end... 287 // 288 std::vector<std::string> PositionalVals; 289 290 // If the program has named positional arguments, and the name has been run 291 // across, keep track of which positional argument was named. Otherwise put 292 // the positional args into the PositionalVals list... 293 Option *ActivePositionalArg = 0; 294 295 // Loop over all of the arguments... processing them. 296 bool DashDashFound = false; // Have we read '--'? 297 for (int i = 1; i < argc; ++i) { 298 Option *Handler = 0; 299 const char *Value = ""; 300 const char *ArgName = ""; 301 302 // Check to see if this is a positional argument. This argument is 303 // considered to be positional if it doesn't start with '-', if it is "-" 304 // itself, or if we have seen "--" already. 305 // 306 if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { 307 // Positional argument! 308 if (ActivePositionalArg) { 309 ProvidePositionalOption(ActivePositionalArg, argv[i]); 310 continue; // We are done! 311 } else if (!PositionalOpts.empty()) { 312 PositionalVals.push_back(argv[i]); 313 314 // All of the positional arguments have been fulfulled, give the rest to 315 // the consume after option... if it's specified... 316 // 317 if (PositionalVals.size() >= NumPositionalRequired && 318 ConsumeAfterOpt != 0) { 319 for (++i; i < argc; ++i) 320 PositionalVals.push_back(argv[i]); 321 break; // Handle outside of the argument processing loop... 322 } 323 324 // Delay processing positional arguments until the end... 325 continue; 326 } 327 } else { // We start with a '-', must be an argument... 328 ArgName = argv[i]+1; 329 while (*ArgName == '-') ++ArgName; // Eat leading dashes 330 331 if (*ArgName == 0 && !DashDashFound) { // Is this the mythical "--"? 332 DashDashFound = true; // Yup, take note of that fact... 333 continue; // Don't try to process it as an argument itself. 334 } 335 336 const char *ArgNameEnd = ArgName; 337 while (*ArgNameEnd && *ArgNameEnd != '=') 338 ++ArgNameEnd; // Scan till end of argument name... 339 340 Value = ArgNameEnd; 341 if (*Value) // If we have an equals sign... 342 ++Value; // Advance to value... 343 344 if (*ArgName != 0) { 345 std::string RealName(ArgName, ArgNameEnd); 346 // Extract arg name part 347 std::map<std::string, Option*>::iterator I = Opts.find(RealName); 348 349 if (I == Opts.end() && !*Value && RealName.size() > 1) { 350 // Check to see if this "option" is really a prefixed or grouped 351 // argument... 352 // 353 unsigned Length = 0; 354 Option *PGOpt = getOptionPred(RealName, Length, isPrefixedOrGrouping); 355 356 // If the option is a prefixed option, then the value is simply the 357 // rest of the name... so fall through to later processing, by 358 // setting up the argument name flags and value fields. 359 // 360 if (PGOpt && PGOpt->getFormattingFlag() == cl::Prefix) { 361 ArgNameEnd = ArgName+Length; 362 Value = ArgNameEnd; 363 I = Opts.find(std::string(ArgName, ArgNameEnd)); 364 assert(I->second == PGOpt); 365 } else if (PGOpt) { 366 // This must be a grouped option... handle all of them now... 367 assert(isGrouping(PGOpt) && "Broken getOptionPred!"); 368 369 do { 370 // Move current arg name out of RealName into RealArgName... 371 std::string RealArgName(RealName.begin(),RealName.begin()+Length); 372 RealName.erase(RealName.begin(), RealName.begin()+Length); 373 374 // Because ValueRequired is an invalid flag for grouped arguments, 375 // we don't need to pass argc/argv in... 376 // 377 assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired && 378 "Option can not be cl::Grouping AND cl::ValueRequired!"); 379 int Dummy; 380 ErrorParsing |= ProvideOption(PGOpt, RealArgName.c_str(), "", 381 0, 0, Dummy); 382 383 // Get the next grouping option... 384 if (!RealName.empty()) 385 PGOpt = getOptionPred(RealName, Length, isGrouping); 386 } while (!RealName.empty() && PGOpt); 387 388 if (RealName.empty()) // Processed all of the options, move on 389 continue; // to the next argv[] value... 390 391 // If RealName is not empty, that means we did not match one of the 392 // options! This is an error. 393 // 394 I = Opts.end(); 395 } 396 } 397 398 Handler = I != Opts.end() ? I->second : 0; 399 } 400 } 401 402 if (Handler == 0) { 403 std::cerr << "Unknown command line argument '" << argv[i] << "'. Try: '" 404 << argv[0] << " --help'\n"; 405 ErrorParsing = true; 406 continue; 407 } 408 409 // Check to see if this option accepts a comma separated list of values. If 410 // it does, we have to split up the value into multiple values... 411 if (Handler->getMiscFlags() & CommaSeparated) { 412 std::string Val(Value); 413 std::string::size_type Pos = Val.find(','); 414 415 while (Pos != std::string::npos) { 416 // Process the portion before the comma... 417 ErrorParsing |= ProvideOption(Handler, ArgName, 418 std::string(Val.begin(), 419 Val.begin()+Pos).c_str(), 420 argc, argv, i); 421 // Erase the portion before the comma, AND the comma... 422 Val.erase(Val.begin(), Val.begin()+Pos+1); 423 Value += Pos+1; // Increment the original value pointer as well... 424 425 // Check for another comma... 426 Pos = Val.find(','); 427 } 428 } 429 430 // If this is a named positional argument, just remember that it is the 431 // active one... 432 if (Handler->getFormattingFlag() == cl::Positional) 433 ActivePositionalArg = Handler; 434 else 435 ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i); 436 } 437 438 // Check and handle positional arguments now... 439 if (NumPositionalRequired > PositionalVals.size()) { 440 std::cerr << "Not enough positional command line arguments specified!\n" 441 << "Must specify at least " << NumPositionalRequired 442 << " positional arguments: See: " << argv[0] << " --help\n"; 443 ErrorParsing = true; 444 445 446 } else if (ConsumeAfterOpt == 0) { 447 // Positional args have already been handled if ConsumeAfter is specified... 448 unsigned ValNo = 0, NumVals = PositionalVals.size(); 449 for (unsigned i = 0, e = PositionalOpts.size(); i != e; ++i) { 450 if (RequiresValue(PositionalOpts[i])) { 451 ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]); 452 --NumPositionalRequired; // We fulfilled our duty... 453 } 454 455 // If we _can_ give this option more arguments, do so now, as long as we 456 // do not give it values that others need. 'Done' controls whether the 457 // option even _WANTS_ any more. 458 // 459 bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required; 460 while (NumVals-ValNo > NumPositionalRequired && !Done) { 461 switch (PositionalOpts[i]->getNumOccurrencesFlag()) { 462 case cl::Optional: 463 Done = true; // Optional arguments want _at most_ one value 464 // FALL THROUGH 465 case cl::ZeroOrMore: // Zero or more will take all they can get... 466 case cl::OneOrMore: // One or more will take all they can get... 467 ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]); 468 break; 469 default: 470 assert(0 && "Internal error, unexpected NumOccurrences flag in " 471 "positional argument processing!"); 472 } 473 } 474 } 475 } else { 476 assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size()); 477 unsigned ValNo = 0; 478 for (unsigned j = 1, e = PositionalOpts.size(); j != e; ++j) 479 if (RequiresValue(PositionalOpts[j])) 480 ErrorParsing |= ProvidePositionalOption(PositionalOpts[j], 481 PositionalVals[ValNo++]); 482 483 // Handle the case where there is just one positional option, and it's 484 // optional. In this case, we want to give JUST THE FIRST option to the 485 // positional option and keep the rest for the consume after. The above 486 // loop would have assigned no values to positional options in this case. 487 // 488 if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty()) 489 ErrorParsing |= ProvidePositionalOption(PositionalOpts[1], 490 PositionalVals[ValNo++]); 491 492 // Handle over all of the rest of the arguments to the 493 // cl::ConsumeAfter command line option... 494 for (; ValNo != PositionalVals.size(); ++ValNo) 495 ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt, 496 PositionalVals[ValNo]); 497 } 498 499 // Loop over args and make sure all required args are specified! 500 for (std::map<std::string, Option*>::iterator I = Opts.begin(), 501 E = Opts.end(); I != E; ++I) { 502 switch (I->second->getNumOccurrencesFlag()) { 503 case Required: 504 case OneOrMore: 505 if (I->second->getNumOccurrences() == 0) { 506 I->second->error(" must be specified at least once!"); 507 ErrorParsing = true; 508 } 509 // Fall through 510 default: 511 break; 512 } 513 } 514 515 // Free all of the memory allocated to the map. Command line options may only 516 // be processed once! 517 delete CommandLineOptions; 518 CommandLineOptions = 0; 519 PositionalOpts.clear(); 520 521 // If we had an error processing our arguments, don't let the program execute 522 if (ErrorParsing) exit(1); 523 } 524 525 //===----------------------------------------------------------------------===// 526 // Option Base class implementation 527 // 528 529 bool Option::error(std::string Message, const char *ArgName) { 530 if (ArgName == 0) ArgName = ArgStr; 531 if (ArgName[0] == 0) 532 std::cerr << HelpStr; // Be nice for positional arguments 533 else 534 std::cerr << "-" << ArgName; 535 std::cerr << " option" << Message << "\n"; 536 return true; 537 } 538 539 bool Option::addOccurrence(const char *ArgName, const std::string &Value) { 540 NumOccurrences++; // Increment the number of times we have been seen 541 542 switch (getNumOccurrencesFlag()) { 543 case Optional: 544 if (NumOccurrences > 1) 545 return error(": may only occur zero or one times!", ArgName); 546 break; 547 case Required: 548 if (NumOccurrences > 1) 549 return error(": must occur exactly one time!", ArgName); 550 // Fall through 551 case OneOrMore: 552 case ZeroOrMore: 553 case ConsumeAfter: break; 554 default: return error(": bad num occurrences flag value!"); 555 } 556 557 return handleOccurrence(ArgName, Value); 558 } 559 560 // addArgument - Tell the system that this Option subclass will handle all 561 // occurrences of -ArgStr on the command line. 562 // 563 void Option::addArgument(const char *ArgStr) { 564 if (ArgStr[0]) 565 AddArgument(ArgStr, this); 566 567 if (getFormattingFlag() == Positional) 568 getPositionalOpts().push_back(this); 569 else if (getNumOccurrencesFlag() == ConsumeAfter) { 570 if (!getPositionalOpts().empty() && 571 getPositionalOpts().front()->getNumOccurrencesFlag() == ConsumeAfter) 572 error("Cannot specify more than one option with cl::ConsumeAfter!"); 573 getPositionalOpts().insert(getPositionalOpts().begin(), this); 574 } 575 } 576 577 void Option::removeArgument(const char *ArgStr) { 578 if (ArgStr[0]) 579 RemoveArgument(ArgStr, this); 580 581 if (getFormattingFlag() == Positional) { 582 std::vector<Option*>::iterator I = 583 std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this); 584 assert(I != getPositionalOpts().end() && "Arg not registered!"); 585 getPositionalOpts().erase(I); 586 } else if (getNumOccurrencesFlag() == ConsumeAfter) { 587 assert(!getPositionalOpts().empty() && getPositionalOpts()[0] == this && 588 "Arg not registered correctly!"); 589 getPositionalOpts().erase(getPositionalOpts().begin()); 590 } 591 } 592 593 594 // getValueStr - Get the value description string, using "DefaultMsg" if nothing 595 // has been specified yet. 596 // 597 static const char *getValueStr(const Option &O, const char *DefaultMsg) { 598 if (O.ValueStr[0] == 0) return DefaultMsg; 599 return O.ValueStr; 600 } 601 602 //===----------------------------------------------------------------------===// 603 // cl::alias class implementation 604 // 605 606 // Return the width of the option tag for printing... 607 unsigned alias::getOptionWidth() const { 608 return std::strlen(ArgStr)+6; 609 } 610 611 // Print out the option for the alias... 612 void alias::printOptionInfo(unsigned GlobalWidth) const { 613 unsigned L = std::strlen(ArgStr); 614 std::cerr << " -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - " 615 << HelpStr << "\n"; 616 } 617 618 619 620 //===----------------------------------------------------------------------===// 621 // Parser Implementation code... 622 // 623 624 // basic_parser implementation 625 // 626 627 // Return the width of the option tag for printing... 628 unsigned basic_parser_impl::getOptionWidth(const Option &O) const { 629 unsigned Len = std::strlen(O.ArgStr); 630 if (const char *ValName = getValueName()) 631 Len += std::strlen(getValueStr(O, ValName))+3; 632 633 return Len + 6; 634 } 635 636 // printOptionInfo - Print out information about this option. The 637 // to-be-maintained width is specified. 638 // 639 void basic_parser_impl::printOptionInfo(const Option &O, 640 unsigned GlobalWidth) const { 641 std::cerr << " -" << O.ArgStr; 642 643 if (const char *ValName = getValueName()) 644 std::cerr << "=<" << getValueStr(O, ValName) << ">"; 645 646 std::cerr << std::string(GlobalWidth-getOptionWidth(O), ' ') << " - " 647 << O.HelpStr << "\n"; 648 } 649 650 651 652 653 // parser<bool> implementation 654 // 655 bool parser<bool>::parse(Option &O, const char *ArgName, 656 const std::string &Arg, bool &Value) { 657 if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || 658 Arg == "1") { 659 Value = true; 660 } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") { 661 Value = false; 662 } else { 663 return O.error(": '" + Arg + 664 "' is invalid value for boolean argument! Try 0 or 1"); 665 } 666 return false; 667 } 668 669 // parser<int> implementation 670 // 671 bool parser<int>::parse(Option &O, const char *ArgName, 672 const std::string &Arg, int &Value) { 673 char *End; 674 Value = (int)strtol(Arg.c_str(), &End, 0); 675 if (*End != 0) 676 return O.error(": '" + Arg + "' value invalid for integer argument!"); 677 return false; 678 } 679 680 // parser<unsigned> implementation 681 // 682 bool parser<unsigned>::parse(Option &O, const char *ArgName, 683 const std::string &Arg, unsigned &Value) { 684 char *End; 685 long long int V = strtoll(Arg.c_str(), &End, 0); 686 Value = (unsigned)V; 687 if (*End != 0 || V < 0 || Value != V) 688 return O.error(": '" + Arg + "' value invalid for uint argument!"); 689 return false; 690 } 691 692 // parser<double>/parser<float> implementation 693 // 694 static bool parseDouble(Option &O, const std::string &Arg, double &Value) { 695 const char *ArgStart = Arg.c_str(); 696 char *End; 697 Value = strtod(ArgStart, &End); 698 if (*End != 0) 699 return O.error(": '" +Arg+ "' value invalid for floating point argument!"); 700 return false; 701 } 702 703 bool parser<double>::parse(Option &O, const char *AN, 704 const std::string &Arg, double &Val) { 705 return parseDouble(O, Arg, Val); 706 } 707 708 bool parser<float>::parse(Option &O, const char *AN, 709 const std::string &Arg, float &Val) { 710 double dVal; 711 if (parseDouble(O, Arg, dVal)) 712 return true; 713 Val = (float)dVal; 714 return false; 715 } 716 717 718 719 // generic_parser_base implementation 720 // 721 722 // findOption - Return the option number corresponding to the specified 723 // argument string. If the option is not found, getNumOptions() is returned. 724 // 725 unsigned generic_parser_base::findOption(const char *Name) { 726 unsigned i = 0, e = getNumOptions(); 727 std::string N(Name); 728 729 while (i != e) 730 if (getOption(i) == N) 731 return i; 732 else 733 ++i; 734 return e; 735 } 736 737 738 // Return the width of the option tag for printing... 739 unsigned generic_parser_base::getOptionWidth(const Option &O) const { 740 if (O.hasArgStr()) { 741 unsigned Size = std::strlen(O.ArgStr)+6; 742 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 743 Size = std::max(Size, (unsigned)std::strlen(getOption(i))+8); 744 return Size; 745 } else { 746 unsigned BaseSize = 0; 747 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) 748 BaseSize = std::max(BaseSize, (unsigned)std::strlen(getOption(i))+8); 749 return BaseSize; 750 } 751 } 752 753 // printOptionInfo - Print out information about this option. The 754 // to-be-maintained width is specified. 755 // 756 void generic_parser_base::printOptionInfo(const Option &O, 757 unsigned GlobalWidth) const { 758 if (O.hasArgStr()) { 759 unsigned L = std::strlen(O.ArgStr); 760 std::cerr << " -" << O.ArgStr << std::string(GlobalWidth-L-6, ' ') 761 << " - " << O.HelpStr << "\n"; 762 763 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 764 unsigned NumSpaces = GlobalWidth-strlen(getOption(i))-8; 765 std::cerr << " =" << getOption(i) << std::string(NumSpaces, ' ') 766 << " - " << getDescription(i) << "\n"; 767 } 768 } else { 769 if (O.HelpStr[0]) 770 std::cerr << " " << O.HelpStr << "\n"; 771 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { 772 unsigned L = std::strlen(getOption(i)); 773 std::cerr << " -" << getOption(i) << std::string(GlobalWidth-L-8, ' ') 774 << " - " << getDescription(i) << "\n"; 775 } 776 } 777 } 778 779 780 //===----------------------------------------------------------------------===// 781 // --help and --help-hidden option implementation 782 // 783 namespace { 784 785 class HelpPrinter { 786 unsigned MaxArgLen; 787 const Option *EmptyArg; 788 const bool ShowHidden; 789 790 // isHidden/isReallyHidden - Predicates to be used to filter down arg lists. 791 inline static bool isHidden(std::pair<std::string, Option *> &OptPair) { 792 return OptPair.second->getOptionHiddenFlag() >= Hidden; 793 } 794 inline static bool isReallyHidden(std::pair<std::string, Option *> &OptPair) { 795 return OptPair.second->getOptionHiddenFlag() == ReallyHidden; 796 } 797 798 public: 799 HelpPrinter(bool showHidden) : ShowHidden(showHidden) { 800 EmptyArg = 0; 801 } 802 803 void operator=(bool Value) { 804 if (Value == false) return; 805 806 // Copy Options into a vector so we can sort them as we like... 807 std::vector<std::pair<std::string, Option*> > Options; 808 copy(getOpts().begin(), getOpts().end(), std::back_inserter(Options)); 809 810 // Eliminate Hidden or ReallyHidden arguments, depending on ShowHidden 811 Options.erase(std::remove_if(Options.begin(), Options.end(), 812 std::ptr_fun(ShowHidden ? isReallyHidden : isHidden)), 813 Options.end()); 814 815 // Eliminate duplicate entries in table (from enum flags options, f.e.) 816 { // Give OptionSet a scope 817 std::set<Option*> OptionSet; 818 for (unsigned i = 0; i != Options.size(); ++i) 819 if (OptionSet.count(Options[i].second) == 0) 820 OptionSet.insert(Options[i].second); // Add new entry to set 821 else 822 Options.erase(Options.begin()+i--); // Erase duplicate 823 } 824 825 if (ProgramOverview) 826 std::cerr << "OVERVIEW:" << ProgramOverview << "\n"; 827 828 std::cerr << "USAGE: " << ProgramName << " [options]"; 829 830 // Print out the positional options... 831 std::vector<Option*> &PosOpts = getPositionalOpts(); 832 Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists... 833 if (!PosOpts.empty() && PosOpts[0]->getNumOccurrencesFlag() == ConsumeAfter) 834 CAOpt = PosOpts[0]; 835 836 for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) { 837 if (PosOpts[i]->ArgStr[0]) 838 std::cerr << " --" << PosOpts[i]->ArgStr; 839 std::cerr << " " << PosOpts[i]->HelpStr; 840 } 841 842 // Print the consume after option info if it exists... 843 if (CAOpt) std::cerr << " " << CAOpt->HelpStr; 844 845 std::cerr << "\n\n"; 846 847 // Compute the maximum argument length... 848 MaxArgLen = 0; 849 for (unsigned i = 0, e = Options.size(); i != e; ++i) 850 MaxArgLen = std::max(MaxArgLen, Options[i].second->getOptionWidth()); 851 852 std::cerr << "OPTIONS:\n"; 853 for (unsigned i = 0, e = Options.size(); i != e; ++i) 854 Options[i].second->printOptionInfo(MaxArgLen); 855 856 // Halt the program if help information is printed 857 exit(1); 858 } 859 }; 860 861 862 863 // Define the two HelpPrinter instances that are used to print out help, or 864 // help-hidden... 865 // 866 HelpPrinter NormalPrinter(false); 867 HelpPrinter HiddenPrinter(true); 868 869 cl::opt<HelpPrinter, true, parser<bool> > 870 HOp("help", cl::desc("display available options (--help-hidden for more)"), 871 cl::location(NormalPrinter), cl::ValueDisallowed); 872 873 cl::opt<HelpPrinter, true, parser<bool> > 874 HHOp("help-hidden", cl::desc("display all available options"), 875 cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed); 876 877 } // End anonymous namespace 878