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