struct ctables_pairwise *pairwise;
};
-struct ctables_var
- {
- bool is_mrset;
- union
- {
- struct variable *var;
- const struct mrset *mrset;
- };
- };
-
-static const struct fmt_spec *
-ctables_var_get_print_format (const struct ctables_var *var)
-{
- return (var->is_mrset
- ? var_get_print_format (var->mrset->vars[0])
- : var_get_print_format (var->var));
-}
-
-static const char *
-ctables_var_name (const struct ctables_var *var)
-{
- return var->is_mrset ? var->mrset->name : var_get_name (var->var);
-}
-
struct ctables_categories
{
size_t n_refs;
union
{
double number; /* CCT_NUMBER. */
- char *string; /* CCT_STRING. */
+ char *string; /* CCT_STRING. In dictionary encoding. */
double range[2]; /* CCT_RANGE. */
struct
/* Terminals. */
struct
{
- struct ctables_var var;
+ struct variable *var;
bool scale;
struct ctables_summary_spec_set specs[N_CSVS];
};
static struct fmt_spec
ctables_summary_default_format (enum ctables_summary_function function,
- const struct ctables_var *var)
+ const struct variable *var)
{
static const enum ctables_format default_formats[] = {
#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) [ENUM] = FORMAT,
return (struct fmt_spec) { .type = FMT_PCT, .w = 40, .d = 1 };
case CTF_GENERAL:
- return *ctables_var_get_print_format (var);
+ return *var_get_print_format (var);
default:
NOT_REACHED ();
if (axis->op == CTAO_VAR)
{
const char *function_name = ctables_summary_function_name (function);
- const char *var_name = ctables_var_name (&axis->var);
+ const char *var_name = var_get_name (axis->var);
switch (ctables_function_availability (function))
{
case CTFA_MRSETS:
- if (!axis->var.is_mrset)
- {
- msg_at (SE, loc, _("Summary function %s applies only to multiple "
- "response sets."), function_name);
- msg_at (SN, axis->loc, _("'%s' is not a multiple response set."),
- var_name);
- return false;
- }
- break;
+ msg_at (SE, loc, _("Summary function %s applies only to multiple "
+ "response sets."), function_name);
+ msg_at (SN, axis->loc, _("'%s' is not a multiple response set."),
+ var_name);
+ return false;
case CTFA_SCALE:
#if 0
.percentile = percentile,
.label = xstrdup (label),
.format = (format ? *format
- : ctables_summary_default_format (function, &axis->var)),
+ : ctables_summary_default_format (function, axis->var)),
.is_ctables_format = is_ctables_format,
};
return true;
static struct ctables_axis *ctables_axis_parse_stack (
struct ctables_axis_parse_ctx *);
-static bool
-ctables_var_parse (struct lexer *lexer, struct dictionary *dict,
- struct ctables_var *var)
-{
- if (ss_starts_with (lex_tokss (lexer), ss_cstr ("$")))
- {
- *var = (struct ctables_var) {
- .is_mrset = true,
- .mrset = dict_lookup_mrset (dict, lex_tokcstr (lexer))
- };
- if (!var->mrset)
- {
- lex_error (lexer, _("'%s' does not name a multiple-response set "
- "in the active file dictionary."),
- lex_tokcstr (lexer));
- return false;
- }
- lex_get (lexer);
- return true;
- }
- else
- {
- *var = (struct ctables_var) {
- .is_mrset = false,
- .var = parse_variable (lexer, dict),
- };
- return var->var != NULL;
- }
-}
static struct ctables_axis *
ctables_axis_parse_primary (struct ctables_axis_parse_ctx *ctx)
return NULL;
int start_ofs = lex_ofs (ctx->lexer);
- struct ctables_var var;
- if (!ctables_var_parse (ctx->lexer, ctx->dict, &var))
+ struct variable *var = parse_variable (ctx->lexer, ctx->dict);
+ if (!var)
return NULL;
struct ctables_axis *axis = xmalloc (sizeof *axis);
*axis = (struct ctables_axis) { .op = CTAO_VAR, .var = var };
/* XXX should figure out default measures by reading data */
- axis->scale = (var.is_mrset ? false
- : lex_match_phrase (ctx->lexer, "[S]") ? true
+ axis->scale = (lex_match_phrase (ctx->lexer, "[S]") ? true
: lex_match_phrase (ctx->lexer, "[C]") ? false
- : var_get_measure (var.var) == MEASURE_SCALE);
+ : var_get_measure (var) == MEASURE_SCALE);
axis->loc = lex_ofs_location (ctx->lexer, start_ofs,
lex_ofs (ctx->lexer) - 1);
+ if (axis->scale && var_is_alpha (var))
+ {
+ msg_at (SE, axis->loc, _("Cannot use string variable %s as a scale "
+ "variable."),
+ var_get_name (var));
+ ctables_axis_destroy (axis);
+ return NULL;
+ }
+
return axis;
}
if (!axis)
return NULL;
else if (axis->op == CTAO_VAR)
- {
- if (axis->scale)
- {
- assert (!axis->var.is_mrset);
- return axis;
- }
- else
- return NULL;
- }
+ return axis->scale ? axis : NULL;
else
{
for (size_t i = 0; i < 2; i++)
static struct ctables_stack
var_fts (const struct ctables_axis *a)
{
- assert (!a->var.is_mrset);
-
struct variable **vars = xmalloc (sizeof *vars);
- *vars = a->var.var;
+ *vars = a->var;
struct ctables_nest *nest = xmalloc (sizeof *nest);
*nest = (struct ctables_nest) {
for (enum ctables_summary_variant sv = 0; sv < N_CSVS; sv++)
{
ctables_summary_spec_set_clone (&nest->specs[sv], &a->specs[sv]);
- nest->specs[sv].var = a->var.var;
+ nest->specs[sv].var = a->var;
nest->specs[sv].is_scale = a->scale;
}
return (struct ctables_stack) { .nests = nest, .n = 1 };
enum ctables_summary_function function
= specs->is_scale ? CTSF_MEAN : CTSF_COUNT;
- struct ctables_var var = { .is_mrset = false, .var = specs->var };
*specs->specs = (struct ctables_summary_spec) {
.function = function,
- .format = ctables_summary_default_format (function, &var),
+ .format = ctables_summary_default_format (function, specs->var),
.label = ctables_summary_default_label (function, 0),
};
if (!specs->var)