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 
24 template<typename T>
25 struct arg_traits { typedef T unref; };
26 
27 template<typename T>
28 struct arg_traits<const T&> { typedef T unref; };
29 
30 namespace 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 
79  int has_arg;
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 
121  Reference::To<Argument> argument;
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 
144  T& value;
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 
210  P parse;
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
bool matches(int c) const
Return true if key matches.
Definition: CommandLine.h:108
Functor< void() > action
The action to be taken.
Definition: CommandLine.h:252
A command line Action.
Definition: CommandLine.h:247
bool & value
Reference to the value to be set.
Definition: CommandLine.h:186
Value(std::vector< T > &_values)
Default constructor.
Definition: CommandLine.h:168
bool * handled
bool handled notification
Definition: CommandLine.h:85
UnaryAction(C *instance, M method, T arg)
Default constructor.
Definition: CommandLine.h:281
Action(C *instance, M method)
Default constructor.
Definition: CommandLine.h:258
std::string short_name
Single-character name of value.
Definition: CommandLine.h:64
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
T argument
The argument to be passed.
Definition: CommandLine.h:275
std::string long_name
Long name of value.
Definition: CommandLine.h:67
virtual void set_help_footer(const std::string &s)
Set the help footer.
Definition: CommandLine.h:330
virtual bool matches(int code) const =0
Return true if code matches.
std::string type
Type of value.
Definition: CommandLine.h:70
Argument * find(const std::string &name)
Find the named Argument.
Definition: CommandLine.C:209
M method
Pointer to the method (unary member function)
Definition: CommandLine.h:207
void handle(const std::string &arg)
Handle the argument.
Definition: CommandLine.h:172
A convenient exception handling class.
Definition: Error.h:54
T & value
Reference to the value to be set.
Definition: CommandLine.h:144
A single item in a command line menu.
Definition: CommandLine.h:35
Attribute(C *_instance, M _method, P _parse)
Default constructor.
Definition: CommandLine.h:215
virtual void add_version()
Add the –version command line option.
Definition: CommandLine.C:70
std::vector< T > & values
Reference to the value to be set.
Definition: CommandLine.h:163
virtual Help get_help() const =0
Return two columns of help text.
A function that can parse the string.
Definition: CommandLine.h:225
void help(const std::string &)
Print help and exit.
Definition: CommandLine.C:221
virtual void set_help_header(const std::string &s)
Set the help header (activates -h,–help)
Definition: CommandLine.h:322
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
void version()
Print version and exit.
Definition: CommandLine.C:304
virtual void handle(const std::string &arg)=0
Handle the argument.
Template class manages Reference::Able objects.
Definition: Reference.h:74
Functor< void(const std::string &) > action
The action to be taken.
Definition: CommandLine.h:230
A command line corresponding to a class attribute.
Definition: CommandLine.h:199
std::string help
Brief description of value.
Definition: CommandLine.h:73
void handle(const std::string &arg)
Handle the argument.
Definition: CommandLine.h:153
C * instance
Pointer to the instance.
Definition: CommandLine.h:204
Value(T &_value)
Default constructor.
Definition: CommandLine.h:149
void set_handled(bool f)
Set the handled flag.
Definition: CommandLine.h:104
Alias to a single command line argument.
Definition: CommandLine.h:116
Menu()
Construct with two default options: –help and –version.
Definition: CommandLine.C:54
std::string get_help_header() const
Get the help header.
Definition: CommandLine.h:326
A command line Action with a single argument.
Definition: CommandLine.h:267
Argument * add(C *ptr, void(B::*method)(), char name)
Add an Action with only a single letter name.
Definition: CommandLine.h:424
virtual void add_help()
Add the –help command line option.
Definition: CommandLine.C:59
void handle(const std::string &arg)
Handle the argument.
Definition: CommandLine.h:133
Functor< void(T) > action
The action to be taken.
Definition: CommandLine.h:272
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
Enable a single template that works for both func(T) and func(const T&)
Definition: CommandLine.h:25
std::string long_help
Detailed description of value.
Definition: CommandLine.h:76
P parse
Pointer to the parser (unary)
Definition: CommandLine.h:210
Manages Reference::To references to the instance.
Definition: ReferenceAble.h:40
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:239
void handle(const std::string &)
Handle the argument.
Definition: CommandLine.h:194
Stores keyword-value pairs.
Definition: Alias.h:21
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
virtual void add(Item *)
Add an item to the menu.
Definition: CommandLine.C:88
virtual void set_version(const std::string &s)
Set the version information string (activates -i,–version)
Definition: CommandLine.h:339
std::string get_help_footer() const
Get the help footer.
Definition: CommandLine.h:333
Help get_help() const
Return two columns of help text.
Definition: CommandLine.C:38
virtual void set_handled(bool)
Set the handled flag.
Definition: CommandLine.h:48
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
Help get_help() const
Return two columns of help text.
Definition: CommandLine.C:18
Implements an adaptable function object in compliance with the STL.
Definition: Functor.h:39
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)(), const std::string &name)
Add an Action with only a long string name.
Definition: CommandLine.h:431
A command line value.
Definition: CommandLine.h:139
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
Argument
The complex phase of the basis.
Definition: Conventions.h:30
Argument * add(T &value, char name, const char *type=0)
Add a Value with only a single letter name.
Definition: CommandLine.h:359
virtual void remove(Item *)
Remove an item from the menu.
Definition: CommandLine.C:103
void handle(const std::string &)
Handle the argument.
Definition: CommandLine.h:285
virtual int process_error(int code, char *const *argv)
Process any option parsing error and return a new code.
Definition: CommandLine.C:196
int val
Code assigned to this Argument by Menu class.
Definition: CommandLine.h:82
A command line menu.
Definition: CommandLine.h:312
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
int has_arg
The has_arg attribute used by getopt_long.
Definition: CommandLine.h:79
A single command line argument.
Definition: CommandLine.h:58
Parser(Functor< void(const std::string &) > &_action)
Default constructor.
Definition: CommandLine.h:235
void handle(const std::string &)
Handle the argument.
Definition: CommandLine.h:262
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
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
virtual void parse(int argc, char *const *argv)
Parse the command line.
Definition: CommandLine.C:120
Value(bool &_value)
Default constructor.
Definition: CommandLine.h:191
void handle(const std::string &arg)
Handle the argument.
Definition: CommandLine.h:220

Generated using doxygen 1.8.17