postcomputes show up in results (all zeros so far)
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Feb 2022 19:09:25 +0000 (11:09 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 2 Apr 2022 01:48:55 +0000 (18:48 -0700)
src/language/stats/ctables.c

index 9b51538a4c877a872be66b56ea30313719e562bc..00275303d5952f93dcda6923cf4e0cd98281c802 100644 (file)
@@ -2739,7 +2739,8 @@ ctables_cell_insert__ (struct ctables_section *s, const struct ccase *c,
           {
             hash = hash_pointer (cats[a][i], hash);
             if (cats[a][i]->type != CCT_TOTAL
-                && cats[a][i]->type != CCT_SUBTOTAL)
+                && cats[a][i]->type != CCT_SUBTOTAL
+                && cats[a][i]->type != CCT_POSTCOMPUTE)
               hash = value_hash (case_data (c, nest->vars[i]),
                                  var_get_width (nest->vars[i]), hash);
             else
@@ -2758,6 +2759,7 @@ ctables_cell_insert__ (struct ctables_section *s, const struct ccase *c,
                 && (cats[a][i] != cell->axes[a].cvs[i].category
                     || (cats[a][i]->type != CCT_TOTAL
                         && cats[a][i]->type != CCT_SUBTOTAL
+                        && cats[a][i]->type != CCT_POSTCOMPUTE
                         && !value_equal (case_data (c, nest->vars[i]),
                                          &cell->axes[a].cvs[i].value,
                                          var_get_width (nest->vars[i])))))
@@ -2788,7 +2790,9 @@ ctables_cell_insert__ (struct ctables_section *s, const struct ccase *c,
               if (cat->hide || (subtotal && subtotal->hide_subcategories))
                 cell->hide = true;
 
-              if (cat->type == CCT_TOTAL || cat->type == CCT_SUBTOTAL)
+              if (cat->type == CCT_TOTAL
+                  || cat->type == CCT_SUBTOTAL
+                  || cat->type == CCT_POSTCOMPUTE)
                 cell->contributes_to_domains = false;
             }
 
@@ -2977,6 +2981,8 @@ ctables_category_create_label (const struct ctables_category *cat,
 {
   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));
 }
 
@@ -3221,6 +3227,7 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t)
                             break;
                           else if (c->type != CCT_SUBTOTAL
                                    && c->type != CCT_TOTAL
+                                   && c->type != CCT_POSTCOMPUTE
                                    && !value_equal (&prev->axes[a].cvs[var_idx].value,
                                                     &cell->axes[a].cvs[var_idx].value,
                                                     var_get_type (nest->vars[var_idx])))
@@ -3708,6 +3715,8 @@ ctables_section_recurse_add_empty_categories (
   else
     {
       const struct variable *var = s->nests[a]->vars[a_idx];
+      const struct ctables_categories *categories = s->table->categories[
+        var_get_dict_index (var)];
       int width = var_get_width (var);
       const struct hmap *occurrences = &s->occurrences[a][a_idx];
       const struct ctables_section_value *sv;
@@ -3716,11 +3725,21 @@ ctables_section_recurse_add_empty_categories (
           union value *value = case_data_rw (c, var);
           value_destroy (value, width);
           value_clone (value, &sv->value, width);
-          cats[a][a_idx] = ctables_categories_match (
-            s->table->categories[var_get_dict_index (var)], value, var);
+          cats[a][a_idx] = ctables_categories_match (categories, value, var);
           assert (cats[a][a_idx] != NULL);
           ctables_section_recurse_add_empty_categories (s, cats, c, a, a_idx + 1);
         }
+
+      for (size_t i = 0; i < categories->n_cats; i++)
+        {
+          const struct ctables_category *cat = &categories->cats[i];
+          if (cat->type == CCT_POSTCOMPUTE)
+            {
+              printf ("%s:%d\n", __FILE__, __LINE__);
+              cats[a][a_idx] = cat;
+              ctables_section_recurse_add_empty_categories (s, cats, c, a, a_idx + 1);
+            }
+        }
     }
 }
 
@@ -4146,7 +4165,7 @@ ctables_find_postcompute (struct ctables *ct, const char *name)
 static bool
 ctables_parse_pcompute (struct lexer *lexer, struct ctables *ct)
 {
-  int start_ofs = lex_ofs (lexer) - 1;
+  int pcompute_start = lex_ofs (lexer) - 1;
 
   if (!lex_force_match (lexer, T_AND) || !lex_force_id (lexer))
     return false;
@@ -4162,15 +4181,18 @@ ctables_parse_pcompute (struct lexer *lexer, struct ctables *ct)
       return false;
     }
 
+  int expr_start = lex_ofs (lexer);
   struct ctables_pcexpr *expr = parse_add (lexer);
+  int expr_end = lex_ofs (lexer) - 1;
   if (!expr || !lex_force_match (lexer, T_RPAREN))
     {
       free (name);
       return false;
     }
+  int pcompute_end = lex_ofs (lexer) - 1;
 
-  struct msg_location *location = lex_ofs_location (lexer, start_ofs,
-                                                    lex_ofs (lexer) - 1);
+  struct msg_location *location = lex_ofs_location (lexer, pcompute_start,
+                                                    pcompute_end);
 
   struct ctables_postcompute *pc = ctables_find_postcompute (ct, name);
   if (pc)
@@ -4193,6 +4215,8 @@ ctables_parse_pcompute (struct lexer *lexer, struct ctables *ct)
     }
   pc->expr = expr;
   pc->location = location;
+  if (!pc->label)
+    pc->label = lex_ofs_representation (lexer, expr_start, expr_end);
   return true;
 }