refactoring
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 27 Aug 2022 23:35:59 +0000 (16:35 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 27 Aug 2022 23:35:59 +0000 (16:35 -0700)
src/language/stats/ctables.c

index ff4a261f89552dbe19fe6d15e2851741a2b7e0a4..0e704be074cb5e95f48e4634263dcbfa708d8d8a 100644 (file)
@@ -548,6 +548,18 @@ is_listwise_missing (const struct ctables_summary_spec_set *specs,
 \f
 /* CTABLES postcompute expressions. */
 
+struct ctables_postcompute
+  {
+    struct hmap_node hmap_node; /* In struct ctables's 'pcompute' hmap. */
+    char *name;                 /* Name, without leading &. */
+
+    struct msg_location *location; /* Location of definition. */
+    struct ctables_pcexpr *expr;
+    char *label;
+    struct ctables_summary_spec_set *specs;
+    bool hide_source_cats;
+  };
+
 struct ctables_pcexpr
   {
     /* Precedence table:
@@ -2006,6 +2018,177 @@ ctables_find_category_for_postcompute (const struct dictionary *dict,
     }
   return ctables_find_category_for_postcompute__ (cats, e);
 }
+
+static struct substring
+rtrim_value (const union value *v, const struct variable *var)
+{
+  struct substring s = ss_buffer (CHAR_CAST (char *, v->s),
+                                  var_get_width (var));
+  ss_rtrim (&s, ss_cstr (" "));
+  return s;
+}
+
+static bool
+in_string_range (const union value *v, const struct variable *var,
+                 const struct substring *srange)
+{
+  struct substring s = rtrim_value (v, var);
+  return ((!srange[0].string || ss_compare (s, srange[0]) >= 0)
+          && (!srange[1].string || ss_compare (s, srange[1]) <= 0));
+}
+
+static const struct ctables_category *
+ctables_categories_match (const struct ctables_categories *c,
+                          const union value *v, const struct variable *var)
+{
+  if (var_is_numeric (var) && v->f == SYSMIS)
+    return NULL;
+
+  const struct ctables_category *othernm = NULL;
+  for (size_t i = c->n_cats; i-- > 0; )
+    {
+      const struct ctables_category *cat = &c->cats[i];
+      switch (cat->type)
+        {
+        case CCT_NUMBER:
+          if (cat->number == v->f)
+            return cat;
+          break;
+
+        case CCT_STRING:
+          if (ss_equals (cat->string, rtrim_value (v, var)))
+            return cat;
+          break;
+
+        case CCT_NRANGE:
+          if ((cat->nrange[0] == -DBL_MAX || v->f >= cat->nrange[0])
+              && (cat->nrange[1] == DBL_MAX || v->f <= cat->nrange[1]))
+            return cat;
+          break;
+
+        case CCT_SRANGE:
+          if (in_string_range (v, var, cat->srange))
+            return cat;
+          break;
+
+        case CCT_MISSING:
+          if (var_is_value_missing (var, v))
+            return cat;
+          break;
+
+        case CCT_POSTCOMPUTE:
+          break;
+
+        case CCT_OTHERNM:
+          if (!othernm)
+            othernm = cat;
+          break;
+
+        case CCT_SUBTOTAL:
+        case CCT_TOTAL:
+          break;
+
+        case CCT_VALUE:
+        case CCT_LABEL:
+        case CCT_FUNCTION:
+          return (cat->include_missing || !var_is_value_missing (var, v) ? cat
+                  : NULL);
+
+        case CCT_EXCLUDED_MISSING:
+          break;
+        }
+    }
+
+  return var_is_value_missing (var, v) ? NULL : othernm;
+}
+
+static const struct ctables_category *
+ctables_categories_total (const struct ctables_categories *c)
+{
+  const struct ctables_category *first = &c->cats[0];
+  const struct ctables_category *last = &c->cats[c->n_cats - 1];
+  return (first->type == CCT_TOTAL ? first
+          : last->type == CCT_TOTAL ? last
+          : NULL);
+}
+
+static void
+ctables_category_format_number (double number, const struct variable *var,
+                                struct string *s)
+{
+  struct pivot_value *pv = pivot_value_new_var_value (
+    var, &(union value) { .f = number });
+  pivot_value_format (pv, NULL, s);
+  pivot_value_destroy (pv);
+}
+
+static void
+ctables_category_format_string (struct substring string,
+                                const struct variable *var, struct string *out)
+{
+  int width = var_get_width (var);
+  char *s = xmalloc (width);
+  buf_copy_rpad (s, width, string.string, string.length, ' ');
+  struct pivot_value *pv = pivot_value_new_var_value (
+    var, &(union value) { .s = CHAR_CAST (uint8_t *, s) });
+  pivot_value_format (pv, NULL, out);
+  pivot_value_destroy (pv);
+  free (s);
+}
+
+static bool
+ctables_category_format_label (const struct ctables_category *cat,
+                               const struct variable *var,
+                               struct string *s)
+{
+  switch (cat->type)
+    {
+    case CCT_NUMBER:
+      ctables_category_format_number (cat->number, var, s);
+      return true;
+
+    case CCT_STRING:
+      ctables_category_format_string (cat->string, var, s);
+      return true;
+
+    case CCT_NRANGE:
+      ctables_category_format_number (cat->nrange[0], var, s);
+      ds_put_format (s, " THRU ");
+      ctables_category_format_number (cat->nrange[1], var, s);
+      return true;
+
+    case CCT_SRANGE:
+      ctables_category_format_string (cat->srange[0], var, s);
+      ds_put_format (s, " THRU ");
+      ctables_category_format_string (cat->srange[1], var, s);
+      return true;
+
+    case CCT_MISSING:
+      ds_put_cstr (s, "MISSING");
+      return true;
+
+    case CCT_OTHERNM:
+      ds_put_cstr (s, "OTHERNM");
+      return true;
+
+    case CCT_POSTCOMPUTE:
+      ds_put_format (s, "&%s", cat->pc->name);
+      return true;
+
+    case CCT_TOTAL:
+    case CCT_SUBTOTAL:
+      ds_put_cstr (s, cat->total_label);
+      return true;
+
+    case CCT_VALUE:
+    case CCT_LABEL:
+    case CCT_FUNCTION:
+    case CCT_EXCLUDED_MISSING:
+      return false;
+    }
+
+  return false;
+}
 \f
 /* CTABLES variable nesting and stacking. */
 
@@ -2169,7 +2352,6 @@ enumerate_fts (enum pivot_axis_type axis_type, const struct ctables_axis *a)
   NOT_REACHED ();
 }
 \f
-\f
 /* CTABLES summary calculation. */
 
 union ctables_summary
@@ -2558,18 +2740,6 @@ struct ctables_cell
     union ctables_summary *summaries;
   };
 
-struct ctables_postcompute
-  {
-    struct hmap_node hmap_node; /* In struct ctables's 'pcompute' hmap. */
-    char *name;                 /* Name, without leading &. */
-
-    struct msg_location *location; /* Location of definition. */
-    struct ctables_pcexpr *expr;
-    char *label;
-    struct ctables_summary_spec_set *specs;
-    bool hide_source_cats;
-  };
-
 struct ctables
   {
     const struct dictionary *dict;
@@ -3456,99 +3626,6 @@ ctables_area_insert (struct ctables_section *s, struct ctables_cell *cell,
   return a;
 }
 
-static struct substring
-rtrim_value (const union value *v, const struct variable *var)
-{
-  struct substring s = ss_buffer (CHAR_CAST (char *, v->s),
-                                  var_get_width (var));
-  ss_rtrim (&s, ss_cstr (" "));
-  return s;
-}
-
-static bool
-in_string_range (const union value *v, const struct variable *var,
-                 const struct substring *srange)
-{
-  struct substring s = rtrim_value (v, var);
-  return ((!srange[0].string || ss_compare (s, srange[0]) >= 0)
-          && (!srange[1].string || ss_compare (s, srange[1]) <= 0));
-}
-
-static const struct ctables_category *
-ctables_categories_match (const struct ctables_categories *c,
-                          const union value *v, const struct variable *var)
-{
-  if (var_is_numeric (var) && v->f == SYSMIS)
-    return NULL;
-
-  const struct ctables_category *othernm = NULL;
-  for (size_t i = c->n_cats; i-- > 0; )
-    {
-      const struct ctables_category *cat = &c->cats[i];
-      switch (cat->type)
-        {
-        case CCT_NUMBER:
-          if (cat->number == v->f)
-            return cat;
-          break;
-
-        case CCT_STRING:
-          if (ss_equals (cat->string, rtrim_value (v, var)))
-            return cat;
-          break;
-
-        case CCT_NRANGE:
-          if ((cat->nrange[0] == -DBL_MAX || v->f >= cat->nrange[0])
-              && (cat->nrange[1] == DBL_MAX || v->f <= cat->nrange[1]))
-            return cat;
-          break;
-
-        case CCT_SRANGE:
-          if (in_string_range (v, var, cat->srange))
-            return cat;
-          break;
-
-        case CCT_MISSING:
-          if (var_is_value_missing (var, v))
-            return cat;
-          break;
-
-        case CCT_POSTCOMPUTE:
-          break;
-
-        case CCT_OTHERNM:
-          if (!othernm)
-            othernm = cat;
-          break;
-
-        case CCT_SUBTOTAL:
-        case CCT_TOTAL:
-          break;
-
-        case CCT_VALUE:
-        case CCT_LABEL:
-        case CCT_FUNCTION:
-          return (cat->include_missing || !var_is_value_missing (var, v) ? cat
-                  : NULL);
-
-        case CCT_EXCLUDED_MISSING:
-          break;
-        }
-    }
-
-  return var_is_value_missing (var, v) ? NULL : othernm;
-}
-
-static const struct ctables_category *
-ctables_categories_total (const struct ctables_categories *c)
-{
-  const struct ctables_category *first = &c->cats[0];
-  const struct ctables_category *last = &c->cats[c->n_cats - 1];
-  return (first->type == CCT_TOTAL ? first
-          : last->type == CCT_TOTAL ? last
-          : NULL);
-}
-
 static struct ctables_cell *
 ctables_cell_insert__ (struct ctables_section *s, const struct ccase *c,
                        const struct ctables_category **cats[PIVOT_N_AXES])
@@ -3878,84 +3955,6 @@ merge_item_compare_3way (const struct merge_item *a, const struct merge_item *b)
   return strcmp (as_label, bs_label);
 }
 
-static void
-ctables_category_format_number (double number, const struct variable *var,
-                                struct string *s)
-{
-  struct pivot_value *pv = pivot_value_new_var_value (
-    var, &(union value) { .f = number });
-  pivot_value_format (pv, NULL, s);
-  pivot_value_destroy (pv);
-}
-
-static void
-ctables_category_format_string (struct substring string,
-                                const struct variable *var, struct string *out)
-{
-  int width = var_get_width (var);
-  char *s = xmalloc (width);
-  buf_copy_rpad (s, width, string.string, string.length, ' ');
-  struct pivot_value *pv = pivot_value_new_var_value (
-    var, &(union value) { .s = CHAR_CAST (uint8_t *, s) });
-  pivot_value_format (pv, NULL, out);
-  pivot_value_destroy (pv);
-  free (s);
-}
-
-static bool
-ctables_category_format_label (const struct ctables_category *cat,
-                               const struct variable *var,
-                               struct string *s)
-{
-  switch (cat->type)
-    {
-    case CCT_NUMBER:
-      ctables_category_format_number (cat->number, var, s);
-      return true;
-
-    case CCT_STRING:
-      ctables_category_format_string (cat->string, var, s);
-      return true;
-
-    case CCT_NRANGE:
-      ctables_category_format_number (cat->nrange[0], var, s);
-      ds_put_format (s, " THRU ");
-      ctables_category_format_number (cat->nrange[1], var, s);
-      return true;
-
-    case CCT_SRANGE:
-      ctables_category_format_string (cat->srange[0], var, s);
-      ds_put_format (s, " THRU ");
-      ctables_category_format_string (cat->srange[1], var, s);
-      return true;
-
-    case CCT_MISSING:
-      ds_put_cstr (s, "MISSING");
-      return true;
-
-    case CCT_OTHERNM:
-      ds_put_cstr (s, "OTHERNM");
-      return true;
-
-    case CCT_POSTCOMPUTE:
-      ds_put_format (s, "&%s", cat->pc->name);
-      return true;
-
-    case CCT_TOTAL:
-    case CCT_SUBTOTAL:
-      ds_put_cstr (s, cat->total_label);
-      return true;
-
-    case CCT_VALUE:
-    case CCT_LABEL:
-    case CCT_FUNCTION:
-    case CCT_EXCLUDED_MISSING:
-      return false;
-    }
-
-  return false;
-}
-
 static struct pivot_value *
 ctables_postcompute_label (const struct ctables_categories *cats,
                            const struct ctables_category *cat,