summary refs log tree commit diff
path: root/Src/Zle/computil.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/computil.c')
-rw-r--r--Src/Zle/computil.c122
1 files changed, 84 insertions, 38 deletions
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 79e18b002..7f743492a 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -305,8 +305,12 @@ struct cadef {
     int argsactive;		/* if arguments are still allowed */
 				/* used while parsing a command line */
     char *set;			/* set name, shared */
+    int flags;			/* see CDF_* below */
 };
 
+#define CDF_SEP 1
+#define CDF_ARG 2
+
 /* Description for an option. */
 
 struct caopt {
@@ -325,6 +329,7 @@ struct caopt {
 #define CAO_DIRECT  2
 #define CAO_ODIRECT 3
 #define CAO_EQUAL   4
+#define CAO_OEQUAL  5
 
 /* Description for an argument */
 
@@ -515,7 +520,7 @@ parse_cadef(char *nam, char **args, int multi)
     Caarg argp;
     char **oargs = args, *p, *q, *match = "r:|[_-]=* r:|=*", **xor;
     char *adpre, *adsuf, *set = NULL, *doset = NULL;
-    int single = 0, anum = 1, xnum, nopts, ndopts, nodopts;
+    int single = 0, anum = 1, xnum, nopts, ndopts, nodopts, flags = 0;
 
     nopts = ndopts = nodopts = 0;
 
@@ -536,23 +541,40 @@ parse_cadef(char *nam, char **args, int multi)
     } else
 	adpre = adsuf = NULL;
 
-    /* Now get the -s and -M options. */
+    /* Now get the -s, -A, -S and -M options. */
 
     args++;
-    while ((p = *args)) {
-	if (!strcmp(p, "-s"))
-	    single = 1;
-	else if (p[0] == '-' && p[1] == 'M') {
-	    if (p[2])
-		match = p + 2;
-	    else if (args[1])
-		match = *++args;
-	    else {
-		args++;
+    while ((p = *args) && *p == '-') {
+	for (q = ++p; *q; q++)
+	    if (*q == 'M') {
+		q = "";
+		break;
+	    } else if (*q != 's' && *q != 'S' && *q != 'A')
 		break;
+
+	if (*q)
+	    break;
+
+	for (; *p; p++) {
+	    if (*p == 's')
+		single = 1;
+	    else if (*p == 'S')
+		flags |= CDF_SEP;
+	    else if (*p == 'A')
+		flags |= CDF_ARG;
+	    else if (*p == 'M') {
+		if (p[1]) {
+		    match = p + 1;
+		    p = "" - 1;
+		} else if (args[1])
+		    match = *++args;
+		else
+		    break;
 	    }
-	} else
+	}
+	if (*p)
 	    break;
+
 	args++;
     }
     if (!*args)
@@ -574,6 +596,7 @@ parse_cadef(char *nam, char **args, int multi)
     } else
 	ret->single = NULL;
     ret->match = ztrdup(match);
+    ret->flags = flags;
 
     /* Get the definitions. */
 
@@ -659,8 +682,10 @@ parse_cadef(char *nam, char **args, int multi)
 
 	    /* Skip over the name. */
 	    for (p++; *p && *p != ':' && *p != '[' &&
-		     ((*p != '-' && *p != '+' && *p != '=') ||
-		      (p[1] != ':' && p[1] != '[')); p++)
+		     ((*p != '-' && *p != '+') ||
+		      (p[1] != ':' && p[1] != '[')) &&
+		     (*p != '=' ||
+		      (p[1] != ':' && p[1] != '[' && p[1] != '-')); p++)
 		if (*p == '\\' && p[1])
 		    p++;
 
@@ -674,8 +699,11 @@ parse_cadef(char *nam, char **args, int multi)
 		otype = CAO_ODIRECT;
 		c = *++p;
 	    } else if (c == '=') {
-		otype = CAO_EQUAL;
-		c = *++p;
+		otype = CAO_OEQUAL;
+		if ((c = *++p) == '-') {
+		    otype = CAO_EQUAL;
+		    c = *++p;
+		}
 	    }
 	    /* Get the optional description, if any. */
 	    if (c == '[') {
@@ -797,9 +825,9 @@ parse_cadef(char *nam, char **args, int multi)
 	    opt->args = oargs;
 	    opt->num = nopts++;
 
-	    if (otype == CAO_DIRECT)
+	    if (otype == CAO_DIRECT || otype == CAO_EQUAL)
 		ndopts++;
-	    else if (otype == CAO_ODIRECT || otype == CAO_EQUAL)
+	    else if (otype == CAO_ODIRECT || otype == CAO_OEQUAL)
 		nodopts++;
 
 	    /* If this is for single-letter option we also store a
@@ -952,7 +980,8 @@ ca_get_opt(Cadef d, char *line, int full, char **end)
 		    /* Return a pointer to the end of the option. */
 		    int l = strlen(p->name);
 
-		    if (p->type == CAO_EQUAL && line[l] == '=')
+		    if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
+			line[l] == '=')
 			l++;
 
 		    *end = line + l;
@@ -983,7 +1012,8 @@ ca_get_sopt(Cadef d, char *line, int full, char **end)
 		p->args && p->type != CAO_NEXT && p->name[0] == pre) {
 		if (end) {
 		    line++;
-		    if (p->type == CAO_EQUAL && *line == '=')
+		    if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
+			*line == '=')
 			line++;
 		    *end = line;
 		}
@@ -1022,14 +1052,14 @@ ca_get_arg(Cadef d, int n)
 static LinkList ca_xor;
 
 static int
-ca_inactive(Cadef d, char **xor, int cur)
+ca_inactive(Cadef d, char **xor, int cur, int opts)
 {
-    if (xor && cur <= compcurrent) {
+    if ((xor || opts) && cur <= compcurrent) {
 	Caopt opt;
 	char *x;
 	int sl = (d->set ? strlen(d->set) : -1);
 
-	for (; (x = *xor); xor++) {
+	for (; (x = (opts ? "-" : *xor)); xor++) {
 	    if (ca_xor)
 		addlinknode(ca_xor, x);
 	    if (sl > 0) {
@@ -1059,6 +1089,9 @@ ca_inactive(Cadef d, char **xor, int cur)
 		    a->active = 0;
 	    } else if ((opt = ca_get_opt(d, x, 1, NULL)))
 		opt->active = 0;
+
+	    if (opts)
+		break;
 	}
     }
     return 0;
@@ -1145,10 +1178,13 @@ ca_parse_line(Cadef d, int multi)
 	ddef = adef = NULL;
 	doff = state.singles = 0;
 
-	if (ca_inactive(d, argxor, cur))
-	    return 1;
-
-	/* We've a definition for an argument, skip to the next. */
+	if (ca_inactive(d, argxor, cur, 0) ||
+	    ((d->flags & CDF_SEP) && !strcmp(line, "--"))) {
+	    if (ca_inactive(d, NULL, cur, 1))
+		return 1;
+	    continue;
+	}
+	/* We've got a definition for an argument, skip to the next. */
 
 	if (state.def) {
 	    state.arg = 0;
@@ -1186,10 +1222,14 @@ ca_parse_line(Cadef d, int multi)
 	/* See if it's an option. */
 
 	if (state.opt == 2 && (state.curopt = ca_get_opt(d, line, 0, &pe)) &&
-	    (state.curopt->type != CAO_EQUAL || 
-	     compwords[cur] || pe[-1] == '=')) {
-
-	    ddef = state.def = state.curopt->args;
+	    (state.curopt->type == CAO_OEQUAL ?
+	     (compwords[cur] || pe[-1] == '=') :
+	     (state.curopt->type == CAO_EQUAL ?
+	      (pe[-1] == '=' || !pe[0]) : 1))) {
+
+	    ddef = state.def = ((state.curopt->type != CAO_EQUAL ||
+				 pe[-1] == '=') ?
+				state.curopt->args : NULL);
 	    doff = pe - line;
 	    state.optbeg = state.argbeg = state.inopt = cur;
 	    state.singles = (d->single && (!pe || !*pe) &&
@@ -1197,15 +1237,16 @@ ca_parse_line(Cadef d, int multi)
 
 	    state.oargs[state.curopt->num] = znewlinklist();
 
-	    if (ca_inactive(d, state.curopt->xor, cur))
+	    if (ca_inactive(d, state.curopt->xor, cur, 0))
 		return 1;
 
 	    /* Collect the argument strings. Maybe. */
 
 	    if (state.def &&
 		(state.curopt->type == CAO_DIRECT ||
+		 state.curopt->type == CAO_EQUAL ||
 		 (state.curopt->type == CAO_ODIRECT && pe[0]) ||
-		 (state.curopt->type == CAO_EQUAL &&
+		 (state.curopt->type == CAO_OEQUAL &&
 		  (pe[0] || pe[-1] == '=')))) {
 		if (state.def->type != CAA_REST &&
 		    state.def->type != CAA_RARGS &&
@@ -1237,14 +1278,15 @@ ca_parse_line(Cadef d, int multi)
 		if ((tmpopt = d->single[STOUC(*p)])) {
 		    state.oargs[tmpopt->num] = znewlinklist();
 
-		    if (ca_inactive(d, tmpopt->xor, cur))
+		    if (ca_inactive(d, tmpopt->xor, cur, 0))
 			return 1;
 		}
 	    }
 	    if (state.def &&
 		(state.curopt->type == CAO_DIRECT ||
+		 state.curopt->type == CAO_EQUAL ||
 		 (state.curopt->type == CAO_ODIRECT && pe[0]) ||
-		 (state.curopt->type == CAO_EQUAL &&
+		 (state.curopt->type == CAO_OEQUAL &&
 		  (pe[0] || pe[-1] == '=')))) {
 		if (state.def->type != CAA_REST &&
 		    state.def->type != CAA_RARGS &&
@@ -1261,6 +1303,9 @@ ca_parse_line(Cadef d, int multi)
 	    return 1;
 	else if (state.arg) {
 	    /* Otherwise it's a normal argument. */
+	    if ((d->flags & CDF_ARG) && ca_inactive(d, NULL, cur + 1, 1))
+		return 1;
+
 	    if (state.inopt) {
 		state.inopt = 0;
 		state.nargbeg = cur - 1;
@@ -1541,7 +1586,7 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
 		ca_xor = newlinklist();
 		if ((xor = getaparam(args[1]))) {
 		    if (arrcontains(xor, args[2], 0) ||
-			ca_inactive(def, xor, compcurrent)) {
+			ca_inactive(def, xor, compcurrent, 0)) {
 			ca_xor = cax;
 			return 1;
 		    }
@@ -1645,7 +1690,8 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
 		      ztrdup(ca_laststate.ddef ?
 			     (ca_laststate.ddef->type == CAO_DIRECT ?
 			      "direct" :
-			      (ca_laststate.ddef->type == CAO_EQUAL ?
+			      ((ca_laststate.ddef->type == CAO_OEQUAL ||
+				ca_laststate.ddef->type == CAO_EQUAL) ?
 			       "equal" : "next")) : ""));
 	    return 0;
 	}