aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog26
-rw-r--r--gdb/ada-lang.c362
-rw-r--r--gdb/ada-lang.h3
-rw-r--r--gdb/c-lang.c4
-rw-r--r--gdb/f-lang.c1
-rw-r--r--gdb/jv-lang.c1
-rw-r--r--gdb/language.c3
-rw-r--r--gdb/language.h5
-rw-r--r--gdb/m2-lang.c1
-rw-r--r--gdb/objc-lang.c1
-rw-r--r--gdb/p-lang.c1
-rw-r--r--gdb/scm-lang.c1
-rw-r--r--gdb/symtab.c27
-rw-r--r--gdb/symtab.h1
14 files changed, 423 insertions, 14 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ae3c56e..41fb91c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 7880645..44a3cc5 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -68,6 +68,24 @@
#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,
}
}
+
+ /* 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,
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 515f698..c2d08c3 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -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**);
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index bf07cb3..c4ef9d6 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -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,
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index fb169fb..038126c 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -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,
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 058ccac..e6c6f7d 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -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,
diff --git a/gdb/language.c b/gdb/language.c
index cc94546..a26218d 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -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,
diff --git a/gdb/language.h b/gdb/language.h
index 1639d4c..f7e654d 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -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 *);
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index bdb1cbd..6b51fd5 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -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,
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 89d06a7..ccf8068 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -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,
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index b8884bd..f7b901f 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -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,
diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c
index a42f87f..339c614 100644
--- a/gdb/scm-lang.c
+++ b/gdb/scm-lang.c
@@ -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,
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 3912ebd..40e31dc 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -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. */
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 5de08ab..c19e741 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -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 *);