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