#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"
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. */
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)
{
{
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];
{
struct transformation *trns;
- chain->finalized = false;
-
if (chain->trns_cnt == chain->trns_cap)
chain->trns = x2nrealloc (chain->trns, &chain->trns_cap,
sizeof *chain->trns);
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;
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;