X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fcontrol%2Floop.c;h=f31486f605f7bd7680257bf4dd0710738374b02a;hb=7496b3a78aafe5c66790f805ef2de1437340a73a;hp=da1dc2fc49dfeda732b6f8e599ffe3d14fd92496;hpb=a19b858e0ac3c69e4a28c0ca6d8674427268a863;p=pspp-builds.git diff --git a/src/language/control/loop.c b/src/language/control/loop.c index da1dc2fc..f31486f6 100644 --- a/src/language/control/loop.c +++ b/src/language/control/loop.c @@ -18,21 +18,23 @@ 02110-1301, USA. */ #include -#include -#include + +#include "control-stack.h" #include -#include -#include #include -#include "control-stack.h" -#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include #include #include -#include #include -#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -79,6 +81,7 @@ struct loop_trns static struct ctl_class loop_class; +static trns_finalize_func loop_trns_finalize; static trns_proc_func loop_trns_proc, end_loop_trns_proc, break_trns_proc; static trns_free_func loop_trns_free; @@ -116,7 +119,7 @@ cmd_loop (void) if (!ok) loop->max_pass_count = 0; - return ok ? CMD_SUCCESS : CMD_PART_SUCCESS; + return ok ? CMD_SUCCESS : CMD_FAILURE; } /* Parses END LOOP. */ @@ -141,7 +144,7 @@ cmd_end_loop (void) ctl_stack_pop (loop); - return ok ? CMD_SUCCESS : CMD_PART_SUCCESS; + return ok ? CMD_SUCCESS : CMD_FAILURE; } /* Parses BREAK. */ @@ -248,7 +251,8 @@ create_loop_trns (void) loop->first_expr = loop->by_expr = loop->last_expr = NULL; loop->loop_condition = loop->end_loop_condition = NULL; - add_transformation (loop_trns_proc, loop_trns_free, loop); + add_transformation_with_finalizer (loop_trns_finalize, + loop_trns_proc, loop_trns_free, loop); loop->past_LOOP_index = next_transformation (); ctl_stack_push (&loop_class, loop); @@ -256,6 +260,17 @@ create_loop_trns (void) return loop; } +/* Finalizes LOOP by clearing the control stack, thus ensuring + that all open LOOPs are closed. */ +static void +loop_trns_finalize (void *do_if_ UNUSED) +{ + /* This will be called multiple times if multiple LOOPs were + executed, which is slightly unclean, but at least it's + idempotent. */ + ctl_stack_clear (); +} + /* Sets up LOOP for the first pass. */ static int loop_trns_proc (void *loop_, struct ccase *c, int case_num)