mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-28 05:00:59 +01:00
35168: Improve parsing of case patterns.
"|" is now found properly by looking for words that come from the lexical analyser, rather than hacking a pattern returned in one dollop. Update some completion functions that need extra quoting as a result. Add test for new parsing. Update version number to 5.0.8-dev-3 because of wordcode incompatibility.
This commit is contained in:
parent
34a1489f43
commit
52aeb9aaeb
14 changed files with 162 additions and 126 deletions
13
ChangeLog
13
ChangeLog
|
|
@ -1,3 +1,16 @@
|
||||||
|
2015-05-18 Peter Stephenson <p.stephenson@samsung.com>
|
||||||
|
|
||||||
|
* 35168: Completion/Unix/Command/_ant,
|
||||||
|
Completion/Unix/Command/_cp, Completion/Unix/Command/_locate,
|
||||||
|
Completion/Unix/Command/_make, Completion/Unix/Command/_tar,
|
||||||
|
Completion/Unix/Type/_path_commands,
|
||||||
|
Completion/X/Command/_xrandr, Config/version.mk, Src/lex.c,
|
||||||
|
Src/loop.c, Src/parse.c, Src/text.c, Test/A01grammar.ztst:
|
||||||
|
Fix parsing of case patterns so "|" is extracted by looking
|
||||||
|
for words; quote completion functions where needed in
|
||||||
|
consequence; add test; updated version number to 5.0.7-dev-3
|
||||||
|
because of wordcode incompatibility.
|
||||||
|
|
||||||
2015-05-18 Daniel Hahler <git@thequod.de>
|
2015-05-18 Daniel Hahler <git@thequod.de>
|
||||||
|
|
||||||
* 35126: Completion/Unix/Command/_git: __git_recent_commits:
|
* 35126: Completion/Unix/Command/_git: __git_recent_commits:
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,7 @@ case $state in
|
||||||
# Output target again indicating its the default one.
|
# Output target again indicating its the default one.
|
||||||
print -n "'${default_target}:(Default target) ' "
|
print -n "'${default_target}:(Default target) ' "
|
||||||
;;
|
;;
|
||||||
(Searching:*|Main:targets:|Subtargets:|BUILD:SUCCESSFUL|Total:time:
|
(Searching:*|Main:targets:|Subtargets:|BUILD:SUCCESSFUL|Total:time:*)
|
||||||
*)
|
|
||||||
;;
|
;;
|
||||||
(*)
|
(*)
|
||||||
# Return target and description
|
# Return target and description
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ if _pick_variant gnu=GNU unix --version; then
|
||||||
'-H[follow command-line symbolic links]' \
|
'-H[follow command-line symbolic links]' \
|
||||||
'(-l --link)'{-l,--link}'[link files instead of copying]' \
|
'(-l --link)'{-l,--link}'[link files instead of copying]' \
|
||||||
'(-L --dereference)'{-L,--dereference}'[always follow symbolic links]' \
|
'(-L --dereference)'{-L,--dereference}'[always follow symbolic links]' \
|
||||||
(-n --no-clobber -i --interactive){-n,--no-clobber}"[don't overwrite an existing file]" \
|
'(-n --no-clobber -i --interactive)'{-n,--no-clobber}"[don't overwrite an existing file]" \
|
||||||
'(-P --no-dereference)'{-P,--no-dereference}'[never follow symbolic links]' \
|
'(-P --no-dereference)'{-P,--no-dereference}'[never follow symbolic links]' \
|
||||||
'-p[same as --preserve=mode,ownership,timestamps]' \
|
'-p[same as --preserve=mode,ownership,timestamps]' \
|
||||||
'--preserve=-[preserve specified attributes]:: :_values -s , attribute mode timestamps ownership links context xattr all' \
|
'--preserve=-[preserve specified attributes]:: :_values -s , attribute mode timestamps ownership links context xattr all' \
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ case $basename in
|
||||||
ltype=gnu
|
ltype=gnu
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(*illegal option*)
|
(*"illegal option"*)
|
||||||
if [[ $OSTYPE == (freebsd|openbsd|dragonfly|darwin)* ]]; then
|
if [[ $OSTYPE == (freebsd|openbsd|dragonfly|darwin)* ]]; then
|
||||||
ltype=bsd
|
ltype=bsd
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ _make-parseMakefile () {
|
||||||
do
|
do
|
||||||
case "$input " in
|
case "$input " in
|
||||||
# VARIABLE = value OR VARIABLE ?= value
|
# VARIABLE = value OR VARIABLE ?= value
|
||||||
([[:alnum:]][[:alnum:]_]#[ $TAB]#(\?|)=*)
|
([[:alnum:]][[:alnum:]_]#[" "$TAB]#(\?|)=*)
|
||||||
var=${input%%[ $TAB]#(\?|)=*}
|
var=${input%%[ $TAB]#(\?|)=*}
|
||||||
val=${input#*=}
|
val=${input#*=}
|
||||||
val=${val##[ $TAB]#}
|
val=${val##[ $TAB]#}
|
||||||
|
|
@ -74,7 +74,7 @@ _make-parseMakefile () {
|
||||||
|
|
||||||
# VARIABLE := value OR VARIABLE ::= value
|
# VARIABLE := value OR VARIABLE ::= value
|
||||||
# Evaluated immediately
|
# Evaluated immediately
|
||||||
([[:alnum:]][[:alnum:]_]#[ $TAB]#:(:|)=*)
|
([[:alnum:]][[:alnum:]_]#[" "$TAB]#:(:|)=*)
|
||||||
var=${input%%[ $TAB]#:(:|)=*}
|
var=${input%%[ $TAB]#:(:|)=*}
|
||||||
val=${input#*=}
|
val=${input#*=}
|
||||||
val=${val##[ $TAB]#}
|
val=${val##[ $TAB]#}
|
||||||
|
|
@ -97,7 +97,7 @@ _make-parseMakefile () {
|
||||||
;;
|
;;
|
||||||
|
|
||||||
# Include another makefile
|
# Include another makefile
|
||||||
(${~incl} *)
|
(${~incl}" "*)
|
||||||
local f=${input##${~incl} ##}
|
local f=${input##${~incl} ##}
|
||||||
if [[ $incl == '.include' ]]
|
if [[ $incl == '.include' ]]
|
||||||
then
|
then
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ local _tar_cmd tf tmp tmpb del index
|
||||||
|
|
||||||
if _pick_variant gnu=GNU unix --version; then
|
if _pick_variant gnu=GNU unix --version; then
|
||||||
case "$($service --version)" in
|
case "$($service --version)" in
|
||||||
(tar \(GNU tar\) (#b)([0-9.-]##)*)
|
("tar (GNU tar) "(#b)([0-9.-]##)*)
|
||||||
autoload -z is-at-least
|
autoload -z is-at-least
|
||||||
is-at-least 1.14.91 "$match[1]" || _cmd_variant[$service]="gnu-old"
|
is-at-least 1.14.91 "$match[1]" || _cmd_variant[$service]="gnu-old"
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ return 1
|
||||||
|
|
||||||
_call_whatis() {
|
_call_whatis() {
|
||||||
case "$(whatis --version)" in
|
case "$(whatis --version)" in
|
||||||
(whatis from *)
|
("whatis from "*)
|
||||||
local -A args
|
local -A args
|
||||||
zparseopts -D -A args s: r:
|
zparseopts -D -A args s: r:
|
||||||
apropos "${args[-r]:-"$@"}" | fgrep "($args[-s]"
|
apropos "${args[-r]:-"$@"}" | fgrep "($args[-s]"
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ _arguments -C \
|
||||||
case $state in
|
case $state in
|
||||||
value)
|
value)
|
||||||
case $words[CURRENT-1] in
|
case $words[CURRENT-1] in
|
||||||
(scaling* mode)
|
(scaling*" mode")
|
||||||
_description value expl "output property 'scaling mode'"
|
_description value expl "output property 'scaling mode'"
|
||||||
compadd "$@" "$expl[@]" None Full Center Full\ aspect && return 0
|
compadd "$@" "$expl[@]" None Full Center Full\ aspect && return 0
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,5 @@
|
||||||
# This must also serve as a shell script, so do not add spaces around the
|
# This must also serve as a shell script, so do not add spaces around the
|
||||||
# `=' signs.
|
# `=' signs.
|
||||||
|
|
||||||
VERSION=5.0.7-dev-2
|
VERSION=5.0.7-dev-3
|
||||||
VERSION_DATE='May 5, 2015'
|
VERSION_DATE='May 17, 2015'
|
||||||
|
|
|
||||||
|
|
@ -761,6 +761,8 @@ gettok(void)
|
||||||
lexstop = 0;
|
lexstop = 0;
|
||||||
return BAR;
|
return BAR;
|
||||||
case LX1_INPAR:
|
case LX1_INPAR:
|
||||||
|
if (incasepat == 2)
|
||||||
|
return INPAR;
|
||||||
d = hgetc();
|
d = hgetc();
|
||||||
if (d == '(') {
|
if (d == '(') {
|
||||||
if (infor) {
|
if (infor) {
|
||||||
|
|
|
||||||
96
Src/loop.c
96
Src/loop.c
|
|
@ -545,7 +545,7 @@ execcase(Estate state, int do_exec)
|
||||||
Wordcode end, next;
|
Wordcode end, next;
|
||||||
wordcode code = state->pc[-1];
|
wordcode code = state->pc[-1];
|
||||||
char *word, *pat;
|
char *word, *pat;
|
||||||
int npat, save;
|
int npat, save, nalts, ialt, patok;
|
||||||
Patprog *spprog, pprog;
|
Patprog *spprog, pprog;
|
||||||
|
|
||||||
end = state->pc + WC_CASE_SKIP(code);
|
end = state->pc + WC_CASE_SKIP(code);
|
||||||
|
|
@ -561,60 +561,74 @@ execcase(Estate state, int do_exec)
|
||||||
if (wc_code(code) != WC_CASE)
|
if (wc_code(code) != WC_CASE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pat = NULL;
|
|
||||||
pprog = NULL;
|
|
||||||
save = 0;
|
save = 0;
|
||||||
npat = state->pc[1];
|
|
||||||
spprog = state->prog->pats + npat;
|
|
||||||
|
|
||||||
next = state->pc + WC_CASE_SKIP(code);
|
next = state->pc + WC_CASE_SKIP(code);
|
||||||
|
nalts = *state->pc++;
|
||||||
|
ialt = patok = 0;
|
||||||
|
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
char *opat;
|
|
||||||
|
|
||||||
pat = dupstring(opat = ecrawstr(state->prog, state->pc, NULL));
|
|
||||||
singsub(&pat);
|
|
||||||
save = (!(state->prog->flags & EF_HEAP) &&
|
|
||||||
!strcmp(pat, opat) && *spprog != dummy_patprog2);
|
|
||||||
|
|
||||||
printprompt4();
|
printprompt4();
|
||||||
fprintf(xtrerr, "case %s (", word);
|
fprintf(xtrerr, "case %s (", word);
|
||||||
quote_tokenized_output(pat, xtrerr);
|
}
|
||||||
|
|
||||||
|
while (!patok && nalts) {
|
||||||
|
npat = state->pc[1];
|
||||||
|
spprog = state->prog->pats + npat;
|
||||||
|
pprog = NULL;
|
||||||
|
pat = NULL;
|
||||||
|
|
||||||
|
if (isset(XTRACE)) {
|
||||||
|
int htok = 0;
|
||||||
|
pat = dupstring(ecrawstr(state->prog, state->pc, &htok));
|
||||||
|
if (htok)
|
||||||
|
singsub(&pat);
|
||||||
|
|
||||||
|
if (ialt++)
|
||||||
|
fprintf(stderr, " | ");
|
||||||
|
quote_tokenized_output(pat, xtrerr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*spprog != dummy_patprog1 && *spprog != dummy_patprog2)
|
||||||
|
pprog = *spprog;
|
||||||
|
|
||||||
|
if (!pprog) {
|
||||||
|
if (!pat) {
|
||||||
|
char *opat;
|
||||||
|
int htok = 0;
|
||||||
|
|
||||||
|
pat = dupstring(opat = ecrawstr(state->prog,
|
||||||
|
state->pc, &htok));
|
||||||
|
if (htok)
|
||||||
|
singsub(&pat);
|
||||||
|
save = (!(state->prog->flags & EF_HEAP) &&
|
||||||
|
!strcmp(pat, opat) && *spprog != dummy_patprog2);
|
||||||
|
}
|
||||||
|
if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
|
||||||
|
NULL)))
|
||||||
|
zerr("bad pattern: %s", pat);
|
||||||
|
else if (save)
|
||||||
|
*spprog = pprog;
|
||||||
|
}
|
||||||
|
if (pprog && pattry(pprog, word))
|
||||||
|
patok = 1;
|
||||||
|
state->pc += 2;
|
||||||
|
nalts--;
|
||||||
|
}
|
||||||
|
state->pc += 2 * nalts;
|
||||||
|
if (isset(XTRACE)) {
|
||||||
fprintf(xtrerr, ")\n");
|
fprintf(xtrerr, ")\n");
|
||||||
fflush(xtrerr);
|
fflush(xtrerr);
|
||||||
}
|
}
|
||||||
state->pc += 2;
|
if (patok) {
|
||||||
|
|
||||||
if (*spprog != dummy_patprog1 && *spprog != dummy_patprog2)
|
|
||||||
pprog = *spprog;
|
|
||||||
|
|
||||||
if (!pprog) {
|
|
||||||
if (!pat) {
|
|
||||||
char *opat;
|
|
||||||
int htok = 0;
|
|
||||||
|
|
||||||
pat = dupstring(opat = ecrawstr(state->prog,
|
|
||||||
state->pc - 2, &htok));
|
|
||||||
if (htok)
|
|
||||||
singsub(&pat);
|
|
||||||
save = (!(state->prog->flags & EF_HEAP) &&
|
|
||||||
!strcmp(pat, opat) && *spprog != dummy_patprog2);
|
|
||||||
}
|
|
||||||
if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
|
|
||||||
NULL)))
|
|
||||||
zerr("bad pattern: %s", pat);
|
|
||||||
else if (save)
|
|
||||||
*spprog = pprog;
|
|
||||||
}
|
|
||||||
if (pprog && pattry(pprog, word)) {
|
|
||||||
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
|
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
|
||||||
do_exec));
|
do_exec));
|
||||||
while (!retflag && wc_code(code) == WC_CASE &&
|
while (!retflag && wc_code(code) == WC_CASE &&
|
||||||
WC_CASE_TYPE(code) == WC_CASE_AND) {
|
WC_CASE_TYPE(code) == WC_CASE_AND) {
|
||||||
state->pc = next;
|
state->pc = next;
|
||||||
code = *state->pc;
|
code = *state->pc++;
|
||||||
state->pc += 3;
|
next = state->pc + WC_CASE_SKIP(code);
|
||||||
next = state->pc + WC_CASE_SKIP(code) - 2;
|
nalts = *state->pc++;
|
||||||
|
state->pc += 2 * nalts;
|
||||||
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
|
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
|
||||||
do_exec));
|
do_exec));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
87
Src/parse.c
87
Src/parse.c
|
|
@ -349,9 +349,8 @@ ecadd(wordcode c)
|
||||||
eclen += a;
|
eclen += a;
|
||||||
}
|
}
|
||||||
ecbuf[ecused] = c;
|
ecbuf[ecused] = c;
|
||||||
ecused++;
|
|
||||||
|
|
||||||
return ecused - 1;
|
return ecused++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete a wordcode. */
|
/* Delete a wordcode. */
|
||||||
|
|
@ -1128,7 +1127,7 @@ par_for(int *cmplx)
|
||||||
static void
|
static void
|
||||||
par_case(int *cmplx)
|
par_case(int *cmplx)
|
||||||
{
|
{
|
||||||
int oecused = ecused, brflag, p, pp, n = 1, type;
|
int oecused = ecused, brflag, p, pp, palts, type, nalts;
|
||||||
int ona, onc;
|
int ona, onc;
|
||||||
|
|
||||||
p = ecadd(0);
|
p = ecadd(0);
|
||||||
|
|
@ -1153,7 +1152,7 @@ par_case(int *cmplx)
|
||||||
YYERRORV(oecused);
|
YYERRORV(oecused);
|
||||||
}
|
}
|
||||||
brflag = (tok == INBRACE);
|
brflag = (tok == INBRACE);
|
||||||
incasepat = 1;
|
incasepat = 2;
|
||||||
incmdpos = 0;
|
incmdpos = 0;
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
nocorrect = onc;
|
nocorrect = onc;
|
||||||
|
|
@ -1166,8 +1165,10 @@ par_case(int *cmplx)
|
||||||
zshlex();
|
zshlex();
|
||||||
if (tok == OUTBRACE)
|
if (tok == OUTBRACE)
|
||||||
break;
|
break;
|
||||||
if (tok == INPAR)
|
if (tok == INPAR) {
|
||||||
|
incasepat = 1;
|
||||||
zshlex();
|
zshlex();
|
||||||
|
}
|
||||||
if (tok != STRING)
|
if (tok != STRING)
|
||||||
YYERRORV(oecused);
|
YYERRORV(oecused);
|
||||||
if (!strcmp(tokstr, "esac"))
|
if (!strcmp(tokstr, "esac"))
|
||||||
|
|
@ -1176,89 +1177,45 @@ par_case(int *cmplx)
|
||||||
incasepat = 0;
|
incasepat = 0;
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
type = WC_CASE_OR;
|
type = WC_CASE_OR;
|
||||||
|
pp = ecadd(0);
|
||||||
|
palts = ecadd(0);
|
||||||
|
nalts = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
ecstr(str);
|
||||||
|
ecadd(ecnpats++);
|
||||||
|
nalts++;
|
||||||
|
|
||||||
zshlex();
|
zshlex();
|
||||||
if (tok == OUTPAR) {
|
if (tok == OUTPAR) {
|
||||||
incasepat = 0;
|
incasepat = 0;
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
zshlex();
|
zshlex();
|
||||||
break;
|
break;
|
||||||
} else if (tok == BAR) {
|
} else if (tok != BAR)
|
||||||
char *str2;
|
YYERRORV(oecused);
|
||||||
int sl = strlen(str);
|
|
||||||
|
|
||||||
incasepat = 1;
|
zshlex();
|
||||||
incmdpos = 0;
|
if (tok != STRING)
|
||||||
str2 = hcalloc(sl + 2);
|
YYERRORV(oecused);
|
||||||
strcpy(str2, str);
|
str = dupstring(tokstr);
|
||||||
str2[sl] = Bar;
|
|
||||||
str2[sl+1] = '\0';
|
|
||||||
str = str2;
|
|
||||||
} else {
|
|
||||||
int sl = strlen(str);
|
|
||||||
|
|
||||||
if (!sl || str[sl - 1] != Bar) {
|
|
||||||
/* POSIX allows (foo*) patterns */
|
|
||||||
int pct;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
for (s = str, pct = 0; *s; s++) {
|
|
||||||
if (*s == Inpar)
|
|
||||||
pct++;
|
|
||||||
if (!pct)
|
|
||||||
break;
|
|
||||||
if (pct == 1) {
|
|
||||||
if (*s == Bar || *s == Inpar)
|
|
||||||
while (iblank(s[1]))
|
|
||||||
chuck(s+1);
|
|
||||||
if (*s == Bar || *s == Outpar)
|
|
||||||
while (iblank(s[-1]) &&
|
|
||||||
(s < str + 1 || s[-2] != Meta))
|
|
||||||
chuck(--s);
|
|
||||||
}
|
|
||||||
if (*s == Outpar)
|
|
||||||
pct--;
|
|
||||||
}
|
|
||||||
if (*s || pct || s == str)
|
|
||||||
YYERRORV(oecused);
|
|
||||||
/* Simplify pattern by removing surrounding (...) */
|
|
||||||
sl = strlen(str);
|
|
||||||
DPUTS(*str != Inpar || str[sl - 1] != Outpar,
|
|
||||||
"BUG: strange case pattern");
|
|
||||||
str[sl - 1] = '\0';
|
|
||||||
chuck(str);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
char *str2;
|
|
||||||
|
|
||||||
if (tok != STRING)
|
|
||||||
YYERRORV(oecused);
|
|
||||||
str2 = hcalloc(sl + strlen(tokstr) + 1);
|
|
||||||
strcpy(str2, str);
|
|
||||||
strcpy(str2 + sl, tokstr);
|
|
||||||
str = str2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pp = ecadd(0);
|
|
||||||
ecstr(str);
|
|
||||||
ecadd(ecnpats++);
|
|
||||||
par_save_list(cmplx);
|
par_save_list(cmplx);
|
||||||
n++;
|
|
||||||
if (tok == SEMIAMP)
|
if (tok == SEMIAMP)
|
||||||
type = WC_CASE_AND;
|
type = WC_CASE_AND;
|
||||||
else if (tok == SEMIBAR)
|
else if (tok == SEMIBAR)
|
||||||
type = WC_CASE_TESTAND;
|
type = WC_CASE_TESTAND;
|
||||||
ecbuf[pp] = WCB_CASE(type, ecused - 1 - pp);
|
ecbuf[pp] = WCB_CASE(type, ecused - 1 - pp);
|
||||||
|
ecbuf[palts] = nalts;
|
||||||
if ((tok == ESAC && !brflag) || (tok == OUTBRACE && brflag))
|
if ((tok == ESAC && !brflag) || (tok == OUTBRACE && brflag))
|
||||||
break;
|
break;
|
||||||
if (tok != DSEMI && tok != SEMIAMP && tok != SEMIBAR)
|
if (tok != DSEMI && tok != SEMIAMP && tok != SEMIBAR)
|
||||||
YYERRORV(oecused);
|
YYERRORV(oecused);
|
||||||
incasepat = 1;
|
incasepat = 2;
|
||||||
incmdpos = 0;
|
incmdpos = 0;
|
||||||
zshlex();
|
zshlex();
|
||||||
}
|
}
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
|
incasepat = 0;
|
||||||
zshlex();
|
zshlex();
|
||||||
|
|
||||||
ecbuf[p] = WCB_CASE(WC_CASE_HEAD, ecused - 1 - p);
|
ecbuf[p] = WCB_CASE(WC_CASE_HEAD, ecused - 1 - p);
|
||||||
|
|
|
||||||
28
Src/text.c
28
Src/text.c
|
|
@ -602,6 +602,7 @@ gettext2(Estate state)
|
||||||
case WC_CASE:
|
case WC_CASE:
|
||||||
if (!s) {
|
if (!s) {
|
||||||
Wordcode end = state->pc + WC_CASE_SKIP(code);
|
Wordcode end = state->pc + WC_CASE_SKIP(code);
|
||||||
|
wordcode nalts;
|
||||||
|
|
||||||
taddstr("case ");
|
taddstr("case ");
|
||||||
taddstr(ecgetstr(state, EC_NODUP, NULL));
|
taddstr(ecgetstr(state, EC_NODUP, NULL));
|
||||||
|
|
@ -622,8 +623,13 @@ gettext2(Estate state)
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
taddstr("(");
|
taddstr("(");
|
||||||
code = *state->pc++;
|
code = *state->pc++;
|
||||||
taddstr(ecgetstr(state, EC_NODUP, NULL));
|
nalts = *state->pc++;
|
||||||
state->pc++;
|
while (nalts--) {
|
||||||
|
taddstr(ecgetstr(state, EC_NODUP, NULL));
|
||||||
|
state->pc++;
|
||||||
|
if (nalts)
|
||||||
|
taddstr(" | ");
|
||||||
|
}
|
||||||
taddstr(") ");
|
taddstr(") ");
|
||||||
tindent++;
|
tindent++;
|
||||||
n = tpush(code, 0);
|
n = tpush(code, 0);
|
||||||
|
|
@ -631,6 +637,7 @@ gettext2(Estate state)
|
||||||
n->pop = (state->pc - 2 + WC_CASE_SKIP(code) >= end);
|
n->pop = (state->pc - 2 + WC_CASE_SKIP(code) >= end);
|
||||||
}
|
}
|
||||||
} else if (state->pc < s->u._case.end) {
|
} else if (state->pc < s->u._case.end) {
|
||||||
|
wordcode nalts;
|
||||||
dec_tindent();
|
dec_tindent();
|
||||||
switch (WC_CASE_TYPE(code)) {
|
switch (WC_CASE_TYPE(code)) {
|
||||||
case WC_CASE_OR:
|
case WC_CASE_OR:
|
||||||
|
|
@ -638,11 +645,11 @@ gettext2(Estate state)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WC_CASE_AND:
|
case WC_CASE_AND:
|
||||||
taddstr(";&");
|
taddstr(" ;&");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
taddstr(";|");
|
taddstr(" ;|");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tnewlins)
|
if (tnewlins)
|
||||||
|
|
@ -651,8 +658,13 @@ gettext2(Estate state)
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
taddstr("(");
|
taddstr("(");
|
||||||
code = *state->pc++;
|
code = *state->pc++;
|
||||||
taddstr(ecgetstr(state, EC_NODUP, NULL));
|
nalts = *state->pc++;
|
||||||
state->pc++;
|
while (nalts--) {
|
||||||
|
taddstr(ecgetstr(state, EC_NODUP, NULL));
|
||||||
|
state->pc++;
|
||||||
|
if (nalts)
|
||||||
|
taddstr(" | ");
|
||||||
|
}
|
||||||
taddstr(") ");
|
taddstr(") ");
|
||||||
tindent++;
|
tindent++;
|
||||||
s->code = code;
|
s->code = code;
|
||||||
|
|
@ -666,11 +678,11 @@ gettext2(Estate state)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WC_CASE_AND:
|
case WC_CASE_AND:
|
||||||
taddstr(";&");
|
taddstr(" ;&");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
taddstr(";|");
|
taddstr(" ;|");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dec_tindent();
|
dec_tindent();
|
||||||
|
|
|
||||||
|
|
@ -572,6 +572,7 @@
|
||||||
$ZTST_testdir/../Src/zsh -f myscript
|
$ZTST_testdir/../Src/zsh -f myscript
|
||||||
127q:PATHSCRIPT option not used.
|
127q:PATHSCRIPT option not used.
|
||||||
?$ZTST_testdir/../Src/zsh: can't open input file: myscript
|
?$ZTST_testdir/../Src/zsh: can't open input file: myscript
|
||||||
|
# '
|
||||||
|
|
||||||
$ZTST_testdir/../Src/zsh -fc 'echo $0; echo $1' myargzero myargone
|
$ZTST_testdir/../Src/zsh -fc 'echo $0; echo $1' myargzero myargone
|
||||||
0:$0 is traditionally if bizarrely set to the first argument with -c
|
0:$0 is traditionally if bizarrely set to the first argument with -c
|
||||||
|
|
@ -611,3 +612,41 @@
|
||||||
>BEGIN
|
>BEGIN
|
||||||
>mytrue
|
>mytrue
|
||||||
>END
|
>END
|
||||||
|
|
||||||
|
fn() {
|
||||||
|
case $1 in
|
||||||
|
( one | two | three )
|
||||||
|
print Matched $1
|
||||||
|
;;
|
||||||
|
( fo* | fi* | si* )
|
||||||
|
print Pattern matched $1
|
||||||
|
;;
|
||||||
|
( []x | a[b]* )
|
||||||
|
print Character class matched $1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
which fn
|
||||||
|
fn one
|
||||||
|
fn two
|
||||||
|
fn three
|
||||||
|
fn four
|
||||||
|
fn five
|
||||||
|
fn six
|
||||||
|
fn abecedinarian
|
||||||
|
fn xylophone
|
||||||
|
0: case word handling
|
||||||
|
>fn () {
|
||||||
|
> case $1 in
|
||||||
|
> (one | two | three) print Matched $1 ;;
|
||||||
|
> (fo* | fi* | si*) print Pattern matched $1 ;;
|
||||||
|
> ([]x | a[b]*) print Character class matched $1 ;;
|
||||||
|
> esac
|
||||||
|
>}
|
||||||
|
>Matched one
|
||||||
|
>Matched two
|
||||||
|
>Matched three
|
||||||
|
>Pattern matched four
|
||||||
|
>Pattern matched five
|
||||||
|
>Pattern matched six
|
||||||
|
>Character class matched abecedinarian
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue