--- a/optparser.c Wed Feb 23 08:47:59 2000 +0100 +++ b/optparser.c Wed Apr 19 22:03:38 2000 +0200 @@ -16,11 +16,6 @@ #include "include/output.h" -#define O_CHAINABLE(o) (o->flags&OPT_CHAINABLE) -#define O_IMM_ARG(o) (o->flags&OPT__IMM_ARG) -#define O_NO_DASH(o) (o->flags&OPT_NO_DASH) -#define O_MIDLONG(o) (o->flags&OPT_MIDLONG) -#define O_NO_LONG(o) (o->flags&OPT_NO_LONG) #define O_ARGS(o) (o->flags&OPT_OPT_ARG) #define O_ARG(o) (o->flasg&OPT_ARG) #define O_OPT_ARG(o) (O_ARGS(o)==OPT_OPT_ARG) @@ -34,13 +29,16 @@ static int o_args_left=0; static const char*o_tmp=NULL; static int o_error=0; +static int o_mode=OPTP_CHAIN; /* */ -void optparser_init(int argc, char *const argv[], const OptParserOpt *opts) +void optparser_init(int argc, char *const argv[], int mode, + const OptParserOpt *opts) { + o_mode=mode; o_opts=opts; o_current=argv+1; o_left=argc-1; @@ -56,14 +54,14 @@ static const OptParserOpt *find_chain_opt(char p, const OptParserOpt *o) { for(;O_ID(o);o++){ - if(O_CHAINABLE(o) && O_ID(o)==p) + if(O_ID(o)==p) return o; } return NULL; } -static bool valid_chain(const char *p, const OptParserOpt *o) +/*static bool valid_chain(const char *p, const OptParserOpt *o) { while(*p!='\0'){ if(!find_chain_opt(*p, o)) @@ -71,7 +69,7 @@ p++; } return TRUE; -} +}*/ static bool is_option(const char *p) @@ -90,12 +88,17 @@ /* */ +enum{ + SHORT, MIDLONG, LONG +}; + int optparser_get_opt() { #define RET(X) return o_tmp=p, o_error=X const char *p, *p2=NULL; - bool lo=FALSE, dash=TRUE; + bool dash=TRUE; + int type=SHORT; const OptParserOpt *o; int l; @@ -104,7 +107,7 @@ o_tmp=NULL; - /* Are we doing a chain (i.e. opt. of style 'tar xzf') ? */ + /* Are we doing a chain (i.e. opt. of style 'tar xzf')? */ if(o_chain_ptr!=NULL){ p=o_chain_ptr++; if(!*o_chain_ptr) @@ -125,16 +128,21 @@ p=*o_current++; if(*p!='-'){ - /* foo */ dash=FALSE; + if(o_mode!=OPTP_NO_DASH) + RET(OPT_ID_ARGUMENT); }else if(*(p+1)=='-'){ /* --foo */ if(*(p+2)=='\0'){ - /* -- */ + /* -- arguments */ o_args_left=o_left; RET(OPT_ID_ARGUMENT); } - lo=TRUE; + /*argptr=strchr(p, '='); + if(argptr!=NULL) + argptr++; + */ + type=LONG; p2=p+2; }else{ /* -foo */ @@ -143,6 +151,9 @@ o_args_left=1; RET(OPT_ID_ARGUMENT); } + if(*(p+2)!='\0' && o_mode==OPTP_MIDLONG) + type=MIDLONG; + p2=p+1; } @@ -150,7 +161,7 @@ again: for(;O_ID(o);o++){ - if(lo){ + if(type==LONG){ /* Do long option (--foo=bar) */ if(o->longopt==NULL) continue; @@ -158,9 +169,6 @@ if(strncmp(p2, o->longopt, l)!=0) continue; - if(O_NO_LONG(o)) - RET(E_OPT_INVALID_OPTION); - if(p2[l]=='\0'){ if(O_ARGS(o)==OPT_ARG) RET(E_OPT_MISSING_ARGUMENT); @@ -174,44 +182,52 @@ o_args_left=1; return O_ID(o); } - }else{ - /* Do midlong option (-foobar) */ - if(dash && o->longopt!=NULL && strcmp(p2, o->longopt)==0){ - if(!O_MIDLONG(o)) - RET(E_OPT_INVALID_OPTION); - goto do_arg; - } - - /* Do short option (-f) */ - if((!dash && !O_NO_DASH(o)) || *p2!=O_ID(o)) + continue; + }else if(type==MIDLONG){ + if(o->longopt==NULL) + continue; + + if(strcmp(p2, o->longopt)!=0) + continue; + }else{ /* type==SHORT */ + if(*p2!=O_ID(o)) continue; if(*(p2+1)!='\0'){ - if(O_CHAINABLE(o) && valid_chain(p2+1, o_opts)){ - o_chain_ptr=p2+1; - }else if(O_IMM_ARG(o)){ - o_tmp=p2+1; - o_args_left=1; - return O_ID(o); + if(o_mode==OPTP_CHAIN || o_mode==OPTP_NO_DASH){ + /*valid_chain(p2+1, o_opts)*/ + o_chain_ptr=p2+1; + p++; + }else if(o_mode==OPTP_IMMEDIATE){ + if(!O_ARGS(o)){ + if(*(p2+1)!='\0') + RET(E_OPT_UNEXPECTED_ARGUMENT); + }else{ + if(*(p2+1)=='\0') + RET(E_OPT_MISSING_ARGUMENT); + o_tmp=p2+1; + o_args_left=1; + } + return O_ID(o); }else{ - continue; + RET(E_OPT_SYNTAX_ERROR); } } -do_arg: - if(!O_ARGS(o)) + } + + do_arg: + + if(!O_ARGS(o)) + return O_ID(o); + + if(!o_left || is_option(*o_current)){ + if(O_ARGS(o)==OPT_OPT_ARG) return O_ID(o); - - if(O_ARGS(o)==OPT_ARG){ - if(o_left==0) - RET(E_OPT_MISSING_ARGUMENT); - }else{ - if(!o_left || is_option(*o_current)) - return O_ID(o); - } + RET(E_OPT_MISSING_ARGUMENT); + } - o_args_left=1; - return O_ID(o); - } + o_args_left=1; + return O_ID(o); } if(dash) @@ -254,7 +270,7 @@ static void warn_arg(const char *e) { - const char*p=optparser_get_arg(); + const char *p=optparser_get_arg(); if(p==NULL) warn("%s (null)", e); @@ -265,7 +281,7 @@ static void warn_opt(const char *e) { - if(o_chain_ptr!=NULL && o_tmp!=NULL) + if(o_tmp!=NULL && o_chain_ptr!=NULL) warn("%s \'-%c\'", e, *o_tmp); else warn_arg(e); @@ -276,13 +292,10 @@ { switch(o_error){ case E_OPT_INVALID_OPTION: + case E_OPT_INVALID_CHAIN_OPTION: warn_opt(TR("Invalid option")); break; - case E_OPT_INVALID_CHAIN_OPTION: - warn_opt(TR("Invalid option in chain (this cannot happen)")); - break; - case E_OPT_SYNTAX_ERROR: warn_arg(TR("Syntax error while parsing")); break; @@ -292,7 +305,7 @@ break; case E_OPT_UNEXPECTED_ARGUMENT: - warn_opt(TR("No argument expected to")); + warn_opt(TR("No argument expected:")); break; case OPT_ID_ARGUMENT: