ubsan: bfin: left shift of negative value
[deliverable/binutils-gdb.git] / gdb / completer.c
index 5d81f24bddedbcbe2e0c51ad3ed3189f3880ff55..6658da6d7fb7d7e36c4b3d377658692935efa4b3 100644 (file)
@@ -1,5 +1,5 @@
 /* Line completion stuff for GDB, the GNU debugger.
-   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   Copyright (C) 2000-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -22,7 +22,7 @@
 #include "expression.h"
 #include "filenames.h"         /* For DOSish file names.  */
 #include "language.h"
-#include "gdb_signals.h"
+#include "gdbsupport/gdb_signals.h"
 #include "target.h"
 #include "reggroups.h"
 #include "user-regs.h"
@@ -76,6 +76,9 @@ enum explicit_location_match_type
     /* The name of a function or method.  */
     MATCH_FUNCTION,
 
+    /* The fully-qualified name of a function or method.  */
+    MATCH_QUALIFIED,
+
     /* A line number.  */
     MATCH_LINE,
 
@@ -99,13 +102,13 @@ enum explicit_location_match_type
 
 /* Variables which are necessary for fancy command line editing.  */
 
-/* When completing on command names, we remove '-' from the list of
+/* When completing on command names, we remove '-' and '.' from the list of
    word break characters, since we use it in command names.  If the
    readline library sees one in any of the current completion strings,
    it thinks that the string needs to be quoted and automatically
    supplies a leading quote.  */
 static const char gdb_completer_command_word_break_characters[] =
-" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,";
+" \t\n!@#$%^&*()+=|~`}{[]\"';:?/><,";
 
 /* When completing on file names, we remove from the list of word
    break characters any characters that are commonly used in file
@@ -151,15 +154,13 @@ filename_completer (struct cmd_list_element *ignore,
                    const char *text, const char *word)
 {
   int subsequent_name;
-  VEC (char_ptr) *return_val = NULL;
 
   subsequent_name = 0;
   while (1)
     {
-      char *p, *q;
-
-      p = rl_filename_completion_function (text, subsequent_name);
-      if (p == NULL)
+      gdb::unique_xmalloc_ptr<char> p_rl
+       (rl_filename_completion_function (text, subsequent_name));
+      if (p_rl == NULL)
        break;
       /* We need to set subsequent_name to a non-zero value before the
         continue line below, because otherwise, if the first file
@@ -168,32 +169,12 @@ filename_completer (struct cmd_list_element *ignore,
       subsequent_name = 1;
       /* Like emacs, don't complete on old versions.  Especially
          useful in the "source" command.  */
+      const char *p = p_rl.get ();
       if (p[strlen (p) - 1] == '~')
-       {
-         xfree (p);
-         continue;
-       }
+       continue;
 
-      if (word == text)
-       /* Return exactly p.  */
-       q = p;
-      else if (word > text)
-       {
-         /* Return some portion of p.  */
-         q = (char *) xmalloc (strlen (p) + 5);
-         strcpy (q, p + (word - text));
-         xfree (p);
-       }
-      else
-       {
-         /* Return some of TEXT plus p.  */
-         q = (char *) xmalloc (strlen (p) + (text - word) + 5);
-         strncpy (q, word, text - word);
-         q[text - word] = '\0';
-         strcat (q, p);
-         xfree (p);
-       }
-      tracker.add_completion (gdb::unique_xmalloc_ptr<char> (q));
+      tracker.add_completion
+       (make_completion_match_str (std::move (p_rl), text, word));
     }
 #if 0
   /* There is no way to do this just long enough to affect quote
@@ -371,29 +352,58 @@ gdb_rl_find_completion_word (struct gdb_rl_completion_word_info *info,
   return line_buffer + point;
 }
 
-/* See completer.h.  */
+/* Find the completion word point for TEXT, emulating the algorithm
+   readline uses to find the word point, using WORD_BREAK_CHARACTERS
+   as word break characters.  */
 
-const char *
-advance_to_expression_complete_word_point (completion_tracker &tracker,
-                                          const char *text)
+static const char *
+advance_to_completion_word (completion_tracker &tracker,
+                           const char *word_break_characters,
+                           const char *text)
 {
   gdb_rl_completion_word_info info;
 
-  info.word_break_characters
-    = current_language->la_word_break_characters ();
+  info.word_break_characters = word_break_characters;
   info.quote_characters = gdb_completer_quote_characters;
   info.basic_quote_characters = rl_basic_quote_characters;
 
+  int delimiter;
   const char *start
-    = gdb_rl_find_completion_word (&info, NULL, NULL, text);
+    = gdb_rl_find_completion_word (&info, NULL, &delimiter, text);
 
   tracker.advance_custom_word_point_by (start - text);
 
+  if (delimiter)
+    {
+      tracker.set_quote_char (delimiter);
+      tracker.set_suppress_append_ws (true);
+    }
+
   return start;
 }
 
 /* See completer.h.  */
 
+const char *
+advance_to_expression_complete_word_point (completion_tracker &tracker,
+                                          const char *text)
+{
+  const char *brk_chars = current_language->la_word_break_characters ();
+  return advance_to_completion_word (tracker, brk_chars, text);
+}
+
+/* See completer.h.  */
+
+const char *
+advance_to_filename_complete_word_point (completion_tracker &tracker,
+                                        const char *text)
+{
+  const char *brk_chars = gdb_completer_file_name_break_characters;
+  return advance_to_completion_word (tracker, brk_chars, text);
+}
+
+/* See completer.h.  */
+
 bool
 completion_tracker::completes_to_completion_word (const char *word)
 {
@@ -413,6 +423,39 @@ completion_tracker::completes_to_completion_word (const char *word)
   return false;
 }
 
+/* See completer.h.  */
+
+void
+complete_nested_command_line (completion_tracker &tracker, const char *text)
+{
+  /* Must be called from a custom-word-point completer.  */
+  gdb_assert (tracker.use_custom_word_point ());
+
+  /* Disable the custom word point temporarily, because we want to
+     probe whether the command we're completing itself uses a custom
+     word point.  */
+  tracker.set_use_custom_word_point (false);
+  size_t save_custom_word_point = tracker.custom_word_point ();
+
+  int quote_char = '\0';
+  const char *word = completion_find_completion_word (tracker, text,
+                                                     &quote_char);
+
+  if (tracker.use_custom_word_point ())
+    {
+      /* The command we're completing uses a custom word point, so the
+        tracker already contains the matches.  We're done.  */
+      return;
+    }
+
+  /* Restore the custom word point settings.  */
+  tracker.set_custom_word_point (save_custom_word_point);
+  tracker.set_use_custom_word_point (true);
+
+  /* Run the handle_completions completer phase.  */
+  complete_line (tracker, word, text, strlen (text));
+}
+
 /* Complete on linespecs, which might be of two possible forms:
 
        file:line
@@ -426,7 +469,6 @@ static void
 complete_files_symbols (completion_tracker &tracker,
                        const char *text, const char *word)
 {
-  int ix;
   completion_list fn_list;
   const char *p;
   int quote_found = 0;
@@ -499,6 +541,7 @@ complete_files_symbols (completion_tracker &tracker,
     {
       collect_file_symbol_completion_matches (tracker,
                                              complete_symbol_mode::EXPRESSION,
+                                             symbol_name_match_type::EXPRESSION,
                                              symbol_start, word,
                                              file_to_match);
       xfree (file_to_match);
@@ -509,6 +552,7 @@ complete_files_symbols (completion_tracker &tracker,
 
       collect_symbol_completion_matches (tracker,
                                         complete_symbol_mode::EXPRESSION,
+                                        symbol_name_match_type::EXPRESSION,
                                         symbol_start, word);
       /* If text includes characters which cannot appear in a file
         name, they cannot be asking for completion on files.  */
@@ -519,8 +563,6 @@ complete_files_symbols (completion_tracker &tracker,
 
   if (!fn_list.empty () && !tracker.have_completions ())
     {
-      char *fn;
-
       /* If we only have file names as possible completion, we should
         bring them in sync with what rl_complete expects.  The
         problem is that if the user types "break /foo/b TAB", and the
@@ -551,6 +593,7 @@ complete_files_symbols (completion_tracker &tracker,
         on the entire text as a symbol.  */
       collect_symbol_completion_matches (tracker,
                                         complete_symbol_mode::EXPRESSION,
+                                        symbol_name_match_type::EXPRESSION,
                                         orig_text, word);
     }
 }
@@ -576,7 +619,8 @@ complete_source_filenames (const char *text)
 
 static void
 complete_address_and_linespec_locations (completion_tracker &tracker,
-                                        const char *text)
+                                        const char *text,
+                                        symbol_name_match_type match_type)
 {
   if (*text == '*')
     {
@@ -588,7 +632,7 @@ complete_address_and_linespec_locations (completion_tracker &tracker,
     }
   else
     {
-      linespec_complete (tracker, text);
+      linespec_complete (tracker, text, match_type);
     }
 }
 
@@ -599,6 +643,7 @@ static const char *const explicit_options[] =
   {
     "-source",
     "-function",
+    "-qualified",
     "-line",
     "-label",
     NULL
@@ -635,6 +680,9 @@ collect_explicit_location_matches (completion_tracker &tracker,
   const struct explicit_location *explicit_loc
     = get_explicit_location (location);
 
+  /* True if the option expects an argument.  */
+  bool needs_arg = true;
+
   /* Note, in the various MATCH_* below, we complete on
      explicit_loc->foo instead of WORD, because only the former will
      have already skipped past any quote char.  */
@@ -653,10 +701,14 @@ collect_explicit_location_matches (completion_tracker &tracker,
       {
        const char *function = string_or_empty (explicit_loc->function_name);
        linespec_complete_function (tracker, function,
+                                   explicit_loc->func_name_match_type,
                                    explicit_loc->source_filename);
       }
       break;
 
+    case MATCH_QUALIFIED:
+      needs_arg = false;
+      break;
     case MATCH_LINE:
       /* Nothing to offer.  */
       break;
@@ -667,6 +719,7 @@ collect_explicit_location_matches (completion_tracker &tracker,
        linespec_complete_label (tracker, language,
                                 explicit_loc->source_filename,
                                 explicit_loc->function_name,
+                                explicit_loc->func_name_match_type,
                                 label);
       }
       break;
@@ -675,7 +728,7 @@ collect_explicit_location_matches (completion_tracker &tracker,
       gdb_assert_not_reached ("unhandled explicit_location_match_type");
     }
 
-  if (tracker.completes_to_completion_word (word))
+  if (!needs_arg || tracker.completes_to_completion_word (word))
     {
       tracker.discard_completions ();
       tracker.advance_custom_word_point_by (strlen (word));
@@ -699,7 +752,7 @@ collect_explicit_location_matches (completion_tracker &tracker,
             keyword.  */
          if (keyword != word)
            {
-             keyword = skip_spaces_const (keyword);
+             keyword = skip_spaces (keyword);
 
              tracker.advance_custom_word_point_by (keyword - word);
              complete_on_enum (tracker, linespec_keywords, keyword, keyword);
@@ -729,7 +782,7 @@ skip_keyword (completion_tracker &tracker,
              const char * const *keywords, const char **text_p)
 {
   const char *text = *text_p;
-  const char *after = skip_to_space_const (text);
+  const char *after = skip_to_space (text);
   size_t len = after - text;
 
   if (text[len] != ' ')
@@ -807,14 +860,12 @@ complete_explicit_location (completion_tracker &tracker,
                   before: "b -function 'not_loaded_function_yet()'"
                   after:  "b -function 'not_loaded_function_yet()' "
              */
-             gdb::unique_xmalloc_ptr<char> text_copy
-               (xstrdup (text));
-             tracker.add_completion (std::move (text_copy));
+             tracker.add_completion (make_unique_xstrdup (text));
            }
          else if (quoted_arg_end[1] == ' ')
            {
              /* We're maybe past the explicit location argument.
-                Skip the argument without interpretion, assuming the
+                Skip the argument without interpretation, assuming the
                 user may want to create pending breakpoint.  Offer
                 the keyword and explicit location options as possible
                 completions.  */
@@ -864,7 +915,7 @@ location_completer (struct cmd_list_element *ignore,
       tracker.advance_custom_word_point_by (1);
     }
 
-  if (location != NULL)
+  if (completion_info.saw_explicit_location_option)
     {
       if (*copy != '\0')
        {
@@ -904,10 +955,29 @@ location_completer (struct cmd_list_element *ignore,
 
        }
     }
+  /* This is an address or linespec location.  */
+  else if (location != NULL)
+    {
+      /* Handle non-explicit location options.  */
+
+      int keyword = skip_keyword (tracker, explicit_options, &text);
+      if (keyword == -1)
+       complete_on_enum (tracker, explicit_options, text, text);
+      else
+       {
+         tracker.advance_custom_word_point_by (copy - text);
+         text = copy;
+
+         symbol_name_match_type match_type
+           = get_explicit_location (location.get ())->func_name_match_type;
+         complete_address_and_linespec_locations (tracker, text, match_type);
+       }
+    }
   else
     {
-      /* This is an address or linespec location.  */
-      complete_address_and_linespec_locations (tracker, text);
+      /* No options.  */
+      complete_address_and_linespec_locations (tracker, text,
+                                              symbol_name_match_type::WILD);
     }
 
   /* Add matches for option names, if either:
@@ -952,7 +1022,7 @@ location_completer_handle_brkchars (struct cmd_list_element *ignore,
 
 static void
 add_struct_fields (struct type *type, completion_list &output,
-                  char *fieldname, int namelen)
+                  const char *fieldname, int namelen)
 {
   int i;
   int computed_type_name = 0;
@@ -989,7 +1059,7 @@ add_struct_fields (struct type *type, completion_list &output,
        {
          if (!computed_type_name)
            {
-             type_name = type_name_no_tag (type);
+             type_name = TYPE_NAME (type);
              computed_type_name = 1;
            }
          /* Omit constructors from the completion list.  */
@@ -1006,23 +1076,21 @@ complete_expression (completion_tracker &tracker,
                     const char *text, const char *word)
 {
   struct type *type = NULL;
-  char *fieldname;
+  gdb::unique_xmalloc_ptr<char> fieldname;
   enum type_code code = TYPE_CODE_UNDEF;
 
   /* Perform a tentative parse of the expression, to see whether a
      field completion is required.  */
-  fieldname = NULL;
-  TRY
+  try
     {
       type = parse_expression_for_completion (text, &fieldname, &code);
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       return;
     }
-  END_CATCH
 
-  if (fieldname && type)
+  if (fieldname != nullptr && type)
     {
       for (;;)
        {
@@ -1035,26 +1103,20 @@ complete_expression (completion_tracker &tracker,
       if (TYPE_CODE (type) == TYPE_CODE_UNION
          || TYPE_CODE (type) == TYPE_CODE_STRUCT)
        {
-         int flen = strlen (fieldname);
          completion_list result;
 
-         add_struct_fields (type, result, fieldname, flen);
-         xfree (fieldname);
+         add_struct_fields (type, result, fieldname.get (),
+                            strlen (fieldname.get ()));
          tracker.add_completions (std::move (result));
          return;
        }
     }
-  else if (fieldname && code != TYPE_CODE_UNDEF)
+  else if (fieldname != nullptr && code != TYPE_CODE_UNDEF)
     {
-      VEC (char_ptr) *result;
-      struct cleanup *cleanup = make_cleanup (xfree, fieldname);
-
-      collect_symbol_completion_matches_type (tracker, fieldname, fieldname,
-                                             code);
-      do_cleanups (cleanup);
+      collect_symbol_completion_matches_type (tracker, fieldname.get (),
+                                             fieldname.get (), code);
       return;
     }
-  xfree (fieldname);
 
   complete_files_symbols (tracker, text, word);
 }
@@ -1079,23 +1141,6 @@ set_rl_completer_word_break_characters (const char *break_chars)
   rl_completer_word_break_characters = (char *) break_chars;
 }
 
-/* See definition in completer.h.  */
-
-void
-set_gdb_completion_word_break_characters (completer_ftype *fn)
-{
-  const char *break_chars;
-
-  /* So far we are only interested in differentiating filename
-     completers from everything else.  */
-  if (fn == filename_completer)
-    break_chars = gdb_completer_file_name_break_characters;
-  else
-    break_chars = gdb_completer_command_word_break_characters;
-
-  set_rl_completer_word_break_characters (break_chars);
-}
-
 /* Complete on symbols.  */
 
 void
@@ -1104,6 +1149,7 @@ symbol_completer (struct cmd_list_element *ignore,
                  const char *text, const char *word)
 {
   collect_symbol_completion_matches (tracker, complete_symbol_mode::EXPRESSION,
+                                    symbol_name_match_type::EXPRESSION,
                                     text, word);
 }
 
@@ -1238,7 +1284,7 @@ complete_line_internal_1 (completion_tracker &tracker,
      on command strings (as opposed to strings supplied by the
      individual command completer functions, which can be any string)
      then we will switch to the special word break set for command
-     strings, which leaves out the '-' character used in some
+     strings, which leaves out the '-' and '.' character used in some
      commands.  */
   set_rl_completer_word_break_characters
     (current_language->la_word_break_characters());
@@ -1266,10 +1312,13 @@ complete_line_internal_1 (completion_tracker &tracker,
       word = tmp_command + point - strlen (text);
     }
 
-  if (point == 0)
+  /* Move P up to the start of the command.  */
+  p = skip_spaces (p);
+
+  if (*p == '\0')
     {
-      /* An empty line we want to consider ambiguous; that is, it
-        could be any command.  */
+      /* An empty line is ambiguous; that is, it could be any
+        command.  */
       c = CMD_LIST_AMBIGUOUS;
       result_list = 0;
     }
@@ -1298,7 +1347,7 @@ complete_line_internal_1 (completion_tracker &tracker,
       /* lookup_cmd_1 advances p up to the first ambiguous thing, but
         doesn't advance over that thing itself.  Do so now.  */
       q = p;
-      while (*q && (isalnum (*q) || *q == '-' || *q == '_'))
+      while (valid_cmd_char_p (*q))
        ++q;
       if (q != tmp_command + point)
        {
@@ -1386,12 +1435,15 @@ complete_line_internal_1 (completion_tracker &tracker,
              q = p;
              while (q > tmp_command)
                {
-                 if (isalnum (q[-1]) || q[-1] == '-' || q[-1] == '_')
+                 if (valid_cmd_char_p (q[-1]))
                    --q;
                  else
                    break;
                }
 
+             /* Move the custom word point back too.  */
+             tracker.advance_custom_word_point_by (q - p);
+
              if (reason != handle_brkchars)
                complete_on_cmdlist (result_list, tracker, q, word,
                                     ignore_help_classes);
@@ -1438,14 +1490,14 @@ complete_line_internal (completion_tracker &tracker,
                        const char *line_buffer, int point,
                        complete_line_internal_reason reason)
 {
-  TRY
+  try
     {
       complete_line_internal_1 (tracker, text, line_buffer, point, reason);
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
-       throw_exception (except);
+       throw;
     }
 }
 
@@ -1461,7 +1513,7 @@ int max_completions = 200;
 completion_tracker::completion_tracker ()
 {
   m_entries_hash = htab_create_alloc (INITIAL_COMPLETION_HTAB_SIZE,
-                                     htab_hash_string, (htab_eq) streq,
+                                     htab_hash_string, streq_hash,
                                      NULL, xcalloc, xfree);
 }
 
@@ -1479,7 +1531,7 @@ completion_tracker::discard_completions ()
 
   htab_delete (m_entries_hash);
   m_entries_hash = htab_create_alloc (INITIAL_COMPLETION_HTAB_SIZE,
-                                     htab_hash_string, (htab_eq) streq,
+                                     htab_hash_string, streq_hash,
                                      NULL, xcalloc, xfree);
 }
 
@@ -1494,7 +1546,10 @@ completion_tracker::~completion_tracker ()
 /* See completer.h.  */
 
 bool
-completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr<char> name)
+completion_tracker::maybe_add_completion
+  (gdb::unique_xmalloc_ptr<char> name,
+   completion_match_for_lcd *match_for_lcd,
+   const char *text, const char *word)
 {
   void **slot;
 
@@ -1507,9 +1562,18 @@ completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr<char> name)
   slot = htab_find_slot (m_entries_hash, name.get (), INSERT);
   if (*slot == HTAB_EMPTY_ENTRY)
     {
-      const char *match_for_lcd_str = name.get ();
+      const char *match_for_lcd_str = NULL;
+
+      if (match_for_lcd != NULL)
+       match_for_lcd_str = match_for_lcd->finish ();
+
+      if (match_for_lcd_str == NULL)
+       match_for_lcd_str = name.get ();
 
-      recompute_lowest_common_denominator (match_for_lcd_str);
+      gdb::unique_xmalloc_ptr<char> lcd
+       = make_completion_match_str (match_for_lcd_str, text, word);
+
+      recompute_lowest_common_denominator (std::move (lcd));
 
       *slot = name.get ();
       m_entries_vec.push_back (std::move (name));
@@ -1521,9 +1585,11 @@ completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr<char> name)
 /* See completer.h.  */
 
 void
-completion_tracker::add_completion (gdb::unique_xmalloc_ptr<char> name)
+completion_tracker::add_completion (gdb::unique_xmalloc_ptr<char> name,
+                                   completion_match_for_lcd *match_for_lcd,
+                                   const char *text, const char *word)
 {
-  if (!maybe_add_completion (std::move (name)))
+  if (!maybe_add_completion (std::move (name), match_for_lcd, text, word))
     throw_error (MAX_COMPLETIONS_REACHED_ERROR, _("Max completions reached."));
 }
 
@@ -1536,6 +1602,105 @@ completion_tracker::add_completions (completion_list &&list)
     add_completion (std::move (candidate));
 }
 
+/* Helper for the make_completion_match_str overloads.  Returns NULL
+   as an indication that we want MATCH_NAME exactly.  It is up to the
+   caller to xstrdup that string if desired.  */
+
+static char *
+make_completion_match_str_1 (const char *match_name,
+                            const char *text, const char *word)
+{
+  char *newobj;
+
+  if (word == text)
+    {
+      /* Return NULL as an indication that we want MATCH_NAME
+        exactly.  */
+      return NULL;
+    }
+  else if (word > text)
+    {
+      /* Return some portion of MATCH_NAME.  */
+      newobj = xstrdup (match_name + (word - text));
+    }
+  else
+    {
+      /* Return some of WORD plus MATCH_NAME.  */
+      size_t len = strlen (match_name);
+      newobj = (char *) xmalloc (text - word + len + 1);
+      memcpy (newobj, word, text - word);
+      memcpy (newobj + (text - word), match_name, len + 1);
+    }
+
+  return newobj;
+}
+
+/* See completer.h.  */
+
+gdb::unique_xmalloc_ptr<char>
+make_completion_match_str (const char *match_name,
+                          const char *text, const char *word)
+{
+  char *newobj = make_completion_match_str_1 (match_name, text, word);
+  if (newobj == NULL)
+    newobj = xstrdup (match_name);
+  return gdb::unique_xmalloc_ptr<char> (newobj);
+}
+
+/* See completer.h.  */
+
+gdb::unique_xmalloc_ptr<char>
+make_completion_match_str (gdb::unique_xmalloc_ptr<char> &&match_name,
+                          const char *text, const char *word)
+{
+  char *newobj = make_completion_match_str_1 (match_name.get (), text, word);
+  if (newobj == NULL)
+    return std::move (match_name);
+  return gdb::unique_xmalloc_ptr<char> (newobj);
+}
+
+/* See complete.h.  */
+
+completion_result
+complete (const char *line, char const **word, int *quote_char)
+{
+  completion_tracker tracker_handle_brkchars;
+  completion_tracker tracker_handle_completions;
+  completion_tracker *tracker;
+
+  /* The WORD should be set to the end of word to complete.  We initialize
+     to the completion point which is assumed to be at the end of LINE.
+     This leaves WORD to be initialized to a sensible value in cases
+     completion_find_completion_word() fails i.e., throws an exception.
+     See bug 24587. */
+  *word = line + strlen (line);
+
+  try
+    {
+      *word = completion_find_completion_word (tracker_handle_brkchars,
+                                             line, quote_char);
+
+      /* Completers that provide a custom word point in the
+        handle_brkchars phase also compute their completions then.
+        Completers that leave the completion word handling to readline
+        must be called twice.  */
+      if (tracker_handle_brkchars.use_custom_word_point ())
+       tracker = &tracker_handle_brkchars;
+      else
+       {
+         complete_line (tracker_handle_completions, *word, line, strlen (line));
+         tracker = &tracker_handle_completions;
+       }
+    }
+  catch (const gdb_exception &ex)
+    {
+      return {};
+    }
+
+  return tracker->build_completion_result (*word, *word - line, strlen (line));
+}
+
+
 /* Generate completions all at once.  Does nothing if max_completions
    is 0.  If max_completions is non-negative, this will collect at
    most max_completions strings.
@@ -1604,10 +1769,7 @@ signal_completer (struct cmd_list_element *ignore,
        continue;
 
       if (strncasecmp (signame, word, len) == 0)
-       {
-         gdb::unique_xmalloc_ptr<char> copy (xstrdup (signame));
-         tracker.add_completion (std::move (copy));
-       }
+       tracker.add_completion (make_unique_xstrdup (signame));
     }
 }
 
@@ -1646,10 +1808,7 @@ reg_or_group_completer_1 (completion_tracker &tracker,
           i++)
        {
          if (*name != '\0' && strncmp (word, name, len) == 0)
-           {
-             gdb::unique_xmalloc_ptr<char> copy (xstrdup (name));
-             tracker.add_completion (std::move (copy));
-           }
+           tracker.add_completion (make_unique_xstrdup (name));
        }
     }
 
@@ -1663,10 +1822,7 @@ reg_or_group_completer_1 (completion_tracker &tracker,
        {
          name = reggroup_name (group);
          if (strncmp (word, name, len) == 0)
-           {
-             gdb::unique_xmalloc_ptr<char> copy (xstrdup (name));
-             tracker.add_completion (std::move (copy));
-           }
+           tracker.add_completion (make_unique_xstrdup (name));
        }
     }
 }
@@ -1754,6 +1910,9 @@ gdb_completion_word_break_characters_throw ()
     {
       gdb_assert (tracker.custom_word_point () > 0);
       rl_point = tracker.custom_word_point () - 1;
+
+      gdb_assert (rl_point >= 0 && rl_point < strlen (rl_line_buffer));
+
       gdb_custom_word_point_brkchars[0] = rl_line_buffer[rl_point];
       rl_completer_word_break_characters = gdb_custom_word_point_brkchars;
       rl_completer_quote_characters = NULL;
@@ -1780,17 +1939,16 @@ gdb_completion_word_break_characters ()
   /* New completion starting.  */
   current_completion.aborted = false;
 
-  TRY
+  try
     {
       return gdb_completion_word_break_characters_throw ();
     }
-  CATCH (ex, RETURN_MASK_ALL)
+  catch (const gdb_exception &ex)
     {
       /* Set this to that gdb_rl_attempted_completion_function knows
         to abort early.  */
       current_completion.aborted = true;
     }
-  END_CATCH
 
   return NULL;
 }
@@ -1824,21 +1982,23 @@ completion_find_completion_word (completion_tracker &tracker, const char *text,
 /* See completer.h.  */
 
 void
-completion_tracker::recompute_lowest_common_denominator (const char *new_match)
+completion_tracker::recompute_lowest_common_denominator
+  (gdb::unique_xmalloc_ptr<char> &&new_match_up)
 {
   if (m_lowest_common_denominator == NULL)
     {
       /* We don't have a lowest common denominator yet, so simply take
-        the whole NEW_MATCH as being it.  */
-      m_lowest_common_denominator = xstrdup (new_match);
+        the whole NEW_MATCH_UP as being it.  */
+      m_lowest_common_denominator = new_match_up.release ();
       m_lowest_common_denominator_unique = true;
     }
   else
     {
       /* Find the common denominator between the currently-known
-        lowest common denominator and NEW_MATCH.  That becomes the
+        lowest common denominator and NEW_MATCH_UP.  That becomes the
         new lowest common denominator.  */
       size_t i;
+      const char *new_match = new_match_up.get ();
 
       for (i = 0;
           (new_match[i] != '\0'
@@ -1856,7 +2016,7 @@ completion_tracker::recompute_lowest_common_denominator (const char *new_match)
 /* See completer.h.  */
 
 void
-completion_tracker::advance_custom_word_point_by (size_t len)
+completion_tracker::advance_custom_word_point_by (int len)
 {
   m_custom_word_point += len;
 }
@@ -1903,7 +2063,7 @@ expand_preserving_ws (const char *orig, size_t orig_len,
        {
          while (p_orig < orig_end && *p_orig == ' ')
            res += *p_orig++;
-         p_lcd = skip_spaces_const (p_lcd);
+         p_lcd = skip_spaces (p_lcd);
        }
       else
        {
@@ -1951,7 +2111,7 @@ completion_tracker::build_completion_result (const char *text,
       /* We don't rely on readline appending the quote char as
         delimiter as then readline wouldn't append the ' ' after the
         completion.  */
-      char buf[2] = { quote_char () };
+      char buf[2] = { (char) quote_char () };
 
       match_list[0] = reconcat (match_list[0], match_list[0],
                                buf, (char *) NULL);
@@ -2126,14 +2286,13 @@ gdb_rl_attempted_completion_function (const char *text, int start, int end)
   if (current_completion.aborted)
     return NULL;
 
-  TRY
+  try
     {
       return gdb_rl_attempted_completion_function_throw (text, start, end);
     }
-  CATCH (ex, RETURN_MASK_ALL)
+  catch (const gdb_exception &ex)
     {
     }
-  END_CATCH
 
   return NULL;
 }
This page took 0.034552 seconds and 4 git commands to generate.