mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-23 04:30:24 +02:00
23115: ";|" at end of case clause causes later patterns to be tested
This commit is contained in:
parent
a5729be835
commit
de272e0309
8 changed files with 101 additions and 29 deletions
|
@ -155,6 +155,7 @@ mod_export char *tokstrings[WHILE + 1] = {
|
|||
"))", /* DOUTPAR */
|
||||
"&|", /* AMPERBANG 30 */
|
||||
";&", /* SEMIAMP */
|
||||
";|", /* SEMIBAR */
|
||||
};
|
||||
|
||||
/* lexical state */
|
||||
|
@ -381,6 +382,7 @@ ctxtlex(void)
|
|||
case SEMI:
|
||||
case DSEMI:
|
||||
case SEMIAMP:
|
||||
case SEMIBAR:
|
||||
case AMPER:
|
||||
case AMPERBANG:
|
||||
case INPAR:
|
||||
|
@ -713,6 +715,8 @@ gettok(void)
|
|||
return DSEMI;
|
||||
else if(d == '&')
|
||||
return SEMIAMP;
|
||||
else if (d == '|')
|
||||
return SEMIBAR;
|
||||
hungetc(d);
|
||||
lexstop = 0;
|
||||
return SEMI;
|
||||
|
|
|
@ -606,9 +606,10 @@ execcase(Estate state, int do_exec)
|
|||
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
|
||||
do_exec));
|
||||
}
|
||||
break;
|
||||
} else
|
||||
state->pc = next;
|
||||
if (WC_CASE_TYPE(code) != WC_CASE_TESTAND)
|
||||
break;
|
||||
}
|
||||
state->pc = next;
|
||||
}
|
||||
cmdpop();
|
||||
|
||||
|
|
12
Src/parse.c
12
Src/parse.c
|
@ -169,9 +169,9 @@ struct heredocs *hdocs;
|
|||
*
|
||||
* WC_CASE
|
||||
* - first CASE is always of type HEAD, data contains offset to esac
|
||||
* - after that CASEs of type OR (;;) and AND (;&), data is offset to
|
||||
* next case
|
||||
* - each OR/AND case is followed by pattern, pattern-number, list
|
||||
* - after that CASEs of type OR (;;), AND (;&) and TESTAND (;|),
|
||||
* data is offset to next case
|
||||
* - each OR/AND/TESTAND case is followed by pattern, pattern-number, list
|
||||
*
|
||||
* WC_IF
|
||||
* - first IF is of type HEAD, data contains offset to fi
|
||||
|
@ -1014,7 +1014,7 @@ par_for(int *complex)
|
|||
/*
|
||||
* case : CASE STRING { SEPER } ( "in" | INBRACE )
|
||||
{ { SEPER } STRING { BAR STRING } OUTPAR
|
||||
list [ DSEMI | SEMIAMP ] }
|
||||
list [ DSEMI | SEMIAMP | SEMIBAR ] }
|
||||
{ SEPER } ( "esac" | OUTBRACE )
|
||||
*/
|
||||
|
||||
|
@ -1141,10 +1141,12 @@ par_case(int *complex)
|
|||
n++;
|
||||
if (tok == SEMIAMP)
|
||||
type = WC_CASE_AND;
|
||||
else if (tok == SEMIBAR)
|
||||
type = WC_CASE_TESTAND;
|
||||
ecbuf[pp] = WCB_CASE(type, ecused - 1 - pp);
|
||||
if ((tok == ESAC && !brflag) || (tok == OUTBRACE && brflag))
|
||||
break;
|
||||
if (tok != DSEMI && tok != SEMIAMP)
|
||||
if (tok != DSEMI && tok != SEMIAMP && tok != SEMIBAR)
|
||||
YYERRORV(oecused);
|
||||
incasepat = 1;
|
||||
incmdpos = 0;
|
||||
|
|
28
Src/text.c
28
Src/text.c
|
@ -537,7 +537,19 @@ gettext2(Estate state)
|
|||
}
|
||||
} else if (state->pc < s->u._case.end) {
|
||||
tindent--;
|
||||
taddstr(WC_CASE_TYPE(code) == WC_CASE_OR ? " ;;" : ";&");
|
||||
switch (WC_CASE_TYPE(code)) {
|
||||
case WC_CASE_OR:
|
||||
taddstr(" ;;");
|
||||
break;
|
||||
|
||||
case WC_CASE_AND:
|
||||
taddstr(";&");
|
||||
break;
|
||||
|
||||
default:
|
||||
taddstr(";|");
|
||||
break;
|
||||
}
|
||||
if (tnewlins)
|
||||
taddnl();
|
||||
else
|
||||
|
@ -553,7 +565,19 @@ gettext2(Estate state)
|
|||
s->u._case.end);
|
||||
} else {
|
||||
tindent--;
|
||||
taddstr(WC_CASE_TYPE(code) == WC_CASE_OR ? " ;;" : ";&");
|
||||
switch (WC_CASE_TYPE(code)) {
|
||||
case WC_CASE_OR:
|
||||
taddstr(" ;;");
|
||||
break;
|
||||
|
||||
case WC_CASE_AND:
|
||||
taddstr(";&");
|
||||
break;
|
||||
|
||||
default:
|
||||
taddstr(";|");
|
||||
break;
|
||||
}
|
||||
tindent--;
|
||||
if (tnewlins)
|
||||
taddnl();
|
||||
|
|
33
Src/zsh.h
33
Src/zsh.h
|
@ -246,37 +246,38 @@ enum {
|
|||
DOUTPAR,
|
||||
AMPERBANG, /* 30 */
|
||||
SEMIAMP,
|
||||
SEMIBAR,
|
||||
DOUTBRACK,
|
||||
STRING,
|
||||
ENVSTRING,
|
||||
ENVARRAY, /* 35 */
|
||||
ENVSTRING, /* 35 */
|
||||
ENVARRAY,
|
||||
ENDINPUT,
|
||||
LEXERR,
|
||||
|
||||
/* Tokens for reserved words */
|
||||
BANG, /* ! */
|
||||
DINBRACK, /* [[ */
|
||||
INBRACE, /* { */ /* 40 */
|
||||
DINBRACK, /* [[ */ /* 40 */
|
||||
INBRACE, /* { */
|
||||
OUTBRACE, /* } */
|
||||
CASE, /* case */
|
||||
COPROC, /* coproc */
|
||||
DOLOOP, /* do */
|
||||
DONE, /* done */ /* 45 */
|
||||
DOLOOP, /* do */ /* 45 */
|
||||
DONE, /* done */
|
||||
ELIF, /* elif */
|
||||
ELSE, /* else */
|
||||
ZEND, /* end */
|
||||
ESAC, /* esac */
|
||||
FI, /* fi */ /* 50 */
|
||||
ESAC, /* esac */ /* 50 */
|
||||
FI, /* fi */
|
||||
FOR, /* for */
|
||||
FOREACH, /* foreach */
|
||||
FUNC, /* function */
|
||||
IF, /* if */
|
||||
NOCORRECT, /* nocorrect */ /* 55 */
|
||||
IF, /* if */ /* 55 */
|
||||
NOCORRECT, /* nocorrect */
|
||||
REPEAT, /* repeat */
|
||||
SELECT, /* select */
|
||||
THEN, /* then */
|
||||
TIME, /* time */
|
||||
UNTIL, /* until */ /* 60 */
|
||||
TIME, /* time */ /* 60 */
|
||||
UNTIL, /* until */
|
||||
WHILE /* while */
|
||||
};
|
||||
|
||||
|
@ -783,12 +784,14 @@ struct eccstr {
|
|||
#define WC_TRY_SKIP(C) wc_data(C)
|
||||
#define WCB_TRY(O) wc_bld(WC_TRY, (O))
|
||||
|
||||
#define WC_CASE_TYPE(C) (wc_data(C) & 3)
|
||||
#define WC_CASE_TYPE(C) (wc_data(C) & 7)
|
||||
#define WC_CASE_HEAD 0
|
||||
#define WC_CASE_OR 1
|
||||
#define WC_CASE_AND 2
|
||||
#define WC_CASE_SKIP(C) (wc_data(C) >> 2)
|
||||
#define WCB_CASE(T,O) wc_bld(WC_CASE, ((T) | ((O) << 2)))
|
||||
#define WC_CASE_TESTAND 3
|
||||
#define WC_CASE_FREE (3) /* Next bit available in integer */
|
||||
#define WC_CASE_SKIP(C) (wc_data(C) >> WC_CASE_FREE)
|
||||
#define WCB_CASE(T,O) wc_bld(WC_CASE, ((T) | ((O) << WC_CASE_FREE)))
|
||||
|
||||
#define WC_IF_TYPE(C) (wc_data(C) & 3)
|
||||
#define WC_IF_HEAD 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue