Home | History | Annotate | Download | only in src
      1 /* Declaration for error-reporting function for Bison.
      2 
      3    Copyright (C) 2000-2002, 2004-2006, 2009-2012 Free Software
      4    Foundation, Inc.
      5 
      6    This program is free software: you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation, either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18 
     19 /* Based on error.c and error.h,
     20    written by David MacKenzie <djm (at) gnu.ai.mit.edu>.  */
     21 
     22 #include <config.h>
     23 #include "system.h"
     24 
     25 #include <stdarg.h>
     26 #include <progname.h>
     27 
     28 #include "complain.h"
     29 #include "files.h"
     30 #include "getargs.h"
     31 
     32 bool complaint_issued;
     33 static unsigned *indent_ptr = 0;
     34 
     35 
     36 
     38 /** Report an error message.
     39  *
     40  * \param loc     the location, defaulting to the current file,
     41  *                or the program name.
     42  * \param prefix  put before the message (e.g., "warning").
     43  * \param message the error message, a printf format string.  Iff it
     44  *                ends with ": ", then no trailing newline is printed,
     45  *                and the caller should print the remaining
     46  *                newline-terminated message to stderr.
     47  * \param args    the arguments of the format string.
     48  */
     49 static
     50 void
     51 error_message (location *loc,
     52 	       const char *prefix,
     53 	       const char *message, va_list args)
     54 {
     55   unsigned pos = 0;
     56 
     57   if (loc)
     58     pos += location_print (stderr, *loc);
     59   else
     60     pos += fprintf(stderr, "%s", current_file ? current_file : program_name);
     61   pos += fprintf(stderr, ": ");
     62 
     63   if (indent_ptr)
     64     {
     65       if (!*indent_ptr)
     66         *indent_ptr = pos;
     67       else if (*indent_ptr > pos)
     68         fprintf (stderr, "%*s", *indent_ptr - pos, "");
     69       indent_ptr = 0;
     70     }
     71 
     72   if (prefix)
     73     fprintf (stderr, "%s: ", prefix);
     74 
     75   vfprintf (stderr, message, args);
     76   {
     77     size_t l = strlen (message);
     78     if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
     79       {
     80         putc ('\n', stderr);
     81         fflush (stderr);
     82         if (loc && feature_flag & feature_caret)
     83           location_caret (stderr, *loc);
     84       }
     85   }
     86   fflush (stderr);
     87 }
     88 
     89 /** Wrap error_message() with varargs handling. */
     90 #define ERROR_MESSAGE(Loc, Prefix, Message)	\
     91 {						\
     92   va_list args;					\
     93   va_start (args, Message);			\
     94   error_message (Loc, Prefix, Message, args);	\
     95   va_end (args);				\
     96 }
     97 
     98 
     99 /*--------------------------------.
    100 | Report a warning, and proceed.  |
    101 `--------------------------------*/
    102 
    103 void
    104 set_warning_issued (void)
    105 {
    106   static bool warning_issued = false;
    107   if (!warning_issued && (warnings_flag & warnings_error))
    108     {
    109       fprintf (stderr, "%s: warnings being treated as errors\n", program_name);
    110       complaint_issued = true;
    111     }
    112   warning_issued = true;
    113 }
    114 
    115 void
    116 warn_at (location loc, const char *message, ...)
    117 {
    118   if (!(warnings_flag & warnings_other))
    119     return;
    120   set_warning_issued ();
    121   ERROR_MESSAGE (&loc, _("warning"), message);
    122 }
    123 
    124 void
    125 warn_at_indent (location loc, unsigned *indent,
    126                 const char *message, ...)
    127 {
    128   if (!(warnings_flag & warnings_other))
    129     return;
    130   set_warning_issued ();
    131   indent_ptr = indent;
    132   ERROR_MESSAGE (&loc, *indent ? NULL : _("warning"), message);
    133 }
    134 
    135 void
    136 warn (const char *message, ...)
    137 {
    138   if (!(warnings_flag & warnings_other))
    139     return;
    140   set_warning_issued ();
    141   ERROR_MESSAGE (NULL, _("warning"), message);
    142 }
    143 
    144 
    145 /*-----------------------------------------------------------.
    146 | An error has occurred, but we can proceed, and die later.  |
    147 `-----------------------------------------------------------*/
    148 
    149 void
    150 complain_at (location loc, const char *message, ...)
    151 {
    152   ERROR_MESSAGE (&loc, _("error"), message);
    153   complaint_issued = true;
    154 }
    155 
    156 void
    157 complain_at_indent (location loc, unsigned *indent,
    158                     const char *message, ...)
    159 {
    160   indent_ptr = indent;
    161   ERROR_MESSAGE (&loc, *indent ? NULL : _("error"), message);
    162   complaint_issued = true;
    163 }
    164 
    165 void
    166 complain (const char *message, ...)
    167 {
    168   ERROR_MESSAGE (NULL, _("error"), message);
    169   complaint_issued = true;
    170 }
    171 
    172 
    173 /*--------------------------------------------------------------.
    174 | An incompatibility with POSIX Yacc: mapped either to warn* or |
    175 | complain* depending on yacc_flag.                             |
    176 `--------------------------------------------------------------*/
    177 
    178 void
    179 yacc_at (location loc, const char *message, ...)
    180 {
    181   if (yacc_flag)
    182     {
    183       ERROR_MESSAGE (&loc, NULL, message);
    184       complaint_issued = true;
    185     }
    186   else if (warnings_flag & warnings_yacc)
    187     {
    188       set_warning_issued ();
    189       ERROR_MESSAGE (&loc, _("warning"), message);
    190     }
    191 }
    192 
    193 void
    194 midrule_value_at (location loc, const char *message, ...)
    195 {
    196   if (!(warnings_flag & warnings_midrule_values))
    197     return;
    198   set_warning_issued ();
    199   ERROR_MESSAGE (&loc, _("warning"), message);
    200 }
    201 
    202 /*-------------------------------------------------.
    203 | A severe error has occurred, we cannot proceed.  |
    204 `-------------------------------------------------*/
    205 
    206 void
    207 fatal_at (location loc, const char *message, ...)
    208 {
    209   ERROR_MESSAGE (&loc, _("fatal error"), message);
    210   exit (EXIT_FAILURE);
    211 }
    212 
    213 void
    214 fatal (const char *message, ...)
    215 {
    216   ERROR_MESSAGE (NULL, _("fatal error"), message);
    217   exit (EXIT_FAILURE);
    218 }
    219