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