* configure.ac: Switch license to GPLv3.
[deliverable/binutils-gdb.git] / gdb / complaints.c
CommitLineData
c906108c 1/* Support for complaint handling during symbol reading in GDB.
b9caf505 2
6aba47ca
DJ
3 Copyright (C) 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000, 2002, 2004,
4 2005, 2006, 2007 Free 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
197e01b6
EZ
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, 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
d9170e22
AC
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. */
66struct explanation
67{
68 const char *prefix;
69 const char *postfix;
70};
71
b9caf505
AC
72struct complaints
73{
74 struct complain *root;
c906108c 75
b9caf505
AC
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). */
82 int series;
c906108c 83
b9caf505
AC
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,
d9170e22
AC
87 the PRE and POST EXPLANATION[SERIES] are used to wrap the
88 message. */
89 const struct explanation *explanation;
b9caf505 90};
c906108c 91
b9caf505 92static struct complain complaint_sentinel;
c906108c 93
b9caf505 94/* The symbol table complaint table. */
c5aa993b 95
d9170e22
AC
96static struct explanation symfile_explanations[] = {
97 { "During symbol reading, ", "." },
98 { "During symbol reading...", "..."},
99 { "", "..."},
100 { "", "..."},
101 { NULL, NULL }
b9caf505 102};
c906108c 103
b9caf505
AC
104static struct complaints symfile_complaint_book = {
105 &complaint_sentinel,
106 0,
107 symfile_explanations
108};
109struct complaints *symfile_complaints = &symfile_complaint_book;
c906108c 110
b9caf505
AC
111/* Wrapper function to, on-demand, fill in a complaints object. */
112
113static struct complaints *
114get_complaints (struct complaints **c)
c906108c 115{
b9caf505
AC
116 if ((*c) != NULL)
117 return (*c);
118 (*c) = XMALLOC (struct complaints);
119 (*c)->root = &complaint_sentinel;
120 (*c)->series = ISOLATED_MESSAGE;
121 (*c)->explanation = NULL;
122 return (*c);
123}
c906108c 124
b9caf505
AC
125static struct complain *
126find_complaint (struct complaints *complaints, const char *file,
127 int line, const char *fmt)
128{
129 struct complain *complaint;
130
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;
136 complaint != NULL;
137 complaint = complaint->next)
c906108c 138 {
b9caf505
AC
139 if (complaint->fmt == fmt
140 && complaint->file == file
141 && complaint->line == line)
142 return complaint;
c906108c 143 }
b9caf505
AC
144
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;
152
153 /* File it, return it. */
154 complaint->next = complaints->root;
155 complaints->root = complaint;
156 return complaint;
157}
158
159
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. */
163
a0841d7a 164static int stop_whining = 0;
b9caf505
AC
165
166/* Print a complaint, and link the complaint block into a chain for
167 later handling. */
168
bee0189a 169static void ATTR_FORMAT (printf, 4, 0)
b9caf505
AC
170vcomplaint (struct complaints **c, const char *file, int line, const char *fmt,
171 va_list args)
172{
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);
177
178 complaint->counter++;
c5aa993b 179 if (complaint->counter > stop_whining)
b9caf505
AC
180 return;
181
182 if (info_verbose)
183 series = SUBSEQUENT_MESSAGE;
184 else
185 series = complaints->series;
186
187 if (complaint->file != NULL)
188 internal_vwarning (complaint->file, complaint->line, complaint->fmt, args);
9a4105ab
AC
189 else if (deprecated_warning_hook)
190 (*deprecated_warning_hook) (complaint->fmt, args);
b9caf505 191 else
c906108c 192 {
b9caf505 193 if (complaints->explanation == NULL)
cc3b68a5 194 /* A [v]warning() call always appends a newline. */
b9caf505
AC
195 vwarning (complaint->fmt, args);
196 else
197 {
198 char *msg;
199 struct cleanup *cleanups;
e623b504 200 msg = xstrvprintf (complaint->fmt, args);
b9caf505
AC
201 cleanups = make_cleanup (xfree, msg);
202 wrap_here ("");
203 if (series != SUBSEQUENT_MESSAGE)
204 begin_line ();
3d263c1d 205 /* XXX: i18n */
d9170e22
AC
206 fprintf_filtered (gdb_stderr, "%s%s%s",
207 complaints->explanation[series].prefix, msg,
208 complaints->explanation[series].postfix);
cc3b68a5
AC
209 /* Force a line-break after any isolated message. For the
210 other cases, clear_complaints() takes care of any missing
211 trailing newline, the wrap_here() is just a hint. */
212 if (series == ISOLATED_MESSAGE)
213 /* It would be really nice to use begin_line() here.
ce2826aa 214 Unfortunately that function doesn't track GDB_STDERR and
cc3b68a5
AC
215 consequently will sometimes supress a line when it
216 shouldn't. */
217 fputs_filtered ("\n", gdb_stderr);
218 else
219 wrap_here ("");
b9caf505
AC
220 do_cleanups (cleanups);
221 }
c906108c 222 }
c906108c 223
b9caf505 224 switch (series)
c906108c 225 {
b9caf505 226 case ISOLATED_MESSAGE:
c5aa993b 227 break;
b9caf505
AC
228 case FIRST_MESSAGE:
229 complaints->series = SUBSEQUENT_MESSAGE;
230 break;
231 case SUBSEQUENT_MESSAGE:
232 case SHORT_FIRST_MESSAGE:
233 complaints->series = SUBSEQUENT_MESSAGE;
c5aa993b 234 break;
c906108c 235 }
b9caf505
AC
236
237 /* If GDB dumps core, we'd like to see the complaints first.
238 Presumably GDB will not be sending so many complaints that this
239 becomes a performance hog. */
240
6426a772 241 gdb_flush (gdb_stderr);
b9caf505
AC
242}
243
244void
245complaint (struct complaints **complaints, const char *fmt, ...)
246{
247 va_list args;
248 va_start (args, fmt);
249 vcomplaint (complaints, NULL/*file*/, 0/*line*/, fmt, args);
250 va_end (args);
251}
252
253void
254internal_complaint (struct complaints **complaints, const char *file,
255 int line, const char *fmt, ...)
256{
257 va_list args;
258 va_start (args, fmt);
259 vcomplaint (complaints, file, line, fmt, args);
260 va_end (args);
261}
262
b9caf505
AC
263/* Clear out / initialize all complaint counters that have ever been
264 incremented. If LESS_VERBOSE is 1, be less verbose about
265 successive complaints, since the messages are appearing all
266 together during a command that is reporting a contiguous block of
267 complaints (rather than being interleaved with other messages). If
268 noisy is 1, we are in a noisy command, and our caller will print
269 enough context for the user to figure it out. */
c906108c
SS
270
271void
b9caf505 272clear_complaints (struct complaints **c, int less_verbose, int noisy)
c906108c 273{
b9caf505
AC
274 struct complaints *complaints = get_complaints (c);
275 struct complain *p;
c906108c 276
b9caf505 277 for (p = complaints->root; p != NULL; p = p->next)
c906108c 278 {
c5aa993b 279 p->counter = 0;
c906108c
SS
280 }
281
cc3b68a5 282 switch (complaints->series)
c906108c 283 {
cc3b68a5
AC
284 case FIRST_MESSAGE:
285 /* Haven't yet printed anything. */
286 break;
287 case SHORT_FIRST_MESSAGE:
288 /* Haven't yet printed anything. */
289 break;
290 case ISOLATED_MESSAGE:
291 /* The code above, always forces a line-break. No need to do it
292 here. */
293 break;
294 case SUBSEQUENT_MESSAGE:
295 /* It would be really nice to use begin_line() here.
ce2826aa 296 Unfortunately that function doesn't track GDB_STDERR and
cc3b68a5
AC
297 consequently will sometimes supress a line when it shouldn't. */
298 fputs_unfiltered ("\n", gdb_stderr);
299 break;
300 default:
3d263c1d 301 internal_error (__FILE__, __LINE__, _("bad switch"));
c906108c
SS
302 }
303
b9caf505
AC
304 if (!less_verbose)
305 complaints->series = ISOLATED_MESSAGE;
306 else if (!noisy)
307 complaints->series = FIRST_MESSAGE;
308 else
309 complaints->series = SHORT_FIRST_MESSAGE;
c906108c
SS
310}
311
335cca0d 312static void
08546159
AC
313complaints_show_value (struct ui_file *file, int from_tty,
314 struct cmd_list_element *cmd, const char *value)
335cca0d
AC
315{
316 fprintf_filtered (file, _("Max number of complaints about incorrect"
08546159 317 " symbols is %s.\n"),
335cca0d
AC
318 value);
319}
320
c906108c 321void
fba45db2 322_initialize_complaints (void)
c906108c 323{
3d263c1d
BI
324 add_setshow_zinteger_cmd ("complaints", class_support, &stop_whining, _("\
325Set max number of complaints about incorrect symbols."), _("\
335cca0d 326Show max number of complaints about incorrect symbols."), NULL,
08546159 327 NULL, complaints_show_value,
b3f42336 328 &setlist, &showlist);
c906108c 329}
This page took 0.486751 seconds and 4 git commands to generate.