[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[q2c 05/12] lexer: New function lex_error_expecting().
From: |
Ben Pfaff |
Subject: |
[q2c 05/12] lexer: New function lex_error_expecting(). |
Date: |
Sat, 5 Nov 2011 20:11:27 -0700 |
This centralizes some fairly common strings into lexer.c.
---
src/language/data-io/get-data.c | 7 ++-
src/language/data-io/get.c | 2 +-
src/language/data-io/save-translate.c | 18 ++++----
src/language/data-io/save.c | 8 ++--
src/language/dictionary/attributes.c | 2 +-
src/language/expressions/parse.c | 3 +-
src/language/lexer/lexer.c | 75 ++++++++++++++++++++++++++++++++-
src/language/lexer/lexer.h | 2 +
src/language/stats/aggregate.c | 2 +-
src/language/utilities/include.c | 10 ++---
src/language/utilities/set.q | 2 +-
tests/language/control/do-repeat.at | 2 +-
tests/language/data-io/inpt-pgm.at | 2 +-
13 files changed, 103 insertions(+), 32 deletions(-)
diff --git a/src/language/data-io/get-data.c b/src/language/data-io/get-data.c
index 9b878c5..4274f95 100644
--- a/src/language/data-io/get-data.c
+++ b/src/language/data-io/get-data.c
@@ -35,6 +35,7 @@
#include "language/data-io/placement-parser.h"
#include "language/lexer/format-parser.h"
#include "language/lexer/lexer.h"
+#include "libpspp/cast.h"
#include "libpspp/i18n.h"
#include "libpspp/message.h"
@@ -345,7 +346,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
DP_DELIMITED, &has_type);
else
{
- lex_error (lexer, _("expecting %s or %s"), "FIXED", "DELIMITED");
+ lex_error_expecting (lexer, "FIXED", "DELIMITED", NULL_SENTINEL);
goto error;
}
if (!ok)
@@ -383,7 +384,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
}
else
{
- lex_error (lexer, _("expecting %s or %s"), "LINE", "VARIABLES");
+ lex_error_expecting (lexer, "LINE", "VARIABLES", NULL_SENTINEL);
goto error;
}
}
@@ -494,7 +495,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
break;
else
{
- lex_error (lexer, _("expecting %s"), "VARIABLES");
+ lex_error_expecting (lexer, "VARIABLES", NULL_SENTINEL);
goto error;
}
}
diff --git a/src/language/data-io/get.c b/src/language/data-io/get.c
index 0e542ef..ea65b5c 100644
--- a/src/language/data-io/get.c
+++ b/src/language/data-io/get.c
@@ -96,7 +96,7 @@ parse_read_command (struct lexer *lexer, struct dataset *ds,
enum reader_command
type = PFM_TAPE;
else
{
- lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+ lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
goto error;
}
}
diff --git a/src/language/data-io/save-translate.c
b/src/language/data-io/save-translate.c
index f6487c5..cbed4b1 100644
--- a/src/language/data-io/save-translate.c
+++ b/src/language/data-io/save-translate.c
@@ -1,5 +1,5 @@
/* PSPP - a program for statistical analysis.
- Copyright (C) 2010 Free Software Foundation, Inc.
+ Copyright (C) 2010, 2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -115,7 +115,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
type = TAB_FILE;
else
{
- lex_error (lexer, _("expecting %s or %s"), "CSV", "TAB");
+ lex_error_expecting (lexer, "CSV", "TAB", NULL_SENTINEL);
goto error;
}
}
@@ -132,7 +132,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
recode_user_missing = true;
else
{
- lex_error (lexer, _("expecting %s or %s"), "IGNORE", "RECODE");
+ lex_error_expecting (lexer, "IGNORE", "RECODE", NULL_SENTINEL);
goto error;
}
}
@@ -145,7 +145,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
use_value_labels = true;
else
{
- lex_error (lexer, _("expecting %s or %s"), "VALUES", "LABELS");
+ lex_error_expecting (lexer, "VALUES", "LABELS", NULL_SENTINEL);
goto error;
}
}
@@ -193,8 +193,8 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
decimal = ',';
else
{
- lex_error (lexer, _("expecting %s or %s"),
- "DOT", "COMMA");
+ lex_error_expecting (lexer, "DOT", "COMMA",
+ NULL_SENTINEL);
goto error;
}
}
@@ -207,8 +207,8 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
use_print_formats = true;
else
{
- lex_error (lexer, _("expecting %s or %s"),
- "PLAIN", "VARIABLE");
+ lex_error_expecting (lexer, "PLAIN", "VARIABLE",
+ NULL_SENTINEL);
goto error;
}
}
@@ -225,7 +225,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
retain_unselected = false;
else
{
- lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+ lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
goto error;
}
}
diff --git a/src/language/data-io/save.c b/src/language/data-io/save.c
index cf84736..66cdd45 100644
--- a/src/language/data-io/save.c
+++ b/src/language/data-io/save.c
@@ -213,8 +213,8 @@ parse_write_command (struct lexer *lexer, struct dataset
*ds,
cw = true;
else
{
- lex_error (lexer, _("expecting %s or %s"),
- "READONLY", "WRITEABLE");
+ lex_error_expecting (lexer, "READONLY", "WRITEABLE",
+ NULL_SENTINEL);
goto error;
}
sysfile_opts.create_writeable = porfile_opts.create_writeable = cw;
@@ -228,7 +228,7 @@ parse_write_command (struct lexer *lexer, struct dataset
*ds,
*retain_unselected = false;
else
{
- lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+ lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
goto error;
}
}
@@ -256,7 +256,7 @@ parse_write_command (struct lexer *lexer, struct dataset
*ds,
porfile_opts.type = PFM_TAPE;
else
{
- lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+ lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
goto error;
}
}
diff --git a/src/language/dictionary/attributes.c
b/src/language/dictionary/attributes.c
index c7598d1..fc9cc9a 100644
--- a/src/language/dictionary/attributes.c
+++ b/src/language/dictionary/attributes.c
@@ -197,7 +197,7 @@ parse_attributes (struct lexer *lexer, const char
*dict_encoding,
command = DELETE;
else if (command == UNKNOWN)
{
- lex_error (lexer, _("expecting %s or %s"), "ATTRIBUTE=", "DELETE=");
+ lex_error_expecting (lexer, "ATTRIBUTE=", "DELETE=", NULL_SENTINEL);
return CMD_FAILURE;
}
diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c
index ed5a070..32c2e61 100644
--- a/src/language/expressions/parse.c
+++ b/src/language/expressions/parse.c
@@ -1268,8 +1268,7 @@ parse_function (struct lexer *lexer, struct expression *e)
break;
else if (!lex_match (lexer, T_COMMA))
{
- lex_error (lexer, _("expecting `,' or `)' invoking %s function"),
- first->name);
+ lex_error_expecting (lexer, ",", ")", NULL_SENTINEL);
goto fail;
}
}
diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c
index 5f1cc4b..a356b38 100644
--- a/src/language/lexer/lexer.c
+++ b/src/language/lexer/lexer.c
@@ -268,6 +268,75 @@ lex_next_error (struct lexer *lexer, int n0, int n1, const
char *format, ...)
va_end (args);
}
+/* Prints a syntax error message saying that OPTION0 or one of the other
+ strings following it, up to the first NULL, is expected. */
+void
+lex_error_expecting (struct lexer *lexer, const char *option0, ...)
+{
+ enum { MAX_OPTIONS = 8 };
+ const char *options[MAX_OPTIONS + 1];
+ va_list args;
+ int n;
+
+ va_start (args, option0);
+ options[0] = option0;
+ n = 0;
+ while (n + 1 < MAX_OPTIONS && options[n] != NULL)
+ options[++n] = va_arg (args, const char *);
+ va_end (args);
+
+ switch (n)
+ {
+ case 0:
+ lex_error (lexer, NULL);
+ break;
+
+ case 1:
+ lex_error (lexer, _("expecting %s"), options[0]);
+ break;
+
+ case 2:
+ lex_error (lexer, _("expecting %s or %s"), options[0], options[1]);
+ break;
+
+ case 3:
+ lex_error (lexer, _("expecting %s, %s, or %s"), options[0], options[1],
+ options[2]);
+ break;
+
+ case 4:
+ lex_error (lexer, _("expecting %s, %s, %s, or %s"),
+ options[0], options[1], options[2], options[3]);
+ break;
+
+ case 5:
+ lex_error (lexer, _("expecting %s, %s, %s, %s, or %s"),
+ options[0], options[1], options[2], options[3], options[4]);
+ break;
+
+ case 6:
+ lex_error (lexer, _("expecting %s, %s, %s, %s, %s, or %s"),
+ options[0], options[1], options[2], options[3], options[4],
+ options[5]);
+ break;
+
+ case 7:
+ lex_error (lexer, _("expecting %s, %s, %s, %s, %s, %s, or %s"),
+ options[0], options[1], options[2], options[3], options[4],
+ options[5], options[6]);
+ break;
+
+ case 8:
+ lex_error (lexer, _("expecting %s, %s, %s, %s, %s, %s, %s, or %s"),
+ options[0], options[1], options[2], options[3], options[4],
+ options[5], options[6], options[7]);
+ break;
+
+ default:
+ NOT_REACHED ();
+ }
+}
+
/* Reports an error to the effect that subcommand SBC may only be
specified once. */
void
@@ -491,7 +560,7 @@ lex_force_match_id (struct lexer *lexer, const char
*identifier)
return true;
else
{
- lex_error (lexer, _("expecting `%s'"), identifier);
+ lex_error_expecting (lexer, identifier, NULL_SENTINEL);
return false;
}
}
@@ -508,7 +577,9 @@ lex_force_match (struct lexer *lexer, enum token_type type)
}
else
{
- lex_error (lexer, _("expecting `%s'"), token_type_to_string (type));
+ char *s = xasprintf ("`%s'", token_type_to_string (type));
+ lex_error_expecting (lexer, s, NULL_SENTINEL);
+ free (s);
return false;
}
}
diff --git a/src/language/lexer/lexer.h b/src/language/lexer/lexer.h
index 0a3e6c3..b0787e8 100644
--- a/src/language/lexer/lexer.h
+++ b/src/language/lexer/lexer.h
@@ -155,6 +155,8 @@ void lex_next_error (struct lexer *, int n0, int n1, const
char *, ...)
PRINTF_FORMAT (4, 5);
int lex_end_of_command (struct lexer *);
+void lex_error_expecting (struct lexer *, const char *, ...) SENTINEL(0);
+
void lex_sbc_only_once (const char *);
void lex_sbc_missing (struct lexer *, const char *);
diff --git a/src/language/stats/aggregate.c b/src/language/stats/aggregate.c
index fed7656..f4cbaac 100644
--- a/src/language/stats/aggregate.c
+++ b/src/language/stats/aggregate.c
@@ -223,7 +223,7 @@ cmd_aggregate (struct lexer *lexer, struct dataset *ds)
lex_match (lexer, T_EQUALS);
if (!lex_match_id (lexer, "COLUMNWISE"))
{
- lex_error (lexer, _("expecting %s"), "COLUMNWISE");
+ lex_error_expecting (lexer, "COLUMNWISE", NULL);
goto error;
}
agr.missing = COLUMNWISE;
diff --git a/src/language/utilities/include.c b/src/language/utilities/include.c
index bcee162..89da3b9 100644
--- a/src/language/utilities/include.c
+++ b/src/language/utilities/include.c
@@ -106,8 +106,8 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum
variant variant)
syntax_mode = LEX_SYNTAX_AUTO;
else
{
- lex_error (lexer, _("expecting %s, %s, or %s after %s"),
- "BATCH", "INTERACTIVE", "AUTO", "SYNTAX");
+ lex_error_expecting (lexer, "BATCH", "INTERACTIVE", "AUTO",
+ NULL_SENTINEL);
goto exit;
}
}
@@ -124,8 +124,7 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum
variant variant)
}
else
{
- lex_error (lexer, _("expecting %s or %s after %s"),
- "YES", "NO", "CD");
+ lex_error_expecting (lexer, "YES", "NO", NULL_SENTINEL);
goto exit;
}
}
@@ -142,8 +141,7 @@ do_insert (struct lexer *lexer, struct dataset *ds, enum
variant variant)
}
else
{
- lex_error (lexer, _("expecting %s or %s after %s"),
- "CONTINUE", "STOP", "ERROR");
+ lex_error_expecting (lexer, "CONTINUE", "STOP", NULL_SENTINEL);
goto exit;
}
}
diff --git a/src/language/utilities/set.q b/src/language/utilities/set.q
index c538c8c..8b892c7 100644
--- a/src/language/utilities/set.q
+++ b/src/language/utilities/set.q
@@ -331,7 +331,7 @@ stc_custom_tnumbers (struct lexer *lexer,
}
else
{
- lex_error (lexer, _("expecting VALUES, LABELS or BOTH"));
+ lex_error_expecting (lexer, "VALUES", "LABELS", "BOTH", NULL_SENTINEL);
return 0;
}
diff --git a/tests/language/control/do-repeat.at
b/tests/language/control/do-repeat.at
index 4421ba6..75c0e77 100644
--- a/tests/language/control/do-repeat.at
+++ b/tests/language/control/do-repeat.at
@@ -145,6 +145,6 @@ DATA LIST NOTABLE /x 1.
DO REPEAT y = 1 TO 10.
])
AT_CHECK([pspp -O format=csv do-repeat.sps], [1], [dnl
-error: DO REPEAT: Syntax error at end of input: expecting `END'.
+error: DO REPEAT: Syntax error at end of input: expecting END.
])
AT_CLEANUP
diff --git a/tests/language/data-io/inpt-pgm.at
b/tests/language/data-io/inpt-pgm.at
index f048d37..03f9a2a 100644
--- a/tests/language/data-io/inpt-pgm.at
+++ b/tests/language/data-io/inpt-pgm.at
@@ -28,6 +28,6 @@ END INPUT PROGRAM.
DESCRIPTIVES x.
])
AT_CHECK([pspp -O format=csv input-program.sps], [1], [dnl
-error: DESCRIPTIVES: Syntax error at end of input: expecting `BEGIN'.
+error: DESCRIPTIVES: Syntax error at end of input: expecting BEGIN.
])
AT_CLEANUP
--
1.7.2.5
- [q2c 04/12] LOOP: Correctly implement MXLOOPS and add a test., (continued)
- [q2c 04/12] LOOP: Correctly implement MXLOOPS and add a test., Ben Pfaff, 2011/11/05
- [q2c 03/12] settings: Implement MXLOOPS subcommand., Ben Pfaff, 2011/11/05
- [q2c 09/12] lexer: New function lex_force_string_or_id()., Ben Pfaff, 2011/11/05
- [q2c 08/12] lexer: New functions lex_spec_missing(), lex_spec_only_once()., Ben Pfaff, 2011/11/05
- [q2c 07/12] lexer: Use error helper functions in more situations., Ben Pfaff, 2011/11/06
- [q2c 12/12] q2c: Remove gettext.h #include from generated code., Ben Pfaff, 2011/11/06
- [q2c 02/12] settings: Update default MXLOOPS and document., Ben Pfaff, 2011/11/06
- [q2c 06/12] lexer: Drop lexer parameter from lex_sbc_missing()., Ben Pfaff, 2011/11/06
- [q2c 11/12] q2c: Remove final untranslated strings from q2c.c., Ben Pfaff, 2011/11/06
- [q2c 10/12] q2c: Use new subc_list_error() to report too many subcommands., Ben Pfaff, 2011/11/06
- [q2c 05/12] lexer: New function lex_error_expecting().,
Ben Pfaff <=
- Re: [q2c 00/12] Fix i18n problems in q2c-generated strings, John Darrington, 2011/11/06