From 8498b2dd663b876b075b7a20f727d57b1a17d5cb Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 3 Jul 2022 11:23:36 -0700 Subject: [PATCH 1/1] )LABEL[N]. untested, probably doesn't work. --- src/language/stats/ctables.c | 76 +++++++++++++++++++++++++++++---- tests/language/stats/ctables.at | 3 +- 2 files changed, 70 insertions(+), 9 deletions(-) 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 (); diff --git a/tests/language/stats/ctables.at b/tests/language/stats/ctables.at index a5ae1eebf0..1d787428d3 100644 --- a/tests/language/stats/ctables.at +++ b/tests/language/stats/ctables.at @@ -18,7 +18,6 @@ dnl * multi-dimensional dnl * MISSING, OTHERNM dnl * strings dnl - PPROPERTIES: -dnl * )LABEL[N]. dnl * summary statistics and formats? dnl dnl Features not yet tested: @@ -46,6 +45,8 @@ dnl - HIDESMALLCOUNTS. dnl - Date/time variables and values dnl - Special formats for summary functions: NEGPAREN, NEQUAL, PAREN, PCTPAREN. dnl - TITLES: )DATE, )TIME, )TABLE. +dnl - PPROPERTIES: +dnl * )LABEL[N]. dnl dnl Not for v1: dnl - Multiple response sets -- 2.30.2