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