mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-06 09:01:13 +02:00
41504: make empty strings work in case patterns with no leading parenthesis
This commit is contained in:
parent
23af20d0b9
commit
cfd34c75ac
4 changed files with 84 additions and 13 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2017-08-09 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
|
* 41504: Src/lex.c, Src/parse.c, Test/A01grammar.ztst: make
|
||||||
|
empty strings work in case patterns with no opening
|
||||||
|
parenthesis.
|
||||||
|
|
||||||
2017-08-08 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
2017-08-08 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
* unposted: Config/version.mk: update to 5.4.1-dev-0.
|
* unposted: Config/version.mk: update to 5.4.1-dev-0.
|
||||||
|
|
|
@ -760,7 +760,7 @@ gettok(void)
|
||||||
return AMPER;
|
return AMPER;
|
||||||
case LX1_BAR:
|
case LX1_BAR:
|
||||||
d = hgetc();
|
d = hgetc();
|
||||||
if (d == '|')
|
if (d == '|' && !incasepat)
|
||||||
return DBAR;
|
return DBAR;
|
||||||
else if (d == '&')
|
else if (d == '&')
|
||||||
return BARAMP;
|
return BARAMP;
|
||||||
|
@ -1058,7 +1058,7 @@ gettokstr(int c, int sub)
|
||||||
if (isset(SHGLOB)) {
|
if (isset(SHGLOB)) {
|
||||||
if (sub || in_brace_param)
|
if (sub || in_brace_param)
|
||||||
break;
|
break;
|
||||||
if (incasepat && !lexbuf.len)
|
if (incasepat > 0 && !lexbuf.len)
|
||||||
return INPAR;
|
return INPAR;
|
||||||
if (!isset(KSHGLOB) && lexbuf.len)
|
if (!isset(KSHGLOB) && lexbuf.len)
|
||||||
goto brk;
|
goto brk;
|
||||||
|
@ -1859,7 +1859,7 @@ exalias(void)
|
||||||
Reswd rw;
|
Reswd rw;
|
||||||
|
|
||||||
hwend();
|
hwend();
|
||||||
if (interact && isset(SHINSTDIN) && !strin && !incasepat &&
|
if (interact && isset(SHINSTDIN) && !strin && incasepat <= 0 &&
|
||||||
tok == STRING && !nocorrect && !(inbufflags & INP_ALIAS) &&
|
tok == STRING && !nocorrect && !(inbufflags & INP_ALIAS) &&
|
||||||
(isset(CORRECTALL) || (isset(CORRECT) && incmdpos)))
|
(isset(CORRECTALL) || (isset(CORRECT) && incmdpos)))
|
||||||
spckword(&tokstr, 1, incmdpos, 1);
|
spckword(&tokstr, 1, incmdpos, 1);
|
||||||
|
|
48
Src/parse.c
48
Src/parse.c
|
@ -48,7 +48,11 @@ mod_export int incond;
|
||||||
/**/
|
/**/
|
||||||
mod_export int inredir;
|
mod_export int inredir;
|
||||||
|
|
||||||
/* != 0 if we are about to read a case pattern */
|
/*
|
||||||
|
* 1 if we are about to read a case pattern
|
||||||
|
* -1 if we are not quite sure
|
||||||
|
* 0 otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int incasepat;
|
int incasepat;
|
||||||
|
@ -1194,6 +1198,7 @@ par_case(int *cmplx)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char *str;
|
char *str;
|
||||||
|
int skip_zshlex;
|
||||||
|
|
||||||
while (tok == SEPER)
|
while (tok == SEPER)
|
||||||
zshlex();
|
zshlex();
|
||||||
|
@ -1201,11 +1206,17 @@ par_case(int *cmplx)
|
||||||
break;
|
break;
|
||||||
if (tok == INPAR)
|
if (tok == INPAR)
|
||||||
zshlex();
|
zshlex();
|
||||||
if (tok != STRING)
|
if (tok == BAR) {
|
||||||
YYERRORV(oecused);
|
str = dupstring("");
|
||||||
if (!strcmp(tokstr, "esac"))
|
skip_zshlex = 1;
|
||||||
break;
|
} else {
|
||||||
str = dupstring(tokstr);
|
if (tok != STRING)
|
||||||
|
YYERRORV(oecused);
|
||||||
|
if (!strcmp(tokstr, "esac"))
|
||||||
|
break;
|
||||||
|
str = dupstring(tokstr);
|
||||||
|
skip_zshlex = 0;
|
||||||
|
}
|
||||||
type = WC_CASE_OR;
|
type = WC_CASE_OR;
|
||||||
pp = ecadd(0);
|
pp = ecadd(0);
|
||||||
palts = ecadd(0);
|
palts = ecadd(0);
|
||||||
|
@ -1243,10 +1254,11 @@ par_case(int *cmplx)
|
||||||
* this doesn't affect our ability to match a | or ) as
|
* this doesn't affect our ability to match a | or ) as
|
||||||
* these are valid on command lines.
|
* these are valid on command lines.
|
||||||
*/
|
*/
|
||||||
incasepat = 0;
|
incasepat = -1;
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
for (;;) {
|
if (!skip_zshlex)
|
||||||
zshlex();
|
zshlex();
|
||||||
|
for (;;) {
|
||||||
if (tok == OUTPAR) {
|
if (tok == OUTPAR) {
|
||||||
ecstr(str);
|
ecstr(str);
|
||||||
ecadd(ecnpats++);
|
ecadd(ecnpats++);
|
||||||
|
@ -1302,10 +1314,26 @@ par_case(int *cmplx)
|
||||||
}
|
}
|
||||||
|
|
||||||
zshlex();
|
zshlex();
|
||||||
if (tok != STRING)
|
switch (tok) {
|
||||||
|
case STRING:
|
||||||
|
/* Normal case */
|
||||||
|
str = dupstring(tokstr);
|
||||||
|
zshlex();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OUTPAR:
|
||||||
|
case BAR:
|
||||||
|
/* Empty string */
|
||||||
|
str = dupstring("");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Oops. */
|
||||||
YYERRORV(oecused);
|
YYERRORV(oecused);
|
||||||
str = dupstring(tokstr);
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
incasepat = 0;
|
||||||
par_save_list(cmplx);
|
par_save_list(cmplx);
|
||||||
if (tok == SEMIAMP)
|
if (tok == SEMIAMP)
|
||||||
type = WC_CASE_AND;
|
type = WC_CASE_AND;
|
||||||
|
|
|
@ -820,6 +820,43 @@
|
||||||
0:case keeps exit status of last command executed in compound-list
|
0:case keeps exit status of last command executed in compound-list
|
||||||
>37
|
>37
|
||||||
|
|
||||||
|
case '' in
|
||||||
|
burble) print No.
|
||||||
|
;;
|
||||||
|
spurble|) print Yes!
|
||||||
|
;;
|
||||||
|
|burble) print Not quite.
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case '' in
|
||||||
|
burble) print No.
|
||||||
|
;;
|
||||||
|
|burble) print Wow!
|
||||||
|
;;
|
||||||
|
spurble|) print Sorry.
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case '' in
|
||||||
|
gurgle) print No.
|
||||||
|
;;
|
||||||
|
wurgle||jurgle) print Yikes!
|
||||||
|
;;
|
||||||
|
durgle|) print Hmm.
|
||||||
|
;;
|
||||||
|
|zurgle) print Hah.
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case '' in
|
||||||
|
# Useless doubled empty string to check special case.
|
||||||
|
||jurgle) print Ok.
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
0: case with no opening parentheses and empty string
|
||||||
|
>Yes!
|
||||||
|
>Wow!
|
||||||
|
>Yikes!
|
||||||
|
>Ok.
|
||||||
|
|
||||||
x=1
|
x=1
|
||||||
x=2 | echo $x
|
x=2 | echo $x
|
||||||
echo $x
|
echo $x
|
||||||
|
|
Loading…
Reference in a new issue