complete command doesn't work for files...

Jim Ingham jingham@apple.com
Tue Jan 20 22:19:00 GMT 2004


FWLIW, your reasoning seems correct to me.  I was trying to fix it 
lower down out of (misplaced) conservatism, but it does sound like 
complete_line is getting the wrong data...  Thanks for looking at this.

Jim

> First of all, sorry about the long delay.  I've been meaning to look at
> this.
>
> On Wed, Sep 24, 2003 at 04:14:05PM -0700, Jim Ingham wrote:
>> I was looking at this for some other reason (I want to add an
>> "interpreter-complete console" type command), and I noticed that
>> "complete" and the complete_line function that it relies on don't work
>> when the input text is a filename, and contains more that just the
>> filename.  You can see this easily, do:
>>
>> (gdb) file /usr/<TAB><TAB>
>> X11R6               etc                 info                local
>>         share
>> bin                 games               kerberos            lost+found
>>         src
>> dict                i386-glibc21-linux  lib                 man
>>         tmp
>> doc                 include             libexec             sbin
>> (gdb) complete file /usr/
>> (gdb)
>>
>> That isn't right, you should get:
>>
>> (gdb) complete file /usr/
>> file /usr/X11R6
>> file /usr/bin
>> file /usr/dict
>> file /usr/doc
>> file /usr/etc
>> file /usr/games
>> file /usr/i386-glibc21-linux
>> file /usr/include
>> file /usr/info
>> file /usr/kerberos
>> file /usr/lib
>> file /usr/libexec
>> file /usr/local
>> file /usr/lost+found
>> file /usr/man
>> file /usr/sbin
>> file /usr/share
>> file /usr/src
>> file /usr/tmp
>>
>> The attached patch fixes the bug.
>>
>> The <TAB><TAB> case works because readline advances the first argument
>> of complete_line past the initial command.  But "complete" always
>> passes both TEXT and LINE_BUFFER as the whole command.  This patch
>> actually does what the comment about file completers above it says it
>> intends, namely that we should go to the cursor, and then back up to
>> the first file-wordbreak we find.  The old code clearly didn't do
>> that...  Both the <TAB> case and the complete case work now.  This 
>> also
>> makes emacs behave a little better when you try to complete files.
>>
>> I added a test case for this failure.
>
> I disagree with your analysis.  The expectation is that readline may
> have broken words prematurely for filenames - which it does, sometimes,
> see my mail to gdb@ yesterday - but not failed to break words.  So the
> caller of complete_line is in error for passing arg.  I imagine it
> messes up some of the other completers too.  Also, you didn't fix
> "complete file "; it was right next to the comment in question and had
> the same problem.
>
> Here's an alternative patch; tested, no regressions, fixes the problem.
> I'll commit it in a few days if no one objects.
>
> -- 
> Daniel Jacobowitz
> MontaVista Software                         Debian GNU/Linux Developer
>
> 2004-01-19  Daniel Jacobowitz  <drow@mvista.com>
>
> 	* cli/cli-cmds.c: Include readline.h.
> 	(complete_command): Pass the start of the last word to
> 	complete_line.
>
> 2004-01-19  Daniel Jacobowitz  <drow@mvista.com>
>
> 	* gdb.base/completion.exp: Kill a stray backslash.
>
> 2004-01-19  Jim Ingham  <jingham@apple.com>
>
> 	* gdb.base/completion.exp: Test that "complete file ./gdb.base/compl"
> 	agrees with the result from sending a tab.
>
> Index: cli/cli-cmds.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/cli/cli-cmds.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 cli-cmds.c
> --- cli/cli-cmds.c	17 Dec 2003 21:47:47 -0000	1.37
> +++ cli/cli-cmds.c	19 Jan 2004 16:13:31 -0000
> @@ -1,6 +1,6 @@
>  /* GDB CLI commands.
>
> -   Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
> +   Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, 
> Inc.
>
>     This file is part of GDB.
>
> @@ -20,6 +20,7 @@
>     Boston, MA 02111-1307, USA.  */
>
>  #include "defs.h"
> +#include <readline/readline.h>
>  #include <readline/tilde.h>
>  #include "completer.h"
>  #include "target.h"	 /* For baud_rate, remote_debug and 
> remote_timeout */
> @@ -224,7 +225,7 @@ complete_command (char *arg, int from_tt
>  {
>    int i;
>    int argpoint;
> -  char **completions;
> +  char **completions, *point, *arg_prefix;
>
>    dont_repeat ();
>
> @@ -232,7 +233,23 @@ complete_command (char *arg, int from_tt
>      arg = "";
>    argpoint = strlen (arg);
>
> -  completions = complete_line (arg, arg, argpoint);
> +  /* complete_line assumes that its first argument is somewhere 
> within,
> +     and except for filenames at the beginning of, the word to be 
> completed.
> +     The following crude imitation of readline's word-breaking tries 
> to
> +     accomodate this.  */
> +  point = arg + argpoint;
> +  while (point > arg)
> +    {
> +      if (strchr (rl_completer_word_break_characters, point[-1]) != 0)
> +        break;
> +      point--;
> +    }
> +
> +  arg_prefix = alloca (point - arg + 1);
> +  memcpy (arg_prefix, arg, point - arg);
> +  arg_prefix[point - arg] = 0;
> +
> +  completions = complete_line (point, arg, argpoint);
>
>    if (completions)
>      {
> @@ -248,7 +265,7 @@ complete_command (char *arg, int from_tt
>        while (item < size)
>  	{
>  	  int next_item;
> -	  printf_unfiltered ("%s\n", completions[item]);
> +	  printf_unfiltered ("%s%s\n", arg_prefix, completions[item]);
>  	  next_item = item + 1;
>  	  while (next_item < size
>  		 && ! strcmp (completions[item], completions[next_item]))
> Index: testsuite/gdb.base/completion.exp
> ===================================================================
> RCS file: /cvs/src/src/gdb/testsuite/gdb.base/completion.exp,v
> retrieving revision 1.20
> diff -u -p -r1.20 completion.exp
> --- testsuite/gdb.base/completion.exp	13 Jan 2004 23:39:54 -0000	1.20
> +++ testsuite/gdb.base/completion.exp	19 Jan 2004 16:13:31 -0000
> @@ -657,6 +657,15 @@ gdb_test "cd ${fullsrcdir}" \
>           "Working directory [string_to_regexp ${fullsrcdir}].*" \
>           "cd to \${srcdir}"
>
> +send_gdb "complete file ./gdb.base/compl\n"
> +sleep 1
> +gdb_expect  {
> +    -re "file ./gdb.base/completion\\.exp.*$gdb_prompt $"
> +	{ pass "complete-command 'file ./gdb.base/compl'"}
> +    -re ".*$gdb_prompt $"       { fail "complete-command 'file 
> ./gdb.base/compl'" }
> +    timeout         { fail "(timeout) complete-command 'file 
> ./gdb.base/compl'" }
> +}
> +
>  send_gdb "file ./gdb.base/complet\t"
>  sleep 1
>  gdb_expect  {
> @@ -664,7 +673,6 @@ gdb_expect  {
>              { send_gdb "\n"
>                gdb_expect {
>                        -re "\r\nA program is being debugged already\\. 
>  Kill it\\? \\(y or n\\) $"
> -\
>                        { send_gdb "n\n"
>                          gdb_expect {
>                                  -re "\r\nProgram not 
> killed\\.\r\n$gdb_prompt $"\
>
>
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
Jim Ingham                                                           
jingham@apple.com
Developer Tools - gdb



More information about the Gdb-patches mailing list