00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025
00026 #include "opt.h"
00027
00028 static int _ParseLongOption( GnoOption_s * pOpt, char * pszArg )
00029 {
00030 char * pszLong;
00031 char * pszPar;
00032 char * pszMatch = NULL;
00033 int nret;
00034
00035
00036 if ( pOpt->pszLong == NULL )
00037 {
00038 return 0;
00039 }
00040
00041 pszLong = strdup( pOpt->pszLong );
00042
00043 if ( (pszPar = strchr( pszArg, '=' )) != NULL )
00044 {
00045 *pszPar = 0;
00046 }
00047 pszMatch = strdup( pszArg );
00048 if ( pszPar ) *pszPar++ = '=';
00049
00050 if ( strcmp( pszLong , pszMatch+2 ) == 0 )
00051 {
00052
00053
00054
00055 if ( pszPar == NULL )
00056 {
00057 nret = -1; goto free_and_exit;
00058 }
00059
00060 if ( pOpt->ppszValue )
00061 {
00062 if ( pOpt->ppszValue[ 0 ] ) free( pOpt->ppszValue[ 0 ] );
00063 pOpt->ppszValue[ 0 ] = strdup( pszPar );
00064 }
00065
00066 nret = 1; goto free_and_exit;
00067 }
00068
00069 nret = 0;
00070
00071 free_and_exit:
00072
00073 free( pszLong );
00074 free( pszMatch );
00075
00076 return nret;
00077 }
00078
00079 static int _ParseLongSwitch( GnoOption_s * pOpt, char * pszArg )
00080 {
00081
00082 if ( pOpt->pszLong == NULL )
00083 {
00084 return 0;
00085 }
00086
00087 if ( strcmp( pOpt->pszLong , pszArg+2 ) == 0 )
00088 {
00089 if ( pOpt->pfValue ) *pOpt->pfValue = True;
00090
00091 return 1;
00092 }
00093
00094 return 0;
00095 }
00096
00097
00098 static int _ParseShortOption( GnoOption_s * pOpt, char * pszArg, char * pszPar )
00099 {
00100 char * pszShort;
00101 int ich;
00102
00103 if ( pOpt->pszShort == NULL ) return 0;
00104
00105 pszShort = strdup( pOpt->pszShort );
00106
00107 for ( ich = 1; pszArg[ ich ]; ich ++ )
00108 {
00109 if ( pszShort[ 0 ] == pszArg[ ich ] )
00110 {
00111 if ( pszPar == NULL || pszPar[ 0 ] == 0 )
00112 {
00113 free( pszShort );
00114
00115 return -1;
00116 }
00117
00118 if ( pszPar[ 0 ] == '-' && pszPar[ 1 ] != 0 )
00119 {
00120 free( pszShort );
00121
00122 return -1;
00123 }
00124
00125 if ( pOpt->ppszValue )
00126 {
00127 if ( pOpt->ppszValue[ 0 ] ) free( pOpt->ppszValue[ 0 ] );
00128 pOpt->ppszValue[ 0 ] = strdup( pszPar );
00129 }
00130
00131 free( pszShort );
00132
00133 return 2;
00134 }
00135 }
00136
00137 free( pszShort );
00138
00139 return 0;
00140 }
00141
00142 static int _ParseShortSwitch( GnoOption_s * pOpt, char * pszArg )
00143 {
00144 int ich;
00145
00146 if ( pOpt->pszShort == NULL ) return 0;
00147
00148 for ( ich = 1; pszArg[ ich ]; ich ++ )
00149 {
00150 if ( pOpt->pszShort[ 0 ] == pszArg[ ich ] )
00151 {
00152 if ( pOpt->pfValue ) *pOpt->pfValue = True;
00153
00154 return 1;
00155 }
00156 }
00157
00158 return 0;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 int GnoParse( int argc , char ** argv , GnoOption_s * pOpt )
00191 {
00192 char * pszArgv;
00193 char * pszArgvNxt;
00194 int iArg, iOpt, cOrphan = 0;
00195 int nret, cret;
00196 Boolean fParseError = False;
00197
00198
00199
00200
00201
00202 for (
00203 iOpt = 0 ;
00204 pOpt[ iOpt ].pszShort || pOpt[ iOpt ].pszLong ;
00205 iOpt ++
00206 )
00207 {
00208 if ( pOpt[ iOpt ].nFlg & GNO_FLG_SWITCH )
00209 {
00210 if ( pOpt[ iOpt ].pfValue )
00211 {
00212 pOpt[ iOpt ].pfValue[ 0 ] = pOpt[ iOpt ].fDef;
00213 }
00214 }
00215 else
00216 {
00217 if ( pOpt[ iOpt ].pszDef )
00218 {
00219 if ( pOpt[ iOpt ].ppszValue )
00220 {
00221 pOpt[ iOpt ].ppszValue[ 0 ] = strdup( pOpt[ iOpt ].pszDef );
00222 }
00223 }
00224 else
00225 {
00226 if ( pOpt[ iOpt ].ppszValue )
00227 {
00228 pOpt[ iOpt ].ppszValue[ 0 ] = NULL;
00229 }
00230 }
00231 }
00232 }
00233
00234
00235
00236 for (
00237 iArg = 0, pszArgv = NULL ;
00238 iArg < argc && (pszArgv = strdup( argv[ iArg ] )) != NULL ;
00239 iArg ++, free( pszArgv ), pszArgv = NULL
00240 )
00241 {
00242
00243 if ( pszArgv[ 0 ] == '-' && pszArgv[ 1 ] == '-' && pszArgv[ 2 ] )
00244 {
00245 for (
00246 iOpt = 0 ;
00247 (pOpt[ iOpt ].pszShort || pOpt[ iOpt ].pszLong) && argv[ iArg ] ;
00248 iOpt ++
00249 )
00250 {
00251 if ( pOpt[ iOpt ].pszLong )
00252 {
00253 if ( pOpt[ iOpt ].nFlg & GNO_FLG_SWITCH )
00254 {
00255 nret = _ParseLongSwitch( & pOpt[ iOpt ], pszArgv );
00256 }
00257 else
00258 {
00259 nret = _ParseLongOption( & pOpt[ iOpt ], pszArgv );
00260 }
00261
00262 if ( nret < 0 )
00263 {
00264 fprintf( stderr, "parse option: syntax error at <%s>\n", pszArgv );
00265 fParseError = True;
00266 }
00267
00268 if ( nret == 1 )
00269 {
00270 argv[ iArg ] = NULL;
00271 }
00272 }
00273 }
00274
00275 if ( argv[ iArg ] )
00276 {
00277 fprintf( stderr, "parse option: <%s> is out of scope\n", pszArgv );
00278 fParseError = True;
00279 }
00280 }
00281 else if ( argv[iArg][ 0 ] == '-' && argv[iArg][ 1 ] )
00282 {
00283 if ( iArg + 1 < argc )
00284 {
00285 pszArgvNxt = strdup( argv[ iArg + 1 ] );
00286 }
00287 else
00288 {
00289 pszArgvNxt = NULL;
00290 }
00291
00292 for (
00293 cret = iOpt = 0 ;
00294 pOpt[ iOpt ].pszShort || pOpt[ iOpt ].pszLong ;
00295 iOpt ++
00296 )
00297 {
00298 if ( pOpt[ iOpt ].pszShort )
00299 {
00300 if ( pOpt[ iOpt ].nFlg & GNO_FLG_SWITCH )
00301 {
00302 nret = _ParseShortSwitch( & pOpt[ iOpt ], pszArgv );
00303 }
00304 else
00305 {
00306 nret = _ParseShortOption( & pOpt[ iOpt ], pszArgv , pszArgvNxt );
00307 }
00308 if ( nret < 0 )
00309 {
00310 fprintf( stderr, "parse option: syntax error at <%s>\n", pszArgv );
00311 fParseError = True;
00312 }
00313 else
00314 {
00315 cret = (nret>cret) ? nret : cret;
00316 }
00317 }
00318 }
00319
00320 if ( pszArgvNxt )
00321 {
00322 free( pszArgvNxt );
00323 }
00324
00325 if ( cret == 1 )
00326 {
00327 argv[ iArg ] = NULL;
00328 }
00329 else if ( cret == 2 )
00330 {
00331 argv[ iArg++ ] = NULL;
00332 argv[ iArg ] = NULL;
00333 }
00334
00335 }
00336 else
00337 {
00338 cOrphan ++;
00339 }
00340 }
00341
00342 if ( pszArgv ) free( pszArgv );
00343
00344 return ( fParseError == True ) ? -1 : cOrphan;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 void GnoFree( GnoOption_s * pOpt )
00358 {
00359 int iOpt;
00360
00361 for (
00362 iOpt = 0 ;
00363 pOpt[ iOpt ].pszShort || pOpt[ iOpt ].pszLong ;
00364 iOpt ++
00365 )
00366 {
00367 if ( pOpt[ iOpt ].ppszValue )
00368 {
00369 if ( pOpt[ iOpt ].ppszValue[ 0 ] )
00370 {
00371 free( pOpt[ iOpt ].ppszValue[ 0 ] );
00372 pOpt[ iOpt ].ppszValue[ 0 ] = NULL;
00373 }
00374 }
00375 }
00376
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 void GnoHelp( char *pszHead, GnoOption_s * pOpt )
00391 {
00392 int iOpt;
00393
00394 fprintf( stderr, "%s\n", (pszHead) ? pszHead : "options" );
00395
00396 for (
00397 iOpt = 0 ;
00398 pOpt[ iOpt ].pszShort || pOpt[ iOpt ].pszLong ;
00399 iOpt ++
00400 )
00401 {
00402
00403 if ( pOpt[ iOpt ].nFlg & GNO_FLG_SWITCH )
00404 {
00405 if ( pOpt[ iOpt ].pszShort )
00406 {
00407 fprintf( stderr, "-%s ", pOpt[ iOpt ].pszShort );
00408 }
00409
00410 if ( pOpt[ iOpt ].pszLong )
00411 {
00412 fprintf( stderr, "--%s", pOpt[ iOpt ].pszLong );
00413 }
00414
00415 fprintf( stderr, "\n\t%s\n",
00416 ( pOpt[ iOpt ].pszDescr )
00417 ?
00418 pOpt[ iOpt ].pszDescr
00419 :
00420 "No description available."
00421 );
00422 }
00423 else
00424 {
00425 if ( pOpt[ iOpt ].pszShort )
00426 {
00427 fprintf( stderr, "-%s ", pOpt[ iOpt ].pszShort );
00428
00429 fprintf( stderr, "<value> " );
00430 }
00431
00432 if ( pOpt[ iOpt ].pszLong )
00433 {
00434 fprintf( stderr, "--%s", pOpt[ iOpt ].pszLong );
00435
00436 fprintf( stderr, "=<value>" );
00437 }
00438
00439 fprintf( stderr, "\n\t%s\n",
00440 ( pOpt[ iOpt ].pszDescr )
00441 ?
00442 pOpt[ iOpt ].pszDescr
00443 :
00444 "No description available."
00445 );
00446 }
00447 }
00448
00449 }
00450
00451
00452