/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2009-2011, 2013 Free Software Foundation, Inc.
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
#include <config.h>
-#include "language/control/control-stack.h"
-
#include "data/case.h"
+#include "data/control-stack.h"
+#include "data/dataset.h"
#include "data/dictionary.h"
-#include "data/procedure.h"
#include "data/settings.h"
#include "data/transformations.h"
#include "data/variable.h"
static const 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;
}
if (loop->last_expr == NULL)
{
- lex_sbc_missing (lexer, "TO");
+ lex_sbc_missing ("TO");
return false;
}
if (loop->by_expr == NULL)
loop->loop_condition = loop->end_loop_condition = NULL;
loop->ds = ds;
- add_transformation_with_finalizer (ds, loop_trns_finalize,
- loop_trns_proc, loop_trns_free, loop);
+ add_transformation (ds, loop_trns_proc, loop_trns_free, loop);
loop->past_LOOP_index = next_transformation (ds);
ctl_stack_push (&loop_class, loop);
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, casenumber case_num)
&& expr_evaluate_num (loop->loop_condition, *c, case_num) != 1.0)
goto zero_pass;
- return loop->past_LOOP_index;
+ return TRNS_CONTINUE;
zero_pass:
- return loop->past_END_LOOP_index;
+ return loop->past_END_LOOP_index - loop->past_LOOP_index + 1;
}
/* Frees LOOP. */
goto break_out;
/* MXLOOPS limiter. */
- if (loop->max_pass_count >= 0)
- {
- if (loop->pass >= loop->max_pass_count)
- goto break_out;
- loop->pass++;
- }
+ if (loop->max_pass_count >= 0 && ++loop->pass >= loop->max_pass_count)
+ goto break_out;
/* Indexing clause limiter: counting downward. */
if (loop->index_var != NULL)
&& expr_evaluate_num (loop->loop_condition, *c, case_num) != 1.0)
goto break_out;
- return loop->past_LOOP_index;
+ return loop->past_LOOP_index - loop->past_END_LOOP_index;
break_out:
- return loop->past_END_LOOP_index;
+ return TRNS_CONTINUE;
}
/* Executes BREAK. */