diff options
author | Oliver Kiddle <opk@zsh.org> | 2021-10-22 21:50:52 +0200 |
---|---|---|
committer | Oliver Kiddle <opk@zsh.org> | 2021-12-14 12:30:55 +0100 |
commit | 7cb980b5366afd5b82b3540961ea4a2e68faab8e (patch) | |
tree | c524f615972a113fafc4531a193f392dd3c3637a | |
parent | 91b7baf25929a20ee776100f406021a422d56e98 (diff) | |
download | zsh-7cb980b5366afd5b82b3540961ea4a2e68faab8e.tar.gz zsh-7cb980b5366afd5b82b3540961ea4a2e68faab8e.tar.xz zsh-7cb980b5366afd5b82b3540961ea4a2e68faab8e.zip |
49518: fix exclusions for mixed - and + stacked options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Etc/BUGS | 2 | ||||
-rw-r--r-- | Src/Zle/computil.c | 39 | ||||
-rw-r--r-- | Test/Y03arguments.ztst | 22 |
4 files changed, 56 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog index 2fd7926ab..676a2584c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2021-12-14 Oliver Kiddle <opk@zsh.org> + + * 49518: Src/Zle/computil.c, Etc/BUGS, Test/Y03arguments.ztst: + fix exclusions for mixed - and + stacked options + 2021-12-13 Oliver Kiddle <opk@zsh.org> * 49646: Doc/Zsh/mod_watch.yo, Src/Modules/watch.c, Src/prompt.c: diff --git a/Etc/BUGS b/Etc/BUGS index f1f8e44f8..5624fb24d 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -37,8 +37,6 @@ See test case in Test/C03traps.ztst. ------------------------------------------------------------------------ 44850 terminal issues with continuation markers ------------------------------------------------------------------------ -45422 _arguments !-x !+x ------------------------------------------------------------------------- users/24765 -direct terminals. Not a bug as such but we may need to do something if -direct values in TERM are ever common ------------------------------------------------------------------------ diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index b311d6c5f..c49d688c8 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -1035,7 +1035,7 @@ freecadef(Cadef d) freecaargs(d->rest); zsfree(d->nonarg); if (d->single) - zfree(d->single, 256 * sizeof(Caopt)); + zfree(d->single, 188 * sizeof(Caopt)); zfree(d, sizeof(*d)); d = s; } @@ -1079,6 +1079,21 @@ bslashcolon(char *s) return r; } +/* Get an index into the single array used in struct cadef + * opt is the option letter and pre is either - or + + * we only keep an array for the 94 ASCII characters from ! to ~ so + * with - and + prefixes, the array is double that at 188 elements + * returns -1 if opt is out-of-range + */ +static int +single_index(char pre, char opt) +{ + if (opt <= 20 || opt > 0x7e) + return -1; + + return opt + (pre == '-' ? -21 : 94 - 21); +} + /* Parse an argument definition. */ static Caarg @@ -1151,8 +1166,8 @@ alloc_cadef(char **args, int single, char *match, char *nonarg, int flags) ret->lastt = time(0); ret->set = NULL; if (single) { - ret->single = (Caopt *) zalloc(256 * sizeof(Caopt)); - memset(ret->single, 0, 256 * sizeof(Caopt)); + ret->single = (Caopt *) zalloc(188 * sizeof(Caopt)); + memset(ret->single, 0, 188 * sizeof(Caopt)); } else ret->single = NULL; ret->match = ztrdup(match); @@ -1558,9 +1573,10 @@ parse_cadef(char *nam, char **args) * pointer for the definition in the array for fast lookup. * But don't treat '--' as a single option called '-' */ - - if (single && name[1] && !name[2] && name[1] != '-') - ret->single[STOUC(name[1])] = opt; + if (single && name[1] && !name[2] && name[1] != '-') { + int sidx = single_index(*name, name[1]); + if (sidx >= 0) ret->single[sidx] = opt; + } if (again == 1) { /* Do it all again for `*-...'. */ @@ -1738,11 +1754,12 @@ ca_get_sopt(Cadef d, char *line, char **end, LinkList *lp) Caopt p, pp = NULL; char pre = *line++; LinkList l = NULL; + int sidx; *lp = NULL; for (p = NULL; *line; line++) { - if ((p = d->single[STOUC(*line)]) && p->active && - p->args && p->name[0] == pre) { + if ((sidx = single_index(pre, *line)) != -1 && + (p = d->single[sidx]) && p->active && p->args) { if (p->type == CAO_NEXT) { if (!l) *lp = l = newlinklist(); @@ -1813,7 +1830,7 @@ ca_get_arg(Cadef d, int n) /* Mark options as inactive. * d: option definitions for a set * pass either: - * xor: a list if exclusions + * xor: a list of exclusions * opts: if set, all options excluded leaving only nornal/rest arguments */ static void @@ -2195,6 +2212,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) char *p; Caopt tmpopt; + int sidx; if (cur != compcurrent && sopts && nonempty(sopts)) state.curopt = (Caopt) uremnode(sopts, firstnode(sopts)); @@ -2212,7 +2230,8 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first) state.singles = (!pe || !*pe); for (p = line + 1; p < pe; p++) { - if ((tmpopt = d->single[STOUC(*p)])) { + if ((sidx = single_index(*line, *p)) != -1 && + (tmpopt = d->single[sidx])) { if (!state.oargs[tmpopt->num]) state.oargs[tmpopt->num] = znewlinklist(); diff --git a/Test/Y03arguments.ztst b/Test/Y03arguments.ztst index ef7a0ec56..200c83e8c 100644 --- a/Test/Y03arguments.ztst +++ b/Test/Y03arguments.ztst @@ -102,6 +102,28 @@ >NO:{+o} >NO:{-o} + tst_arguments -s -{a,b,c} \!-{d,e,f} \!+{d,e,f} + comptest $'tst -ad\t\024\t\bef\t' +0:mix of + and - and exclusion of stacked options +>line: {tst -ad}{} +>DESCRIPTION:{option} +>NO:{-b} +>NO:{-c} +>line: {tst -da}{} +>DESCRIPTION:{option} +>NO:{-b} +>NO:{-c} +>line: {tst -def}{} +>DESCRIPTION:{option} +>NO:{-a} +>NO:{-b} +>NO:{-c} + + tst_arguments -s -{a,b,c} +{a,b,c} + comptest $'tst -a +b +c\t' +0:mix of + and - and exclusion of stacked options +>line: {tst -a +b +ca}{} + tst_arguments '-o:1:(a):2:(b)' comptest $'tst \t\t\t' 0:two option arguments |