Large scale changes to implement new command line argument facility
[oota-llvm.git] / include / llvm / Tools / CommandLine.h
1 //===-- llvm/Tools/CommandLine.h - Command line parser for tools -*- 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 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TOOLS_COMMANDLINE_H
10 #define LLVM_TOOLS_COMMANDLINE_H
11
12 #include <string>
13 #include <vector>
14 #include <utility>
15 #include <stdarg.h>
16
17 namespace cl {   // Short namespace to make usage concise
18
19 //===----------------------------------------------------------------------===//
20 // ParseCommandLineOptions - Minimalistic command line option processing entry
21 //
22 void cl::ParseCommandLineOptions(int &argc, char **argv,
23                                  const char *Overview = 0);
24
25
26 //===----------------------------------------------------------------------===//
27 // Global flags permitted to be passed to command line arguments
28
29 enum FlagsOptions {
30   NoFlags         = 0x00,      // Marker to make explicit that we have no flags
31
32   // Flags for the number of occurances allowed...
33   Optional        = 0x00,      // Zero or One occurance
34   ZeroOrMore      = 0x01,      // Zero or more occurances allowed
35   Required        = 0x02,      // One occurance required
36   OneOrMore       = 0x03,      // One or more occurances required
37   OccurancesMask  = 0x07,
38
39   // Number of arguments to a value expected...
40   //Optional      = 0x00,      // The value can oppear... or not
41   ValueRequired   = 0x08,      // The value is required to appear!
42   ValueDisallowed = 0x10,      // A value may not be specified (for flags)
43   ValueMask       = 0x18,
44
45   // Control whether -help shows the command line option...
46   Hidden          = 0x20,      // -help doesn't -help-hidden does
47   ReallyHidden    = 0x60,      // Neither -help nor -help-hidden show this arg
48   HiddenMask      = 0x60,
49 };
50
51
52 //===----------------------------------------------------------------------===//
53 // Option Base class
54 //
55 class Option {
56   friend void cl::ParseCommandLineOptions(int &, char **, const char *Overview);
57
58   // handleOccurances - Overriden by subclasses to handle the value passed into
59   // an argument.  Should return true if there was an error processing the
60   // argument and the program should exit.
61   //
62   virtual bool handleOccurance(const char *ArgName, const string &Arg) = 0;
63
64   int NumOccurances;          // The number of times specified
65 public:
66   const char * const ArgStr;  // The argument string itself (ex: "help", "o")
67   const char * const HelpStr; // The descriptive text message for --help
68   const int Flags;            // Flags for the argument
69
70 protected:
71   Option(const char *ArgStr, const char *Message, int Flags);
72   Option(int flags) : ArgStr(""), HelpStr(""), Flags(flags) {}
73
74   // Prints option name followed by message.  Always returns true.
75   bool error(string Message, const char *ArgName = 0);
76
77   // addOccurance - Wrapper around handleOccurance that enforces Flags
78   //
79   bool addOccurance(const char *ArgName, const string &Value);
80
81 public:
82   // Return the width of the option tag for printing...
83   virtual unsigned getOptionWidth() const;
84
85   // printOptionInfo - Print out information about this option.  The 
86   // to-be-maintained width is specified.
87   //
88   virtual void printOptionInfo(unsigned GlobalWidth) const;
89
90 public:
91   inline int getNumOccurances() const { return NumOccurances; }
92   virtual ~Option() {}
93 };
94
95
96 //===----------------------------------------------------------------------===//
97 // Boolean/flag command line option
98 //
99 class Flag : public Option {
100   bool Value;
101   virtual bool handleOccurance(const char *ArgName, const string &Arg);
102 public:
103   inline Flag(const char *ArgStr, const char *Message, int Flags = 0, 
104               bool DefaultVal = 0) : Option(ArgStr, Message, Flags), 
105                                      Value(DefaultVal) {}
106   operator bool() const { return Value; }
107   inline bool getValue() const { return Value; }
108   inline void setValue(bool Val) { Value = Val; }
109 };
110
111
112
113 //===----------------------------------------------------------------------===//
114 // Integer valued command line option
115 //
116 class Int : public Option {
117   int Value;
118   virtual bool handleOccurance(const char *ArgName, const string &Arg);
119 public:
120   inline Int(const char *ArgStr, const char *Help, int Flags = 0,
121              int DefaultVal = 0) : Option(ArgStr, Help, Flags | ValueRequired),
122                                    Value(DefaultVal) {}
123   inline operator int() const { return Value; }
124   inline int getValue() const { return Value; }
125   inline void setValue(int Val) { Value = Val; }
126 };
127
128
129 //===----------------------------------------------------------------------===//
130 // String valued command line option
131 //
132 class String : public Option {
133   string Value;
134   virtual bool handleOccurance(const char *ArgName, const string &Arg);
135 public:
136   inline String(const char *ArgStr, const char *Help, int Flags = 0, 
137                 const char *DefaultVal = "") 
138     : Option(ArgStr, Help, Flags | ValueRequired), Value(DefaultVal) {}
139
140   inline const string &getValue() const { return Value; }
141   inline void setValue(const string &Val) { Value = Val; }
142 };
143
144
145 //===----------------------------------------------------------------------===//
146 // Enum valued command line option
147 //
148 #define clEnumVal(ENUMVAL, DESC) #ENUMVAL, ENUMVAL, DESC
149 #define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, ENUMVAL, DESC
150
151 // EnumBase - Base class for all enum/varargs related argument types...
152 class EnumBase : public Option {
153 protected:
154   // Use a vector instead of a map, because the lists should be short,
155   // the overhead is less, and most importantly, it keeps them in the order
156   // inserted so we can print our option out nicely.
157   vector<pair<const char *, pair<int, const char *> > > ValueMap;
158
159   inline EnumBase(const char *ArgStr, const char *Help, int Flags)
160     : Option(ArgStr, Help, Flags) {}
161   inline EnumBase(int Flags) : Option(Flags) {}
162
163   // processValues - Incorporate the specifed varargs arglist into the 
164   // ValueMap.
165   //
166   void processValues(va_list Vals);
167
168   // registerArgs - notify the system about these new arguments
169   void registerArgs();
170
171 public:
172   // Turn an enum into the arg name that activates it
173   const char *getArgName(int ID) const;
174   const char *getArgDescription(int ID) const;
175 };
176
177 class EnumValueBase : public EnumBase {
178 protected:
179   int Value;
180   inline EnumValueBase(const char *ArgStr, const char *Help, int Flags)
181     : EnumBase(ArgStr, Help, Flags) {}
182   inline EnumValueBase(int Flags) : EnumBase(Flags) {}
183
184   // handleOccurance - Set Value to the enum value specified by Arg
185   virtual bool handleOccurance(const char *ArgName, const string &Arg);
186
187   // Return the width of the option tag for printing...
188   virtual unsigned getOptionWidth() const;
189
190   // printOptionInfo - Print out information about this option.  The 
191   // to-be-maintained width is specified.
192   //
193   virtual void printOptionInfo(unsigned GlobalWidth) const;
194 };
195
196 template <class E>  // The enum we are representing
197 class Enum : public EnumValueBase {
198 public:
199   inline Enum(const char *ArgStr, int Flags, const char *Help, ...)
200     : EnumValueBase(ArgStr, Help, Flags | ValueRequired) {
201     va_list Values;
202     va_start(Values, Help);
203     processValues(Values);
204     va_end(Values);
205     Value = ValueMap.front().second.first; // Grab default value
206   }
207
208   inline E getValue() const { return (E)Value; }
209   inline void setValue(E Val) { Value = (E)Val; }
210 };
211
212
213 //===----------------------------------------------------------------------===//
214 // Enum flags command line option
215 //
216 class EnumFlagsBase : public EnumValueBase {
217 protected:
218   virtual bool handleOccurance(const char *ArgName, const string &Arg);
219   inline EnumFlagsBase(int Flags) : EnumValueBase(Flags | ValueDisallowed) {}
220
221   // Return the width of the option tag for printing...
222   virtual unsigned getOptionWidth() const;
223
224   // printOptionInfo - Print out information about this option.  The 
225   // to-be-maintained width is specified.
226   //
227   virtual void printOptionInfo(unsigned GlobalWidth) const;
228 };
229
230 template <class E>  // The enum we are representing
231 class EnumFlags : public EnumFlagsBase {
232 public:
233   inline EnumFlags(int Flags, ...) : EnumFlagsBase(Flags) {
234     va_list Values;
235     va_start(Values, Flags);
236     processValues(Values);
237     va_end(Values);
238     registerArgs();
239     Value = ValueMap.front().second.first; // Grab default value
240   }
241   inline E getValue() const { return (E)Value; }
242   inline void setValue(E Val) { Value = (E)Val; }
243 };
244
245
246 //===----------------------------------------------------------------------===//
247 // Enum list command line option
248 //
249 class EnumListBase : public EnumBase {
250 protected:
251   vector<int> Values;  // The options specified so far.
252
253   inline EnumListBase(int Flags) 
254     : EnumBase(Flags | ValueDisallowed | ZeroOrMore) {}
255   virtual bool handleOccurance(const char *ArgName, const string &Arg);
256
257   // Return the width of the option tag for printing...
258   virtual unsigned getOptionWidth() const;
259
260   // printOptionInfo - Print out information about this option.  The 
261   // to-be-maintained width is specified.
262   //
263   virtual void printOptionInfo(unsigned GlobalWidth) const;
264 public:
265   inline unsigned size() { return Values.size(); }
266 };
267
268 template <class E>  // The enum we are representing
269 class EnumList : public EnumListBase {
270 public:
271   inline EnumList(int Flags, ...) : EnumListBase(Flags) {
272     va_list Values;
273     va_start(Values, Flags);
274     processValues(Values);
275     va_end(Values);
276     registerArgs();
277   }
278   inline E getValue(unsigned i) const { return (E)Values[i]; }
279   inline E operator[](unsigned i) const { return (E)Values[i]; }
280 };
281
282 } // End namespace cl
283
284 #endif