Handle multiple postcomputes. ctables12
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 8 Jul 2022 20:20:07 +0000 (13:20 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 8 Jul 2022 20:20:07 +0000 (13:20 -0700)
src/language/stats/ctables.c
tests/language/stats/ctables.at

index 930c09c6331e8a7eb33e38726ae447e85cc0a8aa..59c97ecdc20e8714de04ae1e1858b8bfad71c0df 100644 (file)
@@ -4213,24 +4213,30 @@ ctables_cell_postcompute (const struct ctables_section *s,
                           size_t *pc_a_idx_p)
 {
   assert (cell->postcompute);
-  for (enum pivot_axis_type pc_a = 0; ; pc_a++)
-    {
-      assert (pc_a < PIVOT_N_AXES);
-      for (size_t pc_a_idx = 0; pc_a_idx < s->nests[pc_a]->n; pc_a_idx++)
-        {
-          const struct ctables_cell_value *cv = &cell->axes[pc_a].cvs[pc_a_idx];
-          if (cv->category->type == CCT_POSTCOMPUTE)
-            {
-              if (pc_a_p)
-                *pc_a_p = pc_a;
-              if (pc_a_idx_p)
-                *pc_a_idx_p = pc_a_idx;
-              return cv->category->pc;
-            }
-        }
-    }
+  const struct ctables_postcompute *pc = NULL;
+  for (enum pivot_axis_type pc_a = 0; pc_a < PIVOT_N_AXES; pc_a++)
+    for (size_t pc_a_idx = 0; pc_a_idx < s->nests[pc_a]->n; pc_a_idx++)
+      {
+        const struct ctables_cell_value *cv = &cell->axes[pc_a].cvs[pc_a_idx];
+        if (cv->category->type == CCT_POSTCOMPUTE)
+          {
+            if (pc)
+              {
+                /* Multiple postcomputes cross each other.  The value is
+                   undefined. */
+                return NULL;
+              }
 
-  NOT_REACHED ();
+            pc = cv->category->pc;
+            if (pc_a_p)
+              *pc_a_p = pc_a;
+            if (pc_a_idx_p)
+              *pc_a_idx_p = pc_a_idx;
+          }
+      }
+
+  assert (pc != NULL);
+  return pc;
 }
 
 static double
@@ -4245,6 +4251,8 @@ ctables_cell_calculate_postcompute (const struct ctables_section *s,
   size_t pc_a_idx;
   const struct ctables_postcompute *pc = ctables_cell_postcompute (
     s, cell, &pc_a, &pc_a_idx);
+  if (!pc)
+    return SYSMIS;
 
   if (pc->specs)
     {
index 7a52b185defa09e0717ec07f160f6119452f3d04..d480df3431d1b972ee6e0a84dc5b5458c4faedbd 100644 (file)
@@ -6,7 +6,6 @@ dnl - SPLIT FILE with SEPARATE splits
 dnl - Definition of columns/rows when labels are rotated from one axis to another.
 dnl - Preprocessing to distinguish categorical from scale.
 dnl - PCOMPUTE:
-dnl   * multi-dimensional (multiple CCT_POSTCOMPUTE in one cell)
 dnl   * dates
 dnl
 dnl Features not yet tested:
@@ -42,6 +41,7 @@ dnl - Test PCOMPUTE:
 dnl   * PCOMPUTE for more than one kind of summary (e.g. [COUNT, ROWPCT]).
 dnl   * MISSING, OTHERNM
 dnl   * strings and string ranges
+dnl   * multi-dimensional (multiple CCT_POSTCOMPUTE in one cell)
 dnl - PPROPERTIES:
 dnl   * )LABEL[N].
 dnl - Summary functions: