CROSSTABS: Improve error messages and coding style.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 11 Nov 2022 06:13:32 +0000 (22:13 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 11 Nov 2022 06:13:32 +0000 (22:13 -0800)
src/language/stats/crosstabs.c
tests/language/stats/crosstabs.at

index 2205544d901bb96a164eacf330b40ffd078a540f..7211d38d53b816e5b68970d9051bfb38734c7f1b 100644 (file)
@@ -155,11 +155,11 @@ struct crosstabulation
     double missing;             /* Weight of missing cases. */
 
     /* Variables (2 or more). */
-    int n_vars;
+    size_t n_vars;
     struct xtab_var *vars;
 
     /* Constants (0 or more). */
-    int n_consts;
+    size_t n_consts;
     struct xtab_var *const_vars;
     size_t *const_indexes;
 
@@ -170,7 +170,7 @@ struct crosstabulation
 
     /* Number of statistically interesting columns/rows
        (columns/rows with data in them). */
-    int ns_cols, ns_rows;
+    size_t ns_cols, ns_rows;
 
     /* Matrix contents. */
     double *mat;               /* Matrix proper. */
@@ -209,10 +209,10 @@ struct crosstabs_proc
 
     /* TABLES. */
     struct crosstabulation *pivots;
-    int n_pivots;
+    size_t n_pivots;
 
     /* CELLS. */
-    int n_cells;               /* Number of cells requested. */
+    size_t n_cells;            /* Number of cells requested. */
     unsigned int cells;         /* Bit k is 1 if cell k is requested. */
     int a_cells[CRS_N_CELLS];   /* 0...n_cells-1 are the requested cells. */
 
@@ -250,13 +250,13 @@ round_weight (const struct crosstabs_proc *proc, double weight)
 }
 
 #define FOR_EACH_POPULATED_COLUMN(C, XT) \
-  for (int C = next_populated_column (0, XT); \
+  for (size_t C = next_populated_column (0, XT); \
        C < (XT)->vars[COL_VAR].n_values;      \
        C = next_populated_column (C + 1, XT))
-static int
-next_populated_column (int c, const struct crosstabulation *xt)
+static size_t
+next_populated_column (size_t c, const struct crosstabulation *xt)
 {
-  int n_columns = xt->vars[COL_VAR].n_values;
+  size_t n_columns = xt->vars[COL_VAR].n_values;
   for (; c < n_columns; c++)
     if (xt->col_tot[c])
       break;
@@ -264,12 +264,12 @@ next_populated_column (int c, const struct crosstabulation *xt)
 }
 
 #define FOR_EACH_POPULATED_ROW(R, XT) \
-  for (int R = next_populated_row (0, XT); R < (XT)->vars[ROW_VAR].n_values; \
+  for (size_t R = next_populated_row (0, XT); R < (XT)->vars[ROW_VAR].n_values; \
        R = next_populated_row (R + 1, XT))
-static int
-next_populated_row (int r, const struct crosstabulation *xt)
+static size_t
+next_populated_row (size_t r, const struct crosstabulation *xt)
 {
-  int n_rows = xt->vars[ROW_VAR].n_values;
+  size_t n_rows = xt->vars[ROW_VAR].n_values;
   for (; r < n_rows; r++)
     if (xt->row_tot[r])
       break;
@@ -330,7 +330,7 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
             proc.exclude = 0;
           else
             {
-              lex_error (lexer, NULL);
+              lex_error_expecting (lexer, "TABLE", "INCLUDE", "REPORT");
               goto exit;
             }
         }
@@ -365,7 +365,8 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
                 proc.round_down = true;
               else
                 {
-                  lex_error (lexer, NULL);
+                  lex_error_expecting (lexer, "ASIS", "CASE", "CELL",
+                                       "ROUND", "TRUNCATE");
                   goto exit;
                 }
               lex_match (lexer, T_COMMA);
@@ -386,7 +387,8 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
                 show_tables = false;
               else
                 {
-                  lex_error (lexer, NULL);
+                  lex_error_expecting (lexer, "AVALUE", "DVALUE",
+                                       "TABLES", "NOTABLES");
                   goto exit;
                 }
               lex_match (lexer, T_COMMA);
@@ -415,7 +417,15 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
                     }
                   CRS_CELLS
 #undef C
-                  lex_error (lexer, NULL);
+
+                  static const char *cells[] =
+                    {
+#define C(KEYWORD, STRING, RC) #KEYWORD,
+                      CRS_CELLS
+#undef C
+                    };
+                  lex_error_expecting_array (lexer, cells,
+                                             sizeof cells / sizeof *cells);
                   goto exit;
                 }
               if (!proc.cells)
@@ -444,7 +454,14 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
                     }
                   CRS_STATISTICS
 #undef S
-                  lex_error (lexer, NULL);
+                  static const char *stats[] =
+                    {
+#define S(KEYWORD) #KEYWORD,
+                      CRS_STATISTICS
+#undef S
+                    };
+                  lex_error_expecting_array (lexer, stats,
+                                             sizeof stats / sizeof *stats);
                   goto exit;
                 }
               if (!proc.statistics)
@@ -470,7 +487,7 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
   /* Cells. */
   if (!show_tables)
     proc.cells = 0;
-  for (int i = 0; i < CRS_N_CELLS; i++)
+  for (size_t i = 0; i < CRS_N_CELLS; i++)
     if (proc.cells & (1u << i))
       proc.a_cells[proc.n_cells++] = i;
   assert (proc.n_cells < CRS_N_CELLS);
@@ -478,9 +495,9 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
   /* Missing values. */
   if (proc.mode == GENERAL && !proc.exclude)
     {
-      lex_ofs_error (lexer, exclude_ofs, exclude_ofs,
-                     _("Missing mode %s not allowed in general mode.  "
-                       "Assuming %s."), "REPORT", "MISSING=TABLE");
+      lex_ofs_msg (lexer, SW, exclude_ofs, exclude_ofs,
+                   _("Missing mode %s not allowed in general mode.  "
+                     "Assuming %s."), "REPORT", "MISSING=TABLE");
       proc.exclude = MV_ANY;
     }
 
@@ -491,10 +508,8 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
   struct casereader *group;
   while (casegrouper_get_next_group (grouper, &group))
     {
-      struct ccase *c;
-
       /* Output SPLIT FILE variables. */
-      c = casereader_peek (group, 0);
+      struct ccase *c = casereader_peek (group, 0);
       if (c != NULL)
         {
           output_split_file_values (ds, c);
@@ -537,7 +552,7 @@ cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
   bool ok = casegrouper_destroy (grouper);
   ok = proc_commit (ds) && ok;
 
-  result = ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
+  result = ok ? CMD_SUCCESS : CMD_FAILURE;
 
 exit:
   free (proc.variables);
@@ -576,7 +591,8 @@ parse_crosstabs_tables (struct lexer *lexer, struct dataset *ds,
          dict_lookup_var (dataset_dict (ds), lex_tokcstr (lexer)) == NULL)
       && lex_token (lexer) != T_ALL)
     {
-      lex_error (lexer, NULL);
+      lex_error (lexer, _("Syntax error expecting subcommand name or "
+                          "variable name."));
       return false;
     }
   lex_match (lexer, T_EQUALS);
@@ -588,39 +604,37 @@ parse_crosstabs_tables (struct lexer *lexer, struct dataset *ds,
        : const_var_set_create_from_dict (dataset_dict (ds)));
 
   size_t nx = 1;
-  int n_by = 0;
+  size_t n_by = 0;
   int vars_start = lex_ofs (lexer);
-  for (;;)
+  do
     {
       by = xnrealloc (by, n_by + 1, sizeof *by);
       by_nvar = xnrealloc (by_nvar, n_by + 1, sizeof *by_nvar);
       if (!parse_const_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]))
+      size_t n = by_nvar[n_by++];
+      if (xalloc_oversized (nx, n))
         {
           lex_ofs_error (
-            lexer, vars_start, lex_ofs (lexer),
+            lexer, vars_start, lex_ofs (lexer) - 1,
             _("Too many cross-tabulation variables or dimensions."));
           goto done;
         }
-      nx *= by_nvar[n_by];
-      n_by++;
-
-      if (!lex_match (lexer, T_BY))
-       {
-         if (n_by < 2)
-           goto done;
-         else
-           break;
-       }
+      nx *= n;
+    }
+  while (lex_match (lexer, T_BY));
+  if (n_by < 2)
+    {
+      bool unused UNUSED = lex_force_match (lexer, T_BY);
+      goto done;
     }
   int vars_end = lex_ofs (lexer) - 1;
 
-  int *by_iter = XCALLOC (n_by, int);
+  size_t *by_iter = XCALLOC (n_by, size_t);
   proc->pivots = xnrealloc (proc->pivots,
                             proc->n_pivots + nx, sizeof *proc->pivots);
-  for (int i = 0; i < nx; i++)
+  for (size_t i = 0; i < nx; i++)
     {
       struct crosstabulation *xt = &proc->pivots[proc->n_pivots++];
 
@@ -637,7 +651,7 @@ parse_crosstabs_tables (struct lexer *lexer, struct dataset *ds,
         .end_ofs = vars_end,
       };
 
-      for (int j = 0; j < n_by; j++)
+      for (size_t j = 0; j < n_by; j++)
         xt->vars[j].var = by[j][by_iter[j]];
 
       for (int j = n_by - 1; j >= 0; j--)
@@ -652,7 +666,7 @@ parse_crosstabs_tables (struct lexer *lexer, struct dataset *ds,
 
 done:
   /* All return paths lead here. */
-  for (int i = 0; i < n_by; i++)
+  for (size_t i = 0; i < n_by; i++)
     free (by[i]);
   free (by);
   free (by_nvar);
@@ -708,11 +722,12 @@ parse_crosstabs_variables (struct lexer *lexer, struct dataset *ds,
         {
           const struct variable *var = proc->variables[i];
           struct var_range *vr = xmalloc (sizeof *vr);
-
-          vr->var = var;
-          vr->min = min;
-         vr->max = max;
-         vr->count = max - min + 1;
+          *vr = (struct var_range) {
+            .var = var,
+            .min = min,
+            .max = max,
+            .count = max - min + 1,
+          };
           hmap_insert (&proc->var_ranges, &vr->hmap_node,
                        hash_pointer (var, 0));
        }
@@ -753,8 +768,7 @@ static bool
 should_tabulate_case (const struct crosstabulation *xt, const struct ccase *c,
                       enum mv_class exclude)
 {
-  int j;
-  for (j = 0; j < xt->n_vars; j++)
+  for (size_t j = 0; j < xt->n_vars; j++)
     {
       const struct variable *var = xt->vars[j].var;
       const struct var_range *range = get_var_range (xt->proc, var);
@@ -776,20 +790,17 @@ static void
 tabulate_integer_case (struct crosstabulation *xt, const struct ccase *c,
                        double weight)
 {
-  struct freq *te;
-  size_t hash;
-  int j;
-
-  hash = 0;
-  for (j = 0; j < xt->n_vars; j++)
+  size_t hash = 0;
+  for (size_t j = 0; j < xt->n_vars; j++)
     {
       /* Throw away fractional parts of values. */
       hash = hash_int (case_num (c, xt->vars[j].var), hash);
     }
 
+  struct freq *te;
   HMAP_FOR_EACH_WITH_HASH (te, struct freq, node, hash, &xt->data)
     {
-      for (j = 0; j < xt->n_vars; j++)
+      for (size_t j = 0; j < xt->n_vars; j++)
         if ((int) case_num (c, xt->vars[j].var) != (int) te->values[j].f)
           goto no_match;
 
@@ -803,7 +814,7 @@ tabulate_integer_case (struct crosstabulation *xt, const struct ccase *c,
   /* No existing entry.  Create a new one. */
   te = xmalloc (table_entry_size (xt->n_vars));
   te->count = weight;
-  for (j = 0; j < xt->n_vars; j++)
+  for (size_t j = 0; j < xt->n_vars; j++)
     te->values[j].f = (int) case_num (c, xt->vars[j].var);
   hmap_insert (&xt->data, &te->node, hash);
 }
@@ -812,20 +823,17 @@ static void
 tabulate_general_case (struct crosstabulation *xt, const struct ccase *c,
                        double weight)
 {
-  struct freq *te;
-  size_t hash;
-  int j;
-
-  hash = 0;
-  for (j = 0; j < xt->n_vars; j++)
+  size_t hash = 0;
+  for (size_t j = 0; j < xt->n_vars; j++)
     {
       const struct variable *var = xt->vars[j].var;
       hash = value_hash (case_data (c, var), var_get_width (var), hash);
     }
 
+  struct freq *te;
   HMAP_FOR_EACH_WITH_HASH (te, struct freq, node, hash, &xt->data)
     {
-      for (j = 0; j < xt->n_vars; j++)
+      for (size_t j = 0; j < xt->n_vars; j++)
         {
           const struct variable *var = xt->vars[j].var;
           if (!value_equal (case_data (c, var), &te->values[j],
@@ -843,7 +851,7 @@ tabulate_general_case (struct crosstabulation *xt, const struct ccase *c,
   /* No existing entry.  Create a new one. */
   te = xmalloc (table_entry_size (xt->n_vars));
   te->count = weight;
-  for (j = 0; j < xt->n_vars; j++)
+  for (size_t j = 0; j < xt->n_vars; j++)
     {
       const struct variable *var = xt->vars[j].var;
       value_clone (&te->values[j], case_data (c, var), var_get_width (var));
@@ -902,19 +910,19 @@ postcalc (struct crosstabs_proc *proc, struct lexer *lexer)
   for (struct crosstabulation *xt = proc->pivots;
        xt < &proc->pivots[proc->n_pivots]; xt++)
     {
-      struct freq *e;
-
       xt->n_entries = hmap_count (&xt->data);
       xt->entries = xnmalloc (xt->n_entries, sizeof *xt->entries);
+
       size_t i = 0;
+      struct freq *e;
       HMAP_FOR_EACH (e, struct freq, node, &xt->data)
         xt->entries[i++] = e;
+
       hmap_destroy (&xt->data);
 
       sort (xt->entries, xt->n_entries, sizeof *xt->entries,
             proc->descending ? compare_table_entry_3way_inv : compare_table_entry_3way,
            xt);
-
     }
 
   make_summary_table (proc);
@@ -954,12 +962,8 @@ postcalc (struct crosstabs_proc *proc, struct lexer *lexer)
         {
           int width = var_get_width (xt->vars[i].var);
           if (value_needs_init (width))
-            {
-              size_t j;
-
-              for (j = 0; j < xt->n_entries; j++)
-                value_destroy (&xt->entries[j]->values[i], width);
-            }
+            for (size_t j = 0; j < xt->n_entries; j++)
+              value_destroy (&xt->entries[j]->values[i], width);
         }
 
       for (size_t i = 0; i < xt->n_entries; i++)
@@ -1018,9 +1022,7 @@ compare_table_entry_vars_3way (const struct freq *a,
                                const struct crosstabulation *xt,
                                int idx0, int idx1)
 {
-  int i;
-
-  for (i = idx1 - 1; i >= idx0; i--)
+  for (int i = idx1 - 1; i >= idx0; i--)
     {
       int cmp = compare_table_entry_var_3way (a, b, xt, i);
       if (cmp != 0)
@@ -1039,9 +1041,8 @@ compare_table_entry_3way (const void *ap_, const void *bp_, const void *xt_)
   const struct freq *a = *ap;
   const struct freq *b = *bp;
   const struct crosstabulation *xt = xt_;
-  int cmp;
 
-  cmp = compare_table_entry_vars_3way (a, b, xt, 2, xt->n_vars);
+  int cmp = compare_table_entry_vars_3way (a, b, xt, 2, xt->n_vars);
   if (cmp != 0)
     return cmp;
 
@@ -1147,10 +1148,9 @@ output_crosstabulation (struct crosstabs_proc *proc, struct crosstabulation *xt,
   if (xt->vars[COL_VAR].n_values == 0)
     {
       struct string vars;
-      int i;
 
       ds_init_cstr (&vars, var_to_string (xt->vars[0].var));
-      for (i = 1; i < xt->n_vars; i++)
+      for (size_t i = 1; i < xt->n_vars; i++)
         ds_put_format (&vars, " Ã— %s", var_to_string (xt->vars[i].var));
 
       /* TRANSLATORS: The %s here describes a crosstabulation.  It takes the
@@ -1258,13 +1258,11 @@ build_matrix (struct crosstabulation *x)
   const int row_var_width = var_get_width (x->vars[ROW_VAR].var);
   size_t n_rows = x->vars[ROW_VAR].n_values;
   size_t n_cols = x->vars[COL_VAR].n_values;
-  int col, row;
-  double *mp;
-  struct freq **p;
 
-  mp = x->mat;
-  col = row = 0;
-  for (p = x->entries; p < &x->entries[x->n_entries]; p++)
+  double *mp = x->mat;
+  size_t col = 0;
+  size_t row = 0;
+  for (struct freq **p = x->entries; p < &x->entries[x->n_entries]; p++)
     {
       const struct freq *te = *p;
 
@@ -1575,23 +1573,22 @@ delete_missing (struct crosstabulation *xt)
 {
   size_t n_rows = xt->vars[ROW_VAR].n_values;
   size_t n_cols = xt->vars[COL_VAR].n_values;
-  int r, c;
 
-  for (r = 0; r < n_rows; r++)
+  for (size_t r = 0; r < n_rows; r++)
     if (var_is_num_missing (xt->vars[ROW_VAR].var,
                             xt->vars[ROW_VAR].values[r].f) == MV_USER)
       {
-        for (c = 0; c < n_cols; c++)
+        for (size_t c = 0; c < n_cols; c++)
           xt->mat[c + r * n_cols] = 0.;
         xt->ns_rows--;
       }
 
 
-  for (c = 0; c < n_cols; c++)
+  for (size_t c = 0; c < n_cols; c++)
     if (var_is_num_missing (xt->vars[COL_VAR].var,
                             xt->vars[COL_VAR].values[c].f) == MV_USER)
       {
-        for (r = 0; r < n_rows; r++)
+        for (size_t r = 0; r < n_rows; r++)
           xt->mat[c + r * n_cols] = 0.;
         xt->ns_cols--;
       }
@@ -1601,11 +1598,10 @@ static bool
 find_crosstab (struct crosstabulation *xt, size_t *row0p, size_t *row1p)
 {
   size_t row0 = *row1p;
-  size_t row1;
-
   if (row0 >= xt->n_entries)
     return false;
 
+  size_t row1;
   for (row1 = row0 + 1; row1 < xt->n_entries; row1++)
     {
       struct freq *a = xt->entries[row0];
@@ -1660,17 +1656,16 @@ enum_var_values (const struct crosstabulation *xt, int var_idx,
   else
     {
       int width = var_get_width (xv->var);
-      struct hmapx_node *node;
-      const union value *iter;
-      struct hmapx set;
+      struct hmapx set = HMAPX_INITIALIZER (set);
 
-      hmapx_init (&set);
       for (size_t i = 0; i < xt->n_entries; i++)
         {
           const struct freq *te = xt->entries[i];
           const union value *value = &te->values[var_idx];
           size_t hash = value_hash (value, width, 0);
 
+          const union value *iter;
+          struct hmapx_node *node;
           HMAPX_FOR_EACH_WITH_HASH (iter, node, hash, &set)
             if (value_equal (iter, value, width))
               goto next_entry;
@@ -1683,6 +1678,8 @@ enum_var_values (const struct crosstabulation *xt, int var_idx,
       xv->n_values = hmapx_count (&set);
       xv->values = xnmalloc (xv->n_values, sizeof *xv->values);
       size_t i = 0;
+      const union value *iter;
+      struct hmapx_node *node;
       HMAPX_FOR_EACH (iter, node, &set)
         xv->values[i++] = *iter;
       hmapx_destroy (&set);
@@ -1811,7 +1808,7 @@ display_crosstabulation (struct crosstabs_proc *proc,
       };
       for (size_t i = 0; i < proc->n_cells; i++)
         {
-          int cell = proc->a_cells[i];
+          size_t cell = proc->a_cells[i];
           double entry = entries[cell];
           if (entry != SYSMIS)
             {
@@ -1845,7 +1842,7 @@ display_chisq (struct crosstabulation *xt, struct pivot_table *chisq)
   assert (xt->n_vars == 2);
   for (size_t i = 0; i < xt->n_consts; i++)
     indexes[i + 2] = xt->const_indexes[i];
-  for (int i = 0; i < N_CHISQ; i++)
+  for (size_t i = 0; i < N_CHISQ; i++)
     {
       indexes[0] = i;
 
@@ -1879,10 +1876,10 @@ display_chisq (struct crosstabulation *xt, struct pivot_table *chisq)
   free (indexes);
 }
 
-static int calc_symmetric (struct crosstabs_proc *, struct crosstabulation *,
-                           double[N_SYMMETRIC], double[N_SYMMETRIC],
-                          double[N_SYMMETRIC],
-                           double[3], double[3], double[3]);
+static bool calc_symmetric (struct crosstabs_proc *, struct crosstabulation *,
+                            double[N_SYMMETRIC], double[N_SYMMETRIC],
+                            double[N_SYMMETRIC],
+                            double[3], double[3], double[3]);
 
 /* Display symmetric measures. */
 static void
@@ -1901,7 +1898,7 @@ display_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
   for (size_t i = 0; i < xt->n_consts; i++)
     indexes[i + 2] = xt->const_indexes[i];
 
-  for (int i = 0; i < N_SYMMETRIC; i++)
+  for (size_t i = 0; i < N_SYMMETRIC; i++)
     {
       if (sym_v[i] == SYSMIS)
        continue;
@@ -1947,7 +1944,7 @@ display_risk (struct crosstabulation *xt, struct pivot_table *risk,
   for (size_t i = 0; i < xt->n_consts; i++)
     indexes[i + 2] = xt->const_indexes[i];
 
-  for (int i = 0; i < 3; i++)
+  for (size_t i = 0; i < 3; i++)
     {
       const struct variable *cv = xt->vars[COL_VAR].var;
       const struct variable *rv = xt->vars[ROW_VAR].var;
@@ -1994,9 +1991,9 @@ display_risk (struct crosstabulation *xt, struct pivot_table *risk,
   free (indexes);
 }
 
-static int calc_directional (struct crosstabs_proc *, struct crosstabulation *,
-                             double[N_DIRECTIONAL], double[N_DIRECTIONAL],
-                            double[N_DIRECTIONAL], double[N_DIRECTIONAL]);
+static void calc_directional (struct crosstabs_proc *, struct crosstabulation *,
+                              double[N_DIRECTIONAL], double[N_DIRECTIONAL],
+                              double[N_DIRECTIONAL], double[N_DIRECTIONAL]);
 
 /* Display directional measures. */
 static void
@@ -2007,15 +2004,14 @@ display_directional (struct crosstabs_proc *proc,
   double direct_ase[N_DIRECTIONAL];
   double direct_t[N_DIRECTIONAL];
   double sig[N_DIRECTIONAL];
-  if (!calc_directional (proc, xt, direct_v, direct_ase, direct_t, sig))
-    return;
+  calc_directional (proc, xt, direct_v, direct_ase, direct_t, sig);
 
   size_t *indexes = xnmalloc (direct->n_dimensions, sizeof *indexes);
   assert (xt->n_vars == 2);
   for (size_t i = 0; i < xt->n_consts; i++)
     indexes[i + 2] = xt->const_indexes[i];
 
-  for (int i = 0; i < N_DIRECTIONAL; i++)
+  for (size_t i = 0; i < N_DIRECTIONAL; i++)
     {
       if (direct_v[i] == SYSMIS)
        continue;
@@ -2045,11 +2041,8 @@ static double
 log_gamma_int (double xt)
 {
   double r = 0;
-  int i;
-
-  for (i = 2; i < xt; i++)
+  for (int i = 2; i < xt; i++)
     r += log(i);
-
   return r;
 }
 
@@ -2079,9 +2072,6 @@ swap (int *a, int *b)
 static void
 calc_fisher (int a, int b, int c, int d, double *fisher1, double *fisher2)
 {
-  int xt;
-  double pn1;
-
   if (MIN (c, d) < MIN (a, b))
     swap (&a, &c), swap (&b, &d);
   if (MIN (b, d) < MIN (a, c))
@@ -2094,16 +2084,13 @@ calc_fisher (int a, int b, int c, int d, double *fisher1, double *fisher2)
        swap (&a, &c), swap (&b, &d);
     }
 
-  pn1 = Pr (a, b, c, d);
+  double pn1 = Pr (a, b, c, d);
   *fisher1 = pn1;
-  for (xt = 1; xt <= a; xt++)
-    {
-      *fisher1 += Pr (a - xt, b + xt, c + xt, d - xt);
-    }
+  for (int xt = 1; xt <= a; xt++)
+    *fisher1 += Pr (a - xt, b + xt, c + xt, d - xt);
 
   *fisher2 = *fisher1;
-
-  for (xt = 1; xt <= b; xt++)
+  for (int xt = 1; xt <= b; xt++)
     {
       double p = Pr (a + xt, b - xt, c - xt, d + xt);
       if (p < pn1)
@@ -2155,39 +2142,33 @@ calc_chisq (struct crosstabulation *xt,
   /* Calculate Yates and Fisher exact test. */
   if (xt->ns_cols == 2 && xt->ns_rows == 2)
     {
-      double f11, f12, f21, f22;
-
-      {
-       int nz_cols[2];
+      int nz_cols[2];
 
-        int j = 0;
-        FOR_EACH_POPULATED_COLUMN (c, xt)
-          {
-            nz_cols[j++] = c;
-            if (j == 2)
-              break;
-          }
-       assert (j == 2);
+      size_t j = 0;
+      FOR_EACH_POPULATED_COLUMN (c, xt)
+        {
+          nz_cols[j++] = c;
+          if (j == 2)
+            break;
+        }
+      assert (j == 2);
 
-       f11 = xt->mat[nz_cols[0]];
-       f12 = xt->mat[nz_cols[1]];
-       f21 = xt->mat[nz_cols[0] + n_cols];
-       f22 = xt->mat[nz_cols[1] + n_cols];
-      }
+      double f11 = xt->mat[nz_cols[0]];
+      double f12 = xt->mat[nz_cols[1]];
+      double f21 = xt->mat[nz_cols[0] + n_cols];
+      double f22 = xt->mat[nz_cols[1] + n_cols];
 
       /* Yates. */
-      {
-       const double xt_ = fabs (f11 * f22 - f12 * f21) - 0.5 * xt->total;
+      const double xt_ = fabs (f11 * f22 - f12 * f21) - 0.5 * xt->total;
 
-       if (xt_ > 0.)
-         chisq[3] = (xt->total * pow2 (xt_)
-                     / (f11 + f12) / (f21 + f22)
-                     / (f11 + f21) / (f12 + f22));
-       else
-         chisq[3] = 0.;
+      if (xt_ > 0.)
+        chisq[3] = (xt->total * pow2 (xt_)
+                    / (f11 + f12) / (f21 + f22)
+                    / (f11 + f21) / (f12 + f22));
+      else
+        chisq[3] = 0.;
 
-       df[3] = 1.;
-      }
+      df[3] = 1.;
 
       /* Fisher. */
       calc_fisher (f11 + .5, f12 + .5, f21 + .5, f22 + .5, fisher1, fisher2);
@@ -2216,70 +2197,63 @@ calc_r (struct crosstabulation *xt,
 {
   size_t n_rows = xt->vars[ROW_VAR].n_values;
   size_t n_cols = xt->vars[COL_VAR].n_values;
-  double SX, SY, S, T;
-  double Xbar, Ybar;
-  double sum_XYf, sum_X2Y2f;
-  double sum_Xr, sum_X2r;
-  double sum_Yc, sum_Y2c;
-  int i, j;
-
-  for (sum_X2Y2f = sum_XYf = 0., i = 0; i < n_rows; i++)
-    for (j = 0; j < n_cols; j++)
+
+  double sum_XYf = 0;
+  for (size_t i = 0; i < n_rows; i++)
+    for (size_t j = 0; j < n_cols; j++)
       {
        double fij = xt->mat[j + i * n_cols];
        double product = XT[i] * Y[j];
        double temp = fij * product;
        sum_XYf += temp;
-       sum_X2Y2f += temp * product;
       }
 
-  for (sum_Xr = sum_X2r = 0., i = 0; i < n_rows; i++)
+  double sum_Xr = 0;
+  double sum_X2r = 0;
+  for (size_t i = 0; i < n_rows; i++)
     {
       sum_Xr += XT[i] * xt->row_tot[i];
       sum_X2r += pow2 (XT[i]) * xt->row_tot[i];
     }
-  Xbar = sum_Xr / xt->total;
+  double Xbar = sum_Xr / xt->total;
 
-  for (sum_Yc = sum_Y2c = 0., i = 0; i < n_cols; i++)
+  double sum_Yc = 0;
+  double sum_Y2c = 0;
+  for (size_t i = 0; i < n_cols; i++)
     {
       sum_Yc += Y[i] * xt->col_tot[i];
       sum_Y2c += Y[i] * Y[i] * xt->col_tot[i];
     }
-  Ybar = sum_Yc / xt->total;
+  double Ybar = sum_Yc / xt->total;
 
-  S = sum_XYf - sum_Xr * sum_Yc / xt->total;
-  SX = sum_X2r - pow2 (sum_Xr) / xt->total;
-  SY = sum_Y2c - pow2 (sum_Yc) / xt->total;
-  T = sqrt (SX * SY);
+  double S = sum_XYf - sum_Xr * sum_Yc / xt->total;
+  double SX = sum_X2r - pow2 (sum_Xr) / xt->total;
+  double SY = sum_Y2c - pow2 (sum_Yc) / xt->total;
+  double T = sqrt (SX * SY);
   *r = S / T;
   *t = *r / sqrt (1 - pow2 (*r)) * sqrt (xt->total - 2);
 
-  {
-    double s, c, y, t;
-
-    for (s = c = 0., i = 0; i < n_rows; i++)
-      for (j = 0; j < n_cols; j++)
-       {
-         double Xresid, Yresid;
-         double temp;
-
-         Xresid = XT[i] - Xbar;
-         Yresid = Y[j] - Ybar;
-         temp = (T * Xresid * Yresid
-                 - ((S / (2. * T))
-                    * (Xresid * Xresid * SY + Yresid * Yresid * SX)));
-         y = xt->mat[j + i * n_cols] * temp * temp - c;
-         t = s + y;
-         c = (t - s) - y;
-         s = t;
-       }
-    *error = sqrt (s) / (T * T);
-  }
+  double s = 0;
+  double c = 0;
+  for (size_t i = 0; i < n_rows; i++)
+    for (size_t j = 0; j < n_cols; j++)
+      {
+        double Xresid = XT[i] - Xbar;
+        double Yresid = Y[j] - Ybar;
+        double temp = (T * Xresid * Yresid
+                       - ((S / (2. * T))
+                          * (Xresid * Xresid * SY + Yresid * Yresid * SX)));
+        double y = xt->mat[j + i * n_cols] * temp * temp - c;
+        double t = s + y;
+        c = (t - s) - y;
+        s = t;
+      }
+  *error = sqrt (s) / (T * T);
 }
 
 /* Calculate symmetric statistics and their asymptotic standard
-   errors.  Returns 0 if none could be calculated. */
-static int
+   errors.  Returns false if none could be calculated. */
+static bool
 calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
                 double v[N_SYMMETRIC], double ase[N_SYMMETRIC],
                double t[N_SYMMETRIC],
@@ -2288,13 +2262,12 @@ calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
 {
   size_t n_rows = xt->vars[ROW_VAR].n_values;
   size_t n_cols = xt->vars[COL_VAR].n_values;
-  int q, i;
 
-  q = MIN (xt->ns_rows, xt->ns_cols);
+  size_t q = MIN (xt->ns_rows, xt->ns_cols);
   if (q <= 1)
-    return 0;
+    return false;
 
-  for (i = 0; i < N_SYMMETRIC; i++)
+  for (size_t i = 0; i < N_SYMMETRIC; i++)
     v[i] = ase[i] = t[i] = SYSMIS;
 
   /* Phi, Cramer's V, contingency coefficient. */
@@ -2324,66 +2297,56 @@ calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
   if (proc->statistics & (CRS_ST_BTAU | CRS_ST_CTAU
                           | CRS_ST_GAMMA | CRS_ST_D))
     {
-      double *cum;
-      double Dr, Dc;
-      double P, Q;
-      double btau_cum, ctau_cum, gamma_cum, d_yx_cum, d_xy_cum;
-      double btau_var;
-      int r, c;
-
-      Dr = Dc = pow2 (xt->total);
-      for (r = 0; r < n_rows; r++)
+      double Dr = pow2 (xt->total);
+      for (size_t r = 0; r < n_rows; r++)
         Dr -= pow2 (xt->row_tot[r]);
-      for (c = 0; c < n_cols; c++)
+
+      double Dc = pow2 (xt->total);
+      for (size_t c = 0; c < n_cols; c++)
         Dc -= pow2 (xt->col_tot[c]);
 
-      cum = xnmalloc (n_cols * n_rows, sizeof *cum);
-      for (c = 0; c < n_cols; c++)
+      double *cum = xnmalloc (n_cols * n_rows, sizeof *cum);
+      for (size_t c = 0; c < n_cols; c++)
         {
           double ct = 0.;
 
-          for (r = 0; r < n_rows; r++)
+          for (size_t r = 0; r < n_rows; r++)
             cum[c + r * n_cols] = ct += xt->mat[c + r * n_cols];
         }
 
       /* P and Q. */
-      {
-       int i, j;
-       double Cij, Dij;
+      double P = 0;
+      double Q = 0;
+      for (size_t i = 0; i < n_rows; i++)
+        {
+          double Cij = 0;
+          for (size_t j = 1; j < n_cols; j++)
+            Cij += xt->col_tot[j] - cum[j + i * n_cols];
 
-       P = Q = 0.;
-       for (i = 0; i < n_rows; i++)
-         {
-           Cij = Dij = 0.;
+          double Dij = 0;
+          if (i > 0)
+            for (size_t j = 1; j < n_cols; j++)
+              Dij += cum[j + (i - 1) * n_cols];
 
-           for (j = 1; j < n_cols; j++)
-             Cij += xt->col_tot[j] - cum[j + i * n_cols];
+          for (size_t j = 0;;)
+            {
+              double fij = xt->mat[j + i * n_cols];
+              P += fij * Cij;
+              Q += fij * Dij;
 
-           if (i > 0)
-             for (j = 1; j < n_cols; j++)
-               Dij += cum[j + (i - 1) * n_cols];
+              if (++j >= n_cols)
+                break;
 
-           for (j = 0;;)
-             {
-               double fij = xt->mat[j + i * n_cols];
-               P += fij * Cij;
-               Q += fij * Dij;
-
-               if (++j == n_cols)
-                 break;
-               assert (j < n_cols);
-
-               Cij -= xt->col_tot[j] - cum[j + i * n_cols];
-               Dij += xt->col_tot[j - 1] - cum[j - 1 + i * n_cols];
-
-               if (i > 0)
-                 {
-                   Cij += cum[j - 1 + (i - 1) * n_cols];
-                   Dij -= cum[j + (i - 1) * n_cols];
-                 }
-             }
-         }
-      }
+              Cij -= xt->col_tot[j] - cum[j + i * n_cols];
+              Dij += xt->col_tot[j - 1] - cum[j - 1 + i * n_cols];
+
+              if (i > 0)
+                {
+                  Cij += cum[j - 1 + (i - 1) * n_cols];
+                  Dij -= cum[j + (i - 1) * n_cols];
+                }
+            }
+        }
 
       if (proc->statistics & CRS_ST_BTAU)
        v[3] = (P - Q) / sqrt (Dr * Dc);
@@ -2394,74 +2357,62 @@ calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
 
       /* ASE for tau-b, tau-c, gamma.  Calculations could be
         eliminated here, at expense of memory.  */
-      {
-       int i, j;
-       double Cij, Dij;
+      double btau_cum = 0;
+      double ctau_cum = 0;
+      double gamma_cum = 0;
+      double d_yx_cum = 0;
+      double d_xy_cum = 0;
+      for (size_t i = 0; i < n_rows; i++)
+        {
+          double Cij = 0;
+          for (size_t j = 1; j < n_cols; j++)
+            Cij += xt->col_tot[j] - cum[j + i * n_cols];
 
-       btau_cum = ctau_cum = gamma_cum = d_yx_cum = d_xy_cum = 0.;
-       for (i = 0; i < n_rows; i++)
-         {
-           Cij = Dij = 0.;
+          double Dij = 0;
+          if (i > 0)
+            for (size_t j = 1; j < n_cols; j++)
+              Dij += cum[j + (i - 1) * n_cols];
 
-           for (j = 1; j < n_cols; j++)
-             Cij += xt->col_tot[j] - cum[j + i * n_cols];
+          for (size_t j = 0;;)
+            {
+              double fij = xt->mat[j + i * n_cols];
 
-           if (i > 0)
-             for (j = 1; j < n_cols; j++)
-               Dij += cum[j + (i - 1) * n_cols];
+              if (proc->statistics & CRS_ST_BTAU)
+                btau_cum += fij * pow2 (2. * sqrt (Dr * Dc) * (Cij - Dij)
+                                        + v[3] * (xt->row_tot[i] * Dc
+                                                  + xt->col_tot[j] * Dr));
+              ctau_cum += fij * pow2 (Cij - Dij);
 
-           for (j = 0;;)
-             {
-               double fij = xt->mat[j + i * n_cols];
-
-               if (proc->statistics & CRS_ST_BTAU)
-                 {
-                   const double temp = (2. * sqrt (Dr * Dc) * (Cij - Dij)
-                                        + v[3] * (xt->row_tot[i] * Dc
-                                                  + xt->col_tot[j] * Dr));
-                   btau_cum += fij * temp * temp;
-                 }
-
-               {
-                 const double temp = Cij - Dij;
-                 ctau_cum += fij * temp * temp;
-               }
-
-               if (proc->statistics & CRS_ST_GAMMA)
-                 {
-                   const double temp = Q * Cij - P * Dij;
-                   gamma_cum += fij * temp * temp;
-                 }
-
-               if (proc->statistics & CRS_ST_D)
-                 {
-                   d_yx_cum += fij * pow2 (Dr * (Cij - Dij)
-                                            - (P - Q) * (xt->total - xt->row_tot[i]));
-                   d_xy_cum += fij * pow2 (Dc * (Dij - Cij)
-                                            - (Q - P) * (xt->total - xt->col_tot[j]));
-                 }
-
-               if (++j == n_cols)
-                 break;
-               assert (j < n_cols);
-
-               Cij -= xt->col_tot[j] - cum[j + i * n_cols];
-               Dij += xt->col_tot[j - 1] - cum[j - 1 + i * n_cols];
-
-               if (i > 0)
-                 {
-                   Cij += cum[j - 1 + (i - 1) * n_cols];
-                   Dij -= cum[j + (i - 1) * n_cols];
-                 }
-             }
-         }
-      }
+              if (proc->statistics & CRS_ST_GAMMA)
+                gamma_cum += fij * pow2 (Q * Cij - P * Dij);
+
+              if (proc->statistics & CRS_ST_D)
+                {
+                  d_yx_cum += fij * pow2 (Dr * (Cij - Dij)
+                                          - (P - Q) * (xt->total - xt->row_tot[i]));
+                  d_xy_cum += fij * pow2 (Dc * (Dij - Cij)
+                                          - (Q - P) * (xt->total - xt->col_tot[j]));
+                }
+
+              if (++j >= n_cols)
+                break;
+
+              Cij -= xt->col_tot[j] - cum[j + i * n_cols];
+              Dij += xt->col_tot[j - 1] - cum[j - 1 + i * n_cols];
+
+              if (i > 0)
+                {
+                  Cij += cum[j - 1 + (i - 1) * n_cols];
+                  Dij -= cum[j + (i - 1) * n_cols];
+                }
+            }
+        }
 
-      btau_var = ((btau_cum
-                  - (xt->total * pow2 (xt->total * (P - Q) / sqrt (Dr * Dc) * (Dr + Dc))))
-                 / pow2 (Dr * Dc));
       if (proc->statistics & CRS_ST_BTAU)
        {
+          double btau_var = ((btau_cum
+                              - (xt->total * pow2 (xt->total * (P - Q) / sqrt (Dr * Dc) * (Dr + Dc))))
+                             / pow2 (Dr * Dc));
          ase[3] = sqrt (btau_var);
          t[3] = v[3] / (2 * sqrt ((ctau_cum - (P - Q) * (P - Q) / xt->total)
                                   / (Dr * Dc)));
@@ -2504,41 +2455,27 @@ calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
   if (proc->statistics & CRS_ST_CORR)
     {
       double *R = xmalloc (sizeof *R * n_rows);
-      double *C = xmalloc (sizeof *C * n_cols);
-
-      {
-       double y, t, c = 0., s = 0.;
-       int i = 0;
-
-       for (;;)
-         {
-           R[i] = s + (xt->row_tot[i] + 1.) / 2.;
-           y = xt->row_tot[i] - c;
-           t = s + y;
-           c = (t - s) - y;
-           s = t;
-           if (++i == n_rows)
-             break;
-           assert (i < n_rows);
-         }
-      }
-
-      {
-       double y, t, c = 0., s = 0.;
-       int j = 0;
+      double c = 0;
+      double s = 0;
+      for (size_t i = 0; i < n_rows; i++)
+        {
+          R[i] = s + (xt->row_tot[i] + 1.) / 2.;
+          double y = xt->row_tot[i] - c;
+          double t = s + y;
+          c = (t - s) - y;
+          s = t;
+        }
 
-       for (;;)
-         {
-           C[j] = s + (xt->col_tot[j] + 1.) / 2;
-           y = xt->col_tot[j] - c;
-           t = s + y;
-           c = (t - s) - y;
-           s = t;
-           if (++j == n_cols)
-             break;
-           assert (j < n_cols);
-         }
-      }
+      double *C = xmalloc (sizeof *C * n_cols);
+      c = s = 0;
+      for (size_t j = 0; j < n_cols; j++)
+        {
+          C[j] = s + (xt->col_tot[j] + 1.) / 2;
+          double y = xt->col_tot[j] - c;
+          double t = s + y;
+          c = (t - s) - y;
+          s = t;
+        }
 
       calc_r (xt, R, C, &v[6], &t[6], &ase[6]);
 
@@ -2553,28 +2490,27 @@ calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
   /* Cohen's kappa. */
   if (proc->statistics & CRS_ST_KAPPA && xt->ns_rows == xt->ns_cols)
     {
-      double ase_under_h0;
-      double sum_fii, sum_rici, sum_fiiri_ci, sum_fijri_ci2, sum_riciri_ci;
-      int i, j;
-
-      for (sum_fii = sum_rici = sum_fiiri_ci = sum_riciri_ci = 0., i = j = 0;
-          i < xt->ns_rows; i++, j++)
+      double sum_fii = 0;
+      double sum_rici = 0;
+      double sum_fiiri_ci = 0;
+      double sum_riciri_ci = 0;
+      for (size_t i = 0, j = 0; i < xt->ns_rows; i++, j++)
        {
-         double prod, sum;
-
          while (xt->col_tot[j] == 0.)
            j++;
 
-         prod = xt->row_tot[i] * xt->col_tot[j];
-         sum = xt->row_tot[i] + xt->col_tot[j];
+         double prod = xt->row_tot[i] * xt->col_tot[j];
+         double sum = xt->row_tot[i] + xt->col_tot[j];
 
          sum_fii += xt->mat[j + i * n_cols];
          sum_rici += prod;
          sum_fiiri_ci += xt->mat[j + i * n_cols] * sum;
          sum_riciri_ci += prod * sum;
        }
-      for (sum_fijri_ci2 = 0., i = 0; i < xt->ns_rows; i++)
-       for (j = 0; j < xt->ns_cols; j++)
+
+      double sum_fijri_ci2 = 0;
+      for (size_t i = 0; i < xt->ns_rows; i++)
+       for (size_t j = 0; j < xt->ns_cols; j++)
          {
            double sum = xt->row_tot[i] + xt->col_tot[j];
            sum_fijri_ci2 += xt->mat[j + i * n_cols] * sum * sum;
@@ -2582,10 +2518,10 @@ calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
 
       v[8] = (xt->total * sum_fii - sum_rici) / (pow2 (xt->total) - sum_rici);
 
-      ase_under_h0 = sqrt ((pow2 (xt->total) * sum_rici
-                           + sum_rici * sum_rici
-                           - xt->total * sum_riciri_ci)
-                          / (xt->total * (pow2 (xt->total) - sum_rici) * (pow2 (xt->total) - sum_rici)));
+      double ase_under_h0 = sqrt ((pow2 (xt->total) * sum_rici
+                                   + sum_rici * sum_rici
+                                   - xt->total * sum_riciri_ci)
+                                  / (xt->total * (pow2 (xt->total) - sum_rici) * (pow2 (xt->total) - sum_rici)));
 
       ase[8] = sqrt (xt->total * (((sum_fii * (xt->total - sum_fii))
                                / pow2 (pow2 (xt->total) - sum_rici))
@@ -2601,7 +2537,7 @@ calc_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
       t[8] = v[8] / ase_under_h0;
     }
 
-  return 1;
+  return true;
 }
 
 /* Calculate risk estimate. */
@@ -2611,42 +2547,38 @@ calc_risk (struct crosstabulation *xt,
            double *n_valid)
 {
   size_t n_cols = xt->vars[COL_VAR].n_values;
-  double f11, f12, f21, f22;
-  double v;
 
-  for (int i = 0; i < 3; i++)
+  for (size_t i = 0; i < 3; i++)
     value[i] = upper[i] = lower[i] = SYSMIS;
 
   if (xt->ns_rows != 2 || xt->ns_cols != 2)
     return false;
 
-  {
-    /* Find populated columns. */
-    int nz_cols[2];
-    int n = 0;
-    FOR_EACH_POPULATED_COLUMN (c, xt)
-      nz_cols[n++] = c;
-    assert (n == 2);
-
-    /* Find populated rows. */
-    int nz_rows[2];
-    n = 0;
-    FOR_EACH_POPULATED_ROW (r, xt)
-      nz_rows[n++] = r;
-    assert (n == 2);
-
-    f11 = xt->mat[nz_cols[0] + n_cols * nz_rows[0]];
-    f12 = xt->mat[nz_cols[1] + n_cols * nz_rows[0]];
-    f21 = xt->mat[nz_cols[0] + n_cols * nz_rows[1]];
-    f22 = xt->mat[nz_cols[1] + n_cols * nz_rows[1]];
-    *n_valid = f11 + f12 + f21 + f22;
-
-    c[0] = xt->vars[COL_VAR].values[nz_cols[0]];
-    c[1] = xt->vars[COL_VAR].values[nz_cols[1]];
-  }
+  /* Find populated columns. */
+  size_t nz_cols[2];
+  size_t n = 0;
+  FOR_EACH_POPULATED_COLUMN (c, xt)
+    nz_cols[n++] = c;
+  assert (n == 2);
+
+  /* Find populated rows. */
+  size_t nz_rows[2];
+  n = 0;
+  FOR_EACH_POPULATED_ROW (r, xt)
+    nz_rows[n++] = r;
+  assert (n == 2);
+
+  double f11 = xt->mat[nz_cols[0] + n_cols * nz_rows[0]];
+  double f12 = xt->mat[nz_cols[1] + n_cols * nz_rows[0]];
+  double f21 = xt->mat[nz_cols[0] + n_cols * nz_rows[1]];
+  double f22 = xt->mat[nz_cols[1] + n_cols * nz_rows[1]];
+  *n_valid = f11 + f12 + f21 + f22;
+
+  c[0] = xt->vars[COL_VAR].values[nz_cols[0]];
+  c[1] = xt->vars[COL_VAR].values[nz_cols[1]];
 
   value[0] = (f11 * f22) / (f12 * f21);
-  v = sqrt (1. / f11 + 1. / f12 + 1. / f21 + 1. / f22);
+  double v = sqrt (1. / f11 + 1. / f12 + 1. / f21 + 1. / f22);
   lower[0] = value[0] * exp (-1.960 * v);
   upper[0] = value[0] * exp (1.960 * v);
 
@@ -2666,14 +2598,14 @@ calc_risk (struct crosstabulation *xt,
 }
 
 /* Calculate directional measures. */
-static int
+static void
 calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
                   double v[N_DIRECTIONAL], double ase[N_DIRECTIONAL],
                  double t[N_DIRECTIONAL], double sig[N_DIRECTIONAL])
 {
   size_t n_rows = xt->vars[ROW_VAR].n_values;
   size_t n_cols = xt->vars[COL_VAR].n_values;
-  for (int i = 0; i < N_DIRECTIONAL; i++)
+  for (size_t i = 0; i < N_DIRECTIONAL; i++)
     v[i] = ase[i] = t[i] = sig[i] = SYSMIS;
 
   /* Lambda. */
@@ -2681,14 +2613,14 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
     {
       /* Find maximum for each row and their sum. */
       double *fim = xnmalloc (n_rows, sizeof *fim);
-      int *fim_index = xnmalloc (n_rows, sizeof *fim_index);
+      size_t *fim_index = xnmalloc (n_rows, sizeof *fim_index);
       double sum_fim = 0.0;
-      for (int i = 0; i < n_rows; i++)
+      for (size_t i = 0; i < n_rows; i++)
        {
          double max = xt->mat[i * n_cols];
-         int index = 0;
+         size_t index = 0;
 
-         for (int j = 1; j < n_cols; j++)
+         for (size_t j = 1; j < n_cols; j++)
            if (xt->mat[j + i * n_cols] > max)
              {
                max = xt->mat[j + i * n_cols];
@@ -2702,14 +2634,14 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
 
       /* Find maximum for each column. */
       double *fmj = xnmalloc (n_cols, sizeof *fmj);
-      int *fmj_index = xnmalloc (n_cols, sizeof *fmj_index);
+      size_t *fmj_index = xnmalloc (n_cols, sizeof *fmj_index);
       double sum_fmj = 0.0;
-      for (int j = 0; j < n_cols; j++)
+      for (size_t j = 0; j < n_cols; j++)
        {
          double max = xt->mat[j];
-         int index = 0;
+         size_t index = 0;
 
-         for (int i = 1; i < n_rows; i++)
+         for (size_t i = 1; i < n_rows; i++)
            if (xt->mat[j + i * n_cols] > max)
              {
                max = xt->mat[j + i * n_cols];
@@ -2723,8 +2655,8 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
 
       /* Find maximum row total. */
       double rm = xt->row_tot[0];
-      int rm_index = 0;
-      for (int i = 1; i < n_rows; i++)
+      size_t rm_index = 0;
+      for (size_t i = 1; i < n_rows; i++)
        if (xt->row_tot[i] > rm)
          {
            rm = xt->row_tot[i];
@@ -2733,8 +2665,8 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
 
       /* Find maximum column total. */
       double cm = xt->col_tot[0];
-      int cm_index = 0;
-      for (int j = 1; j < n_cols; j++)
+      size_t cm_index = 0;
+      for (size_t j = 1; j < n_cols; j++)
        if (xt->col_tot[j] > cm)
          {
            cm = xt->col_tot[j];
@@ -2748,7 +2680,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       /* ASE1 for Y given XT. */
       {
         double accum = 0.0;
-       for (int i = 0; i < n_rows; i++)
+       for (size_t i = 0; i < n_rows; i++)
           if (cm_index == fim_index[i])
             accum += fim[i];
         ase[2] = sqrt ((xt->total - sum_fim) * (sum_fim + cm - 2. * accum)
@@ -2758,7 +2690,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       /* ASE0 for Y given XT. */
       {
        double accum = 0.0;
-       for (int i = 0; i < n_rows; i++)
+       for (size_t i = 0; i < n_rows; i++)
          if (cm_index != fim_index[i])
            accum += (xt->mat[i * n_cols + fim_index[i]]
                      + xt->mat[i * n_cols + cm_index]);
@@ -2768,7 +2700,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       /* ASE1 for XT given Y. */
       {
         double accum = 0.0;
-       for (int j = 0; j < n_cols; j++)
+       for (size_t j = 0; j < n_cols; j++)
           if (rm_index == fmj_index[j])
             accum += fmj[j];
         ase[1] = sqrt ((xt->total - sum_fmj) * (sum_fmj + rm - 2. * accum)
@@ -2778,7 +2710,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       /* ASE0 for XT given Y. */
       {
        double accum = 0.0;
-       for (int j = 0; j < n_cols; j++)
+       for (size_t j = 0; j < n_cols; j++)
          if (rm_index != fmj_index[j])
            accum += (xt->mat[j + n_cols * fmj_index[j]]
                      + xt->mat[j + n_cols * rm_index]);
@@ -2789,8 +2721,8 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       {
        double accum0 = 0.0;
        double accum1 = 0.0;
-       for (int i = 0; i < n_rows; i++)
-         for (int j = 0; j < n_cols; j++)
+       for (size_t i = 0; i < n_rows; i++)
+         for (size_t j = 0; j < n_cols; j++)
            {
              int temp0 = (fmj_index[j] == i) + (fim_index[i] == j);
              int temp1 = (i == rm_index) + (j == cm_index);
@@ -2803,7 +2735,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
                       / (2. * xt->total - rm - cm));
       }
 
-      for (int i = 0; i < 3; i++)
+      for (size_t i = 0; i < 3; i++)
         sig[i] = 2 * gsl_cdf_ugaussian_Q (t[i]);
 
       free (fim);
@@ -2812,28 +2744,26 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       free (fmj_index);
 
       /* Tau. */
-      {
-       double sum_fij2_ri = 0.0;
-        double sum_fij2_ci = 0.0;
-        FOR_EACH_POPULATED_ROW (i, xt)
-          FOR_EACH_POPULATED_COLUMN (j, xt)
-           {
-             double temp = pow2 (xt->mat[j + i * n_cols]);
-             sum_fij2_ri += temp / xt->row_tot[i];
-             sum_fij2_ci += temp / xt->col_tot[j];
-           }
+      double sum_fij2_ri = 0.0;
+      double sum_fij2_ci = 0.0;
+      FOR_EACH_POPULATED_ROW (i, xt)
+        FOR_EACH_POPULATED_COLUMN (j, xt)
+        {
+          double temp = pow2 (xt->mat[j + i * n_cols]);
+          sum_fij2_ri += temp / xt->row_tot[i];
+          sum_fij2_ci += temp / xt->col_tot[j];
+        }
 
-       double sum_ri2 = 0.0;
-       for (int i = 0; i < n_rows; i++)
-         sum_ri2 += pow2 (xt->row_tot[i]);
+      double sum_ri2 = 0.0;
+      for (size_t i = 0; i < n_rows; i++)
+        sum_ri2 += pow2 (xt->row_tot[i]);
 
-        double sum_cj2 = 0.0;
-       for (int j = 0; j < n_cols; j++)
-         sum_cj2 += pow2 (xt->col_tot[j]);
+      double sum_cj2 = 0.0;
+      for (size_t j = 0; j < n_cols; j++)
+        sum_cj2 += pow2 (xt->col_tot[j]);
 
-       v[3] = (xt->total * sum_fij2_ci - sum_ri2) / (pow2 (xt->total) - sum_ri2);
-       v[4] = (xt->total * sum_fij2_ri - sum_cj2) / (pow2 (xt->total) - sum_cj2);
-      }
+      v[3] = (xt->total * sum_fij2_ci - sum_ri2) / (pow2 (xt->total) - sum_ri2);
+      v[4] = (xt->total * sum_fij2_ri - sum_cj2) / (pow2 (xt->total) - sum_cj2);
     }
 
   if (proc->statistics & CRS_ST_UC)
@@ -2848,8 +2778,8 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
 
       double UXY = 0.0;
       double P = 0.0;
-      for (int i = 0; i < n_rows; i++)
-       for (int j = 0; j < n_cols; j++)
+      for (size_t i = 0; i < n_rows; i++)
+       for (size_t j = 0; j < n_cols; j++)
          {
            double entry = xt->mat[j + i * n_cols];
 
@@ -2863,8 +2793,8 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       double ase1_yx = 0.0;
       double ase1_xy = 0.0;
       double ase1_sym = 0.0;
-      for (int i = 0; i < n_rows; i++)
-       for (int j = 0; j < n_cols; j++)
+      for (size_t i = 0; i < n_rows; i++)
+       for (size_t j = 0; j < n_cols; j++)
          {
            double entry = xt->mat[j + i * n_cols];
 
@@ -2906,7 +2836,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       if (calc_symmetric (proc, xt, v_dummy, ase_dummy, t_dummy,
                           somers_d_v, somers_d_ase, somers_d_t))
         {
-          for (int i = 0; i < 3; i++)
+          for (size_t i = 0; i < 3; i++)
             {
               v[8 + i] = somers_d_v[i];
               ase[8 + i] = somers_d_ase[i];
@@ -2922,7 +2852,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       /* X dependent. */
       double sum_Xr = 0.0;
       double sum_X2r = 0.0;
-      for (int i = 0; i < n_rows; i++)
+      for (size_t i = 0; i < n_rows; i++)
         {
           sum_Xr += xt->vars[ROW_VAR].values[i].f * xt->row_tot[i];
           sum_X2r += pow2 (xt->vars[ROW_VAR].values[i].f) * xt->row_tot[i];
@@ -2934,7 +2864,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
         {
           double cum = 0.0;
 
-          for (int i = 0; i < n_rows; i++)
+          for (size_t i = 0; i < n_rows; i++)
             {
               SXW += (pow2 (xt->vars[ROW_VAR].values[i].f)
                       * xt->mat[j + i * n_cols]);
@@ -2949,7 +2879,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       /* Y dependent. */
       double sum_Yc = 0.0;
       double sum_Y2c = 0.0;
-      for (int i = 0; i < n_cols; i++)
+      for (size_t i = 0; i < n_cols; i++)
         {
           sum_Yc += xt->vars[COL_VAR].values[i].f * xt->col_tot[i];
           sum_Y2c += pow2 (xt->vars[COL_VAR].values[i].f) * xt->col_tot[i];
@@ -2960,7 +2890,7 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
       FOR_EACH_POPULATED_ROW (i, xt)
         {
           double cum = 0.0;
-          for (int j = 0; j < n_cols; j++)
+          for (size_t j = 0; j < n_cols; j++)
             {
               SYW += (pow2 (xt->vars[COL_VAR].values[j].f)
                       * xt->mat[j + i * n_cols]);
@@ -2972,6 +2902,4 @@ calc_directional (struct crosstabs_proc *proc, struct crosstabulation *xt,
         }
       v[12] = sqrt (1. - SYW / SY);
     }
-
-  return 1;
 }
index 53a7335de9fa8bdf31a53afce43f48945ad7f1a4..a26379e88af7337aa8cafbca9868414118fcd121 100644 (file)
@@ -1939,3 +1939,93 @@ AT_CHECK([test -e xxx-2.png], [0], [ignore])
 AT_CHECK([diff xxx-1.png xxx-2.png], [0], [ignore])
 
 AT_CLEANUP
+
+AT_SETUP([CROSSTABS syntax errors])
+AT_DATA([crosstabs.sps], [dnl
+DATA LIST LIST NOTABLE/x y v1 to v100.
+CROSSTABS TABLES=x BY y/VARIABLES **.
+CROSSTABS VARIABLES=**.
+CROSSTABS VARIABLES=x **.
+CROSSTABS VARIABLES=x (**).
+CROSSTABS VARIABLES=x (1,**).
+CROSSTABS VARIABLES=x (1,5**).
+CROSSTABS MISSING=**.
+CROSSTABS COUNT=**.
+CROSSTABS FORMAT=**.
+CROSSTABS CELLS=**.
+CROSSTABS STATISTICS=**.
+CROSSTABS **.
+CROSSTABS
+       v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100
+    BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100
+    BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100
+    BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100
+    BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100
+    BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100.
+CROSSTABS BARCHART.
+CROSSTABS x BY y/MISSING=REPORT.
+])
+AT_CHECK([pspp -O format=csv crosstabs.sps], [1], [dnl
+"crosstabs.sps:2.25-2.33: error: CROSSTABS: VARIABLES must be specified before TABLES.
+    2 | CROSSTABS TABLES=x BY y/VARIABLES **.
+      |                         ^~~~~~~~~"
+
+"crosstabs.sps:3.21-3.22: error: CROSSTABS: Syntax error expecting variable name.
+    3 | CROSSTABS VARIABLES=**.
+      |                     ^~"
+
+"crosstabs.sps:4.23-4.24: error: CROSSTABS: Syntax error expecting `('.
+    4 | CROSSTABS VARIABLES=x **.
+      |                       ^~"
+
+"crosstabs.sps:5.24-5.25: error: CROSSTABS: Syntax error expecting integer.
+    5 | CROSSTABS VARIABLES=x (**).
+      |                        ^~"
+
+"crosstabs.sps:6.26-6.27: error: CROSSTABS: Syntax error expecting positive integer.
+    6 | CROSSTABS VARIABLES=x (1,**).
+      |                          ^~"
+
+"crosstabs.sps:7.27-7.28: error: CROSSTABS: Syntax error expecting `)'.
+    7 | CROSSTABS VARIABLES=x (1,5**).
+      |                           ^~"
+
+"crosstabs.sps:8.19-8.20: error: CROSSTABS: Syntax error expecting TABLE, INCLUDE, or REPORT.
+    8 | CROSSTABS MISSING=**.
+      |                   ^~"
+
+"crosstabs.sps:9.17-9.18: error: CROSSTABS: Syntax error expecting ASIS, CASE, CELL, ROUND, or TRUNCATE.
+    9 | CROSSTABS COUNT=**.
+      |                 ^~"
+
+"crosstabs.sps:10.18-10.19: error: CROSSTABS: Syntax error expecting AVALUE, DVALUE, TABLES, or NOTABLES.
+   10 | CROSSTABS FORMAT=**.
+      |                  ^~"
+
+"crosstabs.sps:11.17-11.18: error: CROSSTABS: Syntax error expecting COUNT, EXPECTED, ROW, COLUMN, TOTAL, RESIDUAL, SRESIDUAL, or ASRESIDUAL.
+   11 | CROSSTABS CELLS=**.
+      |                 ^~"
+
+"crosstabs.sps:12.22-12.23: error: CROSSTABS: Syntax error expecting one of the following: CHISQ, PHI, CC, LAMBDA, UC, BTAU, CTAU, RISK, GAMMA, D, KAPPA, ETA, CORR.
+   12 | CROSSTABS STATISTICS=**.
+      |                      ^~"
+
+"crosstabs.sps:13.11-13.12: error: CROSSTABS: Syntax error expecting subcommand name or variable name.
+   13 | CROSSTABS **.
+      |           ^~"
+
+"crosstabs.sps:15.8-16.59: error: CROSSTABS: Too many cross-tabulation variables or dimensions.
+   15 |        v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100
+      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   16 |     BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100 BY v1 to v100
+      | -----------------------------------------------------------"
+
+crosstabs.sps:21: error: CROSSTABS: At least one crosstabulation must be requested (using the TABLES subcommand).
+
+"crosstabs.sps:22.26-22.31: warning: CROSSTABS: Missing mode REPORT not allowed in general mode.  Assuming MISSING=TABLE.
+   22 | CROSSTABS x BY y/MISSING=REPORT.
+      |                          ^~~~~~"
+
+error: CROSSTABS: At end of input: Syntax error expecting `BEGIN DATA'.
+])
+AT_CLEANUP
\ No newline at end of file