diff options
Diffstat (limited to 'Src/parse.c')
-rw-r--r-- | Src/parse.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/Src/parse.c b/Src/parse.c index 2f9319977..6bef195f8 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1330,25 +1330,55 @@ par_repeat(int *complex) } /* - * subsh : ( INPAR | INBRACE ) list ( OUTPAR | OUTBRACE ) + * subsh : INPAR list OUTPAR | + * INBRACE list OUTBRACE [ "always" INBRACE list OUTBRACE ] */ /**/ static void par_subsh(int *complex) { - int oecused = ecused, otok = tok, p; + int oecused = ecused, otok = tok, p, pp; p = ecadd(0); + /* Extra word only needed for always block */ + pp = ecadd(0); yylex(); par_list(complex); ecadd(WCB_END()); if (tok != ((otok == INPAR) ? OUTPAR : OUTBRACE)) YYERRORV(oecused); - ecbuf[p] = (otok == INPAR ? WCB_SUBSH(ecused - 1 - p) : - WCB_CURSH(ecused - 1 - p)); incmdpos = 1; yylex(); + + /* Optional always block. No intervening SEPERs allowed. */ + if (otok == INBRACE && tok == STRING && !strcmp(tokstr, "always")) { + ecbuf[pp] = WCB_TRY(ecused - 1 - pp); + incmdpos = 1; + do { + yylex(); + } while (tok == SEPER); + + if (tok != INBRACE) + YYERRORV(oecused); + cmdpop(); + cmdpush(CS_ALWAYS); + + yylex(); + par_save_list(complex); + while (tok == SEPER) + yylex(); + + incmdpos = 1; + + if (tok != OUTBRACE) + YYERRORV(oecused); + yylex(); + ecbuf[p] = WCB_TRY(ecused - 1 - p); + } else { + ecbuf[p] = (otok == INPAR ? WCB_SUBSH(ecused - 1 - p) : + WCB_CURSH(ecused - 1 - p)); + } } /* |