X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fctables.c;fp=src%2Flanguage%2Fstats%2Fctables.c;h=a29361cc3cc3be987e7d67ab5be8703c596243eb;hb=2ec7a9fa319816227df1684cd32206fcec77d55c;hp=ee35fd6bd3e790ba6a17446ed30139769819e97b;hpb=8498b2dd663b876b075b7a20f727d57b1a17d5cb;p=pspp diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index ee35fd6bd3..a29361cc3c 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -733,7 +733,7 @@ ctables_summary_spec_clone (struct ctables_summary_spec *dst, const struct ctables_summary_spec *src) { *dst = *src; - dst->label = xstrdup (src->label); + dst->label = xstrdup_if_nonnull (src->label); } static void @@ -3546,6 +3546,7 @@ struct ctables_pcexpr_evaluate_ctx const struct ctables_categories *cats; enum pivot_axis_type pc_a; size_t pc_a_idx; + size_t summary_idx; }; static double ctables_pcexpr_evaluate ( @@ -3626,8 +3627,8 @@ found: ; const struct ctables_table *t = s->table; const struct ctables_nest *specs_nest = s->nests[t->summary_axis]; const struct ctables_summary_spec_set *specs = &specs_nest->specs[tc->sv]; - size_t j = 0 /* XXX */; - return ctables_summary_value (tc, &tc->summaries[j], &specs->specs[j]); + return ctables_summary_value (tc, &tc->summaries[ctx->summary_idx], + &specs->specs[ctx->summary_idx]); } static double @@ -3697,27 +3698,61 @@ ctables_pcexpr_evaluate (const struct ctables_pcexpr_evaluate_ctx *ctx, NOT_REACHED (); } +/* XXX what if there is a postcompute in more than one dimension?? */ +static const struct ctables_postcompute * +ctables_cell_postcompute (const struct ctables_section *s, + const struct ctables_cell *cell, + enum pivot_axis_type *pc_a_p, + size_t *pc_a_idx_p) +{ + assert (cell->postcompute); + for (enum pivot_axis_type pc_a = 0; ; pc_a++) + { + assert (pc_a < PIVOT_N_AXES); + for (size_t pc_a_idx = 0; pc_a_idx < s->nests[pc_a]->n; pc_a_idx++) + { + const struct ctables_cell_value *cv = &cell->axes[pc_a].cvs[pc_a_idx]; + if (cv->category->type == CCT_POSTCOMPUTE) + { + if (pc_a_p) + *pc_a_p = pc_a; + if (pc_a_idx_p) + *pc_a_idx_p = pc_a_idx; + return cv->category->pc; + } + } + } + + NOT_REACHED (); +} + static double ctables_cell_calculate_postcompute (const struct ctables_section *s, - const struct ctables_cell *cell) + const struct ctables_cell *cell, + const struct ctables_summary_spec *ss, + struct fmt_spec *format, + bool *is_ctables_format, + size_t summary_idx) { enum pivot_axis_type pc_a; size_t pc_a_idx; - const struct ctables_postcompute *pc; - for (pc_a = 0; ; pc_a++) + const struct ctables_postcompute *pc = ctables_cell_postcompute ( + s, cell, &pc_a, &pc_a_idx); + + if (pc->specs) { - assert (pc_a < PIVOT_N_AXES); - for (pc_a_idx = 0; pc_a_idx < s->nests[pc_a]->n; pc_a_idx++) + for (size_t i = 0; i < pc->specs->n; i++) { - const struct ctables_cell_value *cv = &cell->axes[pc_a].cvs[pc_a_idx]; - if (cv->category->type == CCT_POSTCOMPUTE) + const struct ctables_summary_spec *ss2 = &pc->specs->specs[i]; + if (ss->function == ss2->function + && ss->percentile == ss2->percentile) { - pc = cv->category->pc; - goto found; + *format = ss2->format; + *is_ctables_format = ss2->is_ctables_format; + break; } } } -found: ; const struct variable *var = s->nests[pc_a]->vars[pc_a_idx]; const struct ctables_categories *cats = s->table->categories[ @@ -3728,6 +3763,7 @@ found: ; .cats = cats, .pc_a = pc_a, .pc_a_idx = pc_a_idx, + .summary_idx = summary_idx, }; return ctables_pcexpr_evaluate (&ctx, pc->expr); } @@ -4034,15 +4070,18 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) const struct ctables_summary_spec *ss = &specs->specs[j]; + struct fmt_spec format = specs->specs[j].format; + bool is_ctables_format = ss->is_ctables_format; double d = (cell->postcompute - ? ctables_cell_calculate_postcompute (s, cell) - : ctables_summary_value (cell, &cell->summaries[j], ss)); + ? ctables_cell_calculate_postcompute ( + s, cell, ss, &format, &is_ctables_format, j) + : ctables_summary_value (cell, &cell->summaries[j], + ss)); + struct pivot_value *value; if (ct->hide_threshold != 0 && d < ct->hide_threshold - && (cell->postcompute - ? false /* XXX */ - : ctables_summary_function_is_count (ss->function))) + && ctables_summary_function_is_count (ss->function)) { value = pivot_value_new_user_text_nocopy ( xasprintf ("<%d", ct->hide_threshold)); @@ -4051,18 +4090,17 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) value = pivot_value_new_user_text (ct->zero, SIZE_MAX); else if (d == SYSMIS && ct->missing) value = pivot_value_new_user_text (ct->missing, SIZE_MAX); - else if (specs->specs[j].is_ctables_format) + else if (is_ctables_format) { char *s = data_out_stretchy (&(union value) { .f = d }, - "UTF-8", - &specs->specs[j].format, + "UTF-8", &format, &ct->ctables_formats, NULL); value = pivot_value_new_user_text_nocopy (s); } else { value = pivot_value_new_number (d); - value->numeric.format = specs->specs[j].format; + value->numeric.format = format; } pivot_table_put (pt, dindexes, n_dindexes, value); } @@ -5038,9 +5076,8 @@ ctables_parse_pproperties_format (struct lexer *lexer, /* Parse format. */ struct fmt_spec format; - if (!parse_format_specifier (lexer, &format) - || !fmt_check_output (&format) - || !fmt_check_type_compat (&format, VAL_NUMERIC)) + bool is_ctables_format; + if (!parse_ctables_format_specifier (lexer, &format, &is_ctables_format)) goto error; if (sss->n >= sss->allocated) @@ -5050,6 +5087,7 @@ ctables_parse_pproperties_format (struct lexer *lexer, .function = function, .percentile = percentile, .format = format, + .is_ctables_format = is_ctables_format, }; } return true;