X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fcontrol%2Fdo-if.c;h=a0bbf79381434b101a20ab0b1991a44cb434cf89;hb=9956f167d1db0f91ed35f9fb28b711586a416d42;hp=dc39e66d4db01214c5c174bf83ddbe879dd47bee;hpb=2322678e8fddbbf158b01b2720db2636404bba3b;p=pspp-builds.git diff --git a/src/language/control/do-if.c b/src/language/control/do-if.c index dc39e66d..a0bbf793 100644 --- a/src/language/control/do-if.c +++ b/src/language/control/do-if.c @@ -18,17 +18,21 @@ 02110-1301, USA. */ #include -#include "control-stack.h" -#include "message.h" + #include -#include "alloc.h" -#include "command.h" -#include "compiler.h" -#include "message.h" -#include "expressions/public.h" -#include "lexer.h" -#include "str.h" -#include "variable.h" + +#include "control-stack.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -87,6 +91,7 @@ static bool has_else (struct do_if_trns *); static bool must_not_have_else (struct do_if_trns *); static void close_do_if (void *do_if); +static trns_finalize_func do_if_finalize_func; static trns_proc_func do_if_trns_proc, break_trns_proc; static trns_free_func do_if_trns_free; @@ -99,7 +104,8 @@ cmd_do_if (void) do_if->clause_cnt = 0; ctl_stack_push (&do_if_class, do_if); - add_transformation (do_if_trns_proc, do_if_trns_free, do_if); + add_transformation_with_finalizer (do_if_finalize_func, + do_if_trns_proc, do_if_trns_free, do_if); return parse_clause (do_if); } @@ -217,11 +223,22 @@ add_clause (struct do_if_trns *do_if, clause->target_index = target_index; } +/* Finalizes DO IF by clearing the control stack, thus ensuring + that all open DO IFs are closed. */ +static void +do_if_finalize_func (void *do_if_ UNUSED) +{ + /* This will be called multiple times if multiple DO IFs were + executed, which is slightly unclean, but at least it's + idempotent. */ + ctl_stack_clear (); +} + /* DO IF transformation procedure. Checks each clause and jumps to the appropriate transformation. */ static int -do_if_trns_proc (void *do_if_, struct ccase *c, int case_num UNUSED) +do_if_trns_proc (void *do_if_, struct ccase *c, casenum_t case_num UNUSED) { struct do_if_trns *do_if = do_if_; struct clause *clause; @@ -260,7 +277,7 @@ do_if_trns_free (void *do_if_) /* Breaks out of a DO IF construct. */ static int -break_trns_proc (void *do_if_, struct ccase *c UNUSED, int case_num UNUSED) +break_trns_proc (void *do_if_, struct ccase *c UNUSED, casenum_t case_num UNUSED) { struct do_if_trns *do_if = do_if_;