b07b162a47b5bd3709587f31473fe2de27217776
[oota-llvm.git] / include / Support / CommandLine.h
1 //===- 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
20 namespace cl {   // Short namespace to make usage concise
21
22 //===----------------------------------------------------------------------===//
23 // ParseCommandLineOptions - Minimalistic command line option processing entry
24 //
25 void 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 //
32 enum 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
52 enum 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
59 enum 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
76 enum 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
83 enum 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 //
94 class Alias;
95 class 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   //
103   virtual bool handleOccurance(const char *ArgName, const std::string &Arg) = 0;
104
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
117 public:
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
134 protected:
135   Option(const char *ArgStr, const char *Message, int Flags);
136   Option(int flags) : NumOccurances(0), Flags(flags), ArgStr(""), HelpStr("") {}
137
138 public:
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   //
149   bool addOccurance(const char *ArgName, const std::string &Value);
150
151   // Prints option name followed by message.  Always returns true.
152   bool error(std::string Message, const char *ArgName = 0);
153
154 public:
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 //
163 class Alias : public Option {
164   Option &AliasFor;
165   virtual bool handleOccurance(const char *ArgName, const std::string &Arg) {
166     return AliasFor.handleOccurance(AliasFor.ArgStr, Arg);
167   }
168   virtual enum OptionHidden getOptionHiddenFlagDefault() const {return Hidden;}
169 public:
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 //
178 class Flag : public Option {
179   bool &Value;
180   bool DValue;
181   virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
182 public:
183   inline Flag(const char *ArgStr, const char *Message, int Flags = 0, 
184               bool DefaultVal = false)
185     : Option(ArgStr, Message, Flags), Value(DValue) {
186     Value = DefaultVal;
187   }
188
189   inline Flag(bool &UpdateVal, const char *ArgStr, const char *Message,
190               int Flags = 0, bool DefaultVal = false)
191     : Option(ArgStr, Message, Flags), Value(UpdateVal) {
192     Value = DefaultVal;
193   }
194
195   operator const bool() const { return Value; }
196   inline bool operator=(bool Val) { Value = Val; return Val; }
197 };
198
199
200
201 //===----------------------------------------------------------------------===//
202 // Integer valued command line option
203 //
204 class Int : public Option {
205   int Value;
206   virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
207   virtual enum ValueExpected getValueExpectedFlagDefault() const {
208     return ValueRequired; 
209   }
210 public:
211   inline Int(const char *ArgStr, const char *Help, int Flags = 0,
212              int DefaultVal = 0) : Option(ArgStr, Help, Flags),
213                                    Value(DefaultVal) {}
214   inline operator int() const { return Value; }
215   inline int operator=(int Val) { Value = Val; return Val; }
216 };
217
218
219 //===----------------------------------------------------------------------===//
220 // String valued command line option
221 //
222 class String : public Option, public std::string {
223   virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
224   virtual enum ValueExpected getValueExpectedFlagDefault() const {
225     return ValueRequired; 
226   }
227 public:
228   inline String(const char *ArgStr, const char *Help, int Flags = 0, 
229                 const char *DefaultVal = "") 
230     : Option(ArgStr, Help, Flags), std::string(DefaultVal) {}
231
232   inline const std::string &operator=(const std::string &Val) { 
233     return std::string::operator=(Val);
234   }
235 };
236
237
238 //===----------------------------------------------------------------------===//
239 // String list command line option
240 //
241 class StringList : public Option, public std::vector<std::string> {
242
243   virtual enum NumOccurances getNumOccurancesFlagDefault() const { 
244     return ZeroOrMore;
245   }
246   virtual enum ValueExpected getValueExpectedFlagDefault() const {
247     return ValueRequired;
248   }
249   virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
250
251 public:
252   inline StringList(const char *ArgStr, const char *Help, int Flags = 0)
253     : Option(ArgStr, Help, Flags) {}
254 };
255
256
257 //===----------------------------------------------------------------------===//
258 // Enum valued command line option
259 //
260 #define clEnumVal(ENUMVAL, DESC) #ENUMVAL, ENUMVAL, DESC
261 #define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, ENUMVAL, DESC
262
263 // EnumBase - Base class for all enum/varargs related argument types...
264 class EnumBase : public Option {
265 protected:
266   // Use a vector instead of a map, because the lists should be short,
267   // the overhead is less, and most importantly, it keeps them in the order
268   // inserted so we can print our option out nicely.
269   std::vector<std::pair<const char *, std::pair<int, const char *> > > ValueMap;
270
271   inline EnumBase(const char *ArgStr, const char *Help, int Flags)
272     : Option(ArgStr, Help, Flags) {}
273   inline EnumBase(int Flags) : Option(Flags) {}
274
275   // processValues - Incorporate the specifed varargs arglist into the 
276   // ValueMap.
277   //
278   void processValues(va_list Vals);
279
280   // registerArgs - notify the system about these new arguments
281   void registerArgs();
282
283 public:
284   // Turn an enum into the arg name that activates it
285   const char *getArgName(int ID) const;
286   const char *getArgDescription(int ID) const;
287 };
288
289 class EnumValueBase : public EnumBase {
290 protected:
291   inline EnumValueBase(const char *ArgStr, const char *Help, int Flags)
292     : EnumBase(ArgStr, Help, Flags) {}
293   inline EnumValueBase(int Flags) : EnumBase(Flags) {}
294
295   // handleOccurance - Set Value to the enum value specified by Arg
296   virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
297
298   // Return the width of the option tag for printing...
299   virtual unsigned getOptionWidth() const;
300
301   // printOptionInfo - Print out information about this option.  The 
302   // to-be-maintained width is specified.
303   //
304   virtual void printOptionInfo(unsigned GlobalWidth) const;
305
306   // setValue - Subclasses override this when they need to receive a new value
307   virtual void setValue(int Val) = 0;
308 };
309
310 template <class E>  // The enum we are representing
311 class Enum : public EnumValueBase {
312   virtual enum ValueExpected getValueExpectedFlagDefault() const {
313     return ValueRequired;
314   }
315   E DVal;
316   E &Value;
317
318   // setValue - Subclasses override this when they need to receive a new value
319   virtual void setValue(int Val) { Value = (E)Val; }
320 public:
321   inline Enum(const char *ArgStr, int Flags, const char *Help, ...)
322     : EnumValueBase(ArgStr, Help, Flags), Value(DVal) {
323     va_list Values;
324     va_start(Values, Help);
325     processValues(Values);
326     va_end(Values);
327     Value = (E)ValueMap.front().second.first; // Grab default value
328   }
329
330   inline Enum(E &EUpdate, const char *ArgStr, int Flags, const char *Help, ...)
331     : EnumValueBase(ArgStr, Help, Flags), Value(EUpdate) {
332     va_list Values;
333     va_start(Values, Help);
334     processValues(Values);
335     va_end(Values);
336     Value = (E)ValueMap.front().second.first; // Grab default value
337   }
338
339   inline operator E() const { return Value; }
340   inline E operator=(E Val) { Value = Val; return Val; }
341 };
342
343
344 //===----------------------------------------------------------------------===//
345 // Enum flags command line option
346 //
347 class EnumFlagsBase : public EnumValueBase {
348   virtual enum ValueExpected getValueExpectedFlagDefault() const {
349     return ValueDisallowed;
350   }
351 protected:
352   virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
353   inline EnumFlagsBase(int Flags) : EnumValueBase(Flags) {}
354
355   // Return the width of the option tag for printing...
356   virtual unsigned getOptionWidth() const;
357
358   // printOptionInfo - Print out information about this option.  The 
359   // to-be-maintained width is specified.
360   //
361   virtual void printOptionInfo(unsigned GlobalWidth) const;
362 };
363
364 template <class E>  // The enum we are representing
365 class EnumFlags : public EnumFlagsBase {
366   E DVal;
367   E &Value;
368
369   // setValue - Subclasses override this when they need to receive a new value
370   virtual void setValue(int Val) { Value = (E)Val; }
371 public:
372   inline EnumFlags(int Flags, ...) : EnumFlagsBase(Flags), Value(DVal) {
373     va_list Values;
374     va_start(Values, Flags);
375     processValues(Values);
376     va_end(Values);
377     registerArgs();
378     Value = (E)ValueMap.front().second.first; // Grab default value
379   }
380   inline EnumFlags(E &RV, int Flags, ...) : EnumFlagsBase(Flags), Value(RV) {
381     va_list Values;
382     va_start(Values, Flags);
383     processValues(Values);
384     va_end(Values);
385     registerArgs();
386     Value = (E)ValueMap.front().second.first; // Grab default value
387   }
388
389   inline operator E() const { return (E)Value; }
390   inline E operator=(E Val) { Value = Val; return Val; }
391 };
392
393
394 //===----------------------------------------------------------------------===//
395 // Enum list command line option
396 //
397 class EnumListBase : public EnumBase {
398   virtual enum NumOccurances getNumOccurancesFlagDefault() const { 
399     return ZeroOrMore;
400   }
401   virtual enum ValueExpected getValueExpectedFlagDefault() const {
402     return ValueDisallowed;
403   }
404 protected:
405   std::vector<int> Values;  // The options specified so far.
406
407   inline EnumListBase(int Flags) 
408     : EnumBase(Flags) {}
409   virtual bool handleOccurance(const char *ArgName, const std::string &Arg);
410
411   // Return the width of the option tag for printing...
412   virtual unsigned getOptionWidth() const;
413
414   // printOptionInfo - Print out information about this option.  The 
415   // to-be-maintained width is specified.
416   //
417   virtual void printOptionInfo(unsigned GlobalWidth) const;
418 public:
419   inline unsigned size() { return Values.size(); }
420 };
421
422 template <class E>  // The enum we are representing
423 class EnumList : public EnumListBase {
424 public:
425   inline EnumList(int Flags, ...) : EnumListBase(Flags) {
426     va_list Values;
427     va_start(Values, Flags);
428     processValues(Values);
429     va_end(Values);
430     registerArgs();
431   }
432   inline E  operator[](unsigned i) const { return (E)Values[i]; }
433   inline E &operator[](unsigned i)       { return (E&)Values[i]; }
434 };
435
436 } // End namespace cl
437
438 #endif