X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fmatrix-data.c;h=83490d4db824fe67756d7c1fc824971bcb815003;hb=8011f9998ed6cc3cd8948d080a1b7e36d932e5c5;hp=31d6b710b0ba68a54402d33e50e559b9f581bf2e;hpb=0fde6afee3c995bf264c24c438f43eeb58b859b5;p=pspp diff --git a/src/language/data-io/matrix-data.c b/src/language/data-io/matrix-data.c index 31d6b710b0..83490d4db8 100644 --- a/src/language/data-io/matrix-data.c +++ b/src/language/data-io/matrix-data.c @@ -253,12 +253,13 @@ parse_msg (struct dfm_reader *reader, const struct substring *token, 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 = intern_new (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, + .start = { .line = line_number, .column = first_column }, + .end = { .line = line_number, .column = last_column }, }; struct msg *m = xmalloc (sizeof *m); *m = (struct msg) { @@ -836,17 +837,22 @@ parse_matrix_data_variables (struct lexer *lexer) 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]); @@ -854,7 +860,8 @@ parse_matrix_data_variables (struct lexer *lexer) 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; } @@ -867,8 +874,10 @@ parse_matrix_data_subvars (struct lexer *lexer, struct dictionary *dict, 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++) @@ -876,7 +885,8 @@ parse_matrix_data_subvars (struct lexer *lexer, struct dictionary *dict, 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); @@ -884,12 +894,14 @@ parse_matrix_data_subvars (struct lexer *lexer, struct dictionary *dict, 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; @@ -906,11 +918,13 @@ error: 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); @@ -946,6 +960,8 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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)) @@ -953,16 +969,19 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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) @@ -987,6 +1006,15 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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")) { @@ -1006,6 +1034,7 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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; @@ -1027,7 +1056,9 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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); @@ -1052,7 +1083,14 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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; @@ -1084,11 +1122,6 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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) @@ -1123,7 +1156,8 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) } 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) @@ -1131,19 +1165,22 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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]; @@ -1153,11 +1190,11 @@ cmd_matrix_data (struct lexer *lexer, struct dataset *ds) 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);