aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-03-24 22:56:27 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-03-25 01:53:22 +0200
commit20a0b370e535813c2c46f21f7be9a7ef94b0f0b0 (patch)
tree10d42b1fbe0e196c3766bcfc8b5419996c4dd04c
parentfd1ecf7338de617f28a3f746715058632b0b87d9 (diff)
downloadmailfromd-20a0b370e535813c2c46f21f7be9a7ef94b0f0b0.tar.gz
mailfromd-20a0b370e535813c2c46f21f7be9a7ef94b0f0b0.tar.bz2
Fix the usage of `next' and `break' in try/catch blocks (port of bd4fb40f and 5d311ce8)
-rw-r--r--mfd/drivers.c78
-rw-r--r--tests/Makefile.am12
-rw-r--r--tests/testsuite.at12
-rw-r--r--tests/trycatch01.at2
-rw-r--r--tests/trycatch02.at2
-rw-r--r--tests/trycatch03.at4
-rw-r--r--tests/trycatch04.at4
-rw-r--r--tests/trycatch05.at57
-rw-r--r--tests/trycatch06.at57
-rw-r--r--tests/trycatch07.at57
-rw-r--r--tests/trycatch08.at57
-rw-r--r--tests/trycatch09.at64
-rw-r--r--tests/trycatch10.at66
-rw-r--r--tests/trycatch11.at65
-rw-r--r--tests/trycatch12.at65
-rw-r--r--tests/trycatch13.at57
-rw-r--r--tests/trycatch14.at57
-rw-r--r--tests/trycatch15.at64
-rw-r--r--tests/trycatch16.at64
19 files changed, 836 insertions, 8 deletions
diff --git a/mfd/drivers.c b/mfd/drivers.c
index 76152f02..311f4ed0 100644
--- a/mfd/drivers.c
+++ b/mfd/drivers.c
@@ -23,6 +23,9 @@
code_immediate((void*)node->locus.line); \
} while (0)
+static void code_trycatch_exit(unsigned id);
+static unsigned trycatch_last_id(void);
+
void
@@ -1532,6 +1535,64 @@ code_type_regcomp(NODE *node, struct locus **old_locus)
}
+struct trycatch_stack_entry {
+ int istry;
+ struct locus *locus;
+ unsigned id;
+};
+
+static mf_stack_t trycatch_stack;
+
+static unsigned
+trycatch_last_id(void)
+{
+ struct trycatch_stack_entry ent;
+ if (!trycatch_stack || mf_stack_peek(trycatch_stack, 0, &ent))
+ return 0;
+ return ent.id;
+}
+
+static void
+enter_trycatch(int istry, struct locus *locus)
+{
+ struct trycatch_stack_entry ent;
+
+ if (!trycatch_stack)
+ trycatch_stack = mf_stack_create(sizeof(ent), 0);
+ ent.istry = istry;
+ ent.locus = locus;
+ ent.id = trycatch_last_id() + 1;
+ mf_stack_push(trycatch_stack, &ent);
+}
+
+static void
+leave_trycatch()
+{
+ mf_stack_pop(trycatch_stack, NULL);
+}
+
+static int
+_code_trycatch_exit(void *item, void *data)
+{
+ struct trycatch_stack_entry *ent = item;
+ unsigned id = *(unsigned*)data;
+
+ if (ent->id <= id)
+ return 1;
+ if (!ent->istry)
+ code_op(opcode_retcatch);
+ code_op(opcode_restex);
+ return 0;
+}
+
+static void
+code_trycatch_exit(unsigned id)
+{
+ if (trycatch_stack)
+ mf_stack_enumerate_desc(trycatch_stack, _code_trycatch_exit,
+ &id);
+}
+
/* type catch */
void
print_type_catch(NODE *node, int level)
@@ -1579,8 +1640,10 @@ code_type_catch(NODE *node, struct locus **old_locus)
ctr = jump_pc;
jump_pc = 0;
-
+
+ enter_trycatch(0, &node->locus);
traverse_tree(node->v.catch.node);
+ leave_trycatch();
jump_fixup(jump_pc, code_get_counter());
jump_pc = ctr;
@@ -1647,8 +1710,10 @@ code_type_try(NODE *node, struct locus **old_locus)
/* Compile `catch' part */
jump_pc = 0;
+ enter_trycatch(0, &catch->node->locus);
traverse_tree(catch->node);
-
+ leave_trycatch();
+
/* Normal exit from catch */
code_op(opcode_retcatch);
code_op(opcode_jmp);
@@ -1667,7 +1732,9 @@ code_type_try(NODE *node, struct locus **old_locus)
/* Compile `try' part */
MARK_LOCUS();
jump_pc = 0;
+ enter_trycatch(1, &node->v.try.node->locus);
traverse_tree(node->v.try.node);
+ leave_trycatch();
try_ret_pc = jump_pc;
code_op(opcode_jmp);
try_jmp_pc = code_immediate(NULL);
@@ -2165,6 +2232,7 @@ struct loop_stack {
struct literal *ident;
prog_counter_t *endjmp;
prog_counter_t *nxtjmp;
+ unsigned trycatch_id;
};
static mf_stack_t loop_stack;
@@ -2212,6 +2280,7 @@ enter_loop(struct literal *lit, prog_counter_t *endptr, prog_counter_t *nxtptr)
ent.endjmp = endptr;
ent.nxtjmp = nxtptr;
ent.ident = lit;
+ ent.trycatch_id = trycatch_last_id();
mf_stack_push(loop_stack, &ent);
}
@@ -2247,6 +2316,8 @@ code_type_next(NODE *node, struct locus **old_locus)
abort();
}
+ code_trycatch_exit(ent.trycatch_id);
+
code_op(opcode_jmp);
*ent.nxtjmp = code_immediate((void*) *ent.nxtjmp);
}
@@ -2277,6 +2348,7 @@ code_type_break(NODE *node, struct locus **old_locus)
abort();
}
+ code_trycatch_exit(ent.trycatch_id);
code_op(opcode_jmp);
*ent.endjmp = code_immediate((void*) *ent.endjmp);
}
@@ -2401,6 +2473,8 @@ code_type_loop(NODE *node, struct locus **old_locus)
jump_fixup(endjmp, end);
jump_fixup(nxtjmp, stmt);
+
+ leave_loop();
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 019af424..1f894d16 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -125,6 +125,18 @@ TESTSUITE_AT = \
trycatch02.at\
trycatch03.at\
trycatch04.at\
+ trycatch05.at\
+ trycatch06.at\
+ trycatch07.at\
+ trycatch08.at\
+ trycatch09.at\
+ trycatch10.at\
+ trycatch11.at\
+ trycatch12.at\
+ trycatch13.at\
+ trycatch14.at\
+ trycatch15.at\
+ trycatch16.at\
testsuite.at\
version.at
diff --git a/tests/testsuite.at b/tests/testsuite.at
index ab5588e7..29ef4477 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -150,6 +150,18 @@ m4_include([trycatch01.at])
m4_include([trycatch02.at])
m4_include([trycatch03.at])
m4_include([trycatch04.at])
+m4_include([trycatch05.at])
+m4_include([trycatch06.at])
+m4_include([trycatch07.at])
+m4_include([trycatch08.at])
+m4_include([trycatch09.at])
+m4_include([trycatch10.at])
+m4_include([trycatch11.at])
+m4_include([trycatch12.at])
+m4_include([trycatch13.at])
+m4_include([trycatch14.at])
+m4_include([trycatch15.at])
+m4_include([trycatch16.at])
m4_include([cidr1.at])
m4_include([cidr2.at])
diff --git a/tests/trycatch01.at b/tests/trycatch01.at
index 496c47b8..a061f0ed 100644
--- a/tests/trycatch01.at
+++ b/tests/trycatch01.at
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([Try-catch: returning from try])
-AT_KEYWORDS([try catch try-catch trycatch01])
+AT_KEYWORDS([try catch return try-catch trycatch try-catch01 trycatch01])
# Description: Check returning from the try branch of a `try-catch'
# construct.
diff --git a/tests/trycatch02.at b/tests/trycatch02.at
index 383d0264..493ba79e 100644
--- a/tests/trycatch02.at
+++ b/tests/trycatch02.at
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([Try-catch: returning from catch])
-AT_KEYWORDS([try catch try-catch trycatch02])
+AT_KEYWORDS([try catch return try-catch trycatch try-catch02 trycatch02])
# Description: Check returning from the catch branch of a `try-catch'
# construct.
diff --git a/tests/trycatch03.at b/tests/trycatch03.at
index cdb09538..e53f1c88 100644
--- a/tests/trycatch03.at
+++ b/tests/trycatch03.at
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([Try-catch: passing through try])
-AT_KEYWORDS([try catch try-catch trycatch03])
+AT_KEYWORDS([try catch try-catch trycatch try-catch03 trycatch03])
# Description: Check whether passing through the try branch of a `try-catch'
# construct works correctly.
@@ -50,4 +50,4 @@ done
2
])
-AT_CLEANUP \ No newline at end of file
+AT_CLEANUP
diff --git a/tests/trycatch04.at b/tests/trycatch04.at
index 5c730b61..9584fe57 100644
--- a/tests/trycatch04.at
+++ b/tests/trycatch04.at
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([Try-catch: passing through catch])
-AT_KEYWORDS([try catch try-catch trycatch04])
+AT_KEYWORDS([try catch try-catch trycatch try-catch04 trycatch04])
# Description: Check whether passing through the catch branch of a `try-catch'
# construct works correctly.
@@ -52,4 +52,4 @@ Caught exception: 1, text
2
])
-AT_CLEANUP \ No newline at end of file
+AT_CLEANUP
diff --git a/tests/trycatch05.at b/tests/trycatch05.at
new file mode 100644
index 00000000..bf4c9843
--- /dev/null
+++ b/tests/trycatch05.at
@@ -0,0 +1,57 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: break from try])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch05 trycatch05])
+
+# Description: Check whether break from a try branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop
+ do
+ try
+ do
+ break
+ done
+ catch usr1
+ do
+ pass
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch06.at b/tests/trycatch06.at
new file mode 100644
index 00000000..8fa9b949
--- /dev/null
+++ b/tests/trycatch06.at
@@ -0,0 +1,57 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: break from catch])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch06 trycatch06])
+
+# Description: Check whether break from a catch branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop
+ do
+ try
+ do
+ throw usr1 "break"
+ done
+ catch usr1
+ do
+ break
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch07.at b/tests/trycatch07.at
new file mode 100644
index 00000000..6f1c3e3c
--- /dev/null
+++ b/tests/trycatch07.at
@@ -0,0 +1,57 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: next from try])
+AT_KEYWORDS([try catch next try-catch trycatch try-catch07 trycatch07])
+
+# Description: Check whether next from a try branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop for number i 0, while i < 5, set i i + 1
+ do
+ try
+ do
+ next
+ done
+ catch usr1
+ do
+ pass
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch08.at b/tests/trycatch08.at
new file mode 100644
index 00000000..b970f860
--- /dev/null
+++ b/tests/trycatch08.at
@@ -0,0 +1,57 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: next from catch])
+AT_KEYWORDS([try catch next try-catch trycatch try-catch08 trycatch08])
+
+# Description: Check whether next from a catch branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop for number i 0, while i < 5, set i i + 1
+ do
+ try
+ do
+ throw usr1 "break"
+ done
+ catch usr1
+ do
+ next
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch09.at b/tests/trycatch09.at
new file mode 100644
index 00000000..af684707
--- /dev/null
+++ b/tests/trycatch09.at
@@ -0,0 +1,64 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: break from nested try])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch09 trycatch09])
+
+# Description: Check whether break from a nested try branch does not
+# clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop
+ do
+ try
+ do
+ try
+ do
+ break
+ done
+ catch usr1
+ do
+ pass
+ done
+ done
+ catch usr1
+ do
+ pass
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch10.at b/tests/trycatch10.at
new file mode 100644
index 00000000..0ce30a3b
--- /dev/null
+++ b/tests/trycatch10.at
@@ -0,0 +1,66 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: break from nested catch])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch10 trycatch10])
+
+# Description: Check whether break from a nested catch branch does not
+# clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop
+ do
+ try
+ do
+ try
+ do
+ throw usr1 "break"
+ done
+ catch usr1
+ do
+ break
+ done
+ done
+ catch *
+ do
+ echo "outer catch"
+ pass
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch11.at b/tests/trycatch11.at
new file mode 100644
index 00000000..d08d2366
--- /dev/null
+++ b/tests/trycatch11.at
@@ -0,0 +1,65 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: next from nested try])
+AT_KEYWORDS([try catch next try-catch trycatch try-catch11 trycatch11])
+
+# Description: Check whether next from a nested try branch does not
+# clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop for number i 0, while i < 5, set i i + 1
+ do
+ try
+ do
+ try
+ do
+ next
+ done
+ catch usr1
+ do
+ pass
+ done
+ done
+ catch usr1
+ do
+ echo "outer catch"
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch12.at b/tests/trycatch12.at
new file mode 100644
index 00000000..133145fd
--- /dev/null
+++ b/tests/trycatch12.at
@@ -0,0 +1,65 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: next from nested catch])
+AT_KEYWORDS([try catch next try-catch trycatch try-catch12 trycatch12])
+
+# Description: Check whether next from a nested catch branch does not
+# clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ loop for number i 0, while i < 5, set i i + 1
+ do
+ try
+ do
+ try
+ do
+ throw usr1 "break"
+ done
+ catch usr1
+ do
+ next
+ done
+ done
+ catch *
+ do
+ echo "external catch"
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch13.at b/tests/trycatch13.at
new file mode 100644
index 00000000..b40a8f5a
--- /dev/null
+++ b/tests/trycatch13.at
@@ -0,0 +1,57 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: break from a loop within try])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch13 trycatch13])
+
+# Description: Check whether break from a try branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ try
+ do
+ loop
+ do
+ break
+ done
+ done
+ catch usr1
+ do
+ pass
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch14.at b/tests/trycatch14.at
new file mode 100644
index 00000000..6a5bb73e
--- /dev/null
+++ b/tests/trycatch14.at
@@ -0,0 +1,57 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: break from a loop within catch])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch14 trycatch14])
+
+# Description: Check whether break from a try branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ try
+ do
+ throw usr1 "break"
+ done
+ catch usr1
+ do
+ loop
+ do
+ break
+ done
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+wc -l err
+sort err | uniq | wc -l
+],
+[0],
+[2 err
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch15.at b/tests/trycatch15.at
new file mode 100644
index 00000000..f905a792
--- /dev/null
+++ b/tests/trycatch15.at
@@ -0,0 +1,64 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: next in a loop within try])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch15 trycatch15])
+
+# Description: Check whether break from a try branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ try
+ do
+ loop for number i 0, while i < 5, set i i + 1
+ do
+ if i & 1
+ next
+ fi
+ echo i
+ done
+ done
+ catch usr1
+ do
+ pass
+ done
+ echo _reg(REG_TOS)
+done
+])
+
+AT_CHECK([
+mailfromd MAILFROMD_OPTIONS --run prog 2>err || exit $?
+sed '1d;$d' err
+echo "delimiter"
+sed -n '1p;$p' err | uniq | wc -l
+],
+[0],
+[0
+2
+4
+delimiter
+1
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/trycatch16.at b/tests/trycatch16.at
new file mode 100644
index 00000000..25cc4955
--- /dev/null
+++ b/tests/trycatch16.at
@@ -0,0 +1,64 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2011 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Try-catch: next in a loop within catch])
+AT_KEYWORDS([try catch break try-catch trycatch try-catch16 trycatch16])
+
+# Description: Check whether break from a try branch does not clobber stack
+
+AT_DATA([prog],[
+require '_register'
+dclex usr1
+
+func main(...)
+ returns number
+do
+ echo _reg(REG_TOS)
+ try
+ do
+ throw usr1 "user-defined"
+ done
+ catch usr1