diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-01-27 17:37:20 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-03-19 08:23:30 +0000 |
commit | 724fd9ba432a20ef2e3f2c0d6060bff131226816 (patch) | |
tree | 8026e92b65e594af985dfdab754a3c7867180e26 /gdb/completer.h | |
parent | d8c8b84859d057c58c901c08367ecc9f8a9f09dc (diff) | |
download | gdb-724fd9ba432a20ef2e3f2c0d6060bff131226816.zip gdb-724fd9ba432a20ef2e3f2c0d6060bff131226816.tar.gz gdb-724fd9ba432a20ef2e3f2c0d6060bff131226816.tar.bz2 |
gdb: Restructure the completion_tracker class
In this commit I rewrite how the completion tracker tracks the
completions, and builds its lowest common denominator (LCD) string.
The LCD string is now built lazily when required, and we only track
the completions in one place, the hash table, rather than maintaining
a separate vector of completions.
The motivation for these changes is that the next commit will add the
ability to remove completions from the list, removing a completion
will invalidate the LCD string, so we need to keep hold of enough
information to recompute the LCD string as needed.
Additionally, keeping the completions in a vector makes removing a
completion expensive, so better to only keep the completions in the
hash table.
This commit doesn't add any new functionality itself, and there should
be no user visible changes after this commit.
For testing, I ran the testsuite as usual, but I also ran some manual
completion tests under valgrind, and didn't get any reports about
leaked memory.
gdb/ChangeLog:
* completer.c (completion_tracker::completion_hash_entry): Define
new class.
(advance_to_filename_complete_word_point): Call
recompute_lowest_common_denominator.
(completion_tracker::completion_tracker): Call discard_completions
to setup the hash table.
(completion_tracker::discard_completions): Allow for being called
from the constructor, pass new equal function, and element deleter
when constructing the hash table. Initialise new class member
variables.
(completion_tracker::maybe_add_completion): Remove use of
m_entries_vec, and store more information into m_entries_hash.
(completion_tracker::recompute_lcd_visitor): New function, most
content taken from...
(completion_tracker::recompute_lowest_common_denominator):
...here, this now just visits each item in the hash calling the
above visitor.
(completion_tracker::build_completion_result): Remove use of
m_entries_vec, call recompute_lowest_common_denominator.
* completer.h (completion_tracker::have_completions): Remove use
of m_entries_vec.
(completion_tracker::completion_hash_entry): Declare new class.
(completion_tracker::recompute_lowest_common_denominator): Change
function signature.
(completion_tracker::recompute_lcd_visitor): Declare new function.
(completion_tracker::m_entries_vec): Delete.
(completion_tracker::m_entries_hash): Initialize to NULL.
(completion_tracker::m_lowest_common_denominator_valid): New
member variable.
(completion_tracker::m_lowest_common_denominator_max_length): New
member variable.
Change-Id: I9d1db52c489ca0041b8959ca0d53b7d3af8aea72
Diffstat (limited to 'gdb/completer.h')
-rw-r--r-- | gdb/completer.h | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/gdb/completer.h b/gdb/completer.h index 703a576..7bfe0d5 100644 --- a/gdb/completer.h +++ b/gdb/completer.h @@ -389,7 +389,7 @@ public: /* True if we have any completion match recorded. */ bool have_completions () const - { return !m_entries_vec.empty (); } + { return htab_elements (m_entries_hash) > 0; } /* Discard the current completion match list and the current LCD. */ @@ -403,6 +403,9 @@ public: private: + /* The type that we place into the m_entries_hash hash table. */ + class completion_hash_entry; + /* Add the completion NAME to the list of generated completions if it is not there already. If false is returned, too many completions were found. */ @@ -410,18 +413,15 @@ private: completion_match_for_lcd *match_for_lcd, const char *text, const char *word); - /* Given a new match, recompute the lowest common denominator (LCD) - to hand over to readline. Normally readline computes this itself - based on the whole set of completion matches. However, some - completers want to override readline, in order to be able to - provide a LCD that is not really a prefix of the matches, but the - lowest common denominator of some relevant substring of each - match. E.g., "b push_ba" completes to - "std::vector<..>::push_back", "std::string::push_back", etc., and - in this case we want the lowest common denominator to be - "push_back" instead of "std::". */ - void recompute_lowest_common_denominator - (gdb::unique_xmalloc_ptr<char> &&new_match); + /* Ensure that the lowest common denominator held in the member variable + M_LOWEST_COMMON_DENOMINATOR is valid. This method must be called if + there is any chance that new completions have been added to the + tracker before the lowest common denominator is read. */ + void recompute_lowest_common_denominator (); + + /* Callback used from recompute_lowest_common_denominator, called for + every entry in m_entries_hash. */ + void recompute_lcd_visitor (completion_hash_entry *entry); /* Completion match outputs returned by the symbol name matching routines (see symbol_name_matcher_ftype). These results are only @@ -430,16 +430,13 @@ private: symbol name matching routines. */ completion_match_result m_completion_match_result; - /* The completion matches found so far, in a vector. */ - completion_list m_entries_vec; - /* The completion matches found so far, in a hash table, for duplicate elimination as entries are added. Otherwise the user is left scratching his/her head: readline and complete_command will remove duplicates, and if removal of duplicates there brings the total under max_completions the user may think gdb quit searching too early. */ - htab_t m_entries_hash; + htab_t m_entries_hash = NULL; /* If non-zero, then this is the quote char that needs to be appended after completion (iff we have a unique completion). We @@ -483,6 +480,16 @@ private: "function()", instead of showing all the possible completions. */ bool m_lowest_common_denominator_unique = false; + + /* True if the value in M_LOWEST_COMMON_DENOMINATOR is correct. This is + set to true each time RECOMPUTE_LOWEST_COMMON_DENOMINATOR is called, + and reset to false whenever a new completion is added. */ + bool m_lowest_common_denominator_valid = false; + + /* To avoid calls to xrealloc in RECOMPUTE_LOWEST_COMMON_DENOMINATOR, we + track the maximum possible size of the lowest common denominator, + which we know as each completion is added. */ + size_t m_lowest_common_denominator_max_length = 0; }; /* Return a string to hand off to readline as a completion match |