output-item: Collapse the inheritance hierarchy into a single struct.
[pspp] / src / language / stats / crosstabs.q
index dfafbe9f3eba199717d66ce2e8ce8a736d1bd6f3..e5f174f00773788b18025a8d735d877939f3c5eb 100644 (file)
@@ -56,7 +56,6 @@
 #include "libpspp/pool.h"
 #include "libpspp/str.h"
 #include "output/pivot-table.h"
-#include "output/chart-item.h"
 #include "output/charts/barchart.h"
 
 #include "gl/minmax.h"
@@ -394,12 +393,8 @@ exit:
   for (xt = &proc.pivots[0]; xt < &proc.pivots[proc.n_pivots]; xt++)
     {
       free (xt->vars);
-      /* We must not call value_destroy on const_values because
-         it is a wild pointer; it never pointed to anything owned
-         by the crosstabulation.
-
-         The rest of the data was allocated and destroyed at a
-         lower level already. */
+      free (xt->const_vars);
+      free (xt->const_indexes);
     }
   free (proc.pivots);
 
@@ -475,6 +470,7 @@ crs_custom_tables (struct lexer *lexer, struct dataset *ds,
       xt->vars = xcalloc (n_by, sizeof *xt->vars);
       xt->n_consts = 0;
       xt->const_vars = NULL;
+      xt->const_indexes = NULL;
 
       for (j = 0; j < n_by; j++)
         xt->vars[j].var = by[j][by_iter[j]];
@@ -780,16 +776,18 @@ postcalc (struct crosstabs_proc *proc)
               struct crosstabulation subset;
               make_crosstabulation_subset (xt, row0, row1, &subset);
               output_crosstabulation (proc, &subset);
+              free (subset.const_indexes);
             }
         }
       if (proc->barchart)
         {
-          const struct variable **vars = xcalloc (xt->n_vars, sizeof *vars);
-          for (size_t i = 0; i < xt->n_vars; i++)
+          int n_vars = (xt->n_vars > 2 ? 2 : xt->n_vars);
+          const struct variable **vars = xcalloc (n_vars, sizeof *vars);
+          for (size_t i = 0; i < n_vars; i++)
             vars[i] = xt->vars[i].var;
-          chart_item_submit (barchart_create (vars, xt->n_vars, _("Count"),
-                                              false,
-                                              xt->entries, xt->n_entries));
+          chart_submit (barchart_create (vars, n_vars, _("Count"),
+                                         false,
+                                         xt->entries, xt->n_entries));
           free (vars);
         }
     }
@@ -1015,7 +1013,8 @@ output_crosstabulation (struct crosstabs_proc *proc, struct crosstabulation *xt)
            ds_cstr (&vars));
 
       ds_destroy (&vars);
-      free_var_values (xt, COL_VAR);
+      for (size_t i = 0; i < xt->n_vars; i++)
+        free_var_values (xt, i);
       return;
     }
 
@@ -1081,6 +1080,7 @@ output_crosstabulation (struct crosstabs_proc *proc, struct crosstabulation *xt)
       free (x.mat);
       free (x.row_tot);
       free (x.col_tot);
+      free (x.const_indexes);
     }
 
   if (table)
@@ -1097,7 +1097,7 @@ output_crosstabulation (struct crosstabs_proc *proc, struct crosstabulation *xt)
       if (!pivot_table_is_empty (risk))
         pivot_table_submit (risk);
       else
-        pivot_table_destroy (risk);
+        pivot_table_unref (risk);
     }
 
   if (direct)
@@ -1238,14 +1238,15 @@ create_crosstab_table (struct crosstabs_proc *proc, struct crosstabulation *xt,
       ds_put_format (&title, ", %s=", var_to_string (var));
 
       /* Insert the formatted value of VAR without any leading spaces. */
-      s = data_out (value, var_get_encoding (var), var_get_print_format (var));
+      s = data_out (value, var_get_encoding (var), var_get_print_format (var),
+                    settings_get_fmt_settings ());
       ds_put_cstr (&title, s + strspn (s, " "));
       free (s);
     }
   struct pivot_table *table = pivot_table_create__ (
-    pivot_value_new_user_text_nocopy (ds_steal_cstr (&title)));
+    pivot_value_new_user_text_nocopy (ds_steal_cstr (&title)),
+    "Crosstabulation");
   pivot_table_set_weight_format (table, &proc->weight_format);
-  table->omit_empty = true;
 
   struct pivot_dimension *statistics = pivot_dimension_create (
     table, PIVOT_AXIS_ROW, N_("Statistics"));
@@ -1285,7 +1286,6 @@ create_chisq_table (struct crosstabulation *xt)
 {
   struct pivot_table *chisq = pivot_table_create (N_("Chi-Square Tests"));
   pivot_table_set_weight_format (chisq, &xt->weight_format);
-  chisq->omit_empty = true;
 
   pivot_dimension_create (
     chisq, PIVOT_AXIS_ROW, N_("Statistics"),
@@ -1316,7 +1316,6 @@ create_sym_table (struct crosstabulation *xt)
 {
   struct pivot_table *sym = pivot_table_create (N_("Symmetric Measures"));
   pivot_table_set_weight_format (sym, &xt->weight_format);
-  sym->omit_empty = true;
 
   pivot_dimension_create (
     sym, PIVOT_AXIS_COLUMN, N_("Values"),
@@ -1356,12 +1355,12 @@ create_risk_table (struct crosstabulation *xt,
 {
   struct pivot_table *risk = pivot_table_create (N_("Risk Estimate"));
   pivot_table_set_weight_format (risk, &xt->weight_format);
-  risk->omit_empty = true;
 
   struct pivot_dimension *values = pivot_dimension_create (
     risk, PIVOT_AXIS_COLUMN, N_("Values"),
     N_("Value"), PIVOT_RC_OTHER);
   pivot_category_create_group (
+  /* xgettext:no-c-format */
     values->root, N_("95% Confidence Interval"),
     N_("Lower"), PIVOT_RC_OTHER,
     N_("Upper"), PIVOT_RC_OTHER);
@@ -1402,14 +1401,13 @@ create_direct_table (struct crosstabulation *xt)
 {
   struct pivot_table *direct = pivot_table_create (N_("Directional Measures"));
   pivot_table_set_weight_format (direct, &xt->weight_format);
-  direct->omit_empty = true;
 
   pivot_dimension_create (
     direct, PIVOT_AXIS_COLUMN, N_("Values"),
     N_("Value"), PIVOT_RC_OTHER,
     N_("Asymp. Std. Error"), PIVOT_RC_OTHER,
     N_("Approx. T"), PIVOT_RC_OTHER,
-    N_("Approx Sig."), PIVOT_RC_SIGNIFICANCE);
+    N_("Approx. Sig."), PIVOT_RC_SIGNIFICANCE);
 
   struct pivot_dimension *statistics = pivot_dimension_create (
     direct, PIVOT_AXIS_ROW, N_("Statistics"));
@@ -1504,12 +1502,8 @@ compare_value_3way_inv (const void *a_, const void *b_, const void *width_)
 
 /* Given an array of ENTRY_CNT table_entry structures starting at
    ENTRIES, creates a sorted list of the values that the variable
-   with index VAR_IDX takes on.  The values are returned as a
-   malloc()'d array stored in *VALUES, with the number of values
-   stored in *VALUE_CNT.
-
-   The caller must eventually free *VALUES, but each pointer in *VALUES points
-   to existing data not owned by *VALUES itself. */
+   with index VAR_IDX takes on.  Stores the array of the values in
+   XT->values and the number of values in XT->n_values. */
 static void
 enum_var_values (const struct crosstabulation *xt, int var_idx,
                  bool descending)
@@ -1564,7 +1558,7 @@ static void
 free_var_values (const struct crosstabulation *xt, int var_idx)
 {
   struct xtab_var *xv = &xt->vars[var_idx];
-  //free (xv->values);
+  free (xv->values);
   xv->values = NULL;
   xv->n_values = 0;
 }
@@ -1689,6 +1683,8 @@ display_crosstabulation (struct crosstabs_proc *proc,
             }
         }
     }
+
+  free (indexes);
 }
 
 static void calc_r (struct crosstabulation *,
@@ -1787,6 +1783,8 @@ display_symmetric (struct crosstabs_proc *proc, struct crosstabulation *xt,
   struct pivot_value *total = pivot_value_new_number (xt->total);
   pivot_value_set_rc (sym, total, PIVOT_RC_COUNT);
   pivot_table_put (sym, indexes, sym->n_dimensions, total);
+
+  free (indexes);
 }
 
 static bool calc_risk (struct crosstabulation *,
@@ -1894,6 +1892,8 @@ display_directional (struct crosstabs_proc *proc,
                              pivot_value_new_number (entries[j]));
           }
     }
+
+  free (indexes);
 }
 \f
 /* Statistical calculations. */