Main Page   Class Hierarchy   Compound List   File List   Compound Members  

C_CommandLine.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  * (c)Copyright 2006 Hewlett-Packard Development Company, LP.
00017  *
00018  */
00019 
00020 #include <cctype>
00021 #include <cstring>
00022 
00023 #include "C_CommandLine.hpp"
00024 
00025 
00026 #define UNRECOGNIZED_OPTION -1
00027 
00028 template <class T_TIndexCommand> C_CommandLine<T_TIndexCommand>::C_CommandLine() {
00029   f_programName         = NULL ;
00030   f_command_description = NULL ;
00031   f_option_flags        = NULL ;
00032   f_noHelpIndex         = true ;
00033   f_internalHelpCode    = -1   ;
00034 }
00035 
00036 template <class T_TIndexCommand> C_CommandLine<T_TIndexCommand>::~C_CommandLine() {
00037   f_command_description = NULL ;
00038   f_noHelpIndex         = true ;
00039   f_internalHelpCode    = -1   ;
00040   FREE_VAR (f_programName);
00041   FREE_VAR (f_option_flags);
00042 }
00043 
00044 /*
00045  * function : usage
00046  *            command syntaxe display 
00047  */
00048 
00049 template <class T_TIndexCommand> void C_CommandLine<T_TIndexCommand>::usage (void) {
00050   
00051   int  i ;
00052   char tmpstr[255] ;
00053 
00054   iostream_error << f_programName << iostream_endl ;
00055 
00056 #ifdef VERSION
00057   iostream_error << " Version tool   : " << (char*)VERSION << iostream_endl ;
00058 #endif
00059   iostream_error << " Command syntax : " << iostream_endl ;
00060 
00061   for(i=0; i<(f_command_description->nb_options); i++) {
00062     switch (f_command_description->command_options[i].option_type) {
00063     case E_OT_MANDATORY:
00064       sprintf(tmpstr, " -%s %s %s\n",
00065               f_command_description->command_options[i].name,
00066               f_command_description->command_options[i].param_comment,
00067               f_command_description->command_options[i].comments);
00068       break ;
00069     case E_OT_OPTIONAL:
00070       sprintf(tmpstr, "[ -%s %s ] %s \n",
00071               f_command_description->command_options[i].name,
00072               f_command_description->command_options[i].param_comment,
00073               f_command_description->command_options[i].comments);      
00074       break ;
00075     default :
00076       iostream_error << "Unsupported option type" << iostream_endl ;
00077       usage () ;
00078       exit (-1) ;
00079     }
00080     iostream_error << tmpstr ;
00081   }
00082 } /* usage */
00083 
00084 template <class T_TIndexCommand>
00085 int C_CommandLine<T_TIndexCommand>::integer_ok (char *name) {
00086   unsigned int i ;
00087   for(i=0; i<strlen(name); i++) {
00088     if (!isdigit(name[i])) { return -1; }
00089   }
00090   return 0 ;
00091 }
00092 
00093 template <class T_TIndexCommand>
00094 int C_CommandLine<T_TIndexCommand>::octet_hexa_ok (char *name) {
00095   if (strlen(name) == 4) {
00096     if ((name[0] != '0') 
00097         || ((name[1] != 'x') && (name[1] != 'X')) 
00098         || (!isxdigit(name[2])) 
00099         || (!isxdigit(name[3]))) {
00100       return -1 ;
00101     }
00102   } else {
00103     return -1 ;
00104   }
00105   return 0 ;
00106 }
00107 
00108 template <class T_TIndexCommand> bool C_CommandLine<T_TIndexCommand>::VerifyOptionValues (int opt, int idx, char **argv) {
00109   
00110   int nb_values_to_verify ;
00111   int valueIdx ;
00112   int currentIdx = 0 ;
00113   char *currentValue ;
00114 
00115   nb_values_to_verify = f_command_description->command_options[opt].nb_values ;
00116   valueIdx = idx ;
00117 
00118   while (nb_values_to_verify > 0) {
00119     currentValue = argv[valueIdx] ;
00120     switch (f_command_description->command_options[opt].values_types[currentIdx]) {
00121     case E_VT_INTEGER:
00122       if (integer_ok (currentValue) == -1) {
00123         return false;
00124       }
00125       break ;
00126     case E_VT_OCTET_HEXA:
00127       if (octet_hexa_ok (currentValue) == -1) {
00128         return false;
00129       }
00130       break ;
00131     case E_VT_STRING:
00132       break;
00133     default:
00134       iostream_error << "not supported argument value type" << iostream_endl ;
00135       usage () ;
00136       exit (-1);
00137     }
00138     valueIdx ++ ;
00139     currentIdx ++ ;
00140     nb_values_to_verify -- ;
00141   }
00142 
00143   return true ;
00144   
00145 }
00146 
00147 template <class T_TIndexCommand> int C_CommandLine<T_TIndexCommand>::SearchForOption (char *pattern) {
00148   int optionIdx ;
00149   for (optionIdx=0; optionIdx < f_command_description->nb_options; optionIdx++) {
00150     if (strcmp (pattern, f_command_description->command_options[optionIdx].name) == 0) {
00151       return (optionIdx) ;
00152     } /* if */
00153   } /* for */
00154   return (-1) ;
00155 }
00156 
00157 template <class T_TIndexCommand> int C_CommandLine<T_TIndexCommand>::SearchForOption (T_TIndexCommand idxCmd) {
00158   int optionIdx ;
00159   for (optionIdx=0; optionIdx < f_command_description->nb_options; optionIdx++) {
00160     if (idxCmd == f_command_description->command_options[optionIdx].index) {
00161       return (optionIdx) ;
00162     } /* if */
00163   } /* for */
00164   return (-1) ;
00165 }
00166 
00167 
00168 template <class T_TIndexCommand> bool C_CommandLine<T_TIndexCommand>::VerifyMandatoryArgs () {
00169   int optionIdx ;
00170   for (optionIdx=0; optionIdx < f_command_description->nb_options; optionIdx++) {
00171     if ((f_option_flags[optionIdx] == false) 
00172         && f_command_description->command_options[optionIdx].option_type == E_OT_MANDATORY) {
00173       iostream_error << "option -" << f_command_description->command_options[optionIdx].name << " is mandatory" << iostream_endl ;
00174       return false ;
00175     }
00176   } /* for */
00177   return true ;
00178 }
00179 
00180 template <class T_TIndexCommand> void C_CommandLine<T_TIndexCommand>::AnalyzeCommandLine (int argc, char **argv) {
00181   
00182   char option_first_char = '-' ;   // first character for option 
00183                                          // description of a command line
00184 
00185   int   currentArgIdx = 1 ;              // current command line argument index
00186   char *currentArg        ;              // current command line argument string
00187 
00188   int   optionCode        ;              // current option code 
00189   int   nextCmdshift      ;              // next command option position 
00190   
00191   // init command line with program name
00192   ALLOC_VAR(this->f_programName, char*, strlen(argv[0])+1);
00193   strcpy (this->f_programName, argv[0]) ;
00194 
00195   while ( currentArgIdx < argc ) { 
00196 
00197     currentArg = argv[currentArgIdx] ; 
00198 
00199     if (currentArg[0] != option_first_char) { // first character option verification
00200       iostream_error << "unrecognized option format " << currentArg << " in command line" << iostream_endl ;
00201       usage () ;
00202       exit (-1) ;
00203     }
00204 
00205     currentArg++ ; // shift to the second character (after minus)
00206     optionCode = SearchForOption (currentArg) ; // search for option description
00207 
00208     if (optionCode == UNRECOGNIZED_OPTION) { // unrecognized option
00209       iostream_error << "unrecognized option -" << currentArg << " in command line" << iostream_endl ;
00210       usage () ;
00211       exit (-1) ;
00212     }
00213     
00214     // the option has been recognized
00215     f_option_flags[optionCode] = true ; 
00216     
00217     nextCmdshift = f_command_description->command_options[optionCode].nb_values ;
00218     // ^ the next command option will be at position currentArgIdx + nextCmdshift ;
00219 
00220     // test : number of values for the option
00221     if ((currentArgIdx + 1 + nextCmdshift) > argc) {
00222       iostream_error << "option -" << currentArg << " has " << nextCmdshift << " value(s)" << iostream_endl ;
00223       usage () ;
00224       exit (-1);
00225     }
00226     currentArgIdx++ ; // index at the first value of the option
00227 
00228     // option values
00229     if (VerifyOptionValues (optionCode, currentArgIdx, argv) == false) {
00230       iostream_error << "bad value format for option -" << currentArg << iostream_endl ;
00231       usage () ;
00232       exit (-1) ;
00233     };
00234 
00235     if (set_data (f_command_description->command_options[optionCode].index, 
00236                   &argv[currentArgIdx]) == false) {
00237       iostream_error << "bad value format for option -" 
00238                      << currentArg << iostream_endl ;
00239       usage () ;
00240       exit (-1);
00241     } 
00242                      //    SearchForValue (optionCode, currentArgIdx, argv);
00243     
00244     currentArgIdx += nextCmdshift ;
00245   } /* while */
00246 
00247   if (f_noHelpIndex == false ) {
00248     if (f_option_flags[f_internalHelpCode] == true) { // help option has been used
00249       //    if (f_option_flags[f_command_description->help_index] == true) { 
00250       usage() ;
00251       exit (0) ;
00252     }
00253   }
00254 
00255   if (VerifyMandatoryArgs() == false) { // all mandatory parameters must be present
00256     usage () ;
00257     exit (-1) ;
00258   }
00259 
00260 } /* AnalyzeCommandLine */
00261 
00262 template <class T_TIndexCommand> int C_CommandLine<T_TIndexCommand>::startAnalyzeCommandLine (int argc, char **argv, 
00263                           T_command_line *command_descr) {
00264   
00265   if (command_descr != NULL) {
00266      f_command_description = command_descr ;
00267   } else {
00268     return ( -1 ) ;
00269   }
00270 
00271   ALLOC_VAR(this->f_option_flags, bool*, f_command_description->nb_options);
00272 
00273   for(int i=0; i<f_command_description->nb_options; i++) {
00274     this->f_option_flags[i] = false ;
00275   }
00276 
00277   if (f_command_description->help_index != -1) {
00278     f_noHelpIndex = false ;
00279     f_internalHelpCode = SearchForOption (f_command_description->help_index) ;
00280     if (f_internalHelpCode == -1) { 
00281       f_noHelpIndex = true ; 
00282     }
00283   }
00284 
00285   AnalyzeCommandLine(argc, argv) ;
00286 
00287   return 0 ;
00288 } /* startAnalyzeCommandLine */
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 

Generated on Wed Mar 7 14:44:49 2007 for Seagull by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002