summaryrefslogtreecommitdiff
path: root/Src/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/parse.c')
-rw-r--r--Src/parse.c38
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));
+ }
}
/*