fix parsing
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 17 Jan 2022 03:21:56 +0000 (19:21 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 2 Apr 2022 01:48:55 +0000 (18:48 -0700)
src/language/stats/ctables.c

index fb8bb3a113008c182828b1612af925af08673e1a..4235002c28932deeb3dfe7ea4486d57758dcf4ab 100644 (file)
@@ -2831,8 +2831,94 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t)
   pivot_table_submit (pt);
 }
 
+static bool
+ctables_check_label_position (struct ctables_table *t, enum pivot_axis_type a)
+{
+  enum pivot_axis_type label_pos = t->label_axis[a];
+  if (label_pos == a)
+    return true;
 
-static void
+  t->clabels_from_axis = a;
+
+  const char *subcommand_name = a == PIVOT_AXIS_ROW ? "ROWLABELS" : "COLLABELS";
+  const char *pos_name = label_pos == PIVOT_AXIS_LAYER ? "LAYER" : "OPPOSITE";
+
+  const struct ctables_stack *stack = &t->stacks[a];
+  if (!stack->n)
+    return true;
+
+  const struct ctables_nest *n0 = &stack->nests[0];
+  assert (n0->n > 0);
+  const struct variable *v0 = n0->vars[n0->n - 1];
+  struct ctables_categories *c0 = t->categories[var_get_dict_index (v0)];
+  t->clabels_example = v0;
+
+  for (size_t i = 0; i < c0->n_cats; i++)
+    if (c0->cats[i].type == CCT_FUNCTION)
+      {
+        msg (SE, _("%s=%s is not allowed with sorting based "
+                   "on a summary function."),
+             subcommand_name, pos_name);
+        return false;
+      }
+  if (n0->n - 1 == n0->scale_idx)
+    {
+      msg (SE, _("%s=%s requires the variables to be moved to be categorical, "
+                 "but %s is a scale variable."),
+           subcommand_name, pos_name, var_get_name (v0));
+      return false;
+    }
+
+  for (size_t i = 1; i < stack->n; i++)
+    {
+      const struct ctables_nest *ni = &stack->nests[i];
+      assert (ni->n > 0);
+      const struct variable *vi = ni->vars[ni->n - 1];
+      struct ctables_categories *ci = t->categories[var_get_dict_index (vi)];
+
+      if (ni->n - 1 == ni->scale_idx)
+        {
+          msg (SE, _("%s=%s requires the variables to be moved to be "
+                     "categorical, but %s is a scale variable."),
+               subcommand_name, pos_name, var_get_name (vi));
+          return false;
+        }
+      if (var_get_width (v0) != var_get_width (vi))
+        {
+          msg (SE, _("%s=%s requires the variables to be "
+                     "moved to have the same width, but %s has "
+                     "width %d and %s has width %d."),
+               subcommand_name, pos_name,
+               var_get_name (v0), var_get_width (v0),
+               var_get_name (vi), var_get_width (vi));
+          return false;
+        }
+      if (!val_labs_equal (var_get_value_labels (v0),
+                           var_get_value_labels (vi)))
+        {
+          msg (SE, _("%s=%s requires the variables to be "
+                     "moved to have the same value labels, but %s "
+                     "and %s have different value labels."),
+               subcommand_name, pos_name,
+               var_get_name (v0), var_get_name (vi));
+          return false;
+        }
+      if (!ctables_categories_equal (c0, ci))
+        {
+          msg (SE, _("%s=%s requires the variables to be "
+                     "moved to have the same category "
+                     "specifications, but %s and %s have different "
+                     "category specifications."),
+               subcommand_name, pos_name,
+               var_get_name (v0), var_get_name (vi));
+          return false;
+        }
+    }
+
+  return true;
+}
+
+static bool
 ctables_prepare_table (struct ctables_table *t)
 {
   for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
@@ -2986,6 +3072,9 @@ ctables_prepare_table (struct ctables_table *t)
         }
     }
 #endif
+
+  return (ctables_check_label_position (t, PIVOT_AXIS_ROW)
+          && ctables_check_label_position (t, PIVOT_AXIS_COLUMN));
 }
 
 static void
@@ -3086,93 +3175,6 @@ ctables_execute (struct dataset *ds, struct ctables *ct)
   return proc_commit (ds);
 }
 
-static bool
-ctables_check_label_position (struct ctables_table *t, enum pivot_axis_type a)
-{
-  enum pivot_axis_type label_pos = t->label_axis[a];
-  if (label_pos == a)
-    return true;
-
-  t->clabels_from_axis = a;
-
-  const char *subcommand_name = a == PIVOT_AXIS_ROW ? "ROWLABELS" : "COLLABELS";
-  const char *pos_name = label_pos == PIVOT_AXIS_LAYER ? "LAYER" : "OPPOSITE";
-
-  const struct ctables_stack *stack = &t->stacks[a];
-  if (!stack->n)
-    return true;
-
-  const struct ctables_nest *n0 = &stack->nests[0];
-  assert (n0->n > 0);
-  const struct variable *v0 = n0->vars[n0->n - 1];
-  struct ctables_categories *c0 = t->categories[var_get_dict_index (v0)];
-  t->clabels_example = v0;
-
-  for (size_t i = 0; i < c0->n_cats; i++)
-    if (c0->cats[i].type == CCT_FUNCTION)
-      {
-        msg (SE, _("%s=%s is not allowed with sorting based "
-                   "on a summary function."),
-             subcommand_name, pos_name);
-        return false;
-      }
-  if (n0->n - 1 == n0->scale_idx)
-    {
-      msg (SE, _("%s=%s requires the variables to be moved to be categorical, "
-                 "but %s is a scale variable."),
-           subcommand_name, pos_name, var_get_name (v0));
-      return false;
-    }
-
-  for (size_t i = 1; i < stack->n; i++)
-    {
-      const struct ctables_nest *ni = &stack->nests[i];
-      assert (ni->n > 0);
-      const struct variable *vi = ni->vars[ni->n - 1];
-      struct ctables_categories *ci = t->categories[var_get_dict_index (vi)];
-
-      if (ni->n - 1 == ni->scale_idx)
-        {
-          msg (SE, _("%s=%s requires the variables to be moved to be "
-                     "categorical, but %s is a scale variable."),
-               subcommand_name, pos_name, var_get_name (vi));
-          return false;
-        }
-      if (var_get_width (v0) != var_get_width (vi))
-        {
-          msg (SE, _("%s=%s requires the variables to be "
-                     "moved to have the same width, but %s has "
-                     "width %d and %s has width %d."),
-               subcommand_name, pos_name,
-               var_get_name (v0), var_get_width (v0),
-               var_get_name (vi), var_get_width (vi));
-          return false;
-        }
-      if (!val_labs_equal (var_get_value_labels (v0),
-                           var_get_value_labels (vi)))
-        {
-          msg (SE, _("%s=%s requires the variables to be "
-                     "moved to have the same value labels, but %s "
-                     "and %s have different value labels."),
-               subcommand_name, pos_name,
-               var_get_name (v0), var_get_name (vi));
-          return false;
-        }
-      if (!ctables_categories_equal (c0, ci))
-        {
-          msg (SE, _("%s=%s requires the variables to be "
-                     "moved to have the same category "
-                     "specifications, but %s and %s have different "
-                     "category specifications."),
-               subcommand_name, pos_name,
-               var_get_name (v0), var_get_name (vi));
-          return false;
-        }
-    }
-
-  return true;
-}
-
 int
 cmd_ctables (struct lexer *lexer, struct dataset *ds)
 {
@@ -3504,7 +3506,11 @@ cmd_ctables (struct lexer *lexer, struct dataset *ds)
           }
 
       if (lex_token (lexer) == T_ENDCMD)
-        break;
+        {
+          if (!ctables_prepare_table (t))
+            goto error;
+          break;
+        }
       if (!lex_force_match (lexer, T_SLASH))
         break;
 
@@ -3852,10 +3858,8 @@ cmd_ctables (struct lexer *lexer, struct dataset *ds)
           goto error;
         }
 
-      ctables_prepare_table (t);
-
-      ctables_check_label_position (t, PIVOT_AXIS_ROW);
-      ctables_check_label_position (t, PIVOT_AXIS_COLUMN);
+      if (!ctables_prepare_table (t))
+        goto error;
     }
   while (lex_token (lexer) != T_ENDCMD);