CommandLine.h
1//-*-C++-*-
2/***************************************************************************
3 *
4 * Copyright (C) 2009 by Willem van Straten
5 * Licensed under the Academic Free License version 2.1
6 *
7 ***************************************************************************/
8
9// psrchive/Util/genutil/CommandLine.h
10
11#ifndef __CommandLine_h
12#define __CommandLine_h
13
14#include "Reference.h"
15#include "Functor.h"
16#include "tostring.h"
17
18#include <string>
19#include <vector>
20
21#include <getopt.h>
22
24template<typename T>
25struct arg_traits { typedef T unref; };
26
27template<typename T>
28struct arg_traits<const T&> { typedef T unref; };
29
30namespace CommandLine {
31
32 typedef std::pair<std::string,std::string> Help;
33
35 class Item : public Reference::Able
36 {
37 public:
38
39 virtual ~Item () { }
40
42 virtual bool matches (int code) const = 0;
43
45 virtual void handle (const std::string& arg) = 0;
46
48 virtual void set_handled (bool) { /* do nothing by default */ }
49
51 virtual Help get_help () const = 0;
52 };
53
54 class Menu;
55 class Alias;
56
58 class Argument : public Item
59 {
60
61 protected:
62
64 std::string short_name;
65
67 std::string long_name;
68
70 std::string type;
71
73 std::string help;
74
76 std::string long_help;
77
80
82 int val;
83
85 bool* handled;
86
87 friend class Menu;
88 friend class Alias;
89
90 public:
91
92 Argument () { val = 0; has_arg = no_argument; handled = 0; }
93
94 void set_short_name (char c) {
95 if (c=='\0') short_name = "";
96 else short_name = std::string(1,c);
97 }
98 void set_long_name (const std::string& s) { long_name = s; }
99 void set_type (const std::string& s) { type = s; }
100 void set_help (const std::string& s) { help = s; }
101 void set_long_help (const std::string& s) { long_help = s; }
102 void set_has_arg (int h) { has_arg = h; }
103
104 void set_handled (bool f) { if (handled) *handled = f; }
105 void set_notification (bool& f) { handled = &f; };
106
108 bool matches (int c) const { return val == c; }
109
110 Help get_help () const;
111
112 };
113
114
116 class Alias : public Argument
117 {
118
119 protected:
120
122 void set_argument (Argument*);
123
124 public:
125
126 Alias (Argument* a, char short_alias)
127 { set_argument (a); short_name = short_alias;}
128
129 Alias (Argument* a, const std::string& long_alias)
130 { set_argument (a); long_name = long_alias; }
131
132 void set_handled (bool f) { argument->set_handled (f); }
133 void handle (const std::string& arg) { argument->handle (arg); }
134 Help get_help () const;
135 };
136
138 template<typename T>
139 class Value : public Argument
140 {
141 protected:
142
145
146 public:
147
149 Value (T& _value)
150 : value (_value) { has_arg = required_argument; }
151
153 void handle (const std::string& arg) { value = fromstring<T>(arg); }
154 };
155
157 template<typename T>
158 class Value< std::vector<T> > : public Argument
159 {
160 protected:
161
163 std::vector<T>& values;
164
165 public:
166
168 Value (std::vector<T>& _values)
169 : values (_values) { has_arg = required_argument; }
170
172 void handle (const std::string& arg)
173 {
174 values.push_back( fromstring<T>(arg) );
175 }
176
177 };
178
180 template<>
181 class Value<bool> : public Argument
182 {
183 protected:
184
186 bool& value;
187
188 public:
189
191 Value (bool& _value) : value (_value) { }
192
194 void handle (const std::string&) { value = !value; }
195 };
196
198 template<class C, typename M, typename P>
199 class Attribute : public Argument
200 {
201 protected:
202
205
208
211
212 public:
213
215 Attribute (C* _instance, M _method, P _parse)
216 : instance (_instance), method (_method), parse (_parse)
217 { has_arg = required_argument; }
218
220 void handle (const std::string& arg)
221 { (instance->*method) (parse(arg)); }
222 };
223
225 class Parser : public Argument
226 {
227 protected:
228
230 Functor < void( const std::string& ) > action;
231
232 public:
233
235 Parser (Functor < void( const std::string& ) >& _action)
236 { action = _action; has_arg = required_argument; }
237
239 void handle (const std::string& arg)
240 {
241 // std::cerr << "Parser::handle arg='" << arg << "'" << std::endl;
242 action(arg);
243 }
244 };
245
247 class Action : public Argument
248 {
249 protected:
250
252 Functor < void() > action;
253
254 public:
255
257 template<class C, typename M>
258 Action (C* instance, M method)
259 { action = Functor< void() > (instance, method); }
260
262 void handle (const std::string&) { action(); }
263 };
264
266 template<class T>
267 class UnaryAction : public Argument
268 {
269 protected:
270
272 Functor < void(T) > action;
273
276
277 public:
278
280 template<class C, typename M>
281 UnaryAction (C* instance, M method, T arg)
282 { action = Functor< void(T) > (instance, method); argument=arg; }
283
285 void handle (const std::string&) { action(argument); }
286 };
287
288 class Heading : public Item
289 {
290
291 public:
292
294 Heading (const std::string& _text) { text = _text; }
295
297 bool matches (int) const { return false; }
298
300 void handle (const std::string&) { }
301
303 Help get_help () const { return Help(text,""); }
304
305 protected:
306
307 std::string text;
308 };
309
310
312 class Menu : public Reference::Able
313 {
314 public:
315
317 Menu ();
318
319 virtual ~Menu ();
320
322 virtual void set_help_header (const std::string& s)
323 { help_header=s; add_help (); }
324
326 std::string get_help_header () const
327 { return help_header; }
328
330 virtual void set_help_footer (const std::string& s) { help_footer=s; }
331
333 std::string get_help_footer () const { return help_footer; }
334
336 virtual void add_help ();
337
339 virtual void set_version (const std::string& s)
340 { version_info = s; add_version (); }
341
343 virtual void add_version ();
344
346 virtual void parse (int argc, char* const *argv);
347
349 virtual int process_error (int code, char* const *argv);
350
352 virtual void add (Item*);
353
355 virtual void remove (Item*);
356
358 template<typename T>
359 Argument* add (T& value, char name, const char* type = 0)
360 {
361 return add_value (value, name, &Argument::set_short_name, type);
362 }
363
365 template<typename T>
366 Argument* add (T& value, const std::string& name, const char* type = 0)
367 {
368 return add_value (value, name, &Argument::set_long_name, type);
369 }
370
372 Argument* add (Functor< void(const std::string&) > action,
373 char name, const char* type = 0)
374 {
375 return add_parser (action, name, &Argument::set_short_name, type);
376 }
377
379 Argument* add (Functor< void(const std::string&) > action,
380 const std::string& name, const char* type = 0)
381 {
382 return add_parser (action, name, &Argument::set_long_name, type);
383 }
384
386 template<class C, class B, typename T>
387 Argument* add (C* ptr, void (B::*method)(T), char name,
388 const char* type = 0)
389 {
390 return add_attribute (ptr, method,
391 &fromstring< typename arg_traits<T>::unref >,
392 name, &Argument::set_short_name, type);
393 }
394
396 template<class C, class B, typename T>
397 Argument* add (C* ptr, void (B::*method)(T), const std::string& name,
398 const char* type = 0)
399 {
400 return add_attribute (ptr, method,
401 &fromstring< typename arg_traits<T>::unref >,
402 name, &Argument::set_long_name, type);
403 }
404
406 template<class C, typename M, typename P>
407 Argument* add (C* ptr, M method, P parse, char name, const char* type)
408 {
409 return add_attribute (ptr, method, parse,
410 name, &Argument::set_short_name, type);
411 }
412
414 template<class C, typename M, typename P>
415 Argument* add (C* ptr, M method, P parse, const std::string& name,
416 const char* type)
417 {
418 return add_attribute (ptr, method, parse,
419 name, &Argument::set_long_name, type);
420 }
421
423 template<class C, class B>
424 Argument* add (C* ptr, void (B::*method)(), char name)
425 {
426 return add_action (ptr, method, name, &Argument::set_short_name);
427 }
428
430 template<class C, class B>
431 Argument* add (C* ptr, void (B::*method)(), const std::string& name)
432 {
433 return add_action (ptr, method, name, &Argument::set_long_name);
434 }
435
437 template<class C, class B, class T>
438 Argument* add (C* ptr, void (B::*method)(T), char name, T arg)
439 {
440 return add_action (ptr, method, name, &Argument::set_short_name, arg);
441 }
442
444 template<class C, class B, class T>
445 Argument* add (C* ptr, void (B::*method)(T), const std::string& name, T arg)
446 {
447 return add_action (ptr, method, name, &Argument::set_long_name, arg);
448 }
449
451 Argument* find (const std::string& name);
452
454 void add (const std::string&);
455
457 void help (const std::string&);
458
460 void version ();
461
462 protected:
463
464 std::vector< Reference::To<Item> > item;
465
466 std::string version_info;
467 Argument* version_item;
468
469 std::string help_header;
470 std::string help_footer;
471 Argument* help_item;
472
474 template<typename T, typename N, typename S>
475 Argument* add_value (T& value, N name, S set, const char* type)
476 {
477 Argument* argument = new Value<T> (value);
478 (argument->*set) (name);
479 if (type)
480 argument->set_type (type);
481 item.push_back (argument);
482 return argument;
483 }
484
485 template<class C, typename M, typename P, typename N, typename S>
486 Argument* add_attribute (C* ptr, M method, P parse, N name, S set,
487 const char* type)
488 {
489 Argument* argument = new Attribute<C,M,P> (ptr, method, parse);
490 (argument->*set) (name);
491 if (type)
492 argument->set_type (type);
493 item.push_back (argument);
494 return argument;
495 }
496
497 template<typename N, typename S>
498 Argument* add_parser (Functor< void(const std::string&) >& action,
499 N name, S set, const char* type)
500 {
501 // std::cerr << "Menu::add_parser type='" << type << "'" << std::endl;
502
503 Argument* argument = new Parser (action);
504 (argument->*set) (name);
505 if (type)
506 argument->set_type (type);
507 item.push_back (argument);
508 return argument;
509 }
510
511 template<class C, typename M, typename N, typename S>
512 Argument* add_action (C* ptr, M method, N name, S set)
513 {
514 Argument* argument = new Action (ptr, method);
515
516 (argument->*set) (name);
517 item.push_back (argument);
518 return argument;
519 }
520
521 template<class C, typename M, typename N, typename S, typename T>
522 Argument* add_action (C* ptr, M method, N name, S set, T arg)
523 {
524 Argument* argument = new UnaryAction<T> (ptr, method, arg);
525
526 (argument->*set) (name);
527 item.push_back (argument);
528 return argument;
529 }
530
531 };
532
533
534}
535
536#endif
void handle(const std::string &)
Handle the argument.
Definition CommandLine.h:262
Functor< void() > action
The action to be taken.
Definition CommandLine.h:252
Action(C *instance, M method)
Default constructor.
Definition CommandLine.h:258
Alias to a single command line argument.
Definition CommandLine.h:117
Help get_help() const
Return two columns of help text.
Definition CommandLine.C:38
void set_handled(bool f)
Set the handled flag.
Definition CommandLine.h:132
void handle(const std::string &arg)
Handle the argument.
Definition CommandLine.h:133
A single command line argument.
Definition CommandLine.h:59
Help get_help() const
Return two columns of help text.
Definition CommandLine.C:18
int has_arg
The has_arg attribute used by getopt_long.
Definition CommandLine.h:79
int val
Code assigned to this Argument by Menu class.
Definition CommandLine.h:82
std::string type
Type of value.
Definition CommandLine.h:70
bool matches(int c) const
Return true if key matches.
Definition CommandLine.h:108
std::string long_name
Long name of value.
Definition CommandLine.h:67
std::string long_help
Detailed description of value.
Definition CommandLine.h:76
void set_handled(bool f)
Set the handled flag.
Definition CommandLine.h:104
std::string short_name
Single-character name of value.
Definition CommandLine.h:64
std::string help
Brief description of value.
Definition CommandLine.h:73
bool * handled
bool handled notification
Definition CommandLine.h:85
A command line corresponding to a class attribute.
Definition CommandLine.h:200
P parse
Pointer to the parser (unary)
Definition CommandLine.h:210
Attribute(C *_instance, M _method, P _parse)
Default constructor.
Definition CommandLine.h:215
M method
Pointer to the method (unary member function)
Definition CommandLine.h:207
C * instance
Pointer to the instance.
Definition CommandLine.h:204
void handle(const std::string &arg)
Handle the argument.
Definition CommandLine.h:220
A single item in a command line menu.
Definition CommandLine.h:36
virtual Help get_help() const =0
Return two columns of help text.
virtual void handle(const std::string &arg)=0
Handle the argument.
virtual void set_handled(bool)
Set the handled flag.
Definition CommandLine.h:48
virtual bool matches(int code) const =0
Return true if code matches.
A command line menu.
Definition CommandLine.h:313
Argument * add(C *ptr, void(B::*method)(T), char name, T arg)
Add an UnaryAction with only a single letter name.
Definition CommandLine.h:438
virtual void parse(int argc, char *const *argv)
Parse the command line.
Definition CommandLine.C:120
Menu()
Construct with two default options: –help and –version.
Definition CommandLine.C:54
Argument * add(T &value, char name, const char *type=0)
Add a Value with only a single letter name.
Definition CommandLine.h:359
std::string get_help_footer() const
Get the help footer.
Definition CommandLine.h:333
Argument * add(Functor< void(const std::string &) > action, char name, const char *type=0)
Add an parse action with only a single letter name.
Definition CommandLine.h:372
void version()
Print version and exit.
Definition CommandLine.C:304
Argument * add(C *ptr, void(B::*method)(), char name)
Add an Action with only a single letter name.
Definition CommandLine.h:424
Argument * add(C *ptr, M method, P parse, char name, const char *type)
Add an Attribute with only a single letter name.
Definition CommandLine.h:407
virtual void add_version()
Add the –version command line option.
Definition CommandLine.C:70
virtual void add_help()
Add the –help command line option.
Definition CommandLine.C:59
Argument * add(C *ptr, void(B::*method)(T), const std::string &name, const char *type=0)
Add an Attribute with only a long string name.
Definition CommandLine.h:397
Argument * find(const std::string &name)
Find the named Argument.
Definition CommandLine.C:209
virtual void set_help_footer(const std::string &s)
Set the help footer.
Definition CommandLine.h:330
std::string get_help_header() const
Get the help header.
Definition CommandLine.h:326
virtual void remove(Item *)
Remove an item from the menu.
Definition CommandLine.C:103
virtual void add(Item *)
Add an item to the menu.
Definition CommandLine.C:88
virtual void set_help_header(const std::string &s)
Set the help header (activates -h,–help)
Definition CommandLine.h:322
Argument * add_value(T &value, N name, S set, const char *type)
Add a Value with only a long string name.
Definition CommandLine.h:475
Argument * add(C *ptr, void(B::*method)(T), char name, const char *type=0)
Add an Attribute with only a single letter name.
Definition CommandLine.h:387
virtual int process_error(int code, char *const *argv)
Process any option parsing error and return a new code.
Definition CommandLine.C:196
Argument * add(C *ptr, void(B::*method)(T), const std::string &name, T arg)
Add an UnaryAction with only a long string name.
Definition CommandLine.h:445
Argument * add(C *ptr, M method, P parse, const std::string &name, const char *type)
Add an Attribute with only a long string name.
Definition CommandLine.h:415
Argument * add(C *ptr, void(B::*method)(), const std::string &name)
Add an Action with only a long string name.
Definition CommandLine.h:431
Argument * add(Functor< void(const std::string &) > action, const std::string &name, const char *type=0)
Add a parse action with only a long string name.
Definition CommandLine.h:379
Argument * add(T &value, const std::string &name, const char *type=0)
Add a Value with only a long string name.
Definition CommandLine.h:366
void help(const std::string &)
Print help and exit.
Definition CommandLine.C:221
virtual void set_version(const std::string &s)
Set the version information string (activates -i,–version)
Definition CommandLine.h:339
Functor< void(const std::string &) > action
The action to be taken.
Definition CommandLine.h:230
Parser(Functor< void(const std::string &) > &_action)
Default constructor.
Definition CommandLine.h:235
void handle(const std::string &arg)
Handle the argument.
Definition CommandLine.h:239
UnaryAction(C *instance, M method, T arg)
Default constructor.
Definition CommandLine.h:281
void handle(const std::string &)
Handle the argument.
Definition CommandLine.h:285
T argument
The argument to be passed.
Definition CommandLine.h:275
Functor< void(T) > action
The action to be taken.
Definition CommandLine.h:272
Value(bool &_value)
Default constructor.
Definition CommandLine.h:191
void handle(const std::string &)
Handle the argument.
Definition CommandLine.h:194
bool & value
Reference to the value to be set.
Definition CommandLine.h:186
void handle(const std::string &arg)
Handle the argument.
Definition CommandLine.h:172
Value(std::vector< T > &_values)
Default constructor.
Definition CommandLine.h:168
std::vector< T > & values
Reference to the value to be set.
Definition CommandLine.h:163
A command line value.
Definition CommandLine.h:140
Value(T &_value)
Default constructor.
Definition CommandLine.h:149
void handle(const std::string &arg)
Handle the argument.
Definition CommandLine.h:153
T & value
Reference to the value to be set.
Definition CommandLine.h:144
Implements an adaptable function object in compliance with the STL.
Definition Functor.h:39
Manages Reference::To references to the instance.
Definition ReferenceAble.h:35
Template class manages Reference::Able objects.
Definition ReferenceTo.h:25
STL class.
Argument
The complex phase of the basis.
Definition Conventions.h:25
STL namespace.
Enable a single template that works for both func(T) and func(const T&)
Definition CommandLine.h:25

Generated using doxygen 1.14.0