From: Ben Pfaff Date: Fri, 29 Jul 2022 22:41:35 +0000 (-0700) Subject: work X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp;a=commitdiff_plain;h=4480f216f5be2ba8795bf7fc1594c87da14a69ff work --- diff --git a/src/data/dataset.c b/src/data/dataset.c index c13a941ba8..931d3dcbbf 100644 --- a/src/data/dataset.c +++ b/src/data/dataset.c @@ -1026,15 +1026,14 @@ add_measurement_level_trns_proc__ (struct measurement_level_var *mlv, double val return MEASURE_UNKNOWN; } -static enum trns_result -add_measurement_level_trns_proc (void *mlt_, struct ccase **c, - casenumber case_nr UNUSED) +static void +measurement_level_trns_run (struct measurement_level_trns *mlt, + const struct ccase *c) { - struct measurement_level_trns *mlt = mlt_; for (size_t i = 0; i < mlt->n_vars; ) { struct measurement_level_var *mlv = &mlt->vars[i]; - double value = case_num (*c, mlv->var); + double value = case_num (c, mlv->var); enum measure m = add_measurement_level_trns_proc__ (mlv, value); if (m != MEASURE_UNKNOWN) { @@ -1046,6 +1045,14 @@ add_measurement_level_trns_proc (void *mlt_, struct ccase **c, else i++; } +} + +static enum trns_result +add_measurement_level_trns_proc (void *mlt_, struct ccase **c, + casenumber case_nr UNUSED) +{ + struct measurement_level_trns *mlt = mlt_; + measurement_level_trns_run (mlt, *c); return TRNS_CONTINUE; } @@ -1062,15 +1069,21 @@ add_measurement_level_trns_free__ (struct measurement_level_trns *mlt) free (mlt); } -static bool -add_measurement_level_trns_free (void *mlt_) +static void +measurement_level_trns_commit (struct measurement_level_trns *mlt) { - struct measurement_level_trns *mlt = mlt_; for (size_t i = 0; i < mlt->n_vars; i++) { struct measurement_level_var *mlv = &mlt->vars[i]; var_set_measure (mlv->var, add_measurement_level_var_interpret (mlv)); } +} + +static bool +add_measurement_level_trns_free (void *mlt_) +{ + struct measurement_level_trns *mlt = mlt_; + measurement_level_trns_commit (mlt); add_measurement_level_trns_free__ (mlt); return true; } @@ -1081,8 +1094,8 @@ static const struct trns_class add_measurement_level_trns_class = { .destroy = add_measurement_level_trns_free, }; -static void -add_measurement_level_trns (struct dataset *ds, struct dictionary *dict) +static struct measurement_level_trns * +create_measurement_level_trns (struct dictionary *dict) { struct measurement_level_var *mlvs = NULL; size_t n_mlvs = 0; @@ -1113,14 +1126,22 @@ add_measurement_level_trns (struct dataset *ds, struct dictionary *dict) hmap_init (mlv->values); } if (!n_mlvs) - return; + return NULL; struct measurement_level_trns *mlt = xmalloc (sizeof *mlt); *mlt = (struct measurement_level_trns) { .vars = mlvs, .n_vars = n_mlvs, }; - add_transformation (ds, &add_measurement_level_trns_class, mlt); + return mlt; +} + +static void +add_measurement_level_trns (struct dataset *ds, struct dictionary *dict) +{ + struct measurement_level_trns *mlt = create_measurement_level_trns (dict); + if (mlt) + add_transformation (ds, &add_measurement_level_trns_class, mlt); } static void @@ -1137,6 +1158,40 @@ cancel_measurement_level_trns (struct trns_chain *chain) add_measurement_level_trns_free__ (mlt); chain->n--; } + +bool +measure_guesser_is_needed (struct dataset *ds) +{ + struct measurement_level_trns *mlt + = create_measurement_level_trns (dataset_dict (ds)); + if (mlt) + { + add_measurement_level_trns_free__ (mlt); + return true; + } + return false; +} + +void +measure_guesser_run (struct dataset *ds, const struct casereader *reader) +{ + struct measurement_level_trns *mlt + = create_measurement_level_trns (dataset_dict (ds)); + if (!mlt) + return; + + struct casereader *r = casereader_clone (reader); + while (mlt->n_vars > 0) + { + struct ccase *c = casereader_read (r); + measurement_level_trns_run (mlt, c); + case_unref (c); + } + casereader_destroy (r); + + measurement_level_trns_commit (mlt); + add_measurement_level_trns_free__ (mlt); +} static void dataset_changed__ (struct dataset *ds) diff --git a/src/data/dataset.h b/src/data/dataset.h index 1fe535536f..eaea34f91a 100644 --- a/src/data/dataset.h +++ b/src/data/dataset.h @@ -105,6 +105,9 @@ bool proc_commit (struct dataset *); bool dataset_end_of_command (struct dataset *); +bool measure_guesser_is_needed (struct dataset *); +void measure_guesser_run (struct dataset *, const struct casereader *); + const struct ccase *lagged_case (const struct dataset *ds, int n_before); void dataset_need_lag (struct dataset *ds, int n_before); diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index aa204b4ea5..b2bf14b399 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -5317,7 +5317,8 @@ ctables_table_clear (struct ctables_table *t) } static bool -ctables_execute (struct dataset *ds, struct ctables *ct) +ctables_execute (struct dataset *ds, struct casereader *input, + struct ctables *ct) { for (size_t i = 0; i < ct->n_tables; i++) { @@ -5331,7 +5332,6 @@ ctables_execute (struct dataset *ds, struct ctables *ct) } struct dictionary *dict = dataset_dict (ds); - struct casereader *input = proc_open (ds); struct casegrouper *grouper = (dict_get_split_type (dict) == SPLIT_SEPARATE ? casegrouper_create_splits (input, dict) @@ -5386,8 +5386,7 @@ ctables_execute (struct dataset *ds, struct ctables *ct) ctables_table_clear (t); } } - bool ok = casegrouper_destroy (grouper); - return proc_commit (ds) && ok; + return casegrouper_destroy (grouper); } /* Postcomputes. */ @@ -6022,6 +6021,15 @@ put_title_text (struct string *out, struct substring in, time_t now, int cmd_ctables (struct lexer *lexer, struct dataset *ds) { + struct casereader *input; + if (measure_guesser_is_needed (ds)) + { + input = proc_open (ds); + measure_guesser_run (ds, input); + } + else + input = NULL; + size_t n_vars = dict_get_n_vars (dataset_dict (ds)); enum ctables_vlabel *vlabels = xnmalloc (n_vars, sizeof *vlabels); enum settings_value_show tvars = settings_get_show_variables (); @@ -6750,11 +6758,17 @@ cmd_ctables (struct lexer *lexer, struct dataset *ds) } while (lex_token (lexer) != T_ENDCMD); - bool ok = ctables_execute (ds, ct); + if (!input) + input = proc_open (ds); + bool ok = ctables_execute (ds, input, ct); + ok = proc_commit (ds) && ok; + ctables_destroy (ct); return ok ? CMD_SUCCESS : CMD_FAILURE; error: + if (input) + proc_commit (ds); ctables_destroy (ct); return CMD_FAILURE; } diff --git a/tests/language/stats/ctables.at b/tests/language/stats/ctables.at index d45478f0a1..b1a497db3c 100644 --- a/tests/language/stats/ctables.at +++ b/tests/language/stats/ctables.at @@ -1,10 +1,7 @@ AT_BANNER([CTABLES]) -dnl Features not yet implemented: -dnl -dnl - Preprocessing to distinguish categorical from scale. -dnl dnl Features not yet tested: +dnl - Preprocessing to distinguish categorical from scale. dnl - Parsing (positive and negative) dnl - String variables and values dnl - Testing details of missing value handling in summaries.