/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 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 "data/casereader-provider.h"
#include "data/casereader-shim.h"
#include "data/casewriter.h"
+#include "data/control-stack.h"
#include "data/dictionary.h"
#include "data/file-handle-def.h"
#include "data/session.h"
dataset_clear (ds);
dict_destroy (ds->dict);
caseinit_destroy (ds->caseinit);
+ ctl_stack_clear ();
trns_chain_destroy (ds->permanent_trns_chain);
dataset_transformations_changed__ (ds, false);
free (ds->name);
add_case_limit_trns (ds);
if (filter)
add_filter_trns (ds);
- trns_chain_finalize (ds->cur_trns_chain);
+ ctl_stack_clear ();
/* Make permanent_dict refer to the dictionary right before
data reaches the sink. */
void
add_transformation (struct dataset *ds, trns_proc_func *proc, trns_free_func *free, void *aux)
{
- trns_chain_append (ds->cur_trns_chain, NULL, proc, free, aux);
- dataset_transformations_changed__ (ds, true);
-}
-
-/* Adds a transformation that processes a case with PROC and
- frees itself with FREE to the current set of transformations.
- When parsing of the block of transformations is complete,
- FINALIZE will be called.
- The functions are passed AUX as auxiliary data. */
-void
-add_transformation_with_finalizer (struct dataset *ds,
- trns_finalize_func *finalize,
- trns_proc_func *proc,
- trns_free_func *free, void *aux)
-{
- trns_chain_append (ds->cur_trns_chain, finalize, proc, free, aux);
+ trns_chain_append (ds->cur_trns_chain, proc, free, aux);
dataset_transformations_changed__ (ds, true);
}
ds->permanent_dict = dict_clone (ds->dict);
- trns_chain_finalize (ds->permanent_trns_chain);
+ ctl_stack_clear ();
ds->temporary_trns_chain = ds->cur_trns_chain = trns_chain_create ();
dataset_transformations_changed__ (ds, true);
}
}
-/* Converts all the temporary transformations, if any, to
- permanent transformations. Further transformations will be
- permanent.
+/* Converts all the temporary transformations, if any, to permanent
+ transformations. Further transformations will be permanent.
+
+ The FILTER command is implemented as a temporary transformation, so a
+ procedure that uses this function should usually use proc_open_filtering()
+ with FILTER false, instead of plain proc_open().
+
Returns true if anything changed, false otherwise. */
bool
proc_make_temporary_transformations_permanent (struct dataset *ds)
{
if (proc_in_temporary_transformations (ds))
{
- trns_chain_finalize (ds->temporary_trns_chain);
+ ctl_stack_clear ();
trns_chain_splice (ds->permanent_trns_chain, ds->temporary_trns_chain);
ds->temporary_trns_chain = NULL;
+ ds->cur_trns_chain = ds->permanent_trns_chain;
+
dict_destroy (ds->permanent_dict);
ds->permanent_dict = NULL;
ds->dict = ds->permanent_dict;
ds->permanent_dict = NULL;
+ ctl_stack_clear ();
trns_chain_destroy (ds->temporary_trns_chain);
ds->temporary_trns_chain = NULL;
dataset_transformations_changed__ (
{
bool ok;
assert (ds->proc_state == PROC_COMMITTED);
+ ctl_stack_clear ();
ok = trns_chain_destroy (ds->permanent_trns_chain);
ok = trns_chain_destroy (ds->temporary_trns_chain) && ok;
ds->permanent_trns_chain = ds->cur_trns_chain = trns_chain_create ();
return ok;
}
+
+static int
+store_case_num (void *var_, struct ccase **cc, casenumber case_num)
+{
+ struct variable *var = var_;
+
+ *cc = case_unshare (*cc);
+ case_data_rw (*cc, var)->f = case_num;
+
+ return TRNS_CONTINUE;
+}
+
+/* Add a variable which we can sort by to get back the original order. */
+struct variable *
+add_permanent_ordering_transformation (struct dataset *ds)
+{
+ struct variable *temp_var;
+
+ temp_var = dict_create_var_assert (ds->dict, "$ORDER", 0);
+ if (proc_in_temporary_transformations (ds))
+ {
+ struct variable *perm_var;
+
+ perm_var = dict_clone_var_in_place_assert (ds->permanent_dict, temp_var);
+ trns_chain_append (ds->permanent_trns_chain, NULL, store_case_num,
+ NULL, perm_var);
+ trns_chain_finalize (ds->permanent_trns_chain);
+ }
+ else
+ add_transformation (ds, store_case_num, NULL, temp_var);
+
+ return temp_var;
+}
\f
/* Causes output from the next procedure to be discarded, instead
of being preserved for use as input for the next procedure. */