00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_CLI_H 00024 #define O2SCL_CLI_H 00025 00026 #include <iostream> 00027 #include <vector> 00028 #include <algorithm> 00029 #include <sstream> 00030 00031 #include <o2scl/collection.h> 00032 #include <o2scl/columnify.h> 00033 00034 #ifndef DOXYGENP 00035 namespace o2scl { 00036 #endif 00037 00038 /** 00039 \brief Base for \ref cli command function 00040 00041 See the \ref cli class for more details. 00042 */ 00043 class comm_option_funct { 00044 00045 public: 00046 00047 comm_option_funct() {} 00048 00049 virtual ~comm_option_funct() {} 00050 00051 /// The basic function called by \ref cli 00052 virtual int operator()(std::vector<std::string> &cstr, bool itive_com) { 00053 return 0; 00054 } 00055 00056 #ifndef DOXYGENP 00057 00058 private: 00059 comm_option_funct(const comm_option_funct &); 00060 comm_option_funct& operator=(const comm_option_funct&); 00061 00062 #endif 00063 00064 }; 00065 00066 /// Member function pointer for \ref cli command function 00067 template<class tclass> class comm_option_mfptr : public comm_option_funct { 00068 00069 public: 00070 00071 /// Create from a member function pointer from the specified class 00072 comm_option_mfptr(tclass *tp, int (tclass::*fp)(std::vector<std::string> &, 00073 bool)) { 00074 tptr=tp; 00075 fptr=fp; 00076 } 00077 00078 virtual ~comm_option_mfptr() {} 00079 00080 /// The basic function called by \ref cli 00081 virtual int operator()(std::vector<std::string> &cstr, bool itive_com) { 00082 return (*tptr.*fptr)(cstr,itive_com); 00083 } 00084 00085 #ifndef DOXYGEN_INTERNAL 00086 00087 protected: 00088 00089 /// The pointer to the member function 00090 int (tclass::*fptr)(std::vector<std::string> &cstr, bool itive_com); 00091 00092 /// The pointer to the class 00093 tclass *tptr; 00094 00095 #endif 00096 00097 #ifndef DOXYGENP 00098 00099 private: 00100 comm_option_mfptr(const comm_option_mfptr &); 00101 comm_option_mfptr& operator=(const comm_option_mfptr&); 00102 00103 #endif 00104 00105 }; 00106 00107 /** 00108 \brief Command for interactive mode in \ref cli 00109 00110 See the \ref cli class for more details. 00111 */ 00112 typedef struct { 00113 00114 /// Short option (\c '\\0' for none) 00115 char shrt; 00116 /// Long option (must be specified) 00117 std::string lng; 00118 /// Description for help (default is empty string) 00119 std::string desc; 00120 /// Minimum number of parameters (0 for none, -1 for variable) 00121 int min_parms; 00122 /// Maximum number of parameters (0 for none, -1 for variable) 00123 int max_parms; 00124 /// Description of parameters (default is empty string) 00125 std::string parm_desc; 00126 /// The help description (default is empty string) 00127 std::string help; 00128 /// The pointer to the function to be called (or 0 for no function) 00129 comm_option_funct *func; 00130 /// Type: command-line parameter, command, or both (default command) 00131 int type; 00132 00133 } comm_option_s; 00134 00135 /** 00136 \brief Command for interactive mode in \ref cli 00137 00138 See the \ref cli class for more details. 00139 */ 00140 class comm_option : public comm_option_s { 00141 00142 public: 00143 00144 comm_option() { 00145 shrt=0; 00146 lng=""; 00147 desc=""; 00148 min_parms=0; 00149 max_parms=0; 00150 parm_desc=""; 00151 help=""; 00152 func=0; 00153 type=command; 00154 } 00155 00156 comm_option(comm_option_s c) { 00157 shrt=c.shrt; 00158 lng=c.lng; 00159 desc=c.desc; 00160 min_parms=c.min_parms; 00161 max_parms=c.max_parms; 00162 parm_desc=c.parm_desc; 00163 help=c.help; 00164 func=c.func; 00165 type=c.type; 00166 } 00167 00168 /// \name Possible values of ::type 00169 //@{ 00170 static const int command=0; 00171 static const int cl_param=1; 00172 static const int both=2; 00173 //@} 00174 00175 }; 00176 00177 /** \brief A command-line argument 00178 */ 00179 typedef struct { 00180 /// The argument 00181 std::string arg; 00182 /// Is an option? 00183 bool is_option; 00184 /// Is a properly formatted option 00185 bool is_valid; 00186 /// List of parameters (empty, unless it's an option) 00187 std::vector<std::string> parms; 00188 /// A pointer to the appropriate (0, unless it's an option) 00189 comm_option *cop; 00190 } cmd_line_arg; 00191 00192 /** 00193 \brief Configurable command-line interface 00194 00195 Somewhat experimental. 00196 00197 Default commands: help, get/set, quit, exit, '!', verbose, license, 00198 warranty, alias, run. 00199 00200 Note that if the shell command is allowed (as it is by default) 00201 there are some potential security issues which are not 00202 solved here. 00203 00204 Commands which begin with a '#' character are ignored. 00205 */ 00206 class cli { 00207 00208 #ifndef DOXYGEN_INTERNAL 00209 00210 protected: 00211 00212 /// Replace all occurences of \c sold with \c snew in \c s 00213 int apply_alias(std::string &s, std::string sold, std::string snew); 00214 00215 /// Separate a string into words 00216 int separate(std::string str, std::vector<std::string> &sv); 00217 00218 /// Control screen output 00219 int verbose; 00220 00221 /// Pointer to collection for parameters 00222 collection *cop; 00223 00224 /// \name The hard-coded command functions 00225 //@{ 00226 int comm_option_run(std::vector<std::string> &sv, bool itive_com); 00227 int comm_option_get(std::vector<std::string> &sv, bool itive_com); 00228 int comm_option_set(std::vector<std::string> &sv, bool itive_com); 00229 int comm_option_help(std::vector<std::string> &sv, bool itive_com); 00230 int comm_option_license(std::vector<std::string> &sv, bool itive_com); 00231 int comm_option_warranty(std::vector<std::string> &sv, bool itive_com); 00232 int comm_option_no_intro(std::vector<std::string> &sv, bool itive_com); 00233 int comm_option_alias(std::vector<std::string> &sv, bool itive_com); 00234 //@} 00235 00236 /// Storage for getline 00237 char buf[300]; 00238 00239 /// Storage for the function to call after setting a parameter 00240 comm_option_funct *user_set_func; 00241 00242 /// List of commands 00243 std::vector<comm_option *> clist; 00244 00245 /// \name Help for parameters 00246 //@{ 00247 std::vector<std::string> ph_name, ph_desc; 00248 //@} 00249 00250 /// \name Aliases 00251 //@{ 00252 std::vector<std::string> al1, al2; 00253 //@} 00254 00255 /// Compare two strings, treating dashes as underscores 00256 bool string_equal(std::string s1, std::string s2); 00257 00258 #endif 00259 00260 public: 00261 00262 cli(); 00263 00264 virtual ~cli(); 00265 00266 /** \brief If true, output the usual GNU intro when run_interactive() 00267 is called. 00268 00269 In order to conform to GNU standards, this ought not be set to 00270 false by default. 00271 */ 00272 bool gnu_intro; 00273 00274 /// Function to call when a \c set command is issued 00275 int set_function(comm_option_funct &usf) { 00276 user_set_func=&usf; 00277 return 0; 00278 } 00279 00280 /// \name The hard-coded command objects 00281 //@{ 00282 comm_option c_help; 00283 comm_option c_quit; 00284 comm_option c_exit; 00285 comm_option c_license; 00286 comm_option c_warranty; 00287 comm_option c_set; 00288 comm_option c_get; 00289 comm_option c_run; 00290 comm_option c_no_intro; 00291 comm_option c_alias; 00292 //@} 00293 00294 /// If true, then sync ::verbose, with a parameter of the same name 00295 bool sync_verbose; 00296 00297 /** \brief If true, allow the user to use ! to execute a shell command 00298 (default true) 00299 */ 00300 bool shell_cmd_allowed; 00301 00302 /// The prompt (default \c "> ") 00303 std::string prompt; 00304 00305 /// A one- or two-line description (default is empty string) 00306 std::string desc; 00307 00308 /// The name of the command 00309 std::string cmd_name; 00310 00311 /// Additional help text for interactive mode (default is empty string) 00312 std::string addl_help_cmd; 00313 00314 /// Additional help text for command-line (default is empty string) 00315 std::string addl_help_cli; 00316 00317 /* A static variable for holding the line for \ref sn_cli */ 00318 char *line_read; 00319 00320 virtual char *cli_gets(const char *c) { 00321 std::cout << c << std::flush; 00322 std::cin.getline(buf,300); 00323 return buf; 00324 } 00325 00326 /// Call functions corresponding to command-line args 00327 int call_args(std::vector<cmd_line_arg> &ca); 00328 00329 /// Process command-line arguments 00330 int process_args(int argv, const char *argc[], 00331 std::vector<cmd_line_arg> &ca, int debug=0); 00332 00333 /// Process command-line arguments 00334 int process_args(std::string s, std::vector<cmd_line_arg> &ca, 00335 int debug=0) { 00336 std::vector<std::string> sv; 00337 separate(s,sv); 00338 int argv=sv.size(); 00339 const char **argc=new const char *[argv]; 00340 for(int i=0;i<argv;i++) argc[i]=sv[i].c_str(); 00341 int ret=process_args(argv,argc,ca,debug); 00342 delete[] argc; 00343 return ret; 00344 } 00345 00346 /** 00347 \brief Set verbosity 00348 00349 Most errors are output to the screen even if verbose is zero. 00350 */ 00351 int set_verbose(int v); 00352 00353 /// Run the interactive mode 00354 int run_interactive(); 00355 00356 /** 00357 \brief Add a new command 00358 00359 Each command/option must have either a short form in 00360 comm_option::shrt or a long from in comm_option::lng, 00361 which is unique from the other commands/options already 00362 present. You cannot add two commands/options with the same 00363 short form, even if they have different long forms, and vice 00364 versa. 00365 00366 */ 00367 int set_comm_option(comm_option &ic); 00368 00369 /// Create a new command 00370 // int replace_command(comm_option &ic); 00371 00372 /// Set the parameters with a collection 00373 int set_parameters(collection &co); 00374 00375 /// Set one-line help text for a parameter named \c param 00376 int set_param_help(std::string param, std::string help); 00377 00378 /** 00379 \brief Set an alias \c alias for the string \c str 00380 00381 Aliases can also be set using the command \c 'alias', but 00382 that version allows only one-word aliases. 00383 */ 00384 int set_alias(std::string alias, std::string str) { 00385 al1.push_back(alias); 00386 al2.push_back(str); 00387 return 0; 00388 } 00389 00390 }; 00391 00392 #ifndef DOXYGENP 00393 } 00394 #endif 00395 00396 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page