blob: 3c0ac1ac693bbcf07c970567e132c52c3ce309ff [file] [log] [blame]
Chris Lattnercee8f9a2001-11-27 00:03:19 +00001//===- Support/CommandLine.h - Flexible Command line parser ------*- C++ -*--=//
2//
3// This class implements a command line argument processor that is useful when
4// creating a tool. It provides a simple, minimalistic interface that is easily
5// extensible and supports nonlocal (library) command line options.
6//
7// Note that rather than trying to figure out what this code does, you could try
8// reading the library documentation located in docs/CommandLine.html
9//
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_SUPPORT_COMMANDLINE_H
13#define LLVM_SUPPORT_COMMANDLINE_H
14
15#include <string>
16#include <vector>
17#include <utility>
18#include <stdarg.h>
19
20namespace cl { // Short namespace to make usage concise
21
22//===----------------------------------------------------------------------===//
23// ParseCommandLineOptions - Minimalistic command line option processing entry
24//
25void cl::ParseCommandLineOptions(int &argc, char **argv,
26 const char *Overview = 0,
27 int Flags = 0);
28
29// ParserOptions - This set of option is use to control global behavior of the
30// command line processor.
31//
32enum ParserOptions {
33 // DisableSingleLetterArgGrouping - With this option enabled, multiple letter
34 // options are allowed to bunch together with only a single hyphen for the
35 // whole group. This allows emulation of the behavior that ls uses for
36 // example: ls -la === ls -l -a Providing this option, disables this.
37 //
38 DisableSingleLetterArgGrouping = 0x0001,
39
40 // EnableSingleLetterArgValue - This option allows arguments that are
41 // otherwise unrecognized to match single letter flags that take a value.
42 // This is useful for cases like a linker, where options are typically of the
43 // form '-lfoo' or '-L../../include' where -l or -L are the actual flags.
44 //
45 EnableSingleLetterArgValue = 0x0002,
46};
47
48
49//===----------------------------------------------------------------------===//
50// Global flags permitted to be passed to command line arguments
51
52enum FlagsOptions {
53 NoFlags = 0x00, // Marker to make explicit that we have no flags
54 Default = 0x00, // Equally, marker to use the default flags
55
56 GlobalsMask = 0x80,
57};
58
59enum NumOccurances { // Flags for the number of occurances allowed...
60 Optional = 0x01, // Zero or One occurance
61 ZeroOrMore = 0x02, // Zero or more occurances allowed
62 Required = 0x03, // One occurance required
63 OneOrMore = 0x04, // One or more occurances required
64
65 // ConsumeAfter - Marker for a null ("") flag that can be used to indicate
66 // that anything that matches the null marker starts a sequence of options
67 // that all get sent to the null marker. Thus, for example, all arguments
68 // to LLI are processed until a filename is found. Once a filename is found,
69 // all of the succeeding arguments are passed, unprocessed, to the null flag.
70 //
71 ConsumeAfter = 0x05,
72
73 OccurancesMask = 0x07,
74};
75
76enum ValueExpected { // Is a value required for the option?
77 ValueOptional = 0x08, // The value can oppear... or not
78 ValueRequired = 0x10, // The value is required to appear!
79 ValueDisallowed = 0x18, // A value may not be specified (for flags)
80 ValueMask = 0x18,
81};
82
83enum OptionHidden { // Control whether -help shows this option
84 NotHidden = 0x20, // Option included in --help & --help-hidden
85 Hidden = 0x40, // -help doesn't, but --help-hidden does
86 ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg
87 HiddenMask = 0x60,
88};
89
90
91//===----------------------------------------------------------------------===//
92// Option Base class
93//
94class Alias;
95class Option {
96 friend void cl::ParseCommandLineOptions(int &, char **, const char *, int);
97 friend class Alias;
98
99 // handleOccurances - Overriden by subclasses to handle the value passed into
100 // an argument. Should return true if there was an error processing the
101 // argument and the program should exit.
102 //
Chris Lattner697954c2002-01-20 22:54:45 +0000103 virtual bool handleOccurance(const char *ArgName, const std::string &Arg) = 0;
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000104
105 virtual enum NumOccurances getNumOccurancesFlagDefault() const {
106 return Optional;
107 }
108 virtual enum ValueExpected getValueExpectedFlagDefault() const {
109 return ValueOptional;
110 }
111 virtual enum OptionHidden getOptionHiddenFlagDefault() const {
112 return NotHidden;
113 }
114
115 int NumOccurances; // The number of times specified
116 const int Flags; // Flags for the argument
117public:
118 const char * const ArgStr; // The argument string itself (ex: "help", "o")
119 const char * const HelpStr; // The descriptive text message for --help
120
121 inline enum NumOccurances getNumOccurancesFlag() const {
122 int NO = Flags & OccurancesMask;
123 return NO ? (enum NumOccurances)NO : getNumOccurancesFlagDefault();
124 }
125 inline enum ValueExpected getValueExpectedFlag() const {
126 int VE = Flags & ValueMask;
127 return VE ? (enum ValueExpected)VE : getValueExpectedFlagDefault();
128 }
129 inline enum OptionHidden getOptionHiddenFlag() const {
130 int OH = Flags & HiddenMask;
131 return OH ? (enum OptionHidden)OH : getOptionHiddenFlagDefault();
132 }
133
134protected:
135 Option(const char *ArgStr, const char *Message, int Flags);
136 Option(int flags) : NumOccurances(0), Flags(flags), ArgStr(""), HelpStr("") {}
137
138public:
139 // Return the width of the option tag for printing...
140 virtual unsigned getOptionWidth() const;
141
142 // printOptionInfo - Print out information about this option. The
143 // to-be-maintained width is specified.
144 //
145 virtual void printOptionInfo(unsigned GlobalWidth) const;
146
147 // addOccurance - Wrapper around handleOccurance that enforces Flags
148 //
Chris Lattner697954c2002-01-20 22:54:45 +0000149 bool addOccurance(const char *ArgName, const std::string &Value);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000150
151 // Prints option name followed by message. Always returns true.
Chris Lattner697954c2002-01-20 22:54:45 +0000152 bool error(std::string Message, const char *ArgName = 0);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000153
154public:
155 inline int getNumOccurances() const { return NumOccurances; }
156 virtual ~Option() {}
157};
158
159
160//===----------------------------------------------------------------------===//
161// Aliased command line option (alias this name to a preexisting name)
162//
163class Alias : public Option {
164 Option &AliasFor;
Chris Lattner697954c2002-01-20 22:54:45 +0000165 virtual bool handleOccurance(const char *ArgName, const std::string &Arg) {
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000166 return AliasFor.handleOccurance(AliasFor.ArgStr, Arg);
167 }
168 virtual enum OptionHidden getOptionHiddenFlagDefault() const {return Hidden;}
169public:
170 inline Alias(const char *ArgStr, const char *Message, int Flags,
171 Option &aliasFor) : Option(ArgStr, Message, Flags),
172 AliasFor(aliasFor) {}
173};
174
175//===----------------------------------------------------------------------===//
176// Boolean/flag command line option
177//
178class Flag : public Option {
179 bool Value;
Chris Lattner697954c2002-01-20 22:54:45 +0000180 virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000181public:
182 inline Flag(const char *ArgStr, const char *Message, int Flags = 0,
183 bool DefaultVal = 0) : Option(ArgStr, Message, Flags),
184 Value(DefaultVal) {}
185 operator const bool() const { return Value; }
186 inline bool operator=(bool Val) { Value = Val; return Val; }
187};
188
189
190
191//===----------------------------------------------------------------------===//
192// Integer valued command line option
193//
194class Int : public Option {
195 int Value;
Chris Lattner697954c2002-01-20 22:54:45 +0000196 virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000197 virtual enum ValueExpected getValueExpectedFlagDefault() const {
198 return ValueRequired;
199 }
200public:
201 inline Int(const char *ArgStr, const char *Help, int Flags = 0,
202 int DefaultVal = 0) : Option(ArgStr, Help, Flags),
203 Value(DefaultVal) {}
204 inline operator int() const { return Value; }
205 inline int operator=(int Val) { Value = Val; return Val; }
206};
207
208
209//===----------------------------------------------------------------------===//
210// String valued command line option
211//
Chris Lattner697954c2002-01-20 22:54:45 +0000212class String : public Option, public std::string {
213 virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000214 virtual enum ValueExpected getValueExpectedFlagDefault() const {
215 return ValueRequired;
216 }
217public:
218 inline String(const char *ArgStr, const char *Help, int Flags = 0,
219 const char *DefaultVal = "")
Chris Lattner697954c2002-01-20 22:54:45 +0000220 : Option(ArgStr, Help, Flags), std::string(DefaultVal) {}
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000221
Chris Lattner697954c2002-01-20 22:54:45 +0000222 inline const std::string &operator=(const std::string &Val) {
223 return std::string::operator=(Val);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000224 }
225};
226
227
228//===----------------------------------------------------------------------===//
229// String list command line option
230//
Chris Lattner697954c2002-01-20 22:54:45 +0000231class StringList : public Option, public std::vector<std::string> {
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000232
233 virtual enum NumOccurances getNumOccurancesFlagDefault() const {
234 return ZeroOrMore;
235 }
236 virtual enum ValueExpected getValueExpectedFlagDefault() const {
237 return ValueRequired;
238 }
Chris Lattner697954c2002-01-20 22:54:45 +0000239 virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000240
241public:
242 inline StringList(const char *ArgStr, const char *Help, int Flags = 0)
243 : Option(ArgStr, Help, Flags) {}
244};
245
246
247//===----------------------------------------------------------------------===//
248// Enum valued command line option
249//
250#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, ENUMVAL, DESC
251#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, ENUMVAL, DESC
252
253// EnumBase - Base class for all enum/varargs related argument types...
254class EnumBase : public Option {
255protected:
256 // Use a vector instead of a map, because the lists should be short,
257 // the overhead is less, and most importantly, it keeps them in the order
258 // inserted so we can print our option out nicely.
Chris Lattner697954c2002-01-20 22:54:45 +0000259 std::vector<std::pair<const char *, std::pair<int, const char *> > > ValueMap;
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000260
261 inline EnumBase(const char *ArgStr, const char *Help, int Flags)
262 : Option(ArgStr, Help, Flags) {}
263 inline EnumBase(int Flags) : Option(Flags) {}
264
265 // processValues - Incorporate the specifed varargs arglist into the
266 // ValueMap.
267 //
268 void processValues(va_list Vals);
269
270 // registerArgs - notify the system about these new arguments
271 void registerArgs();
272
273public:
274 // Turn an enum into the arg name that activates it
275 const char *getArgName(int ID) const;
276 const char *getArgDescription(int ID) const;
277};
278
279class EnumValueBase : public EnumBase {
280protected:
281 int Value;
282 inline EnumValueBase(const char *ArgStr, const char *Help, int Flags)
283 : EnumBase(ArgStr, Help, Flags) {}
284 inline EnumValueBase(int Flags) : EnumBase(Flags) {}
285
286 // handleOccurance - Set Value to the enum value specified by Arg
Chris Lattner697954c2002-01-20 22:54:45 +0000287 virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000288
289 // Return the width of the option tag for printing...
290 virtual unsigned getOptionWidth() const;
291
292 // printOptionInfo - Print out information about this option. The
293 // to-be-maintained width is specified.
294 //
295 virtual void printOptionInfo(unsigned GlobalWidth) const;
296};
297
298template <class E> // The enum we are representing
299class Enum : public EnumValueBase {
300 virtual enum ValueExpected getValueExpectedFlagDefault() const {
301 return ValueRequired;
302 }
303public:
304 inline Enum(const char *ArgStr, int Flags, const char *Help, ...)
305 : EnumValueBase(ArgStr, Help, Flags) {
306 va_list Values;
307 va_start(Values, Help);
308 processValues(Values);
309 va_end(Values);
310 Value = ValueMap.front().second.first; // Grab default value
311 }
312
313 inline operator E() const { return (E)Value; }
314 inline E operator=(E Val) { Value = Val; return Val; }
315};
316
317
318//===----------------------------------------------------------------------===//
319// Enum flags command line option
320//
321class EnumFlagsBase : public EnumValueBase {
322 virtual enum ValueExpected getValueExpectedFlagDefault() const {
323 return ValueDisallowed;
324 }
325protected:
Chris Lattner697954c2002-01-20 22:54:45 +0000326 virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000327 inline EnumFlagsBase(int Flags) : EnumValueBase(Flags) {}
328
329 // Return the width of the option tag for printing...
330 virtual unsigned getOptionWidth() const;
331
332 // printOptionInfo - Print out information about this option. The
333 // to-be-maintained width is specified.
334 //
335 virtual void printOptionInfo(unsigned GlobalWidth) const;
336};
337
338template <class E> // The enum we are representing
339class EnumFlags : public EnumFlagsBase {
340public:
341 inline EnumFlags(int Flags, ...) : EnumFlagsBase(Flags) {
342 va_list Values;
343 va_start(Values, Flags);
344 processValues(Values);
345 va_end(Values);
346 registerArgs();
347 Value = ValueMap.front().second.first; // Grab default value
348 }
349
350 inline operator E() const { return (E)Value; }
351 inline E operator=(E Val) { Value = Val; return Val; }
352};
353
354
355//===----------------------------------------------------------------------===//
356// Enum list command line option
357//
358class EnumListBase : public EnumBase {
359 virtual enum NumOccurances getNumOccurancesFlagDefault() const {
360 return ZeroOrMore;
361 }
362 virtual enum ValueExpected getValueExpectedFlagDefault() const {
363 return ValueDisallowed;
364 }
365protected:
Chris Lattner697954c2002-01-20 22:54:45 +0000366 std::vector<int> Values; // The options specified so far.
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000367
368 inline EnumListBase(int Flags)
369 : EnumBase(Flags) {}
Chris Lattner697954c2002-01-20 22:54:45 +0000370 virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
Chris Lattnercee8f9a2001-11-27 00:03:19 +0000371
372 // Return the width of the option tag for printing...
373 virtual unsigned getOptionWidth() const;
374
375 // printOptionInfo - Print out information about this option. The
376 // to-be-maintained width is specified.
377 //
378 virtual void printOptionInfo(unsigned GlobalWidth) const;
379public:
380 inline unsigned size() { return Values.size(); }
381};
382
383template <class E> // The enum we are representing
384class EnumList : public EnumListBase {
385public:
386 inline EnumList(int Flags, ...) : EnumListBase(Flags) {
387 va_list Values;
388 va_start(Values, Flags);
389 processValues(Values);
390 va_end(Values);
391 registerArgs();
392 }
393 inline E operator[](unsigned i) const { return (E)Values[i]; }
394 inline E &operator[](unsigned i) { return (E&)Values[i]; }
395};
396
397} // End namespace cl
398
399#endif