1c7ca977eSAlexander Kabaev /* Default error handlers for CPP Library.
2c7ca977eSAlexander Kabaev Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000,
3c7ca977eSAlexander Kabaev 2001, 2002, 2004 Free Software Foundation, Inc.
4c7ca977eSAlexander Kabaev Written by Per Bothner, 1994.
5c7ca977eSAlexander Kabaev Based on CCCP program by Paul Rubin, June 1986
6c7ca977eSAlexander Kabaev Adapted to ANSI C, Richard Stallman, Jan 1987
7c7ca977eSAlexander Kabaev
8c7ca977eSAlexander Kabaev This program is free software; you can redistribute it and/or modify it
9c7ca977eSAlexander Kabaev under the terms of the GNU General Public License as published by the
10c7ca977eSAlexander Kabaev Free Software Foundation; either version 2, or (at your option) any
11c7ca977eSAlexander Kabaev later version.
12c7ca977eSAlexander Kabaev
13c7ca977eSAlexander Kabaev This program is distributed in the hope that it will be useful,
14c7ca977eSAlexander Kabaev but WITHOUT ANY WARRANTY; without even the implied warranty of
15c7ca977eSAlexander Kabaev MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16c7ca977eSAlexander Kabaev GNU General Public License for more details.
17c7ca977eSAlexander Kabaev
18c7ca977eSAlexander Kabaev You should have received a copy of the GNU General Public License
19c7ca977eSAlexander Kabaev along with this program; if not, write to the Free Software
20c7ca977eSAlexander Kabaev Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21c7ca977eSAlexander Kabaev
22c7ca977eSAlexander Kabaev In other words, you are welcome to use, share and improve this program.
23c7ca977eSAlexander Kabaev You are forbidden to forbid anyone else to use, share and improve
24c7ca977eSAlexander Kabaev what you give them. Help stamp out software-hoarding! */
25c7ca977eSAlexander Kabaev
26c7ca977eSAlexander Kabaev #include "config.h"
27c7ca977eSAlexander Kabaev #include "system.h"
28c7ca977eSAlexander Kabaev #include "cpplib.h"
29c7ca977eSAlexander Kabaev #include "internal.h"
30c7ca977eSAlexander Kabaev
31c7ca977eSAlexander Kabaev static void print_location (cpp_reader *, source_location, unsigned int);
32c7ca977eSAlexander Kabaev
33c7ca977eSAlexander Kabaev /* Print the logical file location (LINE, COL) in preparation for a
34c7ca977eSAlexander Kabaev diagnostic. Outputs the #include chain if it has changed. A line
35c7ca977eSAlexander Kabaev of zero suppresses the include stack, and outputs the program name
36c7ca977eSAlexander Kabaev instead. */
37c7ca977eSAlexander Kabaev static void
print_location(cpp_reader * pfile,source_location line,unsigned int col)38c7ca977eSAlexander Kabaev print_location (cpp_reader *pfile, source_location line, unsigned int col)
39c7ca977eSAlexander Kabaev {
40c7ca977eSAlexander Kabaev if (line == 0)
41c7ca977eSAlexander Kabaev fprintf (stderr, "%s: ", progname);
42c7ca977eSAlexander Kabaev else
43c7ca977eSAlexander Kabaev {
44c7ca977eSAlexander Kabaev const struct line_map *map;
45c7ca977eSAlexander Kabaev unsigned int lin;
46c7ca977eSAlexander Kabaev
47c7ca977eSAlexander Kabaev map = linemap_lookup (pfile->line_table, line);
48c7ca977eSAlexander Kabaev linemap_print_containing_files (pfile->line_table, map);
49c7ca977eSAlexander Kabaev
50c7ca977eSAlexander Kabaev lin = SOURCE_LINE (map, line);
51c7ca977eSAlexander Kabaev if (col == 0)
52c7ca977eSAlexander Kabaev {
53c7ca977eSAlexander Kabaev col = SOURCE_COLUMN (map, line);
54c7ca977eSAlexander Kabaev if (col == 0)
55c7ca977eSAlexander Kabaev col = 1;
56c7ca977eSAlexander Kabaev }
57c7ca977eSAlexander Kabaev
58c7ca977eSAlexander Kabaev if (lin == 0)
59c7ca977eSAlexander Kabaev fprintf (stderr, "%s:", map->to_file);
60c7ca977eSAlexander Kabaev else if (CPP_OPTION (pfile, show_column) == 0)
61c7ca977eSAlexander Kabaev fprintf (stderr, "%s:%u:", map->to_file, lin);
62c7ca977eSAlexander Kabaev else
63c7ca977eSAlexander Kabaev fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col);
64c7ca977eSAlexander Kabaev
65c7ca977eSAlexander Kabaev fputc (' ', stderr);
66c7ca977eSAlexander Kabaev }
67c7ca977eSAlexander Kabaev }
68c7ca977eSAlexander Kabaev
69c7ca977eSAlexander Kabaev /* Set up for a diagnostic: print the file and line, bump the error
70c7ca977eSAlexander Kabaev counter, etc. SRC_LOC is the logical line number; zero means to print
71c7ca977eSAlexander Kabaev at the location of the previously lexed token, which tends to be
72c7ca977eSAlexander Kabaev the correct place by default. The column number can be specified either
73c7ca977eSAlexander Kabaev using COLUMN or (if COLUMN==0) extracting SOURCE_COLUMN from SRC_LOC.
74c7ca977eSAlexander Kabaev (This may seem redundant, but is useful when pre-scanning (cleaning) a line,
75c7ca977eSAlexander Kabaev when we haven't yet verified whether the current line_map has a
76c7ca977eSAlexander Kabaev big enough max_column_hint.)
77c7ca977eSAlexander Kabaev
78c7ca977eSAlexander Kabaev Returns 0 if the error has been suppressed. */
79c7ca977eSAlexander Kabaev int
_cpp_begin_message(cpp_reader * pfile,int code,source_location src_loc,unsigned int column)80c7ca977eSAlexander Kabaev _cpp_begin_message (cpp_reader *pfile, int code,
81c7ca977eSAlexander Kabaev source_location src_loc, unsigned int column)
82c7ca977eSAlexander Kabaev {
83c7ca977eSAlexander Kabaev int level = CPP_DL_EXTRACT (code);
84c7ca977eSAlexander Kabaev
85c7ca977eSAlexander Kabaev switch (level)
86c7ca977eSAlexander Kabaev {
87c7ca977eSAlexander Kabaev case CPP_DL_WARNING:
88c7ca977eSAlexander Kabaev case CPP_DL_PEDWARN:
89c7ca977eSAlexander Kabaev if (cpp_in_system_header (pfile)
90c7ca977eSAlexander Kabaev && ! CPP_OPTION (pfile, warn_system_headers))
91c7ca977eSAlexander Kabaev return 0;
92c7ca977eSAlexander Kabaev /* Fall through. */
93c7ca977eSAlexander Kabaev
94c7ca977eSAlexander Kabaev case CPP_DL_WARNING_SYSHDR:
95c7ca977eSAlexander Kabaev if (CPP_OPTION (pfile, warnings_are_errors)
96c7ca977eSAlexander Kabaev || (level == CPP_DL_PEDWARN && CPP_OPTION (pfile, pedantic_errors)))
97c7ca977eSAlexander Kabaev {
98c7ca977eSAlexander Kabaev if (CPP_OPTION (pfile, inhibit_errors))
99c7ca977eSAlexander Kabaev return 0;
100c7ca977eSAlexander Kabaev level = CPP_DL_ERROR;
101c7ca977eSAlexander Kabaev pfile->errors++;
102c7ca977eSAlexander Kabaev }
103c7ca977eSAlexander Kabaev else if (CPP_OPTION (pfile, inhibit_warnings))
104c7ca977eSAlexander Kabaev return 0;
105c7ca977eSAlexander Kabaev break;
106c7ca977eSAlexander Kabaev
107c7ca977eSAlexander Kabaev case CPP_DL_ERROR:
108c7ca977eSAlexander Kabaev if (CPP_OPTION (pfile, inhibit_errors))
109c7ca977eSAlexander Kabaev return 0;
110c7ca977eSAlexander Kabaev /* ICEs cannot be inhibited. */
111c7ca977eSAlexander Kabaev case CPP_DL_ICE:
112c7ca977eSAlexander Kabaev pfile->errors++;
113c7ca977eSAlexander Kabaev break;
114c7ca977eSAlexander Kabaev }
115c7ca977eSAlexander Kabaev
116c7ca977eSAlexander Kabaev print_location (pfile, src_loc, column);
117c7ca977eSAlexander Kabaev if (CPP_DL_WARNING_P (level))
118c7ca977eSAlexander Kabaev fputs (_("warning: "), stderr);
119c7ca977eSAlexander Kabaev else if (level == CPP_DL_ICE)
120c7ca977eSAlexander Kabaev fputs (_("internal error: "), stderr);
121c7ca977eSAlexander Kabaev else
122c7ca977eSAlexander Kabaev fputs (_("error: "), stderr);
123c7ca977eSAlexander Kabaev
124c7ca977eSAlexander Kabaev return 1;
125c7ca977eSAlexander Kabaev }
126c7ca977eSAlexander Kabaev
127c7ca977eSAlexander Kabaev /* Don't remove the blank before do, as otherwise the exgettext
128c7ca977eSAlexander Kabaev script will mistake this as a function definition */
129c7ca977eSAlexander Kabaev #define v_message(msgid, ap) \
130c7ca977eSAlexander Kabaev do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0)
131c7ca977eSAlexander Kabaev
132c7ca977eSAlexander Kabaev /* Exported interface. */
133c7ca977eSAlexander Kabaev
134c7ca977eSAlexander Kabaev /* Print an error at the location of the previously lexed token. */
135c7ca977eSAlexander Kabaev void
cpp_error(cpp_reader * pfile,int level,const char * msgid,...)136c7ca977eSAlexander Kabaev cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
137c7ca977eSAlexander Kabaev {
138c7ca977eSAlexander Kabaev source_location src_loc;
139c7ca977eSAlexander Kabaev va_list ap;
140c7ca977eSAlexander Kabaev
141c7ca977eSAlexander Kabaev va_start (ap, msgid);
142c7ca977eSAlexander Kabaev
143c7ca977eSAlexander Kabaev if (CPP_OPTION (pfile, client_diagnostic))
144c7ca977eSAlexander Kabaev pfile->cb.error (pfile, level, _(msgid), &ap);
145c7ca977eSAlexander Kabaev else
146c7ca977eSAlexander Kabaev {
147c7ca977eSAlexander Kabaev if (CPP_OPTION (pfile, traditional))
148c7ca977eSAlexander Kabaev {
149c7ca977eSAlexander Kabaev if (pfile->state.in_directive)
150c7ca977eSAlexander Kabaev src_loc = pfile->directive_line;
151c7ca977eSAlexander Kabaev else
152c7ca977eSAlexander Kabaev src_loc = pfile->line_table->highest_line;
153c7ca977eSAlexander Kabaev }
154c7ca977eSAlexander Kabaev else
155c7ca977eSAlexander Kabaev {
156*9b76499aSMatthew D Fleming /* Find actual previous token. */
157*9b76499aSMatthew D Fleming cpp_token *t;
158*9b76499aSMatthew D Fleming
159*9b76499aSMatthew D Fleming if (pfile->cur_token != pfile->cur_run->base)
160*9b76499aSMatthew D Fleming t = pfile->cur_token - 1;
161*9b76499aSMatthew D Fleming else
162*9b76499aSMatthew D Fleming {
163*9b76499aSMatthew D Fleming if (pfile->cur_run->prev != NULL)
164*9b76499aSMatthew D Fleming t = pfile->cur_run->prev->limit;
165*9b76499aSMatthew D Fleming else
166*9b76499aSMatthew D Fleming t = NULL;
167*9b76499aSMatthew D Fleming }
168*9b76499aSMatthew D Fleming /* Retrieve corresponding source location, unless we failed. */
169*9b76499aSMatthew D Fleming src_loc = t ? t->src_loc : 0;
170c7ca977eSAlexander Kabaev }
171c7ca977eSAlexander Kabaev
172c7ca977eSAlexander Kabaev if (_cpp_begin_message (pfile, level, src_loc, 0))
173c7ca977eSAlexander Kabaev v_message (msgid, ap);
174c7ca977eSAlexander Kabaev }
175c7ca977eSAlexander Kabaev
176c7ca977eSAlexander Kabaev va_end (ap);
177c7ca977eSAlexander Kabaev }
178c7ca977eSAlexander Kabaev
179c7ca977eSAlexander Kabaev /* Print an error at a specific location. */
180c7ca977eSAlexander Kabaev void
cpp_error_with_line(cpp_reader * pfile,int level,source_location src_loc,unsigned int column,const char * msgid,...)181c7ca977eSAlexander Kabaev cpp_error_with_line (cpp_reader *pfile, int level,
182c7ca977eSAlexander Kabaev source_location src_loc, unsigned int column,
183c7ca977eSAlexander Kabaev const char *msgid, ...)
184c7ca977eSAlexander Kabaev {
185c7ca977eSAlexander Kabaev va_list ap;
186c7ca977eSAlexander Kabaev
187c7ca977eSAlexander Kabaev va_start (ap, msgid);
188c7ca977eSAlexander Kabaev
189c7ca977eSAlexander Kabaev if (_cpp_begin_message (pfile, level, src_loc, column))
190c7ca977eSAlexander Kabaev v_message (msgid, ap);
191c7ca977eSAlexander Kabaev
192c7ca977eSAlexander Kabaev va_end (ap);
193c7ca977eSAlexander Kabaev }
194c7ca977eSAlexander Kabaev
195c7ca977eSAlexander Kabaev void
cpp_errno(cpp_reader * pfile,int level,const char * msgid)196c7ca977eSAlexander Kabaev cpp_errno (cpp_reader *pfile, int level, const char *msgid)
197c7ca977eSAlexander Kabaev {
198c7ca977eSAlexander Kabaev if (msgid[0] == '\0')
199c7ca977eSAlexander Kabaev msgid = _("stdout");
200c7ca977eSAlexander Kabaev
201c7ca977eSAlexander Kabaev cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno));
202c7ca977eSAlexander Kabaev }
203