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