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