From a2fc35819d149152d02523fcdbf3adc78712f755 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 12 Feb 2022 11:01:39 -0800 Subject: [PATCH] parsing postcomputes into categories --- src/language/stats/ctables.c | 47 +++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index 9dd1fd55a6..7f324349bf 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -242,6 +242,9 @@ struct ctables size_t n_tables; }; +static struct ctables_postcompute *ctables_find_postcompute (struct ctables *, + const char *name); + struct ctables_postcompute { struct hmap_node hmap_node; /* In struct ctables's 'pcompute' hmap. */ @@ -455,6 +458,7 @@ struct ctables_category CCT_RANGE, CCT_MISSING, CCT_OTHERNM, + CCT_POSTCOMPUTE, /* Totals and subtotals. */ CCT_SUBTOTAL, @@ -475,7 +479,8 @@ struct ctables_category double number; /* CCT_NUMBER. */ char *string; /* CCT_STRING. */ double range[2]; /* CCT_RANGE. */ - char *total_label; /* CCT_SUBTOTAL, CCT_HSUBTOTAL, CCT_TOTAL. */ + char *total_label; /* CCT_SUBTOTAL, CCT_HSUBTOTAL, CCT_TOTAL. */ + const struct ctables_postcompute *pc; /* CCT_POSTCOMPUTE. */ /* CCT_VALUE, CCT_LABEL, CCT_FUNCTION. */ struct @@ -503,6 +508,7 @@ ctables_category_uninit (struct ctables_category *cat) case CCT_RANGE: case CCT_MISSING: case CCT_OTHERNM: + case CCT_POSTCOMPUTE: break; case CCT_STRING: @@ -544,6 +550,9 @@ ctables_category_equal (const struct ctables_category *a, case CCT_OTHERNM: return true; + case CCT_POSTCOMPUTE: + return a->pc == b->pc; + case CCT_SUBTOTAL: case CCT_HSUBTOTAL: case CCT_TOTAL: @@ -1302,7 +1311,7 @@ cct_range (double low, double high) static bool ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict, - struct ctables_table *t) + struct ctables *ct, struct ctables_table *t) { if (!lex_match_id (lexer, "VARIABLES")) return false; @@ -1380,6 +1389,27 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict, }; lex_get (lexer); } + else if (lex_match (lexer, T_AND)) + { + if (!lex_force_id (lexer)) + return false; + struct ctables_postcompute *pc = ctables_find_postcompute ( + ct, lex_tokcstr (lexer)); + if (!pc) + { + struct msg_location *loc = lex_get_location (lexer, -1, 0); + msg_at (SE, loc, _("Unknown postcompute &%s."), + lex_tokcstr (lexer)); + msg_location_destroy (loc); + return false; + } + lex_get (lexer); + + *cat = (struct ctables_category) { + .type = CCT_POSTCOMPUTE, + .pc = pc, + }; + } else { lex_error (lexer, NULL); @@ -1578,6 +1608,9 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict, cat->subtotal = subtotal; break; + case CCT_POSTCOMPUTE: + break; + case CCT_SUBTOTAL: case CCT_HSUBTOTAL: subtotal = cat; @@ -2343,6 +2376,7 @@ ctables_cell_compare_3way (const void *a_, const void *b_, const void *aux_) case CCT_SUBTOTAL: case CCT_HSUBTOTAL: case CCT_TOTAL: + case CCT_POSTCOMPUTE: /* Must be equal. */ continue; @@ -2474,6 +2508,9 @@ ctables_categories_match (const struct ctables_categories *c, return cat; break; + case CCT_POSTCOMPUTE: + break; + case CCT_OTHERNM: if (!othernm) othernm = cat; @@ -3462,6 +3499,9 @@ ctables_add_category_occurrences (const struct variable *var, ctables_add_occurrence (var, &vl->value, occurrences); break; + case CCT_POSTCOMPUTE: + break; + case CCT_SUBTOTAL: case CCT_HSUBTOTAL: case CCT_TOTAL: @@ -4564,7 +4604,8 @@ cmd_ctables (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "CATEGORIES")) { - if (!ctables_table_parse_categories (lexer, dataset_dict (ds), t)) + if (!ctables_table_parse_categories (lexer, dataset_dict (ds), + ct, t)) goto error; } else if (lex_match_id (lexer, "TITLES")) -- 2.30.2