From de272e0309bc1739f13cc8271a2f94bcde7ba23c Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 19 Jan 2007 21:36:00 +0000 Subject: 23115: ";|" at end of case clause causes later patterns to be tested --- Src/lex.c | 4 ++++ Src/loop.c | 7 ++++--- Src/parse.c | 12 +++++++----- Src/text.c | 28 ++++++++++++++++++++++++++-- Src/zsh.h | 33 ++++++++++++++++++--------------- 5 files changed, 59 insertions(+), 25 deletions(-) (limited to 'Src') diff --git a/Src/lex.c b/Src/lex.c index 7a0bf2b1c..095d58150 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -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; diff --git a/Src/loop.c b/Src/loop.c index 7037ddc82..b20e379b8 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -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(); diff --git a/Src/parse.c b/Src/parse.c index a25eb3efa..afaa0d944 100644 --- a/Src/parse.c +++ b/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; diff --git a/Src/text.c b/Src/text.c index 0079e9fea..181fea083 100644 --- a/Src/text.c +++ b/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(); diff --git a/Src/zsh.h b/Src/zsh.h index 27c344809..e2eb2544a 100644 --- a/Src/zsh.h +++ b/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 -- cgit 1.4.1