]> git.saurik.com Git - bison.git/blob - src/complain.c
(yyparse): Don't take the address of an item before the start of an
[bison.git] / src / complain.c
1 /* Declaration for error-reporting function for Bison.
2 Copyright 2000 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA. */
18
19 /* Based on error.c and error.h,
20 written by David MacKenzie <djm@gnu.ai.mit.edu>. */
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <stdio.h>
27
28 #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC
29 # if __STDC__
30 # include <stdarg.h>
31 # define VA_START(args, lastarg) va_start(args, lastarg)
32 # else
33 # include <varargs.h>
34 # define VA_START(args, lastarg) va_start(args)
35 # endif
36 #else
37 # define va_alist a1, a2, a3, a4, a5, a6, a7, a8
38 # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
39 #endif
40
41 #if STDC_HEADERS || _LIBC
42 # include <stdlib.h>
43 # include <string.h>
44 #else
45 void exit ();
46 #endif
47
48 #include "complain.h"
49
50 #ifndef HAVE_DECL_STRERROR_R
51 "this configure-time declaration test was not run"
52 #endif
53 #if !HAVE_DECL_STRERROR_R
54 char *strerror_r ();
55 #endif
56
57 #ifndef _
58 # define _(String) String
59 #endif
60
61 #ifdef _LIBC
62 /* In the GNU C library, there is a predefined variable for this. */
63
64 # define program_name program_invocation_name
65 # include <errno.h>
66
67 /* In GNU libc we want do not want to use the common name `error' directly.
68 Instead make it a weak alias. */
69 # define error __error
70 # define error_at_line __error_at_line
71
72 # ifdef USE_IN_LIBIO
73 # include <libio/iolibio.h>
74 # define fflush(s) _IO_fflush (s)
75 # endif
76
77 #else /* not _LIBC */
78
79 /* The calling program should define program_name and set it to the
80 name of the executing program. */
81 extern char *program_name;
82
83 # ifdef HAVE_STRERROR_R
84 # define __strerror_r strerror_r
85 # else
86 # if HAVE_STRERROR
87 # ifndef strerror /* On some systems, strerror is a macro */
88 char *strerror ();
89 # endif
90 # else
91 static char *
92 private_strerror (errnum)
93 int errnum;
94 {
95 extern char *sys_errlist[];
96 extern int sys_nerr;
97
98 if (errnum > 0 && errnum <= sys_nerr)
99 return _(sys_errlist[errnum]);
100 return _("Unknown system error");
101 }
102 # define strerror private_strerror
103 # endif /* HAVE_STRERROR */
104 # endif /* HAVE_STRERROR_R */
105 #endif /* not _LIBC */
106
107 /* This variable is incremented each time `warn' is called. */
108 unsigned int warn_message_count;
109
110 /* This variable is incremented each time `complain' is called. */
111 unsigned int complain_message_count;
112
113 /* Sometimes we want to have at most one error per line. This
114 variable controls whether this mode is selected or not. */
115 int error_one_per_line;
116 \f
117 /*--------------------------------.
118 | Report a warning, and proceed. |
119 `--------------------------------*/
120
121 void
122 #if defined VA_START && __STDC__
123 warn (const char *message, ...)
124 #else
125 warn (message, va_alist)
126 char *message;
127 va_dcl
128 #endif
129 {
130 #ifdef VA_START
131 va_list args;
132 #endif
133
134 if (error_one_per_line)
135 {
136 static const char *old_infile;
137 static int old_lineno;
138
139 if (old_lineno == lineno &&
140 (infile == old_infile || !strcmp (old_infile, infile)))
141 /* Simply return and print nothing. */
142 return;
143
144 old_infile = infile;
145 old_lineno = lineno;
146 }
147
148 fflush (stdout);
149 if (infile != NULL)
150 fprintf (stderr, "%s:%d: ", infile, lineno);
151 else
152 fprintf (stderr, "%s:", program_name);
153
154 fputs (_("warning: "), stderr);
155
156 #ifdef VA_START
157 VA_START (args, message);
158 vfprintf (stderr, message, args);
159 va_end (args);
160 #else
161 fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
162 #endif
163
164 ++warn_message_count;
165 putc ('\n', stderr);
166 fflush (stderr);
167 }
168 \f
169 /*-----------------------------------------------------------.
170 | An error has occurred, but we can proceed, and die later. |
171 `-----------------------------------------------------------*/
172
173 void
174 #if defined VA_START && __STDC__
175 complain (const char *message, ...)
176 #else
177 complain (message, va_alist)
178 char *message;
179 va_dcl
180 #endif
181 {
182 #ifdef VA_START
183 va_list args;
184 #endif
185
186 if (error_one_per_line)
187 {
188 static const char *old_infile;
189 static int old_lineno;
190
191 if (old_lineno == lineno &&
192 (infile == old_infile || !strcmp (old_infile, infile)))
193 /* Simply return and print nothing. */
194 return;
195
196 old_infile = infile;
197 old_lineno = lineno;
198 }
199
200 fflush (stdout);
201 if (infile != NULL)
202 fprintf (stderr, "%s:%d: ", infile, lineno);
203 else
204 fprintf (stderr, "%s:", program_name);
205
206 #ifdef VA_START
207 VA_START (args, message);
208 vfprintf (stderr, message, args);
209 va_end (args);
210 #else
211 fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
212 #endif
213
214 ++complain_message_count;
215 putc ('\n', stderr);
216 fflush (stderr);
217 }
218 \f
219 /*-------------------------------------------------.
220 | A severe error has occurred, we cannot proceed. |
221 `-------------------------------------------------*/
222
223 void
224 #if defined VA_START && __STDC__
225 fatal (const char *message, ...)
226 #else
227 fatal (message, va_alist)
228 char *message;
229 va_dcl
230 #endif
231 {
232 #ifdef VA_START
233 va_list args;
234 #endif
235
236 fflush (stdout);
237 if (infile != NULL)
238 fprintf (stderr, "%s:%d: ", infile, lineno);
239 else
240 fprintf (stderr, "%s:", program_name);
241
242 fputs (_("fatal error: "), stderr);
243
244 #ifdef VA_START
245 VA_START (args, message);
246 vfprintf (stderr, message, args);
247 va_end (args);
248 #else
249 fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
250 #endif
251 putc ('\n', stderr);
252 fflush (stderr);
253 exit (1);
254 }
255 \f
256 /*------------------------------------------------------------------.
257 | A severe error has occurred, we cannot proceed. Exit with STATUS, |
258 | and report the error message of the errno ERRNUM. |
259 `------------------------------------------------------------------*/
260
261 void
262 #if defined VA_START && __STDC__
263 error (int status, int errnum,
264 const char *message, ...)
265 #else
266 error (status, errnum, message, va_alist)
267 int status;
268 int errnum;
269 char *message;
270 va_dcl
271 #endif
272 {
273 #ifdef VA_START
274 va_list args;
275 #endif
276
277 fflush (stdout);
278 if (infile != NULL)
279 fprintf (stderr, "%s:%d: ", infile, lineno);
280 else
281 fprintf (stderr, "%s:", program_name);
282
283 fputs (_("fatal error: "), stderr);
284
285 #ifdef VA_START
286 VA_START (args, message);
287 vfprintf (stderr, message, args);
288 va_end (args);
289 #else
290 fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
291 #endif
292
293 if (errnum)
294 {
295 #if defined HAVE_STRERROR_R || _LIBC
296 char errbuf[1024];
297 # if HAVE_WORKING_STRERROR_R || _LIBC
298 fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf));
299 # else
300 /* Don't use __strerror_r's return value because on some systems
301 (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */
302 __strerror_r (errnum, errbuf, sizeof errbuf);
303 fprintf (stderr, ": %s", errbuf);
304 # endif
305 #else
306 fprintf (stderr, ": %s", strerror (errnum));
307 #endif
308 }
309 putc ('\n', stderr);
310 fflush (stderr);
311 if (status)
312 exit (status);
313 }