/* Declaration for error-reporting function for Bison. Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2009, 2010 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 the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Based on error.c and error.h, written by David MacKenzie . */ #include #include "system.h" #include #include "complain.h" #include "files.h" #include "getargs.h" bool complaint_issued; static unsigned *indent_ptr = 0; /** Report an error message. * * \param loc the location, defaulting to the current file, * or the program name. * \param prefix put before the message (e.g., "warning"). * \param message the error message, a printf format string. * \param args the arguments of the format string. */ static void error_message (location *loc, const char *prefix, const char *message, va_list args) { unsigned pos = 0; if (loc) pos += location_print (stderr, *loc); else pos += fprintf(stderr, "%s", current_file ? current_file : program_name); pos += fprintf(stderr, ": "); if (indent_ptr) { if (!*indent_ptr) *indent_ptr = pos; else if (*indent_ptr > pos) fprintf (stderr, "%*s", *indent_ptr - pos, ""); indent_ptr = 0; } if (prefix) fprintf (stderr, "%s: ", prefix); vfprintf (stderr, message, args); putc ('\n', stderr); fflush (stderr); } /** Wrap error_message() with varargs handling. */ #define ERROR_MESSAGE(Loc, Prefix, Message) \ { \ va_list args; \ va_start (args, Message); \ error_message (Loc, Prefix, Message, args); \ va_end (args); \ } /*--------------------------------. | Report a warning, and proceed. | `--------------------------------*/ static void set_warning_issued (void) { static bool warning_issued = false; if (!warning_issued && (warnings_flag & warnings_error)) { fprintf (stderr, "%s: warnings being treated as errors\n", program_name); complaint_issued = true; } warning_issued = true; } void warn_at (location loc, const char *message, ...) { set_warning_issued (); ERROR_MESSAGE (&loc, _("warning"), message); } void warn_at_indent (location loc, unsigned *indent, const char *message, ...) { set_warning_issued (); indent_ptr = indent; ERROR_MESSAGE (&loc, _("warning"), message); } void warn (const char *message, ...) { 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 & warnings_yacc) { 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); }