1
0
Fork 0
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:
Peter Stephenson 2007-01-19 21:36:00 +00:00
parent a5729be835
commit de272e0309
8 changed files with 101 additions and 29 deletions

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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();

View file

@ -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