gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / completer.h
index 4b3b1882101cd33bbab40f88235c20fc630bda8a..d3afa5fe3ec872f62d993a3936ea2a17e5f56912 100644 (file)
@@ -1,5 +1,5 @@
 /* Header for GDB line completion.
-   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 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<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.
+   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<std::pair<const char *, const char *>> 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,12 +239,10 @@ 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);
+  completion_result (completion_result &&rhs) noexcept;
 
   /* Release ownership of the match list array.  */
   char **release_match_list ();
@@ -133,6 +285,27 @@ public:
      up in the event the user requests to complete on something vague
      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.,
+     the linespec completer needs to bypass readline's too-simple word
+     breaking algorithm.
 */
 class completion_tracker
 {
@@ -140,22 +313,91 @@ 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<char> name);
+  void add_completion (gdb::unique_xmalloc_ptr<char> 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.  */
   void add_completions (completion_list &&list);
 
+  /* Remove completion matching NAME from the completion list, does nothing
+     if NAME is not already in the completion list.  */
+  void remove_completion (const char *name);
+
+  /* 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 (int 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 (); }
+  { return htab_elements (m_entries_hash) > 0; }
+
+  /* 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
@@ -165,17 +407,32 @@ 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.  */
-  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);
-
-  /* The completion matches found so far, in a vector.  */
-  completion_list m_entries_vec;
+  bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name,
+                            completion_match_for_lcd *match_for_lcd,
+                            const char *text, const char *word);
+
+  /* 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
+     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 hash table, for
      duplicate elimination as entries are added.  Otherwise the user
@@ -183,16 +440,77 @@ private:
      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;
-
-  /* Our idea of lowest common denominator to hand over to readline.  */
+  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
+     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.  */
+  /* 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;
+
+  /* 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
+   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<char>
+  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<char>
+  make_completion_match_str (gdb::unique_xmalloc_ptr<char> &&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 *);
 
@@ -203,6 +521,37 @@ 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
+   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);
+
+/* 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);
 
@@ -263,6 +612,28 @@ extern completer_handle_brkchars_ftype *
 
 /* 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);
+
+/* 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 *);
 
This page took 0.035381 seconds and 4 git commands to generate.