mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-06 12:09:26 +08:00
b5ec771e60
Summary: - This is preparation for supporting wild name matching on C++ too. - This is also preparation for TAB-completion fixes. - Makes symbol name matching (think strcmp_iw) be based on a per-language method. - Merges completion and non-completion name comparison (think language_ops::la_get_symbol_name_cmp generalized). - Avoid re-hashing lookup name multiple times - Centralizes preparing a name for lookup (Ada name encoding / C++ Demangling), both completion and non-completion. - Fixes Ada latent bug with verbatim name matches in expressions - Makes ada-lang.c use common|symtab.c completion code a bit more. Ada's wild matching basically means that "(gdb) break foo" will find all methods named "foo" in all packages. Translating to C++, it's roughly the same as saying that "break klass::method" sets breakpoints on all "klass::method" methods of all classes, no matter the namespace. A following patch will teach GDB about fullname vs wild matching for C++ too. This patch is preparatory work to get there. Another idea here is to do symbol name matching based on the symbol language's algorithm. I.e., avoid dependency on current language set. This allows for example doing (gdb) b foo::bar< int > (<tab> and having gdb name match the C++ symbols correctly even if the current language is C or Assembly (or Rust, or Ada, or ...), which can easily happen if you step into an Assembly/C runtime library frame. By encapsulating all the information related to a lookup name in a class, we can also cache hash computation for a given language in the lookup name object, to avoid recomputing it over and over. Similarly, because we don't really know upfront which languages the lookup name will be matched against, for each language we store the lookup name transformed into a search name. E.g., for C++, that means demangling the name. But for Ada, it means encoding the name. This actually forces us to centralize all the different lookup name encoding in a central place, resulting in clearer code, IMO. See e.g., the new ada_lookup_name_info class. The lookup name -> symbol search name computation is also done only once per language. The old language->la_get_symbol_name_cmp / symbol_name_cmp_ftype are generalized to work with both completion, and normal symbol look up. At some point early on, I had separate completion vs non-completion language vector entry points, but a single method ends up being better IMO for simplifying things -- the more we merge the completion / non-completion name lookup code paths, the less changes for bugs causing completion vs normal lookup finding different symbols. The ada-lex.l change is necessary because when doing (gdb) p <UpperCase> then the name that is passed to write_ write_var_or_type -> ada_lookup_symbol_list misses the "<>", i.e., it's just "UpperCase", and we end up doing a wild match against "UpperCase" lowercased by ada_lookup_name_info's constructor. I.e., "uppercase" wouldn't ever match "UpperCase", and the symbol lookup fails. This wouldn't cause any regression in the testsuite, but I added a new test that would pass before the patch and fail after, if it weren't for that fix. This is latent bug that happens to go unnoticed because that particular path was inconsistent with the rest of Ada symbol lookup by not lowercasing the lookup name. Ada's symbol_completion_add is deleted, replaced by using common code's completion_list_add_name. To make the latter work for Ada, we needed to add a new output parameter, because Ada wants to return back a custom completion candidates that are not the symbol name. With this patch, minimal symbol demangled name hashing is made consistent with regular symbol hashing. I.e., it now goes via the language vector's search_name_hash method too, as I had suggested in a previous patch. dw2_expand_symtabs_matching / .gdb_index symbol names were a challenge. The problem is that we have no way to telling what is the language of each symbol name found in the index, until we expand the corresponding full symbol, which is off course what we're trying to avoid. Language information is simply not considered in the index format... Since the symbol name hashing and comparison routines are per-language, we now have a problem. The patch sorts this out by matching each name against all languages. This is inneficient, and indeed slows down completion several times. E.g., with: $ cat script.cmd set pagination off set $count = 0 while $count < 400 complete b string_prin printf "count = %d\n", $count set $count = $count + 1 end $ time gdb --batch -q ./gdb-with-index -ex "source script-string_printf.cmd" I get, before patch (-O2, x86-64): real 0m1.773s user 0m1.737s sys 0m0.040s While after patch (-O2, x86-64): real 0m9.843s user 0m9.482s sys 0m0.034s However, the following patch will optimize this, and will actually make this use case faster compared to the "before patch" above: real 0m1.321s user 0m1.285s sys 0m0.039s gdb/ChangeLog: 2017-11-08 Pedro Alves <palves@redhat.com> * ada-lang.c (ada_encode): Rename to .. (ada_encode_1): ... this. Add throw_errors parameter and handle it. (ada_encode): Reimplement. (match_name): Delete, folded into full_name. (resolve_subexp): No longer pass the encoded name to ada_lookup_symbol_list. (should_use_wild_match): Delete. (name_match_type_from_name): New. (ada_lookup_simple_minsym): Use lookup_name_info and the language's symbol_name_matcher_ftype. (add_symbols_from_enclosing_procs, ada_add_local_symbols) (ada_add_block_renamings): Adjust to use lookup_name_info. (ada_lookup_name): New. (add_nonlocal_symbols, ada_add_all_symbols) (ada_lookup_symbol_list_worker, ada_lookup_symbol_list) (ada_iterate_over_symbols): Adjust to use lookup_name_info. (ada_name_for_lookup): Delete. (ada_lookup_encoded_symbol): Construct a verbatim name. (wild_match): Reverse sense of return type. Use bool. (full_match): Reverse sense of return type. Inline bits of old match_name here. (ada_add_block_symbols): Adjust to use lookup_name_info. (symbol_completion_match): Delete, folded into... (ada_lookup_name_info::matches): ... .this new method. (symbol_completion_add): Delete. (ada_collect_symbol_completion_matches): Add name_match_type parameter. Adjust to use lookup_name_info and completion_list_add_name. (get_var_value, ada_add_global_exceptions): Adjust to use lookup_name_info. (ada_get_symbol_name_cmp): Delete. (do_wild_match, do_full_match): New functions. (ada_lookup_name_info::ada_lookup_name_info): New method. (ada_symbol_name_matches, ada_get_symbol_name_matcher): New functions. (ada_language_defn): Install ada_get_symbol_name_matcher. * ada-lex.l (processId): If name starts with '<', copy it verbatim. * block.c (block_iter_match_step, block_iter_match_first) (block_iter_match_next, block_lookup_symbol) (block_lookup_symbol_primary, block_find_symbol): Adjust to use lookup_name_info. * block.h (block_iter_match_first, block_iter_match_next) (ALL_BLOCK_SYMBOLS_WITH_NAME): Adjust to use lookup_name_info. * c-lang.c (c_language_defn, cplus_language_defn) (asm_language_defn, minimal_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * completer.c (complete_files_symbols) (collect_explicit_location_matches, symbol_completer): Pass a symbol_name_match_type down. * completer.h (class completion_match, completion_match_result): New classes. (completion_tracker::reset_completion_match_result): New method. (completion_tracker::m_completion_match_result): New field. * cp-support.c (make_symbol_overload_list_block): Adjust to use lookup_name_info. (cp_fq_symbol_name_matches, cp_get_symbol_name_matcher): New functions. * cp-support.h (cp_get_symbol_name_matcher): New declaration. * d-lang.c: Adjust comments to refer to la_get_symbol_name_matcher. * dictionary.c (dict_vector) <iter_match_first, iter_match_next>: Adjust to use lookup_name_info. (dict_iter_match_first, dict_iter_match_next) (iter_match_first_hashed, iter_match_next_hashed) (iter_match_first_linear, iter_match_next_linear): Adjust to work with a lookup_name_info. * dictionary.h (dict_iter_match_first, dict_iter_match_next): Likewise. * dwarf2read.c (dw2_lookup_symbol): Adjust to use lookup_name_info. (dw2_map_matching_symbols): Adjust to use symbol_name_match_type. (gdb_index_symbol_name_matcher): New class. (dw2_expand_symtabs_matching) Adjust to use lookup_name_info and gdb_index_symbol_name_matcher. Accept a NULL symbol_matcher. * f-lang.c (f_collect_symbol_completion_matches): Adjust to work with a symbol_name_match_type. (f_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * go-lang.c (go_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * language.c (default_symbol_name_matcher) (language_get_symbol_name_matcher): New functions. (unknown_language_defn, auto_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * language.h (symbol_name_cmp_ftype): Delete. (language_defn) <la_collect_symbol_completion_matches>: Add match type parameter. <la_get_symbol_name_cmp>: Delete field. <la_get_symbol_name_matcher>: New field. <la_iterate_over_symbols>: Adjust to use lookup_name_info. (default_symbol_name_matcher, language_get_symbol_name_matcher): Declare. * linespec.c (iterate_over_all_matching_symtabs) (iterate_over_file_blocks): Adjust to use lookup_name_info. (find_methods): Add language parameter, and use lookup_name_info and the language's symbol_name_matcher_ftype. (linespec_complete_function): Adjust. (lookup_prefix_sym): Use lookup_name_info. (add_all_symbol_names_from_pspace): Adjust. (find_superclass_methods): Add language parameter and pass it down. (find_method): Pass symbol language down. (find_linespec_symbols): Don't demangle or Ada encode here. (search_minsyms_for_name): Add lookup_name_info parameter. (add_matching_symbols_to_info): Add name_match_type parameter. Use lookup_name_info. * m2-lang.c (m2_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * minsyms.c: Include <algorithm>. (add_minsym_to_demangled_hash_table): Remove table parameter and add objfile parameter. Use search_name_hash, and add language to demangled languages vector. (struct found_minimal_symbols): New struct. (lookup_minimal_symbol_mangled, lookup_minimal_symbol_demangled): New functions. (lookup_minimal_symbol): Adjust to use them. Don't canonicalize input names here. Use lookup_name_info instead. Lookup up demangled names once for each language in the demangled names vector. (iterate_over_minimal_symbols): Use lookup_name_info. Lookup up demangled names once for each language in the demangled names vector. (build_minimal_symbol_hash_tables): Adjust. * minsyms.h (iterate_over_minimal_symbols): Adjust to pass down a lookup_name_info. * objc-lang.c (objc_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * objfiles.h: Include <vector>. (objfile_per_bfd_storage) <demangled_hash_languages>: New field. * opencl-lang.c (opencl_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * p-lang.c (pascal_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * psymtab.c (psym_lookup_symbol): Use lookup_name_info. (match_partial_symbol): Use symbol_name_match_type, lookup_name_info and psymbol_name_matches. (lookup_partial_symbol): Use lookup_name_info. (map_block): Use symbol_name_match_type and lookup_name_info. (psym_map_matching_symbols): Use symbol_name_match_type. (psymbol_name_matches): New. (recursively_search_psymtabs): Use lookup_name_info and psymbol_name_matches. Rename 'kind' parameter to 'domain'. (psym_expand_symtabs_matching): Use lookup_name_info. Rename 'kind' parameter to 'domain'. * rust-lang.c (rust_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * symfile-debug.c (debug_qf_map_matching_symbols) (debug_qf_map_matching_symbols): Use symbol_name_match_type. (debug_qf_expand_symtabs_matching): Use lookup_name_info. * symfile.c (expand_symtabs_matching): Use lookup_name_info. * symfile.h (quick_symbol_functions) <map_matching_symbols>: Adjust to use symbol_name_match_type. <expand_symtabs_matching>: Adjust to use lookup_name_info. (expand_symtabs_matching): Adjust to use lookup_name_info. * symmisc.c (maintenance_expand_symtabs): Use lookup_name_info::match_any (). * symtab.c (symbol_matches_search_name): New. (eq_symbol_entry): Adjust to use lookup_name_info and the language's matcher. (demangle_for_lookup_info::demangle_for_lookup_info): New. (lookup_name_info::match_any): New. (iterate_over_symbols, search_symbols): Use lookup_name_info. (compare_symbol_name): Add language, lookup_name_info and completion_match_result parameters, and use them. (completion_list_add_name): Make extern. Add language and lookup_name_info parameters. Use them. (completion_list_add_symbol, completion_list_add_msymbol) (completion_list_objc_symbol): Add lookup_name_info parameters and adjust. Pass down language. (completion_list_add_fields): Add lookup_name_info parameters and adjust. Pass down language. (add_symtab_completions): Add lookup_name_info parameters and adjust. (default_collect_symbol_completion_matches_break_on): Add name_match_type parameter, and use it. Use lookup_name_info. (default_collect_symbol_completion_matches) (collect_symbol_completion_matches): Add name_match_type parameter, and pass it down. (collect_symbol_completion_matches_type): Adjust. (collect_file_symbol_completion_matches): Add name_match_type parameter, and use lookup_name_info. * symtab.h: Include <string> and "common/gdb_optional.h". (enum class symbol_name_match_type): New. (class ada_lookup_name_info): New. (struct demangle_for_lookup_info): New. (class lookup_name_info): New. (symbol_name_matcher_ftype): New. (SYMBOL_MATCHES_SEARCH_NAME): Use symbol_matches_search_name. (symbol_matches_search_name): Declare. (MSYMBOL_MATCHES_SEARCH_NAME): Delete. (default_collect_symbol_completion_matches) (collect_symbol_completion_matches) (collect_file_symbol_completion_matches): Add name_match_type parameter. (iterate_over_symbols): Use lookup_name_info. (completion_list_add_name): Declare. * utils.c (enum class strncmp_iw_mode): Moved to utils.h. (strncmp_iw_with_mode): Now extern. * utils.h (enum class strncmp_iw_mode): Moved from utils.c. (strncmp_iw_with_mode): Declare. gdb/testsuite/ChangeLog: 2017-11-08 Pedro Alves <palves@redhat.com> * gdb.ada/complete.exp (p <Exported_Capitalized>): New test. (p Exported_Capitalized): New test. (p exported_capitalized): New test.
467 lines
17 KiB
C++
467 lines
17 KiB
C++
/* Header for GDB line completion.
|
|
Copyright (C) 2000-2017 Free Software Foundation, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#if !defined (COMPLETER_H)
|
|
#define COMPLETER_H 1
|
|
|
|
#include "gdb_vecs.h"
|
|
#include "command.h"
|
|
|
|
/* Types of functions in struct match_list_displayer. */
|
|
|
|
struct match_list_displayer;
|
|
|
|
typedef void mld_crlf_ftype (const struct match_list_displayer *);
|
|
typedef void mld_putch_ftype (const struct match_list_displayer *, int);
|
|
typedef void mld_puts_ftype (const struct match_list_displayer *,
|
|
const char *);
|
|
typedef void mld_flush_ftype (const struct match_list_displayer *);
|
|
typedef void mld_erase_entire_line_ftype (const struct match_list_displayer *);
|
|
typedef void mld_beep_ftype (const struct match_list_displayer *);
|
|
typedef int mld_read_key_ftype (const struct match_list_displayer *);
|
|
|
|
/* Interface between CLI/TUI and gdb_match_list_displayer. */
|
|
|
|
struct match_list_displayer
|
|
{
|
|
/* The screen dimensions to work with when displaying matches. */
|
|
int height, width;
|
|
|
|
/* Print cr,lf. */
|
|
mld_crlf_ftype *crlf;
|
|
|
|
/* Not "putc" to avoid issues where it is a stdio macro. Sigh. */
|
|
mld_putch_ftype *putch;
|
|
|
|
/* Print a string. */
|
|
mld_puts_ftype *puts;
|
|
|
|
/* Flush all accumulated output. */
|
|
mld_flush_ftype *flush;
|
|
|
|
/* Erase the currently line on the terminal (but don't discard any text the
|
|
user has entered, readline may shortly re-print it). */
|
|
mld_erase_entire_line_ftype *erase_entire_line;
|
|
|
|
/* Ring the bell. */
|
|
mld_beep_ftype *beep;
|
|
|
|
/* Read one key. */
|
|
mld_read_key_ftype *read_key;
|
|
};
|
|
|
|
/* A list of completion candidates. Each element is a malloc string,
|
|
because ownership of the strings is transferred to readline, which
|
|
calls free on each element. */
|
|
typedef std::vector<gdb::unique_xmalloc_ptr<char>> completion_list;
|
|
|
|
/* The result of a successful completion match. When doing symbol
|
|
comparison, we use the symbol search name for the symbol name match
|
|
check, but the matched name that is shown to the user may be
|
|
different. For example, Ada uses encoded names for lookup, but
|
|
then wants to decode the symbol name to show to the user, and also
|
|
in some cases wrap the matched name in "<sym>" (meaning we can't
|
|
always use the symbol's print name). */
|
|
|
|
class completion_match
|
|
{
|
|
public:
|
|
/* Get the completion match result. See m_match/m_storage's
|
|
descriptions. */
|
|
const char *match ()
|
|
{ return m_match; }
|
|
|
|
/* Set the completion match result. See m_match/m_storage's
|
|
descriptions. */
|
|
void set_match (const char *match)
|
|
{ m_match = match; }
|
|
|
|
/* Get temporary storage for generating a match result, dynamically.
|
|
The built string is only good until the next clear() call. I.e.,
|
|
good until the next symbol comparison. */
|
|
std::string &storage ()
|
|
{ return m_storage; }
|
|
|
|
/* Prepare for another completion matching sequence. */
|
|
void clear ()
|
|
{
|
|
m_match = NULL;
|
|
m_storage.clear ();
|
|
}
|
|
|
|
private:
|
|
/* The completion match result. This can either be a pointer into
|
|
M_STORAGE string, or it can be a pointer into the some other
|
|
string that outlives the completion matching sequence (usually, a
|
|
pointer to a symbol's name). */
|
|
const char *m_match;
|
|
|
|
/* Storage a symbol comparison routine can use for generating a
|
|
match result, dynamically. The built string is only good until
|
|
the next clear() call. I.e., good until the next symbol
|
|
comparison. */
|
|
std::string m_storage;
|
|
};
|
|
|
|
/* Convenience aggregate holding info returned by the symbol name
|
|
matching routines (see symbol_name_matcher_ftype). */
|
|
struct completion_match_result
|
|
{
|
|
/* The completion match candidate. */
|
|
completion_match match;
|
|
};
|
|
|
|
/* The final result of a completion that is handed over to either
|
|
readline or the "completion" command (which pretends to be
|
|
readline). Mainly a wrapper for a readline-style match list array,
|
|
though other bits of info are included too. */
|
|
|
|
struct completion_result
|
|
{
|
|
/* Create an empty result. */
|
|
completion_result ();
|
|
|
|
/* Create a result. */
|
|
completion_result (char **match_list, size_t number_matches,
|
|
bool completion_suppress_append);
|
|
|
|
/* Destroy a result. */
|
|
~completion_result ();
|
|
|
|
DISABLE_COPY_AND_ASSIGN (completion_result);
|
|
|
|
/* Move a result. */
|
|
completion_result (completion_result &&rhs);
|
|
|
|
/* Release ownership of the match list array. */
|
|
char **release_match_list ();
|
|
|
|
/* Sort the match list. */
|
|
void sort_match_list ();
|
|
|
|
private:
|
|
/* Destroy the match list array and its contents. */
|
|
void reset_match_list ();
|
|
|
|
public:
|
|
/* (There's no point in making these fields private, since the whole
|
|
point of this wrapper is to build data in the layout expected by
|
|
readline. Making them private would require adding getters for
|
|
the "complete" command, which would expose the same
|
|
implementation details anyway.) */
|
|
|
|
/* The match list array, in the format that readline expects.
|
|
match_list[0] contains the common prefix. The real match list
|
|
starts at index 1. The list is NULL terminated. If there's only
|
|
one match, then match_list[1] is NULL. If there are no matches,
|
|
then this is NULL. */
|
|
char **match_list;
|
|
/* The number of matched completions in MATCH_LIST. Does not
|
|
include the NULL terminator or the common prefix. */
|
|
size_t number_matches;
|
|
|
|
/* Whether readline should suppress appending a whitespace, when
|
|
there's only one possible completion. */
|
|
bool completion_suppress_append;
|
|
};
|
|
|
|
/* Object used by completers to build a completion match list to hand
|
|
over to readline. It tracks:
|
|
|
|
- How many unique completions have been generated, to terminate
|
|
completion list generation early if the list has grown to a size
|
|
so large as to be useless. This helps avoid GDB seeming to lock
|
|
up in the event the user requests to complete on something vague
|
|
that necessitates the time consuming expansion of many symbol
|
|
tables.
|
|
|
|
- The custom word point to hand over to readline, for completers
|
|
that parse the input string in order to dynamically adjust
|
|
themselves depending on exactly what they're completing. E.g.,
|
|
the linespec completer needs to bypass readline's too-simple word
|
|
breaking algorithm.
|
|
*/
|
|
class completion_tracker
|
|
{
|
|
public:
|
|
completion_tracker ();
|
|
~completion_tracker ();
|
|
|
|
DISABLE_COPY_AND_ASSIGN (completion_tracker);
|
|
|
|
/* Add the completion NAME to the list of generated completions if
|
|
it is not there already. If too many completions were already
|
|
found, this throws an error. */
|
|
void add_completion (gdb::unique_xmalloc_ptr<char> name);
|
|
|
|
/* Add all completions matches in LIST. Elements are moved out of
|
|
LIST. */
|
|
void add_completions (completion_list &&list);
|
|
|
|
/* Set the quote char to be appended after a unique completion is
|
|
added to the input line. Set to '\0' to clear. See
|
|
m_quote_char's description. */
|
|
void set_quote_char (int quote_char)
|
|
{ m_quote_char = quote_char; }
|
|
|
|
/* The quote char to be appended after a unique completion is added
|
|
to the input line. Returns '\0' if no quote char has been set.
|
|
See m_quote_char's description. */
|
|
int quote_char () { return m_quote_char; }
|
|
|
|
/* Tell the tracker that the current completer wants to provide a
|
|
custom word point instead of a list of a break chars, in the
|
|
handle_brkchars phase. Such completers must also compute their
|
|
completions then. */
|
|
void set_use_custom_word_point (bool enable)
|
|
{ m_use_custom_word_point = enable; }
|
|
|
|
/* Whether the current completer computes a custom word point. */
|
|
bool use_custom_word_point () const
|
|
{ return m_use_custom_word_point; }
|
|
|
|
/* The custom word point. */
|
|
int custom_word_point () const
|
|
{ return m_custom_word_point; }
|
|
|
|
/* Set the custom word point to POINT. */
|
|
void set_custom_word_point (int point)
|
|
{ m_custom_word_point = point; }
|
|
|
|
/* Advance the custom word point by LEN. */
|
|
void advance_custom_word_point_by (size_t len);
|
|
|
|
/* Whether to tell readline to skip appending a whitespace after the
|
|
completion. See m_suppress_append_ws. */
|
|
bool suppress_append_ws () const
|
|
{ return m_suppress_append_ws; }
|
|
|
|
/* Set whether to tell readline to skip appending a whitespace after
|
|
the completion. See m_suppress_append_ws. */
|
|
void set_suppress_append_ws (bool suppress)
|
|
{ m_suppress_append_ws = suppress; }
|
|
|
|
/* Return true if we only have one completion, and it matches
|
|
exactly the completion word. I.e., completing results in what we
|
|
already have. */
|
|
bool completes_to_completion_word (const char *word);
|
|
|
|
/* Get a reference to the shared (between all the multiple symbol
|
|
name comparison calls) completion_match_result object, ready for
|
|
another symbol name match sequence. */
|
|
completion_match_result &reset_completion_match_result ()
|
|
{
|
|
completion_match_result &res = m_completion_match_result;
|
|
|
|
/* Clear any previous match. */
|
|
res.match.clear ();
|
|
return m_completion_match_result;
|
|
}
|
|
|
|
/* True if we have any completion match recorded. */
|
|
bool have_completions () const
|
|
{ return !m_entries_vec.empty (); }
|
|
|
|
/* Discard the current completion match list and the current
|
|
LCD. */
|
|
void discard_completions ();
|
|
|
|
/* Build a completion_result containing the list of completion
|
|
matches to hand over to readline. The parameters are as in
|
|
rl_attempted_completion_function. */
|
|
completion_result build_completion_result (const char *text,
|
|
int start, int end);
|
|
|
|
private:
|
|
|
|
/* 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. */
|
|
bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name);
|
|
|
|
/* Given a new match, recompute the lowest common denominator (LCD)
|
|
to hand over to readline. */
|
|
void recompute_lowest_common_denominator (const char *new_match);
|
|
|
|
/* Completion match outputs returned by the symbol name matching
|
|
routines (see symbol_name_matcher_ftype). These results are only
|
|
valid for a single match call. This is here in order to be able
|
|
to conveniently share the same storage among all the calls to the
|
|
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;
|
|
|
|
/* If non-zero, then this is the quote char that needs to be
|
|
appended after completion (iff we have a unique completion). We
|
|
don't rely on readline appending the quote char as delimiter as
|
|
then readline wouldn't append the ' ' after the completion.
|
|
I.e., we want this:
|
|
|
|
before tab: "b 'function("
|
|
after tab: "b 'function()' "
|
|
*/
|
|
int m_quote_char = '\0';
|
|
|
|
/* If true, the completer has its own idea of "word" point, and
|
|
doesn't want to rely on readline computing it based on brkchars.
|
|
Set in the handle_brkchars phase. */
|
|
bool m_use_custom_word_point = false;
|
|
|
|
/* The completer's idea of where the "word" we were looking at is
|
|
relative to RL_LINE_BUFFER. This is advanced in the
|
|
handle_brkchars phase as the completer discovers potential
|
|
completable words. */
|
|
int m_custom_word_point = 0;
|
|
|
|
/* If true, tell readline to skip appending a whitespace after the
|
|
completion. Automatically set if we have a unique completion
|
|
that already has a space at the end. A completer may also
|
|
explicitly set this. E.g., the linespec completer sets this when
|
|
the completion ends with the ":" separator between filename and
|
|
function name. */
|
|
bool m_suppress_append_ws = false;
|
|
|
|
/* Our idea of lowest common denominator to hand over to readline.
|
|
See intro. */
|
|
char *m_lowest_common_denominator = NULL;
|
|
|
|
/* If true, the LCD is unique. I.e., all completion candidates had
|
|
the same string. */
|
|
bool m_lowest_common_denominator_unique = false;
|
|
};
|
|
|
|
extern void gdb_display_match_list (char **matches, int len, int max,
|
|
const struct match_list_displayer *);
|
|
|
|
extern const char *get_max_completions_reached_message (void);
|
|
|
|
extern void complete_line (completion_tracker &tracker,
|
|
const char *text,
|
|
const char *line_buffer,
|
|
int point);
|
|
|
|
/* Find the bounds of the word in TEXT for completion purposes, and
|
|
return a pointer to the end of the word. Calls the completion
|
|
machinery for a handle_brkchars phase (using TRACKER) to figure out
|
|
the right work break characters for the command in TEXT.
|
|
QUOTE_CHAR, if non-null, is set to the opening quote character if
|
|
we found an unclosed quoted substring, '\0' otherwise. */
|
|
extern const char *completion_find_completion_word (completion_tracker &tracker,
|
|
const char *text,
|
|
int *quote_char);
|
|
|
|
|
|
/* Assuming TEXT is an expression in the current language, find the
|
|
completion word point for TEXT, emulating the algorithm readline
|
|
uses to find the word point, using the current language's word
|
|
break characters. */
|
|
|
|
const char *advance_to_expression_complete_word_point
|
|
(completion_tracker &tracker, const char *text);
|
|
|
|
extern char **gdb_rl_attempted_completion_function (const char *text,
|
|
int start, int end);
|
|
|
|
extern void noop_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void filename_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void expression_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void location_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void symbol_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void command_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void signal_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void reg_or_group_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern void reggroup_completer (struct cmd_list_element *,
|
|
completion_tracker &tracker,
|
|
const char *, const char *);
|
|
|
|
extern const char *get_gdb_completer_quote_characters (void);
|
|
|
|
extern char *gdb_completion_word_break_characters (void);
|
|
|
|
/* Set the word break characters array to BREAK_CHARS. This function
|
|
is useful as const-correct alternative to direct assignment to
|
|
rl_completer_word_break_characters, which is "char *",
|
|
not "const char *". */
|
|
extern void set_rl_completer_word_break_characters (const char *break_chars);
|
|
|
|
/* Get the matching completer_handle_brkchars_ftype function for FN.
|
|
FN is one of the core completer functions above (filename,
|
|
location, symbol, etc.). This function is useful for cases when
|
|
the completer doesn't know the type of the completion until some
|
|
calculation is done (e.g., for Python functions). */
|
|
|
|
extern completer_handle_brkchars_ftype *
|
|
completer_handle_brkchars_func_for_completer (completer_ftype *fn);
|
|
|
|
/* Exported to linespec.c */
|
|
|
|
/* Return a list of all source files whose names begin with matching
|
|
TEXT. */
|
|
extern completion_list complete_source_filenames (const char *text);
|
|
|
|
/* Complete on expressions. Often this means completing on symbol
|
|
names, but some language parsers also have support for completing
|
|
field names. */
|
|
extern void complete_expression (completion_tracker &tracker,
|
|
const char *text, const char *word);
|
|
|
|
extern const char *skip_quoted_chars (const char *, const char *,
|
|
const char *);
|
|
|
|
extern const char *skip_quoted (const char *);
|
|
|
|
/* Maximum number of candidates to consider before the completer
|
|
bails by throwing MAX_COMPLETIONS_REACHED_ERROR. Negative values
|
|
disable limiting. */
|
|
|
|
extern int max_completions;
|
|
|
|
#endif /* defined (COMPLETER_H) */
|