]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/complaints.c
GDB copyright headers update after running GDB's copyright.py script.
[thirdparty/binutils-gdb.git] / gdb / complaints.c
CommitLineData
c906108c 1/* Support for complaint handling during symbol reading in GDB.
b9caf505 2
618f726f 3 Copyright (C) 1990-2016 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
19
20#include "defs.h"
21#include "complaints.h"
b9caf505 22#include "command.h"
c906108c
SS
23#include "gdbcmd.h"
24
a14ed312 25extern void _initialize_complaints (void);
392a587b 26
aff410f1
MS
27/* Should each complaint message be self explanatory, or should we
28 assume that a series of complaints is being produced? */
b9caf505 29
b9caf505
AC
30enum complaint_series {
31 /* Isolated self explanatory message. */
32 ISOLATED_MESSAGE,
05d999b0 33
b9caf505
AC
34 /* First message of a series, includes an explanation. */
35 FIRST_MESSAGE,
05d999b0 36
b9caf505
AC
37 /* First message of a series, but does not need to include any sort
38 of explanation. */
39 SHORT_FIRST_MESSAGE,
05d999b0 40
b9caf505
AC
41 /* Subsequent message of a series that needs no explanation (the
42 user already knows we have a problem so we can just state our
43 piece). */
44 SUBSEQUENT_MESSAGE
45};
46
c906108c
SS
47/* Structure to manage complaints about symbol file contents. */
48
b9caf505 49struct complain
c5aa993b 50{
b9caf505
AC
51 const char *file;
52 int line;
53 const char *fmt;
54 int counter;
55 struct complain *next;
c906108c
SS
56};
57
d9170e22
AC
58/* The explanatory message that should accompany the complaint. The
59 message is in two parts - pre and post - that are printed around
60 the complaint text. */
61struct explanation
62{
63 const char *prefix;
64 const char *postfix;
65};
66
b9caf505
AC
67struct complaints
68{
69 struct complain *root;
c906108c 70
05d999b0 71 enum complaint_series series;
c906108c 72
b9caf505
AC
73 /* The explanatory messages that should accompany the complaint.
74 NOTE: cagney/2002-08-14: In a desperate attempt at being vaguely
75 i18n friendly, this is an array of two messages. When present,
d9170e22
AC
76 the PRE and POST EXPLANATION[SERIES] are used to wrap the
77 message. */
78 const struct explanation *explanation;
b9caf505 79};
c906108c 80
b9caf505 81static struct complain complaint_sentinel;
c906108c 82
b9caf505 83/* The symbol table complaint table. */
c5aa993b 84
d9170e22
AC
85static struct explanation symfile_explanations[] = {
86 { "During symbol reading, ", "." },
87 { "During symbol reading...", "..."},
88 { "", "..."},
89 { "", "..."},
90 { NULL, NULL }
b9caf505 91};
c906108c 92
b9caf505
AC
93static struct complaints symfile_complaint_book = {
94 &complaint_sentinel,
05d999b0 95 ISOLATED_MESSAGE,
b9caf505
AC
96 symfile_explanations
97};
98struct complaints *symfile_complaints = &symfile_complaint_book;
c906108c 99
b9caf505
AC
100/* Wrapper function to, on-demand, fill in a complaints object. */
101
102static struct complaints *
103get_complaints (struct complaints **c)
c906108c 104{
b9caf505
AC
105 if ((*c) != NULL)
106 return (*c);
70ba0933 107 (*c) = XNEW (struct complaints);
b9caf505
AC
108 (*c)->root = &complaint_sentinel;
109 (*c)->series = ISOLATED_MESSAGE;
110 (*c)->explanation = NULL;
111 return (*c);
112}
c906108c 113
a0b31db1 114static struct complain * ATTRIBUTE_PRINTF (4, 0)
b9caf505
AC
115find_complaint (struct complaints *complaints, const char *file,
116 int line, const char *fmt)
117{
118 struct complain *complaint;
119
120 /* Find the complaint in the table. A more efficient search
121 algorithm (based on hash table or something) could be used. But
122 that can wait until someone shows evidence that this lookup is
123 a real bottle neck. */
124 for (complaint = complaints->root;
125 complaint != NULL;
126 complaint = complaint->next)
c906108c 127 {
b9caf505
AC
128 if (complaint->fmt == fmt
129 && complaint->file == file
130 && complaint->line == line)
131 return complaint;
c906108c 132 }
b9caf505
AC
133
134 /* Oops not seen before, fill in a new complaint. */
70ba0933 135 complaint = XNEW (struct complain);
b9caf505
AC
136 complaint->fmt = fmt;
137 complaint->file = file;
138 complaint->line = line;
139 complaint->counter = 0;
140 complaint->next = NULL;
141
142 /* File it, return it. */
143 complaint->next = complaints->root;
144 complaints->root = complaint;
145 return complaint;
146}
147
148
149/* How many complaints about a particular thing should be printed
150 before we stop whining about it? Default is no whining at all,
151 since so many systems have ill-constructed symbol files. */
152
a0841d7a 153static int stop_whining = 0;
b9caf505
AC
154
155/* Print a complaint, and link the complaint block into a chain for
156 later handling. */
157
a0b31db1 158static void ATTRIBUTE_PRINTF (4, 0)
aff410f1
MS
159vcomplaint (struct complaints **c, const char *file,
160 int line, const char *fmt,
b9caf505
AC
161 va_list args)
162{
163 struct complaints *complaints = get_complaints (c);
aff410f1
MS
164 struct complain *complaint = find_complaint (complaints, file,
165 line, fmt);
b9caf505 166 enum complaint_series series;
c5504eaf 167
b9caf505
AC
168 gdb_assert (complaints != NULL);
169
170 complaint->counter++;
c5aa993b 171 if (complaint->counter > stop_whining)
b9caf505
AC
172 return;
173
174 if (info_verbose)
175 series = SUBSEQUENT_MESSAGE;
176 else
177 series = complaints->series;
178
77b64a49
PA
179 /* Pass 'fmt' instead of 'complaint->fmt' to printf-like callees
180 from here on, to avoid "format string is not a string literal"
181 warnings. 'fmt' is this function's printf-format parameter, so
182 the compiler can assume the passed in argument is a literal
183 string somewhere up the call chain. */
184 gdb_assert (complaint->fmt == fmt);
185
b9caf505 186 if (complaint->file != NULL)
77b64a49 187 internal_vwarning (complaint->file, complaint->line, fmt, args);
9a4105ab 188 else if (deprecated_warning_hook)
77b64a49 189 (*deprecated_warning_hook) (fmt, args);
b9caf505 190 else
c906108c 191 {
b9caf505 192 if (complaints->explanation == NULL)
cc3b68a5 193 /* A [v]warning() call always appends a newline. */
77b64a49 194 vwarning (fmt, args);
b9caf505
AC
195 else
196 {
197 char *msg;
198 struct cleanup *cleanups;
77b64a49 199 msg = xstrvprintf (fmt, args);
b9caf505
AC
200 cleanups = make_cleanup (xfree, msg);
201 wrap_here ("");
202 if (series != SUBSEQUENT_MESSAGE)
203 begin_line ();
3d263c1d 204 /* XXX: i18n */
d9170e22
AC
205 fprintf_filtered (gdb_stderr, "%s%s%s",
206 complaints->explanation[series].prefix, msg,
207 complaints->explanation[series].postfix);
cc3b68a5
AC
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.
ce2826aa 213 Unfortunately that function doesn't track GDB_STDERR and
cc3b68a5
AC
214 consequently will sometimes supress a line when it
215 shouldn't. */
216 fputs_filtered ("\n", gdb_stderr);
217 else
218 wrap_here ("");
b9caf505
AC
219 do_cleanups (cleanups);
220 }
c906108c 221 }
c906108c 222
b9caf505 223 switch (series)
c906108c 224 {
b9caf505 225 case ISOLATED_MESSAGE:
c5aa993b 226 break;
b9caf505
AC
227 case FIRST_MESSAGE:
228 complaints->series = SUBSEQUENT_MESSAGE;
229 break;
230 case SUBSEQUENT_MESSAGE:
231 case SHORT_FIRST_MESSAGE:
232 complaints->series = SUBSEQUENT_MESSAGE;
c5aa993b 233 break;
c906108c 234 }
b9caf505
AC
235
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. */
239
6426a772 240 gdb_flush (gdb_stderr);
b9caf505
AC
241}
242
243void
244complaint (struct complaints **complaints, const char *fmt, ...)
245{
246 va_list args;
c5504eaf 247
b9caf505
AC
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
aff410f1
MS
297 consequently will sometimes supress a line when it
298 shouldn't. */
cc3b68a5
AC
299 fputs_unfiltered ("\n", gdb_stderr);
300 break;
301 default:
3d263c1d 302 internal_error (__FILE__, __LINE__, _("bad switch"));
c906108c
SS
303 }
304
b9caf505
AC
305 if (!less_verbose)
306 complaints->series = ISOLATED_MESSAGE;
307 else if (!noisy)
308 complaints->series = FIRST_MESSAGE;
309 else
310 complaints->series = SHORT_FIRST_MESSAGE;
c906108c
SS
311}
312
335cca0d 313static void
08546159
AC
314complaints_show_value (struct ui_file *file, int from_tty,
315 struct cmd_list_element *cmd, const char *value)
335cca0d
AC
316{
317 fprintf_filtered (file, _("Max number of complaints about incorrect"
08546159 318 " symbols is %s.\n"),
335cca0d
AC
319 value);
320}
321
c906108c 322void
fba45db2 323_initialize_complaints (void)
c906108c 324{
aff410f1
MS
325 add_setshow_zinteger_cmd ("complaints", class_support,
326 &stop_whining, _("\
3d263c1d 327Set max number of complaints about incorrect symbols."), _("\
335cca0d 328Show max number of complaints about incorrect symbols."), NULL,
08546159 329 NULL, complaints_show_value,
b3f42336 330 &setlist, &showlist);
c906108c 331}