-#include <data/case-source.h>
-#include <data/case-sink.h>
-#include <data/case.h>
-#include <data/casefile.h>
-#include <data/dictionary.h>
-#include <data/file-handle-def.h>
-#include <data/procedure.h>
-#include <data/storage-stream.h>
-#include <data/transformations.h>
-#include <data/variable.h>
-#include <libpspp/alloc.h>
-#include <libpspp/misc.h>
-#include <libpspp/str.h>
-
-/*
- Virtual File Manager (vfm):
-
- vfm is used to process data files. It uses the model that
- data is read from one stream (the data source), processed,
- then written to another (the data sink). The data source is
- then deleted and the data sink becomes the data source for the
- next procedure. */
-
-/* Procedure execution data. */
-struct write_case_data
- {
- /* Function to call for each case. */
- bool (*case_func) (const struct ccase *, void *);
- void *aux;
-
- struct ccase trns_case; /* Case used for transformations. */
- struct ccase sink_case; /* Case written to sink, if
- compaction is necessary. */
- size_t cases_written; /* Cases output so far. */
- };
+#include "data/case.h"
+#include "data/case-map.h"
+#include "data/caseinit.h"
+#include "data/casereader.h"
+#include "data/casereader-provider.h"
+#include "data/casereader-shim.h"
+#include "data/casewriter.h"
+#include "data/dictionary.h"
+#include "data/file-handle-def.h"
+#include "data/transformations.h"
+#include "data/variable.h"
+#include "libpspp/deque.h"
+#include "libpspp/misc.h"
+#include "libpspp/str.h"
+#include "libpspp/taint.h"
+#include "libpspp/i18n.h"
+
+#include "gl/minmax.h"
+#include "gl/xalloc.h"
+
+struct dataset {
+ /* Cases are read from source,
+ their transformation variables are initialized,
+ pass through permanent_trns_chain (which transforms them into
+ the format described by permanent_dict),
+ are written to sink,
+ pass through temporary_trns_chain (which transforms them into
+ the format described by dict),
+ and are finally passed to the procedure. */
+ struct casereader *source;
+ struct caseinit *caseinit;
+ struct trns_chain *permanent_trns_chain;
+ struct dictionary *permanent_dict;
+ struct casewriter *sink;
+ struct trns_chain *temporary_trns_chain;
+ struct dictionary *dict;
+
+ /* Callback which occurs whenever the transformation chain(s) have
+ been modified */
+ transformation_change_callback_func *xform_callback;
+ void *xform_callback_aux;
+
+ /* If true, cases are discarded instead of being written to
+ sink. */
+ bool discard_output;
+
+ /* The transformation chain that the next transformation will be
+ added to. */
+ struct trns_chain *cur_trns_chain;
+
+ /* The case map used to compact a case, if necessary;
+ otherwise a null pointer. */
+ struct case_map *compactor;
+
+ /* Time at which proc was last invoked. */
+ time_t last_proc_invocation;
+
+ /* Cases just before ("lagging") the current one. */
+ int n_lag; /* Number of cases to lag. */
+ struct deque lag; /* Deque of lagged cases. */
+ struct ccase **lag_cases; /* Lagged cases managed by deque. */
+
+ /* Procedure data. */
+ enum
+ {
+ PROC_COMMITTED, /* No procedure in progress. */
+ PROC_OPEN, /* proc_open called, casereader still open. */
+ PROC_CLOSED /* casereader from proc_open destroyed,
+ but proc_commit not yet called. */
+ }
+ proc_state;
+ casenumber cases_written; /* Cases output so far. */
+ bool ok; /* Error status. */
+ struct casereader_shim *shim; /* Shim on proc_open() casereader. */