X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fcompleter.h;h=313010fce2280c1b90aa637453deff7b0ad4f5ce;hb=b9ad36868f46d5270347ef50fd62fde94d68328b;hp=f68c6dcd7121c98a3513feb5b0d653042cf52b6a;hpb=c45ec17c07d8aa4554b0b2ca67a5f4dc2c87acc4;p=external%2Fbinutils.git diff --git a/gdb/completer.h b/gdb/completer.h index f68c6dc..313010f 100644 --- a/gdb/completer.h +++ b/gdb/completer.h @@ -1,5 +1,5 @@ /* Header for GDB line completion. - Copyright (C) 2000-2017 Free Software Foundation, Inc. + Copyright (C) 2000-2019 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 @@ -17,7 +17,7 @@ #if !defined (COMPLETER_H) #define COMPLETER_H 1 -#include "gdb_vecs.h" +#include "gdbsupport/gdb_vecs.h" #include "command.h" /* Types of functions in struct match_list_displayer. */ @@ -68,6 +68,160 @@ struct match_list_displayer calls free on each element. */ typedef std::vector> 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 "" (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; +}; + +/* The result of a successful completion match, but for least common + denominator (LCD) computation. Some completers provide matches + that don't start with the completion "word". E.g., completing on + "b push_ba" on a C++ program usually completes to + std::vector<...>::push_back, std::string::push_back etc. In such + case, the symbol comparison routine will set the LCD match to point + into the "push_back" substring within the symbol's name string. + Also, in some cases, the symbol comparison routine will want to + ignore parts of the symbol name for LCD purposes, such as for + example symbols with abi tags in C++. In such cases, the symbol + comparison routine will set MARK_IGNORED_RANGE to mark the ignored + substrings of the matched string. The resulting LCD string with + the ignored parts stripped out is computed at the end of a + completion match sequence iff we had a positive match. */ + +class completion_match_for_lcd +{ +public: + /* Get the resulting LCD, after a successful match. */ + const char *match () + { return m_match; } + + /* Set the match for LCD. See m_match's description. */ + void set_match (const char *match) + { m_match = match; } + + /* Mark the range between [BEGIN, END) as ignored. */ + void mark_ignored_range (const char *begin, const char *end) + { m_ignored_ranges.emplace_back (begin, end); } + + /* Get the resulting LCD, after a successful match. If there are + ignored ranges, then this builds a new string with the ignored + parts removed (and stores it internally). As such, the result of + this call is only good for the current completion match + sequence. */ + const char *finish () + { + if (m_ignored_ranges.empty ()) + return m_match; + else + { + m_finished_storage.clear (); + + const char *prev = m_match; + for (const auto &range : m_ignored_ranges) + { + m_finished_storage.append (prev, range.first); + prev = range.second; + } + m_finished_storage.append (prev); + + return m_finished_storage.c_str (); + } + } + + /* Prepare for another completion matching sequence. */ + void clear () + { + m_match = NULL; + m_ignored_ranges.clear (); + } + +private: + /* The completion match result for LCD. This is usually either a + pointer into to a substring within a symbol's name, or to the + storage of the pairing completion_match object. */ + const char *m_match; + + /* The ignored substring ranges within M_MATCH. E.g., if we were + looking for completion matches for C++ functions starting with + "functio" + and successfully match: + "function[abi:cxx11](int)" + the ignored ranges vector will contain an entry that delimits the + "[abi:cxx11]" substring, such that calling finish() results in: + "function(int)" + */ + std::vector> m_ignored_ranges; + + /* Storage used by the finish() method, if it has to compute a new + string. */ + std::string m_finished_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 completion match, for LCD computation purposes. */ + completion_match_for_lcd match_for_lcd; + + /* Convenience that sets both MATCH and MATCH_FOR_LCD. M_FOR_LCD is + optional. If not specified, defaults to M. */ + void set_match (const char *m, const char *m_for_lcd = NULL) + { + match.set_match (m); + if (m_for_lcd == NULL) + match_for_lcd.set_match (m); + else + match_for_lcd.set_match (m_for_lcd); + } +}; + /* 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, @@ -85,9 +239,7 @@ struct completion_result /* Destroy a result. */ ~completion_result (); - /* Disable copying, since we don't need it. */ - completion_result (const completion_result &rhs) = delete; - void operator= (const completion_result &rhs) = delete; + DISABLE_COPY_AND_ASSIGN (completion_result); /* Move a result. */ completion_result (completion_result &&rhs); @@ -134,6 +286,21 @@ public: that necessitates the time consuming expansion of many symbol tables. + - The completer's idea of least common denominator (aka the common + prefix) between all completion matches to hand over to readline. + Some completers provide matches that don't start with the + completion "word". E.g., completing on "b push_ba" on a C++ + program usually completes to std::vector<...>::push_back, + std::string::push_back etc. If all matches happen to start with + "std::", then readline would figure out that the lowest common + denominator is "std::", and thus would do a partial completion + with that. I.e., it would replace "push_ba" in the input buffer + with "std::", losing the original "push_ba", which is obviously + undesirable. To avoid that, such completers pass the substring + of the match that matters for common denominator computation as + MATCH_FOR_LCD argument to add_completion. The end result is + passed to readline in gdb_rl_attempted_completion_function. + - 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., @@ -146,14 +313,14 @@ public: completion_tracker (); ~completion_tracker (); - /* Disable copy. */ - completion_tracker (const completion_tracker &rhs) = delete; - void operator= (const completion_tracker &rhs) = delete; + 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 name); + void add_completion (gdb::unique_xmalloc_ptr name, + completion_match_for_lcd *match_for_lcd = NULL, + const char *text = NULL, const char *word = NULL); /* Add all completions matches in LIST. Elements are moved out of LIST. */ @@ -190,7 +357,7 @@ public: { m_custom_word_point = point; } /* Advance the custom word point by LEN. */ - void advance_custom_word_point_by (size_t len); + void advance_custom_word_point_by (int len); /* Whether to tell readline to skip appending a whitespace after the completion. See m_suppress_append_ws. */ @@ -207,6 +374,19 @@ public: 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 (); + res.match_for_lcd.clear (); + return m_completion_match_result; + } + /* True if we have any completion match recorded. */ bool have_completions () const { return !m_entries_vec.empty (); } @@ -226,11 +406,29 @@ 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 name); + bool maybe_add_completion (gdb::unique_xmalloc_ptr name, + 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. */ - void recompute_lowest_common_denominator (const char *new_match); + 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 &&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; @@ -277,11 +475,31 @@ private: See intro. */ char *m_lowest_common_denominator = NULL; - /* If true, the LCD is unique. I.e., all completion candidates had - the same string. */ + /* If true, the LCD is unique. I.e., all completions had the same + MATCH_FOR_LCD substring, even if the completions were different. + For example, if "break function" found "a::function()" and + "b::function()", the LCD will be "function()" in both cases and + so we want to tell readline to complete the line with + "function()", instead of showing all the possible + completions. */ bool m_lowest_common_denominator_unique = false; }; +/* Return a string to hand off to readline as a completion match + candidate, potentially composed of parts of MATCH_NAME and of + TEXT/WORD. For a description of TEXT/WORD see completer_ftype. */ + +extern gdb::unique_xmalloc_ptr + make_completion_match_str (const char *match_name, + const char *text, const char *word); + +/* Like above, but takes ownership of MATCH_NAME (i.e., can + reuse/return it). */ + +extern gdb::unique_xmalloc_ptr + make_completion_match_str (gdb::unique_xmalloc_ptr &&match_name, + const char *text, const char *word); + extern void gdb_display_match_list (char **matches, int len, int max, const struct match_list_displayer *); @@ -292,6 +510,13 @@ extern void complete_line (completion_tracker &tracker, const char *line_buffer, int point); +/* Complete LINE and return completion results. For completion purposes, + cursor position is assumed to be at the end of LINE. WORD is set to + the end of word to complete. QUOTE_CHAR is set to the opening quote + character if we found an unclosed quoted substring, '\0' otherwise. */ +extern completion_result + complete (const char *line, char const **word, int *quote_char); + /* 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 @@ -307,10 +532,15 @@ extern const char *completion_find_completion_word (completion_tracker &tracker, 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); +/* Assuming TEXT is an filename, find the completion word point for + TEXT, emulating the algorithm readline uses to find the word + point. */ +extern const char *advance_to_filename_complete_word_point + (completion_tracker &tracker, const char *text); + extern char **gdb_rl_attempted_completion_function (const char *text, int start, int end); @@ -381,6 +611,18 @@ extern completion_list complete_source_filenames (const char *text); extern void complete_expression (completion_tracker &tracker, const char *text, const char *word); +/* Called by custom word point completers that want to recurse into + the completion machinery to complete a command. Used to complete + COMMAND in "thread apply all COMMAND", for example. Note that + unlike command_completer, this fully recurses into the proper + completer for COMMAND, so that e.g., + + (gdb) thread apply all print -[TAB] + + does the right thing and show the print options. */ +extern void complete_nested_command_line (completion_tracker &tracker, + const char *text); + extern const char *skip_quoted_chars (const char *, const char *, const char *);