Remove "Written by Ben Pfaff <blp@gnu.org>" lines everywhere.
[pspp-builds.git] / src / language / stats / crosstabs.q
index 405460de4a4b1c5a637fe9e7eea409b30e6da514..04a2a54c89a18fc73dfc07e9de858fee8867e7e7 100644 (file)
@@ -1,6 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -37,7 +36,9 @@
 #include <stdio.h>
 
 #include <data/case.h>
+#include <data/data-out.h>
 #include <data/dictionary.h>
+#include <data/format.h>
 #include <data/procedure.h>
 #include <data/value-labels.h>
 #include <data/variable.h>
@@ -59,6 +60,8 @@
 #include <output/output.h>
 #include <output/table.h>
 
+#include "minmax.h"
+
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
@@ -128,9 +131,7 @@ struct var_range
 static inline struct var_range *
 get_var_range (struct variable *v) 
 {
-  assert (v != NULL);
-  assert (v->aux != NULL);
-  return v->aux;
+  return var_get_aux (v);
 }
 
 /* Indexes into crosstab.v. */
@@ -175,11 +176,11 @@ static struct cmd_crosstabs cmd;
 static struct pool *pl_tc;     /* For table cells. */
 static struct pool *pl_col;    /* For column data. */
 
-static int internal_cmd_crosstabs (void);
-static void precalc (const struct ccase *, void *);
-static bool calc_general (const struct ccase *, void *);
-static bool calc_integer (const struct ccase *, void *);
-static void postcalc (void *);
+static int internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds);
+static void precalc (const struct ccase *, void *, const struct dataset *);
+static bool calc_general (const struct ccase *, void *, const struct dataset *);
+static bool calc_integer (const struct ccase *, void *, const struct dataset *);
+static bool postcalc (void *, const struct dataset *);
 static void submit (struct tab_table *);
 
 static void format_short (char *s, const struct fmt_spec *fp,
@@ -187,9 +188,9 @@ static void format_short (char *s, const struct fmt_spec *fp,
 
 /* Parse and execute CROSSTABS, then clean up. */
 int
-cmd_crosstabs (void)
+cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
 {
-  int result = internal_cmd_crosstabs ();
+  int result = internal_cmd_crosstabs (lexer, ds);
 
   free (variables);
   pool_destroy (pl_tc);
@@ -200,7 +201,7 @@ cmd_crosstabs (void)
 
 /* Parses and executes the CROSSTABS procedure. */
 static int
-internal_cmd_crosstabs (void)
+internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
 {
   int i;
   bool ok;
@@ -212,7 +213,7 @@ internal_cmd_crosstabs (void)
   pl_tc = pool_create ();
   pl_col = pool_create ();
 
-  if (!parse_crosstabs (&cmd, NULL))
+  if (!parse_crosstabs (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   mode = variables ? INTEGER : GENERAL;
@@ -293,7 +294,7 @@ internal_cmd_crosstabs (void)
   else
     write = CRS_WR_NONE;
 
-  ok = procedure_with_splits (current_dataset, precalc,
+  ok = procedure_with_splits (ds, precalc,
                               mode == GENERAL ? calc_general : calc_integer,
                               postcalc, NULL);
 
@@ -302,7 +303,7 @@ internal_cmd_crosstabs (void)
 
 /* Parses the TABLES subcommand. */
 static int
-crs_custom_tables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
+crs_custom_tables (struct lexer *lexer, struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 {
   struct var_set *var_set;
   int n_by;
@@ -312,23 +313,23 @@ crs_custom_tables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
   int success = 0;
 
   /* Ensure that this is a TABLES subcommand. */
-  if (!lex_match_id ("TABLES")
-      && (token != T_ID || dict_lookup_var (dataset_dict (current_dataset), tokid) == NULL)
-      && token != T_ALL)
+  if (!lex_match_id (lexer, "TABLES")
+      && (lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match ('=');
+  lex_match (lexer, '=');
 
   if (variables != NULL)
     var_set = var_set_create_from_array (variables, variables_cnt);
   else
-    var_set = var_set_create_from_dict (dataset_dict (current_dataset));
+    var_set = var_set_create_from_dict (dataset_dict (ds));
   assert (var_set != NULL);
   
   for (n_by = 0; ;)
     {
       by = xnrealloc (by, n_by + 1, sizeof *by);
       by_nvar = xnrealloc (by_nvar, n_by + 1, sizeof *by_nvar);
-      if (!parse_var_set_vars (var_set, &by[n_by], &by_nvar[n_by],
+      if (!parse_var_set_vars (lexer, var_set, &by[n_by], &by_nvar[n_by],
                                PV_NO_DUPLICATE | PV_NO_SCRATCH))
        goto done;
       if (xalloc_oversized (nx, by_nvar[n_by])) 
@@ -339,11 +340,11 @@ crs_custom_tables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
       nx *= by_nvar[n_by];
       n_by++;
 
-      if (!lex_match (T_BY))
+      if (!lex_match (lexer, T_BY))
        {
          if (n_by < 2)
            {
-             lex_error (_("expecting BY"));
+             lex_error (lexer, _("expecting BY"));
              goto done;
            }
          else 
@@ -406,7 +407,7 @@ crs_custom_tables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 
 /* Parses the VARIABLES subcommand. */
 static int
-crs_custom_variables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
+crs_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 {
   if (nxtab)
     {
@@ -414,7 +415,7 @@ crs_custom_variables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
       return 0;
     }
 
-  lex_match ('=');
+  lex_match (lexer, '=');
   
   for (;;)
     {
@@ -423,42 +424,43 @@ crs_custom_variables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 
       long min, max;
       
-      if (!parse_variables (dataset_dict (current_dataset), &variables, &variables_cnt,
+      if (!parse_variables (lexer, dataset_dict (ds), 
+                           &variables, &variables_cnt,
                            (PV_APPEND | PV_NUMERIC
                             | PV_NO_DUPLICATE | PV_NO_SCRATCH)))
        return 0;
 
-      if (token != '(')
+      if (lex_token (lexer) != '(')
        {
-         lex_error ("expecting `('");
+         lex_error (lexer, "expecting `('");
          goto lossage;
        }
-      lex_get ();
+      lex_get (lexer);
 
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        goto lossage;
-      min = lex_integer ();
-      lex_get ();
+      min = lex_integer (lexer);
+      lex_get (lexer);
 
-      lex_match (',');
+      lex_match (lexer, ',');
 
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        goto lossage;
-      max = lex_integer ();
+      max = lex_integer (lexer);
       if (max < min)
        {
          msg (SE, _("Maximum value (%ld) less than minimum value (%ld)."),
               max, min);
          goto lossage;
        }
-      lex_get ();
+      lex_get (lexer);
 
-      if (token != ')')
+      if (lex_token (lexer) != ')')
        {
-         lex_error ("expecting `)'");
+         lex_error (lexer, "expecting `)'");
          goto lossage;
        }
-      lex_get ();
+      lex_get (lexer);
       
       for (i = orig_nv; i < variables_cnt; i++) 
         {
@@ -469,7 +471,7 @@ crs_custom_variables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
           var_attach_aux (variables[i], vr, var_dtor_free);
        }
       
-      if (token == '/')
+      if (lex_token (lexer) == '/')
        break;
     }
   
@@ -483,14 +485,14 @@ crs_custom_variables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 \f
 /* Data file processing. */
 
-static int compare_table_entry (const void *, const void *, void *);
-static unsigned hash_table_entry (const void *, void *);
+static int compare_table_entry (const void *, const void *, const void *);
+static unsigned hash_table_entry (const void *, const void *);
 
 /* Set up the crosstabulation tables for processing. */
 static  void
-precalc (const struct ccase *first, void *aux UNUSED)
+precalc (const struct ccase *first, void *aux UNUSED, const struct dataset *ds)
 {
-  output_split_file_values (first);
+  output_split_file_values (ds, first);
   if (mode == GENERAL)
     {
       gen_tab = hsh_create (512, compare_table_entry, hash_table_entry,
@@ -563,12 +565,12 @@ precalc (const struct ccase *first, void *aux UNUSED)
 
 /* Form crosstabulations for general mode. */
 static bool
-calc_general (const struct ccase *c, void *aux UNUSED)
+calc_general (const struct ccase *c, void *aux UNUSED, const struct dataset *ds)
 {
   bool bad_warn = true;
 
   /* Case weight. */
-  double weight = dict_get_case_weight (dataset_dict (current_dataset), c, &bad_warn);
+  double weight = dict_get_case_weight (dataset_dict (ds), c, &bad_warn);
 
   /* Flattened current table index. */
   int t;
@@ -588,26 +590,25 @@ calc_general (const struct ccase *c, void *aux UNUSED)
        assert (x != NULL);
        for (j = 0; j < x->nvar; j++)
          {
-            const union value *v = case_data (c, x->vars[j]->fv);
-            const struct missing_values *mv = &x->vars[j]->miss;
-           if ((cmd.miss == CRS_TABLE && mv_is_value_missing (mv, v))
+            const union value *v = case_data (c, x->vars[j]);
+           if ((cmd.miss == CRS_TABLE && var_is_value_missing (x->vars[j], v))
                || (cmd.miss == CRS_INCLUDE
-                   && mv_is_value_system_missing (mv, v)))
+                   && var_is_value_system_missing (x->vars[j], v)))
              {
                x->missing += weight;
                goto next_crosstab;
              }
              
-           if (x->vars[j]->type == NUMERIC)
-             te->values[j].f = case_num (c, x->vars[j]->fv);
+           if (var_is_numeric (x->vars[j]))
+             te->values[j].f = case_num (c, x->vars[j]);
            else
              {
-               memcpy (te->values[j].s, case_str (c, x->vars[j]->fv),
-                        x->vars[j]->width);
+               memcpy (te->values[j].s, case_str (c, x->vars[j]),
+                        var_get_width (x->vars[j]));
              
                /* Necessary in order to simplify comparisons. */
-               memset (&te->values[j].s[x->vars[j]->width], 0,
-                       sizeof (union value) - x->vars[j]->width);
+               memset (&te->values[j].s[var_get_width (x->vars[j])], 0,
+                       sizeof (union value) - var_get_width (x->vars[j]));
              }
          }
       }
@@ -637,12 +638,12 @@ calc_general (const struct ccase *c, void *aux UNUSED)
 }
 
 static bool
-calc_integer (const struct ccase *c, void *aux UNUSED)
+calc_integer (const struct ccase *c, void *aux UNUSED, const struct dataset *ds)
 {
   bool bad_warn = true;
 
   /* Case weight. */
-  double weight = dict_get_case_weight (dataset_dict (current_dataset), c, &bad_warn);
+  double weight = dict_get_case_weight (dataset_dict (ds), c, &bad_warn);
   
   /* Flattened current table index. */
   int t;
@@ -658,12 +659,11 @@ calc_integer (const struct ccase *c, void *aux UNUSED)
        {
          struct variable *const v = x->vars[i];
           struct var_range *vr = get_var_range (v);
-         double value = case_num (c, v->fv);
+         double value = case_num (c, v);
          
          /* Note that the first test also rules out SYSMIS. */
          if ((value < vr->min || value >= vr->max)
-             || (cmd.miss == CRS_TABLE
-                  && mv_is_num_user_missing (&v->miss, value)))
+             || (cmd.miss == CRS_TABLE && var_is_num_user_missing (v, value)))
            {
              x->missing += weight;
              goto next_crosstab;
@@ -678,10 +678,10 @@ calc_integer (const struct ccase *c, void *aux UNUSED)
       
       {
         struct variable *row_var = x->vars[ROW_VAR];
-       const int row = case_num (c, row_var->fv) - get_var_range (row_var)->min;
+       const int row = case_num (c, row_var) - get_var_range (row_var)->min;
 
         struct variable *col_var = x->vars[COL_VAR];
-       const int col = case_num (c, col_var->fv) - get_var_range (col_var)->min;
+       const int col = case_num (c, col_var) - get_var_range (col_var)->min;
 
        const int col_dim = get_var_range (col_var)->count;
 
@@ -697,7 +697,7 @@ calc_integer (const struct ccase *c, void *aux UNUSED)
 /* Compare the table_entry's at A and B and return a strcmp()-type
    result. */
 static int 
-compare_table_entry (const void *a_, const void *b_, void *foo UNUSED)
+compare_table_entry (const void *a_, const void *b_, const void *aux UNUSED)
 {
   const struct table_entry *a = a_;
   const struct table_entry *b = b_;
@@ -712,7 +712,7 @@ compare_table_entry (const void *a_, const void *b_, void *foo UNUSED)
     int i;
 
     for (i = x->nvar - 1; i >= 0; i--)
-      if (x->vars[i]->type == NUMERIC)
+      if (var_is_numeric (x->vars[i]))
        {
          const double diffnum = a->values[i].f - b->values[i].f;
          if (diffnum < 0)
@@ -721,15 +721,12 @@ compare_table_entry (const void *a_, const void *b_, void *foo UNUSED)
            return 1;
        }
       else 
-       {
-         assert (x->vars[i]->type == ALPHA);
-         {
-           const int diffstr = strncmp (a->values[i].s, b->values[i].s,
-                                         x->vars[i]->width);
-           if (diffstr)
-             return diffstr;
-         }
-       }
+        {
+          const int diffstr = strncmp (a->values[i].s, b->values[i].s,
+                                       var_get_width (x->vars[i]));
+          if (diffstr)
+            return diffstr;
+        }
   }
   
   return 0;
@@ -737,7 +734,7 @@ compare_table_entry (const void *a_, const void *b_, void *foo UNUSED)
 
 /* Calculate a hash value from table_entry A. */
 static unsigned
-hash_table_entry (const void *a_, void *foo UNUSED)
+hash_table_entry (const void *a_, const void *aux UNUSED)
 {
   const struct table_entry *a = a_;
   unsigned long hash;
@@ -762,8 +759,8 @@ static void output_pivot_table (struct table_entry **, struct table_entry **,
                                int *, int *, int *);
 static void make_summary_table (void);
 
-static void
-postcalc (void *aux UNUSED)
+static bool
+postcalc (void *aux UNUSED, const struct dataset *ds UNUSED)
 {
   if (mode == GENERAL)
     {
@@ -799,6 +796,8 @@ postcalc (void *aux UNUSED)
   }
   
   hsh_destroy (gen_tab);
+
+  return true;
 }
 
 static void insert_summary (struct tab_table *, int tab_index, double valid);
@@ -896,8 +895,7 @@ insert_summary (struct tab_table *t, int tab_index, double valid)
        if (i > 0)
          cp = stpcpy (cp, " * ");
 
-       cp = stpcpy (cp,
-                     x->vars[i]->label ? x->vars[i]->label : x->vars[i]->name);
+       cp = stpcpy (cp, var_to_string (x->vars[i]));
       }
     tab_text (t, 0, 0, TAB_LEFT, buf);
 
@@ -950,7 +948,7 @@ static int n_rows;
 static int ns_cols, ns_rows;
 
 /* Crosstabulation. */
-static struct crosstab *x;
+static const struct crosstab *x;
 
 /* Number of variables from the crosstabulation to consider.  This is
    either x->nvar, if pivoting is on, or 2, if pivoting is off. */
@@ -1004,7 +1002,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
 
       /* First header line. */
       tab_joint_text (table, nvar - 1, 0, (nvar - 1) + (n_cols - 1), 0,
-                     TAB_CENTER | TAT_TITLE, x->vars[COL_VAR]->name);
+                     TAB_CENTER | TAT_TITLE, var_get_name (x->vars[COL_VAR]));
   
       tab_hline (table, TAL_1, nvar - 1, nvar + n_cols - 2, 1);
             
@@ -1014,11 +1012,9 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
 
        for (i = 2; i < nvar; i++)
          tab_joint_text (table, nvar - i - 1, 0, nvar - i - 1, 1,
-                         TAB_RIGHT | TAT_TITLE,
-                         (x->vars[i]->label
-                           ? x->vars[i]->label : x->vars[i]->name));
+                         TAB_RIGHT | TAT_TITLE, var_to_string (x->vars[i]));
        tab_text (table, nvar - 2, 1, TAB_RIGHT | TAT_TITLE,
-                 x->vars[ROW_VAR]->name);
+                 var_get_name (x->vars[ROW_VAR]));
        for (i = 0; i < n_cols; i++)
          table_value_missing (table, nvar + i - 1, 1, TAB_RIGHT, &cols[i],
                               x->vars[COL_VAR]);
@@ -1039,12 +1035,13 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
            {
              if (i)
                cp = stpcpy (cp, " by ");
-             cp = stpcpy (cp, x->vars[i]->name);
+             cp = stpcpy (cp, var_get_name (x->vars[i]));
            }
        else
          {
            cp = spprintf (cp, "%s by %s for",
-                           x->vars[0]->name, x->vars[1]->name);
+                           var_get_name (x->vars[0]),
+                           var_get_name (x->vars[1]));
            for (i = 2; i < nvar; i++)
              {
                char buf[64], *bufp;
@@ -1052,9 +1049,10 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
                if (i > 2)
                  *cp++ = ',';
                *cp++ = ' ';
-               cp = stpcpy (cp, x->vars[i]->name);
+               cp = stpcpy (cp, var_get_name (x->vars[i]));
                *cp++ = '=';
-               format_short (buf, &x->vars[i]->print, &(*pb)->values[i]);
+               format_short (buf, var_get_print_format (x->vars[i]),
+                              &(*pb)->values[i]);
                for (bufp = buf; isspace ((unsigned char) *bufp); bufp++)
                  ;
                cp = stpcpy (cp, bufp);
@@ -1218,7 +1216,7 @@ output_pivot_table (struct table_entry **pb, struct table_entry **pe,
       /* Allocate table space for the matrix. */
       if (table && tab_row (table) + (n_rows + 1) * num_cells > tab_nr (table))
        tab_realloc (table, -1,
-                    max (tab_nr (table) + (n_rows + 1) * num_cells,
+                    MAX (tab_nr (table) + (n_rows + 1) * num_cells,
                          tab_nr (table) * (pe - pb) / (te - tb)));
 
       if (mode == GENERAL)
@@ -1423,7 +1421,7 @@ delete_missing (void)
     int r;
 
     for (r = 0; r < n_rows; r++)
-      if (mv_is_num_user_missing (&x->vars[ROW_VAR]->miss, rows[r].f))
+      if (var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f))
        {
          int c;
 
@@ -1437,7 +1435,7 @@ delete_missing (void)
     int c;
 
     for (c = 0; c < n_cols; c++)
-      if (mv_is_num_user_missing (&x->vars[COL_VAR]->miss, cols[c].f))
+      if (var_is_num_user_missing (x->vars[COL_VAR], cols[c].f))
        {
          int r;
 
@@ -1467,7 +1465,7 @@ submit (struct tab_table *t)
   if (t != table)
     for (i = 2; i < nvar; i++)
       tab_text (t, nvar - i - 1, 0, TAB_RIGHT | TAT_TITLE,
-               x->vars[i]->label ? x->vars[i]->label : x->vars[i]->name);
+                var_to_string (x->vars[i]));
   tab_box (t, TAL_2, TAL_2, -1, -1, 0, 0, tab_nc (t) - 1, tab_nr (t) - 1);
   tab_box (t, -1, -1, -1, TAL_1, tab_l (t), tab_t (t) - 1, tab_nc (t) - 1,
           tab_nr (t) - 1);
@@ -1608,7 +1606,7 @@ find_pivot_extent_integer (struct table_entry **tp, int *cnt, int pivot)
    result.  WIDTH_ points to an int which is either 0 for a
    numeric value or a string width for a string value. */
 static int
-compare_value (const void *a_, const void *b_, void *width_)
+compare_value (const void *a_, const void *b_, const void *width_)
 {
   const union value *a = a_;
   const union value *b = b_;
@@ -1635,7 +1633,7 @@ enum_var_values (struct table_entry **entries, int entry_cnt, int var_idx,
 
   if (mode == GENERAL)
     {
-      int width = v->width;
+      int width = var_get_width (v);
       int i;
 
       *values = xnmalloc (entry_cnt, sizeof **values);
@@ -1665,18 +1663,19 @@ table_value_missing (struct tab_table *table, int c, int r, unsigned char opt,
                     const union value *v, const struct variable *var)
 {
   struct substring s;
+  const struct fmt_spec *print = var_get_print_format (var);
 
-  const char *label = val_labs_find (var->val_labs, *v);
+  const char *label = var_lookup_value_label (var, v);
   if (label) 
     {
       tab_text (table, c, r, TAB_LEFT, label);
       return;
     }
 
-  s.string = tab_alloc (table, var->print.w);
-  format_short (s.string, &var->print, v);
+  s.string = tab_alloc (table, print->w);
+  format_short (s.string, print, v);
   s.length = strlen (s.string);
-  if (cmd.miss == CRS_REPORT && mv_is_num_user_missing (&var->miss, v->f))
+  if (cmd.miss == CRS_REPORT && var_is_num_user_missing (var, v->f))
     s.string[s.length++] = 'M';
   while (s.length && *s.string == ' ')
     {
@@ -1716,7 +1715,7 @@ format_cell_entry (struct tab_table *table, int c, int r, double value,
   s.length = 10;
   s.string = tab_alloc (table, 16);
   v.f = value;
-  data_out (s.string, &f, &v);
+  data_out (&v, &f, s.string);
   while (*s.string == ' ')
     {
       s.length--;
@@ -1759,9 +1758,8 @@ display_crosstabulation (void)
             bool mark_missing = false;
             double expected_value = row_tot[r] * col_tot[c] / W;
             if (cmd.miss == CRS_REPORT
-                && (mv_is_num_user_missing (&x->vars[COL_VAR]->miss, cols[c].f)
-                    || mv_is_num_user_missing (&x->vars[ROW_VAR]->miss,
-                                               rows[r].f)))
+                && (var_is_num_user_missing (x->vars[COL_VAR], cols[c].f)
+                    || var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f)))
               mark_missing = true;
            for (i = 0; i < num_cells; i++)
              {
@@ -1825,7 +1823,7 @@ display_crosstabulation (void)
         bool mark_missing = false;
 
         if (cmd.miss == CRS_REPORT
-            && mv_is_num_user_missing (&x->vars[ROW_VAR]->miss, rows[r].f))
+            && var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f))
           mark_missing = true;
 
         for (i = 0; i < num_cells; i++)
@@ -1880,7 +1878,7 @@ display_crosstabulation (void)
         int i;
            
         if (cmd.miss == CRS_REPORT && c < n_cols 
-            && mv_is_num_user_missing (&x->vars[COL_VAR]->miss, cols[c].f))
+            && var_is_num_user_missing (x->vars[COL_VAR], cols[c].f))
           mark_missing = true;
 
         for (i = 0; i < num_cells; i++)
@@ -2076,24 +2074,24 @@ display_risk (void)
       switch (i)
        {
        case 0:
-         if (x->vars[COL_VAR]->type == NUMERIC)
+         if (var_is_numeric (x->vars[COL_VAR]))
            sprintf (buf, _("Odds Ratio for %s (%g / %g)"),
-                    x->vars[COL_VAR]->name, c[0].f, c[1].f);
+                    var_get_name (x->vars[COL_VAR]), c[0].f, c[1].f);
          else
            sprintf (buf, _("Odds Ratio for %s (%.*s / %.*s)"),
-                    x->vars[COL_VAR]->name,
-                    x->vars[COL_VAR]->width, c[0].s,
-                    x->vars[COL_VAR]->width, c[1].s);
+                    var_get_name (x->vars[COL_VAR]),
+                    var_get_width (x->vars[COL_VAR]), c[0].s,
+                    var_get_width (x->vars[COL_VAR]), c[1].s);
          break;
        case 1:
        case 2:
-         if (x->vars[ROW_VAR]->type == NUMERIC)
+         if (var_is_numeric (x->vars[ROW_VAR]))
            sprintf (buf, _("For cohort %s = %g"),
-                    x->vars[ROW_VAR]->name, rows[i - 1].f);
+                    var_get_name (x->vars[ROW_VAR]), rows[i - 1].f);
          else
            sprintf (buf, _("For cohort %s = %.*s"),
-                    x->vars[ROW_VAR]->name,
-                    x->vars[ROW_VAR]->width, rows[i - 1].s);
+                    var_get_name (x->vars[ROW_VAR]),
+                    var_get_width (x->vars[ROW_VAR]), rows[i - 1].s);
          break;
        }
                   
@@ -2202,15 +2200,15 @@ display_directional (void)
              
              for (; j < 3; j++)
                {
-                 char *string;
+                 const char *string;
                  int k = last[j] = stats_lookup[j][i];
 
                  if (k == 0)
                    string = NULL;
                  else if (k == 1)
-                   string = x->vars[0]->name;
+                   string = var_get_name (x->vars[0]);
                  else
-                   string = x->vars[1]->name;
+                   string = var_get_name (x->vars[1]);
                  
                  tab_text (direct, j, 0, TAB_LEFT | TAT_PRINTF,
                            gettext (stats_names[j][k]), string);
@@ -2273,9 +2271,9 @@ calc_fisher (int a, int b, int c, int d, double *fisher1, double *fisher2)
 {
   int x;
   
-  if (min (c, d) < min (a, b))
+  if (MIN (c, d) < MIN (a, b))
     swap (&a, &c), swap (&b, &d);
-  if (min (b, d) < min (a, c))
+  if (MIN (b, d) < MIN (a, c))
     swap (&a, &b), swap (&c, &d);
   if (b * c < a * d)
     {
@@ -2380,7 +2378,7 @@ calc_chisq (double chisq[N_CHISQ], int df[N_CHISQ],
     }
 
   /* Calculate Mantel-Haenszel. */
-  if (x->vars[ROW_VAR]->type == NUMERIC && x->vars[COL_VAR]->type == NUMERIC)
+  if (var_is_numeric (x->vars[ROW_VAR]) && var_is_numeric (x->vars[COL_VAR]))
     {
       double r, ase_0, ase_1;
       calc_r ((double *) rows, (double *) cols, &r, &ase_0, &ase_1);
@@ -2467,7 +2465,7 @@ static int
 calc_symmetric (double v[N_SYMMETRIC], double ase[N_SYMMETRIC],
                double t[N_SYMMETRIC])
 {
-  int q = min (ns_rows, ns_cols);
+  int q = MIN (ns_rows, ns_cols);
   
   if (q <= 1)
     return 0;
@@ -3184,22 +3182,22 @@ format_short (char *s, const struct fmt_spec *fp, const union value *v)
   struct fmt_spec fmt_subst;
 
   /* Limit to short string width. */
-  if (formats[fp->type].cat & FCAT_STRING
+  if (fmt_is_string (fp->type)
     {
       fmt_subst = *fp;
 
       assert (fmt_subst.type == FMT_A || fmt_subst.type == FMT_AHEX);
       if (fmt_subst.type == FMT_A)
-        fmt_subst.w = min (8, fmt_subst.w);
+        fmt_subst.w = MIN (8, fmt_subst.w);
       else
-        fmt_subst.w = min (16, fmt_subst.w);
+        fmt_subst.w = MIN (16, fmt_subst.w);
 
       fp = &fmt_subst;
     }
 
   /* Format. */
-  data_out (s, fp, v);
-  
+  data_out (v, fp, s);
+    
   /* Null terminate. */
   s[fp->w] = '\0';
 }