warnings: factoring: complaints

* src/complain.c (error_message): Accept warning categories (an integer) as
argument.
Location is a 'const location *' instead of 'location *'.
(ERROR_MESSAGE): Delete it.
* src/complain.c, src/complain.h (complains): New function.
(complain, complain_at, complain_at_indent): Generic functions for
complaints. Call 'complains'.
(warn_at, warn_at_indent, warn, yacc_at, midrule_value_at)
(fatal_at, fatal): Delete them. Adjust dependencies.
* src/complain.h (enum warnings): New fields 'complaint' and 'fatal'.
* bootstrap.conf (XGETTEXT_OPTIONS): Adjust.
This commit is contained in:
Victor Santet
2012-06-28 16:44:21 +02:00
committed by Akim Demaille
parent d0f11c1b62
commit 6fb8b25619
17 changed files with 310 additions and 364 deletions

View File

@@ -45,9 +45,9 @@ gnulib_modules='
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--from-code=UTF-8\\\ --from-code=UTF-8\\\
--flag=asprintf:2:c-format\\\ --flag=asprintf:2:c-format\\\
--flag=complain:1:c-format --flag=complain_at:2:c-format\\\ --flag=complain:2:c-format\\\
--flag=fatal:1:c-format --flag=fatal_at:2:c-format\\\ --flag=complain_at:3:c-format\\\
--flag=warn:1:c-format --flag=warn_at:2:c-format\\\ --flag=complain_at_indent:4:c-format\\\
--flag=unexpected_end:2:c-format\\\ --flag=unexpected_end:2:c-format\\\
' '
XGETTEXT_OPTIONS_RUNTIME=$XGETTEXT_OPTIONS'\\\ XGETTEXT_OPTIONS_RUNTIME=$XGETTEXT_OPTIONS'\\\

View File

@@ -29,7 +29,7 @@
#include "files.h" #include "files.h"
#include "getargs.h" #include "getargs.h"
int warnings_flag = Wconflicts_sr | Wconflicts_rr | Wother; warnings warnings_flag = Wconflicts_sr | Wconflicts_rr | Wother;
bool complaint_issued; bool complaint_issued;
static unsigned *indent_ptr = 0; static unsigned *indent_ptr = 0;
@@ -40,6 +40,7 @@ static unsigned *indent_ptr = 0;
* *
* \param loc the location, defaulting to the current file, * \param loc the location, defaulting to the current file,
* or the program name. * or the program name.
* \param flags the category for this message.
* \param prefix put before the message (e.g., "warning"). * \param prefix put before the message (e.g., "warning").
* \param message the error message, a printf format string. Iff it * \param message the error message, a printf format string. Iff it
* ends with ": ", then no trailing newline is printed, * ends with ": ", then no trailing newline is printed,
@@ -49,10 +50,10 @@ static unsigned *indent_ptr = 0;
*/ */
static static
void void
error_message (location *loc, error_message (const location *loc, warnings flags, const char *prefix,
const char *prefix,
const char *message, va_list args) const char *message, va_list args)
{ {
(void) flags;
unsigned pos = 0; unsigned pos = 0;
if (loc) if (loc)
@@ -84,15 +85,73 @@ error_message (location *loc,
} }
} }
/** Wrap error_message() with varargs handling. */ /** Raise a complaint. That can be a fatal error, a complaint or just a
#define ERROR_MESSAGE(Loc, Prefix, Message) \ warning. */
{ \
va_list args; \ static inline void
va_start (args, Message); \ complains (const location *loc, warnings flags, const char *message,
error_message (Loc, Prefix, Message, args); \ va_list args)
va_end (args); \ {
if (flags & complaint)
{
error_message (loc, complaint, NULL, message, args);
complaint_issued = true;
}
else if (flags & fatal)
{
error_message (loc, fatal, _("fatal error"), message, args);
exit (EXIT_FAILURE);
}
else if (flags & Wyacc)
{
if (yacc_flag)
{
error_message (loc, flags, NULL, message, args);
complaint_issued = true;
}
else if (warnings_flag & Wyacc)
{
set_warning_issued ();
error_message (loc, flags, _("warning"), message, args);
}
}
else
{
if (! (warnings_flag & flags))
return;
set_warning_issued ();
error_message (loc, flags, _("warning"), message, args);
}
} }
void
complain (warnings flags, const char *message, ...)
{
va_list args;
va_start (args, message);
complains (NULL, flags, message, args);
va_end (args);
}
void
complain_at (location loc, warnings flags, const char *message, ...)
{
va_list args;
va_start (args, message);
complains (&loc, flags, message, args);
va_end (args);
}
void complain_at_indent (location loc, warnings flags, unsigned *indent,
const char *message, ...)
{
indent_ptr = indent;
va_list args;
va_start (args, message);
complains (&loc, flags, message, args);
va_end (args);
}
/*--------------------------------. /*--------------------------------.
| Report a warning, and proceed. | | Report a warning, and proceed. |
@@ -109,108 +168,3 @@ set_warning_issued (void)
} }
warning_issued = true; warning_issued = true;
} }
void
warn_at (location loc, const char *message, ...)
{
if (!(warnings_flag & Wother))
return;
set_warning_issued ();
ERROR_MESSAGE (&loc, _("warning"), message);
}
void
warn_at_indent (location loc, unsigned *indent,
const char *message, ...)
{
if (!(warnings_flag & Wother))
return;
set_warning_issued ();
indent_ptr = indent;
ERROR_MESSAGE (&loc, _("warning"), message);
}
void
warn (const char *message, ...)
{
if (!(warnings_flag & Wother))
return;
set_warning_issued ();
ERROR_MESSAGE (NULL, _("warning"), message);
}
/*-----------------------------------------------------------.
| An error has occurred, but we can proceed, and die later. |
`-----------------------------------------------------------*/
void
complain_at (location loc, const char *message, ...)
{
ERROR_MESSAGE (&loc, NULL, message);
complaint_issued = true;
}
void
complain_at_indent (location loc, unsigned *indent,
const char *message, ...)
{
indent_ptr = indent;
ERROR_MESSAGE (&loc, NULL, message);
complaint_issued = true;
}
void
complain (const char *message, ...)
{
ERROR_MESSAGE (NULL, NULL, message);
complaint_issued = true;
}
/*--------------------------------------------------------------.
| An incompatibility with POSIX Yacc: mapped either to warn* or |
| complain* depending on yacc_flag. |
`--------------------------------------------------------------*/
void
yacc_at (location loc, const char *message, ...)
{
if (yacc_flag)
{
ERROR_MESSAGE (&loc, NULL, message);
complaint_issued = true;
}
else if (warnings_flag & Wyacc)
{
set_warning_issued ();
ERROR_MESSAGE (&loc, _("warning"), message);
}
}
void
midrule_value_at (location loc, const char *message, ...)
{
if (!(warnings_flag & Wmidrule_values))
return;
set_warning_issued ();
ERROR_MESSAGE (&loc, _("warning"), message);
}
/*-------------------------------------------------.
| A severe error has occurred, we cannot proceed. |
`-------------------------------------------------*/
void
fatal_at (location loc, const char *message, ...)
{
ERROR_MESSAGE (&loc, _("fatal error"), message);
exit (EXIT_FAILURE);
}
void
fatal (const char *message, ...)
{
ERROR_MESSAGE (NULL, _("fatal error"), message);
exit (EXIT_FAILURE);
}

View File

@@ -29,7 +29,7 @@ extern "C" {
| --warnings. | | --warnings. |
`-------------*/ `-------------*/
enum warnings typedef enum
{ {
Wnone = 0, /**< Issue no warnings. */ Wnone = 0, /**< Issue no warnings. */
Werror = 1 << 0, /**< Warnings are treated as errors. */ Werror = 1 << 0, /**< Warnings are treated as errors. */
@@ -38,11 +38,13 @@ enum warnings
Wconflicts_sr = 1 << 3, /**< S/R conflicts. */ Wconflicts_sr = 1 << 3, /**< S/R conflicts. */
Wconflicts_rr = 1 << 4, /**< R/R conflicts. */ Wconflicts_rr = 1 << 4, /**< R/R conflicts. */
Wother = 1 << 5, /**< All other warnings. */ Wother = 1 << 5, /**< All other warnings. */
complaint = 1 << 6, /**< All complaints. */
fatal = 1 << 7, /**< All fatal errors. */
Wall = ~Werror /**< All above warnings. */ Wall = ~Werror /**< All above warnings. */
}; } warnings;
/** What warnings are issued. */ /** What warnings are issued. */
extern int warnings_flag; extern warnings warnings_flag;
/** Record that a warning is about to be issued, and treat it as an /** Record that a warning is about to be issued, and treat it as an
error if <tt>warnings_flag & Werror</tt>. This is exported error if <tt>warnings_flag & Werror</tt>. This is exported
@@ -51,56 +53,18 @@ extern int warnings_flag;
the normal warning format. */ the normal warning format. */
void set_warning_issued (void); void set_warning_issued (void);
/** Informative messages, but we proceed. Report iff /** Make a complaint, but don't specify any location. */
<tt>warnings_flag & Wother</tt>. */ void complain (warnings flags, char const *message, ...)
void warn (char const *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
void warn_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __attribute__ ((__format__ (__printf__, 2, 3)));
/* Generate a message aligned by an indent. /** Make a complaint with location. */
When *indent == 0, assign message's indent to *indent, void complain_at (location loc, warnings flags, char const *message, ...)
When *indent > 0, align the message by *indent value. */
void warn_at_indent (location loc, unsigned *indent,
char const *format, ...)
__attribute__ ((__format__ (__printf__, 3, 4))); __attribute__ ((__format__ (__printf__, 3, 4)));
/** An error, but we continue and die later. */ /** Make a complaint with location and some indentation. */
void complain_at_indent (location loc, warnings flags, unsigned *indent,
void complain (char const *format, ...) char const *message, ...)
__attribute__ ((__format__ (__printf__, 1, 2))); __attribute__ ((__format__ (__printf__, 4, 5)));
void complain_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/* Generate a message aligned by an indent.
When *indent == 0, assign message's indent to *indent,
When *indent > 0, align the message by *indent value. */
void complain_at_indent (location loc, unsigned *indent,
char const *format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
/** An incompatibility with POSIX Yacc: mapped either to warn* or
complain* depending on yacc_flag. */
void yacc_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/** A midrule-value warning. Report iff
<tt>warnings_flag & Wmidrule_values</tt>. */
void midrule_value_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/** A fatal error, causing immediate exit. */
void fatal (char const *format, ...)
__attribute__ ((__noreturn__, __format__ (__printf__, 1, 2)));
void fatal_at (location loc, char const *format, ...)
__attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
/** Whether an error was reported. */ /** Whether an error was reported. */
extern bool complaint_issued; extern bool complaint_issued;

View File

@@ -584,7 +584,7 @@ conflicts_print (void)
if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1) if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1)
{ {
warn (_("%%expect-rr applies only to GLR parsers")); complain (Wother, _("%%expect-rr applies only to GLR parsers"));
expected_rr_conflicts = -1; expected_rr_conflicts = -1;
} }
@@ -618,14 +618,14 @@ conflicts_print (void)
if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1) if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1)
{ {
if (! src_ok) if (! src_ok)
complain (ngettext ("expected %d shift/reduce conflict", complain (complaint, ngettext ("expected %d shift/reduce conflict",
"expected %d shift/reduce conflicts", "expected %d shift/reduce conflicts",
src_expected), src_expected),
src_expected); src_expected);
if (! rrc_ok) if (! rrc_ok)
complain (ngettext ("expected %d reduce/reduce conflict", complain (complaint, ngettext ("expected %d reduce/reduce conflict",
"expected %d reduce/reduce conflicts", "expected %d reduce/reduce conflicts",
rrc_expected), rrc_expected),
rrc_expected); rrc_expected);
} }
} }

View File

@@ -360,7 +360,7 @@ output_file_name_check (char **file_name)
bool conflict = false; bool conflict = false;
if (STREQ (*file_name, grammar_file)) if (STREQ (*file_name, grammar_file))
{ {
complain (_("refusing to overwrite the input file %s"), complain (complaint, _("refusing to overwrite the input file %s"),
quote (*file_name)); quote (*file_name));
conflict = true; conflict = true;
} }
@@ -370,8 +370,8 @@ output_file_name_check (char **file_name)
for (i = 0; i < file_names_count; i++) for (i = 0; i < file_names_count; i++)
if (STREQ (file_names[i], *file_name)) if (STREQ (file_names[i], *file_name))
{ {
warn (_("conflicting outputs to file %s"), complain (Wother, _("conflicting outputs to file %s"),
quote (*file_name)); quote (*file_name));
conflict = true; conflict = true;
} }
} }

View File

@@ -401,7 +401,8 @@ skeleton_arg (char const *arg, int prio, location loc)
skeleton = arg; skeleton = arg;
} }
else if (prio == skeleton_prio) else if (prio == skeleton_prio)
complain_at (loc, _("multiple skeleton declarations are invalid")); complain_at (loc, complaint,
_("multiple skeleton declarations are invalid"));
} }
void void
@@ -426,7 +427,7 @@ language_argmatch (char const *arg, int prio, location loc)
else else
return; return;
complain_at (loc, msg, quotearg_colon (arg)); complain_at (loc, complaint, msg, quotearg_colon (arg));
} }
/*----------------------. /*----------------------.

View File

@@ -308,7 +308,7 @@ grammar_rules_useless_report (const char *message)
for (r = 0; r < nrules ; ++r) for (r = 0; r < nrules ; ++r)
if (!rules[r].useful) if (!rules[r].useful)
{ {
warn_at (rules[r].location, "%s: ", message); complain_at (rules[r].location, Wother, "%s: ", message);
if (warnings_flag & Wother) if (warnings_flag & Wother)
{ {
rule_print (&rules[r], stderr); rule_print (&rules[r], stderr);

View File

@@ -90,9 +90,9 @@ location_compute (location *loc, boundary *cur, char const *token, size_t size)
loc->end = *cur; loc->end = *cur;
if (line == INT_MAX && loc->start.line != INT_MAX) if (line == INT_MAX && loc->start.line != INT_MAX)
warn_at (*loc, _("line number overflow")); complain_at (*loc, Wother, _("line number overflow"));
if (column == INT_MAX && loc->start.column != INT_MAX) if (column == INT_MAX && loc->start.column != INT_MAX)
warn_at (*loc, _("column number overflow")); complain_at (*loc, Wother, _("column number overflow"));
} }

View File

@@ -439,10 +439,10 @@ muscle_percent_define_insert (char const *variable, location variable_loc,
atoi (muscle_find_const (how_name)); atoi (muscle_find_const (how_name));
if (how_old == MUSCLE_PERCENT_DEFINE_F) if (how_old == MUSCLE_PERCENT_DEFINE_F)
return; return;
complain_at (variable_loc, _("%%define variable %s redefined"), complain_at (variable_loc, complaint, _("%%define variable %s redefined"),
quote (variable)); quote (variable));
complain_at (muscle_percent_define_get_loc (variable), location loc = muscle_percent_define_get_loc (variable);
_("previous definition")); complain_at (loc, complaint, _("previous definition"));
} }
MUSCLE_INSERT_STRING (name, value); MUSCLE_INSERT_STRING (name, value);
@@ -503,7 +503,7 @@ muscle_percent_define_get_loc (char const *variable)
char const *loc_name; char const *loc_name;
loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
if (!muscle_find_const (loc_name)) if (!muscle_find_const (loc_name))
fatal(_("%s: undefined %%define variable %s"), complain (fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_get_loc", quote (variable)); "muscle_percent_define_get_loc", quote (variable));
return muscle_location_decode (loc_name); return muscle_location_decode (loc_name);
} }
@@ -517,7 +517,7 @@ muscle_percent_define_get_syncline (char const *variable)
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
syncline = muscle_find_const (syncline_name); syncline = muscle_find_const (syncline_name);
if (!syncline) if (!syncline)
fatal(_("%s: undefined %%define variable %s"), complain (fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_get_syncline", quote (variable)); "muscle_percent_define_get_syncline", quote (variable));
return syncline; return syncline;
} }
@@ -562,15 +562,16 @@ muscle_percent_define_flag_if (char const *variable)
else if (!muscle_find_const (invalid_boolean_name)) else if (!muscle_find_const (invalid_boolean_name))
{ {
muscle_insert (invalid_boolean_name, ""); muscle_insert (invalid_boolean_name, "");
complain_at(muscle_percent_define_get_loc (variable), location loc = muscle_percent_define_get_loc (variable);
_("invalid value for %%define Boolean variable %s"), complain_at (loc, complaint,
quote (variable)); _("invalid value for %%define Boolean variable %s"),
quote (variable));
} }
free (value); free (value);
} }
else else
fatal(_("%s: undefined %%define variable %s"), complain (fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_flag", quote (variable)); "muscle_percent_define_flag", quote (variable));
return result; return result;
} }
@@ -620,11 +621,12 @@ muscle_percent_define_check_values (char const * const *values)
if (!*values) if (!*values)
{ {
location loc = muscle_percent_define_get_loc (*variablep); location loc = muscle_percent_define_get_loc (*variablep);
complain_at(loc, complain_at (loc, complaint,
_("invalid value for %%define variable %s: %s"), _("invalid value for %%define variable %s: %s"),
quote (*variablep), quote_n (1, value)); quote (*variablep), quote_n (1, value));
for (values = variablep + 1; *values; ++values) for (values = variablep + 1; *values; ++values)
complain_at (loc, _("accepted value: %s"), quote (*values)); complain_at (loc, complaint, _("accepted value: %s"),
quote (*values));
} }
else else
{ {
@@ -634,8 +636,8 @@ muscle_percent_define_check_values (char const * const *values)
free (value); free (value);
} }
else else
fatal (_("%s: undefined %%define variable %s"), complain (fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_check_values", quote (*variablep)); "muscle_percent_define_check_values", quote (*variablep));
} }
} }

View File

@@ -773,7 +773,8 @@ add_param (param_type type, char *decl, location loc)
} }
if (! name_start) if (! name_start)
complain_at (loc, _("missing identifier in parameter declaration")); complain_at (loc, complaint,
_("missing identifier in parameter declaration"));
else else
{ {
char *name = xmemdup0 (name_start, strspn (name_start, alphanum)); char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
@@ -793,7 +794,7 @@ version_check (location const *loc, char const *version)
{ {
if (strverscmp (version, PACKAGE_VERSION) > 0) if (strverscmp (version, PACKAGE_VERSION) > 0)
{ {
complain_at (*loc, "require bison %s, but have %s", complain_at (*loc, complaint, "require bison %s, but have %s",
version, PACKAGE_VERSION); version, PACKAGE_VERSION);
exit (EX_MISMATCH); exit (EX_MISMATCH);
} }
@@ -802,7 +803,7 @@ version_check (location const *loc, char const *version)
static void static void
gram_error (location const *loc, char const *msg) gram_error (location const *loc, char const *msg)
{ {
complain_at (*loc, "%s", msg); complain_at (*loc, complaint, "%s", msg);
} }
char const * char const *

View File

@@ -59,7 +59,7 @@ void
grammar_start_symbol_set (symbol *sym, location loc) grammar_start_symbol_set (symbol *sym, location loc)
{ {
if (start_flag) if (start_flag)
complain_at (loc, _("multiple %s declarations"), "%start"); complain_at (loc, complaint, _("multiple %s declarations"), "%start");
else else
{ {
start_flag = true; start_flag = true;
@@ -128,11 +128,11 @@ record_merge_function_type (int merger, uniqstr type, location declaration_loc)
aver (merge_function != NULL && merger_find == merger); aver (merge_function != NULL && merger_find == merger);
if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type)) if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type))
{ {
complain_at (declaration_loc, complain_at (declaration_loc, complaint,
_("result type clash on merge function %s: <%s> != <%s>"), _("result type clash on merge function %s: <%s> != <%s>"),
quote (merge_function->name), type, merge_function->type); quote (merge_function->name), type, merge_function->type);
complain_at (merge_function->type_declaration_location, complain_at (merge_function->type_declaration_location, complaint,
_("previous declaration")); _("previous declaration"));
} }
merge_function->type = uniqstr_new (type); merge_function->type = uniqstr_new (type);
merge_function->type_declaration_location = declaration_loc; merge_function->type_declaration_location = declaration_loc;
@@ -197,9 +197,9 @@ assign_named_ref (symbol_list *p, named_ref *name)
if (name->id == sym->tag) if (name->id == sym->tag)
{ {
warn_at (name->loc, complain_at (name->loc, Wother,
_("duplicated symbol name for %s ignored"), _("duplicated symbol name for %s ignored"),
quote (sym->tag)); quote (sym->tag));
named_ref_free (name); named_ref_free (name);
} }
else else
@@ -242,7 +242,8 @@ grammar_current_rule_begin (symbol *lhs, location loc,
++nvars; ++nvars;
} }
else if (lhs->class == token_sym) else if (lhs->class == token_sym)
complain_at (loc, _("rule given for %s, which is a token"), lhs->tag); complain_at (loc, complaint, _("rule given for %s, which is a token"),
lhs->tag);
} }
@@ -296,14 +297,14 @@ grammar_rule_check (const symbol_list *r)
const char *rhs_type = const char *rhs_type =
first_rhs->type_name ? first_rhs->type_name : ""; first_rhs->type_name ? first_rhs->type_name : "";
if (!UNIQSTR_EQ (lhs_type, rhs_type)) if (!UNIQSTR_EQ (lhs_type, rhs_type))
warn_at (r->location, complain_at (r->location, Wother,
_("type clash on default action: <%s> != <%s>"), _("type clash on default action: <%s> != <%s>"),
lhs_type, rhs_type); lhs_type, rhs_type);
} }
/* Warn if there is no default for $$ but we need one. */ /* Warn if there is no default for $$ but we need one. */
else else
warn_at (r->location, complain_at (r->location, Wother,
_("empty rule for typed nonterminal, and no action")); _("empty rule for typed nonterminal, and no action"));
} }
/* Check that symbol values that should be used are in fact used. */ /* Check that symbol values that should be used are in fact used. */
@@ -318,12 +319,12 @@ grammar_rule_check (const symbol_list *r)
/* The default action, $$ = $1, `uses' both. */ /* The default action, $$ = $1, `uses' both. */
&& (r->action_props.code || (n != 0 && n != 1))) && (r->action_props.code || (n != 0 && n != 1)))
{ {
void (*warn_at_ptr)(location, char const*, ...) = int warn_flag =
midrule_warning ? midrule_value_at : warn_at; midrule_warning ? Wmidrule_values : Wother;
if (n) if (n)
warn_at_ptr (r->location, _("unused value: $%d"), n); complain_at (r->location, warn_flag, _("unused value: $%d"), n);
else else
warn_at_ptr (r->location, _("unset value: $$")); complain_at (r->location, warn_flag, _("unset value: $$"));
} }
} }
} }
@@ -334,8 +335,8 @@ grammar_rule_check (const symbol_list *r)
if (r->ruleprec if (r->ruleprec
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"' && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
&& r->ruleprec->status != declared && !r->ruleprec->prec) && r->ruleprec->status != declared && !r->ruleprec->prec)
warn_at (r->location, _("token for %%prec is not defined: %s"), complain_at (r->location, Wother,
r->ruleprec->tag); _("token for %%prec is not defined: %s"), r->ruleprec->tag);
} }
@@ -425,7 +426,7 @@ grammar_current_rule_prec_set (symbol *precsym, location loc)
token. */ token. */
symbol_class_set (precsym, token_sym, loc, false); symbol_class_set (precsym, token_sym, loc, false);
if (current_rule->ruleprec) if (current_rule->ruleprec)
complain_at (loc, _("only one %s allowed per rule"), "%prec"); complain_at (loc, complaint, _("only one %s allowed per rule"), "%prec");
current_rule->ruleprec = precsym; current_rule->ruleprec = precsym;
} }
@@ -435,11 +436,13 @@ void
grammar_current_rule_dprec_set (int dprec, location loc) grammar_current_rule_dprec_set (int dprec, location loc)
{ {
if (! glr_parser) if (! glr_parser)
warn_at (loc, _("%s affects only GLR parsers"), "%dprec"); complain_at (loc, Wother, _("%s affects only GLR parsers"),
"%dprec");
if (dprec <= 0) if (dprec <= 0)
complain_at (loc, _("%s must be followed by positive number"), "%dprec"); complain_at (loc, complaint, _("%s must be followed by positive number"),
"%dprec");
else if (current_rule->dprec != 0) else if (current_rule->dprec != 0)
complain_at (loc, _("only one %s allowed per rule"), "%dprec"); complain_at (loc, complaint, _("only one %s allowed per rule"), "%dprec");
current_rule->dprec = dprec; current_rule->dprec = dprec;
} }
@@ -450,9 +453,10 @@ void
grammar_current_rule_merge_set (uniqstr name, location loc) grammar_current_rule_merge_set (uniqstr name, location loc)
{ {
if (! glr_parser) if (! glr_parser)
warn_at (loc, _("%s affects only GLR parsers"), "%merge"); complain_at (loc, Wother, _("%s affects only GLR parsers"),
"%merge");
if (current_rule->merger != 0) if (current_rule->merger != 0)
complain_at (loc, _("only one %s allowed per rule"), "%merge"); complain_at (loc, complaint, _("only one %s allowed per rule"), "%merge");
current_rule->merger = get_merge_function (name); current_rule->merger = get_merge_function (name);
current_rule->merger_declaration_location = loc; current_rule->merger_declaration_location = loc;
} }
@@ -551,7 +555,7 @@ packgram (void)
/* Don't allow rule_length == INT_MAX, since that might /* Don't allow rule_length == INT_MAX, since that might
cause confusion with strtol if INT_MAX == LONG_MAX. */ cause confusion with strtol if INT_MAX == LONG_MAX. */
if (rule_length == INT_MAX) if (rule_length == INT_MAX)
fatal_at (rules[ruleno].location, _("rule is too long")); complain_at (rules[ruleno].location, fatal, _("rule is too long"));
/* item_number = symbol_number. /* item_number = symbol_number.
But the former needs to contain more: negative rule numbers. */ But the former needs to contain more: negative rule numbers. */
@@ -669,7 +673,7 @@ check_and_convert_grammar (void)
{ {
/* Grammar has been read. Do some checking. */ /* Grammar has been read. Do some checking. */
if (nrules == 0) if (nrules == 0)
fatal (_("no rules in the input grammar")); complain (fatal, _("no rules in the input grammar"));
/* If the user did not define her ENDTOKEN, do it now. */ /* If the user did not define her ENDTOKEN, do it now. */
if (!endtoken) if (!endtoken)

View File

@@ -299,9 +299,9 @@ nonterminals_reduce (void)
{ {
nontermmap[i - ntokens] = n++; nontermmap[i - ntokens] = n++;
if (symbols[i]->status != used) if (symbols[i]->status != used)
warn_at (symbols[i]->location, complain_at (symbols[i]->location, Wother,
_("nonterminal useless in grammar: %s"), _("nonterminal useless in grammar: %s"),
symbols[i]->tag); symbols[i]->tag);
} }
@@ -383,15 +383,15 @@ static void
reduce_print (void) reduce_print (void)
{ {
if (nuseless_nonterminals > 0) if (nuseless_nonterminals > 0)
warn (ngettext ("%d nonterminal useless in grammar", complain (Wother, ngettext ("%d nonterminal useless in grammar",
"%d nonterminals useless in grammar", "%d nonterminals useless in grammar",
nuseless_nonterminals), nuseless_nonterminals),
nuseless_nonterminals); nuseless_nonterminals);
if (nuseless_productions > 0) if (nuseless_productions > 0)
warn (ngettext ("%d rule useless in grammar", complain (Wother, ngettext ("%d rule useless in grammar",
"%d rules useless in grammar", "%d rules useless in grammar",
nuseless_productions), nuseless_productions),
nuseless_productions); nuseless_productions);
} }
void void
@@ -416,9 +416,9 @@ reduce_grammar (void)
reduce_print (); reduce_print ();
if (!bitset_test (N, accept->number - ntokens)) if (!bitset_test (N, accept->number - ntokens))
fatal_at (startsymbol_location, complain_at (startsymbol_location, fatal,
_("start symbol %s does not derive any sentence"), _("start symbol %s does not derive any sentence"),
startsymbol->tag); startsymbol->tag);
/* First reduce the nonterminals, as they renumber themselves in the /* First reduce the nonterminals, as they renumber themselves in the
whole grammar. If you change the order, nonterms would be whole grammar. If you change the order, nonterms would be

View File

@@ -198,12 +198,12 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
need_semicolon = true; need_semicolon = true;
} }
"$" { "$" {
warn_at (*loc, _("stray '$'")); complain_at (*loc, Wother, _("stray '$'"));
obstack_sgrow (&obstack_for_string, "$]["); obstack_sgrow (&obstack_for_string, "$][");
need_semicolon = true; need_semicolon = true;
} }
"@" { "@" {
warn_at (*loc, _("stray '@'")); complain_at (*loc, Wother, _("stray '@'"));
obstack_sgrow (&obstack_for_string, "@@"); obstack_sgrow (&obstack_for_string, "@@");
need_semicolon = true; need_semicolon = true;
} }
@@ -228,8 +228,10 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
if (outer_brace && !yacc_flag && language_prio == default_prio if (outer_brace && !yacc_flag && language_prio == default_prio
&& skeleton_prio == default_prio && need_semicolon && ! in_cpp) && skeleton_prio == default_prio && need_semicolon && ! in_cpp)
{ {
warn_at (*loc, _("a ';' might be needed at the end of action code")); complain_at (*loc, Wother,
warn_at (*loc, _("future versions of Bison will not add the ';'")); _("a ';' might be needed at the end of action code"));
complain_at (*loc, Wother,
_("future versions of Bison will not add the ';'"));
obstack_1grow (&obstack_for_string, ';'); obstack_1grow (&obstack_for_string, ';');
} }
@@ -251,8 +253,8 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
2.4.2. */ 2.4.2. */
YYFAIL { YYFAIL {
STRING_GROW; need_semicolon = true; STRING_GROW; need_semicolon = true;
warn_at (*loc, _("use of YYFAIL, which is deprecated and will be" complain_at (*loc, Wother,
" removed")); _("use of YYFAIL, which is deprecated and will be removed"));
} }
/* The sole purpose of this is to make sure identifiers that merely /* The sole purpose of this is to make sure identifiers that merely
@@ -436,11 +438,13 @@ show_sub_messages (const char* cp, bool explicit_bracketing,
if (var->err == 0) if (var->err == 0)
{ {
if (is_warning) if (is_warning)
warn_at_indent (var->loc, &indent, _("refers to: %c%s at %s"), complain_at_indent (var->loc, Wother, &indent,
dollar_or_at, var->id, at_spec); _("refers to: %c%s at %s"), dollar_or_at,
var->id, at_spec);
else else
complain_at_indent (var->loc, &indent, _("refers to: %c%s at %s"), complain_at_indent (var->loc, complaint, &indent,
dollar_or_at, var->id, at_spec); _("refers to: %c%s at %s"), dollar_or_at,
var->id, at_spec);
} }
else else
{ {
@@ -483,10 +487,10 @@ show_sub_messages (const char* cp, bool explicit_bracketing,
obstack_1grow (&msg_buf, '\0'); obstack_1grow (&msg_buf, '\0');
if (is_warning) if (is_warning)
warn_at_indent (id_loc, &indent, "%s", complain_at_indent (id_loc, Wother, &indent, "%s",
(char *) obstack_finish (&msg_buf)); (char *) obstack_finish (&msg_buf));
else else
complain_at_indent (id_loc, &indent, "%s", complain_at_indent (id_loc, complaint, &indent, "%s",
(char *) obstack_finish (&msg_buf)); (char *) obstack_finish (&msg_buf));
obstack_free (&msg_buf, 0); obstack_free (&msg_buf, 0);
} }
@@ -529,7 +533,7 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
return num; return num;
else else
{ {
complain_at (text_loc, _("integer out of range: %s"), complain_at (text_loc, complaint, _("integer out of range: %s"),
quote (text)); quote (text));
return INVALID_REF; return INVALID_REF;
} }
@@ -618,8 +622,8 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
cp_end - cp : ref_tail_fields - cp; cp_end - cp : ref_tail_fields - cp;
unsigned indent = 0; unsigned indent = 0;
complain_at_indent (text_loc, &indent, _("invalid reference: %s"), complain_at_indent (text_loc, complaint, &indent,
quote (text)); _("invalid reference: %s"), quote (text));
indent += SUB_INDENT; indent += SUB_INDENT;
if (len == 0) if (len == 0)
{ {
@@ -629,20 +633,21 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
const char *format = const char *format =
_("syntax error after '%c', expecting integer, letter," _("syntax error after '%c', expecting integer, letter,"
" '_', '[', or '$'"); " '_', '[', or '$'");
complain_at_indent (sym_loc, &indent, format, dollar_or_at); complain_at_indent (sym_loc, complaint, &indent, format,
dollar_or_at);
} }
else if (midrule_rhs_index) else if (midrule_rhs_index)
{ {
const char *format = const char *format =
_("symbol not found in production before $%d: %.*s"); _("symbol not found in production before $%d: %.*s");
complain_at_indent (rule->location, &indent, format, complain_at_indent (rule->location, complaint, &indent, format,
midrule_rhs_index, len, cp); midrule_rhs_index, len, cp);
} }
else else
{ {
const char *format = const char *format =
_("symbol not found in production: %.*s"); _("symbol not found in production: %.*s");
complain_at_indent (rule->location, &indent, format, complain_at_indent (rule->location, complaint, &indent, format,
len, cp); len, cp);
} }
@@ -656,8 +661,8 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
unsigned indent = 0; unsigned indent = 0;
if (variant_count > 1) if (variant_count > 1)
{ {
warn_at_indent (text_loc, &indent, _("misleading reference: %s"), complain_at_indent (text_loc, Wother, &indent,
quote (text)); _("misleading reference: %s"), quote (text));
show_sub_messages (cp, explicit_bracketing, midrule_rhs_index, show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
dollar_or_at, true, indent + SUB_INDENT); dollar_or_at, true, indent + SUB_INDENT);
} }
@@ -671,8 +676,8 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
default: default:
{ {
unsigned indent = 0; unsigned indent = 0;
complain_at_indent (text_loc, &indent, _("ambiguous reference: %s"), complain_at_indent (text_loc, complaint, &indent,
quote (text)); _("ambiguous reference: %s"), quote (text));
show_sub_messages (cp, explicit_bracketing, midrule_rhs_index, show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
dollar_or_at, false, indent + SUB_INDENT); dollar_or_at, false, indent + SUB_INDENT);
return INVALID_REF; return INVALID_REF;
@@ -730,7 +735,8 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
gt_ptr = cp; gt_ptr = cp;
++cp; ++cp;
if (untyped_var_seen) if (untyped_var_seen)
complain_at (dollar_loc, _("explicit type given in untyped grammar")); complain_at (dollar_loc, complaint,
_("explicit type given in untyped grammar"));
tag_seen = true; tag_seen = true;
} }
@@ -754,13 +760,14 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
if (union_seen | tag_seen) if (union_seen | tag_seen)
{ {
if (rule->midrule_parent_rule) if (rule->midrule_parent_rule)
complain_at (dollar_loc, complain_at (dollar_loc, complaint,
_("$$ for the midrule at $%d of %s" _("$$ for the midrule at $%d of %s"
" has no declared type"), " has no declared type"),
rule->midrule_parent_rhs_index, rule->midrule_parent_rhs_index,
quote (effective_rule->content.sym->tag)); quote (effective_rule->content.sym->tag));
else else
complain_at (dollar_loc, _("$$ of %s has no declared type"), complain_at (dollar_loc, complaint,
_("$$ of %s has no declared type"),
quote (rule->content.sym->tag)); quote (rule->content.sym->tag));
} }
else else
@@ -782,8 +789,9 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
if (!type_name) if (!type_name)
{ {
if (union_seen | tag_seen) if (union_seen | tag_seen)
complain_at (dollar_loc, _("$%s of %s has no declared type"), complain_at (dollar_loc, complaint,
cp, quote (effective_rule->content.sym->tag)); _("$%s of %s has no declared type"), cp,
quote (effective_rule->content.sym->tag));
else else
untyped_var_seen = true; untyped_var_seen = true;
type_name = ""; type_name = "";

View File

@@ -164,7 +164,9 @@ splice (\\[ \f\t\v]*\n)*
<INITIAL,SC_AFTER_IDENTIFIER,SC_BRACKETED_ID,SC_RETURN_BRACKETED_ID> <INITIAL,SC_AFTER_IDENTIFIER,SC_BRACKETED_ID,SC_RETURN_BRACKETED_ID>
{ {
/* Comments and white space. */ /* Comments and white space. */
"," warn_at (*loc, _("stray ',' treated as white space")); "," {
complain_at (*loc, Wother, _("stray ',' treated as white space"));
}
[ \f\n\t\v] | [ \f\n\t\v] |
"//".* ; "//".* ;
"/*" { "/*" {
@@ -239,7 +241,7 @@ splice (\\[ \f\t\v]*\n)*
"%yacc" return PERCENT_YACC; "%yacc" return PERCENT_YACC;
{directive} { {directive} {
complain_at (*loc, _("invalid directive: %s"), quote (yytext)); complain_at (*loc, complaint, _("invalid directive: %s"), quote (yytext));
} }
"=" return EQUAL; "=" return EQUAL;
@@ -265,7 +267,7 @@ splice (\\[ \f\t\v]*\n)*
/* Identifiers may not start with a digit. Yet, don't silently /* Identifiers may not start with a digit. Yet, don't silently
accept "1FOO" as "1 FOO". */ accept "1FOO" as "1 FOO". */
{int}{id} { {int}{id} {
complain_at (*loc, _("invalid identifier: %s"), quote (yytext)); complain_at (*loc, complaint, _("invalid identifier: %s"), quote (yytext));
} }
/* Characters. */ /* Characters. */
@@ -323,7 +325,7 @@ splice (\\[ \f\t\v]*\n)*
} }
. { . {
complain_at (*loc, _("invalid character: %s"), quote (yytext)); complain_at (*loc, complaint, _("invalid character: %s"), quote (yytext));
} }
<<EOF>> { <<EOF>> {
@@ -340,7 +342,7 @@ splice (\\[ \f\t\v]*\n)*
<SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING,SC_TAG> <SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING,SC_TAG>
{ {
\0 complain_at (*loc, _("invalid null character")); \0 complain_at (*loc, complaint, _("invalid null character"));
} }
@@ -392,7 +394,8 @@ splice (\\[ \f\t\v]*\n)*
{id} { {id} {
if (bracketed_id_str) if (bracketed_id_str)
{ {
complain_at (*loc, _("unexpected identifier in bracketed name: %s"), complain_at (*loc, complaint,
_("unexpected identifier in bracketed name: %s"),
quote (yytext)); quote (yytext));
} }
else else
@@ -414,10 +417,10 @@ splice (\\[ \f\t\v]*\n)*
} }
} }
else else
complain_at (*loc, _("an identifier expected")); complain_at (*loc, complaint, _("an identifier expected"));
} }
. { . {
complain_at (*loc, _("invalid character in bracketed name: %s"), complain_at (*loc, complaint, _("invalid character in bracketed name: %s"),
quote (yytext)); quote (yytext));
} }
<<EOF>> { <<EOF>> {
@@ -515,12 +518,13 @@ splice (\\[ \f\t\v]*\n)*
/* FIXME: Eventually, make these errors. */ /* FIXME: Eventually, make these errors. */
if (last_string[0] == '\0') if (last_string[0] == '\0')
{ {
warn_at (*loc, _("empty character literal")); complain_at (*loc, Wother, _("empty character literal"));
/* '\0' seems dangerous even if we are about to complain. */ /* '\0' seems dangerous even if we are about to complain. */
val->character = '\''; val->character = '\'';
} }
else if (last_string[1] != '\0') else if (last_string[1] != '\0')
warn_at (*loc, _("extra characters in character literal")); complain_at (*loc, Wother,
_("extra characters in character literal"));
} }
if (yytext[0] == '\n') if (yytext[0] == '\n')
unexpected_newline (token_start, "'"); unexpected_newline (token_start, "'");
@@ -536,12 +540,13 @@ splice (\\[ \f\t\v]*\n)*
/* FIXME: Eventually, make these errors. */ /* FIXME: Eventually, make these errors. */
if (last_string[0] == '\0') if (last_string[0] == '\0')
{ {
warn_at (*loc, _("empty character literal")); complain_at (*loc, Wother, _("empty character literal"));
/* '\0' seems dangerous even if we are about to complain. */ /* '\0' seems dangerous even if we are about to complain. */
val->character = '\''; val->character = '\'';
} }
else if (last_string[1] != '\0') else if (last_string[1] != '\0')
warn_at (*loc, _("extra characters in character literal")); complain_at (*loc, Wother,
_("extra characters in character literal"));
} }
unexpected_eof (token_start, "'"); unexpected_eof (token_start, "'");
STRING_FREE; STRING_FREE;
@@ -594,7 +599,7 @@ splice (\\[ \f\t\v]*\n)*
\\[0-7]{1,3} { \\[0-7]{1,3} {
unsigned long int c = strtoul (yytext + 1, NULL, 8); unsigned long int c = strtoul (yytext + 1, NULL, 8);
if (!c || UCHAR_MAX < c) if (!c || UCHAR_MAX < c)
complain_at (*loc, _("invalid number after \\-escape: %s"), complain_at (*loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1); yytext+1);
else else
obstack_1grow (&obstack_for_string, c); obstack_1grow (&obstack_for_string, c);
@@ -604,7 +609,7 @@ splice (\\[ \f\t\v]*\n)*
verify (UCHAR_MAX < ULONG_MAX); verify (UCHAR_MAX < ULONG_MAX);
unsigned long int c = strtoul (yytext + 2, NULL, 16); unsigned long int c = strtoul (yytext + 2, NULL, 16);
if (!c || UCHAR_MAX < c) if (!c || UCHAR_MAX < c)
complain_at (*loc, _("invalid number after \\-escape: %s"), complain_at (*loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1); yytext+1);
else else
obstack_1grow (&obstack_for_string, c); obstack_1grow (&obstack_for_string, c);
@@ -624,7 +629,7 @@ splice (\\[ \f\t\v]*\n)*
\\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} { \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
int c = convert_ucn_to_byte (yytext); int c = convert_ucn_to_byte (yytext);
if (c <= 0) if (c <= 0)
complain_at (*loc, _("invalid number after \\-escape: %s"), complain_at (*loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1); yytext+1);
else else
obstack_1grow (&obstack_for_string, c); obstack_1grow (&obstack_for_string, c);
@@ -636,7 +641,8 @@ splice (\\[ \f\t\v]*\n)*
p = quote (p); p = quote (p);
else else
p = quotearg_style_mem (escape_quoting_style, p, 1); p = quotearg_style_mem (escape_quoting_style, p, 1);
complain_at (*loc, _("invalid character after \\-escape: %s"), p); complain_at (*loc, complaint, _("invalid character after \\-escape: %s"),
p);
} }
} }
@@ -867,7 +873,8 @@ scan_integer (char const *number, int base, location loc)
if (INT_MAX < num) if (INT_MAX < num)
{ {
complain_at (loc, _("integer out of range: %s"), quote (number)); complain_at (loc, complaint, _("integer out of range: %s"),
quote (number));
num = INT_MAX; num = INT_MAX;
} }
@@ -945,7 +952,7 @@ handle_syncline (char *args, location loc)
*strchr (file, '"') = '\0'; *strchr (file, '"') = '\0';
if (INT_MAX <= lineno) if (INT_MAX <= lineno)
{ {
warn_at (loc, _("line number overflow")); complain_at (loc, Wother, _("line number overflow"));
lineno = INT_MAX; lineno = INT_MAX;
} }
current_file = uniqstr_new (file); current_file = uniqstr_new (file);
@@ -969,7 +976,7 @@ unexpected_end (boundary start, char const *msgid, char const *token_end)
// Instead of '\'', display "'". // Instead of '\'', display "'".
if (STREQ (token_end, "'\\''")) if (STREQ (token_end, "'\\''"))
token_end = "\"'\""; token_end = "\"'\"";
complain_at (loc, _(msgid), token_end); complain_at (loc, complaint, _(msgid), token_end);
} }

View File

@@ -141,7 +141,8 @@ static void fail_for_invalid_at (char const *at);
<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{ <SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{
<<EOF>> { <<EOF>> {
fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]); complain (fatal, _("unclosed %s directive in skeleton"),
at_directive_argv[0]);
} }
} }
@@ -188,34 +189,36 @@ at_directive_perform (int at_directive_argc,
|| STREQ (at_directive_argv[0], "@complain") || STREQ (at_directive_argv[0], "@complain")
|| STREQ (at_directive_argv[0], "@fatal")) || STREQ (at_directive_argv[0], "@fatal"))
{ {
void (*func)(char const *, ...); warnings complaint_flag;
switch (at_directive_argv[0][1]) switch (at_directive_argv[0][1])
{ {
case 'w': func = warn; break; case 'w': complaint_flag = Wother; break;
case 'c': func = complain; break; case 'c': complaint_flag = complaint; break;
case 'f': func = fatal; break; case 'f': complaint_flag = fatal; break;
default: aver (false); break; default: aver (false); break;
} }
switch (at_directive_argc) switch (at_directive_argc)
{ {
case 2: case 2:
func (_(at_directive_argv[1])); complain (complaint_flag, "%s", _(at_directive_argv[1]));
break; break;
case 3: case 3:
func (_(at_directive_argv[1]), at_directive_argv[2]); complain (complaint_flag, _(at_directive_argv[1]),
at_directive_argv[2]);
break; break;
case 4: case 4:
func (_(at_directive_argv[1]), at_directive_argv[2], complain (complaint_flag, _(at_directive_argv[1]),
at_directive_argv[3]); at_directive_argv[2], at_directive_argv[3]);
break; break;
case 5: case 5:
func (_(at_directive_argv[1]), at_directive_argv[2], complain (complaint_flag, _(at_directive_argv[1]),
at_directive_argv[3], at_directive_argv[4]); at_directive_argv[2], at_directive_argv[3],
at_directive_argv[4]);
break; break;
case 6: case 6:
func (_(at_directive_argv[1]), at_directive_argv[2], complain (complaint_flag, _(at_directive_argv[1]),
at_directive_argv[3], at_directive_argv[4], at_directive_argv[2], at_directive_argv[3],
at_directive_argv[5]); at_directive_argv[4], at_directive_argv[5]);
break; break;
default: default:
fail_for_at_directive_too_many_args (at_directive_argv[0]); fail_for_at_directive_too_many_args (at_directive_argv[0]);
@@ -226,39 +229,41 @@ at_directive_perform (int at_directive_argc,
|| STREQ (at_directive_argv[0], "@complain_at") || STREQ (at_directive_argv[0], "@complain_at")
|| STREQ (at_directive_argv[0], "@fatal_at")) || STREQ (at_directive_argv[0], "@fatal_at"))
{ {
void (*func)(location, char const *, ...); warnings complaint_flag;
location loc; location loc;
if (at_directive_argc < 4) if (at_directive_argc < 4)
fail_for_at_directive_too_few_args (at_directive_argv[0]); fail_for_at_directive_too_few_args (at_directive_argv[0]);
switch (at_directive_argv[0][1]) switch (at_directive_argv[0][1])
{ {
case 'w': func = warn_at; break; case 'w': complaint_flag = Wother; break;
case 'c': func = complain_at; break; case 'c': complaint_flag = complaint; break;
case 'f': func = fatal_at; break; case 'f': complaint_flag = fatal; break;
default: aver (false); break; default: aver (false); break;
} }
boundary_set_from_string (&loc.start, at_directive_argv[1]); boundary_set_from_string (&loc.start, at_directive_argv[1]);
boundary_set_from_string (&loc.end, at_directive_argv[2]); boundary_set_from_string (&loc.end, at_directive_argv[2]);
switch (at_directive_argc) switch (at_directive_argc)
{ {
case 4: case 4:
func (loc, _(at_directive_argv[3])); complain_at (loc, complaint_flag, "%s", _(at_directive_argv[3]));
break; break;
case 5: case 5:
func (loc, _(at_directive_argv[3]), at_directive_argv[4]); complain_at (loc, complaint_flag, _(at_directive_argv[3]),
at_directive_argv[4]);
break; break;
case 6: case 6:
func (loc, _(at_directive_argv[3]), at_directive_argv[4], complain_at (loc, complaint_flag, _(at_directive_argv[3]),
at_directive_argv[5]); at_directive_argv[4], at_directive_argv[5]);
break; break;
case 7: case 7:
func (loc, _(at_directive_argv[3]), at_directive_argv[4], complain_at (loc, complaint_flag, _(at_directive_argv[3]),
at_directive_argv[5], at_directive_argv[6]); at_directive_argv[4], at_directive_argv[5],
at_directive_argv[6]);
break; break;
case 8: case 8:
func (loc, _(at_directive_argv[3]), at_directive_argv[4], complain_at (loc, complaint_flag, _(at_directive_argv[3]),
at_directive_argv[5], at_directive_argv[6], at_directive_argv[4], at_directive_argv[5],
at_directive_argv[7]); at_directive_argv[6], at_directive_argv[7]);
break; break;
default: default:
fail_for_at_directive_too_many_args (at_directive_argv[0]); fail_for_at_directive_too_many_args (at_directive_argv[0]);
@@ -286,19 +291,19 @@ at_directive_perform (int at_directive_argc,
static void static void
fail_for_at_directive_too_few_args (char const *at_directive_name) fail_for_at_directive_too_few_args (char const *at_directive_name)
{ {
fatal (_("too few arguments for %s directive in skeleton"), complain (fatal, _("too few arguments for %s directive in skeleton"),
at_directive_name); at_directive_name);
} }
static void static void
fail_for_at_directive_too_many_args (char const *at_directive_name) fail_for_at_directive_too_many_args (char const *at_directive_name)
{ {
fatal (_("too many arguments for %s directive in skeleton"), complain (fatal, _("too many arguments for %s directive in skeleton"),
at_directive_name); at_directive_name);
} }
static void static void
fail_for_invalid_at (char const *at) fail_for_invalid_at (char const *at)
{ {
fatal ("invalid @ in skeleton: %s", at); complain (fatal, "invalid @ in skeleton: %s", at);
} }

View File

@@ -24,7 +24,6 @@
#include "complain.h" #include "complain.h"
#include "symlist.h" #include "symlist.h"
/*--------------------------------------. /*--------------------------------------.
| Create a list containing SYM at LOC. | | Create a list containing SYM at LOC. |
`--------------------------------------*/ `--------------------------------------*/
@@ -212,7 +211,7 @@ symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
l = symbol_list_n_get (l, n); l = symbol_list_n_get (l, n);
if (!l) if (!l)
{ {
complain_at (loc, _("invalid $ value: $%d"), n); complain_at (loc, complaint, _("invalid $ value: $%d"), n);
return NULL; return NULL;
} }
aver (l->content_type == SYMLIST_SYMBOL); aver (l->content_type == SYMLIST_SYMBOL);

View File

@@ -75,8 +75,8 @@ symbol_new (uniqstr tag, location loc)
/* If the tag is not a string (starts with a double quote), check /* If the tag is not a string (starts with a double quote), check
that it is valid for Yacc. */ that it is valid for Yacc. */
if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-')) if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-'))
yacc_at (loc, _("POSIX Yacc forbids dashes in symbol names: %s"), complain_at (loc, Wyacc,
tag); _("POSIX Yacc forbids dashes in symbol names: %s"), tag);
res->tag = tag; res->tag = tag;
res->location = loc; res->location = loc;
@@ -95,8 +95,8 @@ symbol_new (uniqstr tag, location loc)
res->status = undeclared; res->status = undeclared;
if (nsyms == SYMBOL_NUMBER_MAXIMUM) if (nsyms == SYMBOL_NUMBER_MAXIMUM)
fatal (_("too many symbols in input grammar (limit is %d)"), complain (fatal, _("too many symbols in input grammar (limit is %d)"),
SYMBOL_NUMBER_MAXIMUM); SYMBOL_NUMBER_MAXIMUM);
nsyms++; nsyms++;
return res; return res;
} }
@@ -207,16 +207,16 @@ static void
symbol_redeclaration (symbol *s, const char *what, location first, symbol_redeclaration (symbol *s, const char *what, location first,
location second) location second)
{ {
complain_at (second, _("%s redeclaration for %s"), what, s->tag); complain_at (second, complaint, _("%s redeclaration for %s"), what, s->tag);
complain_at (first, _("previous declaration")); complain_at (first, complaint, _("previous declaration"));
} }
static void static void
semantic_type_redeclaration (semantic_type *s, const char *what, location first, semantic_type_redeclaration (semantic_type *s, const char *what, location first,
location second) location second)
{ {
complain_at (second, _("%s redeclaration for <%s>"), what, s->tag); complain_at (second, complaint, _("%s redeclaration for <%s>"), what, s->tag);
complain_at (first, _("previous declaration")); complain_at (first, complaint, _("previous declaration"));
} }
@@ -333,7 +333,7 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
bool warned = false; bool warned = false;
if (sym->class != unknown_sym && sym->class != class) if (sym->class != unknown_sym && sym->class != class)
{ {
complain_at (loc, _("symbol %s redefined"), sym->tag); complain_at (loc, complaint, _("symbol %s redefined"), sym->tag);
// Don't report both "redefined" and "redeclared". // Don't report both "redefined" and "redeclared".
warned = true; warned = true;
} }
@@ -348,7 +348,7 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
if (declaring) if (declaring)
{ {
if (sym->status == declared && !warned) if (sym->status == declared && !warned)
warn_at (loc, _("symbol %s redeclared"), sym->tag); complain_at (loc, Wother, _("symbol %s redeclared"), sym->tag);
sym->status = declared; sym->status = declared;
} }
} }
@@ -369,7 +369,8 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
user_token_numberp = &sym->alias->user_token_number; user_token_numberp = &sym->alias->user_token_number;
if (*user_token_numberp != USER_NUMBER_UNDEFINED if (*user_token_numberp != USER_NUMBER_UNDEFINED
&& *user_token_numberp != user_token_number) && *user_token_numberp != user_token_number)
complain_at (loc, _("redefining user token number of %s"), sym->tag); complain_at (loc, complaint, _("redefining user token number of %s"),
sym->tag);
*user_token_numberp = user_token_number; *user_token_numberp = user_token_number;
/* User defined $end token? */ /* User defined $end token? */
@@ -398,17 +399,17 @@ symbol_check_defined (symbol *sym)
switch (sym->status) switch (sym->status)
{ {
case used: case used:
warn_at (sym->location, complain_at (sym->location, Wother,
_("symbol %s is used, but is not defined as a token" _("symbol %s is used, but is not defined as a token"
" and has no rules"), " and has no rules"),
sym->tag); sym->tag);
break; break;
case undeclared: case undeclared:
case needed: case needed:
complain_at (sym->location, complain_at (sym->location, complaint,
_("symbol %s is used, but is not defined as a token" _("symbol %s is used, but is not defined as a token"
" and has no rules"), " and has no rules"),
sym->tag); sym->tag);
break; break;
case declared: case declared:
/* If declared, then sym->class != unknown_sym. */ /* If declared, then sym->class != unknown_sym. */
@@ -448,14 +449,14 @@ semantic_type_check_defined (semantic_type *sem_type)
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
if (sem_type->props[i].kind != CODE_PROPS_NONE if (sem_type->props[i].kind != CODE_PROPS_NONE
&& ! sem_type->props[i].is_used) && ! sem_type->props[i].is_used)
warn_at (sem_type->location, complain_at (sem_type->location, Wother,
_("useless %s for type <%s>"), _("useless %s for type <%s>"),
code_props_type_string (i), sem_type->tag); code_props_type_string (i), sem_type->tag);
} }
else else
warn_at (sem_type->location, complain_at (sem_type->location, Wother,
_("type <%s> is used, but is not associated to any symbol"), _("type <%s> is used, but is not associated to any symbol"),
sem_type->tag); sem_type->tag);
return true; return true;
} }
@@ -478,11 +479,11 @@ void
symbol_make_alias (symbol *sym, symbol *str, location loc) symbol_make_alias (symbol *sym, symbol *str, location loc)
{ {
if (str->alias) if (str->alias)
warn_at (loc, _("symbol %s used more than once as a literal string"), complain_at (loc, Wother,
str->tag); _("symbol %s used more than once as a literal string"), str->tag);
else if (sym->alias) else if (sym->alias)
warn_at (loc, _("symbol %s given more than one literal string"), complain_at (loc, Wother,
sym->tag); _("symbol %s given more than one literal string"), sym->tag);
else else
{ {
str->class = token_sym; str->class = token_sym;
@@ -586,10 +587,10 @@ user_token_number_redeclaration (int num, symbol *first, symbol *second)
first = second; first = second;
second = tmp; second = tmp;
} }
complain_at (second->location, complain_at (second->location, complaint,
_("user token number %d redeclaration for %s"), _("user token number %d redeclaration for %s"),
num, second->tag); num, second->tag);
complain_at (first->location, _("previous declaration for %s"), complain_at (first->location, complaint, _("previous declaration for %s"),
first->tag); first->tag);
} }
@@ -610,10 +611,10 @@ symbol_translation (symbol *this)
(this->user_token_number, (this->user_token_number,
symbols[token_translations[this->user_token_number]], symbols[token_translations[this->user_token_number]],
this); this);
token_translations[this->user_token_number] = this->number; token_translations[this->user_token_number] = this->number;
} }
return true; return true;
} }
@@ -968,13 +969,13 @@ symbols_pack (void)
symbols_token_translations_init (); symbols_token_translations_init ();
if (startsymbol->class == unknown_sym) if (startsymbol->class == unknown_sym)
fatal_at (startsymbol_location, complain_at (startsymbol_location, fatal,
_("the start symbol %s is undefined"), _("the start symbol %s is undefined"),
startsymbol->tag); startsymbol->tag);
else if (startsymbol->class == token_sym) else if (startsymbol->class == token_sym)
fatal_at (startsymbol_location, complain_at (startsymbol_location, fatal,
_("the start symbol %s is a token"), _("the start symbol %s is a token"),
startsymbol->tag); startsymbol->tag);
} }
@@ -987,10 +988,10 @@ default_tagged_code_props_set (code_props_type kind, code_props const *code)
{ {
if (default_tagged_code_props[kind].code) if (default_tagged_code_props[kind].code)
{ {
complain_at (code->location, complain_at (code->location, complaint,
_("redeclaration for default tagged %s"), _("redeclaration for default tagged %s"),
code_props_type_string (kind)); code_props_type_string (kind));
complain_at (default_tagged_code_props[kind].location, complain_at (default_tagged_code_props[kind].location, complaint,
_("previous declaration")); _("previous declaration"));
} }
default_tagged_code_props[kind] = *code; default_tagged_code_props[kind] = *code;
@@ -1001,10 +1002,10 @@ default_tagless_code_props_set (code_props_type kind, code_props const *code)
{ {
if (default_tagless_code_props[kind].code) if (default_tagless_code_props[kind].code)
{ {
complain_at (code->location, complain_at (code->location, complaint,
_("redeclaration for default tagless %s"), _("redeclaration for default tagless %s"),
code_props_type_string (kind)); code_props_type_string (kind));
complain_at (default_tagless_code_props[kind].location, complain_at (default_tagless_code_props[kind].location, complaint,
_("previous declaration")); _("previous declaration"));
} }
default_tagless_code_props[kind] = *code; default_tagless_code_props[kind] = *code;