1/* Default error handlers for CPP Library.
2 Copyright (C) 1986-2025 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
7This program is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by the
9Free Software Foundation; either version 3, or (at your option) any
10later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
33location_t
34cpp_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/* Sometimes a diagnostic needs to be generated before libcpp has been able
56 to generate a valid location for the current token; in that case, the
57 non-zero location returned by this function is the preferred one to use. */
58
59location_t
60cpp_get_diagnostic_override_loc (const cpp_reader *pfile)
61{
62 return pfile->diagnostic_override_loc;
63}
64
65/* Print a diagnostic at the given location. */
66
67ATTRIBUTE_CPP_PPDIAG (5, 0)
68static bool
69cpp_diagnostic_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
70 enum cpp_warning_reason reason, rich_location *richloc,
71 const char *msgid, va_list *ap)
72{
73 if (!pfile->cb.diagnostic)
74 abort ();
75 if (pfile->diagnostic_override_loc && level != CPP_DL_NOTE)
76 {
77 rich_location rc2{pfile->line_table, pfile->diagnostic_override_loc};
78 rc2.set_escape_on_output (richloc->escape_on_output_p ());
79 return pfile->cb.diagnostic (pfile, level, reason, &rc2, _(msgid), ap);
80 }
81 return pfile->cb.diagnostic (pfile, level, reason, richloc, _(msgid), ap);
82}
83
84/* Print a diagnostic at the location of the previously lexed token. */
85
86ATTRIBUTE_CPP_PPDIAG (4, 0)
87static bool
88cpp_diagnostic (cpp_reader * pfile, enum cpp_diagnostic_level level,
89 enum cpp_warning_reason reason,
90 const char *msgid, va_list *ap)
91{
92 location_t src_loc = cpp_diagnostic_get_current_location (pfile);
93 rich_location richloc (pfile->line_table, src_loc);
94 return cpp_diagnostic_at (pfile, level, reason, richloc: &richloc, msgid, ap);
95}
96
97/* Print a warning or error, depending on the value of LEVEL. */
98
99bool
100cpp_error (cpp_reader * pfile, enum cpp_diagnostic_level level,
101 const char *msgid, ...)
102{
103 va_list ap;
104 bool ret;
105
106 va_start (ap, msgid);
107
108 ret = cpp_diagnostic (pfile, level, reason: CPP_W_NONE, msgid, ap: &ap);
109
110 va_end (ap);
111 return ret;
112}
113
114/* Print a warning. The warning reason may be given in REASON. */
115
116bool
117cpp_warning (cpp_reader * pfile, enum cpp_warning_reason reason,
118 const char *msgid, ...)
119{
120 va_list ap;
121 bool ret;
122
123 va_start (ap, msgid);
124
125 ret = cpp_diagnostic (pfile, level: CPP_DL_WARNING, reason, msgid, ap: &ap);
126
127 va_end (ap);
128 return ret;
129}
130
131/* Print a pedantic warning. The warning reason may be given in REASON. */
132
133bool
134cpp_pedwarning (cpp_reader * pfile, enum cpp_warning_reason reason,
135 const char *msgid, ...)
136{
137 va_list ap;
138 bool ret;
139
140 va_start (ap, msgid);
141
142 ret = cpp_diagnostic (pfile, level: CPP_DL_PEDWARN, reason, msgid, ap: &ap);
143
144 va_end (ap);
145 return ret;
146}
147
148/* Print a warning, including system headers. The warning reason may be
149 given in REASON. */
150
151bool
152cpp_warning_syshdr (cpp_reader * pfile, enum cpp_warning_reason reason,
153 const char *msgid, ...)
154{
155 va_list ap;
156 bool ret;
157
158 va_start (ap, msgid);
159
160 ret = cpp_diagnostic (pfile, level: CPP_DL_WARNING_SYSHDR, reason, msgid, ap: &ap);
161
162 va_end (ap);
163 return ret;
164}
165
166/* As cpp_warning above, but use RICHLOC as the location of the diagnostic. */
167
168bool cpp_warning_at (cpp_reader *pfile, enum cpp_warning_reason reason,
169 rich_location *richloc, const char *msgid, ...)
170{
171 va_list ap;
172 bool ret;
173
174 va_start (ap, msgid);
175
176 ret = cpp_diagnostic_at (pfile, level: CPP_DL_WARNING, reason, richloc,
177 msgid, ap: &ap);
178
179 va_end (ap);
180 return ret;
181
182}
183
184/* As cpp_pedwarning above, but use RICHLOC as the location of the
185 diagnostic. */
186
187bool
188cpp_pedwarning_at (cpp_reader * pfile, enum cpp_warning_reason reason,
189 rich_location *richloc, const char *msgid, ...)
190{
191 va_list ap;
192 bool ret;
193
194 va_start (ap, msgid);
195
196 ret = cpp_diagnostic_at (pfile, level: CPP_DL_PEDWARN, reason, richloc,
197 msgid, ap: &ap);
198
199 va_end (ap);
200 return ret;
201}
202
203/* Print a diagnostic at a specific location. */
204
205ATTRIBUTE_CPP_PPDIAG (6, 0)
206static bool
207cpp_diagnostic_with_line (cpp_reader * pfile, enum cpp_diagnostic_level level,
208 enum cpp_warning_reason reason,
209 location_t src_loc, unsigned int column,
210 const char *msgid, va_list *ap)
211{
212 bool ret;
213
214 if (!pfile->cb.diagnostic)
215 abort ();
216 /* Don't override note locations, which will likely make the note
217 more confusing. */
218 const bool do_loc_override
219 = pfile->diagnostic_override_loc && level != CPP_DL_NOTE;
220 if (do_loc_override)
221 src_loc = pfile->diagnostic_override_loc;
222 rich_location richloc (pfile->line_table, src_loc);
223 if (column && !do_loc_override)
224 richloc.override_column (column);
225 ret = pfile->cb.diagnostic (pfile, level, reason, &richloc, _(msgid), ap);
226
227 return ret;
228}
229
230/* Print a warning or error, depending on the value of LEVEL. */
231
232bool
233cpp_error_with_line (cpp_reader *pfile, enum cpp_diagnostic_level level,
234 location_t src_loc, unsigned int column,
235 const char *msgid, ...)
236{
237 va_list ap;
238 bool ret;
239
240 va_start (ap, msgid);
241
242 ret = cpp_diagnostic_with_line (pfile, level, reason: CPP_W_NONE, src_loc,
243 column, msgid, ap: &ap);
244
245 va_end (ap);
246 return ret;
247}
248
249/* Print a warning. The warning reason may be given in REASON. */
250
251bool
252cpp_warning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason,
253 location_t src_loc, unsigned int column,
254 const char *msgid, ...)
255{
256 va_list ap;
257 bool ret;
258
259 va_start (ap, msgid);
260
261 ret = cpp_diagnostic_with_line (pfile, level: CPP_DL_WARNING, reason, src_loc,
262 column, msgid, ap: &ap);
263
264 va_end (ap);
265 return ret;
266}
267
268/* Print a pedantic warning. The warning reason may be given in REASON. */
269
270bool
271cpp_pedwarning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason,
272 location_t src_loc, unsigned int column,
273 const char *msgid, ...)
274{
275 va_list ap;
276 bool ret;
277
278 va_start (ap, msgid);
279
280 ret = cpp_diagnostic_with_line (pfile, level: CPP_DL_PEDWARN, reason, src_loc,
281 column, msgid, ap: &ap);
282
283 va_end (ap);
284 return ret;
285}
286
287/* Print a warning, including system headers. The warning reason may be
288 given in REASON. */
289
290bool
291cpp_warning_with_line_syshdr (cpp_reader *pfile, enum cpp_warning_reason reason,
292 location_t src_loc, unsigned int column,
293 const char *msgid, ...)
294{
295 va_list ap;
296 bool ret;
297
298 va_start (ap, msgid);
299
300 ret = cpp_diagnostic_with_line (pfile, level: CPP_DL_WARNING_SYSHDR, reason, src_loc,
301 column, msgid, ap: &ap);
302
303 va_end (ap);
304 return ret;
305}
306
307/* As cpp_error, but use SRC_LOC as the location of the error, without
308 a column override. */
309
310bool
311cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
312 location_t src_loc, const char *msgid, ...)
313{
314 va_list ap;
315 bool ret;
316
317 va_start (ap, msgid);
318
319 rich_location richloc (pfile->line_table, src_loc);
320 ret = cpp_diagnostic_at (pfile, level, reason: CPP_W_NONE, richloc: &richloc,
321 msgid, ap: &ap);
322
323 va_end (ap);
324 return ret;
325}
326
327/* As cpp_error, but use RICHLOC as the location of the error, without
328 a column override. */
329
330bool
331cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level,
332 rich_location *richloc, const char *msgid, ...)
333{
334 va_list ap;
335 bool ret;
336
337 va_start (ap, msgid);
338
339 ret = cpp_diagnostic_at (pfile, level, reason: CPP_W_NONE, richloc,
340 msgid, ap: &ap);
341
342 va_end (ap);
343 return ret;
344}
345
346/* Print a warning or error, depending on the value of LEVEL. Include
347 information from errno. */
348
349bool
350cpp_errno (cpp_reader *pfile, enum cpp_diagnostic_level level,
351 const char *msgid)
352{
353 return cpp_error (pfile, level, msgid: "%s: %s", _(msgid), xstrerror (errno));
354}
355
356/* Print a warning or error, depending on the value of LEVEL. Include
357 information from errno. Unlike cpp_errno, the argument is a filename
358 that is not localized, but "" is replaced with localized "stdout". */
359
360bool
361cpp_errno_filename (cpp_reader *pfile, enum cpp_diagnostic_level level,
362 const char *filename,
363 location_t loc)
364{
365 if (filename[0] == '\0')
366 filename = _("stdout");
367
368 return cpp_error_at (pfile, level, src_loc: loc, msgid: "%s: %s", filename,
369 xstrerror (errno));
370}
371
372cpp_auto_suppress_diagnostics::cpp_auto_suppress_diagnostics (cpp_reader *pfile)
373 : m_pfile (pfile), m_cb (pfile->cb.diagnostic)
374{
375 m_pfile->cb.diagnostic
376 = [] (cpp_reader *, cpp_diagnostic_level, cpp_warning_reason,
377 rich_location *, const char *, va_list *)
378 {
379 return true;
380 };
381}
382
383cpp_auto_suppress_diagnostics::~cpp_auto_suppress_diagnostics ()
384{
385 m_pfile->cb.diagnostic = m_cb;
386}
387

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of libcpp/errors.cc