1/* Default error handlers for CPP Library.
2   Copyright (C) 1986-2015 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/* Print a diagnostic at the location of the previously lexed token.  */
31
32ATTRIBUTE_FPTR_PRINTF(4,0)
33static bool
34cpp_diagnostic (cpp_reader * pfile, int level, int reason,
35                const char *msgid, va_list *ap)
36{
37  source_location src_loc;
38  bool ret;
39
40  if (CPP_OPTION (pfile, traditional))
41    {
42      if (pfile->state.in_directive)
43	src_loc = pfile->directive_line;
44      else
45	src_loc = pfile->line_table->highest_line;
46    }
47  /* We don't want to refer to a token before the beginning of the
48     current run -- that is invalid.  */
49  else if (pfile->cur_token == pfile->cur_run->base)
50    {
51      src_loc = 0;
52    }
53  else
54    {
55      src_loc = pfile->cur_token[-1].src_loc;
56    }
57
58  if (!pfile->cb.error)
59    abort ();
60  ret = pfile->cb.error (pfile, level, reason, src_loc, 0, _(msgid), ap);
61
62  return ret;
63}
64
65/* Print a warning or error, depending on the value of LEVEL.  */
66
67bool
68cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
69{
70  va_list ap;
71  bool ret;
72
73  va_start (ap, msgid);
74
75  ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap);
76
77  va_end (ap);
78  return ret;
79}
80
81/* Print a warning.  The warning reason may be given in REASON.  */
82
83bool
84cpp_warning (cpp_reader * pfile, int reason, const char *msgid, ...)
85{
86  va_list ap;
87  bool ret;
88
89  va_start (ap, msgid);
90
91  ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap);
92
93  va_end (ap);
94  return ret;
95}
96
97/* Print a pedantic warning.  The warning reason may be given in REASON.  */
98
99bool
100cpp_pedwarning (cpp_reader * pfile, int reason, const char *msgid, ...)
101{
102  va_list ap;
103  bool ret;
104
105  va_start (ap, msgid);
106
107  ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap);
108
109  va_end (ap);
110  return ret;
111}
112
113/* Print a warning, including system headers.  The warning reason may be
114   given in REASON.  */
115
116bool
117cpp_warning_syshdr (cpp_reader * pfile, int reason, const char *msgid, ...)
118{
119  va_list ap;
120  bool ret;
121
122  va_start (ap, msgid);
123
124  ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap);
125
126  va_end (ap);
127  return ret;
128}
129
130/* Print a diagnostic at a specific location.  */
131
132ATTRIBUTE_FPTR_PRINTF(6,0)
133static bool
134cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason,
135		          source_location src_loc, unsigned int column,
136		          const char *msgid, va_list *ap)
137{
138  bool ret;
139
140  if (!pfile->cb.error)
141    abort ();
142  ret = pfile->cb.error (pfile, level, reason, src_loc, column, _(msgid), ap);
143
144  return ret;
145}
146
147/* Print a warning or error, depending on the value of LEVEL.  */
148
149bool
150cpp_error_with_line (cpp_reader *pfile, int level,
151		     source_location src_loc, unsigned int column,
152		     const char *msgid, ...)
153{
154  va_list ap;
155  bool ret;
156
157  va_start (ap, msgid);
158
159  ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc,
160                                  column, msgid, &ap);
161
162  va_end (ap);
163  return ret;
164}
165
166/* Print a warning.  The warning reason may be given in REASON.  */
167
168bool
169cpp_warning_with_line (cpp_reader *pfile, int reason,
170		       source_location src_loc, unsigned int column,
171		       const char *msgid, ...)
172{
173  va_list ap;
174  bool ret;
175
176  va_start (ap, msgid);
177
178  ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc,
179                                  column, msgid, &ap);
180
181  va_end (ap);
182  return ret;
183}
184
185/* Print a pedantic warning.  The warning reason may be given in REASON.  */
186
187bool
188cpp_pedwarning_with_line (cpp_reader *pfile, int reason,
189		          source_location src_loc, unsigned int column,
190		          const char *msgid, ...)
191{
192  va_list ap;
193  bool ret;
194
195  va_start (ap, msgid);
196
197  ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc,
198                                  column, msgid, &ap);
199
200  va_end (ap);
201  return ret;
202}
203
204/* Print a warning, including system headers.  The warning reason may be
205   given in REASON.  */
206
207bool
208cpp_warning_with_line_syshdr (cpp_reader *pfile, int reason,
209		              source_location src_loc, unsigned int column,
210		              const char *msgid, ...)
211{
212  va_list ap;
213  bool ret;
214
215  va_start (ap, msgid);
216
217  ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc,
218                                  column, msgid, &ap);
219
220  va_end (ap);
221  return ret;
222}
223
224/* Print a warning or error, depending on the value of LEVEL.  Include
225   information from errno.  */
226
227bool
228cpp_errno (cpp_reader *pfile, int level, const char *msgid)
229{
230  return cpp_error (pfile, level, "%s: %s", _(msgid), xstrerror (errno));
231}
232
233/* Print a warning or error, depending on the value of LEVEL.  Include
234   information from errno.  Unlike cpp_errno, the argument is a filename
235   that is not localized, but "" is replaced with localized "stdout".  */
236
237bool
238cpp_errno_filename (cpp_reader *pfile, int level, const char *filename)
239{
240  if (filename[0] == '\0')
241    filename = _("stdout");
242
243  return cpp_error (pfile, level, "%s: %s", filename, xstrerror (errno));
244}
245