This centralizes some fairly common strings into lexer.c.
#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"
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)
}
else
{
- lex_error (lexer, _("expecting %s or %s"), "LINE", "VARIABLES");
+ lex_error_expecting (lexer, "LINE", "VARIABLES", NULL_SENTINEL);
goto error;
}
}
break;
else
{
- lex_error (lexer, _("expecting %s"), "VARIABLES");
+ lex_error_expecting (lexer, "VARIABLES", NULL_SENTINEL);
goto error;
}
}
type = PFM_TAPE;
else
{
- lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+ lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
goto error;
}
}
/* 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
type = TAB_FILE;
else
{
- lex_error (lexer, _("expecting %s or %s"), "CSV", "TAB");
+ lex_error_expecting (lexer, "CSV", "TAB", NULL_SENTINEL);
goto error;
}
}
recode_user_missing = true;
else
{
- lex_error (lexer, _("expecting %s or %s"), "IGNORE", "RECODE");
+ lex_error_expecting (lexer, "IGNORE", "RECODE", NULL_SENTINEL);
goto error;
}
}
use_value_labels = true;
else
{
- lex_error (lexer, _("expecting %s or %s"), "VALUES", "LABELS");
+ lex_error_expecting (lexer, "VALUES", "LABELS", NULL_SENTINEL);
goto error;
}
}
decimal = ',';
else
{
- lex_error (lexer, _("expecting %s or %s"),
- "DOT", "COMMA");
+ lex_error_expecting (lexer, "DOT", "COMMA",
+ NULL_SENTINEL);
goto error;
}
}
use_print_formats = true;
else
{
- lex_error (lexer, _("expecting %s or %s"),
- "PLAIN", "VARIABLE");
+ lex_error_expecting (lexer, "PLAIN", "VARIABLE",
+ NULL_SENTINEL);
goto error;
}
}
retain_unselected = false;
else
{
- lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+ lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
goto error;
}
}
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;
*retain_unselected = false;
else
{
- lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+ lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL);
goto error;
}
}
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;
}
}
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;
}
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;
}
}
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
return true;
else
{
- lex_error (lexer, _("expecting `%s'"), identifier);
+ lex_error_expecting (lexer, identifier, NULL_SENTINEL);
return false;
}
}
}
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;
}
}
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 *);
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;
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;
}
}
}
else
{
- lex_error (lexer, _("expecting %s or %s after %s"),
- "YES", "NO", "CD");
+ lex_error_expecting (lexer, "YES", "NO", NULL_SENTINEL);
goto exit;
}
}
}
else
{
- lex_error (lexer, _("expecting %s or %s after %s"),
- "CONTINUE", "STOP", "ERROR");
+ lex_error_expecting (lexer, "CONTINUE", "STOP", NULL_SENTINEL);
goto exit;
}
}
}
else
{
- lex_error (lexer, _("expecting VALUES, LABELS or BOTH"));
+ lex_error_expecting (lexer, "VALUES", "LABELS", "BOTH", NULL_SENTINEL);
return 0;
}
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
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