From da1bf03a84fa10f04e8c5438f22b523f0480dd7d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 5 Nov 2011 16:23:05 -0700 Subject: [PATCH] lexer: Use error helper functions in more situations. The error helpers print error messages that are just as helpful as handwritten error messages in most cases, especially now that the error messages include column numbers. They also have advantages for i18n. One important purpose of this commit is to remove several strings from q2c.c that require translation but currently are not translatable. --- src/language/data-io/inpt-pgm.c | 2 +- src/language/data-io/trim.c | 2 +- src/language/dictionary/formats.c | 4 +-- src/language/dictionary/modify-variables.c | 19 +++++------- src/language/dictionary/numeric.c | 2 +- src/language/dictionary/rename-variables.c | 21 ++++--------- src/language/expressions/parse.c | 2 +- src/language/lexer/q2c.c | 34 +++++----------------- src/language/stats/frequencies.q | 2 +- src/language/stats/npar.c | 4 +-- src/language/stats/sort-criteria.c | 9 ++---- src/language/stats/t-test-parser.c | 2 +- src/language/utilities/permissions.c | 3 +- tests/language/lexer/q2c.at | 4 +-- tests/language/stats/t-test.at | 4 +-- 15 files changed, 41 insertions(+), 73 deletions(-) diff --git a/src/language/data-io/inpt-pgm.c b/src/language/data-io/inpt-pgm.c index eac1f06f..6f2a99e0 100644 --- a/src/language/data-io/inpt-pgm.c +++ b/src/language/data-io/inpt-pgm.c @@ -277,7 +277,7 @@ cmd_reread (struct lexer *lexer, struct dataset *ds) if (e) { - msg (SE, _("%s subcommand may be given at most once."), "COLUMN"); + lex_sbc_only_once ("COLUMN"); expr_free (e); return CMD_CASCADING_FAILURE; } diff --git a/src/language/data-io/trim.c b/src/language/data-io/trim.c index 63041f25..947a7524 100644 --- a/src/language/data-io/trim.c +++ b/src/language/data-io/trim.c @@ -112,7 +112,7 @@ parse_dict_rename (struct lexer *lexer, struct dictionary *dict) goto done; if (!lex_match (lexer, T_EQUALS)) { - msg (SE, _("`=' expected after variable list.")); + lex_error_expecting (lexer, "`='", NULL_SENTINEL); goto done; } if (!parse_DATA_LIST_vars (lexer, dict, &new_names, &nn, diff --git a/src/language/dictionary/formats.c b/src/language/dictionary/formats.c index 2244ef77..4b5a2b20 100644 --- a/src/language/dictionary/formats.c +++ b/src/language/dictionary/formats.c @@ -84,7 +84,7 @@ internal_cmd_formats (struct lexer *lexer, struct dataset *ds, int which) if (!lex_match (lexer, T_LPAREN)) { - msg (SE, _("`(' expected after variable list.")); + lex_error_expecting (lexer, "`('", NULL_SENTINEL); goto fail; } if (!parse_format_specifier (lexer, &f) @@ -94,7 +94,7 @@ internal_cmd_formats (struct lexer *lexer, struct dataset *ds, int which) if (!lex_match (lexer, T_RPAREN)) { - msg (SE, _("`)' expected after output format.")); + lex_error_expecting (lexer, "`)'", NULL_SENTINEL); goto fail; } diff --git a/src/language/dictionary/modify-variables.c b/src/language/dictionary/modify-variables.c index b9a8a28e..d73b95e8 100644 --- a/src/language/dictionary/modify-variables.c +++ b/src/language/dictionary/modify-variables.c @@ -110,7 +110,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) if (already_encountered & 1) { - msg (SE, _("%s subcommand may be given at most once."), "REORDER"); + lex_sbc_only_once ("REORDER"); goto done; } already_encountered |= 1; @@ -143,7 +143,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) { if (!lex_match (lexer, T_LPAREN)) { - msg (SE, _("`(' expected on %s subcommand."), "REORDER"); + lex_error_expecting (lexer, "`('", NULL_SENTINEL); free (v); goto done; } @@ -155,8 +155,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) } if (!lex_match (lexer, T_RPAREN)) { - msg (SE, _("`)' expected following variable names on " - "REORDER subcommand.")); + lex_error_expecting (lexer, "`)'", NULL_SENTINEL); free (v); goto done; } @@ -174,7 +173,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) { if (already_encountered & 2) { - msg (SE, _("%s subcommand may be given at most once."), "RENAME"); + lex_sbc_only_once ("RENAME"); goto done; } already_encountered |= 2; @@ -187,7 +186,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) if (!lex_match (lexer, T_LPAREN)) { - msg (SE, _("`(' expected on %s subcommand."), "RENAME"); + lex_error_expecting (lexer, "`('", NULL_SENTINEL); goto done; } if (!parse_variables (lexer, dataset_dict (ds), @@ -196,8 +195,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) goto done; if (!lex_match (lexer, T_EQUALS)) { - msg (SE, _("`=' expected between lists of new and old variable " - "names on RENAME subcommand.")); + lex_error_expecting (lexer, "`='", NULL_SENTINEL); goto done; } if (!parse_DATA_LIST_vars (lexer, dataset_dict (ds), @@ -216,8 +214,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) } if (!lex_match (lexer, T_RPAREN)) { - msg (SE, _("`)' expected after variable lists on RENAME " - "subcommand.")); + lex_error_expecting (lexer, "`)'", NULL_SENTINEL); goto done; } } @@ -310,7 +307,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds) break; if (lex_token (lexer) != T_SLASH) { - msg (SE, _("`/' or `.' expected.")); + lex_error_expecting (lexer, "`/'", "`.'", NULL_SENTINEL); goto done; } lex_get (lexer); diff --git a/src/language/dictionary/numeric.c b/src/language/dictionary/numeric.c index 7b367f9d..1a81e0e4 100644 --- a/src/language/dictionary/numeric.c +++ b/src/language/dictionary/numeric.c @@ -72,7 +72,7 @@ cmd_numeric (struct lexer *lexer, struct dataset *ds) if (!lex_match (lexer, T_RPAREN)) { - msg (SE, _("`)' expected after output format.")); + lex_error_expecting (lexer, "`)'", NULL_SENTINEL); goto fail; } } diff --git a/src/language/dictionary/rename-variables.c b/src/language/dictionary/rename-variables.c index 82fc1d96..4fc5bada 100644 --- a/src/language/dictionary/rename-variables.c +++ b/src/language/dictionary/rename-variables.c @@ -53,19 +53,13 @@ cmd_rename_variables (struct lexer *lexer, struct dataset *ds) size_t prev_nv_1 = rename_cnt; size_t prev_nv_2 = rename_cnt; - if (!lex_match (lexer, T_LPAREN)) - { - msg (SE, _("`(' expected.")); - goto lossage; - } + if (!lex_force_match (lexer, T_LPAREN)) + goto lossage; if (!parse_variables (lexer, dataset_dict (ds), &rename_vars, &rename_cnt, PV_APPEND | PV_NO_DUPLICATE)) goto lossage; - if (!lex_match (lexer, T_EQUALS)) - { - msg (SE, _("`=' expected between lists of new and old variable names.")); - goto lossage; - } + if (!lex_force_match (lexer, T_EQUALS)) + goto lossage; if (!parse_DATA_LIST_vars (lexer, dataset_dict (ds), &rename_new_names, &prev_nv_1, PV_APPEND | PV_NO_DUPLICATE)) @@ -83,11 +77,8 @@ cmd_rename_variables (struct lexer *lexer, struct dataset *ds) rename_new_names = NULL; goto lossage; } - if (!lex_match (lexer, T_RPAREN)) - { - msg (SE, _("`)' expected after variable names.")); - goto lossage; - } + if (!lex_force_match (lexer, T_RPAREN)) + goto lossage; } while (lex_token (lexer) != T_ENDCMD); diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c index 32c2e615..1bdec188 100644 --- a/src/language/expressions/parse.c +++ b/src/language/expressions/parse.c @@ -1268,7 +1268,7 @@ parse_function (struct lexer *lexer, struct expression *e) break; else if (!lex_match (lexer, T_COMMA)) { - lex_error_expecting (lexer, ",", ")", NULL_SENTINEL); + lex_error_expecting (lexer, "`,'", "`)'", NULL_SENTINEL); goto fail; } } diff --git a/src/language/lexer/q2c.c b/src/language/lexer/q2c.c index f53ccfc3..48f7d33b 100644 --- a/src/language/lexer/q2c.c +++ b/src/language/lexer/q2c.c @@ -1500,10 +1500,9 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) { dump (1, "if (!lex_match (lexer, T_LPAREN))"); dump (1, "{"); - dump (0, "msg (SE, _(\"`(' expected after %s " - "specifier of %s subcommand.\"));", - s->specname, sbc->name); - dump (0, "goto lossage;"); + dump (0, "lex_error_expecting (lexer, \"`('\", " + "NULL_SENTINEL);"); + dump (0, "goto lossage;"); dump (-1, "}"); outdent (); } @@ -1511,25 +1510,15 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) if (s->value == VAL_INT) { - dump (1, "if (!lex_is_integer (lexer))"); - dump (1, "{"); - dump (0, "msg (SE, _(\"%s specifier of %s subcommand " - "requires an integer argument.\"));", - s->specname, sbc->name); + dump (1, "if (!lex_force_int (lexer))"); dump (0, "goto lossage;"); - dump (-1, "}"); dump (-1, "p->%s%s = lex_integer (lexer);", sbc->prefix, st_lower (s->valname)); } else if (s->value == VAL_DBL) { - dump (1, "if (!lex_is_number (lexer))"); - dump (1, "{"); - dump (0, "msg (SE, _(\"Number expected after %s " - "specifier of %s subcommand.\"));", - s->specname, sbc->name); + dump (1, "if (!lex_force_num (lexer))"); dump (0, "goto lossage;"); - dump (-1, "}"); dump (-1, "p->%s%s = lex_tokval (lexer);", sbc->prefix, st_lower (s->valname)); } @@ -1577,13 +1566,8 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) if (s->valtype == VT_PAREN) { - dump (1, "if (!lex_match (lexer, T_RPAREN))"); - dump (1, "{"); - dump (0, "msg (SE, _(\"`)' expected after argument for " - "%s specifier of %s.\"));", - s->specname, sbc->name); + dump (1, "if (!lex_force_match (lexer, T_RPAREN))"); dump (0, "goto lossage;"); - dump (-1, "}"); outdent (); if (s->optvalue) { @@ -1891,8 +1875,7 @@ dump_parser (int persistent) { dump (1, "if (p->sbc_%s > 1)", st_lower (sbc->name)); dump (1, "{"); - dump (0, "msg (SE, _(\"%s subcommand may be given only once.\"));", - sbc->name); + dump (0, "lex_sbc_only_once (\"%s\");", sbc->name); dump (0, "goto lossage;"); dump (-1, "}"); outdent (); @@ -1946,8 +1929,7 @@ dump_parser (int persistent) { dump (0, "if ( 0 == p->sbc_%s)", st_lower (sbc->name)); dump (1, "{"); - dump (0, "msg (SE, _(\"%s subcommand must be given.\"));", - sbc->name); + dump (0, "lex_sbc_missing (\"%s\");", sbc->name); dump (0, "goto lossage;"); dump (-1, "}"); dump_blank_line (0); diff --git a/src/language/stats/frequencies.q b/src/language/stats/frequencies.q index 01247f51..a2ffe91c 100644 --- a/src/language/stats/frequencies.q +++ b/src/language/stats/frequencies.q @@ -699,7 +699,7 @@ frq_custom_grouped (struct lexer *lexer, struct dataset *ds, struct cmd_frequenc if (!lex_match (lexer, T_RPAREN)) { free (v); - msg (SE, _("`)' expected after GROUPED interval list.")); + lex_error_expecting (lexer, "`)'", NULL_SENTINEL); return 0; } } diff --git a/src/language/stats/npar.c b/src/language/stats/npar.c index e0d50d4a..3260117d 100644 --- a/src/language/stats/npar.c +++ b/src/language/stats/npar.c @@ -398,7 +398,7 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests npt->missing++; if (npt->missing > 1) { - msg (SE, _("The %s subcommand may be given only once."), "MISSING"); + lex_sbc_only_once ("MISSING"); goto lossage; } while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD) @@ -425,7 +425,7 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests npt->method++; if (npt->method > 1) { - msg (SE, _("The %s subcommand may be given only once."), "METHOD"); + lex_sbc_only_once ("METHOD"); goto lossage; } switch (npar_method (lexer, nps)) diff --git a/src/language/stats/sort-criteria.c b/src/language/stats/sort-criteria.c index b8bdbd06..a8c1ff13 100644 --- a/src/language/stats/sort-criteria.c +++ b/src/language/stats/sort-criteria.c @@ -71,14 +71,11 @@ parse_sort_criteria (struct lexer *lexer, const struct dictionary *dict, direction = SC_ASCEND; else { - msg (SE, _("`A' or `D' expected inside parentheses.")); - goto error; - } - if (!lex_match (lexer, T_RPAREN)) - { - msg (SE, _("`)' expected.")); + lex_error_expecting (lexer, "A", "D", NULL_SENTINEL); goto error; } + if (!lex_force_match (lexer, T_RPAREN)) + goto error; if (saw_direction != NULL) *saw_direction = true; } diff --git a/src/language/stats/t-test-parser.c b/src/language/stats/t-test-parser.c index 089d0dd8..3ce1d028 100644 --- a/src/language/stats/t-test-parser.c +++ b/src/language/stats/t-test-parser.c @@ -297,7 +297,7 @@ cmd_t_test (struct lexer *lexer, struct dataset *ds) if (tt.n_vars == 0 && tt.mode != MODE_PAIRED) { - msg (SE, _("One or more VARIABLES must be specified.")); + lex_sbc_missing ("VARIABLES"); goto parse_failed; } diff --git a/src/language/utilities/permissions.c b/src/language/utilities/permissions.c index 8b0e3f0c..2ea91de1 100644 --- a/src/language/utilities/permissions.c +++ b/src/language/utilities/permissions.c @@ -25,6 +25,7 @@ #include "data/settings.h" #include "language/command.h" #include "language/lexer/lexer.h" +#include "libpspp/cast.h" #include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/misc.h" @@ -75,7 +76,7 @@ cmd_permissions (struct lexer *lexer, struct dataset *ds UNUSED) } else { - msg (SE, _("Expecting %s or %s."), "WRITEABLE", "READONLY"); + lex_error_expecting (lexer, "WRITEABLE", "READONLY", NULL_SENTINEL); goto error; } diff --git a/tests/language/lexer/q2c.at b/tests/language/lexer/q2c.at index 6ba3f7ab..e8338ace 100644 --- a/tests/language/lexer/q2c.at +++ b/tests/language/lexer/q2c.at @@ -14,10 +14,10 @@ ONEWAY. CROSSTABS. ]) AT_CHECK([pspp -O format=csv q2c.sps], [1], [dnl -q2c.sps:8: error: EXAMINE: VARIABLES subcommand must be given. +q2c.sps:8: error: EXAMINE: Required subcommand VARIABLES was not specified. q2c.sps:9.7: error: ONEWAY: Syntax error at end of command: expecting variable name. -q2c.sps:10: error: CROSSTABS: TABLES subcommand must be given. +q2c.sps:10: error: CROSSTABS: Required subcommand TABLES was not specified. ]) AT_CLEANUP diff --git a/tests/language/stats/t-test.at b/tests/language/stats/t-test.at index ceda4c28..d5b7aad3 100644 --- a/tests/language/stats/t-test.at +++ b/tests/language/stats/t-test.at @@ -626,9 +626,9 @@ T-TEST /testval=2.0 . T-TEST /groups=id(3) . ]) AT_CHECK([pspp -O format=csv t-test.sps], [1], [dnl -t-test.sps:11: error: T-TEST: One or more VARIABLES must be specified. +t-test.sps:11: error: T-TEST: Required subcommand VARIABLES was not specified. -t-test.sps:12: error: T-TEST: One or more VARIABLES must be specified. +t-test.sps:12: error: T-TEST: Required subcommand VARIABLES was not specified. ]) AT_CLEANUP -- 2.30.2