00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 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. 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_get(std::vector<std::string> &sv, bool itive_com); 00227 int comm_option_set(std::vector<std::string> &sv, bool itive_com); 00228 int comm_option_help(std::vector<std::string> &sv, bool itive_com); 00229 int comm_option_license(std::vector<std::string> &sv, bool itive_com); 00230 int comm_option_warranty(std::vector<std::string> &sv, bool itive_com); 00231 int comm_option_no_intro(std::vector<std::string> &sv, bool itive_com); 00232 int comm_option_alias(std::vector<std::string> &sv, bool itive_com); 00233 //@} 00234 00235 /// Storage for getline 00236 char buf[300]; 00237 00238 /// Storage for the function to call after setting a parameter 00239 comm_option_funct *user_set_func; 00240 00241 /// List of commands 00242 std::vector<comm_option *> clist; 00243 00244 /// \name Help for parameters 00245 //@{ 00246 std::vector<std::string> ph_name, ph_desc; 00247 //@} 00248 00249 /// \name Aliases 00250 //@{ 00251 std::vector<std::string> al1, al2; 00252 //@} 00253 00254 /// Compare two strings, treating dashes as underscores 00255 bool string_equal(std::string s1, std::string s2); 00256 00257 #endif 00258 00259 public: 00260 00261 cli(); 00262 00263 virtual ~cli(); 00264 00265 /** \brief If true, output the usual GNU intro when run_interactive() 00266 is called. 00267 00268 In order to conform to GNU standards, this ought not be set to 00269 false by default. 00270 */ 00271 bool gnu_intro; 00272 00273 /// Function to call when a \c set command is issued 00274 int set_function(comm_option_funct &usf) { 00275 user_set_func=&usf; 00276 return 0; 00277 } 00278 00279 /// \name The hard-coded command objects 00280 //@{ 00281 comm_option c_help; 00282 comm_option c_quit; 00283 comm_option c_exit; 00284 comm_option c_license; 00285 comm_option c_warranty; 00286 comm_option c_set; 00287 comm_option c_get; 00288 comm_option c_no_intro; 00289 comm_option c_alias; 00290 //@} 00291 00292 /// If true, then sync ::verbose, with a parameter of the same name 00293 bool sync_verbose; 00294 00295 /** \brief If true, allow the user to use ! to execute a shell command 00296 (default true) 00297 */ 00298 bool shell_cmd_allowed; 00299 00300 /// The prompt (default \c "> ") 00301 std::string prompt; 00302 00303 /// A one- or two-line description (default is empty string) 00304 std::string desc; 00305 00306 /// The name of the command 00307 std::string cmd_name; 00308 00309 /// Additional help text for interactive mode (default is empty string) 00310 std::string addl_help_cmd; 00311 00312 /// Additional help text for command-line (default is empty string) 00313 std::string addl_help_cli; 00314 00315 /* A static variable for holding the line for \ref sn_cli */ 00316 char *line_read; 00317 00318 virtual char *cli_gets(const char *c) { 00319 std::cout << c << std::flush; 00320 std::cin.getline(buf,300); 00321 return buf; 00322 } 00323 00324 /// Call functions corresponding to command-line args 00325 int call_args(std::vector<cmd_line_arg> &ca); 00326 00327 /// Process command-line arguments 00328 int process_args(int argv, const char *argc[], 00329 std::vector<cmd_line_arg> &ca, int debug=0); 00330 00331 /// Process command-line arguments 00332 int process_args(std::string s, std::vector<cmd_line_arg> &ca, 00333 int debug=0) { 00334 std::vector<std::string> sv; 00335 separate(s,sv); 00336 int argv=sv.size(); 00337 const char **argc=new const char *[argv]; 00338 for(int i=0;i<argv;i++) argc[i]=sv[i].c_str(); 00339 int ret=process_args(argv,argc,ca,debug); 00340 delete[] argc; 00341 return ret; 00342 } 00343 00344 /** 00345 \brief Set verbosity 00346 00347 Most errors are output to the screen even if verbose is zero. 00348 */ 00349 int set_verbose(int v); 00350 00351 /// Run the interactive mode 00352 int run_interactive(); 00353 00354 /** 00355 \brief Add a new command 00356 00357 Each command/option must have either a short form in 00358 comm_option::shrt or a long from in comm_option::lng, 00359 which is unique from the other commands/options already 00360 present. You cannot add two commands/options with the same 00361 short form, even if they have different long forms, and vice 00362 versa. 00363 00364 */ 00365 int set_comm_option(comm_option &ic); 00366 00367 /// Create a new command 00368 // int replace_command(comm_option &ic); 00369 00370 /// Set the parameters with a collection 00371 int set_parameters(collection &co); 00372 00373 /// Set one-line help text for a parameter named \c param 00374 int set_param_help(std::string param, std::string help); 00375 00376 /** 00377 \brief Set an alias \c alias for the string \c str 00378 00379 Aliases can also be set using the command \c 'alias', but 00380 that version allows only one-word aliases. 00381 */ 00382 int set_alias(std::string alias, std::string str) { 00383 al1.push_back(alias); 00384 al2.push_back(str); 00385 return 0; 00386 } 00387 00388 }; 00389 00390 #ifndef DOXYGENP 00391 } 00392 #endif 00393 00394 #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