00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00046
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 }
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 }
00153 }
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 }
00163 }
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 }
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 = '-' ;
00183
00184
00185 int currentArgIdx = 1 ;
00186 char *currentArg ;
00187
00188 int optionCode ;
00189 int nextCmdshift ;
00190
00191
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) {
00200 iostream_error << "unrecognized option format " << currentArg << " in command line" << iostream_endl ;
00201 usage () ;
00202 exit (-1) ;
00203 }
00204
00205 currentArg++ ;
00206 optionCode = SearchForOption (currentArg) ;
00207
00208 if (optionCode == UNRECOGNIZED_OPTION) {
00209 iostream_error << "unrecognized option -" << currentArg << " in command line" << iostream_endl ;
00210 usage () ;
00211 exit (-1) ;
00212 }
00213
00214
00215 f_option_flags[optionCode] = true ;
00216
00217 nextCmdshift = f_command_description->command_options[optionCode].nb_values ;
00218
00219
00220
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++ ;
00227
00228
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
00243
00244 currentArgIdx += nextCmdshift ;
00245 }
00246
00247 if (f_noHelpIndex == false ) {
00248 if (f_option_flags[f_internalHelpCode] == true) {
00249
00250 usage() ;
00251 exit (0) ;
00252 }
00253 }
00254
00255 if (VerifyMandatoryArgs() == false) {
00256 usage () ;
00257 exit (-1) ;
00258 }
00259
00260 }
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 }
00289
00290
00291
00292
00293
00294
00295
00296