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