*/
#include <config.h>
-#include <libpspp/message.h>
+
#include <ctype.h>
+#include <gsl/gsl_cdf.h>
#include <stdlib.h>
#include <stdio.h>
-#include <gsl/gsl_cdf.h>
-#include <libpspp/array.h>
-#include <libpspp/alloc.h>
+
#include <data/case.h>
#include <data/dictionary.h>
-#include <libpspp/hash.h>
-#include <libpspp/pool.h>
+#include <data/procedure.h>
+#include <data/value-labels.h>
+#include <data/variable.h>
#include <language/command.h>
-#include <libpspp/compiler.h>
+#include <language/dictionary/split-file.h>
#include <language/lexer/lexer.h>
-#include <libpspp/message.h>
+#include <language/lexer/variable-parser.h>
+#include <libpspp/alloc.h>
+#include <libpspp/array.h>
+#include <libpspp/assertion.h>
+#include <libpspp/compiler.h>
+#include <libpspp/hash.h>
#include <libpspp/magic.h>
+#include <libpspp/message.h>
+#include <libpspp/message.h>
#include <libpspp/misc.h>
-#include <output/output.h>
+#include <libpspp/pool.h>
#include <libpspp/str.h>
+#include <output/output.h>
#include <output/table.h>
-#include <data/value-labels.h>
-#include <data/variable.h>
-#include <procedure.h>
#include "gettext.h"
#define _(msgid) gettext (msgid)
/* (headers) */
-#include <libpspp/debug-print.h>
-
/* (specification)
crosstabs (crs_):
*^tables=custom;
+variables=custom;
- +missing=miss:!table/include/report;
+ missing=miss:!table/include/report;
+write[wr_]=none,cells,all;
+format=fmt:!labels/nolabels/novallabs,
val:!avalue/dvalue,
static struct pool *pl_col; /* For column data. */
static int internal_cmd_crosstabs (void);
-static void precalc (void *);
-static bool calc_general (struct ccase *, void *);
-static bool calc_integer (struct ccase *, 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 void submit (struct tab_table *);
pl_tc = pool_create ();
pl_col = pool_create ();
- if (!parse_crosstabs (&cmd))
+ if (!parse_crosstabs (&cmd, NULL))
return CMD_FAILURE;
mode = variables ? INTEGER : GENERAL;
else
write = CRS_WR_NONE;
- ok = procedure_with_splits (precalc,
+ ok = procedure_with_splits (current_dataset, precalc,
mode == GENERAL ? calc_general : calc_integer,
postcalc, NULL);
/* Parses the TABLES subcommand. */
static int
-crs_custom_tables (struct cmd_crosstabs *cmd UNUSED)
+crs_custom_tables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
{
struct var_set *var_set;
int n_by;
/* Ensure that this is a TABLES subcommand. */
if (!lex_match_id ("TABLES")
- && (token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
+ && (token != T_ID || dict_lookup_var (dataset_dict (current_dataset), tokid) == NULL)
&& token != T_ALL)
return 2;
lex_match ('=');
if (variables != NULL)
var_set = var_set_create_from_array (variables, variables_cnt);
else
- var_set = var_set_create_from_dict (default_dict);
+ var_set = var_set_create_from_dict (dataset_dict (current_dataset));
assert (var_set != NULL);
for (n_by = 0; ;)
/* Parses the VARIABLES subcommand. */
static int
-crs_custom_variables (struct cmd_crosstabs *cmd UNUSED)
+crs_custom_variables (struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
{
if (nxtab)
{
long min, max;
- if (!parse_variables (default_dict, &variables, &variables_cnt,
+ if (!parse_variables (dataset_dict (current_dataset), &variables, &variables_cnt,
(PV_APPEND | PV_NUMERIC
| PV_NO_DUPLICATE | PV_NO_SCRATCH)))
return 0;
static unsigned hash_table_entry (const void *, void *);
/* Set up the crosstabulation tables for processing. */
-static void
-precalc (void *aux UNUSED)
+static void
+precalc (const struct ccase *first, void *aux UNUSED)
{
+ output_split_file_values (first);
if (mode == GENERAL)
{
gen_tab = hsh_create (512, compare_table_entry, hash_table_entry,
n_sorted_tab + 1, sizeof *sorted_tab);
sorted_tab[n_sorted_tab] = NULL;
}
+
}
/* Form crosstabulations for general mode. */
static bool
-calc_general (struct ccase *c, void *aux UNUSED)
+calc_general (const struct ccase *c, void *aux UNUSED)
{
- int bad_warn = 1;
+ bool bad_warn = true;
/* Case weight. */
- double weight = dict_get_case_weight (default_dict, c, &bad_warn);
+ double weight = dict_get_case_weight (dataset_dict (current_dataset), c, &bad_warn);
/* Flattened current table index. */
int t;
}
static bool
-calc_integer (struct ccase *c, void *aux UNUSED)
+calc_integer (const struct ccase *c, void *aux UNUSED)
{
- int bad_warn = 1;
+ bool bad_warn = true;
/* Case weight. */
- double weight = dict_get_case_weight (default_dict, c, &bad_warn);
+ double weight = dict_get_case_weight (dataset_dict (current_dataset), c, &bad_warn);
/* Flattened current table index. */
int t;
int cur_tab = 0;
summary = tab_create (7, 3 + nxtab, 1);
- tab_title (summary, 0, _("Summary."));
+ tab_title (summary, _("Summary."));
tab_headers (summary, 1, 0, 3, 0);
tab_joint_text (summary, 1, 0, 6, 0, TAB_CENTER, _("Cases"));
tab_joint_text (summary, 1, 1, 2, 1, TAB_CENTER, _("Valid"));
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. */
}
strcpy (cp, "].");
- tab_title (table, 0, title);
+ tab_title (table, "%s", title);
local_free (title);
}
(pe - pb) / n_cols * 3 / 2 * N_CHISQ + 10, 1);
tab_headers (chisq, 1 + (nvar - 2), 0, 1, 0);
- tab_title (chisq, 0, "Chi-square tests.");
+ tab_title (chisq, _("Chi-square tests."));
tab_offset (chisq, nvar - 2, 0);
tab_text (chisq, 0, 0, TAB_LEFT | TAT_TITLE, _("Statistic"));
{
sym = tab_create (6 + (nvar - 2), (pe - pb) / n_cols * 7 + 10, 1);
tab_headers (sym, 2 + (nvar - 2), 0, 1, 0);
- tab_title (sym, 0, "Symmetric measures.");
+ tab_title (sym, _("Symmetric measures."));
tab_offset (sym, nvar - 2, 0);
tab_text (sym, 0, 0, TAB_LEFT | TAT_TITLE, _("Category"));
{
risk = tab_create (4 + (nvar - 2), (pe - pb) / n_cols * 4 + 10, 1);
tab_headers (risk, 1 + nvar - 2, 0, 2, 0);
- tab_title (risk, 0, "Risk estimate.");
+ tab_title (risk, _("Risk estimate."));
tab_offset (risk, nvar - 2, 0);
tab_joint_text (risk, 2, 0, 3, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF,
- _(" 95%% Confidence Interval"));
+ _("95%% Confidence Interval"));
tab_text (risk, 0, 1, TAB_LEFT | TAT_TITLE, _("Statistic"));
tab_text (risk, 1, 1, TAB_RIGHT | TAT_TITLE, _("Value"));
tab_text (risk, 2, 1, TAB_RIGHT | TAT_TITLE, _("Lower"));
{
direct = tab_create (7 + (nvar - 2), (pe - pb) / n_cols * 7 + 10, 1);
tab_headers (direct, 3 + (nvar - 2), 0, 1, 0);
- tab_title (direct, 0, "Directional measures.");
+ tab_title (direct, _("Directional measures."));
tab_offset (direct, nvar - 2, 0);
tab_text (direct, 0, 0, TAB_LEFT | TAT_TITLE, _("Category"));
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);
- tab_box (t, -1, -1, -1, TAL_1 | TAL_SPACING, 0, tab_t (t), tab_l (t) - 1,
+ tab_box (t, -1, -1, -1, TAL_GAP, 0, tab_t (t), tab_l (t) - 1,
tab_nr (t) - 1);
tab_vline (t, TAL_2, tab_l (t), 0, tab_nr (t) - 1);
tab_dim (t, crosstabs_dim);
int i;
/* Width of a numerical column. */
- int c = outp_string_width (d, "0.000000");
+ int c = outp_string_width (d, "0.000000", OUTP_PROPORTIONAL);
if (cmd.miss == CRS_REPORT)
- c += outp_string_width (d, "M");
+ c += outp_string_width (d, "M", OUTP_PROPORTIONAL);
/* Set width for header columns. */
if (t->l != 0)
{
- int w = (d->width - t->vr_tot - c * (t->nc - t->l)) / t->l;
+ size_t i;
+ int w;
+
+ w = d->width - c * (t->nc - t->l);
+ for (i = 0; i <= t->nc; i++)
+ w -= t->wrv[i];
+ w /= t->l;
if (w < d->prop_em_width * 8)
w = d->prop_em_width * 8;
table_value_missing (struct tab_table *table, int c, int r, unsigned char opt,
const union value *v, const struct variable *var)
{
- struct fixed_string s;
+ struct substring s;
const char *label = val_labs_find (var->val_labs, *v);
if (label)
}
/* Put VALUE into cell (C,R) of TABLE, suffixed with character
- SUFFIX if nonzero. If MARK_MISSING is nonzero the entry is
+ SUFFIX if nonzero. If MARK_MISSING is true the entry is
additionally suffixed with a letter `M'. */
static void
format_cell_entry (struct tab_table *table, int c, int r, double value,
- char suffix, int mark_missing)
+ char suffix, bool mark_missing)
{
const struct fmt_spec f = {FMT_F, 10, 1};
union value v;
- struct fixed_string s;
+ struct substring s;
s.length = 10;
s.string = tab_alloc (table, 16);
tab_hline (table, TAL_1, -1, n_cols, 0);
for (c = 0; c < n_cols; c++)
{
- int mark_missing = 0;
+ 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)))
- mark_missing = 1;
+ mark_missing = true;
for (i = 0; i < num_cells; i++)
{
double v;
* (1. - col_tot[c] / W)));
break;
default:
- assert (0);
- abort ();
+ NOT_REACHED ();
}
format_cell_entry (table, c, i, v, suffix, mark_missing);
for (r = 0; r < n_rows; r++)
{
char suffix = 0;
- int mark_missing = 0;
+ bool mark_missing = false;
if (cmd.miss == CRS_REPORT
&& mv_is_num_user_missing (&x->vars[ROW_VAR]->miss, rows[r].f))
- mark_missing = 1;
+ mark_missing = true;
for (i = 0; i < num_cells; i++)
{
v = 0.;
break;
default:
- assert (0);
- abort ();
+ NOT_REACHED ();
}
format_cell_entry (table, n_cols, 0, v, suffix, mark_missing);
for (c = 0; c <= n_cols; c++)
{
double ct = c < n_cols ? col_tot[c] : W;
- int mark_missing = 0;
+ bool mark_missing = false;
char suffix = 0;
int i;
if (cmd.miss == CRS_REPORT && c < n_cols
&& mv_is_num_user_missing (&x->vars[COL_VAR]->miss, cols[c].f))
- mark_missing = 1;
+ mark_missing = true;
for (i = 0; i < num_cells; i++)
{
case CRS_CL_ASRESIDUAL:
continue;
default:
- assert (0);
- abort ();
+ NOT_REACHED ();
}
format_cell_entry (table, c, i, v, suffix, mark_missing);