]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/complaints.c
2003-01-21 Andrew Cagney <ac131313@redhat.com>
[thirdparty/binutils-gdb.git] / gdb / complaints.c
CommitLineData
c906108c 1/* Support for complaint handling during symbol reading in GDB.
b9caf505
AC
2
3 Copyright 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000, 2002 Free
4 Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "complaints.h"
b9caf505
AC
25#include "gdb_assert.h"
26#include "command.h"
c906108c
SS
27#include "gdbcmd.h"
28
a14ed312 29extern void _initialize_complaints (void);
392a587b 30
b9caf505
AC
31/* Should each complaint message be self explanatory, or should we assume that
32 a series of complaints is being produced? */
33
34/* case 1: First message of a series that must
35 start off with explanation. case 2: Subsequent message of a series
36 that needs no explanation (the user already knows we have a problem
37 so we can just state our piece). */
38enum complaint_series {
39 /* Isolated self explanatory message. */
40 ISOLATED_MESSAGE,
41 /* First message of a series, includes an explanation. */
42 FIRST_MESSAGE,
43 /* First message of a series, but does not need to include any sort
44 of explanation. */
45 SHORT_FIRST_MESSAGE,
46 /* Subsequent message of a series that needs no explanation (the
47 user already knows we have a problem so we can just state our
48 piece). */
49 SUBSEQUENT_MESSAGE
50};
51
c906108c
SS
52/* Structure to manage complaints about symbol file contents. */
53
b9caf505 54struct complain
c5aa993b 55{
b9caf505
AC
56 const char *file;
57 int line;
58 const char *fmt;
59 int counter;
60 struct complain *next;
c906108c
SS
61};
62
b9caf505
AC
63struct complaints
64{
65 struct complain *root;
c906108c 66
b9caf505
AC
67 /* Should each complaint be self explanatory, or should we assume
68 that a series of complaints is being produced? case 0: Isolated
69 self explanatory message. case 1: First message of a series that
70 must start off with explanation. case 2: Subsequent message of a
71 series that needs no explanation (the user already knows we have
72 a problem so we can just state our piece). */
73 int series;
c906108c 74
b9caf505
AC
75 /* The explanatory messages that should accompany the complaint.
76 NOTE: cagney/2002-08-14: In a desperate attempt at being vaguely
77 i18n friendly, this is an array of two messages. When present,
78 EXPLANATION[SERIES] is used to wrap the message. */
79 const char **explanation;
80};
c906108c 81
b9caf505 82static struct complain complaint_sentinel;
c906108c 83
b9caf505 84/* The symbol table complaint table. */
c5aa993b 85
b9caf505 86static const char *symfile_explanations[] = {
cc3b68a5 87 "During symbol reading, %s.",
b9caf505
AC
88 "During symbol reading...%s...",
89 "%s...",
90 "%s...",
91 NULL
92};
c906108c 93
b9caf505
AC
94static struct complaints symfile_complaint_book = {
95 &complaint_sentinel,
96 0,
97 symfile_explanations
98};
99struct complaints *symfile_complaints = &symfile_complaint_book;
c906108c 100
b9caf505
AC
101/* Wrapper function to, on-demand, fill in a complaints object. */
102
103static struct complaints *
104get_complaints (struct complaints **c)
c906108c 105{
b9caf505
AC
106 if ((*c) != NULL)
107 return (*c);
108 (*c) = XMALLOC (struct complaints);
109 (*c)->root = &complaint_sentinel;
110 (*c)->series = ISOLATED_MESSAGE;
111 (*c)->explanation = NULL;
112 return (*c);
113}
c906108c 114
b9caf505
AC
115static struct complain *
116find_complaint (struct complaints *complaints, const char *file,
117 int line, const char *fmt)
118{
119 struct complain *complaint;
120
121 /* Find the complaint in the table. A more efficient search
122 algorithm (based on hash table or something) could be used. But
123 that can wait until someone shows evidence that this lookup is
124 a real bottle neck. */
125 for (complaint = complaints->root;
126 complaint != NULL;
127 complaint = complaint->next)
c906108c 128 {
b9caf505
AC
129 if (complaint->fmt == fmt
130 && complaint->file == file
131 && complaint->line == line)
132 return complaint;
c906108c 133 }
b9caf505
AC
134
135 /* Oops not seen before, fill in a new complaint. */
136 complaint = XMALLOC (struct complain);
137 complaint->fmt = fmt;
138 complaint->file = file;
139 complaint->line = line;
140 complaint->counter = 0;
141 complaint->next = NULL;
142
143 /* File it, return it. */
144 complaint->next = complaints->root;
145 complaints->root = complaint;
146 return complaint;
147}
148
149
150/* How many complaints about a particular thing should be printed
151 before we stop whining about it? Default is no whining at all,
152 since so many systems have ill-constructed symbol files. */
153
154static unsigned int stop_whining = 0;
155
156/* Print a complaint, and link the complaint block into a chain for
157 later handling. */
158
159static void
160vcomplaint (struct complaints **c, const char *file, int line, const char *fmt,
161 va_list args)
162{
163 struct complaints *complaints = get_complaints (c);
164 struct complain *complaint = find_complaint (complaints, file, line, fmt);
165 enum complaint_series series;
166 gdb_assert (complaints != NULL);
167
168 complaint->counter++;
c5aa993b 169 if (complaint->counter > stop_whining)
b9caf505
AC
170 return;
171
172 if (info_verbose)
173 series = SUBSEQUENT_MESSAGE;
174 else
175 series = complaints->series;
176
177 if (complaint->file != NULL)
178 internal_vwarning (complaint->file, complaint->line, complaint->fmt, args);
179 else if (warning_hook)
180 (*warning_hook) (complaint->fmt, args);
181 else
c906108c 182 {
b9caf505 183 if (complaints->explanation == NULL)
cc3b68a5 184 /* A [v]warning() call always appends a newline. */
b9caf505
AC
185 vwarning (complaint->fmt, args);
186 else
187 {
188 char *msg;
189 struct cleanup *cleanups;
190 xvasprintf (&msg, complaint->fmt, args);
191 cleanups = make_cleanup (xfree, msg);
192 wrap_here ("");
193 if (series != SUBSEQUENT_MESSAGE)
194 begin_line ();
195 fprintf_filtered (gdb_stderr,
196 complaints->explanation[series],
197 msg);
cc3b68a5
AC
198 /* Force a line-break after any isolated message. For the
199 other cases, clear_complaints() takes care of any missing
200 trailing newline, the wrap_here() is just a hint. */
201 if (series == ISOLATED_MESSAGE)
202 /* It would be really nice to use begin_line() here.
203 Unfortunatly that function doesn't track GDB_STDERR and
204 consequently will sometimes supress a line when it
205 shouldn't. */
206 fputs_filtered ("\n", gdb_stderr);
207 else
208 wrap_here ("");
b9caf505
AC
209 do_cleanups (cleanups);
210 }
c906108c 211 }
c906108c 212
b9caf505 213 switch (series)
c906108c 214 {
b9caf505 215 case ISOLATED_MESSAGE:
c5aa993b 216 break;
b9caf505
AC
217 case FIRST_MESSAGE:
218 complaints->series = SUBSEQUENT_MESSAGE;
219 break;
220 case SUBSEQUENT_MESSAGE:
221 case SHORT_FIRST_MESSAGE:
222 complaints->series = SUBSEQUENT_MESSAGE;
c5aa993b 223 break;
c906108c 224 }
b9caf505
AC
225
226 /* If GDB dumps core, we'd like to see the complaints first.
227 Presumably GDB will not be sending so many complaints that this
228 becomes a performance hog. */
229
6426a772 230 gdb_flush (gdb_stderr);
b9caf505
AC
231}
232
233void
234complaint (struct complaints **complaints, const char *fmt, ...)
235{
236 va_list args;
237 va_start (args, fmt);
238 vcomplaint (complaints, NULL/*file*/, 0/*line*/, fmt, args);
239 va_end (args);
240}
241
242void
243internal_complaint (struct complaints **complaints, const char *file,
244 int line, const char *fmt, ...)
245{
246 va_list args;
247 va_start (args, fmt);
248 vcomplaint (complaints, file, line, fmt, args);
249 va_end (args);
250}
251
252void
72367fb4 253complain (struct deprecated_complaint *complaint, ...)
b9caf505
AC
254{
255 va_list args;
256 va_start (args, complaint);
257 vcomplaint (&symfile_complaints, NULL/*file*/, 0/*line*/,
258 complaint->message, args);
c906108c
SS
259 va_end (args);
260}
261
b9caf505
AC
262/* Clear out / initialize all complaint counters that have ever been
263 incremented. If LESS_VERBOSE is 1, be less verbose about
264 successive complaints, since the messages are appearing all
265 together during a command that is reporting a contiguous block of
266 complaints (rather than being interleaved with other messages). If
267 noisy is 1, we are in a noisy command, and our caller will print
268 enough context for the user to figure it out. */
c906108c
SS
269
270void
b9caf505 271clear_complaints (struct complaints **c, int less_verbose, int noisy)
c906108c 272{
b9caf505
AC
273 struct complaints *complaints = get_complaints (c);
274 struct complain *p;
c906108c 275
b9caf505 276 for (p = complaints->root; p != NULL; p = p->next)
c906108c 277 {
c5aa993b 278 p->counter = 0;
c906108c
SS
279 }
280
cc3b68a5 281 switch (complaints->series)
c906108c 282 {
cc3b68a5
AC
283 case FIRST_MESSAGE:
284 /* Haven't yet printed anything. */
285 break;
286 case SHORT_FIRST_MESSAGE:
287 /* Haven't yet printed anything. */
288 break;
289 case ISOLATED_MESSAGE:
290 /* The code above, always forces a line-break. No need to do it
291 here. */
292 break;
293 case SUBSEQUENT_MESSAGE:
294 /* It would be really nice to use begin_line() here.
295 Unfortunatly that function doesn't track GDB_STDERR and
296 consequently will sometimes supress a line when it shouldn't. */
297 fputs_unfiltered ("\n", gdb_stderr);
298 break;
299 default:
300 internal_error (__FILE__, __LINE__, "bad switch");
c906108c
SS
301 }
302
b9caf505
AC
303 if (!less_verbose)
304 complaints->series = ISOLATED_MESSAGE;
305 else if (!noisy)
306 complaints->series = FIRST_MESSAGE;
307 else
308 complaints->series = SHORT_FIRST_MESSAGE;
c906108c
SS
309}
310
311void
fba45db2 312_initialize_complaints (void)
c906108c 313{
b9caf505
AC
314 add_setshow_cmd ("complaints", class_support, var_zinteger,
315 &stop_whining,
316 "Set max number of complaints about incorrect symbols.",
317 "Show max number of complaints about incorrect symbols.",
318 NULL, NULL,
319 &setlist, &showlist);
c906108c
SS
320
321}