int nvar; /* Number of variables. */
double missing; /* Missing cases count. */
int ofs; /* Integer mode: Offset into sorted_tab[]. */
- struct variable *vars[2]; /* At least two variables; sorted by
+ const struct variable *vars[2]; /* At least two variables; sorted by
larger indices first. */
};
};
static inline struct var_range *
-get_var_range (struct variable *v)
+get_var_range (const struct variable *v)
{
return var_get_aux (v);
}
static struct table_entry **sorted_tab; /* Sorted table. */
/* Variables specifies on VARIABLES. */
-static struct variable **variables;
+static const struct variable **variables;
static size_t variables_cnt;
/* TABLES. */
static int cells[8]; /* Cells requested. */
/* WRITE. */
-static int write; /* One of WR_* that specifies the WRITE style. */
+static int write_style; /* One of WR_* that specifies the WRITE style. */
/* Command parsing info. */
static struct cmd_crosstabs cmd;
+ cmd.a_write[CRS_WR_CELLS] == 0))
cmd.a_write[CRS_WR_CELLS] = 1;
if (cmd.a_write[CRS_WR_CELLS])
- write = CRS_WR_CELLS;
+ write_style = CRS_WR_CELLS;
else if (cmd.a_write[CRS_WR_ALL])
- write = CRS_WR_ALL;
+ write_style = CRS_WR_ALL;
else
- write = CRS_WR_NONE;
+ write_style = CRS_WR_NONE;
ok = procedure_with_splits (ds, precalc,
mode == GENERAL ? calc_general : calc_integer,
static int
crs_custom_tables (struct lexer *lexer, struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
{
- struct var_set *var_set;
+ struct const_var_set *var_set;
int n_by;
- struct variable ***by = NULL;
+ const struct variable ***by = NULL;
size_t *by_nvar = NULL;
size_t nx = 1;
int success = 0;
/* Ensure that this is a TABLES subcommand. */
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_ID ||
+ dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL)
&& lex_token (lexer) != T_ALL)
return 2;
lex_match (lexer, '=');
if (variables != NULL)
- var_set = var_set_create_from_array (variables, variables_cnt);
+ var_set = const_var_set_create_from_array (variables, variables_cnt);
else
- var_set = var_set_create_from_dict (dataset_dict (ds));
+ var_set = const_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 (lexer, var_set, &by[n_by], &by_nvar[n_by],
+ 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]))
free (by_nvar);
}
- var_set_destroy (var_set);
+ const_var_set_destroy (var_set);
return success;
}
long min, max;
- if (!parse_variables (lexer, dataset_dict (ds),
+ if (!parse_variables_const (lexer, dataset_dict (ds),
&variables, &variables_cnt,
(PV_APPEND | PV_NUMERIC
| PV_NO_DUPLICATE | PV_NO_SCRATCH)))
{
bool bad_warn = true;
+ /* Missing values to exclude. */
+ enum mv_class exclude = (cmd.miss == CRS_TABLE ? MV_ANY
+ : cmd.miss == CRS_INCLUDE ? MV_SYSTEM
+ : MV_NEVER);
+
/* Case weight. */
double weight = dict_get_case_weight (dataset_dict (ds), c, &bad_warn);
for (j = 0; j < x->nvar; j++)
{
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
- && var_is_value_system_missing (x->vars[j], v)))
+ if (var_is_value_missing (x->vars[j], v, exclude))
{
x->missing += weight;
goto next_crosstab;
ofs = x->ofs;
for (i = 0; i < x->nvar; i++)
{
- struct variable *const v = x->vars[i];
+ const struct variable *const v = x->vars[i];
struct var_range *vr = get_var_range (v);
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 && var_is_num_user_missing (v, value)))
+ || (cmd.miss == CRS_TABLE
+ && var_is_num_missing (v, value, MV_USER)))
{
x->missing += weight;
goto next_crosstab;
}
{
- struct variable *row_var = x->vars[ROW_VAR];
+ const struct variable *row_var = x->vars[ROW_VAR];
const int row = case_num (c, row_var) - get_var_range (row_var)->min;
- struct variable *col_var = x->vars[COL_VAR];
+ const struct variable *col_var = x->vars[COL_VAR];
const int col = case_num (c, col_var) - get_var_range (col_var)->min;
const int col_dim = get_var_range (col_var)->count;
int r;
for (r = 0; r < n_rows; r++)
- if (var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f))
+ if (var_is_num_missing (x->vars[ROW_VAR], rows[r].f, MV_USER))
{
int c;
int c;
for (c = 0; c < n_cols; c++)
- if (var_is_num_user_missing (x->vars[COL_VAR], cols[c].f))
+ if (var_is_num_missing (x->vars[COL_VAR], cols[c].f, MV_USER))
{
int r;
enum_var_values (struct table_entry **entries, int entry_cnt, int var_idx,
union value **values, int *value_cnt)
{
- struct variable *v = xtab[(*entries)->table]->vars[var_idx];
+ const struct variable *v = xtab[(*entries)->table]->vars[var_idx];
if (mode == GENERAL)
{
s.string = tab_alloc (table, print->w);
format_short (s.string, print, v);
s.length = strlen (s.string);
- if (cmd.miss == CRS_REPORT && var_is_num_user_missing (var, v->f))
+ if (cmd.miss == CRS_REPORT && var_is_num_missing (var, v->f, MV_USER))
s.string[s.length++] = 'M';
while (s.length && *s.string == ' ')
{
bool mark_missing = false;
double expected_value = row_tot[r] * col_tot[c] / W;
if (cmd.miss == CRS_REPORT
- && (var_is_num_user_missing (x->vars[COL_VAR], cols[c].f)
- || var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f)))
+ && (var_is_num_missing (x->vars[COL_VAR], cols[c].f, MV_USER)
+ || var_is_num_missing (x->vars[ROW_VAR], rows[r].f,
+ MV_USER)))
mark_missing = true;
for (i = 0; i < num_cells; i++)
{
bool mark_missing = false;
if (cmd.miss == CRS_REPORT
- && var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f))
+ && var_is_num_missing (x->vars[ROW_VAR], rows[r].f, MV_USER))
mark_missing = true;
for (i = 0; i < num_cells; i++)
int i;
if (cmd.miss == CRS_REPORT && c < n_cols
- && var_is_num_user_missing (x->vars[COL_VAR], cols[c].f))
+ && var_is_num_missing (x->vars[COL_VAR], cols[c].f, MV_USER))
mark_missing = true;
for (i = 0; i < num_cells; i++)