summaryrefslogtreecommitdiff
path: root/Src/Zle/computil.c
diff options
context:
space:
mode:
authorSven Wischnowsky <wischnow@users.sourceforge.net>2000-06-13 12:14:32 +0000
committerSven Wischnowsky <wischnow@users.sourceforge.net>2000-06-13 12:14:32 +0000
commit9310826027fcd5a2a4b868f3cc89b1a5995aa931 (patch)
treeac7d7ace846ed95bb628e81fcf018c970ad386e0 /Src/Zle/computil.c
parentbde4cfde51526bb8910c1dfbce8b6e4c4e1f5149 (diff)
downloadzsh-9310826027fcd5a2a4b868f3cc89b1a5995aa931.tar.gz
zsh-9310826027fcd5a2a4b868f3cc89b1a5995aa931.zip
make -A take a pattern as argument to match non-arguments; allow single-letter option strings to have multiple arguments; fix to allow option completion with multiple sets (?)
Diffstat (limited to 'Src/Zle/computil.c')
-rw-r--r--Src/Zle/computil.c101
1 files changed, 62 insertions, 39 deletions
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index d32f77a1c..b58729fc1 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -308,10 +308,10 @@ struct cadef {
char *set; /* set name prefix (<name>-), shared */
char *sname; /* set name */
int flags; /* see CDF_* below */
+ char *nonarg; /* pattern for non-args (-A argument) */
};
#define CDF_SEP 1
-#define CDF_ARG 2
/* Description for an option. */
@@ -423,6 +423,7 @@ freecadef(Cadef d)
}
freecaargs(d->args);
freecaargs(d->rest);
+ zsfree(d->nonarg);
if (d->single)
zfree(d->single, 256 * sizeof(Caopt));
zfree(d, sizeof(*d));
@@ -518,7 +519,7 @@ parse_caarg(int mult, int type, int num, int opt, char *oname, char **def,
}
static Cadef
-alloc_cadef(char **args, int single, char *match, int flags)
+alloc_cadef(char **args, int single, char *match, char *nonarg, int flags)
{
Cadef ret;
@@ -526,6 +527,7 @@ alloc_cadef(char **args, int single, char *match, int flags)
ret->next = ret->snext = NULL;
ret->opts = NULL;
ret->args = ret->rest = NULL;
+ ret->nonarg = ztrdup(nonarg);
if (args) {
ret->defs = zarrdup(args);
ret->ndefs = arrlen(args);
@@ -569,6 +571,7 @@ parse_cadef(char *nam, char **args)
Caopt *optp;
char **oargs = args, *p, *q, *match = "r:|[_-]=* r:|=*", **xor, **sargs;
char *adpre, *adsuf, *axor = NULL, *doset = NULL, **setp = NULL;
+ char *nonarg = NULL;
int single = 0, anum = 1, xnum, nopts, ndopts, nodopts, flags = 0;
int state = 0;
@@ -591,10 +594,10 @@ parse_cadef(char *nam, char **args)
args++;
while ((p = *args) && *p == '-' && p[1]) {
for (q = ++p; *q; q++)
- if (*q == 'M') {
+ if (*q == 'M' || *q == 'A') {
q = "";
break;
- } else if (*q != 's' && *q != 'S' && *q != 'A')
+ } else if (*q != 's' && *q != 'S')
break;
if (*q)
@@ -605,9 +608,15 @@ parse_cadef(char *nam, char **args)
single = 1;
else if (*p == 'S')
flags |= CDF_SEP;
- else if (*p == 'A')
- flags |= CDF_ARG;
- else if (*p == 'M') {
+ else if (*p == 'A') {
+ if (p[1]) {
+ nonarg = p + 1;
+ p = "" - 1;
+ } else if (args[1])
+ nonarg = *++args;
+ else
+ break;
+ } else if (*p == 'M') {
if (p[1]) {
match = p + 1;
p = "" - 1;
@@ -625,9 +634,12 @@ parse_cadef(char *nam, char **args)
if (!*args)
return NULL;
+ if (nonarg)
+ tokenize(nonarg = dupstring(nonarg));
+
/* Looks good. Optimistically allocate the cadef structure. */
- all = ret = alloc_cadef(oargs, single, match, flags);
+ all = ret = alloc_cadef(oargs, single, match, nonarg, flags);
optp = &(ret->opts);
anum = 1;
@@ -662,7 +674,7 @@ parse_cadef(char *nam, char **args)
ret->ndopts = ndopts;
ret->nodopts = nodopts;
set_cadef_opts(ret);
- ret = ret->snext = alloc_cadef(NULL, single, NULL, flags);
+ ret = ret->snext = alloc_cadef(NULL, single, NULL, nonarg, flags);
optp = &(ret->opts);
nopts = ndopts = nodopts = 0;
anum = 1;
@@ -1064,21 +1076,21 @@ ca_get_opt(Cadef d, char *line, int full, char **end)
/* Same as above, only for single-letter-style. */
static Caopt
-ca_get_sopt(Cadef d, char *line, int full, char **end)
+ca_get_sopt(Cadef d, char *line, char **end, LinkList *lp)
{
Caopt p;
char pre = *line++;
-
- if (full) {
- for (p = NULL; *line; line++)
- if (!(p = d->single[STOUC(*line)]) || !p->active ||
- (line[1] && p->args))
- return NULL;
- return p;
- } else {
- for (p = NULL; *line; line++)
- if ((p = d->single[STOUC(*line)]) && p->active &&
- p->args && p->type != CAO_NEXT && p->name[0] == pre) {
+ LinkList l = NULL;
+
+ *lp = NULL;
+ for (p = NULL; *line; line++)
+ if ((p = d->single[STOUC(*line)]) && p->active &&
+ p->args && p->name[0] == pre) {
+ if (p->type == CAO_NEXT) {
+ if (!l)
+ *lp = l = newlinklist();
+ addlinknode(l, p);
+ } else {
if (end) {
line++;
if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
@@ -1087,14 +1099,12 @@ ca_get_sopt(Cadef d, char *line, int full, char **end)
*end = line;
}
break;
- } else if (!p || !p->active || (line[1] && p->args) ||
- p->name[0] != pre)
- return NULL;
- if (p && end)
- *end = line;
- return p;
- }
- return NULL;
+ }
+ } else if (!p || (!p->active && p->name[0] != pre))
+ return NULL;
+ if (p && end)
+ *end = line;
+ return p;
}
/* Return the n'th argument definition. */
@@ -1228,7 +1238,8 @@ ca_parse_line(Cadef d, int multi, int first)
struct castate state;
char *line, *pe, **argxor = NULL;
int cur, doff, argend, arglast;
- Patprog endpat = NULL;
+ Patprog endpat = NULL, napat = NULL;
+ LinkList sopts = NULL;
/* Free old state. */
@@ -1279,6 +1290,9 @@ ca_parse_line(Cadef d, int multi, int first)
goto end;
}
+ if (d->nonarg)
+ napat = patcompile(d->nonarg, 0, NULL);
+
/* Loop over the words from the line. */
for (line = compwords[1], cur = 2, state.curopt = NULL, state.def = NULL;
@@ -1315,6 +1329,15 @@ ca_parse_line(Cadef d, int multi, int first)
} else if ((state.def = state.def->next)) {
state.argbeg = cur;
state.argend = argend;
+ } else if (sopts && nonempty(sopts)) {
+ state.curopt = (Caopt) uremnode(sopts, firstnode(sopts));
+ state.def = state.curopt->args;
+ state.opt = 0;
+ state.argbeg = state.optbeg = state.inopt = cur;
+ state.argend = argend;
+ doff = state.doff = 0;
+ state.singles = 1;
+ goto cont;
} else {
state.curopt = NULL;
state.opt = 1;
@@ -1378,12 +1401,16 @@ ca_parse_line(Cadef d, int multi, int first)
state.curopt = NULL;
}
} else if (state.opt == 2 && d->single &&
- (state.curopt = ca_get_sopt(d, line, 0, &pe))) {
+ ((state.curopt = ca_get_sopt(d, line, &pe, &sopts)) ||
+ (sopts && nonempty(sopts)))) {
/* Or maybe it's a single-letter option? */
char *p;
Caopt tmpopt;
+ if (sopts && nonempty(sopts))
+ state.curopt = (Caopt) uremnode(sopts, firstnode(sopts));
+
ddef = state.def = state.curopt->args;
dopt = state.curopt;
doff = pe - line;
@@ -1419,9 +1446,9 @@ ca_parse_line(Cadef d, int multi, int first)
state.curopt = NULL;
} else if (multi && (*line == '-' || *line == '+') && cur != compcurrent)
return 1;
- else if (state.arg) {
+ else if (state.arg && (!napat || !pattry(napat, line))) {
/* Otherwise it's a normal argument. */
- if ((d->flags & CDF_ARG) && ca_inactive(d, NULL, cur + 1, 1))
+ if (napat && ca_inactive(d, NULL, cur + 1, 1))
return 1;
arglast = 1;
@@ -1438,9 +1465,7 @@ ca_parse_line(Cadef d, int multi, int first)
state.inrest = 0;
state.opt = (cur == state.nargbeg + 1 &&
(!multi || !*line ||
- ((*line == '-' || *line == '+') &&
- (!line[1] ||
- (*line == '-' && line[1] == '-' && !line[2])))));
+ *line == '-' || *line == '+'));
state.optbeg = state.nargbeg;
state.argbeg = cur - 1;
state.argend = argend;
@@ -1517,9 +1542,7 @@ ca_parse_line(Cadef d, int multi, int first)
} else {
ca_laststate.def = adef;
ca_laststate.opt = (!arglast || !multi || !*line ||
- ((*line == '-' || *line == '+') &&
- (!line[1] ||
- (*line == '-' && line[1] == '-' && !line[2]))));
+ *line == '-' || *line == '+');
ca_laststate.ddef = NULL;
ca_laststate.dopt = NULL;
ca_laststate.optbeg = state.nargbeg;