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;
+};
+
+/* 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. */
+
+class completion_match_for_lcd
+{
+public:
+ /* Set the match for LCD. See m_match's description. */
+ void set_match (const char *match)
+ { m_match = match; }
+
+ /* Get the resulting LCD, after a successful match. */
+ const char *finish ()
+ { return m_match; }
+
+ /* Prepare for another completion matching sequence. */
+ void clear ()
+ { m_match = NULL; }
+
+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;
+};
+
+/* 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,
/* 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);
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.,
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<char> name);
+ void add_completion (gdb::unique_xmalloc_ptr<char> name,
+ completion_match_for_lcd *match_for_lcd = NULL);
/* Add all completions matches in LIST. Elements are moved out of
LIST. */
/* 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 ();
+ 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 (); }
/* 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);
+ bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name,
+ completion_match_for_lcd *match_for_lcd);
/* Given a new match, recompute the lowest common denominator (LCD)
- to hand over to readline. */
+ 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 (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;
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. */
+ /* 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<tab>" 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;
};
/* 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 *);