Index: ada-lang.c =================================================================== --- ada-lang.c (revision 12) +++ ada-lang.c (revision 13) @@ -68,6 +68,17 @@ #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. */ + +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); @@ -315,6 +326,65 @@ static struct obstack symbol_list_obstac /* 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) @@ -5275,6 +5345,289 @@ ada_add_block_symbols (struct obstack *o } } + + /* 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]); + + /* FIXME: brobecker/2003-09-17: When we get rid of ADA_RETAIN_DOTS, + we can restrict the wild_match check to searching "__" only. */ + wild_match = (strstr (text0, "__") == NULL + && strchr (text0, '.') == NULL); + encoded = (strstr (text0, "__") != NULL); + } + + /* 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 */ /* True if field number FIELD_NUM in struct or union type TYPE is supposed @@ -10510,6 +10863,7 @@ const struct language_defn ada_language_ 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: ada-lang.h =================================================================== --- ada-lang.h (revision 12) +++ ada-lang.h (revision 13) @@ -311,9 +311,6 @@ extern enum language ada_update_initial_ 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: objc-lang.c =================================================================== --- objc-lang.c (revision 12) +++ objc-lang.c (revision 13) @@ -517,6 +517,7 @@ const struct language_defn objc_language 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: scm-lang.c =================================================================== --- scm-lang.c (revision 12) +++ scm-lang.c (revision 13) @@ -262,6 +262,7 @@ const struct language_defn scm_language_ 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: m2-lang.c =================================================================== --- m2-lang.c (revision 12) +++ m2-lang.c (revision 13) @@ -384,6 +384,7 @@ const struct language_defn m2_language_d 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: f-lang.c =================================================================== --- f-lang.c (revision 12) +++ f-lang.c (revision 13) @@ -333,6 +333,7 @@ const struct language_defn f_language_de 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: jv-lang.c =================================================================== --- jv-lang.c (revision 12) +++ jv-lang.c (revision 13) @@ -1079,6 +1079,7 @@ const struct language_defn java_language 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: language.c =================================================================== --- language.c (revision 12) +++ language.c (revision 13) @@ -1197,6 +1197,7 @@ const struct language_defn unknown_langu 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, @@ -1232,6 +1233,7 @@ const struct language_defn auto_language 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, @@ -1266,6 +1268,7 @@ const struct language_defn local_languag 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: language.h =================================================================== --- language.h (revision 12) +++ language.h (revision 13) @@ -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: symtab.c =================================================================== --- symtab.c (revision 12) +++ symtab.c (revision 13) @@ -3505,17 +3505,13 @@ language_search_unquoted_string (char *t 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; @@ -3699,6 +3695,16 @@ make_symbol_completion_list (char *text, 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: symtab.h =================================================================== --- symtab.h (revision 12) +++ symtab.h (revision 13) @@ -1322,6 +1322,7 @@ extern void forget_cached_source_info (v 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 *); Index: p-lang.c =================================================================== --- p-lang.c (revision 12) +++ p-lang.c (revision 13) @@ -423,6 +423,7 @@ const struct language_defn pascal_langua 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: c-lang.c =================================================================== --- c-lang.c (revision 12) +++ c-lang.c (revision 13) @@ -423,6 +423,7 @@ const struct language_defn c_language_de 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_languag 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_ 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_langu 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,