From mboxrd@z Thu Jan 1 00:00:00 1970 From: Elena Zannoni To: Eli Zaretskii Cc: gdb-patches@sources.redhat.com Subject: Re: [RFA] Improve completion of locations Date: Tue, 08 May 2001 13:32:00 -0000 Message-id: <15096.22514.59476.717438@kwikemart.cygnus.com> References: <9743-Sat05May2001210007+0300-eliz@is.elta.co.il> X-SW-Source: 2001-05/msg00102.html Eli Zaretskii writes: > I'm seeking approval for the patches below, which improve GDB's > completion of locations in commands like "break LOCATION". The two > main improvements are: > > - GDB now considers file names as well as symbol names when you > type, e.g., "break foo". If there's a symbol foo_bar and a file > foo-bar.c, both will be shown in the list of possible completions. > Only files recorded in the debug info are used for completing file > names for these commands. > > - When the user types "break foo.c:bar TAB", only symbols defined in > the source file foo.c whose names begin with "bar" will be > considered for completion. This reduces the number of possible > completions by a large factor in many typical situations (I'd even > dare to say that it makes symbol completion a useful feature ;-). > > This is the last installment of my recent completion-related frenzy. > I'm now quite happy with GDB's completion ;-) > > AFAICS, the responsible maintainers who need to approve these patches > are Fernando, Elena, Michael Snyder, and someone for printcmd.c and > infcmd.c. > Eli, one minor problem with your patch is that your sources are not up to date. The #include of completer.h in tracepoint.c and infcmd.c was removed by JT on March 27. So you will have to add it back in when you commit the patch. Using a gdb with your patch applied to debug another gdb I am getting something I don't understand: (top-gdb) b symtab. Display all 10987 possibilities? (y or n) what is it trying to do (note the '.')? Using the ':' I get a list of completions which includes: (top-gdb) b symtab.c: __builtin_va_list int _initialize_symtab keep_going add_filename_to_list long double block_found long int block_function long long int bound long long unsigned int builtin_type_error long unsigned int char lookup_block_symbol completion_list_add_name lookup_partial_symbol complex double lookup_partial_symtab complex float lookup_symbol complex int lookup_symbol_aux complex long double lookup_symtab contained_in lookup_symtab_1 cplusplus_hint lookup_transparent_type [...many more...] But why am I getting the types names, like 'char', 'long double', etc? They must be coming from the minsymbols, maybe. Do we want those? Probably not. (top-gdb) b symtab symtab symtab.h symtab_fns symtab_to_filename symtab.c symtab_and_line symtab_symbol_info symtabs_and_lines (top-gdb) b symt symtab symtab_and_line symtab_to_filename symtab.c symtab_fns symtabs_and_lines symtab.h symtab_symbol_info symtoken (top-gdb) b symtab.c:make_ make_cleanup_free_search_symbols make_symbol_completion_list make_file_symbol_completion_list make_symbol_overload_list make_source_files_completion_list These all seem to work now and didn't before, which is really neat. I think some more refinements are needed. Syntactically, there is a line I don't like : > + (*list)[*list_used += 1] = NULL; Could you just use '++'? Sorry, I don't have much more time right now to look at it in more detail. I think I am starting to understand this whole patch. I may have some more comments tomorrow. Elena > 2001-05-05 Eli Zaretskii > > * completer.c (gdb_completer_loc_break_characters): New variable. > (line_completion_function): If we are completing on locations, > back up the start of word pointer past all characters which can > appear in a location spec. > (location_completer): New function. > > * completer.h: Add prototype for location_completer. > > * symtab.c (make_source_files_completion_list) > (add_filename_to_list, not_interesting_fname): New functions. > (filename_seen): New function, body extracted from > output_source_filename. > (output_source_filename): Call filename_seen to check if the file > was already printed. > (make_symbol_completion_list): If TEXT includes a > double-quoted string, return an empty list, not NULL. > (make_file_symbol_completion_list): New function, similar to > make_symbol_completion_list but with an additional argument > SRCFILE. > > * symtab.h (make_file_symbol_completion_list) > (make_source_files_completion_list): Add prototypes. > > * breakpoint.c (_initialize_breakpoint): Make location_completer > be the completion function for all commands which set breakpoints > and watchpoints. > (top-level): #include "completer.h". > > * tracepoint.c (_initialize_tracepoint): Make location_completer > be the completion function for the "trace" command. > > * printcmd.c (_initialize_printcmd): Make location_completer be > the completion function for the "print", "inspect", "call", and > "disassemble" commands. > (top-level): #include "completer.h". > > * infcmd.c (_initialize_infcmd): Make location_completer be the > completion function for the "go", "jump", and "until" commands. > > > --- gdb/completer.c~1 Sat Feb 17 12:22:10 2001 > +++ gdb/completer.c Sat May 5 20:20:24 2001 > @@ -22,12 +22,14 @@ > #include "symtab.h" > #include "gdbtypes.h" > #include "expression.h" > +#include "filenames.h" /* for DOSish file names */ > > /* FIXME: This is needed because of lookup_cmd_1(). > We should be calling a hook instead so we eliminate the CLI dependency. */ > #include "gdbcmd.h" > > -/* Needed for rl_completer_word_break_characters() */ > +/* Needed for rl_completer_word_break_characters() and for > + filename_completion_function. */ > #include > > /* readline defines this. */ > @@ -72,6 +74,10 @@ static char *gdb_completer_file_name_bre > static char *gdb_completer_file_name_break_characters = " \t\n*|\"';:?><"; > #endif > > +/* These are used when completing on locations, which can mix file > + names and symbol names separated by a colon. */ > +static char *gdb_completer_loc_break_characters = " \t\n*|\"';:?><,"; > + > /* Characters that can be used to quote completion strings. Note that we > can't include '"' because the gdb C parser treats such quoted sequences > as strings. */ > @@ -95,8 +101,6 @@ get_gdb_completer_quote_characters (void > char ** > filename_completer (char *text, char *word) > { > - /* From readline. */ > -extern char *filename_completion_function (char *, int); > int subsequent_name; > char **return_val; > int return_val_used; > @@ -170,6 +174,151 @@ extern char *filename_completion_functio > return return_val; > } > > +/* Complete on locations, which might be of two possible forms: > + > + file:line > + or > + symbol+offset > + > + This is intended to be used in commands that set breakpoints etc. */ > +char ** > +location_completer (char *text, char *word) > +{ > + int n_syms = 0, n_files = 0; > + char ** fn_list = NULL; > + char ** list = NULL; > + char *p; > + int quote_found = 0; > + int quoted = *text == '\'' || *text == '"'; > + int quote_char = '\0'; > + char *colon = NULL; > + char *file_to_match = NULL; > + char *symbol_start = text; > + char *orig_text = text; > + size_t text_len; > + > + /* Do we have an unquoted colon, as in "break foo.c::bar"? */ > + for (p = text; *p != '\0'; ++p) > + { > + if (*p == '\\' && p[1] == '\'') > + p++; > + else if (*p == '\'' || *p == '"') > + { > + quote_found = *p; > + quote_char = *p++; > + while (*p != '\0' && *p != quote_found) > + { > + if (*p == '\\' && p[1] == quote_found) > + p++; > + p++; > + } > + > + if (*p == quote_found) > + quote_found = 0; > + } > +#if HAVE_DOS_BASED_FILE_SYSTEM > + /* If we have a DOS-style absolute file name at the beginning of > + TEXT, and the colon after the drive letter is the only colon > + we found, pretend the colon is not there. */ > + else if (p < text + 3 && *p == ':' && p == text + 1 + quoted) > + ; > +#endif > + else if (*p == ':' && !colon) > + { > + colon = p; > + symbol_start = p + 1; > + } > + else if (strchr (gdb_completer_word_break_characters, *p)) > + symbol_start = p + 1; > + } > + > + if (quoted) > + text++; > + text_len = strlen (text); > + > + /* Where is the file name? */ > + if (colon) > + { > + char *s; > + > + file_to_match = (char *) xmalloc (colon - text + 1); > + strncpy (file_to_match, text, colon - text + 1); > + /* Remove trailing colons and quotes from the file name. */ > + for (s = file_to_match + (colon - text); > + s > file_to_match; > + s--) > + if (*s == ':' || *s == quote_char) > + *s = '\0'; > + } > + /* If the text includes a colon, they want completion only on a > + symbol name after the colon. Otherwise, we need to complete on > + symbols as well as on files. */ > + if (colon) > + { > + list = make_file_symbol_completion_list (symbol_start, word, > + file_to_match); > + xfree (file_to_match); > + } > + else > + { > + list = make_symbol_completion_list (symbol_start, word); > + /* If text includes characters which cannot appear in a file > + name, they cannot be asking for completion on files. */ > + if (strcspn (text, gdb_completer_file_name_break_characters) == text_len) > + fn_list = make_source_files_completion_list (text, text); > + } > + > + /* How many completions do we have in both lists? */ > + if (fn_list) > + for ( ; fn_list[n_files]; n_files++) > + ; > + if (list) > + for ( ; list[n_syms]; n_syms++) > + ; > + > + /* Make list[] large enough to hold both lists, then catenate > + fn_list[] onto the end of list[]. */ > + if (n_syms && n_files) > + { > + list = xrealloc (list, (n_syms + n_files + 1) * sizeof (char *)); > + memcpy (list + n_syms, fn_list, (n_files + 1) * sizeof (char *)); > + xfree (fn_list); > + } > + else if (n_files) > + { > + /* If we only have file names as possible completion, we should > + bring them in sync with what rl_complete expects. The > + problem is that if the user types "break /foo/b TAB", and the > + possible completions are "/foo/bar" and "/foo/baz" > + rl_complete expects us to return "bar" and "baz", without the > + leading directories, as possible completions, because `word' > + starts at the "b". But we ignore the value of `word' when we > + call make_source_files_completion_list above (because that > + would not DTRT when the completion results in both symbols > + and file names), so make_source_files_completion_list returns > + the full "/foo/bar" and "/foo/baz" strings. This produces > + wrong results when, e.g., there's only one possible > + completion, because rl_complete will prepend "/foo/" to each > + candidate completion. The loop below removes that leading > + part. */ > + for (n_files = 0; fn_list[n_files]; n_files++) > + { > + memmove (fn_list[n_files], fn_list[n_files] + (word - text), > + strlen (fn_list[n_files]) + 1 - (word - text)); > + } > + /* Return just the file-name list as the result. */ > + list = fn_list; > + } > + else if (!n_syms) > + { > + /* No completions at all. As the final resort, try completing > + on the entire text as a symbol. */ > + list = make_symbol_completion_list (orig_text, word); > + } > + > + return list; > +} > + > /* Here are some useful test cases for completion. FIXME: These should > be put in the test suite. They should be tested with both M-? and TAB. > > @@ -362,7 +511,7 @@ line_completion_function (char *text, in > to complete the entire text after the > command, just the last word. To this > end, we need to find the beginning of the > - file name starting at `word' and going > + file name by starting at `word' and going > backwards. */ > for (p = word; > p > tmp_command > @@ -372,6 +521,16 @@ line_completion_function (char *text, in > rl_completer_word_break_characters = > gdb_completer_file_name_break_characters; > } > + else if (c->completer == location_completer) > + { > + /* Commands which complete on locations want to > + see the entire argument. */ > + for (p = word; > + p > tmp_command > + && p[-1] != ' ' && p[-1] != '\t'; > + p--) > + ; > + } > list = (*c->completer) (p, word); > } > } > @@ -430,6 +589,14 @@ line_completion_function (char *text, in > rl_completer_word_break_characters = > gdb_completer_file_name_break_characters; > } > + else if (c->completer == location_completer) > + { > + for (p = word; > + p > tmp_command > + && p[-1] != ' ' && p[-1] != '\t'; > + p--) > + ; > + } > list = (*c->completer) (p, word); > } > } > > --- gdb/completer.h~ Fri Dec 1 02:41:26 2000 > +++ gdb/completer.h Sat Apr 7 16:44:22 2001 > @@ -23,6 +23,8 @@ extern char *line_completion_function (c > > extern char **filename_completer (char *, char *); > > +extern char **location_completer (char *, char *); > + > extern char *get_gdb_completer_word_break_characters (void); > > extern char *get_gdb_completer_quote_characters (void); > > --- gdb/symtab.c~2 Fri Mar 30 14:57:20 2001 > +++ gdb/symtab.c Sat May 5 18:56:00 2001 > @@ -2161,50 +2147,72 @@ operator_chars (char *p, char **end) > } > > > -/* Slave routine for sources_info. Force line breaks at ,'s. > - NAME is the name to print and *FIRST is nonzero if this is the first > - name printed. Set *FIRST to zero. */ > -static void > -output_source_filename (char *name, int *first) > +/* If FILE is not already in the table of files, return zero; > + otherwise return non-zero. Optionally add FILE to the table if ADD > + is non-zero. If *FIRST is non-zero, forget the old table > + contents. */ > +static int > +filename_seen (const char *file, int add, int *first) > { > - /* Table of files printed so far. Since a single source file can > - result in several partial symbol tables, we need to avoid printing > - it more than once. Note: if some of the psymtabs are read in and > - some are not, it gets printed both under "Source files for which > - symbols have been read" and "Source files for which symbols will > - be read in on demand". I consider this a reasonable way to deal > - with the situation. I'm not sure whether this can also happen for > - symtabs; it doesn't hurt to check. */ > - static char **tab = NULL; > + /* Table of files seen so far. */ > + static const char **tab = NULL; > /* Allocated size of tab in elements. > Start with one 256-byte block (when using GNU malloc.c). > 24 is the malloc overhead when range checking is in effect. */ > static int tab_alloc_size = (256 - 24) / sizeof (char *); > /* Current size of tab in elements. */ > static int tab_cur_size; > - > - char **p; > + const char **p; > > if (*first) > { > if (tab == NULL) > - tab = (char **) xmalloc (tab_alloc_size * sizeof (*tab)); > + tab = (const char **) xmalloc (tab_alloc_size * sizeof (*tab)); > tab_cur_size = 0; > } > > - /* Is NAME in tab? */ > + /* Is FILE in tab? */ > for (p = tab; p < tab + tab_cur_size; p++) > - if (STREQ (*p, name)) > - /* Yes; don't print it again. */ > - return; > - /* No; add it to tab. */ > - if (tab_cur_size == tab_alloc_size) > + if (strcmp (*p, file) == 0) > + return 1; > + > + /* No; maybe add it to tab. */ > + if (add) > { > - tab_alloc_size *= 2; > - tab = (char **) xrealloc ((char *) tab, tab_alloc_size * sizeof (*tab)); > + if (tab_cur_size == tab_alloc_size) > + { > + tab_alloc_size *= 2; > + tab = (const char **) xrealloc ((char *) tab, > + tab_alloc_size * sizeof (*tab)); > + } > + tab[tab_cur_size++] = file; > } > - tab[tab_cur_size++] = name; > > + return 0; > +} > + > +/* Slave routine for sources_info. Force line breaks at ,'s. > + NAME is the name to print and *FIRST is nonzero if this is the first > + name printed. Set *FIRST to zero. */ > +static void > +output_source_filename (char *name, int *first) > +{ > + /* Since a single source file can result in several partial symbol > + tables, we need to avoid printing it more than once. Note: if > + some of the psymtabs are read in and some are not, it gets > + printed both under "Source files for which symbols have been > + read" and "Source files for which symbols will be read in on > + demand". I consider this a reasonable way to deal with the > + situation. I'm not sure whether this can also happen for > + symtabs; it doesn't hurt to check. */ > + > + /* Was NAME already seen? */ > + if (filename_seen (name, 1, first)) > + { > + /* Yes; don't print it again. */ > + return; > + } > + /* No; print it and reset *FIRST. */ > if (*first) > { > *first = 0; > @@ -2871,9 +2879,9 @@ completion_list_add_name (char *symname, > } > } > > -/* 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. > +/* 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. */ > @@ -2927,7 +2935,11 @@ make_symbol_completion_list (char *text, > else if (quote_found == '"') > /* A double-quoted string is never a symbol, nor does it make sense > to complete it any other way. */ > - return NULL; > + { > + return_val = (char **) xmalloc (sizeof (char *)); > + return_val[0] = NULL; > + return return_val; > + } > else > { > /* It is not a quoted string. Break it based on the characters > @@ -3059,6 +3071,277 @@ make_symbol_completion_list (char *text, > return (return_val); > } > > +/* Like make_symbol_completion_list, but returns a list of symbols > + defined in a source file FILE. */ > + > +char ** > +make_file_symbol_completion_list (char *text, char *word, char *srcfile) > +{ > + register struct symbol *sym; > + register struct symtab *s; > + register struct block *b; > + register int i; > + /* The symbol we are completing on. Points in same buffer as text. */ > + char *sym_text; > + /* 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. */ > + { > + char *p; > + char quote_found; > + char *quote_pos = NULL; > + > + /* First see if this is a quoted string. */ > + quote_found = '\0'; > + for (p = text; *p != '\0'; ++p) > + { > + if (quote_found != '\0') > + { > + if (*p == quote_found) > + /* Found close quote. */ > + quote_found = '\0'; > + else if (*p == '\\' && p[1] == quote_found) > + /* A backslash followed by the quote character > + doesn't end the string. */ > + ++p; > + } > + else if (*p == '\'' || *p == '"') > + { > + quote_found = *p; > + quote_pos = p; > + } > + } > + if (quote_found == '\'') > + /* A string within single quotes can be a symbol, so complete on it. */ > + sym_text = quote_pos + 1; > + else if (quote_found == '"') > + /* A double-quoted string is never a symbol, nor does it make sense > + to complete it any other way. */ > + { > + return_val = (char **) xmalloc (sizeof (char *)); > + return_val[0] = NULL; > + return return_val; > + } > + else > + { > + /* It is not a quoted string. Break it based on the characters > + which are in symbols. */ > + while (p > text) > + { > + if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0') > + --p; > + else > + break; > + } > + sym_text = p; > + } > + } > + > + sym_text_len = strlen (sym_text); > + > + return_val_size = 10; > + return_val_index = 0; > + return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *)); > + return_val[0] = NULL; > + > + /* Find the symtab for SRCFILE (this loads it if it was not yet read > + in). */ > + s = lookup_symtab (srcfile); > + if (s == NULL) > + { > + /* Maybe they typed the file with leading directories, while the > + symbol tables record only its basename. */ > + char *tail = basename (srcfile); > + > + if (tail > srcfile) > + s = lookup_symtab (tail); > + } > + > + /* If we have no symtab for that file, return an empty list. */ > + if (s == NULL) > + return (return_val); > + > + /* Go through this symtab and check the externs and statics for > + symbols which match. */ > + > + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); > + for (i = 0; i < BLOCK_NSYMS (b); i++) > + { > + sym = BLOCK_SYM (b, i); > + COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); > + } > + > + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); > + for (i = 0; i < BLOCK_NSYMS (b); i++) > + { > + sym = BLOCK_SYM (b, i); > + COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); > + } > + > + return (return_val); > +} > + > +/* A helper function for make_source_files_completion_list. It adds > + another file name to a list of possible completions, growing the > + list as necessary. */ > + > +static void > +add_filename_to_list (const char *fname, char *text, char *word, > + char ***list, int *list_used, int *list_alloced) > +{ > + char *new; > + size_t fnlen = strlen (fname); > + > + if (*list_used + 1 >= *list_alloced) > + { > + *list_alloced *= 2; > + *list = (char **) xrealloc ((char *) *list, > + *list_alloced * sizeof (char *)); > + } > + > + if (word == text) > + { > + /* Return exactly fname. */ > + new = xmalloc (fnlen + 5); > + strcpy (new, fname); > + } > + else if (word > text) > + { > + /* Return some portion of fname. */ > + new = xmalloc (fnlen + 5); > + strcpy (new, fname + (word - text)); > + } > + else > + { > + /* Return some of TEXT plus fname. */ > + new = xmalloc (fnlen + (text - word) + 5); > + strncpy (new, word, text - word); > + new[text - word] = '\0'; > + strcat (new, fname); > + } > + (*list)[*list_used] = new; > + (*list)[*list_used += 1] = NULL; > +} > + > +static int > +not_interesting_fname (const char *fname) > +{ > + static const char *illegal_aliens[] = { > + "_globals_", /* inserted by coff_symtab_read */ > + NULL > + }; > + int i; > + > + for (i = 0; illegal_aliens[i]; i++) > + { > + if (strcmp (fname, illegal_aliens[i]) == 0) > + return 1; > + } > + return 0; > +} > + > +/* Return a NULL terminated array 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 an array which contains only a NULL pointer. */ > + > +char ** > +make_source_files_completion_list (char *text, char *word) > +{ > + register struct symtab *s; > + register struct partial_symtab *ps; > + register struct objfile *objfile; > + int first = 1; > + int list_alloced = 1; > + int list_used = 0; > + size_t text_len = strlen (text); > + char **list = (char **) xmalloc (list_alloced * sizeof (char *)); > + char *base_name; > + > + list[0] = NULL; > + > + if (!have_full_symbols () && !have_partial_symbols ()) > + return list; > + > + ALL_SYMTABS (objfile, s) > + { > + if (not_interesting_fname (s->filename)) > + continue; > + if (!filename_seen (s->filename, 1, &first) > +#if HAVE_DOS_BASED_FILE_SYSTEM > + && strncasecmp (s->filename, text, text_len) == 0 > +#else > + && strncmp (s->filename, text, text_len) == 0 > +#endif > + ) > + { > + /* This file matches for a completion; add it to the current > + list of matches. */ > + add_filename_to_list (s->filename, text, word, > + &list, &list_used, &list_alloced); > + } > + else > + { > + /* NOTE: We allow the user to type a base name when the > + debug info records leading directories, but not the other > + way around. This is what subroutines of breakpoint > + command do when they parse file names. */ > + base_name = basename (s->filename); > + if (base_name != s->filename > + && !filename_seen (base_name, 1, &first) > +#if HAVE_DOS_BASED_FILE_SYSTEM > + && strncasecmp (base_name, text, text_len) == 0 > +#else > + && strncmp (base_name, text, text_len) == 0 > +#endif > + ) > + add_filename_to_list (base_name, text, word, > + &list, &list_used, &list_alloced); > + } > + } > + > + ALL_PSYMTABS (objfile, ps) > + { > + if (not_interesting_fname (ps->filename)) > + continue; > + if (!ps->readin) > + { > + if (!filename_seen (ps->filename, 1, &first) > +#if HAVE_DOS_BASED_FILE_SYSTEM > + && strncasecmp (ps->filename, text, text_len) == 0 > +#else > + && strncmp (ps->filename, text, text_len) == 0 > +#endif > + ) > + { > + /* This file matches for a completion; add it to the > + current list of matches. */ > + add_filename_to_list (ps->filename, text, word, > + &list, &list_used, &list_alloced); > + > + } > + else > + { > + base_name = basename (ps->filename); > + if (base_name != ps->filename > + && !filename_seen (base_name, 1, &first) > +#if HAVE_DOS_BASED_FILE_SYSTEM > + && strncasecmp (base_name, text, text_len) == 0 > +#else > + && strncmp (base_name, text, text_len) == 0 > +#endif > + ) > + add_filename_to_list (base_name, text, word, > + &list, &list_used, &list_alloced); > + } > + } > + } > + > + return list; > +} > + > /* Determine if PC is in the prologue of a function. The prologue is the area > between the first instruction of a function, and the first executable line. > Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue. > > --- gdb/symtab.h~2 Fri Feb 2 22:01:16 2001 > +++ gdb/symtab.h Sat Apr 28 14:00:24 2001 > @@ -1386,8 +1386,12 @@ extern void select_source_symtab (struct > > extern char **make_symbol_completion_list (char *, char *); > > +extern char **make_file_symbol_completion_list (char *, char *, char *); > + > extern struct symbol **make_symbol_overload_list (struct symbol *); > > +extern char **make_source_files_completion_list (char *, char *); > + > /* symtab.c */ > > extern struct partial_symtab *find_main_psymtab (void); > > --- gdb/breakpoint.c~2 Sun Mar 18 20:34:06 2001 > +++ gdb/breakpoint.c Sat May 5 19:05:36 2001 > @@ -40,6 +40,7 @@ > #include "symfile.h" > #include "objfiles.h" > #include "linespec.h" > +#include "completer.h" > #ifdef UI_OUT > #include "ui-out.h" > #endif > @@ -7520,24 +7521,29 @@ then no output is printed when it is hit > Usage is `condition N COND', where N is an integer and COND is an\n\ > expression to be evaluated whenever breakpoint N is reached. "); > > - add_com ("tbreak", class_breakpoint, tbreak_command, > - "Set a temporary breakpoint. Args like \"break\" command.\n\ > + c = add_com ("tbreak", class_breakpoint, tbreak_command, > + "Set a temporary breakpoint. Args like \"break\" command.\n\ > Like \"break\" except the breakpoint is only temporary,\n\ > so it will be deleted when hit. Equivalent to \"break\" followed\n\ > by using \"enable delete\" on the breakpoint number."); > - add_com ("txbreak", class_breakpoint, tbreak_at_finish_command, > - "Set temporary breakpoint at procedure exit. Either there should\n\ > + c->completer = location_completer; > + > + c = add_com ("txbreak", class_breakpoint, tbreak_at_finish_command, > + "Set temporary breakpoint at procedure exit. Either there should\n\ > be no argument or the argument must be a depth.\n"); > + c->completer = location_completer; > > - add_com ("hbreak", class_breakpoint, hbreak_command, > - "Set a hardware assisted breakpoint. Args like \"break\" command.\n\ > + c = add_com ("hbreak", class_breakpoint, hbreak_command, > + "Set a hardware assisted breakpoint. Args like \"break\" command.\n\ > Like \"break\" except the breakpoint requires hardware support,\n\ > some target hardware may not have this support."); > + c->completer = location_completer; > > - add_com ("thbreak", class_breakpoint, thbreak_command, > - "Set a temporary hardware assisted breakpoint. Args like \"break\" command.\n\ > + c = add_com ("thbreak", class_breakpoint, thbreak_command, > + "Set a temporary hardware assisted breakpoint. Args like \"break\" command.\n\ > Like \"hbreak\" except the breakpoint is only temporary,\n\ > so it will be deleted when hit."); > + c->completer = location_completer; > > add_prefix_cmd ("enable", class_breakpoint, enable_command, > "Enable some breakpoints.\n\ > @@ -7639,8 +7645,8 @@ is executing in.\n\ > \n\ > See also the \"delete\" command which clears breakpoints by number.", NULL)); > > - add_com ("break", class_breakpoint, break_command, > - concat ("Set breakpoint at specified line or function.\n\ > + c = add_com ("break", class_breakpoint, break_command, > + concat ("Set breakpoint at specified line or function.\n\ > Argument may be line number, function name, or \"*\" and an address.\n\ > If line number is specified, break at start of code for that line.\n\ > If function is specified, break at start of code for that function.\n\ > @@ -7651,6 +7657,8 @@ This is useful for breaking on return to > Multiple breakpoints at one place are permitted, and useful if conditional.\n\ > \n\ > Do \"help breakpoints\" for info on other commands dealing with breakpoints.", NULL)); > + c->completer = location_completer; > + > add_com_alias ("b", "break", class_run, 1); > add_com_alias ("br", "break", class_run, 1); > add_com_alias ("bre", "break", class_run, 1); > @@ -7796,20 +7804,23 @@ Like \"catch\" except the catchpoint is > so it will be deleted when hit. Equivalent to \"catch\" followed\n\ > by using \"enable delete\" on the catchpoint number."); > > - add_com ("watch", class_breakpoint, watch_command, > - "Set a watchpoint for an expression.\n\ > + c = add_com ("watch", class_breakpoint, watch_command, > + "Set a watchpoint for an expression.\n\ > A watchpoint stops execution of your program whenever the value of\n\ > an expression changes."); > + c->completer = location_completer; > > - add_com ("rwatch", class_breakpoint, rwatch_command, > - "Set a read watchpoint for an expression.\n\ > + c = add_com ("rwatch", class_breakpoint, rwatch_command, > + "Set a read watchpoint for an expression.\n\ > A watchpoint stops execution of your program whenever the value of\n\ > an expression is read."); > + c->completer = location_completer; > > - add_com ("awatch", class_breakpoint, awatch_command, > - "Set a watchpoint for an expression.\n\ > + c = add_com ("awatch", class_breakpoint, awatch_command, > + "Set a watchpoint for an expression.\n\ > A watchpoint stops execution of your program whenever the value of\n\ > an expression is either read or written."); > + c->completer = location_completer; > > add_info ("watchpoints", breakpoints_info, > "Synonym for ``info breakpoints''."); > > --- gdb/tracepoint.c~2 Sat Feb 17 22:42:54 2001 > +++ gdb/tracepoint.c Sat May 5 19:33:50 2001 > @@ -2774,12 +2774,13 @@ Arguments are tracepoint numbers, separa > No argument means enable all tracepoints.", > &enablelist); > > - add_com ("trace", class_trace, trace_command, > - "Set a tracepoint at a specified line or function or address.\n\ > + c = add_com ("trace", class_trace, trace_command, > + "Set a tracepoint at a specified line or function or address.\n\ > Argument may be a line number, function name, or '*' plus an address.\n\ > For a line number or function, trace at the start of its code.\n\ > If an address is specified, trace at that exact address.\n\n\ > Do \"help tracepoints\" for info on other tracepoint commands."); > + c->completer = location_completer; > > add_com_alias ("tp", "trace", class_alias, 0); > add_com_alias ("tr", "trace", class_alias, 1); > > --- gdb/printcmd.c~2 Fri Dec 15 03:01:48 2000 > +++ gdb/printcmd.c Sat May 5 19:38:42 2001 > @@ -37,6 +37,7 @@ > #include "annotate.h" > #include "symfile.h" /* for overlay functions */ > #include "objfiles.h" /* ditto */ > +#include "completer.h" /* for completion functions */ > #ifdef UI_OUT > #include "ui-out.h" > #endif > @@ -2452,6 +2453,8 @@ print_insn (CORE_ADDR memaddr, struct ui > void > _initialize_printcmd (void) > { > + struct cmd_list_element *c; > + > current_display_number = -1; > > add_info ("address", address_info, > @@ -2474,11 +2477,12 @@ Defaults for format and size letters are > Default count is 1. Default address is following last thing printed\n\ > with this command or \"print\".", NULL)); > > - add_com ("disassemble", class_vars, disassemble_command, > - "Disassemble a specified section of memory.\n\ > + c = add_com ("disassemble", class_vars, disassemble_command, > + "Disassemble a specified section of memory.\n\ > Default is the function surrounding the pc of the selected frame.\n\ > With a single argument, the function surrounding that address is dumped.\n\ > Two arguments are taken as a range of memory to dump."); > + c->completer = location_completer; > if (xdb_commands) > add_com_alias ("va", "disassemble", class_xdb, 0); > > @@ -2556,11 +2560,12 @@ variable in the program being debugged. > You can see these environment settings with the \"show\" command.", NULL)); > > /* "call" is the same as "set", but handy for dbx users to call fns. */ > - add_com ("call", class_vars, call_command, > - "Call a function in the program.\n\ > + c = add_com ("call", class_vars, call_command, > + "Call a function in the program.\n\ > The argument is the function name and arguments, in the notation of the\n\ > current working language. The result is printed and saved in the value\n\ > history, if it is not void."); > + c->completer = location_completer; > > add_cmd ("variable", class_vars, set_command, > "Evaluate expression EXP and assign result to variable VAR, using assignment\n\ > @@ -2571,7 +2576,7 @@ variable in the program being debugged. > This may usually be abbreviated to simply \"set\".", > &setlist); > > - add_com ("print", class_vars, print_command, > + c = add_com ("print", class_vars, print_command, > concat ("Print value of expression EXP.\n\ > Variables accessible are those of the lexical environment of the selected\n\ > stack frame, plus all those whose scope is global or an entire file.\n\ > @@ -2593,11 +2598,13 @@ resides in memory.\n", > "\n\ > EXP may be preceded with /FMT, where FMT is a format letter\n\ > but no count or size letter (see \"x\" command).", NULL)); > + c->completer = location_completer; > add_com_alias ("p", "print", class_vars, 1); > > - add_com ("inspect", class_vars, inspect_command, > + c = add_com ("inspect", class_vars, inspect_command, > "Same as \"print\" command, except that if you are running in the epoch\n\ > environment, the value is printed in its own window."); > + c->completer = location_completer; > > add_show_from_set ( > add_set_cmd ("max-symbolic-offset", no_class, var_uinteger, > > --- gdb/infcmd.c~2 Mon Feb 12 23:03:02 2001 > +++ gdb/infcmd.c Sat May 5 19:23:36 2001 > @@ -1793,8 +1793,8 @@ _initialize_infcmd (void) > { > struct cmd_list_element *c; > > - c= add_com ("tty", class_run, tty_command, > - "Set terminal for future runs of program being debugged."); > + c = add_com ("tty", class_run, tty_command, > + "Set terminal for future runs of program being debugged."); > c->completer = filename_completer; > > add_show_from_set > @@ -1899,25 +1899,30 @@ Argument N means do this N times (or til > Argument N means do this N times (or till program stops for another reason)."); > add_com_alias ("s", "step", class_run, 1); > > - add_com ("until", class_run, until_command, > - "Execute until the program reaches a source line greater than the current\n\ > + c = add_com ("until", class_run, until_command, > + "Execute until the program reaches a source line greater than the current\n\ > or a specified line or address or function (same args as break command).\n\ > Execution will also stop upon exit from the current stack frame."); > + c->completer = location_completer; > add_com_alias ("u", "until", class_run, 1); > > - add_com ("jump", class_run, jump_command, > - "Continue program being debugged at specified line or address.\n\ > + c = add_com ("jump", class_run, jump_command, > + "Continue program being debugged at specified line or address.\n\ > Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\ > for an address to start at."); > + c->completer = location_completer; > > if (xdb_commands) > - add_com ("go", class_run, go_command, > - "Usage: go \n\ > + { > + c = add_com ("go", class_run, go_command, > + "Usage: go \n\ > Continue program being debugged, stopping at specified line or \n\ > address.\n\ > Give as argument either LINENUM or *ADDR, where ADDR is an \n\ > expression for an address to start at.\n\ > This command is a combination of tbreak and jump."); > + c->completer = location_completer; > + } > > if (xdb_commands) > add_com_alias ("g", "go", class_run, 1); >