1 /* Support for complaint handling during symbol reading in GDB.
3 Copyright 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000, 2002,
4 2004 Free Software Foundation, Inc.
6 This file is part of GDB.
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.
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.
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. */
24 #include "complaints.h"
25 #include "gdb_assert.h"
29 extern void _initialize_complaints (void);
31 /* Should each complaint message be self explanatory, or should we assume that
32 a series of complaints is being produced? */
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). */
38 enum complaint_series {
39 /* Isolated self explanatory message. */
41 /* First message of a series, includes an explanation. */
43 /* First message of a series, but does not need to include any sort
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
52 /* Structure to manage complaints about symbol file contents. */
60 struct complain *next;
63 /* The explanatory message that should accompany the complaint. The
64 message is in two parts - pre and post - that are printed around
65 the complaint text. */
74 struct complain *root;
76 /* Should each complaint be self explanatory, or should we assume
77 that a series of complaints is being produced? case 0: Isolated
78 self explanatory message. case 1: First message of a series that
79 must start off with explanation. case 2: Subsequent message of a
80 series that needs no explanation (the user already knows we have
81 a problem so we can just state our piece). */
84 /* The explanatory messages that should accompany the complaint.
85 NOTE: cagney/2002-08-14: In a desperate attempt at being vaguely
86 i18n friendly, this is an array of two messages. When present,
87 the PRE and POST EXPLANATION[SERIES] are used to wrap the
89 const struct explanation *explanation;
92 static struct complain complaint_sentinel;
94 /* The symbol table complaint table. */
96 static struct explanation symfile_explanations[] = {
97 { "During symbol reading, ", "." },
98 { "During symbol reading...", "..."},
104 static struct complaints symfile_complaint_book = {
109 struct complaints *symfile_complaints = &symfile_complaint_book;
111 /* Wrapper function to, on-demand, fill in a complaints object. */
113 static struct complaints *
114 get_complaints (struct complaints **c)
118 (*c) = XMALLOC (struct complaints);
119 (*c)->root = &complaint_sentinel;
120 (*c)->series = ISOLATED_MESSAGE;
121 (*c)->explanation = NULL;
125 static struct complain *
126 find_complaint (struct complaints *complaints, const char *file,
127 int line, const char *fmt)
129 struct complain *complaint;
131 /* Find the complaint in the table. A more efficient search
132 algorithm (based on hash table or something) could be used. But
133 that can wait until someone shows evidence that this lookup is
134 a real bottle neck. */
135 for (complaint = complaints->root;
137 complaint = complaint->next)
139 if (complaint->fmt == fmt
140 && complaint->file == file
141 && complaint->line == line)
145 /* Oops not seen before, fill in a new complaint. */
146 complaint = XMALLOC (struct complain);
147 complaint->fmt = fmt;
148 complaint->file = file;
149 complaint->line = line;
150 complaint->counter = 0;
151 complaint->next = NULL;
153 /* File it, return it. */
154 complaint->next = complaints->root;
155 complaints->root = complaint;
160 /* How many complaints about a particular thing should be printed
161 before we stop whining about it? Default is no whining at all,
162 since so many systems have ill-constructed symbol files. */
164 static unsigned int stop_whining = 0;
166 /* Print a complaint, and link the complaint block into a chain for
170 vcomplaint (struct complaints **c, const char *file, int line, const char *fmt,
173 struct complaints *complaints = get_complaints (c);
174 struct complain *complaint = find_complaint (complaints, file, line, fmt);
175 enum complaint_series series;
176 gdb_assert (complaints != NULL);
178 complaint->counter++;
179 if (complaint->counter > stop_whining)
183 series = SUBSEQUENT_MESSAGE;
185 series = complaints->series;
187 if (complaint->file != NULL)
188 internal_vwarning (complaint->file, complaint->line, complaint->fmt, args);
189 else if (deprecated_warning_hook)
190 (*deprecated_warning_hook) (complaint->fmt, args);
193 if (complaints->explanation == NULL)
194 /* A [v]warning() call always appends a newline. */
195 vwarning (complaint->fmt, args);
199 struct cleanup *cleanups;
200 msg = xstrvprintf (complaint->fmt, args);
201 cleanups = make_cleanup (xfree, msg);
203 if (series != SUBSEQUENT_MESSAGE)
205 fprintf_filtered (gdb_stderr, "%s%s%s",
206 complaints->explanation[series].prefix, msg,
207 complaints->explanation[series].postfix);
208 /* Force a line-break after any isolated message. For the
209 other cases, clear_complaints() takes care of any missing
210 trailing newline, the wrap_here() is just a hint. */
211 if (series == ISOLATED_MESSAGE)
212 /* It would be really nice to use begin_line() here.
213 Unfortunately that function doesn't track GDB_STDERR and
214 consequently will sometimes supress a line when it
216 fputs_filtered ("\n", gdb_stderr);
219 do_cleanups (cleanups);
225 case ISOLATED_MESSAGE:
228 complaints->series = SUBSEQUENT_MESSAGE;
230 case SUBSEQUENT_MESSAGE:
231 case SHORT_FIRST_MESSAGE:
232 complaints->series = SUBSEQUENT_MESSAGE;
236 /* If GDB dumps core, we'd like to see the complaints first.
237 Presumably GDB will not be sending so many complaints that this
238 becomes a performance hog. */
240 gdb_flush (gdb_stderr);
244 complaint (struct complaints **complaints, const char *fmt, ...)
247 va_start (args, fmt);
248 vcomplaint (complaints, NULL/*file*/, 0/*line*/, fmt, args);
253 internal_complaint (struct complaints **complaints, const char *file,
254 int line, const char *fmt, ...)
257 va_start (args, fmt);
258 vcomplaint (complaints, file, line, fmt, args);
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. */
271 clear_complaints (struct complaints **c, int less_verbose, int noisy)
273 struct complaints *complaints = get_complaints (c);
276 for (p = complaints->root; p != NULL; p = p->next)
281 switch (complaints->series)
284 /* Haven't yet printed anything. */
286 case SHORT_FIRST_MESSAGE:
287 /* Haven't yet printed anything. */
289 case ISOLATED_MESSAGE:
290 /* The code above, always forces a line-break. No need to do it
293 case SUBSEQUENT_MESSAGE:
294 /* It would be really nice to use begin_line() here.
295 Unfortunately 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);
300 internal_error (__FILE__, __LINE__, "bad switch");
304 complaints->series = ISOLATED_MESSAGE;
306 complaints->series = FIRST_MESSAGE;
308 complaints->series = SHORT_FIRST_MESSAGE;
312 _initialize_complaints (void)
314 add_setshow_cmd ("complaints", class_support, var_zinteger,
316 Set max number of complaints about incorrect symbols.", "\
317 Show max number of complaints about incorrect symbols.", "\
318 Set to zero to disable incorrect symbol complaints.", "\
319 Max number of complaints about incorrect symbols is %s.",
321 &setlist, &showlist);