if (settings_get_safer_mode ())
{
- msg (SE, _("This command not allowed when the %s option is set."), "SAFER");
+ lex_ofs_error (lexer, 0, 0,
+ _("This command not allowed when the %s option is set."),
+ "SAFER");
return CMD_FAILURE;
}
}
int
-cmd_inside_do_if (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
+cmd_inside_do_if (struct lexer *lexer, struct dataset *ds UNUSED)
{
- msg (SE, _("This command cannot appear outside DO IF...END IF."));
+ lex_ofs_error (lexer, 0, lex_ofs (lexer) - 1,
+ _("This command cannot appear outside DO IF...END IF."));
return CMD_FAILURE;
}
}
int
-cmd_inside_loop (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
+cmd_inside_loop (struct lexer *lexer, struct dataset *ds UNUSED)
{
- msg (SE, _("This command cannot appear outside LOOP...END LOOP."));
+ lex_ofs_error (lexer, 0, lex_ofs (lexer) - 1,
+ _("This command cannot appear outside LOOP...END LOOP."));
return CMD_FAILURE;
}
goto error;
name = lex_tokcstr (lexer);
if (dict_lookup_var (dict, name))
- msg (SW, _("Dummy variable name `%s' hides dictionary variable `%s'."),
- name, name);
+ lex_msg (lexer, SW,
+ _("Dummy variable name `%s' hides dictionary variable `%s'."),
+ name, name);
size_t name_len = strlen (name);
if (find_dummy_var (dummies, name, name_len))
}
\f
int
-cmd_end_repeat (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
+cmd_end_repeat (struct lexer *lexer, struct dataset *ds UNUSED)
{
- msg (SE, _("No matching %s."), "DO REPEAT");
+ lex_ofs_error (lexer, 0, 1, _("No matching %s."), "DO REPEAT");
return CMD_CASCADING_FAILURE;
}
int
cmd_input_program (struct lexer *lexer, struct dataset *ds)
{
+ struct msg_location *location = lex_ofs_location (lexer, 0, 1);
if (!lex_match (lexer, T_ENDCMD))
- return lex_end_of_command (lexer);
+ {
+ msg_location_destroy (location);
+ return lex_end_of_command (lexer);
+ }
struct session *session = session_create (dataset_session (ds));
struct dataset *inp_ds = dataset_create (session, "INPUT PROGRAM");
msg (SE, _("Unexpected end-of-file within %s."), "INPUT PROGRAM");
inside_input_program = false;
destroy_input_program (inp);
+ msg_location_destroy (location);
return result;
}
}
inside_input_program = false;
proc_pop_transformations (inp->ds, &inp->xforms);
+ struct msg_location *end = lex_ofs_location (lexer, 0, 2);
+ msg_location_merge (&location, end);
+ location->omit_underlines = true;
+ msg_location_destroy (end);
+
if (!saw_DATA_LIST && !saw_END_FILE)
{
- msg (SE, _("Input program must contain %s or %s."), "DATA LIST", "END FILE");
+ msg_at (SE, location, _("Input program does not contain %s or %s."),
+ "DATA LIST", "END FILE");
destroy_input_program (inp);
+ msg_location_destroy (location);
return CMD_FAILURE;
}
if (dict_get_next_value_idx (dataset_dict (inp->ds)) == 0)
{
- msg (SE, _("Input program did not create any variables."));
+ msg_at (SE, location, _("Input program did not create any variables."));
destroy_input_program (inp);
+ msg_location_destroy (location);
return CMD_FAILURE;
}
+ msg_location_destroy (location);
/* Figure out how to initialize each input case. */
inp->init = caseinit_create ();
struct variable ***vars, size_t **indexes,
size_t *n_vars)
{
+ int start_ofs = lex_ofs (lexer);
if (!parse_variables (lexer, dict, vars, n_vars, 0))
return false;
+ int end_ofs = lex_ofs (lexer) - 1;
*indexes = xnmalloc (*n_vars, sizeof **indexes);
for (size_t i = 0; i < *n_vars; i++)
struct variable *v = (*vars)[i];
if (!strcasecmp (var_get_name (v), "ROWTYPE_"))
{
- msg (SE, _("ROWTYPE_ is not allowed on SPLIT or FACTORS."));
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("ROWTYPE_ is not allowed on SPLIT or FACTORS."));
goto error;
}
(*indexes)[i] = var_get_dict_index (v);
/* Check that OLD_NAME can be renamed to NEW_NAME in DICT. */
static bool
-check_rename (const struct dictionary *dict, const char *old_name, const char *new_name)
+check_rename (struct lexer *lexer, int start_ofs, int end_ofs,
+ const struct dictionary *dict,
+ const char *old_name, const char *new_name)
{
if (dict_lookup_var (dict, new_name) != NULL)
{
- msg (SE, _("Cannot rename %s as %s because there already exists "
- "a variable named %s. To rename variables with "
- "overlapping names, use a single RENAME subcommand "
- "such as `/RENAME (A=B)(B=C)(C=A)', or equivalently, "
- "`/RENAME (A B C=B C A)'."),
- old_name, new_name, new_name);
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("Cannot rename %s as %s because a variable named %s "
+ "already exists."),
+ old_name, new_name, new_name);
+ msg (SN, _("To rename variables with overlapping names, use a single "
+ "RENAME subcommand such as `/RENAME (A=B)(B=C)(C=A)', or "
+ "equivalently, `/RENAME (A B C=B C A)'."));
return false;
}
return true;
{
/* These 3 tokens have already been checked in the
try_to_sequence function. */
+ int start_ofs = lex_ofs (lexer);
lex_get (lexer);
lex_get (lexer);
lex_get (lexer);
+ int end_ofs = lex_ofs (lexer) - 1;
/* Make sure the new names are suitable. */
for (int i = first; i <= last; ++i)
{
- int sz = strlen (prefix) + intlog10 (last) + 1;
- char *vn = malloc (sz);
- snprintf (vn, sz, "%s%d", prefix, i);
+ char *vn = xasprintf ("%s%d", prefix, i);
- if (!check_rename (dict, var_get_name (oldvars[n_newvars]), vn))
+ if (!check_rename (lexer, start_ofs, end_ofs,
+ dict, var_get_name (oldvars[n_newvars]), vn))
{
+ free (vn);
free (prefix);
goto fail;
}
}
}
- if (!check_rename (dict, var_get_name (oldvars[n_newvars]), new_name))
+ int ofs = lex_ofs (lexer);
+ if (!check_rename (lexer, ofs, ofs,
+ dict, var_get_name (oldvars[n_newvars]), new_name))
goto fail;
- newnames[n_newvars] = strdup (new_name);
+ newnames[n_newvars] = xstrdup (new_name);
lex_get (lexer);
n_newvars++;
}
#include "data/variable.h"
#include "language/command.h"
#include "language/lexer/lexer.h"
+#include "language/lexer/token.h"
#include "language/lexer/value-parser.h"
#include "language/lexer/variable-parser.h"
#include "libpspp/i18n.h"
for (i = 0; i < nv; i++)
var_clear_missing_values (v[i]);
+ int start_ofs = lex_ofs (lexer);
+ int end_ofs;
+ for (end_ofs = start_ofs; ; end_ofs++)
+ {
+ enum token_type next = lex_ofs_token (lexer, end_ofs + 1)->type;
+ if (next == T_RPAREN || next == T_ENDCMD || next == T_STOP)
+ break;
+ }
+
if (!lex_match (lexer, T_RPAREN))
{
struct missing_values mv;
? mv_add_num (&mv, x)
: mv_add_range (&mv, x, y)))
{
- msg (SE, _("Too many numeric missing values. At most "
- "three individual values or one value and "
- "one range are allowed."));
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("Too many numeric missing values. At "
+ "most three individual values or one "
+ "value and one range are allowed."));
ok = false;
}
if (!mv_add_str (&mv, CHAR_CAST (const uint8_t *, raw_s),
strlen (raw_s)))
{
- msg (SE,
- _("Too many string missing values. "
- "At most three individual values are allowed."));
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("Too many string missing values. "
+ "At most three individual values "
+ "are allowed."));
ok = false;
}
free (raw_s);
var_set_missing_values (v[i], &mv);
else
{
- msg (SE, _("Missing values provided are too long to assign "
- "to variable of width %d."),
- var_get_width (v[i]));
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("Missing values are too long to assign "
+ "to variable %s with width %d."),
+ var_get_name (v[i]), var_get_width (v[i]));
ok = false;
}
}
}
already_encountered |= 4;
+ int start_ofs = lex_ofs (lexer) - 1;
lex_match (lexer, T_EQUALS);
if (!parse_variables (lexer, dataset_dict (ds),
&drop_vars, &n_drop, PV_NONE))
goto done;
+ int end_ofs = lex_ofs (lexer) - 1;
vm.drop_vars = drop_vars;
vm.n_drop = n_drop;
if (n_drop == dict_get_n_vars (dataset_dict (ds)))
{
- msg (SE, _("%s may not be used to delete all variables "
- "from the active dataset dictionary. "
- "Use %s instead."), "MODIFY VARS", "NEW FILE");
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("%s may not be used to delete all variables "
+ "from the active dataset dictionary. "
+ "Use %s instead."), "MODIFY VARS", "NEW FILE");
goto done;
}
}
enum mrset_type type)
{
const char *subcommand_name = type == MRSET_MD ? "MDGROUP" : "MCGROUP";
- bool labelsource_varlabel;
- bool has_value;
struct mrset *mrset = XZALLOC (struct mrset);
mrset->type = type;
mrset->cat_source = MRSET_VARLABELS;
- labelsource_varlabel = false;
- has_value = false;
+ bool labelsource_varlabel = false;
+ bool has_value = false;
+
+ int vars_start = 0;
+ int vars_end = 0;
+ int value_ofs = 0;
+ int labelsource_start = 0;
+ int labelsource_end = 0;
+ int label_start = 0;
+ int label_end = 0;
while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
{
if (lex_match_id (lexer, "NAME"))
goto error;
free (mrset->vars);
+ vars_start = lex_ofs (lexer);
if (!parse_variables (lexer, dict, &mrset->vars, &mrset->n_vars,
PV_SAME_TYPE | PV_NO_SCRATCH))
goto error;
+ vars_end = lex_ofs (lexer) - 1;
if (mrset->n_vars < 2)
{
- msg (SE, _("VARIABLES specified only variable %s on %s, but "
- "at least two variables are required."),
+ lex_ofs_error (lexer, vars_start, vars_end,
+ _("VARIABLES specified only variable %s on %s, but "
+ "at least two variables are required."),
var_get_name (mrset->vars[0]), subcommand_name);
goto error;
}
}
else if (lex_match_id (lexer, "LABEL"))
{
+ label_start = lex_ofs (lexer) - 1;
if (!lex_force_match (lexer, T_EQUALS) || !lex_force_string (lexer))
goto error;
+ label_end = lex_ofs (lexer);
free (mrset->label);
mrset->label = ss_xstrdup (lex_tokss (lexer));
goto error;
labelsource_varlabel = true;
+ labelsource_start = lex_ofs (lexer) - 3;
+ labelsource_end = lex_ofs (lexer) - 1;
}
else if (type == MRSET_MD && lex_match_id (lexer, "VALUE"))
{
goto error;
has_value = true;
+ value_ofs = lex_ofs (lexer);
if (lex_is_number (lexer))
{
if (!lex_is_integer (lexer))
{
if (mrset->width == 0)
{
- msg (SE, _("MDGROUP subcommand for group %s specifies a string "
- "VALUE, but the variables specified for this group "
- "are numeric."),
- mrset->name);
+ lex_ofs_error (lexer, value_ofs, value_ofs,
+ _("MDGROUP subcommand for group %s specifies a "
+ "string VALUE, but the variables specified for "
+ "this group are numeric."),
+ mrset->name);
goto error;
}
else {
}
if (mrset->width > min_width)
{
- msg (SE, _("VALUE string on MDGROUP subcommand for group "
- "%s is %d bytes long, but it must be no longer "
- "than the narrowest variable in the group, "
- "which is %s with a width of %d bytes."),
- mrset->name, mrset->width,
- var_get_name (shortest_var), min_width);
+ lex_ofs_error (lexer, value_ofs, value_ofs,
+ _("VALUE string on MDGROUP subcommand for "
+ "group %s is %d bytes long, but it must be "
+ "no longer than the narrowest variable in "
+ "the group, which is %s with a width of "
+ "%d bytes."),
+ mrset->name, mrset->width,
+ var_get_name (shortest_var), min_width);
goto error;
}
}
{
if (mrset->width != 0)
{
- msg (SE, _("MDGROUP subcommand for group %s specifies a string "
- "VALUE, but the variables specified for this group "
- "are numeric."),
+ lex_ofs_error (lexer, value_ofs, value_ofs,
+ _("MDGROUP subcommand for group %s specifies a "
+ "string VALUE, but the variables specified for "
+ "this group are numeric."),
mrset->name);
goto error;
}
if (labelsource_varlabel)
{
if (mrset->cat_source != MRSET_COUNTEDVALUES)
- msg (SW, _("MDGROUP subcommand for group %s specifies "
- "LABELSOURCE=VARLABEL but not "
- "CATEGORYLABELS=COUNTEDVALUES. "
- "Ignoring LABELSOURCE."),
+ lex_ofs_msg (lexer, SW, labelsource_start, labelsource_end,
+ _("MDGROUP subcommand for group %s specifies "
+ "LABELSOURCE=VARLABEL but not "
+ "CATEGORYLABELS=COUNTEDVALUES. "
+ "Ignoring LABELSOURCE."),
mrset->name);
else if (mrset->label)
- msg (SW, _("MDGROUP subcommand for group %s specifies both LABEL "
- "and LABELSOURCE, but only one of these subcommands "
- "may be used at a time. Ignoring LABELSOURCE."),
- mrset->name);
+ {
+ msg (SW, _("MDGROUP subcommand for group %s specifies both "
+ "LABEL and LABELSOURCE, but only one of these "
+ "subcommands may be used at a time. "
+ "Ignoring LABELSOURCE."),
+ mrset->name);
+ lex_ofs_msg (lexer, SN, label_start, label_end,
+ _("Here is the %s setting."), "LABEL");
+ lex_ofs_msg (lexer, SN, labelsource_start, labelsource_end,
+ _("Here is the %s setting."), "LABELSOURCE");
+ }
else
{
size_t i;
if (other_name == NULL)
stringi_map_insert (&seen, label, name);
else
- msg (SW, _("Variables %s and %s specified as part of "
- "multiple dichotomy group %s have the same "
- "variable label. Categories represented by "
- "these variables will not be distinguishable "
- "in output."),
- other_name, name, mrset->name);
+ lex_ofs_msg (lexer, SW, vars_start, vars_end,
+ _("Variables %s and %s specified as part of "
+ "multiple dichotomy group %s have the same "
+ "variable label. Categories represented by "
+ "these variables will not be distinguishable "
+ "in output."),
+ other_name, name, mrset->name);
}
}
stringi_map_destroy (&seen);
val_labs = var_get_value_labels (var);
label = val_labs_find (val_labs, &value);
if (label == NULL)
- msg (SW, _("Variable %s specified as part of multiple "
- "dichotomy group %s (which has "
- "CATEGORYLABELS=COUNTEDVALUES) has no value label "
- "for its counted value. This category will not "
- "be distinguishable in output."),
+ lex_ofs_msg (lexer, SW, vars_start, vars_end,
+ _("Variable %s specified as part of multiple "
+ "dichotomy group %s (which has "
+ "CATEGORYLABELS=COUNTEDVALUES) has no value "
+ "label for its counted value. This category "
+ "will not be distinguishable in output."),
name, mrset->name);
else
{
if (other_name == NULL)
stringi_map_insert (&seen, label, name);
else
- msg (SW, _("Variables %s and %s specified as part of "
- "multiple dichotomy group %s (which has "
- "CATEGORYLABELS=COUNTEDVALUES) have the same "
- "value label for the group's counted "
- "value. These categories will not be "
- "distinguishable in output."),
- other_name, name, mrset->name);
+ lex_ofs_msg (lexer, SW, vars_start, vars_end,
+ _("Variables %s and %s specified as part of "
+ "multiple dichotomy group %s (which has "
+ "CATEGORYLABELS=COUNTEDVALUES) have the same "
+ "value label for the group's counted "
+ "value. These categories will not be "
+ "distinguishable in output."),
+ other_name, name, mrset->name);
}
}
stringi_map_destroy (&seen);
var_get_print_format (var),
settings_get_fmt_settings ());
c->warned = true;
- msg (SW, _("Variables specified on MCGROUP should "
- "have the same categories, but %s and %s "
- "(and possibly others) in multiple "
- "category group %s have different "
- "value labels for value %s."),
- c->var_name, name, mrset->name, s);
+ lex_ofs_msg (lexer, SW, vars_start, vars_end,
+ _("Variables specified on MCGROUP should "
+ "have the same categories, but %s and "
+ "%s (and possibly others) in multiple "
+ "category group %s have different "
+ "value labels for value %s."),
+ c->var_name, name, mrset->name, s);
free (s);
}
goto found;
if (n == 0)
{
if (dict_get_n_mrsets (dict) == 0)
- msg (SN, _("The active dataset dictionary does not contain any "
- "multiple response sets."));
+ lex_next_msg (lexer, SN, -1, -1,
+ _("The active dataset dictionary does not contain any "
+ "multiple response sets."));
stringi_set_destroy (&mrset_names_set);
return true;
}
if (!lex_match (lexer, T_LPAREN))
opts |= PV_SINGLE;
+ int start_ofs = lex_ofs (lexer);
if (!parse_variables (lexer, dataset_dict (ds),
&vars_to_be_renamed, &n_vars_to_be_renamed, opts))
{
{
goto lossage;
}
+ int end_ofs = lex_ofs (lexer) - 1;
if (n_new_names != n_vars_to_be_renamed)
{
- msg (SE, _("Differing number of variables in old name list "
- "(%zu) and in new name list (%zu)."),
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("Differing number of variables in old name list "
+ "(%zu) and in new name list (%zu)."),
n_vars_to_be_renamed, n_new_names);
goto lossage;
}
vars_to_be_renamed, new_names, n_new_names,
&err_name))
{
- msg (SE, _("Renaming would duplicate variable name %s."), err_name);
+ lex_ofs_error (lexer, 2, lex_ofs (lexer) - 1,
+ _("Renaming would duplicate variable name %s."), err_name);
goto lossage;
}
: SPLIT_LAYERED);
lex_match (lexer, T_BY);
+ int vars_start = lex_ofs (lexer);
if (!parse_variables (lexer, dataset_dict (ds), &v, &n, PV_NO_DUPLICATE))
return CMD_CASCADING_FAILURE;
+ int vars_end = lex_ofs (lexer) - 1;
if (n > MAX_SPLITS)
{
verify (MAX_SPLITS == 8);
- msg (SE, _("At most 8 split variables may be specified."));
+ lex_ofs_error (lexer, vars_start, vars_end,
+ _("At most 8 split variables may be specified."));
free (v);
return CMD_CASCADING_FAILURE;
}
vl, n, attribute_flags);
}
else
- msg (SW, _("No variables to display."));
+ msg (SN, _("No variables to display."));
free (vl);
}
}
/* Parses a numeric expression that is intended to be assigned to newly created
- variable NEW_VAR_NAME. (This allows for a better error message if the
- expression is not numeric.) Otherwise similar to expr_parse(). */
+ variable NEW_VAR_NAME at NEW_VAR_LOCATION. (This allows for a better error
+ message if the expression is not numeric.) Otherwise similar to
+ expr_parse(). */
struct expression *
expr_parse_new_variable (struct lexer *lexer, struct dataset *ds,
- const char *new_var_name)
+ const char *new_var_name,
+ const struct msg_location *new_var_location)
{
struct expression *e = expr_create (ds);
struct expr_node *n = parse_expr (lexer, e);
atom_type actual_type = expr_node_returns (n);
if (actual_type != OP_number && actual_type != OP_boolean)
{
- msg (SE, _("This command tries to create a new variable %s by assigning a "
- "string value to it, but this is not supported. Use "
- "the STRING command to create the new variable with the "
- "correct width before assigning to it, e.g. STRING %s(A20)."),
+ msg_at (SE, new_var_location,
+ _("This command tries to create a new variable %s by assigning a "
+ "string value to it, but this is not supported. Use "
+ "the STRING command to create the new variable with the "
+ "correct width before assigning to it, e.g. STRING %s(A20)."),
new_var_name, new_var_name);
expr_free (e);
return NULL;
struct dictionary;
struct expression;
struct lexer;
+struct msg_location;
struct pool;
union value;
struct expression *expr_parse (struct lexer *, struct dataset *, enum val_type);
struct expression *expr_parse_bool (struct lexer *, struct dataset *);
-struct expression *expr_parse_new_variable (struct lexer *, struct dataset *,
- const char *new_var_name);
+struct expression *expr_parse_new_variable (
+ struct lexer *, struct dataset *,
+ const char *new_var_name, const struct msg_location *new_var_location);
void expr_free (struct expression *);
struct dataset;
return parse_number (lexer, &v->f, &var_get_print_format (var)->type);
else if (lex_force_string (lexer))
{
- const char *s = lex_tokcstr (lexer);
- value_copy_str_rpad (v, width, CHAR_CAST_BUG (const uint8_t *, s), ' ');
+ struct substring out;
+ if (recode_pedantically (var_get_encoding (var), "UTF-8",
+ lex_tokss (lexer), NULL, &out))
+ {
+ lex_error (lexer, _("This string is not representable in the "
+ "dataset encoding."));
+ return false;
+ }
+ if (out.length > width)
+ {
+ lex_error (lexer, _("This %zu-byte string is too long for "
+ "variable %s with width %d."),
+ out.length, var_get_name (var), width);
+ ss_dealloc (&out);
+ return false;
+ }
+
+ value_copy_buf_rpad (v, width, CHAR_CAST (const uint8_t *, out.string),
+ out.length, ' ');
+ ss_dealloc (&out);
}
else
return false;
double *row_tot; /* Row totals. */
double *col_tot; /* Column totals. */
double total; /* Grand total. */
+
+ /* Syntax. */
+ int start_ofs;
+ int end_ofs;
};
/* Integer mode variable info. */
double weight);
static void tabulate_integer_case (struct crosstabulation *, const struct ccase *,
double weight);
-static void postcalc (struct crosstabs_proc *);
+static void postcalc (struct crosstabs_proc *, struct lexer *);
static double
round_weight (const struct crosstabs_proc *proc, double weight)
casereader_destroy (group);
/* Output. */
- postcalc (&proc);
+ postcalc (&proc, lexer);
}
bool ok = casegrouper_destroy (grouper);
ok = proc_commit (ds) && ok;
size_t nx = 1;
int n_by = 0;
+ int vars_start = lex_ofs (lexer);
for (;;)
{
by = xnrealloc (by, n_by + 1, sizeof *by);
goto done;
if (xalloc_oversized (nx, by_nvar[n_by]))
{
- msg (SE, _("Too many cross-tabulation variables or dimensions."));
+ lex_ofs_error (
+ lexer, vars_start, lex_ofs (lexer),
+ _("Too many cross-tabulation variables or dimensions."));
goto done;
}
nx *= by_nvar[n_by];
break;
}
}
+ int vars_end = lex_ofs (lexer) - 1;
int *by_iter = XCALLOC (n_by, int);
proc->pivots = xnrealloc (proc->pivots,
.n_consts = 0,
.const_vars = NULL,
.const_indexes = NULL,
+ .start_ofs = vars_start,
+ .end_ofs = vars_end,
};
for (int j = 0; j < n_by; j++)
bool descending);
static void free_var_values (const struct crosstabulation *, int var_idx);
static void output_crosstabulation (struct crosstabs_proc *,
- struct crosstabulation *);
+ struct crosstabulation *,
+ struct lexer *);
static void make_crosstabulation_subset (struct crosstabulation *xt,
size_t row0, size_t row1,
struct crosstabulation *subset);
size_t *row1p);
static void
-postcalc (struct crosstabs_proc *proc)
+postcalc (struct crosstabs_proc *proc, struct lexer *lexer)
{
/* Round hash table entries, if requested
for (struct crosstabulation *xt = proc->pivots;
xt < &proc->pivots[proc->n_pivots]; xt++)
{
- output_crosstabulation (proc, xt);
+ output_crosstabulation (proc, xt, lexer);
if (proc->barchart)
{
int n_vars = (xt->n_vars > 2 ? 2 : xt->n_vars);
/* Output pivot table XT in the context of PROC. */
static void
-output_crosstabulation (struct crosstabs_proc *proc, struct crosstabulation *xt)
+output_crosstabulation (struct crosstabs_proc *proc, struct crosstabulation *xt,
+ struct lexer *lexer)
{
for (size_t i = 0; i < xt->n_vars; i++)
enum_var_values (xt, i, proc->descending);
/* TRANSLATORS: The %s here describes a crosstabulation. It takes the
form "var1 * var2 * var3 * ...". */
- msg (SW, _("Crosstabulation %s contained no non-missing cases."),
- ds_cstr (&vars));
+ lex_ofs_msg (lexer, SW, xt->start_ofs, xt->end_ofs,
+ _("Crosstabulation %s contained no non-missing cases."),
+ ds_cstr (&vars));
ds_destroy (&vars);
for (size_t i = 0; i < xt->n_vars; i++)
dsc->z_writer = NULL;
/* Parse DESCRIPTIVES. */
+ int z_ofs = 0;
while (lex_token (lexer) != T_ENDCMD)
{
if (lex_match_id (lexer, "MISSING"))
}
}
else if (lex_match_id (lexer, "SAVE"))
- save_z_scores = 1;
+ {
+ save_z_scores = 1;
+ z_ofs = lex_ofs (lexer) - 1;
+ }
else if (lex_match_id (lexer, "FORMAT"))
{
lex_match (lexer, T_EQUALS);
{
if (!lex_force_id (lexer))
goto error;
+ z_ofs = lex_ofs (lexer);
if (try_name (dict, dsc, lex_tokcstr (lexer)))
{
struct dsc_var *dsc_var = &dsc->vars[dsc->n_vars - 1];
that) when TEMPORARY is in effect, but in the meantime this at least
prevents a use-after-free error. See bug #38786. */
if (proc_make_temporary_transformations_permanent (ds))
- msg (SW, _("DESCRIPTIVES with Z scores ignores TEMPORARY. "
- "Temporary transformations will be made permanent."));
+ lex_ofs_msg (lexer, SW, z_ofs, z_ofs,
+ _("DESCRIPTIVES with Z scores ignores TEMPORARY. "
+ "Temporary transformations will be made permanent."));
proto = caseproto_create ();
for (i = 0; i < 1 + 2 * n_zs; i++)
For a vector element, the `vector' member is non-null. */
struct lvalue
{
+ struct msg_location *location; /* Syntax for variable or vector. */
+
struct variable *variable; /* Destination variable. */
bool is_new_variable; /* Did we create the variable? */
const struct vector *vector; /* Destination vector, if any. */
struct expression *element; /* Destination vector element expr. */
+ struct msg_location *lvalue_location;
+
/* Rvalue. */
struct expression *rvalue; /* Rvalue expression. */
};
|| rindx < 1 || rindx > vector_get_n_vars (compute->vector))
{
if (index == SYSMIS)
- msg (SW, _("When executing COMPUTE: SYSMIS is not a valid value "
- "as an index into vector %s."),
+ msg_at (SW, compute->lvalue_location,
+ _("When executing COMPUTE: SYSMIS is not a valid value "
+ "as an index into vector %s."),
vector_get_name (compute->vector));
else
- msg (SW, _("When executing COMPUTE: %.*g is not a valid value as "
+ msg_at (SW, compute->lvalue_location,
+ _("When executing COMPUTE: %.*g is not a valid value as "
"an index into vector %s."),
DBL_DIG + 1, index, vector_get_name (compute->vector));
return TRNS_CONTINUE;
rindx = floor (index + EPSILON);
if (index == SYSMIS)
{
- msg (SW, _("When executing COMPUTE: SYSMIS is not a valid "
- "value as an index into vector %s."),
- vector_get_name (compute->vector));
+ msg_at (SW, compute->lvalue_location,
+ _("When executing COMPUTE: SYSMIS is not a valid "
+ "value as an index into vector %s."),
+ vector_get_name (compute->vector));
return TRNS_CONTINUE;
}
else if (rindx < 1 || rindx > vector_get_n_vars (compute->vector))
{
- msg (SW, _("When executing COMPUTE: %.*g is not a valid value as "
- "an index into vector %s."),
- DBL_DIG + 1, index, vector_get_name (compute->vector));
+ msg_at (SW, compute->lvalue_location,
+ _("When executing COMPUTE: %.*g is not a valid value as "
+ "an index into vector %s."),
+ DBL_DIG + 1, index, vector_get_name (compute->vector));
return TRNS_CONTINUE;
}
const struct lvalue *lvalue, struct dataset *ds)
{
if (lvalue->is_new_variable)
- return expr_parse_new_variable (lexer, ds, var_get_name (lvalue->variable));
+ return expr_parse_new_variable (lexer, ds, var_get_name (lvalue->variable),
+ lvalue->location);
else
return expr_parse (lexer, ds, lvalue_get_type (lvalue));
}
compute_trns_create (void)
{
struct compute_trns *compute = xmalloc (sizeof *compute);
- compute->test = NULL;
- compute->variable = NULL;
- compute->vector = NULL;
- compute->element = NULL;
- compute->rvalue = NULL;
+ *compute = (struct compute_trns) { .test = NULL };
return compute;
}
if (compute != NULL)
{
+ msg_location_destroy (compute->lvalue_location);
expr_free (compute->test);
expr_free (compute->element);
expr_free (compute->rvalue);
lvalue_parse (struct lexer *lexer, struct dataset *ds)
{
struct dictionary *dict = dataset_dict (ds);
- struct lvalue *lvalue;
- lvalue = xmalloc (sizeof *lvalue);
- lvalue->variable = NULL;
- lvalue->is_new_variable = false;
- lvalue->vector = NULL;
- lvalue->element = NULL;
+ struct lvalue *lvalue = xmalloc (sizeof *lvalue);
+ *lvalue = (struct lvalue) { .variable = NULL };
if (!lex_force_id (lexer))
goto lossage;
+ int start_ofs = lex_ofs (lexer);
if (lex_next_token (lexer, 1) == T_LPAREN)
{
/* Vector. */
}
lex_get (lexer);
}
+ int end_ofs = lex_ofs (lexer) - 1;
+ lvalue->location = lex_ofs_location (lexer, start_ofs, end_ofs);
return lvalue;
lossage:
struct compute_trns *compute,
struct dictionary *dict)
{
+ compute->lvalue_location = lvalue->location;
+ lvalue->location = NULL;
+
if (lvalue->vector == NULL)
{
compute->variable = lvalue->variable;
if (lvalue->is_new_variable)
dict_delete_var (dict, lvalue->variable);
expr_free (lvalue->element);
+ msg_location_destroy (lvalue->location);
free (lvalue);
}
int c0 = ln == l0 ? loc->start.column : 1;
int c1 = ln == l1 ? loc->end.column : ss_utf8_count_columns (line);
- if (c0 > 0 && c1 >= c0)
+ if (c0 > 0 && c1 >= c0 && !loc->omit_underlines)
{
ds_put_cstr (&s, "\n |");
ds_put_byte_multiple (&s, ' ', c0);
Both 'start' and 'end' are inclusive, line-wise and column-wise.
*/
struct msg_point start, end;
+
+ /* Normally, 'start' and 'end' contain column information, then displaying
+ the message will underline the location. Setting this to true disables
+ displaying underlines. */
+ bool omit_underlines;
};
void msg_location_uninit (struct msg_location *);
AÈIÖU,aeiou
1.00,2.00
-dictionary.sps:8: error: RENAME VARIABLES: Renaming would duplicate variable name aèiöu.
+"dictionary.sps:8.17-8.29: error: RENAME VARIABLES: Renaming would duplicate variable name aèiöu.
+ 8 | RENAME VARIABLE (aeiou=aèiöu).
+ | ^~~~~~~~~~~~~"
])
AT_CLEANUP
erase FILE='foobar'.
])
AT_CHECK([pspp -O format=csv erase.sps], [1], [dnl
-erase.sps:3: error: ERASE: This command not allowed when the SAFER option is set.
+"erase.sps:3.1-3.5: error: ERASE: This command not allowed when the SAFER option is set.
+ 3 | erase FILE='foobar'.
+ | ^~~~~"
])
AT_CHECK([cat foobar], [0], [contents
])
DO IF 0.
])
AT_CHECK([pspp -O format=csv do-if.sps], [1], [dnl
-do-if.sps:6: error: END IF: This command cannot appear outside DO IF...END IF.
+"do-if.sps:6.1-6.6: error: END IF: This command cannot appear outside DO IF...END IF.
+ 6 | END IF.
+ | ^~~~~~"
-do-if.sps:7: error: ELSE: This command cannot appear outside DO IF...END IF.
+"do-if.sps:7.1-7.4: error: ELSE: This command cannot appear outside DO IF...END IF.
+ 7 | ELSE.
+ | ^~~~"
-do-if.sps:8: error: ELSE IF: This command cannot appear outside DO IF...END IF.
+"do-if.sps:8.1-8.7: error: ELSE IF: This command cannot appear outside DO IF...END IF.
+ 8 | ELSE IF 1.
+ | ^~~~~~~"
"do-if.sps:12.1-12.4: error: DO IF: Only one ELSE is allowed within DO IF...END IF.
12 | ELSE.
LIST.
])
AT_CHECK([pspp -o pspp.csv do-repeat.sps], [0], [dnl
-do-repeat.sps:8: warning: DO REPEAT: Dummy variable name `x' hides dictionary variable `x'.
+do-repeat.sps:8.11: warning: DO REPEAT: Dummy variable name `x' hides dictionary variable `x'.
+ 8 | DO REPEAT x = 1 2 3.
+ | ^
])
AT_CHECK([cat pspp.csv], [0], [dnl
-do-repeat.sps:8: warning: DO REPEAT: Dummy variable name `x' hides dictionary variable `x'.
+"do-repeat.sps:8.11: warning: DO REPEAT: Dummy variable name `x' hides dictionary variable `x'.
+ 8 | DO REPEAT x = 1 2 3.
+ | ^"
Table: Data List
x,y
LOOP.
])
AT_CHECK([pspp loop.sps], 1, [dnl
-loop.sps:2: error: BREAK: This command cannot appear outside LOOP...END LOOP.
-
-loop.sps:3: error: END LOOP: This command cannot appear outside LOOP...END
+loop.sps:2.1-2.5: error: BREAK: This command cannot appear outside LOOP...END
LOOP.
+ 2 | BREAK.
+ | ^~~~~
+
+loop.sps:3.1-3.8: error: END LOOP: This command cannot appear outside LOOP...
+END LOOP.
+ 3 | END LOOP.
+ | ^~~~~~~~
loop.sps:5: error: LOOP: Only one index clause may be specified.
EXECUTE.
])
AT_CHECK([pspp -O format=csv input-program.sps], [1], [dnl
-input-program.sps:3: error: INPUT PROGRAM: Input program must contain DATA LIST or END FILE.
+"input-program.sps:1.1-3.17: error: INPUT PROGRAM: Input program does not contain DATA LIST or END FILE.
+ 1 | INPUT PROGRAM.
+ 2 | STRING firstname lastname (a24) / address (a80).
+ 3 | END INPUT PROGRAM."
"input-program.sps:4.1-4.7: error: EXECUTE: EXECUTE is allowed only after the active dataset has been defined.
4 | EXECUTE.
END INPUT PROGRAM.
])
AT_CHECK([pspp input-program.sps], 1, [dnl
-input-program.sps:3: error: INPUT PROGRAM: Input program did not create any
-variables.
+input-program.sps:1.1-3.17: error: INPUT PROGRAM: Input program did not create
+any variables.
+ 1 | INPUT PROGRAM.
+ 2 | END FILE.
+ 3 | END INPUT PROGRAM.
])
AT_CLEANUP
\ No newline at end of file
2 | MATRIX DATA VARIABLES=v v v.
| ^"
-matrix-data.sps:3: error: MATRIX DATA: ROWTYPE_ is not allowed on SPLIT or FACTORS.
+"matrix-data.sps:3.47-3.54: error: MATRIX DATA: ROWTYPE_ is not allowed on SPLIT or FACTORS.
+ 3 | MATRIX DATA VARIABLES=rowtype_ v1 v2 v3/SPLIT=rowtype_.
+ | ^~~~~~~~"
-matrix-data.sps:4: error: MATRIX DATA: ROWTYPE_ is not allowed on SPLIT or FACTORS.
+"matrix-data.sps:4.49-4.56: error: MATRIX DATA: ROWTYPE_ is not allowed on SPLIT or FACTORS.
+ 4 | MATRIX DATA VARIABLES=rowtype_ v1 v2 v3/FACTORS=rowtype_.
+ | ^~~~~~~~"
matrix-data.sps:5: error: MATRIX DATA: v1 may not appear on both SPLIT and FACTORS.
])
AT_CHECK([pspp -O format=csv bad.sps], [1], [dnl
-"bad.sps:16: error: SAVE TRANSLATE: Cannot rename Var2 as Var3 because there already exists a variable named Var3. To rename variables with overlapping names, use a single RENAME subcommand such as `/RENAME (A=B)(B=C)(C=A)', or equivalently, `/RENAME (A B C=B C A)'."
+"bad.sps:16.26-16.29: error: SAVE TRANSLATE: Cannot rename Var2 as Var3 because a variable named Var3 already exists.
+ 16 | (Var1 Var2 = one Var3 )
+ | ^~~~"
+
+"bad.sps:16: note: SAVE TRANSLATE: To rename variables with overlapping names, use a single RENAME subcommand such as `/RENAME (A=B)(B=C)(C=A)', or equivalently, `/RENAME (A B C=B C A)'."
])
MISSING VALUES num1 (2 THRU 1).
])
AT_CHECK([pspp -O format=csv missing-values.sps], [1], [dnl
-missing-values.sps:5: error: MISSING VALUES: Missing values provided are too long to assign to variable of width 3.
+"missing-values.sps:5.35-5.41: error: MISSING VALUES: Missing values are too long to assign to variable str2 with width 3.
+ 5 | MISSING VALUES str1 str2 longstr ('abcde').
+ | ^~~~~~~"
"missing-values.sps:8.25-8.37: error: MISSING VALUES: Truncating missing value to maximum acceptable length (8 bytes).
8 | MISSING VALUES longstr ('abcdefghijk').
missing-values.sps:14: error: MISSING VALUES: Cannot mix numeric variables (e.g. num1) and string variables (e.g. str1) within a single list.
-missing-values.sps:17: error: MISSING VALUES: Too many numeric missing values. At most three individual values or one value and one range are allowed.
+"missing-values.sps:17.22-17.31: error: MISSING VALUES: Too many numeric missing values. At most three individual values or one value and one range are allowed.
+ 17 | MISSING VALUES num1 (1, 2, 3, 4).
+ | ^~~~~~~~~~"
-missing-values.sps:18: error: MISSING VALUES: Too many numeric missing values. At most three individual values or one value and one range are allowed.
+"missing-values.sps:18.22-18.39: error: MISSING VALUES: Too many numeric missing values. At most three individual values or one value and one range are allowed.
+ 18 | MISSING VALUES num1 (1 THRU 2, 3 THRU 4).
+ | ^~~~~~~~~~~~~~~~~~"
-missing-values.sps:19: error: MISSING VALUES: Too many numeric missing values. At most three individual values or one value and one range are allowed.
+"missing-values.sps:19.22-19.35: error: MISSING VALUES: Too many numeric missing values. At most three individual values or one value and one range are allowed.
+ 19 | MISSING VALUES num1 (1, 2 THRU 3, 4).
+ | ^~~~~~~~~~~~~~"
-missing-values.sps:20: error: MISSING VALUES: Too many string missing values. At most three individual values are allowed.
+"missing-values.sps:20.22-20.47: error: MISSING VALUES: Too many string missing values. At most three individual values are allowed.
+ 20 | MISSING VALUES str1 ('abc', 'def', 'ghi', 'jkl').
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~"
"missing-values.sps:23.22-23.29: warning: MISSING VALUES: The high end of the range (1) is below the low end (2). The range will be treated as if reversed.
23 | MISSING VALUES num1 (2 THRU 1).
Name,Position
y,1
-modify-variables.sps:16: error: MODIFY VARS: MODIFY VARS may not be used to delete all variables from the active dataset dictionary. Use NEW FILE instead.
+"modify-variables.sps:16.14-16.19: error: MODIFY VARS: MODIFY VARS may not be used to delete all variables from the active dataset dictionary. Use NEW FILE instead.
+ 16 | MODIFY VARS /DROP y.
+ | ^~~~~~"
modify-variables.sps:17: error: Stopping syntax file processing here to avoid a cascade of dependent command failures.
])
VARIABLES=a b c d.
]])
-m4_define([DEFINE_MRSETS_OUTPUT],
- [mrsets.sps:25: warning: MRSETS: Variables w and z specified as part of multiple dichotomy group $a have the same variable label. Categories represented by these variables will not be distinguishable in output.
+m4_define([DEFINE_MRSETS_OUTPUT], [dnl
+"mrsets.sps:23.16-23.22: warning: MRSETS: Variables w and z specified as part of multiple dichotomy group $a have the same variable label. Categories represented by these variables will not be distinguishable in output.
+ 23 | VARIABLES=w x y z
+ | ^~~~~~~"
-mrsets.sps:29: warning: MRSETS: Variable z specified as part of multiple dichotomy group $b (which has CATEGORYLABELS=COUNTEDVALUES) has no value label for its counted value. This category will not be distinguishable in output.
+"mrsets.sps:27.16-27.18: warning: MRSETS: Variable z specified as part of multiple dichotomy group $b (which has CATEGORYLABELS=COUNTEDVALUES) has no value label for its counted value. This category will not be distinguishable in output.
+ 27 | VARIABLES=z y
+ | ^~~"
-mrsets.sps:29: warning: MRSETS: Variable y specified as part of multiple dichotomy group $b (which has CATEGORYLABELS=COUNTEDVALUES) has no value label for its counted value. This category will not be distinguishable in output.
+"mrsets.sps:27.16-27.18: warning: MRSETS: Variable y specified as part of multiple dichotomy group $b (which has CATEGORYLABELS=COUNTEDVALUES) has no value label for its counted value. This category will not be distinguishable in output.
+ 27 | VARIABLES=z y
+ | ^~~"
-mrsets.sps:34: warning: MRSETS: Variable x specified as part of multiple dichotomy group $c (which has CATEGORYLABELS=COUNTEDVALUES) has no value label for its counted value. This category will not be distinguishable in output.
+"mrsets.sps:32.16-32.22: warning: MRSETS: Variable x specified as part of multiple dichotomy group $c (which has CATEGORYLABELS=COUNTEDVALUES) has no value label for its counted value. This category will not be distinguishable in output.
+ 32 | VARIABLES=w x y z
+ | ^~~~~~~"
-mrsets.sps:34: warning: MRSETS: Variables y and z specified as part of multiple dichotomy group $c (which has CATEGORYLABELS=COUNTEDVALUES) have the same value label for the group's counted value. These categories will not be distinguishable in output.
+"mrsets.sps:32.16-32.22: warning: MRSETS: Variables y and z specified as part of multiple dichotomy group $c (which has CATEGORYLABELS=COUNTEDVALUES) have the same value label for the group's counted value. These categories will not be distinguishable in output.
+ 32 | VARIABLES=w x y z
+ | ^~~~~~~"
-mrsets.sps:38: warning: MRSETS: MDGROUP subcommand for group $d specifies LABELSOURCE=VARLABEL but not CATEGORYLABELS=COUNTEDVALUES. Ignoring LABELSOURCE.
+"mrsets.sps:35.6-35.25: warning: MRSETS: MDGROUP subcommand for group $d specifies LABELSOURCE=VARLABEL but not CATEGORYLABELS=COUNTEDVALUES. Ignoring LABELSOURCE.
+ 35 | LABELSOURCE=VARLABEL
+ | ^~~~~~~~~~~~~~~~~~~~"
-"mrsets.sps:41: warning: MRSETS: Variables specified on MCGROUP should have the same categories, but w and y (and possibly others) in multiple category group $e have different value labels for value 1."
+"mrsets.sps:40.16-40.22: warning: MRSETS: Variables specified on MCGROUP should have the same categories, but w and y (and possibly others) in multiple category group $e have different value labels for value 1.
+ 40 | VARIABLES=w x y z
+ | ^~~~~~~"
-"mrsets.sps:42: warning: MRSETS: Variables specified on MCGROUP should have the same categories, but a and c (and possibly others) in multiple category group $f have different value labels for value b."
+"mrsets.sps:42.16-42.22: warning: MRSETS: Variables specified on MCGROUP should have the same categories, but a and c (and possibly others) in multiple category group $f have different value labels for value b.
+ 42 | VARIABLES=a b c d.
+ | ^~~~~~~"
])
m4_define([MRSETS_DISPLAY_OUTPUT], [dnl
c
d"
-mrsets.sps:50: note: MRSETS: The active dataset dictionary does not contain any multiple response sets.
+"mrsets.sps:50.19-50.21: note: MRSETS: The active dataset dictionary does not contain any multiple response sets.
+ 50 | /DISPLAY NAME=ALL.
+ | ^~~"
])
AT_CLEANUP
[DEFINE_MRSETS_DATA
MRSETS /MCGROUP NAME=$x VARIABLES=a.
])
-AT_CHECK([pspp -O format=csv mrsets.sps], [1],
- ["mrsets.sps:6: error: MRSETS: VARIABLES specified only variable a on MCGROUP, but at least two variables are required."
+AT_CHECK([pspp -O format=csv mrsets.sps], [1], [dnl
+"mrsets.sps:6.35: error: MRSETS: VARIABLES specified only variable a on MCGROUP, but at least two variables are required.
+ 6 | MRSETS /MCGROUP NAME=$x VARIABLES=a.
+ | ^"
])
AT_CLEANUP
MRSETS /MDGROUP NAME=$group1 VARIABLES=a b VALUE=1.
MRSETS /MDGROUP NAME=$group2 VARIABLES=x y VALUE='abc'.
])
-AT_CHECK([pspp -O format=csv mrsets.sps], [1],
- ["mrsets.sps:6: error: MRSETS: MDGROUP subcommand for group $group1 specifies a string VALUE, but the variables specified for this group are numeric."
+AT_CHECK([pspp -O format=csv mrsets.sps], [1], [dnl
+"mrsets.sps:6.50: error: MRSETS: MDGROUP subcommand for group $group1 specifies a string VALUE, but the variables specified for this group are numeric.
+ 6 | MRSETS /MDGROUP NAME=$group1 VARIABLES=a b VALUE=1.
+ | ^"
-"mrsets.sps:7: error: MRSETS: MDGROUP subcommand for group $group2 specifies a string VALUE, but the variables specified for this group are numeric."
+"mrsets.sps:7.50-7.54: error: MRSETS: MDGROUP subcommand for group $group2 specifies a string VALUE, but the variables specified for this group are numeric.
+ 7 | MRSETS /MDGROUP NAME=$group2 VARIABLES=x y VALUE='abc'.
+ | ^~~~~"
])
AT_CLEANUP
[DEFINE_MRSETS_DATA
MRSETS /MDGROUP NAME=$group1 VARIABLES=a b VALUE='abc'.
])
-AT_CHECK([pspp -O format=csv mrsets.sps], [1],
- ["mrsets.sps:6: error: MRSETS: VALUE string on MDGROUP subcommand for group $group1 is 3 bytes long, but it must be no longer than the narrowest variable in the group, which is a with a width of 1 bytes."
+AT_CHECK([pspp -O format=csv mrsets.sps], [1], [dnl
+"mrsets.sps:6.50-6.54: error: MRSETS: VALUE string on MDGROUP subcommand for group $group1 is 3 bytes long, but it must be no longer than the narrowest variable in the group, which is a with a width of 1 bytes.
+ 6 | MRSETS /MDGROUP NAME=$group1 VARIABLES=a b VALUE='abc'.
+ | ^~~~~"
])
AT_CLEANUP
MRSETS /MDGROUP NAME=$group1 VARIABLES=a b VALUE='a'
LABEL='label' LABELSOURCE=VARLABEL.
])
-AT_CHECK([pspp -O format=csv mrsets.sps], [0],
- [mrsets.sps:7: warning: MRSETS: MDGROUP subcommand for group $group1 specifies LABELSOURCE=VARLABEL but not CATEGORYLABELS=COUNTEDVALUES. Ignoring LABELSOURCE.
+AT_CHECK([pspp -O format=csv mrsets.sps], [0], [dnl
+"mrsets.sps:7.31-7.50: warning: MRSETS: MDGROUP subcommand for group $group1 specifies LABELSOURCE=VARLABEL but not CATEGORYLABELS=COUNTEDVALUES. Ignoring LABELSOURCE.
+ 7 | LABEL='label' LABELSOURCE=VARLABEL.
+ | ^~~~~~~~~~~~~~~~~~~~"
])
AT_CLEANUP
])
AT_CHECK([pspp -o pspp.csv rename-variables.sps], [1], [dnl
-rename-variables.sps:2: error: RENAME VARIABLES: Differing number of variables in old name list (1) and in new name list (2).
+rename-variables.sps:2.19-2.41: error: RENAME VARIABLES: Differing number of variables in old name list (1) and in new name list (2).
+ 2 | RENAME VARIABLES (brakeFluid=applecarts y=bananamobiles).
+ | ^~~~~~~~~~~~~~~~~~~~~~~
])
AT_CLEANUP
SPLIT FILE BY V1 TO V9.
])
AT_CHECK([pspp split-file.sps], [1], [dnl
-split-file.sps:2: error: SPLIT FILE: At most 8 split variables may be
+split-file.sps:2.15-2.22: error: SPLIT FILE: At most 8 split variables may be
specified.
+ 2 | SPLIT FILE BY V1 TO V9.
+ | ^~~~~~~~
])
AT_CLEANUP
DISPLAY SCRATCH.
])
AT_CHECK([pspp -O format=csv sysfile-info.sps], [0], [dnl
-sysfile-info.sps:2: warning: DISPLAY: No variables to display.
+sysfile-info.sps:2: note: DISPLAY: No variables to display.
Table: Variables
Name
COMPUTE y='a'.
])
AT_CHECK([pspp parse.sps], [1], [dnl
-parse.sps:2: error: COMPUTE: This command tries to create a new variable y by
+parse.sps:2.9: error: COMPUTE: This command tries to create a new variable y by
assigning a string value to it, but this is not supported. Use the STRING
command to create the new variable with the correct width before assigning to
it, e.g. STRING y(A20).
+ 2 | COMPUTE y='a'.
+ | ^
])
AT_CLEANUP
5 | COMPUTE c = 2**3**4.
| ^~~~~~~
-parse.sps:10: error: INPUT PROGRAM: Input program must contain DATA LIST or END
-FILE.
+parse.sps:1.1-10.17: error: INPUT PROGRAM: Input program does not contain DATA
+LIST or END FILE.
+ 1 | INPUT PROGRAM.
+ 2 | * These should provoke warnings.
+ ... |
+ 10 | END INPUT PROGRAM.
])
AT_CLEANUP
,N,Percent,N,Percent,N,Percent
X1 × X2,0,.0%,1,100.0%,1,100.0%
-crosstabs.sps:8: warning: CROSSTABS: Crosstabulation X1 × X2 contained no non-missing cases.
+"crosstabs.sps:8.20-8.27: warning: CROSSTABS: Crosstabulation X1 × X2 contained no non-missing cases.
+ 8 | CROSSTABS /TABLES= X1 by X2.
+ | ^~~~~~~~"
])
AT_CLEANUP
LIST.
])
AT_CHECK([pspp -o pspp.csv -o pspp.txt descriptives.sps], [0], [dnl
-descriptives.sps:15: warning: DESCRIPTIVES: DESCRIPTIVES with Z scores ignores TEMPORARY. Temporary transformations will be made permanent.
+descriptives.sps:15.23-15.26: warning: DESCRIPTIVES: DESCRIPTIVES with Z scores ignores TEMPORARY. Temporary transformations will be made permanent.
+ 15 | DESCRIPTIVES /VAR=abc/SAVE.
+ | ^~~~
])
AT_CHECK([cat pspp.csv], [0], [dnl
-descriptives.sps:15: warning: DESCRIPTIVES: DESCRIPTIVES with Z scores ignores TEMPORARY. Temporary transformations will be made permanent.
+"descriptives.sps:15.23-15.26: warning: DESCRIPTIVES: DESCRIPTIVES with Z scores ignores TEMPORARY. Temporary transformations will be made permanent.
+ 15 | DESCRIPTIVES /VAR=abc/SAVE.
+ | ^~~~"
Table: Mapping of Variables to Z-scores
Source,Target