From cfd34c75ac10e05a9573f6b26d3cb2d08b269f6a Mon Sep 17 00:00:00 2001
From: Peter Stephenson
Date: Wed, 9 Aug 2017 19:57:47 +0100
Subject: 41504: make empty strings work in case patterns with no leading
parenthesis
---
Src/lex.c | 6 +++---
Src/parse.c | 48 ++++++++++++++++++++++++++++++++++++++----------
2 files changed, 41 insertions(+), 13 deletions(-)
(limited to 'Src')
diff --git a/Src/lex.c b/Src/lex.c
index b2d9b3f42..8493d4737 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -760,7 +760,7 @@ gettok(void)
return AMPER;
case LX1_BAR:
d = hgetc();
- if (d == '|')
+ if (d == '|' && !incasepat)
return DBAR;
else if (d == '&')
return BARAMP;
@@ -1058,7 +1058,7 @@ gettokstr(int c, int sub)
if (isset(SHGLOB)) {
if (sub || in_brace_param)
break;
- if (incasepat && !lexbuf.len)
+ if (incasepat > 0 && !lexbuf.len)
return INPAR;
if (!isset(KSHGLOB) && lexbuf.len)
goto brk;
@@ -1859,7 +1859,7 @@ exalias(void)
Reswd rw;
hwend();
- if (interact && isset(SHINSTDIN) && !strin && !incasepat &&
+ if (interact && isset(SHINSTDIN) && !strin && incasepat <= 0 &&
tok == STRING && !nocorrect && !(inbufflags & INP_ALIAS) &&
(isset(CORRECTALL) || (isset(CORRECT) && incmdpos)))
spckword(&tokstr, 1, incmdpos, 1);
diff --git a/Src/parse.c b/Src/parse.c
index ba9cd61eb..27052527d 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -48,7 +48,11 @@ mod_export int incond;
/**/
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;
@@ -1194,6 +1198,7 @@ par_case(int *cmplx)
for (;;) {
char *str;
+ int skip_zshlex;
while (tok == SEPER)
zshlex();
@@ -1201,11 +1206,17 @@ par_case(int *cmplx)
break;
if (tok == INPAR)
zshlex();
- if (tok != STRING)
- YYERRORV(oecused);
- if (!strcmp(tokstr, "esac"))
- break;
- str = dupstring(tokstr);
+ if (tok == BAR) {
+ str = dupstring("");
+ skip_zshlex = 1;
+ } else {
+ if (tok != STRING)
+ YYERRORV(oecused);
+ if (!strcmp(tokstr, "esac"))
+ break;
+ str = dupstring(tokstr);
+ skip_zshlex = 0;
+ }
type = WC_CASE_OR;
pp = ecadd(0);
palts = ecadd(0);
@@ -1243,10 +1254,11 @@ par_case(int *cmplx)
* this doesn't affect our ability to match a | or ) as
* these are valid on command lines.
*/
- incasepat = 0;
+ incasepat = -1;
incmdpos = 1;
- for (;;) {
+ if (!skip_zshlex)
zshlex();
+ for (;;) {
if (tok == OUTPAR) {
ecstr(str);
ecadd(ecnpats++);
@@ -1302,10 +1314,26 @@ par_case(int *cmplx)
}
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);
- str = dupstring(tokstr);
+ break;
+ }
}
+ incasepat = 0;
par_save_list(cmplx);
if (tok == SEMIAMP)
type = WC_CASE_AND;
--
cgit 1.4.1