summaryrefslogtreecommitdiff
path: root/Src/loop.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2004-06-22 13:09:55 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2004-06-22 13:09:55 +0000
commitd591334e9d616830fbd24909db2e21ac4b959742 (patch)
tree65b44f10e6995c95605c8a56c3ca0fd9bfe6ad9d /Src/loop.c
parent6a1d913bd6214d7ca7f8cf1a82efef1fa4bae101 (diff)
downloadzsh-d591334e9d616830fbd24909db2e21ac4b959742.tar.gz
zsh-d591334e9d616830fbd24909db2e21ac4b959742.zip
20076, 20084: { ... } always { ... } syntax.
Diffstat (limited to 'Src/loop.c')
-rw-r--r--Src/loop.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/Src/loop.c b/Src/loop.c
index f52f5e74e..4c45c1f78 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -616,3 +616,68 @@ execcase(Estate state, int do_exec)
return lastval;
}
+
+/*
+ * Errflag from `try' block, may be reset in `always' block.
+ * Accessible from an integer parameter, so needs to be a zlong.
+ */
+
+/**/
+zlong
+try_errflag = -1;
+
+/**/
+int
+exectry(Estate state, int do_exec)
+{
+ Wordcode end, always;
+ int endval;
+ int save_retflag, save_breaks, save_loops, save_contflag;
+ zlong save_try_errflag;
+
+ end = state->pc + WC_TRY_SKIP(state->pc[-1]);
+ always = state->pc + 1 + WC_TRY_SKIP(*state->pc);
+ state->pc++;
+ pushheap();
+ cmdpush(CS_CURSH);
+
+ /* The :try clause */
+ execlist(state, 1, do_exec);
+
+ /* Don't record errflag here, may be reset. */
+ endval = lastval;
+
+ freeheap();
+
+ cmdpop();
+ cmdpush(CS_ALWAYS);
+
+ /* The always clause. */
+ save_try_errflag = try_errflag;
+ try_errflag = (zlong)errflag;
+ errflag = 0;
+ save_retflag = retflag;
+ retflag = 0;
+ save_breaks = breaks;
+ breaks = 0;
+ save_loops = loops;
+ loops = 0;
+ save_contflag = contflag;
+ contflag = 0;
+
+ state->pc = always;
+ execlist(state, 1, do_exec);
+
+ errflag = try_errflag ? 1 : 0;
+ try_errflag = save_try_errflag;
+ retflag = save_retflag;
+ breaks = save_breaks;
+ loops = save_loops;
+ contflag = save_contflag;
+
+ cmdpop();
+ popheap();
+ state->pc = end;
+
+ return endval;
+}