#include "language/lexer/variable-parser.h"
#include "libpspp/assertion.h"
#include "libpspp/i18n.h"
+#include "libpspp/intern.h"
#include "libpspp/message.h"
#include "libpspp/str.h"
int line_number = dfm_get_line_number (reader);
struct msg_location *location = xmalloc (sizeof *location);
+ int last_column = (first_column && token->length
+ ? first_column + token->length - 1
+ : 0);
*location = (struct msg_location) {
- .file_name = xstrdup (dfm_get_file_name (reader)),
- .first_line = line_number,
- .last_line = line_number + 1,
- .first_column = first_column,
- .last_column = first_column ? first_column + token->length : 0,
+ .file_name = intern_new (dfm_get_file_name (reader)),
+ .start = { .line = line_number, .column = first_column },
+ .end = { .line = line_number, .column = last_column },
};
struct msg *m = xmalloc (sizeof *m);
*m = (struct msg) {
size_t n_names = 0;
char **names = NULL;
+ int vars_start = lex_ofs (lexer);
if (!parse_DATA_LIST_vars (lexer, dict, &names, &n_names, PV_NO_DUPLICATE))
{
dict_unref (dict);
return NULL;
}
+ int vars_end = lex_ofs (lexer) - 1;
for (size_t i = 0; i < n_names; i++)
if (!strcasecmp (names[i], "ROWTYPE_"))
dict_create_var_assert (dict, "ROWTYPE_", 8);
else
- dict_create_var_assert (dict, names[i], 0);
+ {
+ struct variable *var = dict_create_var_assert (dict, names[i], 0);
+ var_set_measure (var, MEASURE_SCALE);
+ }
for (size_t i = 0; i < n_names; ++i)
free (names[i]);
if (dict_lookup_var (dict, "VARNAME_"))
{
- msg (SE, _("VARIABLES may not include VARNAME_."));
+ lex_ofs_error (lexer, vars_start, vars_end,
+ _("VARIABLES may not include VARNAME_."));
dict_unref (dict);
return NULL;
}
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);
bool *tv = &taken_vars[var_get_dict_index (v)];
if (*tv)
{
- msg (SE, _("%s may not appear on both SPLIT and FACTORS."),
- var_get_name (v));
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("%s may not appear on both SPLIT and FACTORS."),
+ var_get_name (v));
goto error;
}
*tv = true;
+ var_set_measure (v, MEASURE_NOMINAL);
var_set_both_formats (v, &(struct fmt_spec) { .type = FMT_F, .w = 4 });
}
return true;
int
cmd_matrix_data (struct lexer *lexer, struct dataset *ds)
{
+ int input_vars_start = lex_ofs (lexer);
struct dictionary *dict = parse_matrix_data_variables (lexer);
if (!dict)
return CMD_FAILURE;
+ int input_vars_end = lex_ofs (lexer) - 1;
- size_t n_input_vars = dict_get_var_cnt (dict);
+ size_t n_input_vars = dict_get_n_vars (dict);
struct variable **input_vars = xnmalloc (n_input_vars, sizeof *input_vars);
for (size_t i = 0; i < n_input_vars; i++)
input_vars[i] = dict_get_var (dict, i);
.cells = -1,
};
- bool *taken_vars = xzalloc (n_input_vars);
+ bool *taken_vars = XCALLOC (n_input_vars, bool);
if (input_rowtype)
taken_vars[var_get_dict_index (rowtype)] = true;
struct file_handle *fh = NULL;
+ int n_start = 0;
+ int n_end = 0;
while (lex_token (lexer) != T_ENDCMD)
{
if (!lex_force_match (lexer, T_SLASH))
if (lex_match_id (lexer, "N"))
{
+ n_start = lex_ofs (lexer) - 1;
lex_match (lexer, T_EQUALS);
if (!lex_force_int_range (lexer, "N", 0, INT_MAX))
goto error;
mf.n = lex_integer (lexer);
+ n_end = lex_ofs (lexer);
lex_get (lexer);
}
else if (lex_match_id (lexer, "FORMAT"))
{
+ int start_ofs = lex_ofs (lexer) - 1;
lex_match (lexer, T_EQUALS);
while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD)
goto error;
}
}
+ int end_ofs = lex_ofs (lexer) - 1;
+
+ if (mf.diagonal == NO_DIAGONAL && mf.triangle == FULL)
+ {
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("FORMAT=FULL and FORMAT=NODIAGONAL are "
+ "mutually exclusive."));
+ goto error;
+ }
}
else if (lex_match_id (lexer, "FILE"))
{
mf.svars = xmalloc (sizeof *mf.svars);
mf.svars[0] = dict_create_var_assert (dict, lex_tokcstr (lexer),
0);
+ var_set_measure (mf.svars[0], MEASURE_NOMINAL);
var_set_both_formats (
mf.svars[0], &(struct fmt_spec) { .type = FMT_F, .w = 4 });
mf.n_svars = 1;
else if (lex_match_id (lexer, "CELLS"))
{
if (mf.input_rowtype)
- msg (SW, _("CELLS is ignored when VARIABLES includes ROWTYPE_"));
+ lex_next_msg (lexer, SW,
+ -1, -1, _("CELLS is ignored when VARIABLES "
+ "includes ROWTYPE_"));
lex_match (lexer, T_EQUALS);
if (open || in_parens || (lex_token (lexer) != T_ENDCMD
&& lex_token (lexer) != T_SLASH))
{
- lex_error (lexer, _("Row type keyword expected."));
+ const char *rowtypes[] = {
+#define RT(NAME, DIMS) #NAME,
+ ROWTYPES
+#undef RT
+ "N_VECTOR", "SD",
+ };
+ lex_error_expecting_array (
+ lexer, rowtypes, sizeof rowtypes / sizeof *rowtypes);
goto error;
}
break;
goto error;
}
}
- if (mf.diagonal == NO_DIAGONAL && mf.triangle == FULL)
- {
- msg (SE, _("FORMAT=FULL and FORMAT=NODIAGONAL are mutually exclusive."));
- goto error;
- }
if (!mf.input_rowtype)
{
if (mf.cells < 0)
}
if (!mf.n_cvars)
{
- msg (SE, _("At least one continuous variable is required."));
+ lex_ofs_error (lexer, input_vars_start, input_vars_end,
+ _("At least one continuous variable is required."));
goto error;
}
if (mf.input_rowtype)
for (size_t i = 0; i < mf.n_cvars; i++)
if (mf.cvars[i] != input_vars[n_input_vars - mf.n_cvars + i])
{
- msg (SE, _("VARIABLES includes ROWTYPE_ but the continuous "
- "variables are not the last ones on VARIABLES."));
+ lex_ofs_error (lexer, input_vars_start, input_vars_end,
+ _("VARIABLES includes ROWTYPE_ but the continuous "
+ "variables are not the last ones on VARIABLES."));
goto error;
}
}
unsigned int rowtype_mask = mf.pooled_rowtype_mask | mf.factor_rowtype_mask;
if (rowtype_mask & (1u << C_N) && mf.n >= 0)
{
- msg (SE, _("Cannot specify N on CONTENTS along with the N subcommand."));
+ lex_ofs_error (lexer, n_start, n_end,
+ _("Cannot specify N on CONTENTS along with the "
+ "N subcommand."));
goto error;
}
- struct variable **order = xnmalloc (dict_get_var_cnt (dict), sizeof *order);
+ struct variable **order = xnmalloc (dict_get_n_vars (dict), sizeof *order);
size_t n_order = 0;
for (size_t i = 0; i < mf.n_svars; i++)
order[n_order++] = mf.svars[i];
order[n_order++] = mf.varname;
for (size_t i = 0; i < mf.n_cvars; i++)
order[n_order++] = mf.cvars[i];
- assert (n_order == dict_get_var_cnt (dict));
+ assert (n_order == dict_get_n_vars (dict));
dict_reorder_vars (dict, order, n_order);
free (order);
- dict_set_split_vars (dict, mf.svars, mf.n_svars);
+ dict_set_split_vars (dict, mf.svars, mf.n_svars, SPLIT_LAYERED);
schedule_matrices (&mf);