00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032
00033 #include "xalloc.h"
00034 #include "clargs.h"
00035 #include "uti.h"
00036
00037
00038
00039 PRIVATE const char * _file_switches[3] = {
00040 CLARGS_CFGFILE,
00041 CLARGS_ARGFILE,
00042 NULL
00043 };
00044
00045 int _clargs_case_sensitive = 0;
00046
00047
00048
00049
00050
00051 void clargs_close_cfgf( clargs * c )
00052 {
00053 if (c->cfgf!=NULL)
00054 cdie_beep(fclose(c->cfgf) == EOF,"clargs: error closing config file");
00055
00056 c->cfgf = NULL;
00057 }
00058
00059
00060
00061
00062
00063 void clargs_close_argf( clargs * c )
00064 {
00065 if (c->argf!=NULL) {
00066 cdie_beep(fclose(c->argf) == EOF,"clargs: error closing args file");
00067 }
00068 c->argf = NULL;
00069 }
00070
00071
00072
00073
00074
00075
00076 void clargs_close_f( clargs * c )
00077 {
00078 clargs_close_argf(c);
00079 clargs_close_cfgf(c);
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 void clargs_open_cfgf( clargs * c )
00090 {
00091 if (c->cfgfn!=NULL) {
00092 if ((c->cfgf=fopen(c->cfgfn,"r")) == NULL) {
00093 cdie_beep(c->exefn==NULL,"clargs: error opening config file %s",c->cfgfn);
00094 c->cfgf=fopen(c->exefn,"r");
00095 }
00096 }
00097 }
00098
00099
00100
00101
00102
00103
00104 void clargs_open_argf( clargs * c, char * argfn )
00105 {
00106 cdie_beep(c->argf!=NULL,"clargs: error, can't manage recursive args file");
00107
00108 cdie_beep((c->argf=fopen(argfn,"r")) == NULL,"clargs: error opening args file %s",argfn);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118 char * clargs_find_cfgfn( clargs * c, int argc, char * argv[] )
00119 {
00120 int i;
00121 char * retval = NULL;
00122
00123 (void)c;
00124 for (i=0; i<argc; i++) {
00125 if (str_isswitch(argv[i])) {
00126 if (label_match(_file_switches,1,argv[i]+1,_clargs_case_sensitive,0)==0)
00127 retval = argv[i];
00128 }
00129 }
00130 if (retval!=NULL)
00131 return str_assignptrnext(retval);
00132 else
00133 return NULL;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 char * clargs_exe_cfgfn( clargs * c, const char * exen, const char * cfgfn )
00146 {
00147 (void)c;
00148 return path_src2destp(exen,cfgfn,"");
00149 }
00150
00151
00152
00153
00154
00155 char * clargs_readcfgf( clargs * c )
00156 {
00157 char * retval;
00158
00159 clearerr(c->cfgf);
00160 retval = fgetlnf(c->args,CLARGS_MAX_LEN,c->cfgf);
00161 cdie_beep(ferror(c->cfgf),"clargs: error reading config file");
00162 return retval;
00163 }
00164
00165
00166
00167
00168
00169 char * clargs_readargf( clargs * c )
00170 {
00171 char * retval;
00172
00173 clearerr(c->argf);
00174 retval = fgetlnf(c->args,CLARGS_MAX_LEN,c->argf);
00175 cdie_beep(ferror(c->argf),"clargs: error reading args file");
00176 return retval;
00177 }
00178
00179
00180
00181
00182
00183 char * clargs_readcl( clargs * c )
00184 {
00185 if ((++(c->lastarg)) >= (c->argc))
00186 return NULL;
00187 else
00188 return (strcpy(c->args,c->argv[c->lastarg]));
00189 }
00190
00191
00192
00193
00194
00195 char * clargs_read_a( clargs * c )
00196 {
00197 char * retval;
00198
00199 if (c->argf!=NULL) {
00200 retval = clargs_readargf(c);
00201 if (retval==NULL)
00202 clargs_close_argf(c);
00203 else
00204 return retval;
00205 }
00206 if (c->cfgf!=NULL) {
00207 retval = clargs_readcfgf(c);
00208 if (retval==NULL)
00209 clargs_close_cfgf(c);
00210 else
00211 return retval;
00212 }
00213
00214 retval = clargs_readcl(c);
00215 if (retval==NULL)
00216 clargs_close_f(c);
00217
00218 return retval;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 clargs * clargs_construct( int argc, char * argv[], const char * def_cfgfn )
00239 {
00240 clargs * c = NULL;
00241
00242 c = (clargs *)xmalloc(sizeof(clargs));
00243 cdie_beep(c==NULL,"clargs: error constructing command line parser");
00244
00245 c->argc = argc-1;
00246 c->argv = argv+1;
00247 c->lastarg = -1;
00248
00249 c->exefn = NULL;
00250 c->cfgfn = clargs_find_cfgfn(c,c->argc,c->argv);
00251 if (c->cfgfn!=NULL)
00252 c->cfgfn = xstrdup(c->cfgfn);
00253 else if (def_cfgfn!=NULL) {
00254 c->cfgfn = xstrdup(def_cfgfn);
00255 c->exefn = clargs_exe_cfgfn(c,argv[0],def_cfgfn);
00256 }
00257
00258 c->cfgf = NULL;
00259 c->argf = NULL;
00260
00261 clargs_restart(c);
00262 return c;
00263 }
00264
00265
00266
00267
00268
00269 void clargs_destruct( clargs * c )
00270 {
00271 clargs_close_f(c);
00272
00273 if (c->cfgfn!=NULL)
00274 xfree(c->cfgfn);
00275 if (c->exefn!=NULL)
00276 xfree(c->exefn);
00277
00278 if (c)
00279 xfree(c);
00280 }
00281
00282
00283
00284
00285
00286 void clargs_restart( clargs * c )
00287 {
00288 clargs_close_f(c);
00289 clargs_open_cfgf(c);
00290 c->lastarg = (-1);
00291 }
00292
00293
00294
00295
00296
00297 char * clargs_getarg( clargs * c )
00298 {
00299 char * retval;
00300
00301 while (1) {
00302 retval=clargs_read_a(c);
00303 if (retval==NULL)
00304 break;
00305
00306 if (str_isswitch(retval)) {
00307 int i = label_match(_file_switches,2,retval+1,_clargs_case_sensitive,0);
00308 if (i==1)
00309 clargs_open_argf(c,str_assignptrnext(retval));
00310 else if (i<0)
00311 break;
00312 }
00313 else
00314 break;
00315 }
00316 return retval;
00317 }
00318
00319
00320
00321
00322
00323 char * clargs_getsarg( clargs * c )
00324 {
00325 char * retval;
00326
00327 while (1) {
00328 retval=clargs_getarg(c);
00329 if ((retval==NULL)||(str_isswitch(retval)))
00330 break;
00331 }
00332 return retval;
00333 }
00334
00335
00336
00337
00338
00339 char * clargs_getparg( clargs * c )
00340 {
00341 char * retval;
00342
00343 while (1) {
00344 retval=clargs_getarg(c);
00345 if ((retval==NULL)||(!(str_isswitch(retval))))
00346 break;
00347 }
00348 return retval;
00349 }
00350
00351
00352
00353
00354
00355
00356 clasw * clasw_construct( int argc, char * argv[], const char * sw[],
00357 const char * def_cfgfn )
00358 {
00359 clasw * c;
00360
00361 c = (clasw *)xmalloc(sizeof(clasw));
00362 cdie_beep(c==NULL,"clasw: error constructing command line parser");
00363
00364 c->c=clargs_construct(argc,argv,def_cfgfn);
00365 c->switches=sw;
00366 c->nswitches=nptrs((const void * *)sw);
00367
00368 return c;
00369 }
00370
00371
00372
00373
00374
00375 void clasw_destruct( clasw * c )
00376 {
00377 clargs_destruct(c->c);
00378 xfree(c);
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 int clasw_getsw( clasw * c, char * * value, int allow_unknown )
00391 {
00392 int retval;
00393
00394 *value = clargs_getsarg(c->c);
00395 if (*value!=NULL) {
00396 (*value)++;
00397 retval = label_match( c->switches,c->nswitches,*value,
00398 _clargs_case_sensitive,1);
00399 cdie_beep(retval==-2,"clasw: ambiguous label (%s)",*value);
00400 if (retval==-1) {
00401 cdie_beep(!allow_unknown,"error: unknown label (%s)",*value);
00402 retval=-2;
00403 }
00404 else
00405 *value = str_assignptrnext(*value);
00406 }
00407 else
00408 retval = -1;
00409
00410 return retval;
00411 }
00412
00413
00414
00415 void clasw_restart( clasw * c )
00416 {
00417 clargs_restart(c->c);
00418 }
00419
00420
00421
00422 char * clasw_getarg( clasw * c )
00423 {
00424 return clargs_getarg(c->c);
00425 }
00426
00427
00428
00429 char * clasw_getsarg( clasw * c )
00430 {
00431 return clargs_getsarg(c->c);
00432 }
00433
00434
00435
00436 char * clasw_getparg( clasw * c )
00437 {
00438 return clargs_getparg(c->c);
00439 }
00440
00441