CommandLine.cpp revision 697954c15da58bd8b186dbafdedd8b06db770201
1dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===-- CommandLine.cpp - Command line parser implementation --------------===// 2dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 3dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// This class implements a command line argument processor that is useful when 4dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// creating a tool. It provides a simple, minimalistic interface that is easily 5dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// extensible and supports nonlocal (library) command line options. 6dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 703fe1bd149b21855098e9cc9f959c8e8ca80693cChris Lattner// Note that rather than trying to figure out what this code does, you could try 803fe1bd149b21855098e9cc9f959c8e8ca80693cChris Lattner// reading the library documentation located in docs/CommandLine.html 903fe1bd149b21855098e9cc9f959c8e8ca80693cChris Lattner// 10dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 11dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 12cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/CommandLine.h" 13cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/STLExtras.h" 14dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner#include <vector> 15dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner#include <algorithm> 16dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner#include <map> 17dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner#include <set> 18697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner#include <iostream> 19dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerusing namespace cl; 20697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::map; 21697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::pair; 22697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::vector; 23697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::string; 24697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::cerr; 25dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 26dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Return the global command line option vector. Making it a function scoped 27f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner// static ensures that it will be initialized correctly before its first use. 28dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 29dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerstatic map<string, Option*> &getOpts() { 30dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner static map<string,Option*> CommandLineOptions; 31dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return CommandLineOptions; 32dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 33dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 34dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerstatic void AddArgument(const string &ArgName, Option *Opt) { 35dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (getOpts().find(ArgName) != getOpts().end()) { 36dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << "CommandLine Error: Argument '" << ArgName 37dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner << "' specified more than once!\n"; 38dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } else { 39f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // Add argument to the argument map! 40697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner getOpts().insert(std::make_pair(ArgName, Opt)); 41dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 42dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 43dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 44dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerstatic const char *ProgramName = 0; 45dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerstatic const char *ProgramOverview = 0; 46dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 47caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattnerstatic inline bool ProvideOption(Option *Handler, const char *ArgName, 48caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner const char *Value, int argc, char **argv, 49caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner int &i) { 50caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner // Enforce value requirements 51caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner switch (Handler->getValueExpectedFlag()) { 52caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner case ValueRequired: 53caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner if (Value == 0 || *Value == 0) { // No value specified? 54caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner if (i+1 < argc) { // Steal the next argument, like for '-o filename' 55caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner Value = argv[++i]; 56caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner } else { 57caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner return Handler->error(" requires a value!"); 58caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner } 59caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner } 60caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner break; 61caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner case ValueDisallowed: 62caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner if (*Value != 0) 63caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner return Handler->error(" does not allow a value! '" + 64caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner string(Value) + "' specified."); 65caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner break; 66caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner case ValueOptional: break; 67caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner default: cerr << "Bad ValueMask flag! CommandLine usage error:" 68697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner << Handler->getValueExpectedFlag() << "\n"; abort(); 69caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner } 70caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner 71caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner // Run the handler now! 72caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner return Handler->addOccurance(ArgName, Value); 73caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner} 74caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner 75f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner// ValueGroupedArgs - Return true if the specified string is valid as a group 76f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner// of single letter arguments stuck together like the 'ls -la' case. 77f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner// 78f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattnerstatic inline bool ValidGroupedArgs(string Args) { 79f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner for (unsigned i = 0; i < Args.size(); ++i) { 80f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner map<string, Option*>::iterator I = getOpts().find(string(1, Args[i])); 81f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner if (I == getOpts().end()) return false; // Make sure option exists 82f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 83f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // Grouped arguments have no value specified, make sure that if this option 84f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // exists that it can accept no argument. 85f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // 86f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner switch (I->second->getValueExpectedFlag()) { 87f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner case ValueDisallowed: 88f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner case ValueOptional: break; 89f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner default: return false; 90f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner } 91f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner } 92f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 93f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner return true; 94f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner} 95caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner 96dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnervoid cl::ParseCommandLineOptions(int &argc, char **argv, 97f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner const char *Overview = 0, int Flags = 0) { 98dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner ProgramName = argv[0]; // Save this away safe and snug 99dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner ProgramOverview = Overview; 100dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner bool ErrorParsing = false; 101dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 102dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // Loop over all of the arguments... processing them. 103dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (int i = 1; i < argc; ++i) { 104dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Option *Handler = 0; 105dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const char *Value = ""; 106dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const char *ArgName = ""; 107dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (argv[i][0] != '-') { // Unnamed argument? 1083805e4ccfa6b908c5035256ea6ee51e219f029dbChris Lattner map<string, Option*>::iterator I = getOpts().find(""); 1093805e4ccfa6b908c5035256ea6ee51e219f029dbChris Lattner Handler = I != getOpts().end() ? I->second : 0; 110dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Value = argv[i]; 111dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } else { // We start with a - or --, eat dashes 112dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner ArgName = argv[i]+1; 113dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner while (*ArgName == '-') ++ArgName; // Eat leading dashes 114dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 115dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const char *ArgNameEnd = ArgName; 116f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner while (*ArgNameEnd && *ArgNameEnd != '=') 117f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner ++ArgNameEnd; // Scan till end of argument name... 118dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 119dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Value = ArgNameEnd; 120dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (*Value) // If we have an equals sign... 121dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner ++Value; // Advance to value... 122dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 123dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (*ArgName != 0) { 124f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner string RealName(ArgName, ArgNameEnd); 1253805e4ccfa6b908c5035256ea6ee51e219f029dbChris Lattner // Extract arg name part 126f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner map<string, Option*>::iterator I = getOpts().find(RealName); 127f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 128f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner if (I == getOpts().end() && !*Value && RealName.size() > 1) { 129f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // If grouping of single letter arguments is enabled, see if this is a 130f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // legal grouping... 131f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // 132f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner if (!(Flags & DisableSingleLetterArgGrouping) && 133f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner ValidGroupedArgs(RealName)) { 134f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 135f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner for (unsigned i = 0; i < RealName.size(); ++i) { 136f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner char ArgName[2] = { 0, 0 }; int Dummy; 137f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner ArgName[0] = RealName[i]; 138f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner I = getOpts().find(ArgName); 139f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner assert(I != getOpts().end() && "ValidGroupedArgs failed!"); 140f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 141f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // Because ValueRequired is an invalid flag for grouped arguments, 142f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // we don't need to pass argc/argv in... 143f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // 144f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner ErrorParsing |= ProvideOption(I->second, ArgName, "", 145f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 0, 0, Dummy); 146f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner } 147f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner continue; 148f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner } else if (Flags & EnableSingleLetterArgValue) { 149f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // Check to see if the first letter is a single letter argument that 150f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // have a value that is equal to the rest of the string. If this 151f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // is the case, recognize it now. (Example: -lfoo for a linker) 152f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // 153f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner I = getOpts().find(string(1, RealName[0])); 154f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner if (I != getOpts().end()) { 155f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // If we are successful, fall through to later processing, by 156f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // setting up the argument name flags and value fields. 157f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner // 158f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner ArgNameEnd = ArgName+1; 159f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner Value = ArgNameEnd; 160f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner } 161f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner } 162f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner } 163f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 164f78032fe064bdd2b9a19b875261747b7d0a27a73Chris Lattner 1653805e4ccfa6b908c5035256ea6ee51e219f029dbChris Lattner Handler = I != getOpts().end() ? I->second : 0; 166dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 167dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 168dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 169dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (Handler == 0) { 170dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << "Unknown command line argument '" << argv[i] << "'. Try: " 171f038acbee21cfed998451aedd00a81901d299516Chris Lattner << argv[0] << " --help'\n"; 172dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner ErrorParsing = true; 173dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner continue; 174dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 175dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 176caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i); 177dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 178caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner // If this option should consume all arguments that come after it... 179caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner if (Handler->getNumOccurancesFlag() == ConsumeAfter) { 180caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner for (++i; i < argc; ++i) 181caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner ErrorParsing |= ProvideOption(Handler, ArgName, argv[i], argc, argv, i); 182caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner } 183dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 184dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 185dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner // Loop over args and make sure all required args are specified! 186dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner for (map<string, Option*>::iterator I = getOpts().begin(), 187dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner E = getOpts().end(); I != E; ++I) { 188dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner switch (I->second->getNumOccurancesFlag()) { 189dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner case Required: 190dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner case OneOrMore: 191f038acbee21cfed998451aedd00a81901d299516Chris Lattner if (I->second->getNumOccurances() == 0) { 192dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner I->second->error(" must be specified at least once!"); 193f038acbee21cfed998451aedd00a81901d299516Chris Lattner ErrorParsing = true; 194f038acbee21cfed998451aedd00a81901d299516Chris Lattner } 195dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner // Fall through 196dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner default: 197dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner break; 198dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner } 199dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner } 200dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 201dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // Free all of the memory allocated to the vector. Command line options may 202dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // only be processed once! 203dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner getOpts().clear(); 204dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 205dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // If we had an error processing our arguments, don't let the program execute 206dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (ErrorParsing) exit(1); 207dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 208dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 209dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 210dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Option Base class implementation 211dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 212dbab15a2c9accc0242109881e1632137cb97dbc9Chris LattnerOption::Option(const char *argStr, const char *helpStr, int flags) 213dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner : NumOccurances(0), Flags(flags), ArgStr(argStr), HelpStr(helpStr) { 214dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner AddArgument(ArgStr, this); 215dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 216dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 217dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool Option::error(string Message, const char *ArgName = 0) { 218dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (ArgName == 0) ArgName = ArgStr; 219697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cerr << "-" << ArgName << " option" << Message << "\n"; 220dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return true; 221dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 222dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 223dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool Option::addOccurance(const char *ArgName, const string &Value) { 224dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner NumOccurances++; // Increment the number of times we have been seen 225dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 226dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner switch (getNumOccurancesFlag()) { 227dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner case Optional: 228dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (NumOccurances > 1) 229dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return error(": may only occur zero or one times!", ArgName); 230dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner break; 231dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner case Required: 232dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (NumOccurances > 1) 233dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return error(": must occur exactly one time!", ArgName); 234dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // Fall through 235dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner case OneOrMore: 236caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner case ZeroOrMore: 237caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner case ConsumeAfter: break; 238dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner default: return error(": bad num occurances flag value!"); 239dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 240dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 241dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return handleOccurance(ArgName, Value); 242dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 243dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 244dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Return the width of the option tag for printing... 245dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerunsigned Option::getOptionWidth() const { 246dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return std::strlen(ArgStr)+6; 247dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 248dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 249dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnervoid Option::printOptionInfo(unsigned GlobalWidth) const { 250dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned L = std::strlen(ArgStr); 251dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (L == 0) return; // Don't print the empty arg like this! 252dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << " -" << ArgStr << string(GlobalWidth-L-6, ' ') << " - " 253697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner << HelpStr << "\n"; 254dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 255dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 256dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 257dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 258dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Boolean/flag command line option implementation 259dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 260dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 261dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool Flag::handleOccurance(const char *ArgName, const string &Arg) { 262dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || 263dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Arg == "1") { 264dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Value = true; 265dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") { 266dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Value = false; 267dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } else { 268d215fd1f5610033fbe704c975805790530262d26Chris Lattner return error(": '" + Arg + 269d215fd1f5610033fbe704c975805790530262d26Chris Lattner "' is invalid value for boolean argument! Try 0 or 1"); 270dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 271dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 272dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return false; 273dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 274dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 275dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 276dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Integer valued command line option implementation 277dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 278dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool Int::handleOccurance(const char *ArgName, const string &Arg) { 279dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const char *ArgStart = Arg.c_str(); 280dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner char *End; 281dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Value = (int)strtol(ArgStart, &End, 0); 282dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (*End != 0) 283dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return error(": '" + Arg + "' value invalid for integer argument!"); 284dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return false; 285dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 286dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 287dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 288dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// String valued command line option implementation 289dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 290dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool String::handleOccurance(const char *ArgName, const string &Arg) { 2911e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner *this = Arg; 292dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return false; 293dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 294dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 295dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 296d215fd1f5610033fbe704c975805790530262d26Chris Lattner// StringList valued command line option implementation 297d215fd1f5610033fbe704c975805790530262d26Chris Lattner// 298d215fd1f5610033fbe704c975805790530262d26Chris Lattnerbool StringList::handleOccurance(const char *ArgName, const string &Arg) { 299caccd761a6320d9068a44198b9e1b6c3659f8bb5Chris Lattner push_back(Arg); 300d215fd1f5610033fbe704c975805790530262d26Chris Lattner return false; 301d215fd1f5610033fbe704c975805790530262d26Chris Lattner} 302d215fd1f5610033fbe704c975805790530262d26Chris Lattner 303d215fd1f5610033fbe704c975805790530262d26Chris Lattner//===----------------------------------------------------------------------===// 304dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Enum valued command line option implementation 305dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 306dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnervoid EnumBase::processValues(va_list Vals) { 307dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner while (const char *EnumName = va_arg(Vals, const char *)) { 308dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner int EnumVal = va_arg(Vals, int); 309dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const char *EnumDesc = va_arg(Vals, const char *); 310697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner ValueMap.push_back(std::make_pair(EnumName, // Add value to value map 311697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::make_pair(EnumVal, EnumDesc))); 312dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 313dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 314dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 315dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// registerArgs - notify the system about these new arguments 316dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnervoid EnumBase::registerArgs() { 317dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) 318dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner AddArgument(ValueMap[i].first, this); 319dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 320dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 321dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerconst char *EnumBase::getArgName(int ID) const { 322dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) 323dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (ID == ValueMap[i].second.first) return ValueMap[i].first; 324dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return ""; 325dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 326dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerconst char *EnumBase::getArgDescription(int ID) const { 327dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) 328dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (ID == ValueMap[i].second.first) return ValueMap[i].second.second; 329dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return ""; 330dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 331dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 332dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 333dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 334dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool EnumValueBase::handleOccurance(const char *ArgName, const string &Arg) { 335dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned i; 336dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (i = 0; i < ValueMap.size(); ++i) 337dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (ValueMap[i].first == Arg) break; 338dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (i == ValueMap.size()) 339dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return error(": unrecognized alternative '"+Arg+"'!"); 340dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Value = ValueMap[i].second.first; 341dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return false; 342dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 343dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 344dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Return the width of the option tag for printing... 345dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerunsigned EnumValueBase::getOptionWidth() const { 346dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned BaseSize = Option::getOptionWidth(); 347dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) 348697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner BaseSize = std::max(BaseSize, std::strlen(ValueMap[i].first)+8); 349dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return BaseSize; 350dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 351dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 352dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// printOptionInfo - Print out information about this option. The 353dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// to-be-maintained width is specified. 354dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 355dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnervoid EnumValueBase::printOptionInfo(unsigned GlobalWidth) const { 356dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Option::printOptionInfo(GlobalWidth); 357dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) { 358dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned NumSpaces = GlobalWidth-strlen(ValueMap[i].first)-8; 359dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << " =" << ValueMap[i].first << string(NumSpaces, ' ') << " - " 360dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner << ValueMap[i].second.second; 361dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 362dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (i == 0) cerr << " (default)"; 363697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cerr << "\n"; 364dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 365dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 366dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 367dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 368dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Enum flags command line option implementation 369dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 370dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 371dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool EnumFlagsBase::handleOccurance(const char *ArgName, const string &Arg) { 372dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return EnumValueBase::handleOccurance("", ArgName); 373dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 374dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 375dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerunsigned EnumFlagsBase::getOptionWidth() const { 376dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned BaseSize = 0; 377dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) 378697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner BaseSize = std::max(BaseSize, std::strlen(ValueMap[i].first)+6); 379dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return BaseSize; 380dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 381dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 382dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnervoid EnumFlagsBase::printOptionInfo(unsigned GlobalWidth) const { 383dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) { 384dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned L = std::strlen(ValueMap[i].first); 385dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << " -" << ValueMap[i].first << string(GlobalWidth-L-6, ' ') << " - " 386dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner << ValueMap[i].second.second; 387dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (i == 0) cerr << " (default)"; 388697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cerr << "\n"; 389dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 390dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 391dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 392dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 393dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 394dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Enum list command line option implementation 395dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 396dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 397dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerbool EnumListBase::handleOccurance(const char *ArgName, const string &Arg) { 398dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned i; 399dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (i = 0; i < ValueMap.size(); ++i) 400dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (ValueMap[i].first == string(ArgName)) break; 401dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (i == ValueMap.size()) 402dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return error(": CommandLine INTERNAL ERROR", ArgName); 403dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Values.push_back(ValueMap[i].second.first); 404dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return false; 405dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 406dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 407dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Return the width of the option tag for printing... 408dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerunsigned EnumListBase::getOptionWidth() const { 409dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned BaseSize = 0; 410dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) 411697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner BaseSize = std::max(BaseSize, std::strlen(ValueMap[i].first)+6); 412dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return BaseSize; 413dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 414dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 415dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 416dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// printOptionInfo - Print out information about this option. The 417dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// to-be-maintained width is specified. 418dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 419dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnervoid EnumListBase::printOptionInfo(unsigned GlobalWidth) const { 420dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < ValueMap.size(); ++i) { 421dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned L = std::strlen(ValueMap[i].first); 422dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << " -" << ValueMap[i].first << string(GlobalWidth-L-6, ' ') << " - " 423697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner << ValueMap[i].second.second << "\n"; 424dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 425dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 426dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 427dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 428dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner//===----------------------------------------------------------------------===// 429dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// Help option... always automatically provided. 430dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// 431dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnernamespace { 432dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 433dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner// isHidden/isReallyHidden - Predicates to be used to filter down arg lists. 434dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerinline bool isHidden(pair<string, Option *> &OptPair) { 435dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner return OptPair.second->getOptionHiddenFlag() >= Hidden; 436dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 437dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerinline bool isReallyHidden(pair<string, Option *> &OptPair) { 438dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner return OptPair.second->getOptionHiddenFlag() == ReallyHidden; 439dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} 440dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 441dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerclass Help : public Option { 442dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner unsigned MaxArgLen; 443dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const Option *EmptyArg; 444dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const bool ShowHidden; 445dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 446dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner virtual bool handleOccurance(const char *ArgName, const string &Arg) { 447dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // Copy Options into a vector so we can sort them as we like... 448dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner vector<pair<string, Option*> > Options; 449697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner copy(getOpts().begin(), getOpts().end(), std::back_inserter(Options)); 450dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 451dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // Eliminate Hidden or ReallyHidden arguments, depending on ShowHidden 452dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Options.erase(remove_if(Options.begin(), Options.end(), 453697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::ptr_fun(ShowHidden ? isReallyHidden : isHidden)), 454dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Options.end()); 455dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 456dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // Eliminate duplicate entries in table (from enum flags options, f.e.) 457697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::set<Option*> OptionSet; 458dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for (unsigned i = 0; i < Options.size(); ) 459dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (OptionSet.count(Options[i].second) == 0) 460dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner OptionSet.insert(Options[i++].second); // Add to set 461dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner else 462dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Options.erase(Options.begin()+i); // Erase duplicate 463dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 464dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 465dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (ProgramOverview) 466697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cerr << "OVERVIEW:" << ProgramOverview << "\n"; 467dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // TODO: Sort options by some criteria 468dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 469dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << "USAGE: " << ProgramName << " [options]\n\n"; 470dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // TODO: print usage nicer 471dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 472dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner // Compute the maximum argument length... 473dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner MaxArgLen = 0; 474dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for_each(Options.begin(), Options.end(), 475dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner bind_obj(this, &Help::getMaxArgLen)); 476dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 477dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner cerr << "OPTIONS:\n"; 478dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner for_each(Options.begin(), Options.end(), 479dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner bind_obj(this, &Help::printOption)); 480dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 481dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner return true; // Displaying help is cause to terminate the program 482dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 483dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 484dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner void getMaxArgLen(pair<string, Option *> OptPair) { 485dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const Option *Opt = OptPair.second; 486dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner if (Opt->ArgStr[0] == 0) EmptyArg = Opt; // Capture the empty arg if exists 487697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner MaxArgLen = std::max(MaxArgLen, Opt->getOptionWidth()); 488dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 489dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 490dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner void printOption(pair<string, Option *> OptPair) { 491dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner const Option *Opt = OptPair.second; 492dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner Opt->printOptionInfo(MaxArgLen); 493dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 494dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 495dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattnerpublic: 496dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner inline Help(const char *ArgVal, const char *HelpVal, bool showHidden) 497dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner : Option(ArgVal, HelpVal, showHidden ? Hidden : 0), ShowHidden(showHidden) { 498dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner EmptyArg = 0; 499dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner } 500dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner}; 501dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 502dbab15a2c9accc0242109881e1632137cb97dbc9Chris LattnerHelp HelpOp("help", "display available options" 503dc4693dbcf164ec404a3a91c67cf1dbe5f45a8e5Chris Lattner " (--help-hidden for more)", false); 504dbab15a2c9accc0242109881e1632137cb97dbc9Chris LattnerHelp HelpHiddenOpt("help-hidden", "display all available options", true); 505dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner 506dbab15a2c9accc0242109881e1632137cb97dbc9Chris Lattner} // End anonymous namespace 507