From c40b1abf21793c5923d2c8e8be320eb1c97a9240 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 14 Jan 2022 21:56:35 -0800 Subject: [PATCH] Make all the spec_sets distinct. --- src/language/stats/ctables.c | 64 ++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index e572429606..a6de212483 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -293,6 +293,8 @@ struct ctables_summary_spec_set struct variable *var; }; +static void ctables_summary_spec_set_clone (struct ctables_summary_spec_set *, + const struct ctables_summary_spec_set *); static void ctables_summary_spec_set_uninit (struct ctables_summary_spec_set *); /* A nested sequence of variables, e.g. a > b > c. */ @@ -540,6 +542,14 @@ struct ctables_summary_spec struct fmt_spec format; /* XXX extra CTABLES formats */ }; +static void +ctables_summary_spec_clone (struct ctables_summary_spec *dst, + const struct ctables_summary_spec *src) +{ + *dst = *src; + dst->label = xstrdup (src->label); +} + static void ctables_summary_spec_uninit (struct ctables_summary_spec *s) { @@ -547,6 +557,22 @@ ctables_summary_spec_uninit (struct ctables_summary_spec *s) free (s->label); } +static void +ctables_summary_spec_set_clone (struct ctables_summary_spec_set *dst, + const struct ctables_summary_spec_set *src) +{ + struct ctables_summary_spec *specs = xnmalloc (src->n, sizeof *specs); + for (size_t i = 0; i < src->n; i++) + ctables_summary_spec_clone (&specs[i], &src->specs[i]); + + *dst = (struct ctables_summary_spec_set) { + .specs = specs, + .n = src->n, + .allocated = src->n, + .var = src->var + }; +} + static void ctables_summary_spec_set_uninit (struct ctables_summary_spec_set *set) { @@ -1491,17 +1517,17 @@ nest_fts (struct ctables_stack s0, struct ctables_stack s1) summary_src = a; else NOT_REACHED (); - stack.nests[stack.n++] = (struct ctables_nest) { + + struct ctables_nest *new = &stack.nests[stack.n++]; + *new = (struct ctables_nest) { .vars = vars, .scale_idx = (a->scale_idx != SIZE_MAX ? a->scale_idx : b->scale_idx != SIZE_MAX ? a->n + b->scale_idx : SIZE_MAX), .n = n, - .specs = { - [CSV_CELL] = summary_src->specs[CSV_CELL], - [CSV_TOTAL] = summary_src->specs[CSV_TOTAL], - }, }; + for (enum ctables_summary_variant sv = 0; sv < N_CSVS; sv++) + ctables_summary_spec_set_clone (&new->specs[sv], &summary_src->specs[sv]); } ctables_stack_uninit (&s0); ctables_stack_uninit (&s1); @@ -1543,10 +1569,10 @@ enumerate_fts (enum pivot_axis_type axis_type, const struct ctables_axis *a) .scale_idx = a->scale ? 0 : SIZE_MAX, }; if (a->specs[CSV_CELL].n || a->scale) - for (size_t i = 0; i < N_CSVS; i++) + for (enum ctables_summary_variant sv = 0; sv < N_CSVS; sv++) { - nest->specs[i] = a->specs[i]; - nest->specs[i].var = a->var.var; + ctables_summary_spec_set_clone (&nest->specs[sv], &a->specs[sv]); + nest->specs[sv].var = a->var.var; } return (struct ctables_stack) { .nests = nest, .n = 1 }; @@ -2480,26 +2506,28 @@ ctables_execute (struct dataset *ds, struct ctables *ct) struct ctables_nest *nest = &t->stacks[t->summary_axis].nests[i]; if (!nest->specs[CSV_CELL].n) { - struct ctables_summary_spec_set *sss = &nest->specs[CSV_CELL]; - sss->specs = xmalloc (sizeof *sss->specs); - sss->n = 1; + struct ctables_summary_spec_set *specs = &nest->specs[CSV_CELL]; + specs->specs = xmalloc (sizeof *specs->specs); + specs->n = 1; enum ctables_summary_function function - = sss->var ? CTSF_MEAN : CTSF_COUNT; - struct ctables_var var = { .is_mrset = false, .var = sss->var }; + = specs->var ? CTSF_MEAN : CTSF_COUNT; + struct ctables_var var = { .is_mrset = false, .var = specs->var }; - *sss->specs = (struct ctables_summary_spec) { + *specs->specs = (struct ctables_summary_spec) { .function = function, .format = ctables_summary_default_format (function, &var), .label = ctables_summary_default_label (function, 0), }; - if (!sss->var) - sss->var = nest->vars[0]; + if (!specs->var) + specs->var = nest->vars[0]; - nest->specs[CSV_TOTAL] = nest->specs[CSV_CELL]; + ctables_summary_spec_set_clone (&nest->specs[CSV_TOTAL], + &nest->specs[CSV_CELL]); } else if (!nest->specs[CSV_TOTAL].n) - nest->specs[CSV_TOTAL] = nest->specs[CSV_CELL]; + ctables_summary_spec_set_clone (&nest->specs[CSV_TOTAL], + &nest->specs[CSV_CELL]); } } -- 2.30.2