ubsan: nds32: left shift cannot be represented in type 'int'
[deliverable/binutils-gdb.git] / gdb / completer.c
index 6d87174253c5461a80b57b09462cdd611e6e53b1..6658da6d7fb7d7e36c4b3d377658692935efa4b3 100644 (file)
@@ -22,7 +22,7 @@
 #include "expression.h"
 #include "filenames.h"         /* For DOSish file names.  */
 #include "language.h"
-#include "common/gdb_signals.h"
+#include "gdbsupport/gdb_signals.h"
 #include "target.h"
 #include "reggroups.h"
 #include "user-regs.h"
@@ -102,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
@@ -352,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)
 {
@@ -394,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
@@ -798,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.  */
@@ -1025,7 +1085,7 @@ complete_expression (completion_tracker &tracker,
     {
       type = parse_expression_for_completion (text, &fieldname, &code);
     }
-  catch (const gdb_exception_RETURN_MASK_ERROR &except)
+  catch (const gdb_exception_error &except)
     {
       return;
     }
@@ -1081,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
@@ -1241,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());
@@ -1304,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)
        {
@@ -1392,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);
@@ -1448,10 +1494,10 @@ complete_line_internal (completion_tracker &tracker,
     {
       complete_line_internal_1 (tracker, text, line_buffer, point, reason);
     }
-  catch (const gdb_exception_RETURN_MASK_ERROR &except)
+  catch (const gdb_exception_error &except)
     {
       if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
-       throw_exception (except);
+       throw;
     }
 }
 
@@ -1613,6 +1659,48 @@ make_completion_match_str (gdb::unique_xmalloc_ptr<char> &&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.
@@ -1681,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));
     }
 }
 
@@ -1723,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));
        }
     }
 
@@ -1740,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));
        }
     }
 }
@@ -1831,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;
@@ -1861,7 +1943,7 @@ gdb_completion_word_break_characters ()
     {
       return gdb_completion_word_break_characters_throw ();
     }
-  catch (const gdb_exception_RETURN_MASK_ALL &ex)
+  catch (const gdb_exception &ex)
     {
       /* Set this to that gdb_rl_attempted_completion_function knows
         to abort early.  */
@@ -1934,7 +2016,7 @@ completion_tracker::recompute_lowest_common_denominator
 /* 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;
 }
@@ -2208,7 +2290,7 @@ gdb_rl_attempted_completion_function (const char *text, int start, int end)
     {
       return gdb_rl_attempted_completion_function_throw (text, start, end);
     }
-  catch (const gdb_exception_RETURN_MASK_ALL &ex)
+  catch (const gdb_exception &ex)
     {
     }
 
This page took 0.035432 seconds and 4 git commands to generate.