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