* language.h (struct language_defn): Add new field
authorJoel Brobecker <brobecker@gnat.com>
Tue, 5 Feb 2008 22:17:41 +0000 (22:17 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 5 Feb 2008 22:17:41 +0000 (22:17 +0000)
        la_make_symbol_completion_list.
        * symtab.c (default_make_symbol_completion_list): Renames
        make_symbol_completion_list.
        (make_symbol_completion_list): New function.
        * symtab.h (default_make_symbol_completion_list): Add declaration.
        * langauge.c (unknown_language): Set la_make_symbol_completion_list.
        (auto_language, local_language): Likewise.
        * objc-lang.c (objc_language_defn): Likewise.
        * scm-lang.c (scm_language_defn): Likewise.
        * m2-lang.c (m2_language_defn): Likewise.
        * f-lang.c (f_language_defn): Likewise.
        * jv-lang.c (java_language_defn): Likewise.
        * p-lang.c (pascal_language_defn): Likewise.
        * c-lang.c (c_language_defn, cplus_language_defn, asm_language_defn)
        (minimal_language_defn): Likewise.
        * ada-lang.c (struct string_vector): New structure.
        (new_string_vector, string_vector_append, ada_unqualified_name)
        (add_angle_brackets, symbol_completion_match, symbol_completion_add)
        (ada_make_symbol_completion_list): New functions.
        (ada_language_defn): Set la_make_symbol_completion_list.
        * ada-lang.h (ada_make_symbol_completion_list): Remove declaration,
        this function is static.

14 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/ada-lang.h
gdb/c-lang.c
gdb/f-lang.c
gdb/jv-lang.c
gdb/language.c
gdb/language.h
gdb/m2-lang.c
gdb/objc-lang.c
gdb/p-lang.c
gdb/scm-lang.c
gdb/symtab.c
gdb/symtab.h

index ae3c56e..41fb91c 100644 (file)
@@ -1,3 +1,29 @@
+2007-02-05  Joel Brobecker  <brobecker@adacore.com>
+
+       * language.h (struct language_defn): Add new field
+       la_make_symbol_completion_list.
+       * symtab.c (default_make_symbol_completion_list): Renames
+       make_symbol_completion_list.
+       (make_symbol_completion_list): New function.
+       * symtab.h (default_make_symbol_completion_list): Add declaration.
+       * langauge.c (unknown_language): Set la_make_symbol_completion_list.
+       (auto_language, local_language): Likewise.
+       * objc-lang.c (objc_language_defn): Likewise.
+       * scm-lang.c (scm_language_defn): Likewise.
+       * m2-lang.c (m2_language_defn): Likewise.
+       * f-lang.c (f_language_defn): Likewise.
+       * jv-lang.c (java_language_defn): Likewise.
+       * p-lang.c (pascal_language_defn): Likewise.
+       * c-lang.c (c_language_defn, cplus_language_defn, asm_language_defn)
+       (minimal_language_defn): Likewise.
+       * ada-lang.c (struct string_vector): New structure.
+       (new_string_vector, string_vector_append, ada_unqualified_name)
+       (add_angle_brackets, symbol_completion_match, symbol_completion_add)
+       (ada_make_symbol_completion_list): New functions.
+       (ada_language_defn): Set la_make_symbol_completion_list.
+       * ada-lang.h (ada_make_symbol_completion_list): Remove declaration,
+       this function is static.
+
 2008-02-05  Kevin Buettner  <kevinb@redhat.com>
 
        * mn10300-tdep.c (mn10300_push_dummy_call): Adjust stack pointer
index 7880645..44a3cc5 100644 (file)
 #define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
 #endif
 
+/* A structure that contains a vector of strings.
+   The main purpose of this type is to group the vector and its
+   associated parameters in one structure.  This makes it easier
+   to handle and pass around.
+   
+   brobecker/2008-02-04:  GDB does provide a generic VEC which should be
+   preferable.  But we are using the string_vector structure in the context
+   of symbol completion, and the current infrastructure is such that it's
+   more convenient to use the string vector for now.  It would become
+   advantageous to switch to VECs if the rest of the completion-related
+   code switches to VECs as well.  */
+
+struct string_vector
+{
+  char **array; /* The vector itself.  */
+  int index;    /* Index of the next available element in the array.  */
+  size_t size;  /* The number of entries allocated in the array.  */
+};
 
 static void extract_string (CORE_ADDR addr, char *buf);
 
@@ -316,6 +334,65 @@ static struct obstack symbol_list_obstack;
 
                         /* Utilities */
 
+/* Create a new empty string_vector struct with an initial size of
+   INITIAL_SIZE.  */
+
+static struct string_vector
+new_string_vector (int initial_size)
+{
+  struct string_vector result;
+
+  result.array = (char **) xmalloc ((initial_size + 1) * sizeof (char *));
+  result.index = 0;
+  result.size = initial_size;
+
+  return result;
+}
+
+/* Add STR at the end of the given string vector SV.  If SV is already
+   full, its size is automatically increased (doubled).  */
+
+static void
+string_vector_append (struct string_vector *sv, char *str)
+{
+  if (sv->index >= sv->size)
+    GROW_VECT (sv->array, sv->size, sv->size * 2);
+
+  sv->array[sv->index] = str;
+  sv->index++;
+}
+
+/* Given DECODED_NAME a string holding a symbol name in its
+   decoded form (ie using the Ada dotted notation), returns
+   its unqualified name.  */
+
+static const char *
+ada_unqualified_name (const char *decoded_name)
+{
+  const char *result = strrchr (decoded_name, '.');
+
+  if (result != NULL)
+    result++;                   /* Skip the dot...  */
+  else
+    result = decoded_name;
+
+  return result;
+}
+
+/* Return a string starting with '<', followed by STR, and '>'.
+   The result is good until the next call.  */
+
+static char *
+add_angle_brackets (const char *str)
+{
+  static char *result = NULL;
+
+  xfree (result);
+  result = (char *) xmalloc ((strlen (str) + 3) * sizeof (char));
+
+  sprintf (result, "<%s>", str);
+  return result;
+}
 
 static char *
 ada_get_gdb_completer_word_break_characters (void)
@@ -5340,6 +5417,290 @@ ada_add_block_symbols (struct obstack *obstackp,
     }
 }
 \f
+
+                                /* Symbol Completion */
+
+/* If SYM_NAME is a completion candidate for TEXT, return this symbol
+   name in a form that's appropriate for the completion.  The result
+   does not need to be deallocated, but is only good until the next call.
+
+   TEXT_LEN is equal to the length of TEXT.
+   Perform a wild match if WILD_MATCH is set.
+   ENCODED should be set if TEXT represents the start of a symbol name
+   in its encoded form.  */
+
+static const char *
+symbol_completion_match (const char *sym_name,
+                         const char *text, int text_len,
+                         int wild_match, int encoded)
+{
+  char *result;
+  const int verbatim_match = (text[0] == '<');
+  int match = 0;
+
+  if (verbatim_match)
+    {
+      /* Strip the leading angle bracket.  */
+      text = text + 1;
+      text_len--;
+    }
+
+  /* First, test against the fully qualified name of the symbol.  */
+
+  if (strncmp (sym_name, text, text_len) == 0)
+    match = 1;
+
+  if (match && !encoded)
+    {
+      /* One needed check before declaring a positive match is to verify
+         that iff we are doing a verbatim match, the decoded version
+         of the symbol name starts with '<'.  Otherwise, this symbol name
+         is not a suitable completion.  */
+      const char *sym_name_copy = sym_name;
+      int has_angle_bracket;
+
+      sym_name = ada_decode (sym_name);
+      has_angle_bracket = (sym_name[0] == '<');
+      match = (has_angle_bracket == verbatim_match);
+      sym_name = sym_name_copy;
+    }
+
+  if (match && !verbatim_match)
+    {
+      /* When doing non-verbatim match, another check that needs to
+         be done is to verify that the potentially matching symbol name
+         does not include capital letters, because the ada-mode would
+         not be able to understand these symbol names without the
+         angle bracket notation.  */
+      const char *tmp;
+
+      for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
+      if (*tmp != '\0')
+        match = 0;
+    }
+
+  /* Second: Try wild matching...  */
+
+  if (!match && wild_match)
+    {
+      /* Since we are doing wild matching, this means that TEXT
+         may represent an unqualified symbol name.  We therefore must
+         also compare TEXT against the unqualified name of the symbol.  */
+      sym_name = ada_unqualified_name (ada_decode (sym_name));
+
+      if (strncmp (sym_name, text, text_len) == 0)
+        match = 1;
+    }
+
+  /* Finally: If we found a mach, prepare the result to return.  */
+
+  if (!match)
+    return NULL;
+
+  if (verbatim_match)
+    sym_name = add_angle_brackets (sym_name);
+
+  if (!encoded)
+    sym_name = ada_decode (sym_name);
+
+  return sym_name;
+}
+
+/* A companion function to ada_make_symbol_completion_list().
+   Check if SYM_NAME represents a symbol which name would be suitable
+   to complete TEXT (TEXT_LEN is the length of TEXT), in which case
+   it is appended at the end of the given string vector SV.
+
+   ORIG_TEXT is the string original string from the user command
+   that needs to be completed.  WORD is the entire command on which
+   completion should be performed.  These two parameters are used to
+   determine which part of the symbol name should be added to the
+   completion vector.
+   if WILD_MATCH is set, then wild matching is performed.
+   ENCODED should be set if TEXT represents a symbol name in its
+   encoded formed (in which case the completion should also be
+   encoded).  */
+
+static void
+symbol_completion_add (struct string_vector *sv,
+                       const char *sym_name,
+                       const char *text, int text_len,
+                       const char *orig_text, const char *word,
+                       int wild_match, int encoded)
+{
+  const char *match = symbol_completion_match (sym_name, text, text_len,
+                                               wild_match, encoded);
+  char *completion;
+
+  if (match == NULL)
+    return;
+
+  /* We found a match, so add the appropriate completion to the given
+     string vector.  */
+
+  if (word == orig_text)
+    {
+      completion = xmalloc (strlen (match) + 5);
+      strcpy (completion, match);
+    }
+  else if (word > orig_text)
+    {
+      /* Return some portion of sym_name.  */
+      completion = xmalloc (strlen (match) + 5);
+      strcpy (completion, match + (word - orig_text));
+    }
+  else
+    {
+      /* Return some of ORIG_TEXT plus sym_name.  */
+      completion = xmalloc (strlen (match) + (orig_text - word) + 5);
+      strncpy (completion, word, orig_text - word);
+      completion[orig_text - word] = '\0';
+      strcat (completion, match);
+    }
+
+  string_vector_append (sv, completion);
+}
+
+/* Return a list of possible symbol names completing TEXT0.  The list
+   is NULL terminated.  WORD is the entire command on which completion
+   is made.  */
+
+static char **
+ada_make_symbol_completion_list (char *text0, char *word)
+{
+  char *text;
+  int text_len;
+  int wild_match;
+  int encoded;
+  struct string_vector result = new_string_vector (128);
+  struct symbol *sym;
+  struct symtab *s;
+  struct partial_symtab *ps;
+  struct minimal_symbol *msymbol;
+  struct objfile *objfile;
+  struct block *b, *surrounding_static_block = 0;
+  int i;
+  struct dict_iterator iter;
+
+  if (text0[0] == '<')
+    {
+      text = xstrdup (text0);
+      make_cleanup (xfree, text);
+      text_len = strlen (text);
+      wild_match = 0;
+      encoded = 1;
+    }
+  else
+    {
+      text = xstrdup (ada_encode (text0));
+      make_cleanup (xfree, text);
+      text_len = strlen (text);
+      for (i = 0; i < text_len; i++)
+        text[i] = tolower (text[i]);
+
+      encoded = (strstr (text0, "__") != NULL);
+      /* If the name contains a ".", then the user is entering a fully
+         qualified entity name, and the match must not be done in wild
+         mode.  Similarly, if the user wants to complete what looks like
+         an encoded name, the match must not be done in wild mode.  */
+      wild_match = (strchr (text0, '.') == NULL && !encoded);
+    }
+
+  /* First, look at the partial symtab symbols.  */
+  ALL_PSYMTABS (objfile, ps)
+  {
+    struct partial_symbol **psym;
+
+    /* If the psymtab's been read in we'll get it when we search
+       through the blockvector.  */
+    if (ps->readin)
+      continue;
+
+    for (psym = objfile->global_psymbols.list + ps->globals_offset;
+         psym < (objfile->global_psymbols.list + ps->globals_offset
+                 + ps->n_global_syms); psym++)
+      {
+        QUIT;
+        symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
+                               text, text_len, text0, word,
+                               wild_match, encoded);
+      }
+
+    for (psym = objfile->static_psymbols.list + ps->statics_offset;
+         psym < (objfile->static_psymbols.list + ps->statics_offset
+                 + ps->n_static_syms); psym++)
+      {
+        QUIT;
+        symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
+                               text, text_len, text0, word,
+                               wild_match, encoded);
+      }
+  }
+
+  /* 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
+     handled by the psymtab code above).  */
+
+  ALL_MSYMBOLS (objfile, msymbol)
+  {
+    QUIT;
+    symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (msymbol),
+                           text, text_len, text0, word, wild_match, encoded);
+  }
+
+  /* Search upwards from currently selected frame (so that we can
+     complete on local vars.  */
+
+  for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+    {
+      if (!BLOCK_SUPERBLOCK (b))
+        surrounding_static_block = b;   /* For elmin of dups */
+
+      ALL_BLOCK_SYMBOLS (b, iter, sym)
+      {
+        symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
+                               text, text_len, text0, word,
+                               wild_match, encoded);
+      }
+    }
+
+  /* Go through the symtabs and check the externs and statics for
+     symbols which match.  */
+
+  ALL_SYMTABS (objfile, s)
+  {
+    QUIT;
+    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+    ALL_BLOCK_SYMBOLS (b, iter, sym)
+    {
+      symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
+                             text, text_len, text0, word,
+                             wild_match, encoded);
+    }
+  }
+
+  ALL_SYMTABS (objfile, s)
+  {
+    QUIT;
+    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+    /* Don't do this block twice.  */
+    if (b == surrounding_static_block)
+      continue;
+    ALL_BLOCK_SYMBOLS (b, iter, sym)
+    {
+      symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
+                             text, text_len, text0, word,
+                             wild_match, encoded);
+    }
+  }
+
+  /* Append the closing NULL entry.  */
+  string_vector_append (&result, NULL);
+
+  return (result.array);
+}
+
                                 /* Field Access */
 
 /* Return non-zero if TYPE is a pointer to the GNAT dispatch table used
@@ -10676,6 +11037,7 @@ const struct language_defn ada_language_defn = {
   0,                            /* c-style arrays */
   1,                            /* String lower bound */
   ada_get_gdb_completer_word_break_characters,
+  ada_make_symbol_completion_list,
   ada_language_arch_info,
   ada_print_array_index,
   default_pass_by_reference,
index 515f698..c2d08c3 100644 (file)
@@ -312,9 +312,6 @@ extern enum language ada_update_initial_language (enum language,
 
 extern void clear_ada_sym_cache (void);
 
-extern char **ada_make_symbol_completion_list (const char *text0,
-                                               const char *word);
-
 extern int ada_lookup_symbol_list (const char *, const struct block *,
                                    domain_enum, struct ada_symbol_info**);
 
index bf07cb3..c4ef9d6 100644 (file)
@@ -423,6 +423,7 @@ const struct language_defn c_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
@@ -535,6 +536,7 @@ const struct language_defn cplus_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   cplus_language_arch_info,
   default_print_array_index,
   cp_pass_by_reference,
@@ -569,6 +571,7 @@ const struct language_defn asm_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info, /* FIXME: la_language_arch_info.  */
   default_print_array_index,
   default_pass_by_reference,
@@ -608,6 +611,7 @@ const struct language_defn minimal_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
index fb169fb..038126c 100644 (file)
@@ -333,6 +333,7 @@ const struct language_defn f_language_defn =
   0,                           /* arrays are first-class (not c-style) */
   1,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   f_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
index 058ccac..e6c6f7d 100644 (file)
@@ -1079,6 +1079,7 @@ const struct language_defn java_language_defn =
   0,                           /* not c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
index cc94546..a26218d 100644 (file)
@@ -1201,6 +1201,7 @@ const struct language_defn unknown_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   unknown_language_arch_info,  /* la_language_arch_info.  */
   default_print_array_index,
   default_pass_by_reference,
@@ -1236,6 +1237,7 @@ const struct language_defn auto_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   unknown_language_arch_info,  /* la_language_arch_info.  */
   default_print_array_index,
   default_pass_by_reference,
@@ -1270,6 +1272,7 @@ const struct language_defn local_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   unknown_language_arch_info,  /* la_language_arch_info.  */
   default_print_array_index,
   default_pass_by_reference,
index 1639d4c..f7e654d 100644 (file)
@@ -249,6 +249,11 @@ struct language_defn
     /* The list of characters forming word boundaries.  */
     char *(*la_word_break_characters) (void);
 
+    /* Should return a NULL terminated array of all symbols which
+       are possible completions for TEXT.  WORD is the entire command
+       on which the completion is being made.  */
+    char **(*la_make_symbol_completion_list) (char *text, char *word);
+
     /* The per-architecture (OS/ABI) language information.  */
     void (*la_language_arch_info) (struct gdbarch *,
                                   struct language_arch_info *);
index bdb1cbd..6b51fd5 100644 (file)
@@ -384,6 +384,7 @@ const struct language_defn m2_language_defn =
   0,                           /* arrays are first-class (not c-style) */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   m2_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
index 89d06a7..ccf8068 100644 (file)
@@ -518,6 +518,7 @@ const struct language_defn objc_language_defn = {
   1,                           /* C-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
index b8884bd..f7b901f 100644 (file)
@@ -423,6 +423,7 @@ const struct language_defn pascal_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   pascal_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
index a42f87f..339c614 100644 (file)
@@ -262,6 +262,7 @@ const struct language_defn scm_language_defn =
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
   default_word_break_characters,
+  default_make_symbol_completion_list,
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
index 3912ebd..40e31dc 100644 (file)
@@ -3523,17 +3523,13 @@ language_search_unquoted_string (char *text, char *p)
   return p;
 }
 
-
-/* Return a NULL terminated array of all symbols (regardless of class)
-   which begin by matching TEXT.  If the answer is no symbols, then
-   the return value is an array which contains only a NULL pointer.
-
-   Problem: All of the symbols have to be copied because readline frees them.
-   I'm not going to worry about this; hopefully there won't be that many.  */
-
 char **
-make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list (char *text, char *word)
 {
+  /* Problem: All of the symbols have to be copied because readline
+     frees them.  I'm not going to worry about this; hopefully there
+     won't be that many.  */
+
   struct symbol *sym;
   struct symtab *s;
   struct partial_symtab *ps;
@@ -3548,8 +3544,7 @@ make_symbol_completion_list (char *text, char *word)
   /* Length of sym_text.  */
   int sym_text_len;
 
-  /* Now look for the symbol we are supposed to complete on.
-     FIXME: This should be language-specific.  */
+  /* Now look for the symbol we are supposed to complete on.  */
   {
     char *p;
     char quote_found;
@@ -3717,6 +3712,16 @@ make_symbol_completion_list (char *text, char *word)
   return (return_val);
 }
 
+/* Return a NULL terminated array of all symbols (regardless of class)
+   which begin by matching TEXT.  If the answer is no symbols, then
+   the return value is an array which contains only a NULL pointer.  */
+
+char **
+make_symbol_completion_list (char *text, char *word)
+{
+  return current_language->la_make_symbol_completion_list (text, word);
+}
+
 /* Like make_symbol_completion_list, but returns a list of symbols
    defined in a source file FILE.  */
 
index 5de08ab..c19e741 100644 (file)
@@ -1322,6 +1322,7 @@ extern void forget_cached_source_info (void);
 
 extern void select_source_symtab (struct symtab *);
 
+extern char **default_make_symbol_completion_list (char *, char *);
 extern char **make_symbol_completion_list (char *, char *);
 
 extern char **make_file_symbol_completion_list (char *, char *, char *);