X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fprocedure.c;h=67f22c5c0dfca5a0e0442feb0a8888973bd222a1;hb=147ca04d11f632e63cef3ce395b471a12897f5f9;hp=69665c8b1b3c9c845fb5d2defe3646a26d64acf4;hpb=83141cdd4ab281da80d5dfeda05073f0cb354eab;p=pspp-builds.git diff --git a/src/procedure.c b/src/procedure.c index 69665c8b..67f22c5c 100644 --- a/src/procedure.c +++ b/src/procedure.c @@ -18,28 +18,32 @@ 02110-1301, USA. */ #include + #include -#include + #include #include #include #include -#include + +#include "expressions/public.h" +#include +#include #include #include -#include #include +#include +#include +#include +#include +#include #include +#include #include -#include "expressions/public.h" -#include #include -#include +#include #include #include -#include -#include -#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -80,6 +84,10 @@ static struct dict_compactor *compactor; /* Time at which vfm was last invoked. */ static time_t last_vfm_invocation; +/* Whether we're inside a procedure. + For debugging purposes only. */ +static bool in_procedure; + /* Lag queue. */ int n_lag; /* Number of cases to lag. */ static int lag_count; /* Number of cases in lag_queue so far. */ @@ -109,7 +117,7 @@ static bool close_active_file (void); /* Returns the last time the data was read. */ time_t -vfm_last_invocation (void) +time_of_last_procedure (void) { if (last_vfm_invocation == 0) update_last_vfm_invocation (); @@ -173,12 +181,9 @@ procedure (bool (*proc_func) (struct ccase *, void *), void *aux) static bool internal_procedure (bool (*proc_func) (struct ccase *, void *), void *aux) { - static int recursive_call; struct write_case_data wc_data; bool ok; - assert (++recursive_call == 1); - wc_data.proc_func = proc_func; wc_data.aux = aux; create_trns_case (&wc_data.trns_case, default_dict); @@ -195,8 +200,6 @@ internal_procedure (bool (*proc_func) (struct ccase *, void *), void *aux) case_destroy (&wc_data.sink_case); case_destroy (&wc_data.trns_case); - assert (--recursive_call == 0); - return ok; } @@ -223,7 +226,7 @@ create_trns_case (struct ccase *trns_case, struct dictionary *dict) union value *value = case_data_rw (trns_case, v->fv); if (v->type == NUMERIC) - value->f = v->reinit ? 0.0 : SYSMIS; + value->f = v->leave ? 0.0 : SYSMIS; else memset (value->s, ' ', v->width); } @@ -234,6 +237,9 @@ create_trns_case (struct ccase *trns_case, struct dictionary *dict) static void open_active_file (void) { + assert (!in_procedure); + in_procedure = true; + /* Make temp_dict refer to the dictionary right before data reaches the sink */ if (!temporary) @@ -270,9 +276,9 @@ open_active_file (void) } /* Transforms trns_case and writes it to the replacement active - file if advisable. Returns nonzero if more cases can be - accepted, zero otherwise. Do not call this function again - after it has returned zero once. */ + file if advisable. Returns true if more cases can be + accepted, false otherwise. Do not call this function again + after it has returned false once. */ static bool write_case (struct write_case_data *wc_data) { @@ -376,7 +382,7 @@ execute_transformations (struct ccase *c, } /* Returns nonzero if case C with case number CASE_NUM should be - exclude as specified on FILTER or PROCESS IF, otherwise + excluded as specified on FILTER or PROCESS IF, otherwise zero. */ static int filter_case (const struct ccase *c, int case_idx) @@ -421,7 +427,7 @@ clear_case (struct ccase *c) for (i = 0; i < var_cnt; i++) { struct variable *v = dict_get_var (default_dict, i); - if (v->reinit) + if (!v->leave) { if (v->type == NUMERIC) case_data_rw (c, v->fv)->f = SYSMIS; @@ -478,163 +484,13 @@ close_active_file (void) process_if_expr = NULL; dict_set_case_limit (default_dict, 0); dict_clear_vectors (default_dict); - return cancel_transformations (); -} - -/* Storage case stream. */ - -/* Information about storage sink or source. */ -struct storage_stream_info - { - struct casefile *casefile; /* Storage. */ - }; - -/* Initializes a storage sink. */ -static void -storage_sink_open (struct case_sink *sink) -{ - struct storage_stream_info *info; - - sink->aux = info = xmalloc (sizeof *info); - info->casefile = casefile_create (sink->value_cnt); -} - -/* Destroys storage stream represented by INFO. */ -static void -destroy_storage_stream_info (struct storage_stream_info *info) -{ - if (info != NULL) - { - casefile_destroy (info->casefile); - free (info); - } -} - -/* Writes case C to the storage sink SINK. - Returns true if successful, false if an I/O error occurred. */ -static bool -storage_sink_write (struct case_sink *sink, const struct ccase *c) -{ - struct storage_stream_info *info = sink->aux; - - return casefile_append (info->casefile, c); -} - -/* Destroys internal data in SINK. */ -static void -storage_sink_destroy (struct case_sink *sink) -{ - destroy_storage_stream_info (sink->aux); -} - -/* Closes the sink and returns a storage source to read back the - written data. */ -static struct case_source * -storage_sink_make_source (struct case_sink *sink) -{ - struct case_source *source - = create_case_source (&storage_source_class, sink->aux); - sink->aux = NULL; - return source; -} - -/* Storage sink. */ -const struct case_sink_class storage_sink_class = - { - "storage", - storage_sink_open, - storage_sink_write, - storage_sink_destroy, - storage_sink_make_source, - }; - -/* Storage source. */ -/* Returns the number of cases that will be read by - storage_source_read(). */ -static int -storage_source_count (const struct case_source *source) -{ - struct storage_stream_info *info = source->aux; - - return casefile_get_case_cnt (info->casefile); -} - -/* Reads all cases from the storage source and passes them one by one to - write_case(). */ -static bool -storage_source_read (struct case_source *source, - struct ccase *output_case, - write_case_func *write_case, write_case_data wc_data) -{ - struct storage_stream_info *info = source->aux; - struct ccase casefile_case; - struct casereader *reader; - bool ok = true; - - for (reader = casefile_get_reader (info->casefile); - ok && casereader_read (reader, &casefile_case); - case_destroy (&casefile_case)) - { - case_copy (output_case, 0, - &casefile_case, 0, - casefile_get_value_cnt (info->casefile)); - ok = write_case (wc_data); - } - casereader_destroy (reader); - - return ok; -} - -/* Destroys the source's internal data. */ -static void -storage_source_destroy (struct case_source *source) -{ - destroy_storage_stream_info (source->aux); -} - -/* Storage source. */ -const struct case_source_class storage_source_class = - { - "storage", - storage_source_count, - storage_source_read, - storage_source_destroy, - }; - -struct casefile * -storage_source_get_casefile (struct case_source *source) -{ - struct storage_stream_info *info = source->aux; - - assert (source->class == &storage_source_class); - return info->casefile; -} - -struct case_source * -storage_source_create (struct casefile *cf) -{ - struct storage_stream_info *info; - - info = xmalloc (sizeof *info); - info->casefile = cf; + assert (in_procedure); + in_procedure = false; - return create_case_source (&storage_source_class, info); + return cancel_transformations (); } -/* Null sink. Used by a few procedures that keep track of output - themselves and would throw away anything that the sink - contained anyway. */ - -const struct case_sink_class null_sink_class = - { - "null", - NULL, - NULL, - NULL, - NULL, - }; - /* Returns a pointer to the lagged case from N_BEFORE cases before the current one, or NULL if there haven't been that many cases yet. */ struct ccase * @@ -660,6 +516,9 @@ void add_transformation (trns_proc_func *proc, trns_free_func *free, void *private) { struct transformation *trns; + + assert (!in_procedure); + if (n_trns >= m_trns) t_trns = x2nrealloc (t_trns, &m_trns, sizeof *t_trns); trns = &t_trns[n_trns++]; @@ -701,65 +560,6 @@ cancel_transformations (void) return ok; } -/* Creates a case source with class CLASS and auxiliary data AUX - and based on dictionary DICT. */ -struct case_source * -create_case_source (const struct case_source_class *class, - void *aux) -{ - struct case_source *source = xmalloc (sizeof *source); - source->class = class; - source->aux = aux; - return source; -} - -/* Destroys case source SOURCE. It is the caller's responsible to - call the source's destroy function, if any. */ -void -free_case_source (struct case_source *source) -{ - if (source != NULL) - { - if (source->class->destroy != NULL) - source->class->destroy (source); - free (source); - } -} - -/* Returns nonzero if CLASS is the class of SOURCE. */ -int -case_source_is_class (const struct case_source *source, - const struct case_source_class *class) -{ - return source != NULL && source->class == class; -} - -/* Creates a case sink to accept cases from the given DICT with - class CLASS and auxiliary data AUX. */ -struct case_sink * -create_case_sink (const struct case_sink_class *class, - const struct dictionary *dict, - void *aux) -{ - struct case_sink *sink = xmalloc (sizeof *sink); - sink->class = class; - sink->value_cnt = dict_get_compacted_value_cnt (dict); - sink->aux = aux; - return sink; -} - -/* Destroys case sink SINK. */ -void -free_case_sink (struct case_sink *sink) -{ - if (sink != NULL) - { - if (sink->class->destroy != NULL) - sink->class->destroy (sink); - free (sink); - } -} - /* Represents auxiliary data for handling SPLIT FILE. */ struct split_aux_data {