X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fvfm.c;h=08e3ca30f1f5818a88b8ea1dddadce283260abfa;hb=8cf495e615e4feca5777f3592de98321d4fcdc0b;hp=797167e6eabaeb91224c001429dcfcb1073627bc;hpb=d5e5cf282cc56899913654a62c425e584acecfb2;p=pspp diff --git a/src/vfm.c b/src/vfm.c index 797167e6ea..08e3ca30f1 100644 --- a/src/vfm.c +++ b/src/vfm.c @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #include #include "vfm.h" @@ -30,10 +30,11 @@ #include "alloc.h" #include "case.h" #include "casefile.h" +#include "command.h" #include "dictionary.h" #include "do-ifP.h" #include "error.h" -#include "expr.h" +#include "expressions/public.h" #include "misc.h" #include "settings.h" #include "som.h" @@ -42,6 +43,9 @@ #include "var.h" #include "value-labels.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + /* Virtual File Manager (vfm): @@ -95,7 +99,6 @@ static int execute_transformations (struct ccase *c, int case_num); static int filter_case (const struct ccase *c, int case_num); static void lag_case (const struct ccase *c); -static void compact_case (struct ccase *dest, const struct ccase *src); static void clear_case (struct ccase *c); static void close_active_file (void); @@ -224,7 +227,7 @@ open_active_file (void) 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]); } @@ -260,7 +263,8 @@ write_case (struct write_case_data *wc_data) { if (compaction_necessary) { - compact_case (&wc_data->sink_case, &wc_data->trns_case); + dict_compact_case (temp_dict, &wc_data->sink_case, + &wc_data->trns_case); vfm_sink->class->write (vfm_sink, &wc_data->sink_case); } else @@ -333,13 +337,13 @@ filter_case (const struct ccase *c, int case_idx) 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; } /* PROCESS IF. */ if (process_if_expr != NULL - && expr_evaluate (process_if_expr, c, case_idx, NULL) != 1.0) + && expr_evaluate_num (process_if_expr, c, case_idx) != 1.0) return 1; return 0; @@ -357,43 +361,6 @@ lag_case (const struct ccase *c) lag_head = 0; } -/* Copies case SRC to case DEST, compacting it in the process. */ -static void -compact_case (struct ccase *dest, const struct ccase *src) -{ - int i; - int nval = 0; - size_t var_cnt; - - assert (compaction_necessary); - - /* Copy all the variables except scratch variables from SRC to - DEST. */ - /* FIXME: this should be temp_dict not default_dict I guess. */ - var_cnt = dict_get_var_cnt (default_dict); - for (i = 0; i < var_cnt; i++) - { - struct variable *v = dict_get_var (default_dict, i); - - if (dict_class_from_id (v->name) == DC_SCRATCH) - continue; - - if (v->type == NUMERIC) - { - case_data_rw (dest, nval)->f = case_num (src, v->fv); - nval++; - } - else - { - int w = DIV_RND_UP (v->width, sizeof (union value)); - - memcpy (case_data_rw (dest, nval), case_str (src, v->fv), - w * sizeof (union value)); - nval += w; - } - } -} - /* Clears the variables in C that need to be cleared between processing cases. */ static void @@ -443,11 +410,8 @@ close_active_file (void) dict_compact_values (default_dict); /* Free data source. */ - if (vfm_source != NULL) - { - free_case_source (vfm_source); - vfm_source = NULL; - } + free_case_source (vfm_source); + vfm_source = NULL; /* Old data sink becomes new data source. */ if (vfm_sink->class->make_source != NULL) @@ -518,7 +482,7 @@ static struct case_source * storage_sink_make_source (struct case_sink *sink) { struct case_source *source - = create_case_source (&storage_source_class, sink->dict, sink->aux); + = create_case_source (&storage_source_class, sink->aux); sink->aux = NULL; return source; } @@ -594,14 +558,14 @@ storage_source_get_casefile (struct case_source *source) } struct case_source * -storage_source_create (struct casefile *cf, const struct dictionary *dict) +storage_source_create (struct casefile *cf) { struct storage_stream_info *info; info = xmalloc (sizeof *info); info->casefile = cf; - return create_case_source (&storage_source_class, dict, info); + return create_case_source (&storage_source_class, info); } /* Null sink. Used by a few procedures that keep track of output @@ -622,7 +586,9 @@ const struct case_sink_class null_sink_class = struct ccase * lagged_case (int n_before) { + assert (n_before >= 1 ); assert (n_before <= n_lag); + if (n_before <= lag_count) { int index = lag_head - n_before; @@ -642,7 +608,7 @@ add_transformation (struct trns_header * trns) if (n_trns >= m_trns) { m_trns += 16; - t_trns = xrealloc (t_trns, sizeof *t_trns * m_trns); + t_trns = xnrealloc (t_trns, m_trns, sizeof *t_trns); } t_trns[n_trns] = trns; trns->index = n_trns++; @@ -661,24 +627,19 @@ cancel_transformations (void) free (t_trns[i]); } n_trns = f_trns = 0; - if (m_trns > 32) - { - free (t_trns); - t_trns=NULL; - m_trns = 0; - } + free (t_trns); + t_trns = NULL; + m_trns = 0; } /* 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, - const struct dictionary *dict, void *aux) { struct case_source *source = xmalloc (sizeof *source); source->class = class; - source->value_cnt = dict_get_next_value_idx (dict); source->aux = aux; return source; } @@ -712,8 +673,8 @@ case_source_is_class (const struct case_source *source, return source != NULL && source->class == class; } -/* Creates a case sink with class CLASS and auxiliary data - AUX. */ +/* 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, @@ -721,8 +682,6 @@ create_case_sink (const struct case_sink_class *class, { struct case_sink *sink = xmalloc (sizeof *sink); sink->class = class; - sink->dict = dict; - sink->idx_to_fv = dict_get_compacted_idx_to_fv (dict); sink->value_cnt = dict_get_compacted_value_cnt (dict); sink->aux = aux; return sink; @@ -736,7 +695,6 @@ free_case_sink (struct case_sink *sink) { if (sink->class->destroy != NULL) sink->class->destroy (sink); - free (sink->idx_to_fv); free (sink); } } @@ -786,10 +744,12 @@ procedure_with_splits (void (*begin_func) (void *aux), split_aux.end_func = end_func; split_aux.func_aux = func_aux; - procedure (procedure_with_splits_callback, &split_aux); - + open_active_file (); + internal_procedure (procedure_with_splits_callback, &split_aux); if (split_aux.case_count > 0 && end_func != NULL) end_func (func_aux); + close_active_file (); + case_destroy (&split_aux.prev_case); } @@ -826,32 +786,9 @@ procedure_with_splits_callback (struct ccase *c, void *split_aux_) static int equal_splits (const struct ccase *a, const struct ccase *b) { - struct variable *const *split; - size_t split_cnt; - size_t i; - - split = dict_get_split_vars (default_dict); - split_cnt = dict_get_split_cnt (default_dict); - for (i = 0; i < split_cnt; i++) - { - struct variable *v = split[i]; - - switch (v->type) - { - case NUMERIC: - if (case_num (a, v->fv) != case_num (b, v->fv)) - return 0; - break; - case ALPHA: - if (memcmp (case_str (a, v->fv), case_str (b, v->fv), v->width)) - return 0; - break; - default: - assert (0); - } - } - - return 1; + return case_compare (a, b, + dict_get_split_vars (default_dict), + dict_get_split_cnt (default_dict)) == 0; } /* Dumps out the values of all the split variables for the case C. */ @@ -971,3 +908,32 @@ multipass_split_output (struct multipass_split_aux_data *aux) 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 = NULL; + + expr_free (process_if_expr); + process_if_expr = NULL; + + cancel_temporary (); + + pgm_state = STATE_INIT; +}