All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cli.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2014, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 /** \file cli.h
24  \brief File defining command-line interface in \ref o2scl::cli
25 */
26 #ifndef O2SCL_CLI_H
27 #define O2SCL_CLI_H
28 
29 #include <iostream>
30 #include <vector>
31 #include <algorithm>
32 #include <sstream>
33 #include <map>
34 
35 #include <o2scl/columnify.h>
36 #include <o2scl/vector.h>
37 #include <o2scl/string_conv.h>
38 
39 #ifndef DOXYGEN_NO_O2NS
40 namespace o2scl {
41 #endif
42 
43  /** \brief Base for \ref o2scl::cli command function
44 
45  See the \ref o2scl::cli class for more details.
46  */
48 
49  public:
50 
52 
53  virtual ~comm_option_funct() {}
54 
55  /// The basic function called by \ref o2scl::cli
56  virtual int operator()(std::vector<std::string> &cstr, bool itive_com)=0;
57 
58  };
59 
60  /// Function pointer for \ref o2scl::cli command function
62 
63  public:
64 
65  /// Create from a member function pointer from the specified class
66  comm_option_fptr(int (*fp)(std::vector<std::string> &, bool)) {
67  fptr=fp;
68  }
69 
70  virtual ~comm_option_fptr() {}
71 
72  /// The basic function called by \ref o2scl::cli
73  virtual int operator()(std::vector<std::string> &cstr, bool itive_com) {
74  return (*fptr)(cstr,itive_com);
75  }
76 
77 #ifndef DOXYGEN_INTERNAL
78 
79  protected:
80 
81  /// The pointer to the member function
82  int (*fptr)(std::vector<std::string> &cstr, bool itive_com);
83 
84  // Copy constructor
85  //comm_option_fptr(const comm_option_fptr &f) {
86  //fptr=f.fptr;
87  //}
88 
89  /// Copy constructor
91  fptr=f.fptr;
92  return *this;
93  }
94 
95 #endif
96 
97  };
98 
99  /// Member function pointer for \ref o2scl::cli command function
100  template<class tclass> class comm_option_mfptr : public comm_option_funct {
101 
102  public:
103 
104  /// Create from a member function pointer from the specified class
105  comm_option_mfptr(tclass *tp, int (tclass::*fp)(std::vector<std::string> &,
106  bool)) {
107  tptr=tp;
108  fptr=fp;
109  }
110 
111  virtual ~comm_option_mfptr() {}
112 
113  /// The basic function called by \ref o2scl::cli
114  virtual int operator()(std::vector<std::string> &cstr, bool itive_com) {
115  return (*tptr.*fptr)(cstr,itive_com);
116  }
117 
118 #ifndef DOXYGEN_INTERNAL
119 
120  protected:
121 
122  /// The pointer to the member function
123  int (tclass::*fptr)(std::vector<std::string> &cstr, bool itive_com);
124 
125  /// The pointer to the class
126  tclass *tptr;
127 
128  /// Copy constructor
130  fptr=f.fptr;
131  tptr=f.tptr;
132  }
133 
134  /// Copy constructor
136  fptr=f.fptr;
137  tptr=f.tptr;
138  return *this;
139  }
140 
141 #endif
142 
143  };
144 
145  /** \brief Command for interactive mode in \ref o2scl::cli
146 
147  See the \ref o2scl::cli class for more details.
148 
149  \comment
150  This was at one point converted into a class, but it wasn't that
151  easy to use, in comparison to structs which are easy to
152  initialize in aggregate.
153  \endcomment
154  */
155  typedef struct {
156 
157  /// Short option (\c '\\0' for none, must be unique if present)
158  char shrt;
159  /// Long option (must be specified and must be unique)
160  std::string lng;
161  /// Description for help
162  std::string desc;
163  /// Minimum number of parameters (0 for none, -1 for variable)
165  /// Maximum number of parameters (0 for none, -1 for variable)
167  /// Description of parameters
168  std::string parm_desc;
169  /// The help description
170  std::string help;
171  /// The pointer to the function to be called (or 0 for no function)
173  /// Type: command-line parameter, command, or both
174  int type;
175 
176  } comm_option_s;
177 
178  /** \brief A command-line argument for \ref o2scl::cli
179 
180  This is the internal structure that \ref o2scl::cli uses to package
181  command-line arguments.
182  */
183  typedef struct {
184  /// The argument
185  std::string arg;
186  /// Is an option?
187  bool is_option;
188  /// Is a properly formatted option
189  bool is_valid;
190  /// List of parameters (empty, unless it's an option)
191  std::vector<std::string> parms;
192  /// A pointer to the appropriate option (0, unless it's an option)
194  } cmd_line_arg;
195 
196  /** \brief Configurable command-line interface
197 
198  This class is experimental.
199 
200  Default commands: help, get/set, quit, exit, '!', verbose, license,
201  warranty, alias, run.
202 
203  Note that if the shell command is allowed (as it is by default)
204  there are some potential security issues which are not solved
205  here.
206 
207  Commands which begin with a '#' character are ignored.
208 
209  \note In interactive mode, commands are limited to 300 characters.
210 
211  \todo Long options cannot be one letter long, or else
212  process_args() will fail, thus the class should throw
213  if a long option with only one letter is given.
214 
215  \future Warn in run_interactive() when extra parameters are given
216  \future Include a "remove command" function
217  \future A replace command function, there's already some code
218  in cli.cpp for this.
219  \future There's some code duplication between comm_option_run()
220  and run_interactive()
221  \future Allow the user to set the tilde string
222  \future Disallow direct access to \ref o2scl::cli::par_list in order to
223  ensure parameter names do not contain whitespace
224 
225  <b>Concepts</b>
226 
227  As a matter of definition, the command-line arguments are simply
228  called arguments. These arguments may be options (in which case
229  they begin with either one dash or two) or parameters to these
230  options. When run in interactive mode, these options are also
231  commands.
232 
233  */
234  class cli {
235 
236  public:
237 
238  /// Parameter for \ref o2scl::cli
239  class parameter {
240 
241  public:
242 
243  virtual ~parameter() {}
244 
245  /// Help description
246  std::string help;
247 
248  /// Set from string
249  virtual int set(std::string s)=0;
250 
251  /// Convert to string
252  virtual std::string get()=0;
253 
254  };
255 
256  /// String parameter for \ref o2scl::cli
257  class parameter_string : public parameter {
258 
259  public:
260 
261  virtual ~parameter_string() {}
262 
263  /// Parameter
264  std::string *str;
265 
266  /// Set from string
267  virtual int set(std::string s) {
268  *str=s;
269  return 0;
270  }
271 
272  /// Convert to string
273  virtual std::string get() {
274  return *str;
275  }
276 
277  };
278 
279  /// String parameter for \ref o2scl::cli
280  class parameter_bool : public parameter {
281 
282  public:
283 
284  virtual ~parameter_bool() {}
285 
286  /// Parameter
287  bool *b;
288 
289  /// Set from string
290  virtual int set(std::string s) {
291  *b=o2scl::stob(s);
292  return 0;
293  }
294 
295  /// Convert to string
296  virtual std::string get() {
297  return btos(*b);
298  }
299 
300  };
301 
302  /// Double parameter for \ref o2scl::cli
303  class parameter_double : public parameter {
304 
305  public:
306 
307  virtual ~parameter_double() {}
308 
309  /// Parameter
310  double *d;
311 
312  /// Set from string
313  virtual int set(std::string s) {
314  *d=o2scl::stod(s);
315  return 0;
316  }
317 
318  /// Convert to string
319  virtual std::string get() {
320  return dtos(*d);
321  }
322 
323  };
324 
325  /// Integer parameter for \ref o2scl::cli
326  class parameter_int : public parameter {
327 
328  public:
329 
330  virtual ~parameter_int() {}
331 
332  /// Parameter
333  int *i;
334 
335  /// Set from string
336  virtual int set(std::string s) {
337  *i=o2scl::stoi(s);
338  return 0;
339  }
340 
341  /// Convert to string
342  virtual std::string get() {
343  return itos(*i);
344  }
345 
346  };
347 
348  /// \name Parameter storage and associated iterator type
349  //@{
350  /// Parameter list
351  std::map<std::string,parameter *,string_comp> par_list;
352  /// List iterator
353  typedef std::map<std::string,parameter *,string_comp>::iterator par_t;
354  //@}
355 
356 #ifndef DOXYGEN_NO_O2NS_INTERNAL
357 
358  protected:
359 
360  /// Output the parameter list
361  int output_param_list();
362 
363  /** \brief Attempt to expand a tilde to a user's home directory
364 
365  Experimental and currently unused.
366  */
367  int expand_tilde(std::vector<std::string> &sv);
368 
369  /// Replace all occurences of \c sold with \c snew in \c sv
370  int apply_alias(std::vector<std::string> &sv,
371  std::string sold, std::string snew);
372 
373  /** \brief Separate a string into words, handling quotes
374 
375  This function separates a string into words, and handles words
376  that begin with a <tt>"</tt> by adding more words until
377  finding one which ends with another <tt>"</tt>.
378 
379  This is used to reformat command descriptions and help text
380  for the screen width in comm_option_help(), to process lines
381  read from a file in comm_option_run(), and to process input in
382  run_interactive().
383 
384  \note This function does not understand nested quotes.
385 
386  \future Move this to a global function and use in
387  acol also.
388  \future Handle comma-delimited as well as space-delimited strings
389  */
390  int separate(std::string str, std::vector<std::string> &sv);
391 
392  /// Control screen output
393  int verbose;
394 
395  /// \name The hard-coded command functions
396  //@{
397  int comm_option_alias(std::vector<std::string> &sv, bool itive_com);
398  int comm_option_commands(std::vector<std::string> &sv, bool itive_com);
399  int comm_option_get(std::vector<std::string> &sv, bool itive_com);
400  int comm_option_help(std::vector<std::string> &sv, bool itive_com);
401  int comm_option_license(std::vector<std::string> &sv, bool itive_com);
402  int comm_option_no_intro(std::vector<std::string> &sv, bool itive_com);
403  int comm_option_run(std::vector<std::string> &sv, bool itive_com);
404  int comm_option_set(std::vector<std::string> &sv, bool itive_com);
405  int comm_option_warranty(std::vector<std::string> &sv, bool itive_com);
406  //@}
407 
408  /// Storage for getline
409  char buf[300];
410 
411  /// Storage for the function to call after setting a parameter
413 
414  /// List of commands
415  std::vector<comm_option_s> clist;
416 
417  /// \name Help for parameters
418  //@{
419  std::vector<std::string> ph_name, ph_desc;
420  //@}
421 
422  /// \name Aliases
423  //@{
424  std::map<std::string,std::string,string_comp> als;
425  typedef std::map<std::string,std::string,string_comp>::iterator al_it;
426  //@}
427 
428  /// Compare two strings, treating dashes and underscores as equivalent
429  bool string_equal_dash(std::string s1, std::string s2);
430 
431 #endif
432 
433  public:
434 
435  cli();
436 
437  virtual ~cli();
438 
439  /// String to replace tildes with
440  std::string tilde_string;
441 
442  /** \brief If true, output the usual GNU intro when run_interactive()
443  is called (default true).
444 
445  In order to conform to GNU standards, this ought not be set to
446  false by default.
447  */
448  bool gnu_intro;
449 
450  /// Function to call when a \c set command is issued
452  user_set_func=&usf;
453  return 0;
454  }
455 
456  /// \name Value to indicate whether commands are also command-line options
457  //@{
458  static const int comm_option_command=0;
459  static const int comm_option_cl_param=1;
460  static const int comm_option_both=2;
461  //@}
462 
463  /// \name The default command objects
464  //@{
465  comm_option_s c_commands;
466  comm_option_s c_help;
467  comm_option_s c_quit;
468  comm_option_s c_exit;
469  comm_option_s c_license;
470  comm_option_s c_warranty;
471  comm_option_s c_set;
472  comm_option_s c_get;
473  comm_option_s c_run;
474  comm_option_s c_no_intro;
475  comm_option_s c_alias;
476  //@}
477 
478  /// If true, then sync cli::verbose, with a parameter of the same name
480 
481  /** \brief If true, allow the user to use ! to execute a shell command
482  (default true)
483  */
485 
486  /// The prompt (default <tt>"> "</tt>)
487  std::string prompt;
488 
489  /// A one- or two-line description (default is empty string)
490  std::string desc;
491 
492  /// The name of the command
493  std::string cmd_name;
494 
495  /// Additional help text for interactive mode (default is empty string)
496  std::string addl_help_cmd;
497 
498  /// Additional help text for command-line (default is empty string)
499  std::string addl_help_cli;
500 
501  /// \name Basic operation
502  //@{
503  /** \brief Add a new command
504 
505  Each command/option must have either a short form in
506  comm_option_s::shrt or a long from in comm_option_s::lng,
507  which is unique from the other commands/options already
508  present. You cannot add two commands/options with the same
509  short form, even if they have different long forms, and vice
510  versa.
511 
512  */
514 
515  /// Add a vector containing new commands/options
516  template<class vec_t> int set_comm_option_vec
517  (size_t list_size, vec_t &option_list) {
518 
519  for(size_t k=0;k<list_size;k++) {
520  bool found=false;
521  for(size_t i=0;found==false && i<clist.size();i++) {
522  // If short or long options match
523  if ((option_list[k].shrt!=0 &&
524  clist[i].shrt==option_list[k].shrt) ||
525  (option_list[k].lng.length()>0 &&
526  clist[i].lng==option_list[k].lng)) {
527  found=true;
528  }
529  }
530  if (found==true) {
531  // Call the error handler
532  if (option_list[k].shrt!=0) {
533  std::string err="Option ";
534  err+=option_list[k].shrt;
535  err+=((std::string)" , ")+option_list[k].lng+" already present.";
536  O2SCL_ERR(err.c_str(),exc_einval);
537  } else {
538  std::string err="Option ";
539  err+=option_list[k].lng+" already present.";
540  O2SCL_ERR(err.c_str(),exc_einval);
541  }
542  }
543  // Add the option to the option list
544  clist.push_back(option_list[k]);
545  }
546 
547  return 0;
548  }
549 
550  /// Set one-line help text for a parameter named \c param
551  int set_param_help(std::string param, std::string help);
552 
553  /** \brief Automatically parse arguments to main and
554  call interactive mode if required
555  */
556  int run_auto(int argc, char *argv[], int debug=0);
557  //@}
558 
559  /** \brief The function which obtains input from the user
560 
561  \future Think about whether or not this should be protected?
562  (Possibly not, as it's extensively used by acolm.cpp)
563  */
564  virtual char *cli_gets(const char *c);
565 
566  /// Call functions corresponding to command-line args
567  int call_args(std::vector<cmd_line_arg> &ca);
568 
569  /** \brief Process command-line arguments from a const char array
570 
571  This doesn't actually execute the functions for the
572  corresponding options, but simply processes the parameters \c
573  argv and \c argv and packs the information into \c ca.
574 
575  This function assumes that <tt>argc[0]</tt> just contains
576  the name of the command, and should thus be ignored.
577  */
578  int process_args(int argc, char *argv[],
579  std::vector<cmd_line_arg> &ca, int debug=0);
580 
581  /** \brief Process command-line arguments from a string
582 
583  \todo There's a typecast in this function to (char *)
584  from (const char *) which needs reworking.
585  */
586  int process_args(std::string s, std::vector<cmd_line_arg> &ca,
587  int debug=0);
588 
589  /** \brief Set verbosity
590 
591  Most errors are output to the screen even if verbose is zero.
592  */
593  int set_verbose(int v);
594 
595  /// Run the interactive mode
596  int run_interactive();
597 
598  // Create a new command
599  // int replace_command(comm_option &ic);
600 
601  /** \brief Set an alias \c alias for the string \c str
602 
603  Aliases can also be set using the command \c 'alias', but
604  that version allows only one-word aliases.
605  */
606  int set_alias(std::string alias, std::string str);
607 
608  /** \brief Set an alias \c alias for the string \c str
609 
610  Aliases can also be set using the command \c 'alias', but
611  that version allows only one-word aliases.
612  */
613  std::string get_alias(std::string alias);
614 
615  };
616 
617 #ifndef DOXYGEN_NO_O2NS
618 }
619 #endif
620 
621 #endif
comm_option_mfptr(const comm_option_mfptr &f)
Copy constructor.
Definition: cli.h:129
Double parameter for o2scl::cli.
Definition: cli.h:303
comm_option_fptr(int(*fp)(std::vector< std::string > &, bool))
Create from a member function pointer from the specified class.
Definition: cli.h:66
virtual int set(std::string s)=0
Set from string.
std::string cmd_name
The name of the command.
Definition: cli.h:493
int apply_alias(std::vector< std::string > &sv, std::string sold, std::string snew)
Replace all occurences of sold with snew in sv.
int * i
Parameter.
Definition: cli.h:333
int run_interactive()
Run the interactive mode.
std::string help
The help description.
Definition: cli.h:170
int verbose
Control screen output.
Definition: cli.h:393
String parameter for o2scl::cli.
Definition: cli.h:257
int output_param_list()
Output the parameter list.
int expand_tilde(std::vector< std::string > &sv)
Attempt to expand a tilde to a user's home directory.
virtual int set(std::string s)
Set from string.
Definition: cli.h:290
invalid argument supplied by user
Definition: err_hnd.h:59
std::string desc
A one- or two-line description (default is empty string)
Definition: cli.h:490
bool string_equal_dash(std::string s1, std::string s2)
Compare two strings, treating dashes and underscores as equivalent.
std::string lng
Long option (must be specified and must be unique)
Definition: cli.h:160
int(tclass::* fptr)(std::vector< std::string > &cstr, bool itive_com)
The pointer to the member function.
Definition: cli.h:123
comm_option_fptr & operator=(const comm_option_fptr &f)
Copy constructor.
Definition: cli.h:90
Parameter for o2scl::cli.
Definition: cli.h:239
int process_args(int argc, char *argv[], std::vector< cmd_line_arg > &ca, int debug=0)
Process command-line arguments from a const char array.
std::string get_alias(std::string alias)
Set an alias alias for the string str.
int set_alias(std::string alias, std::string str)
Set an alias alias for the string str.
std::string parm_desc
Description of parameters.
Definition: cli.h:168
tclass * tptr
The pointer to the class.
Definition: cli.h:126
int run_auto(int argc, char *argv[], int debug=0)
Automatically parse arguments to main and call interactive mode if required.
std::string btos(bool b)
Convert a boolean value to a string.
comm_option_funct * func
The pointer to the function to be called (or 0 for no function)
Definition: cli.h:172
int set_function(comm_option_funct &usf)
Function to call when a set command is issued.
Definition: cli.h:451
std::string addl_help_cli
Additional help text for command-line (default is empty string)
Definition: cli.h:499
virtual int set(std::string s)
Set from string.
Definition: cli.h:336
std::string prompt
The prompt (default "> ")
Definition: cli.h:487
std::string tilde_string
String to replace tildes with.
Definition: cli.h:440
int type
Type: command-line parameter, command, or both.
Definition: cli.h:174
Configurable command-line interface.
Definition: cli.h:234
virtual int operator()(std::vector< std::string > &cstr, bool itive_com)
The basic function called by o2scl::cli.
Definition: cli.h:73
std::string help
Help description.
Definition: cli.h:246
virtual int operator()(std::vector< std::string > &cstr, bool itive_com)=0
The basic function called by o2scl::cli.
int stoi(std::string s, bool err_on_fail=true)
Convert a string to an integer.
bool stob(std::string s, bool err_on_fail=true)
Convert a string to a boolean value.
bool is_valid
Is a properly formatted option.
Definition: cli.h:189
bool shell_cmd_allowed
If true, allow the user to use ! to execute a shell command (default true)
Definition: cli.h:484
comm_option_mfptr(tclass *tp, int(tclass::*fp)(std::vector< std::string > &, bool))
Create from a member function pointer from the specified class.
Definition: cli.h:105
int set_param_help(std::string param, std::string help)
Set one-line help text for a parameter named param.
virtual char * cli_gets(const char *c)
The function which obtains input from the user.
comm_option_mfptr & operator=(const comm_option_mfptr &f)
Copy constructor.
Definition: cli.h:135
A command-line argument for o2scl::cli.
Definition: cli.h:183
Member function pointer for o2scl::cli command function.
Definition: cli.h:100
std::string dtos(double x, int prec=6, bool auto_prec=false)
Convert a double to a string.
int min_parms
Minimum number of parameters (0 for none, -1 for variable)
Definition: cli.h:164
String parameter for o2scl::cli.
Definition: cli.h:280
virtual int set(std::string s)
Set from string.
Definition: cli.h:267
bool * b
Parameter.
Definition: cli.h:287
int separate(std::string str, std::vector< std::string > &sv)
Separate a string into words, handling quotes.
int set_comm_option(comm_option_s &ic)
Add a new command.
char buf[300]
Storage for getline.
Definition: cli.h:409
Base for o2scl::cli command function.
Definition: cli.h:47
std::string * str
Parameter.
Definition: cli.h:264
int set_verbose(int v)
Set verbosity.
std::vector< comm_option_s > clist
List of commands.
Definition: cli.h:415
Function pointer for o2scl::cli command function.
Definition: cli.h:61
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
int set_comm_option_vec(size_t list_size, vec_t &option_list)
Add a vector containing new commands/options.
Definition: cli.h:517
double * d
Parameter.
Definition: cli.h:310
virtual int set(std::string s)
Set from string.
Definition: cli.h:313
Integer parameter for o2scl::cli.
Definition: cli.h:326
int max_parms
Maximum number of parameters (0 for none, -1 for variable)
Definition: cli.h:166
Command for interactive mode in o2scl::cli.
Definition: cli.h:155
char shrt
Short option ('\0' for none, must be unique if present)
Definition: cli.h:158
int call_args(std::vector< cmd_line_arg > &ca)
Call functions corresponding to command-line args.
std::string addl_help_cmd
Additional help text for interactive mode (default is empty string)
Definition: cli.h:496
bool gnu_intro
If true, output the usual GNU intro when run_interactive() is called (default true).
Definition: cli.h:448
std::map< std::string, parameter *, string_comp >::iterator par_t
List iterator.
Definition: cli.h:353
std::map< std::string, parameter *, string_comp > par_list
Parameter list.
Definition: cli.h:351
comm_option_s * cop
A pointer to the appropriate option (0, unless it's an option)
Definition: cli.h:193
bool is_option
Is an option?
Definition: cli.h:187
bool sync_verbose
If true, then sync cli::verbose, with a parameter of the same name.
Definition: cli.h:479
int(* fptr)(std::vector< std::string > &cstr, bool itive_com)
The pointer to the member function.
Definition: cli.h:82
virtual int operator()(std::vector< std::string > &cstr, bool itive_com)
The basic function called by o2scl::cli.
Definition: cli.h:114
double stod(std::string s, bool err_on_fail=true)
Convert a string to a double.
std::string itos(int x)
Convert an integer to a string.
comm_option_funct * user_set_func
Storage for the function to call after setting a parameter.
Definition: cli.h:412
std::string desc
Description for help.
Definition: cli.h:162
std::vector< std::string > parms
List of parameters (empty, unless it's an option)
Definition: cli.h:191
std::string arg
The argument.
Definition: cli.h:185

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..