#include "alloc.h"
#include "case.h"
#include "casefile.h"
+#include "command.h"
#include "dictionary.h"
-#include "do-ifP.h"
+#include "ctl-stack.h"
#include "error.h"
#include "expressions/public.h"
#include "misc.h"
#include "var.h"
#include "value-labels.h"
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
/*
Virtual File Manager (vfm):
static int compaction_necessary;
/* Time at which vfm was last invoked. */
-time_t last_vfm_invocation;
+static time_t last_vfm_invocation;
/* Lag queue. */
int n_lag; /* Number of cases to lag. */
static void internal_procedure (int (*proc_func) (struct ccase *, void *),
void *aux);
+static void update_last_vfm_invocation (void);
static void create_trns_case (struct ccase *, struct dictionary *);
static void open_active_file (void);
static int write_case (struct write_case_data *wc_data);
static int execute_transformations (struct ccase *c,
- struct trns_header **trns,
+ struct transformation *trns,
int first_idx, int last_idx,
int case_num);
static int filter_case (const struct ccase *c, int case_num);
\f
/* Public functions. */
+/* Returns the last time the data was read. */
+time_t
+vfm_last_invocation (void)
+{
+ if (last_vfm_invocation == 0)
+ update_last_vfm_invocation ();
+ return last_vfm_invocation;
+}
+
/* Reads the data from the input program and writes it to a new
active file. For each case we read from the input program, we
do the following
&& n_trns == 0)
{
/* Nothing to do. */
+ update_last_vfm_invocation ();
return;
}
case_create (&wc_data.sink_case, dict_get_next_value_idx (default_dict));
wc_data.cases_written = 0;
- last_vfm_invocation = time (NULL);
+ update_last_vfm_invocation ();
if (vfm_source != NULL)
vfm_source->class->read (vfm_source,
assert (--recursive_call == 0);
}
+/* Updates last_vfm_invocation. */
+static void
+update_last_vfm_invocation (void)
+{
+ last_vfm_invocation = time (NULL);
+}
+
/* Creates and returns a case, initializing it from the vectors
that say which `value's need to be initialized just once, and
which ones need to be re-initialized before every case. */
lag_count = 0;
lag_head = 0;
- lag_queue = xmalloc (n_lag * sizeof *lag_queue);
+ lag_queue = xnmalloc (n_lag, sizeof *lag_queue);
for (i = 0; i < n_lag; i++)
case_nullify (&lag_queue[i]);
}
/* Close any unclosed DO IF or LOOP constructs. */
- discard_ctl_stack ();
+ ctl_stack_clear ();
}
/* Transforms trns_case and writes it to the replacement active
transformations, nonzero otherwise. */
static int
execute_transformations (struct ccase *c,
- struct trns_header **trns,
+ struct transformation *trns,
int first_idx, int last_idx,
int case_num)
{
for (idx = first_idx; idx != last_idx; )
{
- int retval = trns[idx]->proc (trns[idx], c, case_num);
+ struct transformation *t = &trns[idx];
+ int retval = t->proc (t->private, c, case_num);
switch (retval)
{
case -1:
if (filter_var != NULL)
{
double f = case_num (c, filter_var->fv);
- if (f == 0.0 || f == SYSMIS || is_num_user_missing (f, filter_var))
+ if (f == 0.0 || mv_is_num_missing (&filter_var->miss, f))
return 1;
}
/* Appends TRNS to t_trns[], the list of all transformations to be
performed on data as it is read from the active file. */
void
-add_transformation (struct trns_header * trns)
+add_transformation (trns_proc_func *proc, trns_free_func *free, void *private)
{
+ struct transformation *trns;
if (n_trns >= m_trns)
- {
- m_trns += 16;
- t_trns = xrealloc (t_trns, sizeof *t_trns * m_trns);
- }
- t_trns[n_trns] = trns;
- trns->index = n_trns++;
+ t_trns = x2nrealloc (t_trns, &m_trns, sizeof *t_trns);
+ trns = &t_trns[n_trns++];
+ trns->proc = proc;
+ trns->free = free;
+ trns->private = private;
+}
+
+/* Returns the index number that the next transformation added by
+ add_transformation() will receive. A trns_proc_func that
+ returns this index causes control flow to jump to it. */
+size_t
+next_transformation (void)
+{
+ return n_trns;
}
/* Cancels all active transformations, including any transformations
void
cancel_transformations (void)
{
- int i;
+ size_t i;
for (i = 0; i < n_trns; i++)
{
- if (t_trns[i]->free)
- t_trns[i]->free (t_trns[i]);
- free (t_trns[i]);
+ struct transformation *t = &t_trns[i];
+ if (t->free != NULL)
+ t->free (t->private);
}
n_trns = f_trns = 0;
free (t_trns);
casefile_destroy (aux->casefile);
aux->casefile = NULL;
}
+
+
+/* Discards all the current state in preparation for a data-input
+ command like DATA LIST or GET. */
+void
+discard_variables (void)
+{
+ dict_clear (default_dict);
+ default_handle = NULL;
+
+ n_lag = 0;
+
+ if (vfm_source != NULL)
+ {
+ free_case_source (vfm_source);
+ vfm_source = NULL;
+ }
+
+ cancel_transformations ();
+
+ ctl_stack_clear ();
+
+ expr_free (process_if_expr);
+ process_if_expr = NULL;
+
+ cancel_temporary ();
+
+ pgm_state = STATE_INIT;
+}