optparser.c

changeset 3
b1fbfab67908
parent 0
86b7f6f9c5c0
child 5
f878a9ffa3e0
--- 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:

mercurial