work on making transformations use relative return values
[pspp] / src / language / control / loop.c
index 8f4ff8251648a8cf93958347de0ce69b5d6970af..2505d2ef29f49ce9b343bceaf798e74270a5733b 100644 (file)
@@ -1,5 +1,5 @@
 /* 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"
@@ -81,7 +80,6 @@ struct loop_trns
 
 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;
 
@@ -261,7 +259,7 @@ parse_index_clause (struct dataset *ds, struct lexer *lexer,
     }
   if (loop->last_expr == NULL)
     {
-      lex_sbc_missing (lexer, "TO");
+      lex_sbc_missing ("TO");
       return false;
     }
   if (loop->by_expr == NULL)
@@ -282,8 +280,7 @@ create_loop_trns (struct dataset *ds)
   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);
@@ -291,17 +288,6 @@ create_loop_trns (struct dataset *ds)
   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)
@@ -340,10 +326,10 @@ 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. */
@@ -367,12 +353,8 @@ end_loop_trns_proc (void *loop_, struct ccase **c, casenumber case_num UNUSED)
     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)
@@ -389,10 +371,10 @@ end_loop_trns_proc (void *loop_, struct ccase **c, casenumber case_num UNUSED)
       && 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. */