X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fctables.c;h=25908eb65d5fa14626fd3b34e771ef7f2b909645;hb=9574a6c2bf65ddc8ef13d4e942833bc5d4b0d2e0;hp=2833ce6b519911419408066728faa81cf50c375f;hpb=7cd70df07f7e183645853716642810afd4b87bcd;p=pspp diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index 2833ce6b51..25908eb65d 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -1395,6 +1395,7 @@ ctables_destroy (struct ctables *ct) hmap_delete (&ct->postcomputes, &pc->hmap_node); free (pc); } + hmap_destroy (&ct->postcomputes); fmt_settings_uninit (&ct->ctables_formats); pivot_table_look_unref (ct->look); @@ -3893,21 +3894,88 @@ merge_item_compare_3way (const struct merge_item *a, const struct merge_item *b) return strcmp (as_label, bs_label); } -static struct pivot_value * -ctables_category_create_label__ (const struct ctables_category *cat, - const struct variable *var, - const union value *value) +static void +ctables_category_format_number (double number, const struct variable *var, + struct string *s) { - return (cat->type == CCT_TOTAL || cat->type == CCT_SUBTOTAL - ? pivot_value_new_user_text (cat->total_label, SIZE_MAX) - : pivot_value_new_var_value (var, value)); + struct pivot_value *pv = pivot_value_new_var_value ( + var, &(union value) { .f = number }); + pivot_value_format (pv, NULL, s); + pivot_value_destroy (pv); +} + +static void +ctables_category_format_string (struct substring string, + const struct variable *var, struct string *out) +{ + int width = var_get_width (var); + char *s = xmalloc (width); + buf_copy_rpad (s, width, string.string, string.length, ' '); + struct pivot_value *pv = pivot_value_new_var_value ( + var, &(union value) { .s = CHAR_CAST (uint8_t *, s) }); + pivot_value_format (pv, NULL, out); + pivot_value_destroy (pv); + free (s); +} + +static bool +ctables_category_format_label (const struct ctables_category *cat, + const struct variable *var, + struct string *s) +{ + switch (cat->type) + { + case CCT_NUMBER: + ctables_category_format_number (cat->number, var, s); + return true; + + case CCT_STRING: + ctables_category_format_string (cat->string, var, s); + return true; + + case CCT_NRANGE: + ctables_category_format_number (cat->nrange[0], var, s); + ds_put_format (s, " THRU "); + ctables_category_format_number (cat->nrange[1], var, s); + return true; + + case CCT_SRANGE: + ctables_category_format_string (cat->srange[0], var, s); + ds_put_format (s, " THRU "); + ctables_category_format_string (cat->srange[1], var, s); + return true; + + case CCT_MISSING: + ds_put_cstr (s, "MISSING"); + return true; + + case CCT_OTHERNM: + ds_put_cstr (s, "OTHERNM"); + return true; + + case CCT_POSTCOMPUTE: + ds_put_format (s, "&%s", cat->pc->name); + return true; + + case CCT_TOTAL: + case CCT_SUBTOTAL: + ds_put_cstr (s, cat->total_label); + return true; + + case CCT_VALUE: + case CCT_LABEL: + case CCT_FUNCTION: + case CCT_EXCLUDED_MISSING: + return false; + } + + return false; } static struct pivot_value * ctables_postcompute_label (const struct ctables_categories *cats, const struct ctables_category *cat, - const struct variable *var, - const union value *value) + const struct variable *var) { struct substring in = ss_cstr (cat->pc->label); struct substring target = ss_cstr (")LABEL["); @@ -3939,12 +4007,8 @@ ctables_postcompute_label (const struct ctables_categories *cats, goto error; struct ctables_category *cat2 = &cats->cats[idx - 1]; - struct pivot_value *label2 - = ctables_category_create_label__ (cat2, var, value); - char *label2_s = pivot_value_to_string_defaults (label2); - ds_put_cstr (&out, label2_s); - free (label2_s); - pivot_value_destroy (label2); + if (!ctables_category_format_label (cat2, var, &out)) + goto error; } error: @@ -3953,14 +4017,16 @@ error: } static struct pivot_value * -ctables_category_create_label (const struct ctables_categories *cats, - const struct ctables_category *cat, - const struct variable *var, - const union value *value) +ctables_category_create_value_label (const struct ctables_categories *cats, + const struct ctables_category *cat, + const struct variable *var, + const union value *value) { return (cat->type == CCT_POSTCOMPUTE && cat->pc->label - ? ctables_postcompute_label (cats, cat, var, value) - : ctables_category_create_label__ (cat, var, value)); + ? ctables_postcompute_label (cats, cat, var) + : cat->type == CCT_TOTAL || cat->type == CCT_SUBTOTAL + ? pivot_value_new_user_text (cat->total_label, SIZE_MAX) + : pivot_value_new_var_value (var, value)); } static struct ctables_value * @@ -4174,6 +4240,8 @@ ctables_pcexpr_evaluate (const struct ctables_pcexpr_evaluate_ctx *ctx, case CTPO_CAT_NRANGE: case CTPO_CAT_SRANGE: + case CTPO_CAT_MISSING: + case CTPO_CAT_OTHERNM: { struct ctables_cell_value cv = { .category = ctables_find_category_for_postcompute (ctx->section->table->ctables->dict, ctx->cats, ctx->parse_format, e) @@ -4195,8 +4263,6 @@ ctables_pcexpr_evaluate (const struct ctables_pcexpr_evaluate_ctx *ctx, } case CTPO_CAT_NUMBER: - case CTPO_CAT_MISSING: - case CTPO_CAT_OTHERNM: case CTPO_CAT_SUBTOTAL: case CTPO_CAT_TOTAL: { @@ -4359,11 +4425,26 @@ ctables_format (double d, const struct fmt_spec *format, return s; } +static bool +all_hidden_vlabels (const struct ctables_table *t, enum pivot_axis_type a) +{ + for (size_t i = 0; i < t->stacks[a].n; i++) + { + struct ctables_nest *nest = &t->stacks[a].nests[i]; + if (nest->n != 1 || nest->scale_idx != 0) + return false; + + enum ctables_vlabel vlabel + = t->ctables->vlabels[var_get_dict_index (nest->vars[0])]; + if (vlabel != CTVL_NONE) + return false; + } + return true; +} + static void ctables_table_output (struct ctables *ct, struct ctables_table *t) { - printf ("\n"); - struct pivot_table *pt = pivot_table_create__ ( (t->title ? pivot_value_new_user_text (t->title, SIZE_MAX) @@ -4381,7 +4462,6 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) && t->summary_specs.n > 1)); if (summary_dimension) { - printf ("summary_dimension\n"); struct pivot_dimension *d = pivot_dimension_create ( pt, t->slabels_axis, N_("Statistics")); const struct ctables_summary_spec_set *specs = &t->summary_specs; @@ -4395,7 +4475,6 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) bool categories_dimension = t->clabels_example != NULL; if (categories_dimension) { - printf ("categories_dimension\n"); struct pivot_dimension *d = pivot_dimension_create ( pt, t->label_axis[t->clabels_from_axis], t->clabels_from_axis == PIVOT_AXIS_ROW @@ -4408,9 +4487,10 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) const struct ctables_value *value = t->clabels_values[i]; const struct ctables_category *cat = ctables_categories_match (c, &value->value, var); assert (cat != NULL); - pivot_category_create_leaf (d->root, ctables_category_create_label ( - c, cat, t->clabels_example, - &value->value)); + pivot_category_create_leaf ( + d->root, ctables_category_create_value_label (c, cat, + t->clabels_example, + &value->value)); } } @@ -4418,9 +4498,17 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) struct pivot_dimension *d[PIVOT_N_AXES]; for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++) { - d[a] = NULL; - if (!t->axes[a] && a != t->summary_axis) + static const char *names[] = { + [PIVOT_AXIS_ROW] = N_("Rows"), + [PIVOT_AXIS_COLUMN] = N_("Columns"), + [PIVOT_AXIS_LAYER] = N_("Layers"), + }; + d[a] = (t->axes[a] || a == t->summary_axis + ? pivot_dimension_create (pt, a, names[a]) + : NULL); + if (!d[a]) continue; + assert (t->axes[a]); for (size_t i = 0; i < t->stacks[a].n; i++) @@ -4505,6 +4593,8 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) for (size_t k = 0; k < nest->n; k++) { enum ctables_vlabel vlabel = ct->vlabels[var_get_dict_index (nest->vars[k])]; + if (vlabel == CTVL_NONE && nest->scale_idx == k) + vlabel = CTVL_NAME; if (vlabel != CTVL_NONE) { levels[n_levels++] = (struct ctables_level) { @@ -4532,17 +4622,6 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) }; } - if (!n_levels) - goto next_free; - - static const char *names[] = { - [PIVOT_AXIS_ROW] = N_("Rows"), - [PIVOT_AXIS_COLUMN] = N_("Columns"), - [PIVOT_AXIS_LAYER] = N_("Layers"), - }; - d[a] = pivot_dimension_create (pt, a, names[a]); - printf ("%s dimension\n", names[a]); - /* Pivot categories: - variable label for nest->vars[0], if vlabel != CTVL_NONE @@ -4624,7 +4703,7 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) else if (level->type == CTL_CATEGORY) { const struct ctables_cell_value *cv = &cell->axes[a].cvs[level->var_idx]; - label = ctables_category_create_label ( + label = ctables_category_create_value_label ( t->categories[var_get_dict_index (var)], cv->category, var, &cv->value); } @@ -4640,12 +4719,14 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) cell->axes[a].leaf = prev_leaf; } - free (groups); - next_free: free (sorted); + free (groups); free (levels); free (sections); + } + + d[a]->hide_all_labels = all_hidden_vlabels (t, a); } {