Home | History | Annotate | Line # | Download | only in libcpp
errors.cc revision 1.1
      1 /* Default error handlers for CPP Library.
      2    Copyright (C) 1986-2022 Free Software Foundation, Inc.
      3    Written by Per Bothner, 1994.
      4    Based on CCCP program by Paul Rubin, June 1986
      5    Adapted to ANSI C, Richard Stallman, Jan 1987
      6 
      7 This program is free software; you can redistribute it and/or modify it
      8 under the terms of the GNU General Public License as published by the
      9 Free Software Foundation; either version 3, or (at your option) any
     10 later version.
     11 
     12 This program is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with this program; see the file COPYING3.  If not see
     19 <http://www.gnu.org/licenses/>.
     20 
     21  In other words, you are welcome to use, share and improve this program.
     22  You are forbidden to forbid anyone else to use, share and improve
     23  what you give them.   Help stamp out software-hoarding!  */
     24 
     25 #include "config.h"
     26 #include "system.h"
     27 #include "cpplib.h"
     28 #include "internal.h"
     29 
     30 /* Get a location_t for the current location in PFILE,
     31    generally that of the previously lexed token.  */
     32 
     33 location_t
     34 cpp_diagnostic_get_current_location (cpp_reader *pfile)
     35 {
     36   if (CPP_OPTION (pfile, traditional))
     37     {
     38       if (pfile->state.in_directive)
     39 	return pfile->directive_line;
     40       else
     41 	return pfile->line_table->highest_line;
     42     }
     43   /* We don't want to refer to a token before the beginning of the
     44      current run -- that is invalid.  */
     45   else if (pfile->cur_token == pfile->cur_run->base)
     46     {
     47       return 0;
     48     }
     49   else
     50     {
     51       return pfile->cur_token[-1].src_loc;
     52     }
     53 }
     54 
     55 /* Print a diagnostic at the given location.  */
     56 
     57 ATTRIBUTE_FPTR_PRINTF(5,0)
     58 static bool
     59 cpp_diagnostic_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
     60 		   enum cpp_warning_reason reason, rich_location *richloc,
     61 		   const char *msgid, va_list *ap)
     62 {
     63   bool ret;
     64 
     65   if (!pfile->cb.diagnostic)
     66     abort ();
     67   ret = pfile->cb.diagnostic (pfile, level, reason, richloc, _(msgid), ap);
     68 
     69   return ret;
     70 }
     71 
     72 /* Print a diagnostic at the location of the previously lexed token.  */
     73 
     74 ATTRIBUTE_FPTR_PRINTF(4,0)
     75 static bool
     76 cpp_diagnostic (cpp_reader * pfile, enum cpp_diagnostic_level level,
     77 		enum cpp_warning_reason reason,
     78 		const char *msgid, va_list *ap)
     79 {
     80   location_t src_loc = cpp_diagnostic_get_current_location (pfile);
     81   rich_location richloc (pfile->line_table, src_loc);
     82   return cpp_diagnostic_at (pfile, level, reason, &richloc, msgid, ap);
     83 }
     84 
     85 /* Print a warning or error, depending on the value of LEVEL.  */
     86 
     87 bool
     88 cpp_error (cpp_reader * pfile, enum cpp_diagnostic_level level,
     89 	   const char *msgid, ...)
     90 {
     91   va_list ap;
     92   bool ret;
     93 
     94   va_start (ap, msgid);
     95 
     96   ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap);
     97 
     98   va_end (ap);
     99   return ret;
    100 }
    101 
    102 /* Print a warning.  The warning reason may be given in REASON.  */
    103 
    104 bool
    105 cpp_warning (cpp_reader * pfile, enum cpp_warning_reason reason,
    106 	     const char *msgid, ...)
    107 {
    108   va_list ap;
    109   bool ret;
    110 
    111   va_start (ap, msgid);
    112 
    113   ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap);
    114 
    115   va_end (ap);
    116   return ret;
    117 }
    118 
    119 /* Print a pedantic warning.  The warning reason may be given in REASON.  */
    120 
    121 bool
    122 cpp_pedwarning (cpp_reader * pfile, enum cpp_warning_reason reason,
    123 		const char *msgid, ...)
    124 {
    125   va_list ap;
    126   bool ret;
    127 
    128   va_start (ap, msgid);
    129 
    130   ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap);
    131 
    132   va_end (ap);
    133   return ret;
    134 }
    135 
    136 /* Print a warning, including system headers.  The warning reason may be
    137    given in REASON.  */
    138 
    139 bool
    140 cpp_warning_syshdr (cpp_reader * pfile, enum cpp_warning_reason reason,
    141 		    const char *msgid, ...)
    142 {
    143   va_list ap;
    144   bool ret;
    145 
    146   va_start (ap, msgid);
    147 
    148   ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap);
    149 
    150   va_end (ap);
    151   return ret;
    152 }
    153 
    154 /* As cpp_warning above, but use RICHLOC as the location of the diagnostic.  */
    155 
    156 bool cpp_warning_at (cpp_reader *pfile, enum cpp_warning_reason reason,
    157 		     rich_location *richloc, const char *msgid, ...)
    158 {
    159   va_list ap;
    160   bool ret;
    161 
    162   va_start (ap, msgid);
    163 
    164   ret = cpp_diagnostic_at (pfile, CPP_DL_WARNING, reason, richloc,
    165 			   msgid, &ap);
    166 
    167   va_end (ap);
    168   return ret;
    169 
    170 }
    171 
    172 /* As cpp_pedwarning above, but use RICHLOC as the location of the
    173    diagnostic.  */
    174 
    175 bool
    176 cpp_pedwarning_at (cpp_reader * pfile, enum cpp_warning_reason reason,
    177 		   rich_location *richloc, const char *msgid, ...)
    178 {
    179   va_list ap;
    180   bool ret;
    181 
    182   va_start (ap, msgid);
    183 
    184   ret = cpp_diagnostic_at (pfile, CPP_DL_PEDWARN, reason, richloc,
    185 			   msgid, &ap);
    186 
    187   va_end (ap);
    188   return ret;
    189 }
    190 
    191 /* Print a diagnostic at a specific location.  */
    192 
    193 ATTRIBUTE_FPTR_PRINTF(6,0)
    194 static bool
    195 cpp_diagnostic_with_line (cpp_reader * pfile, enum cpp_diagnostic_level level,
    196 			  enum cpp_warning_reason reason,
    197 			  location_t src_loc, unsigned int column,
    198 			  const char *msgid, va_list *ap)
    199 {
    200   bool ret;
    201 
    202   if (!pfile->cb.diagnostic)
    203     abort ();
    204   rich_location richloc (pfile->line_table, src_loc);
    205   if (column)
    206     richloc.override_column (column);
    207   ret = pfile->cb.diagnostic (pfile, level, reason, &richloc, _(msgid), ap);
    208 
    209   return ret;
    210 }
    211 
    212 /* Print a warning or error, depending on the value of LEVEL.  */
    213 
    214 bool
    215 cpp_error_with_line (cpp_reader *pfile, enum cpp_diagnostic_level level,
    216 		     location_t src_loc, unsigned int column,
    217 		     const char *msgid, ...)
    218 {
    219   va_list ap;
    220   bool ret;
    221 
    222   va_start (ap, msgid);
    223 
    224   ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc,
    225                                   column, msgid, &ap);
    226 
    227   va_end (ap);
    228   return ret;
    229 }
    230 
    231 /* Print a warning.  The warning reason may be given in REASON.  */
    232 
    233 bool
    234 cpp_warning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason,
    235 		       location_t src_loc, unsigned int column,
    236 		       const char *msgid, ...)
    237 {
    238   va_list ap;
    239   bool ret;
    240 
    241   va_start (ap, msgid);
    242 
    243   ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc,
    244                                   column, msgid, &ap);
    245 
    246   va_end (ap);
    247   return ret;
    248 }
    249 
    250 /* Print a pedantic warning.  The warning reason may be given in REASON.  */
    251 
    252 bool
    253 cpp_pedwarning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason,
    254 			  location_t src_loc, unsigned int column,
    255 			  const char *msgid, ...)
    256 {
    257   va_list ap;
    258   bool ret;
    259 
    260   va_start (ap, msgid);
    261 
    262   ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc,
    263                                   column, msgid, &ap);
    264 
    265   va_end (ap);
    266   return ret;
    267 }
    268 
    269 /* Print a warning, including system headers.  The warning reason may be
    270    given in REASON.  */
    271 
    272 bool
    273 cpp_warning_with_line_syshdr (cpp_reader *pfile, enum cpp_warning_reason reason,
    274 			      location_t src_loc, unsigned int column,
    275 			      const char *msgid, ...)
    276 {
    277   va_list ap;
    278   bool ret;
    279 
    280   va_start (ap, msgid);
    281 
    282   ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc,
    283                                   column, msgid, &ap);
    284 
    285   va_end (ap);
    286   return ret;
    287 }
    288 
    289 /* As cpp_error, but use SRC_LOC as the location of the error, without
    290    a column override.  */
    291 
    292 bool
    293 cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
    294 	      location_t src_loc, const char *msgid, ...)
    295 {
    296   va_list ap;
    297   bool ret;
    298 
    299   va_start (ap, msgid);
    300 
    301   rich_location richloc (pfile->line_table, src_loc);
    302   ret = cpp_diagnostic_at (pfile, level, CPP_W_NONE, &richloc,
    303 			   msgid, &ap);
    304 
    305   va_end (ap);
    306   return ret;
    307 }
    308 
    309 /* As cpp_error, but use RICHLOC as the location of the error, without
    310    a column override.  */
    311 
    312 bool
    313 cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
    314 	      rich_location *richloc, const char *msgid, ...)
    315 {
    316   va_list ap;
    317   bool ret;
    318 
    319   va_start (ap, msgid);
    320 
    321   ret = cpp_diagnostic_at (pfile, level, CPP_W_NONE, richloc,
    322 			   msgid, &ap);
    323 
    324   va_end (ap);
    325   return ret;
    326 }
    327 
    328 /* Print a warning or error, depending on the value of LEVEL.  Include
    329    information from errno.  */
    330 
    331 bool
    332 cpp_errno (cpp_reader *pfile, enum cpp_diagnostic_level level,
    333 	   const char *msgid)
    334 {
    335   return cpp_error (pfile, level, "%s: %s", _(msgid), xstrerror (errno));
    336 }
    337 
    338 /* Print a warning or error, depending on the value of LEVEL.  Include
    339    information from errno.  Unlike cpp_errno, the argument is a filename
    340    that is not localized, but "" is replaced with localized "stdout".  */
    341 
    342 bool
    343 cpp_errno_filename (cpp_reader *pfile, enum cpp_diagnostic_level level,
    344 		    const char *filename,
    345 		    location_t loc)
    346 {
    347   if (filename[0] == '\0')
    348     filename = _("stdout");
    349 
    350   return cpp_error_at (pfile, level, loc, "%s: %s", filename,
    351 		       xstrerror (errno));
    352 }
    353