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);
}