Work on getting rid of trns_chain_finalize().
[pspp] / src / data / transformations.c
index 884def67531de301129872b6298f96327b6d5d09..8b246b7399d036826361412bc0b3657b702f4a93 100644 (file)
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 
 #include "libpspp/str.h"
-#include "language/control/control-stack.h" /* XXX layering violation */
+#include "data/control-stack.h" /* XXX layering violation */
 
 #include "gl/xalloc.h"
 
@@ -44,7 +44,6 @@ struct trns_chain
     struct transformation *trns;        /* Array of transformations. */
     size_t trns_cnt;                    /* Number of transformations. */
     size_t trns_cap;                    /* Allocated capacity. */
-    bool finalized;                     /* Finalize functions called? */
   };
 
 /* Allocates and returns a new transformation chain. */
@@ -55,24 +54,10 @@ trns_chain_create (void)
   chain->trns = NULL;
   chain->trns_cnt = 0;
   chain->trns_cap = 0;
-  chain->finalized = false;
   return chain;
 }
 
-/* Finalizes all the un-finalized transformations in CHAIN.
-   Any given transformation is only finalized once. */
-void
-trns_chain_finalize (struct trns_chain *chain)
-{
-  while (!chain->finalized)
-    {
-      ctl_stack_clear ();       /* XXX layering violation */
-      chain->finalized = true;
-    }
-}
-
-/* Destroys CHAIN, finalizing it in the process if it has not
-   already been finalized. */
+/* Destroys CHAIN. */
 bool
 trns_chain_destroy (struct trns_chain *chain)
 {
@@ -82,9 +67,6 @@ trns_chain_destroy (struct trns_chain *chain)
     {
       size_t i;
 
-      /* Needed to ensure that the control stack gets cleared. */
-      trns_chain_finalize (chain);
-
       for (i = 0; i < chain->trns_cnt; i++)
         {
           struct transformation *trns = &chain->trns[i];
@@ -114,8 +96,6 @@ trns_chain_append (struct trns_chain *chain, trns_proc_func *execute,
 {
   struct transformation *trns;
 
-  chain->finalized = false;
-
   if (chain->trns_cnt == chain->trns_cap)
     chain->trns = x2nrealloc (chain->trns, &chain->trns_cap,
                               sizeof *chain->trns);
@@ -127,17 +107,12 @@ trns_chain_append (struct trns_chain *chain, trns_proc_func *execute,
   trns->aux = aux;
 }
 
-/* Appends the transformations in SRC to those in DST,
-   and destroys SRC.
-   Both DST and SRC must already be finalized. */
+/* Appends the transformations in SRC to those in DST, and destroys SRC. */
 void
 trns_chain_splice (struct trns_chain *dst, struct trns_chain *src)
 {
   size_t i;
 
-  assert (dst->finalized);
-  assert (src->finalized);
-
   if (dst->trns_cnt + src->trns_cnt > dst->trns_cap)
     {
       dst->trns_cap = dst->trns_cnt + src->trns_cnt;
@@ -175,19 +150,33 @@ enum trns_result
 trns_chain_execute (const struct trns_chain *chain, enum trns_result start,
                     struct ccase **c, casenumber case_nr)
 {
-  size_t i;
+  int i;
 
-  assert (chain->finalized);
   for (i = start < 0 ? 0 : start; i < chain->trns_cnt; )
     {
       struct transformation *trns = &chain->trns[i];
-      int retval = trns->execute (trns->aux, c, case_nr);
-      if (retval == TRNS_CONTINUE)
-        i++;
-      else if (retval >= 0)
-        i = retval + trns->idx_ofs;
-      else
-        return retval == TRNS_END_CASE ? i + 1 : retval;
+      int retval;
+
+      retval = trns->execute (trns->aux, c, case_nr);
+      switch (retval)
+        {
+        case TRNS_CONTINUE:
+          i++;
+          break;
+
+        case TRNS_END_CASE:
+          return i + 1;
+
+        case TRNS_DROP_CASE:
+        case TRNS_ERROR:
+        case TRNS_END_FILE:
+          return retval;
+
+        default:
+          i += retval;
+          assert (i <= chain->trns_cnt);
+          break;
+        }
     }
 
   return TRNS_CONTINUE;