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