"complete" command and completion word break characters
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 44809aeaff52983a15b76ff2dd53a875e5f02794..57fb355328f16fa82cc906ac9184516bdb681998 100644 (file)
@@ -4747,44 +4747,13 @@ compare_symbol_name (const char *name, const char *sym_text, int sym_text_len)
   return 1;
 }
 
-/* Free any memory associated with a completion list.  */
-
-static void
-free_completion_list (VEC (char_ptr) **list_ptr)
-{
-  int i;
-  char *p;
-
-  for (i = 0; VEC_iterate (char_ptr, *list_ptr, i, p); ++i)
-    xfree (p);
-  VEC_free (char_ptr, *list_ptr);
-}
-
-/* Callback for make_cleanup.  */
-
-static void
-do_free_completion_list (void *list)
-{
-  free_completion_list ((VEC (char_ptr) **) list);
-}
-
-static VEC (char_ptr) *return_val;
-
-/* Tracker for how many unique completions have been generated.  Used
-   to terminate completion list generation early if the list has grown
-   to a size so large as to be useless.  This helps avoid GDB seeming
-   to lock up in the event the user requests to complete on something
-   vague that necessitates the time consuming expansion of many symbol
-   tables.  */
-
-static completion_tracker_t completion_tracker;
-
 /*  Test to see if the symbol specified by SYMNAME (which is already
    demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
    characters.  If so, add it to the current completion list.  */
 
 static void
-completion_list_add_name (const char *symname,
+completion_list_add_name (completion_tracker &tracker,
+                         const char *symname,
                          const char *sym_text, int sym_text_len,
                          const char *text, const char *word)
 {
@@ -4797,7 +4766,6 @@ completion_list_add_name (const char *symname,
 
   {
     char *newobj;
-    enum maybe_add_completion_enum add_status;
 
     if (word == sym_text)
       {
@@ -4819,45 +4787,33 @@ completion_list_add_name (const char *symname,
        strcat (newobj, symname);
       }
 
-    add_status = maybe_add_completion (completion_tracker, newobj);
+    gdb::unique_xmalloc_ptr<char> completion (newobj);
 
-    switch (add_status)
-      {
-      case MAYBE_ADD_COMPLETION_OK:
-       VEC_safe_push (char_ptr, return_val, newobj);
-       break;
-      case MAYBE_ADD_COMPLETION_OK_MAX_REACHED:
-       VEC_safe_push (char_ptr, return_val, newobj);
-       throw_max_completions_reached_error ();
-      case MAYBE_ADD_COMPLETION_MAX_REACHED:
-       xfree (newobj);
-       throw_max_completions_reached_error ();
-      case MAYBE_ADD_COMPLETION_DUPLICATE:
-       xfree (newobj);
-       break;
-      }
+    tracker.add_completion (std::move (completion));
   }
 }
 
 /* completion_list_add_name wrapper for struct symbol.  */
 
 static void
-completion_list_add_symbol (symbol *sym,
+completion_list_add_symbol (completion_tracker &tracker,
+                           symbol *sym,
                            const char *sym_text, int sym_text_len,
                            const char *text, const char *word)
 {
-  completion_list_add_name (SYMBOL_NATURAL_NAME (sym),
+  completion_list_add_name (tracker, SYMBOL_NATURAL_NAME (sym),
                            sym_text, sym_text_len, text, word);
 }
 
 /* completion_list_add_name wrapper for struct minimal_symbol.  */
 
 static void
-completion_list_add_msymbol (minimal_symbol *sym,
+completion_list_add_msymbol (completion_tracker &tracker,
+                            minimal_symbol *sym,
                             const char *sym_text, int sym_text_len,
                             const char *text, const char *word)
 {
-  completion_list_add_name (MSYMBOL_NATURAL_NAME (sym),
+  completion_list_add_name (tracker, MSYMBOL_NATURAL_NAME (sym),
                            sym_text, sym_text_len, text, word);
 }
 
@@ -4865,7 +4821,8 @@ completion_list_add_msymbol (minimal_symbol *sym,
    again and feed all the selectors into the mill.  */
 
 static void
-completion_list_objc_symbol (struct minimal_symbol *msymbol,
+completion_list_objc_symbol (completion_tracker &tracker,
+                            struct minimal_symbol *msymbol,
                             const char *sym_text, int sym_text_len,
                             const char *text, const char *word)
 {
@@ -4883,7 +4840,8 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol,
 
   if (sym_text[0] == '[')
     /* Complete on shortened method method.  */
-    completion_list_add_name (method + 1, sym_text, sym_text_len, text, word);
+    completion_list_add_name (tracker, method + 1,
+                             sym_text, sym_text_len, text, word);
 
   while ((strlen (method) + 1) >= tmplen)
     {
@@ -4904,9 +4862,11 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol,
       memcpy (tmp, method, (category - method));
       tmp[category - method] = ' ';
       memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1);
-      completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+      completion_list_add_name (tracker, tmp,
+                               sym_text, sym_text_len, text, word);
       if (sym_text[0] == '[')
-       completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word);
+       completion_list_add_name (tracker, tmp + 1,
+                                 sym_text, sym_text_len, text, word);
     }
 
   if (selector != NULL)
@@ -4917,7 +4877,8 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol,
       if (tmp2 != NULL)
        *tmp2 = '\0';
 
-      completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+      completion_list_add_name (tracker, tmp,
+                               sym_text, sym_text_len, text, word);
     }
 }
 
@@ -4968,9 +4929,10 @@ language_search_unquoted_string (const char *text, const char *p)
 }
 
 static void
-completion_list_add_fields (struct symbol *sym, const char *sym_text,
-                           int sym_text_len, const char *text,
-                           const char *word)
+completion_list_add_fields (completion_tracker &tracker,
+                           struct symbol *sym,
+                           const char *sym_text, int sym_text_len,
+                           const char *text, const char *word)
 {
   if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
     {
@@ -4981,7 +4943,7 @@ completion_list_add_fields (struct symbol *sym, const char *sym_text,
       if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
        for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
          if (TYPE_FIELD_NAME (t, j))
-           completion_list_add_name (TYPE_FIELD_NAME (t, j),
+           completion_list_add_name (tracker, TYPE_FIELD_NAME (t, j),
                                      sym_text, sym_text_len, text, word);
     }
 }
@@ -4990,6 +4952,7 @@ completion_list_add_fields (struct symbol *sym, const char *sym_text,
 
 static void
 add_symtab_completions (struct compunit_symtab *cust,
+                       completion_tracker &tracker,
                        const char *sym_text, int sym_text_len,
                        const char *text, const char *word,
                        enum type_code code)
@@ -5011,18 +4974,18 @@ add_symtab_completions (struct compunit_symtab *cust,
          if (code == TYPE_CODE_UNDEF
              || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
                  && TYPE_CODE (SYMBOL_TYPE (sym)) == code))
-           completion_list_add_symbol (sym,
+           completion_list_add_symbol (tracker, sym,
                                        sym_text, sym_text_len,
                                        text, word);
        }
     }
 }
 
-static void
-default_make_symbol_completion_list_break_on_1 (const char *text,
-                                               const char *word,
-                                               const char *break_on,
-                                               enum type_code code)
+void
+default_collect_symbol_completion_matches_break_on
+  (completion_tracker &tracker,
+   const char *text, const char *word,
+   const char *break_on, enum type_code code)
 {
   /* Problem: All of the symbols have to be copied because readline
      frees them.  I'm not going to worry about this; hopefully there
@@ -5039,7 +5002,6 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
   const char *sym_text;
   /* Length of sym_text.  */
   int sym_text_len;
-  struct cleanup *cleanups;
 
   /* Now look for the symbol we are supposed to complete on.  */
   {
@@ -5109,9 +5071,6 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
     }
   gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '(');
 
-  completion_tracker = new_completion_tracker ();
-  cleanups = make_cleanup_free_completion_tracker (&completion_tracker);
-
   /* At this point scan through the misc symbol vectors and add each
      symbol you find to the list.  Eventually we want to ignore
      anything that isn't a text symbol (everything else will be
@@ -5122,18 +5081,21 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
       ALL_MSYMBOLS (objfile, msymbol)
        {
          QUIT;
-         completion_list_add_msymbol (msymbol, sym_text, sym_text_len, text,
-                                      word);
 
-         completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text,
-                                      word);
+         completion_list_add_msymbol (tracker,
+                                      msymbol, sym_text, sym_text_len,
+                                      text, word);
+
+         completion_list_objc_symbol (tracker,
+                                      msymbol, sym_text, sym_text_len,
+                                      text, word);
        }
     }
 
   /* Add completions for all currently loaded symbol tables.  */
   ALL_COMPUNITS (objfile, cust)
-    add_symtab_completions (cust, sym_text, sym_text_len, text, word,
-                           code);
+    add_symtab_completions (cust, tracker,
+                           sym_text, sym_text_len, text, word, code);
 
   /* Look through the partial symtabs for all symbols which begin by
      matching SYM_TEXT.  Expand all CUs that you find to the list.  */
@@ -5147,6 +5109,7 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
                           [&] (compunit_symtab *symtab) /* expansion notify */
                             {
                               add_symtab_completions (symtab,
+                                                      tracker,
                                                       sym_text, sym_text_len,
                                                       text, word, code);
                             },
@@ -5169,14 +5132,17 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
          {
            if (code == TYPE_CODE_UNDEF)
              {
-               completion_list_add_symbol (sym, sym_text, sym_text_len, text,
+               completion_list_add_symbol (tracker, sym,
+                                           sym_text, sym_text_len, text,
                                            word);
-               completion_list_add_fields (sym, sym_text, sym_text_len, text,
+               completion_list_add_fields (tracker, sym,
+                                           sym_text, sym_text_len, text,
                                            word);
              }
            else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
                     && TYPE_CODE (SYMBOL_TYPE (sym)) == code)
-             completion_list_add_symbol (sym, sym_text, sym_text_len, text,
+             completion_list_add_symbol (tracker, sym,
+                                         sym_text, sym_text_len, text,
                                          word);
          }
 
@@ -5194,11 +5160,13 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
     {
       if (surrounding_static_block != NULL)
        ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
-         completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+         completion_list_add_fields (tracker, sym,
+                                     sym_text, sym_text_len, text, word);
 
       if (surrounding_global_block != NULL)
        ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
-         completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+         completion_list_add_fields (tracker, sym,
+                                     sym_text, sym_text_len, text, word);
     }
 
   /* Skip macros if we are completing a struct tag -- arguable but
@@ -5214,7 +5182,7 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
                                 macro_source_file *,
                                 int)
        {
-         completion_list_add_name (macro_name,
+         completion_list_add_name (tracker, macro_name,
                                    sym_text, sym_text_len,
                                    text, word);
        };
@@ -5237,84 +5205,52 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
       /* User-defined macros are always visible.  */
       macro_for_each (macro_user_macros, add_macro_name);
     }
-
-  do_cleanups (cleanups);
 }
 
-VEC (char_ptr) *
-default_make_symbol_completion_list_break_on (const char *text,
-                                             const char *word,
-                                             const char *break_on,
-                                             enum type_code code)
-{
-  struct cleanup *back_to;
-
-  return_val = NULL;
-  back_to = make_cleanup (do_free_completion_list, &return_val);
-
-  TRY
-    {
-      default_make_symbol_completion_list_break_on_1 (text, word,
-                                                     break_on, code);
-    }
-  CATCH (except, RETURN_MASK_ERROR)
-    {
-      if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
-       throw_exception (except);
-    }
-  END_CATCH
-
-  discard_cleanups (back_to);
-  return return_val;
-}
-
-VEC (char_ptr) *
-default_make_symbol_completion_list (const char *text, const char *word,
-                                    enum type_code code)
+void
+default_collect_symbol_completion_matches (completion_tracker &tracker,
+                                          const char *text, const char *word,
+                                          enum type_code code)
 {
-  return default_make_symbol_completion_list_break_on (text, word, "", code);
+  return default_collect_symbol_completion_matches_break_on (tracker,
+                                                            text, word, "",
+                                                            code);
 }
 
-/* Return a vector of all symbols (regardless of class) which begin by
-   matching TEXT.  If the answer is no symbols, then the return value
-   is NULL.  */
+/* Collect all symbols (regardless of class) which begin by matching
+   TEXT.  */
 
-VEC (char_ptr) *
-make_symbol_completion_list (const char *text, const char *word)
+void
+collect_symbol_completion_matches (completion_tracker &tracker,
+                                  const char *text, const char *word)
 {
-  return current_language->la_make_symbol_completion_list (text, word,
-                                                          TYPE_CODE_UNDEF);
+  current_language->la_collect_symbol_completion_matches (tracker,
+                                                         text, word,
+                                                         TYPE_CODE_UNDEF);
 }
 
-/* Like make_symbol_completion_list, but only return STRUCT_DOMAIN
-   symbols whose type code is CODE.  */
+/* Like collect_symbol_completion_matches, but only collect
+   STRUCT_DOMAIN symbols whose type code is CODE.  */
 
-VEC (char_ptr) *
-make_symbol_completion_type (const char *text, const char *word,
-                            enum type_code code)
+void
+collect_symbol_completion_matches_type (completion_tracker &tracker,
+                                       const char *text, const char *word,
+                                       enum type_code code)
 {
   gdb_assert (code == TYPE_CODE_UNION
              || code == TYPE_CODE_STRUCT
              || code == TYPE_CODE_ENUM);
-  return current_language->la_make_symbol_completion_list (text, word, code);
-}
-
-/* Like make_symbol_completion_list, but suitable for use as a
-   completion function.  */
-
-VEC (char_ptr) *
-make_symbol_completion_list_fn (struct cmd_list_element *ignore,
-                               const char *text, const char *word)
-{
-  return make_symbol_completion_list (text, word);
+  current_language->la_collect_symbol_completion_matches (tracker,
+                                                         text, word, code);
 }
 
-/* Like make_symbol_completion_list, but returns a list of symbols
-   defined in all source files name SRCFILE.  */
+/* Like collect_symbol_completion_matches, but collects a list of
+   symbols defined in all source files named SRCFILE.  */
 
-static VEC (char_ptr) *
-make_file_symbol_completion_list_1 (const char *text, const char *word,
-                                   const char *srcfile)
+void
+collect_file_symbol_completion_matches (completion_tracker &tracker,
+                                       const char *text, const char *word,
+                                       const char *srcfile)
 {
   /* The symbol we are completing on.  Points in same buffer as text.  */
   const char *sym_text;
@@ -5355,7 +5291,7 @@ make_file_symbol_completion_list_1 (const char *text, const char *word,
       /* A double-quoted string is never a symbol, nor does it make sense
          to complete it any other way.  */
       {
-       return NULL;
+       return;
       }
     else
       {
@@ -5371,42 +5307,11 @@ make_file_symbol_completion_list_1 (const char *text, const char *word,
   iterate_over_symtabs (srcfile, [&] (symtab *s)
     {
       add_symtab_completions (SYMTAB_COMPUNIT (s),
+                             tracker,
                              sym_text, sym_text_len,
                              text, word, TYPE_CODE_UNDEF);
       return false;
     });
-
-  return (return_val);
-}
-
-/* Wrapper around make_file_symbol_completion_list_1
-   to handle MAX_COMPLETIONS_REACHED_ERROR.  */
-
-VEC (char_ptr) *
-make_file_symbol_completion_list (const char *text, const char *word,
-                                 const char *srcfile)
-{
-  struct cleanup *back_to, *cleanups;
-
-  completion_tracker = new_completion_tracker ();
-  cleanups = make_cleanup_free_completion_tracker (&completion_tracker);
-  return_val = NULL;
-  back_to = make_cleanup (do_free_completion_list, &return_val);
-
-  TRY
-    {
-      make_file_symbol_completion_list_1 (text, word, srcfile);
-    }
-  CATCH (except, RETURN_MASK_ERROR)
-    {
-      if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
-       throw_exception (except);
-    }
-  END_CATCH
-
-  discard_cleanups (back_to);
-  do_cleanups (cleanups);
-  return return_val;
 }
 
 /* A helper function for make_source_files_completion_list.  It adds
@@ -5415,7 +5320,7 @@ make_file_symbol_completion_list (const char *text, const char *word,
 
 static void
 add_filename_to_list (const char *fname, const char *text, const char *word,
-                     VEC (char_ptr) **list)
+                     completion_list *list)
 {
   char *newobj;
   size_t fnlen = strlen (fname);
@@ -5440,7 +5345,7 @@ add_filename_to_list (const char *fname, const char *text, const char *word,
       newobj[text - word] = '\0';
       strcat (newobj, fname);
     }
-  VEC_safe_push (char_ptr, *list, newobj);
+  list->emplace_back (newobj);
 }
 
 static int
@@ -5468,7 +5373,7 @@ struct add_partial_filename_data
   const char *text;
   const char *word;
   int text_len;
-  VEC (char_ptr) **list;
+  completion_list *list;
 };
 
 /* A callback for map_partial_symbol_filenames.  */
@@ -5500,19 +5405,18 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
     }
 }
 
-/* Return a vector of all source files whose names begin with matching
+/* Return a list of all source files whose names begin with matching
    TEXT.  The file names are looked up in the symbol tables of this
-   program.  If the answer is no matchess, then the return value is
-   NULL.  */
+   program.  */
 
-VEC (char_ptr) *
+completion_list
 make_source_files_completion_list (const char *text, const char *word)
 {
   struct compunit_symtab *cu;
   struct symtab *s;
   struct objfile *objfile;
   size_t text_len = strlen (text);
-  VEC (char_ptr) *list = NULL;
+  completion_list list;
   const char *base_name;
   struct add_partial_filename_data datum;
   struct cleanup *back_to;
@@ -5520,8 +5424,6 @@ make_source_files_completion_list (const char *text, const char *word)
   if (!have_full_symbols () && !have_partial_symbols ())
     return list;
 
-  back_to = make_cleanup (do_free_completion_list, &list);
-
   filename_seen_cache filenames_seen;
 
   ALL_FILETABS (objfile, cu, s)
@@ -5557,8 +5459,6 @@ make_source_files_completion_list (const char *text, const char *word)
   map_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
                        0 /*need_fullname*/);
 
-  discard_cleanups (back_to);
-
   return list;
 }
 \f
This page took 0.032247 seconds and 4 git commands to generate.