From ff1cf532dbabdee0d34974a77809bf2fa23d43a5 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 16 May 2018 23:22:54 -0600 Subject: [PATCH] Remove struct complain At this point, struct complain is just holds a key, a value, and a "next" pointer to form a linked list. It's simpler to replace this with an unordered map. gdb/ChangeLog 2018-05-23 Tom Tromey * complaints.c (counters): New global. (struct complain): Remove. (struct complaints) : Remove. (complaint_sentinel): Remove. (symfile_complaint_book): Update. (find_complaint) Remove. (complaint_internal, clear_complaints): Update. gdb/testsuite/ChangeLog 2018-05-23 Tom Tromey * gdb.gdb/complaints.exp (test_initial_complaints): Simplify. --- gdb/ChangeLog | 10 +++++ gdb/complaints.c | 62 +++------------------------- gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.gdb/complaints.exp | 16 ++----- 4 files changed, 23 insertions(+), 69 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cd30155141d..e4ee33643ea 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2018-05-23 Tom Tromey + + * complaints.c (counters): New global. + (struct complain): Remove. + (struct complaints) : Remove. + (complaint_sentinel): Remove. + (symfile_complaint_book): Update. + (find_complaint) Remove. + (complaint_internal, clear_complaints): Update. + 2018-05-23 Tom Tromey * complaints.c (struct complain) : Remove. diff --git a/gdb/complaints.c b/gdb/complaints.c index 851d8f5d6f1..2c69b8ca2c9 100644 --- a/gdb/complaints.c +++ b/gdb/complaints.c @@ -21,6 +21,7 @@ #include "complaints.h" #include "command.h" #include "gdbcmd.h" +#include /* Should each complaint message be self explanatory, or should we assume that a series of complaints is being produced? */ @@ -34,59 +35,19 @@ enum complaint_series { SHORT_FIRST_MESSAGE, }; -/* Structure to manage complaints about symbol file contents. */ +/* Map format strings to counters. */ -struct complain -{ - const char *fmt; - int counter; - struct complain *next; -}; +static std::unordered_map counters; struct complaints { - struct complain *root; - enum complaint_series series; }; -static struct complain complaint_sentinel; - static struct complaints symfile_complaint_book = { - &complaint_sentinel, ISOLATED_MESSAGE }; -static struct complain * ATTRIBUTE_PRINTF (2, 0) -find_complaint (struct complaints *complaints, const char *fmt) -{ - struct complain *complaint; - - /* Find the complaint in the table. A more efficient search - algorithm (based on hash table or something) could be used. But - that can wait until someone shows evidence that this lookup is - a real bottle neck. */ - for (complaint = complaints->root; - complaint != NULL; - complaint = complaint->next) - { - if (complaint->fmt == fmt) - return complaint; - } - - /* Oops not seen before, fill in a new complaint. */ - complaint = XNEW (struct complain); - complaint->fmt = fmt; - complaint->counter = 0; - complaint->next = NULL; - - /* File it, return it. */ - complaint->next = complaints->root; - complaints->root = complaint; - return complaint; -} - - /* How many complaints about a particular thing should be printed before we stop whining about it? Default is no whining at all, since so many systems have ill-constructed symbol files. */ @@ -99,24 +60,14 @@ void complaint_internal (const char *fmt, ...) { va_list args; - - struct complain *complaint = find_complaint (&symfile_complaint_book, fmt); enum complaint_series series; - complaint->counter++; - if (complaint->counter > stop_whining) + if (counters[fmt]++ > stop_whining) return; va_start (args, fmt); series = symfile_complaint_book.series; - /* Pass 'fmt' instead of 'complaint->fmt' to printf-like callees - from here on, to avoid "format string is not a string literal" - warnings. 'fmt' is this function's printf-format parameter, so - the compiler can assume the passed in argument is a literal - string somewhere up the call chain. */ - gdb_assert (complaint->fmt == fmt); - if (deprecated_warning_hook) (*deprecated_warning_hook) (fmt, args); else @@ -150,10 +101,7 @@ clear_complaints (int less_verbose) { struct complain *p; - for (p = symfile_complaint_book.root; p != NULL; p = p->next) - { - p->counter = 0; - } + counters.clear (); if (!less_verbose) symfile_complaint_book.series = ISOLATED_MESSAGE; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4f727dbb3a6..4b27640ccb7 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-05-23 Tom Tromey + + * gdb.gdb/complaints.exp (test_initial_complaints): Simplify. + 2018-05-23 Tom Tromey * gdb.gdb/complaints.exp (test_initial_complaints): Don't mention diff --git a/gdb/testsuite/gdb.gdb/complaints.exp b/gdb/testsuite/gdb.gdb/complaints.exp index 886b43521d4..65b6bdc2818 100644 --- a/gdb/testsuite/gdb.gdb/complaints.exp +++ b/gdb/testsuite/gdb.gdb/complaints.exp @@ -57,26 +57,18 @@ proc test_initial_complaints { } { # Unsupress complaints gdb_test "set stop_whining = 2" + gdb_test_no_output "set var \$cstr = \"Register a complaint\"" + # Prime the system gdb_test_stdio \ - "call complaint_internal (\"Register a complaint\")" \ + "call complaint_internal (\$cstr)" \ "During symbol reading, Register a complaint." - # Check that the complaint was inserted and where - gdb_test "print symfile_complaint_book.root->fmt" \ - ".\[0-9\]+ =.*\"Register a complaint\"" - # Re-issue the first message #1 gdb_test_stdio \ - "call complaint_internal (symfile_complaint_book.root->fmt)" \ + "call complaint_internal (\$cstr)" \ "During symbol reading, Register a complaint." - # Check that there is only one thing in the list. How the boolean - # result is output depends on whether GDB is built as a C or C++ - # program. - gdb_test "print symfile_complaint_book.root->next == &complaint_sentinel" \ - ".\[0-9\]+ = \(1|true\)" "list has one entry" - # Add a second complaint, expect it gdb_test_stdio \ "call complaint_internal (\"Testing! Testing! Testing!\")" \ -- 2.30.2