]> git.saurik.com Git - bison.git/blob - src/complain.c
fadef5a18aaa9f52df3eef857f04243e2ffdab49
[bison.git] / src / complain.c
1 /* Declaration for error-reporting function for Bison.
2
3 Copyright (C) 2000-2002, 2004-2006, 2009-2012 Free Software
4 Foundation, Inc.
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19 /* Based on error.c and error.h,
20 written by David MacKenzie <djm@gnu.ai.mit.edu>. */
21
22 #include <config.h>
23 #include "system.h"
24
25 #include <stdarg.h>
26 #include <progname.h>
27
28 #include "complain.h"
29 #include "files.h"
30 #include "getargs.h"
31
32 int warnings_flag = Wconflicts_sr | Wconflicts_rr | Wother;
33
34 bool complaint_issued;
35 static unsigned *indent_ptr = 0;
36
37 \f
38
39 /** Report an error message.
40 *
41 * \param loc the location, defaulting to the current file,
42 * or the program name.
43 * \param prefix put before the message (e.g., "warning").
44 * \param message the error message, a printf format string. Iff it
45 * ends with ": ", then no trailing newline is printed,
46 * and the caller should print the remaining
47 * newline-terminated message to stderr.
48 * \param args the arguments of the format string.
49 */
50 static
51 void
52 error_message (location *loc,
53 const char *prefix,
54 const char *message, va_list args)
55 {
56 unsigned pos = 0;
57
58 if (loc)
59 pos += location_print (stderr, *loc);
60 else
61 pos += fprintf(stderr, "%s", current_file ? current_file : program_name);
62 pos += fprintf(stderr, ": ");
63
64 if (indent_ptr)
65 {
66 if (!*indent_ptr)
67 *indent_ptr = pos;
68 else if (*indent_ptr > pos)
69 fprintf (stderr, "%*s", *indent_ptr - pos, "");
70 indent_ptr = 0;
71 }
72
73 if (prefix)
74 fprintf (stderr, "%s: ", prefix);
75
76 vfprintf (stderr, message, args);
77 {
78 size_t l = strlen (message);
79 if (l < 2 || message[l-2] != ':' || message[l-1] != ' ')
80 {
81 putc ('\n', stderr);
82 fflush (stderr);
83 }
84 }
85 }
86
87 /** Wrap error_message() with varargs handling. */
88 #define ERROR_MESSAGE(Loc, Prefix, Message) \
89 { \
90 va_list args; \
91 va_start (args, Message); \
92 error_message (Loc, Prefix, Message, args); \
93 va_end (args); \
94 }
95
96
97 /*--------------------------------.
98 | Report a warning, and proceed. |
99 `--------------------------------*/
100
101 void
102 set_warning_issued (void)
103 {
104 static bool warning_issued = false;
105 if (!warning_issued && (warnings_flag & Werror))
106 {
107 fprintf (stderr, "%s: warnings being treated as errors\n", program_name);
108 complaint_issued = true;
109 }
110 warning_issued = true;
111 }
112
113 void
114 warn_at (location loc, const char *message, ...)
115 {
116 if (!(warnings_flag & Wother))
117 return;
118 set_warning_issued ();
119 ERROR_MESSAGE (&loc, _("warning"), message);
120 }
121
122 void
123 warn_at_indent (location loc, unsigned *indent,
124 const char *message, ...)
125 {
126 if (!(warnings_flag & Wother))
127 return;
128 set_warning_issued ();
129 indent_ptr = indent;
130 ERROR_MESSAGE (&loc, _("warning"), message);
131 }
132
133 void
134 warn (const char *message, ...)
135 {
136 if (!(warnings_flag & Wother))
137 return;
138 set_warning_issued ();
139 ERROR_MESSAGE (NULL, _("warning"), message);
140 }
141
142
143 /*-----------------------------------------------------------.
144 | An error has occurred, but we can proceed, and die later. |
145 `-----------------------------------------------------------*/
146
147 void
148 complain_at (location loc, const char *message, ...)
149 {
150 ERROR_MESSAGE (&loc, NULL, message);
151 complaint_issued = true;
152 }
153
154 void
155 complain_at_indent (location loc, unsigned *indent,
156 const char *message, ...)
157 {
158 indent_ptr = indent;
159 ERROR_MESSAGE (&loc, NULL, message);
160 complaint_issued = true;
161 }
162
163 void
164 complain (const char *message, ...)
165 {
166 ERROR_MESSAGE (NULL, NULL, message);
167 complaint_issued = true;
168 }
169
170
171 /*--------------------------------------------------------------.
172 | An incompatibility with POSIX Yacc: mapped either to warn* or |
173 | complain* depending on yacc_flag. |
174 `--------------------------------------------------------------*/
175
176 void
177 yacc_at (location loc, const char *message, ...)
178 {
179 if (yacc_flag)
180 {
181 ERROR_MESSAGE (&loc, NULL, message);
182 complaint_issued = true;
183 }
184 else if (warnings_flag & Wyacc)
185 {
186 set_warning_issued ();
187 ERROR_MESSAGE (&loc, _("warning"), message);
188 }
189 }
190
191 void
192 midrule_value_at (location loc, const char *message, ...)
193 {
194 if (!(warnings_flag & Wmidrule_values))
195 return;
196 set_warning_issued ();
197 ERROR_MESSAGE (&loc, _("warning"), message);
198 }
199
200 /*-------------------------------------------------.
201 | A severe error has occurred, we cannot proceed. |
202 `-------------------------------------------------*/
203
204 void
205 fatal_at (location loc, const char *message, ...)
206 {
207 ERROR_MESSAGE (&loc, _("fatal error"), message);
208 exit (EXIT_FAILURE);
209 }
210
211 void
212 fatal (const char *message, ...)
213 {
214 ERROR_MESSAGE (NULL, _("fatal error"), message);
215 exit (EXIT_FAILURE);
216 }