blob: f00b8865aff6bc9819de368f63ac98a8eedd7e7d [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001-2010 Gianni Mariani
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16//
17// As a special exception, you may use this file as part of a free software
18// library without restriction. Specifically, if other files instantiate
19// templates or use macros or inline functions from this file, or you compile
20// this file and link it with other files to produce an executable, this
21// file does not by itself cause the resulting executable to be covered by
22// the GNU General Public License. This exception does not however
23// invalidate any other reasons why the executable file might be covered by
24// the GNU General Public License.
25//
26// This exception applies only to the code released under the name GNU
27// Common C++. If you copy code from other releases into a copy of GNU
28// Common C++, as the General Public License permits, the exception does
29// not apply to the code that you add in this way. To avoid misleading
30// anyone as to the status of such modified files, you must delete
31// this exception notice from them.
32//
33// If you write modifications of your own for GNU Common C++, it is your choice
34// whether to permit this exception to apply to your modifications.
35// If you do not wish that, delete this exception notice.
36//
37
38/**
39 * @file cmdoptns.h
40 * @short Command line option parsing interface.
41 **/
42
43#ifndef CCXX_CMDOPTNS_H_
44#define CCXX_CMDOPTNS_H_
45
46#ifndef CCXX_STRING_H_
47#include <cc++/string.h>
48#endif
49
50#ifdef CCXX_NAMESPACES
51namespace ost {
52#endif
53
54class CommandOption;
55class CommandOptionParse;
56
57/**
58 * This defines a linked list head pointer for all the command line
59 * options that use the default list. It will most likely
60 * be used in most cases without being explicitly referenced in application
61 * code. It is a default value of various method's parameters.
62 *
63 */
64extern __EXPORT CommandOption * defaultCommandOptionList;
65
66/**
67 * CommandOption is the base class for all command line options. Command
68 * line options can be defined statically and used when constructing
69 * a command line parser onject using makeCommandOptionParse. This serves
70 * only as a base class to CommandOptionWithArg, CommandOptionRest or
71 * CommandOptionNoArg which can also be used to derive more complex
72 * classes or even entire applications.
73 *
74 * @author Gianni Mariani <gianni@mariani.ws>
75 */
76class __EXPORT CommandOption {
77public:
78
79 /**
80 * Long option name, these will be preceded with "--" on the command line.
81 * e.g. --file foo.x
82 */
83 const char * optionName;
84
85 /**
86 * option letter, these will be preceded with "-" on the command line.
87 * e.g. -f foo.x
88 */
89 const char * optionLetter;
90
91 /**
92 * A short description of the option for Usage messages.
93 * e.g. Usage: mycommand : blah
94 * -f, --file \<DESCRIPTION here\>
95 */
96 const char * description;
97
98 /**
99 * OptionType is for denoting what type of option this is, with an
100 * arg, without an arg or the trailing args.
101 * @short Option type
102 */
103 enum OptionType {
104 /**
105 * This option is associated with a value
106 */
107 hasArg,
108 /**
109 * This option is a flag only
110 */
111 noArg,
112 /**
113 * Remaining of the command line arguments
114 */
115 trailing,
116 /**
117 * Collect values that are not a value to an option
118 */
119 collect
120 };
121
122 /**
123 * This command option's OptionType.
124 */
125 OptionType optionType; // HasArg, NoArg or Trailing
126
127 /**
128 * True if this parameter is required. If the parameter is not supplied
129 * and required is true, an error will be flagged in the option processor.
130 */
131 bool required; // Option is required - fail without it
132
133 /**
134 * This next CommandOption in this list of options or nil if no more
135 * options exist.
136 */
137 CommandOption * next;
138
139 /**
140 * A virtual destructor just in case.
141 */
142 virtual ~CommandOption();
143
144 /**
145 * CommandOption contructor. Note the default values for required and
146 * ppNext.
147 *
148 * @param inOptionName long option name
149 * @param inOptionLetter short letter name
150 * @param inDescription short description of the option
151 * @param inOptionType the type of this option
152 * @param inRequired true if option is required
153 * @param ppNext the linked list header
154 */
155 CommandOption(
156 const char * inOptionName,
157 const char * inOptionLetter,
158 const char * inDescription,
159 OptionType inOptionType,
160 bool inRequired = false,
161 CommandOption ** ppNext = & defaultCommandOptionList
162 );
163
164 /**
165 * foundOption is called by the CommandOptionParse object during the parsing
166 * of the command line options.
167 *
168 * @param cop pointer to the command option parser
169 * @param value the value of this option
170 */
171 virtual void foundOption( CommandOptionParse * cop, const char * value = 0 );
172
173 /**
174 * foundOption is called by the CommandOptionParse object during the parsing
175 * of the command line options.
176 *
177 * @param cop pointer to the command option parser
178 * @param value an array of values of this option
179 * @param num number of values in the array
180 */
181 virtual void foundOption( CommandOptionParse * cop, const char ** value, int num );
182
183 /**
184 * Once parsing of command line options is complete, this method is called.
185 * This can be used to perform last minute checks on the options collected.
186 *
187 * @param cop pointer to the command option parser
188 */
189 virtual void parseDone( CommandOptionParse * cop );
190
191 /**
192 * Once CommandOption objects have completed parsing and there are no
193 * errors they may have some specific tasks to perform. PerformTask
194 * must return.
195 *
196 * @param cop pointer to the command option parser
197 */
198 virtual void performTask( CommandOptionParse * cop );
199
200 /**
201 * For fields with the required flag set, this method is used to determine
202 * if the Option has satisfied it's required status. The default methods
203 * simply returns true if any values have been found. This could be specialized
204 * to return true based on some other criteria.
205 */
206 virtual bool hasValue();
207
208};
209
210/**
211 * Derived class of CommandOption for options that have a value associated with them.
212 * Classes CommandOptionRest and CommandOptionArg derive from this class.
213 */
214class __EXPORT CommandOptionWithArg : public CommandOption {
215public:
216
217 /**
218 * Array of list of values collected for this option.
219 */
220 const char ** values;
221
222 /**
223 * Number of values in the values array.
224 */
225 int numValue;
226
227 /**
228 * CommandOptionWithArg contructor. Note the default values for required and
229 * ppNext.
230 *
231 * @param inOptionName long option name
232 * @param inOptionLetter short letter name
233 * @param inDescription short description of the option
234 * @param inOptionType the type of this option
235 * @param inRequired true if option is required
236 * @param ppNext the linked list header
237 */
238 CommandOptionWithArg(
239 const char * inOptionName,
240 const char * inOptionLetter,
241 const char * inDescription,
242 OptionType inOptionType,
243 bool inRequired = false,
244 CommandOption ** ppNext = & defaultCommandOptionList
245 );
246
247 virtual ~CommandOptionWithArg();
248
249 virtual void foundOption( CommandOptionParse * cop, const char * value = 0 );
250 virtual void foundOption( CommandOptionParse * cop, const char ** value, int num );
251 virtual bool hasValue();
252};
253
254/**
255 * Class for options with an argument e.g. --option value .
256 */
257class __EXPORT CommandOptionArg : public CommandOptionWithArg {
258public:
259
260 /**
261 * CommandOptionArg contructor. This sets the optionType for this
262 * object to HasArg.
263 *
264 * @param inOptionName long option name
265 * @param inOptionLetter short letter name
266 * @param inDescription short description of the option
267 * @param inRequired true if option is required
268 * @param ppNext the linked list header
269 */
270 CommandOptionArg(
271 const char * inOptionName,
272 const char * inOptionLetter,
273 const char * inDescription,
274 bool inRequired = false,
275 CommandOption ** ppNext = & defaultCommandOptionList
276 );
277
278 virtual ~CommandOptionArg();
279
280
281};
282
283/**
284 * It only makes sense to have a single one of these set and it is
285 * exclusive with CommandOptionCollect. It is the option that takes the rest
286 * of the command line options that are not part of any other options.
287 * e.g. "strace -ofile command arg1 arg2". The "command arg1 arg2" part is
288 * placed in objects of this class.
289 *
290 * @short CommandOption to take the rest of the command line
291 */
292class __EXPORT CommandOptionRest : public CommandOptionWithArg {
293public:
294
295 /**
296 * CommandOptionRest contructor. This sets the optionType for this
297 * object to Trailing.
298 *
299 * @param inOptionName long option name
300 * @param inOptionLetter short letter name
301 * @param inDescription short description of the option
302 * @param inRequired true if option is required
303 * @param ppNext the linked list header
304 */
305 CommandOptionRest(
306 const char * inOptionName,
307 const char * inOptionLetter,
308 const char * inDescription,
309 bool inRequired = false,
310 CommandOption ** ppNext = & defaultCommandOptionList
311 );
312
313};
314
315/**
316 * It only makes sense to have a single one of these set and it is also
317 * exclusive with CommandOptionRest. This makes parameter collecting
318 * behave line the Unix "cat" command.
319 *
320 * @short CommandOption to collect parameters that are not options.
321 */
322class __EXPORT CommandOptionCollect : public CommandOptionWithArg {
323public:
324
325 /**
326 * CommandOptionRest contructor. This sets the optionType for this
327 * object to Collect.
328 *
329 * @param inOptionName long option name
330 * @param inOptionLetter short letter name
331 * @param inDescription short description of the option
332 * @param inRequired true if option is required
333 * @param ppNext the linked list header
334 */
335 CommandOptionCollect(
336 const char * inOptionName,
337 const char * inOptionLetter,
338 const char * inDescription,
339 bool inRequired = false,
340 CommandOption ** ppNext = & defaultCommandOptionList
341 );
342
343};
344
345/**
346 * CommandOption type for flags.
347 */
348class __EXPORT CommandOptionNoArg : public CommandOption {
349public:
350
351 /**
352 * The number of times this value has been set.
353 */
354 int numSet; // The number of times this argument is set
355
356 /**
357 * CommandOptionArg contructor. This sets the optionType for this
358 * object to NoArg.
359 *
360 * @param inOptionName long option name
361 * @param inOptionLetter short letter name
362 * @param inDescription short description of the option
363 * @param inRequired true if option is required
364 * @param ppNext the linked list header
365 */
366 CommandOptionNoArg(
367 const char * inOptionName,
368 const char * inOptionLetter,
369 const char * inDescription,
370 bool inRequired = false,
371 CommandOption ** ppNext = & defaultCommandOptionList
372 );
373
374 /**
375 * CommandOptionNoArg::foundOption will evpect a nil "value" passed in.
376 */
377 virtual void foundOption( CommandOptionParse * cop, const char * value = 0 );
378
379};
380
381/**
382 * This is the CommandOptionParse interface class. To implement this object you can
383 * call makeCommandOptionParse(); This will instantiate a dynamically allocated
384 * version of this class and parse the command line for the list of command options
385 * that are passed in.
386 *
387 * @author Gianni Mariani <gianni@mariani.ws>
388 */
389
390class __EXPORT CommandOptionParse {
391public:
392
393 /**
394 * Virtual destructor needed so that the object may be correctly deleted.
395 */
396 virtual ~CommandOptionParse() = 0;
397
398 /**
399 * Get the value of the error flag set if the parser encountered errors.
400 */
401 virtual bool argsHaveError() = 0;
402
403 /**
404 * Return a string of text describing the list of errors encountered.
405 */
406 virtual const char * printErrors() = 0;
407
408 /**
409 * Return a string that contains the usage description of this list of paramaters.
410 */
411 virtual const char * printUsage() = 0;
412
413 /**
414 * Register an error with this parser. This string will be appended to the
415 * errors already buffered in this object.
416 */
417 virtual void registerError( const char * errMsg ) = 0;
418
419 /**
420 * The method should be invoked by the main code once it has determined that
421 * the application should be started.
422 */
423 virtual void performTask() = 0;
424
425};
426
427/**
428 * makeCommandOptionParse will create an implementation of a CommandOptionParse
429 * object. This particular implementation is a wrapper around getopt_long(3).
430 * That interface unfortunatly does not provide enough information to give
431 * the best error messages with malformed input. If the implementation changes
432 * there is a good chance that the binary interface will remain the same.
433 *
434 */
435__EXPORT CommandOptionParse * makeCommandOptionParse(
436 int argc,
437 char ** argv,
438 const char * comment,
439 CommandOption * options = defaultCommandOptionList
440);
441
442#ifdef CCXX_NAMESPACES
443}
444#endif
445
446#endif
447
448/** EMACS **
449 * Local variables:
450 * mode: c++
451 * c-basic-offset: 4
452 * End:
453 */
454