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=ee35fd6bd3e790ba6a17446ed30139769819e97b;hb=8498b2dd663b876b075b7a20f727d57b1a17d5cb;hp=072b9f83a8d4f688d65c2a095f4498e454597f5a;hpb=ec2799682bc9aeefb092b7204f419fb46547b8b6;p=pspp diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index 072b9f83a8..ee35fd6bd3 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -3363,17 +3363,75 @@ merge_item_compare_3way (const struct merge_item *a, const struct merge_item *b) } static struct pivot_value * -ctables_category_create_label (const struct ctables_category *cat, - const struct variable *var, - const union value *value) +ctables_category_create_label__ (const struct ctables_category *cat, + const struct variable *var, + const union value *value) { return (cat->type == CCT_TOTAL || cat->type == CCT_SUBTOTAL ? pivot_value_new_user_text (cat->total_label, SIZE_MAX) - : cat->type == CCT_POSTCOMPUTE && cat->pc->label - ? pivot_value_new_user_text (cat->pc->label, SIZE_MAX) : pivot_value_new_var_value (var, value)); } +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) +{ + struct substring in = ss_cstr (cat->pc->label); + struct substring target = ss_cstr (")LABEL["); + + struct string out = DS_EMPTY_INITIALIZER; + for (;;) + { + size_t chunk = ss_find_substring (in, target); + if (chunk == SIZE_MAX) + { + if (ds_is_empty (&out)) + return pivot_value_new_user_text (in.string, in.length); + else + { + ds_put_substring (&out, in); + return pivot_value_new_user_text_nocopy (ds_steal_cstr (&out)); + } + } + + ds_put_substring (&out, ss_head (in, chunk)); + ss_advance (&in, chunk + target.length); + + struct substring idx_s; + if (!ss_get_until (&in, ']', &idx_s)) + goto error; + char *tail; + long int idx = strtol (idx_s.string, &tail, 10); + if (idx < 1 || idx > cats->n_cats || tail != ss_end (idx_s)) + 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); + } + +error: + ds_destroy (&out); + return pivot_value_new_user_text (cat->pc->label, SIZE_MAX); +} + +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) +{ + return (cat->type == CCT_POSTCOMPUTE && cat->pc->label + ? ctables_postcompute_label (cats, cat, var, value) + : ctables_category_create_label__ (cat, var, value)); +} + static struct ctables_value * ctables_value_find__ (struct ctables_table *t, const union value *value, int width, unsigned int hash) @@ -3720,7 +3778,8 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) 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 ( - cat, t->clabels_example, &value->value)); + c, cat, t->clabels_example, + &value->value)); } } @@ -3912,8 +3971,9 @@ 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 (cv->category, - var, &cv->value); + label = ctables_category_create_label ( + t->categories[var_get_dict_index (var)], + cv->category, var, &cv->value); } else NOT_REACHED ();