Re: complete command doesn't work for files...

Jim Ingham
2004-01-20T22:19:04Z

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