gdb/gdb-python-completer-1of2.patch
Jan Kratochvil cec9297712 Rebase the Intel VLA patchset.
- Python completion w/overriden completer (Sergio Durigan Junior, BZ 1075199).
- Remove %{_bindir}/mono-gdb.py workaround of mono BZ 815501.
2014-07-08 21:11:05 +02:00

748 lines
27 KiB
Diff

http://sourceware.org/ml/gdb-patches/2014-07/msg00002.html
Subject: Re: [PATCH] PR python/16699: GDB Python command completion with overriden complete vs. completer class
https://bugzilla.redhat.com/show_bug.cgi?id=1075199
On Wednesday, May 21 2014, Doug Evans wrote:
> Sergio Durigan Junior <sergiodj@redhat.com> writes:
>> [...]
>> Thanks. WDYT of the following patch?
>
> Hi.
>
> fwiw it's too bad the ability to plug in different completers isn't more,
> I dunno, parameterized (couldn't pick a better term, apologies -
> I thought of "object oriented" but that carries its own baggage).
> Performing completion obviously involves specifying more than a just
> single function (witness the comparison of the completer with specific
> functions).
Thanks for the reply, and sorry for the long delay in answering.
> Plus it's more than specifying brkchars.
> Witness code like this:
>
> /* Many commands which want to complete on
> file names accept several file names, as
> in "run foo bar >>baz". So we don't want
> 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 by starting at `word' and going
> backwards. */
> for (p = word;
> p > tmp_command
> && strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
> p--)
> ;
>
> IWBN if a "completer" object described how to do all these three things.
> Then the special case code for filename_completer (and location_completer)
> in completer.c could disappear. But maybe that's a patch for another day.
While I agree with you that the completion mechanism could be better (I
myself had a lot of trouble with it), I unfortunately don't have enough
time to tackle this problem now. So yeah, I think it will be a patch
for another day...
> Regarding the hack of using a static local to pass data from
> handle_brkchars to handle_completion, I know it's a hacky pragmatic
> choice. To get the reference counting right the code assumes that
> if the handle_brkchars phase is done then the handle_completion
> phase will be done too, right?
Yeah. This is true for the current code (well, except maybe for the
case you describe below...).
> I wonder if a SIGINT could sneak in
> there between the two passes (either today or tomorrow).
> Maybe the code in cmdpy_completer_helper for handle_brkchars_p could
> first check whether resultobj is already non-NULL, and decrement its
> reference count before setting it to NULL?
Yes, done (I think). Thanks for raising this issue.
> And cmdpy_completer_helper
> could be defined to return a borrowed reference to resultobj?
> Dunno, just thinking out loud.
Done, I guess.
> Something puzzles me though: If it's ok to cache the completion result from the
> handle_brkchars pass to the handle_completion pass, why have two passes?
> It feels like there must be a case where this caching of the result
> in a static local from one pass to the next won't work.
I'm not sure I follow.
It's OK to cache the result because handle_brkchars and
handle_completion work on the same set of data. In fact, we wouldn't
need to have two passes here; my previous patch didn't have two passes,
and worked fine. I just implemented it this way because Tom (correctly)
raised the point that the completion itself might be time-consuming, and
thus we could reuse its result in the two phases.
> Another question:
> I noticed complete_command doesn't do this two-phase dance
> of handle_brkchars followed by handle_completions. Should it?
> It just goes straight to handle_completions.
I don't think it should, because for complete_command (and
complete_filename et al) the handle_brkchars is already defined
internally by GDB. See:
...
/* Choose the default set of word break characters to break
completions. If we later find out that we are doing completions
on command strings (as opposed to strings supplied by the
individual command completer functions, which can be any string)
then we will switch to the special word break set for command
strings, which leaves out the '-' character used in some
commands. */
rl_completer_word_break_characters =
current_language->la_word_break_characters();
...
/* It is a normal command; what comes after it is
completed by the command's completer function. */
if (c->completer == filename_completer)
{
/* Many commands which want to complete on
file names accept several file names, as
in "run foo bar >>baz". So we don't want
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 by starting at `word' and going
backwards. */
for (p = word;
p > tmp_command
&& strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
p--)
;
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--)
;
}
if (reason == handle_brkchars
&& c->completer_handle_brkchars != NULL)
(*c->completer_handle_brkchars) (c, p, word);
if (reason != handle_brkchars && c->completer != NULL)
list = (*c->completer) (c, p, word);
The complete_command function will only be called by the last "if"
clause, when reason != handle_brkchars. Otherwise,
complete_line_internal will just deal with handle_brkchars. And for
complete_command, the right value for rl_completer_word_break_characters
is what is attributed at the beginning of the function.
My patch implements this "two-phase" dance for Python because in this
specific case (i.e., a completion method defined in the Python script)
there is no way to know the value of handle_brkchars before we actually
do the completion itself.
In fact, my patch could probably be "simplified" and be made to call
cmdpy_completer directly (without any cmdpy_completer_handle_brkchars),
assuming that this function took care of filling handle_brkchars
correctly. What I mean is: when dealing with the handle_brkchars case,
the completer command can do anything it wants.
> [Maybe that explains the difference from using TAB. Dunno off hand.]
> It seems like complete_command is trying to hand-code its own
> handle_brkchars handling:
>
> static void
> complete_command (char *arg, int from_tty)
> {
> int argpoint;
> char *point, *arg_prefix;
> VEC (char_ptr) *completions;
>
> dont_repeat ();
>
> if (arg == NULL)
> arg = "";
> argpoint = strlen (arg);
>
> /* 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);
>
> ...
> }
Yes, it seems so, but I did not check further.
> TAB and the complete command should work identically of course,
> but for your testcase, maybe you should test both just to verify
> both work reasonably well (even if not identically).
> Given that complete_command doesn't do the two phase dance,
> does it work with your patch?
> Maybe it does, but IWBN to confirm that.
The 'complete' command does not work as it should with my patch:
(gdb) complete completefileinit /hom
completefileinit /home
(gdb) complete completefilemethod /hom
completefilemethod /home
But then, it also does not work without my patch either:
(gdb) complete file /hom
file /home
So I am not extending the testcase for now, because this bug needs to be
fixed first (and it is unrelated to the patch I am proposing).
WDYT of this version?
Thanks,
--
Sergio
GPG key ID: 65FC5E36
Please send encrypted e-mail if possible
http://blog.sergiodj.net/
gdb/
2014-06-30 Sergio Durigan Junior <sergiodj@redhat.com>
PR python/16699
* cli/cli-decode.c (set_cmd_completer_handle_brkchars): New
function.
(add_cmd): Set "completer_handle_brkchars" to NULL.
* cli/cli-decode.h (struct cmd_list_element)
<completer_handle_brkchars>: New field.
* command.h (completer_ftype_void): New typedef.
(set_cmd_completer_handle_brkchars): New prototype.
* completer.c (set_gdb_completion_word_break_characters): New
function.
(complete_line_internal): Call "completer_handle_brkchars"
callback from command.
* completer.h: Include "command.h".
(set_gdb_completion_word_break_characters): New prototype.
* python/py-cmd.c (cmdpy_completer_helper): New function.
(cmdpy_completer_handle_brkchars): New function.
(cmdpy_completer): Adjust to use cmdpy_completer_helper.
(cmdpy_init): Set completer_handle_brkchars to
cmdpy_completer_handle_brkchars.
gdb/testsuite/
2014-06-30 Sergio Durigan Junior <sergiodj@redhat.com>
PR python/16699
* gdb.python/py-completion.exp: New file.
* gdb.python/py-completion.py: Likewise.
Index: gdb-7.7.90.20140627/gdb/cli/cli-decode.c
===================================================================
--- gdb-7.7.90.20140627.orig/gdb/cli/cli-decode.c 2014-07-07 20:53:52.635106914 +0200
+++ gdb-7.7.90.20140627/gdb/cli/cli-decode.c 2014-07-07 20:53:55.429110207 +0200
@@ -164,6 +164,15 @@ set_cmd_completer (struct cmd_list_eleme
cmd->completer = completer; /* Ok. */
}
+/* See definition in commands.h. */
+
+void
+set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
+ completer_ftype_void *completer_handle_brkchars)
+{
+ cmd->completer_handle_brkchars = completer_handle_brkchars;
+}
+
/* Add element named NAME.
Space for NAME and DOC must be allocated by the caller.
CLASS is the top level category into which commands are broken down
@@ -239,6 +248,7 @@ add_cmd (const char *name, enum command_
c->prefix = NULL;
c->abbrev_flag = 0;
set_cmd_completer (c, make_symbol_completion_list_fn);
+ c->completer_handle_brkchars = NULL;
c->destroyer = NULL;
c->type = not_set_cmd;
c->var = NULL;
Index: gdb-7.7.90.20140627/gdb/cli/cli-decode.h
===================================================================
--- gdb-7.7.90.20140627.orig/gdb/cli/cli-decode.h 2014-07-07 20:53:52.636106915 +0200
+++ gdb-7.7.90.20140627/gdb/cli/cli-decode.h 2014-07-07 20:53:55.429110207 +0200
@@ -176,6 +176,15 @@ struct cmd_list_element
"baz/foo", return "baz/foobar". */
completer_ftype *completer;
+ /* Handle the word break characters for this completer. Usually
+ this function need not be defined, but for some types of
+ completers (e.g., Python completers declared as methods inside
+ a class) the word break chars may need to be redefined
+ depending on the completer type (e.g., for filename
+ completers). */
+
+ completer_ftype_void *completer_handle_brkchars;
+
/* Destruction routine for this command. If non-NULL, this is
called when this command instance is destroyed. This may be
used to finalize the CONTEXT field, if needed. */
Index: gdb-7.7.90.20140627/gdb/command.h
===================================================================
--- gdb-7.7.90.20140627.orig/gdb/command.h 2014-07-07 20:53:52.636106915 +0200
+++ gdb-7.7.90.20140627/gdb/command.h 2014-07-07 20:53:55.430110208 +0200
@@ -158,8 +158,16 @@ extern void set_cmd_sfunc (struct cmd_li
typedef VEC (char_ptr) *completer_ftype (struct cmd_list_element *,
const char *, const char *);
+typedef void completer_ftype_void (struct cmd_list_element *,
+ const char *, const char *);
+
extern void set_cmd_completer (struct cmd_list_element *, completer_ftype *);
+/* Set the completer_handle_brkchars callback. */
+
+extern void set_cmd_completer_handle_brkchars (struct cmd_list_element *,
+ completer_ftype_void *);
+
/* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
around in cmd objects to test the value of the commands sfunc(). */
extern int cmd_cfunc_eq (struct cmd_list_element *cmd,
Index: gdb-7.7.90.20140627/gdb/completer.c
===================================================================
--- gdb-7.7.90.20140627.orig/gdb/completer.c 2014-07-07 20:53:52.637106916 +0200
+++ gdb-7.7.90.20140627/gdb/completer.c 2014-07-07 20:53:55.430110208 +0200
@@ -450,6 +450,21 @@ expression_completer (struct cmd_list_el
return location_completer (ignore, p, word);
}
+/* See definition in completer.h. */
+
+void
+set_gdb_completion_word_break_characters (completer_ftype *fn)
+{
+ /* So far we are only interested in differentiating filename
+ completers from everything else. */
+ if (fn == filename_completer)
+ rl_completer_word_break_characters
+ = gdb_completer_file_name_break_characters;
+ else
+ rl_completer_word_break_characters
+ = gdb_completer_command_word_break_characters;
+}
+
/* 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.
@@ -678,6 +693,9 @@ complete_line_internal (const char *text
p--)
;
}
+ if (reason == handle_brkchars
+ && c->completer_handle_brkchars != NULL)
+ (*c->completer_handle_brkchars) (c, p, word);
if (reason != handle_brkchars && c->completer != NULL)
list = (*c->completer) (c, p, word);
}
@@ -751,6 +769,9 @@ complete_line_internal (const char *text
p--)
;
}
+ if (reason == handle_brkchars
+ && c->completer_handle_brkchars != NULL)
+ (*c->completer_handle_brkchars) (c, p, word);
if (reason != handle_brkchars && c->completer != NULL)
list = (*c->completer) (c, p, word);
}
Index: gdb-7.7.90.20140627/gdb/completer.h
===================================================================
--- gdb-7.7.90.20140627.orig/gdb/completer.h 2014-07-07 20:53:52.637106916 +0200
+++ gdb-7.7.90.20140627/gdb/completer.h 2014-07-07 20:54:13.297131831 +0200
@@ -18,6 +18,7 @@
#define COMPLETER_H 1
#include "gdb_vecs.h"
+#include "command.h"
extern VEC (char_ptr) *complete_line (const char *text,
char *line_buffer,
@@ -48,6 +49,13 @@ extern char *get_gdb_completer_quote_cha
extern char *gdb_completion_word_break_characters (void);
+/* Set the word break characters array to the corresponding set of
+ chars, based on FN. This function is useful for cases when the
+ completer doesn't know the type of the completion until some
+ calculation is done (e.g., for Python functions). */
+
+extern void set_gdb_completion_word_break_characters (completer_ftype *fn);
+
/* Exported to linespec.c */
extern const char *skip_quoted_chars (const char *, const char *,
Index: gdb-7.7.90.20140627/gdb/python/py-cmd.c
===================================================================
--- gdb-7.7.90.20140627.orig/gdb/python/py-cmd.c 2014-07-07 20:53:52.637106916 +0200
+++ gdb-7.7.90.20140627/gdb/python/py-cmd.c 2014-07-07 20:53:55.431110209 +0200
@@ -208,45 +208,155 @@ cmdpy_function (struct cmd_list_element
do_cleanups (cleanup);
}
+/* Helper function for the Python command completers (both "pure"
+ completer and brkchar handler). This function takes COMMAND, TEXT
+ and WORD and tries to call the Python method for completion with
+ these arguments. It also takes HANDLE_BRKCHARS_P, an argument to
+ identify whether it is being called from the brkchar handler or
+ from the "pure" completer. In the first case, it effectively calls
+ the Python method for completion, and records the PyObject in a
+ static variable (used as a "cache"). In the second case, it just
+ returns that variable, without actually calling the Python method
+ again. This saves us one Python method call.
+
+ It is important to mention that this function is built on the
+ assumption that the calls to cmdpy_completer_handle_brkchars and
+ cmdpy_completer will be subsequent with nothing intervening. This
+ is true for our completer mechanism.
+
+ This function returns the PyObject representing the Python method
+ call. */
+
+static PyObject *
+cmdpy_completer_helper (struct cmd_list_element *command,
+ const char *text, const char *word,
+ int handle_brkchars_p)
+{
+ cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
+ PyObject *textobj, *wordobj;
+ /* This static variable will server as a "cache" for us, in order to
+ store the PyObject that results from calling the Python
+ function. */
+ static PyObject *resultobj = NULL;
+
+ if (handle_brkchars_p)
+ {
+ /* If we were called to handle brkchars, it means this is the
+ first function call of two that will happen in a row.
+ Therefore, we need to call the completer ourselves, and cache
+ the return value in the static variable RESULTOBJ. Then, in
+ the second call, we can just use the value of RESULTOBJ to do
+ our job. */
+ if (resultobj != NULL)
+ Py_DECREF (resultobj);
+
+ resultobj = NULL;
+ if (!obj)
+ error (_("Invalid invocation of Python command object."));
+ if (!PyObject_HasAttr ((PyObject *) obj, complete_cst))
+ {
+ /* If there is no complete method, don't error. */
+ return NULL;
+ }
+
+ textobj = PyUnicode_Decode (text, strlen (text), host_charset (), NULL);
+ if (!textobj)
+ error (_("Could not convert argument to Python string."));
+ wordobj = PyUnicode_Decode (word, sizeof (word), host_charset (), NULL);
+ if (!wordobj)
+ {
+ Py_DECREF (textobj);
+ error (_("Could not convert argument to Python string."));
+ }
+
+ resultobj = PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst,
+ textobj, wordobj, NULL);
+ Py_DECREF (textobj);
+ Py_DECREF (wordobj);
+ if (!resultobj)
+ {
+ /* Just swallow errors here. */
+ PyErr_Clear ();
+ }
+
+ Py_XINCREF (resultobj);
+ }
+
+ return resultobj;
+}
+
+/* Python function called to determine the break characters of a
+ certain completer. We are only interested in knowing if the
+ completer registered by the user will return one of the integer
+ codes (see COMPLETER_* symbols). */
+
+static void
+cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
+ const char *text, const char *word)
+{
+ PyObject *resultobj = NULL;
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ /* Calling our helper to obtain the PyObject of the Python
+ function. */
+ resultobj = cmdpy_completer_helper (command, text, word, 1);
+
+ /* Check if there was an error. */
+ if (resultobj == NULL)
+ goto done;
+
+ if (PyInt_Check (resultobj))
+ {
+ /* User code may also return one of the completion constants,
+ thus requesting that sort of completion. We are only
+ interested in this kind of return. */
+ long value;
+
+ if (!gdb_py_int_as_long (resultobj, &value))
+ {
+ /* Ignore. */
+ PyErr_Clear ();
+ }
+ else if (value >= 0 && value < (long) N_COMPLETERS)
+ {
+ /* This is the core of this function. Depending on which
+ completer type the Python function returns, we have to
+ adjust the break characters accordingly. */
+ set_gdb_completion_word_break_characters
+ (completers[value].completer);
+ }
+ }
+
+ done:
+
+ /* We do not call Py_XDECREF here because RESULTOBJ will be used in
+ the subsequent call to cmdpy_completer function. */
+ do_cleanups (cleanup);
+}
+
/* Called by gdb for command completion. */
static VEC (char_ptr) *
cmdpy_completer (struct cmd_list_element *command,
const char *text, const char *word)
{
- cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
- PyObject *textobj, *wordobj, *resultobj = NULL;
+ PyObject *resultobj = NULL;
VEC (char_ptr) *result = NULL;
struct cleanup *cleanup;
cleanup = ensure_python_env (get_current_arch (), current_language);
- if (! obj)
- error (_("Invalid invocation of Python command object."));
- if (! PyObject_HasAttr ((PyObject *) obj, complete_cst))
- {
- /* If there is no complete method, don't error -- instead, just
- say that there are no completions. */
- goto done;
- }
-
- textobj = PyUnicode_Decode (text, strlen (text), host_charset (), NULL);
- if (! textobj)
- error (_("Could not convert argument to Python string."));
- wordobj = PyUnicode_Decode (word, strlen (word), host_charset (), NULL);
- if (! wordobj)
- error (_("Could not convert argument to Python string."));
-
- resultobj = PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst,
- textobj, wordobj, NULL);
- Py_DECREF (textobj);
- Py_DECREF (wordobj);
- if (! resultobj)
- {
- /* Just swallow errors here. */
- PyErr_Clear ();
- goto done;
- }
+ /* Calling our helper to obtain the PyObject of the Python
+ function. */
+ resultobj = cmdpy_completer_helper (command, text, word, 0);
+
+ /* If the result object of calling the Python function is NULL, it
+ means that there was an error. In this case, just give up and
+ return NULL. */
+ if (resultobj == NULL)
+ goto done;
result = NULL;
if (PyInt_Check (resultobj))
@@ -302,7 +412,6 @@ cmdpy_completer (struct cmd_list_element
done:
- Py_XDECREF (resultobj);
do_cleanups (cleanup);
return result;
@@ -548,6 +657,9 @@ cmdpy_init (PyObject *self, PyObject *ar
set_cmd_context (cmd, self);
set_cmd_completer (cmd, ((completetype == -1) ? cmdpy_completer
: completers[completetype].completer));
+ if (completetype == -1)
+ set_cmd_completer_handle_brkchars (cmd,
+ cmdpy_completer_handle_brkchars);
}
if (except.reason < 0)
{
Index: gdb-7.7.90.20140627/gdb/testsuite/gdb.python/py-completion.exp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.7.90.20140627/gdb/testsuite/gdb.python/py-completion.exp 2014-07-07 20:53:55.431110209 +0200
@@ -0,0 +1,70 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set testfile "py-completion"
+
+load_lib gdb-python.exp
+
+gdb_exit
+gdb_start
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_test_no_output "source ${srcdir}/${subdir}/${testfile}.py"
+
+# Create a temporary directory
+set testdir "${objdir}/${subdir}/py-completion-testdir/"
+set testdir_regex [string_to_regexp $testdir]
+set testdir_complete "${objdir}/${subdir}/py-completion-test"
+file mkdir $testdir
+
+# This one should always pass.
+send_gdb "completefileinit ${testdir_complete}\t"
+gdb_test_multiple "" "completefileinit completion" {
+ -re "^completefileinit ${testdir_regex}$" {
+ pass "completefileinit completion"
+ }
+}
+
+# Just discarding whatever we typed.
+send_gdb "\n"
+gdb_test "print" ".*"
+
+# This is the problematic one.
+send_gdb "completefilemethod ${testdir_complete}\t"
+gdb_test_multiple "" "completefilemethod completion" {
+ -re "^completefilemethod ${testdir_regex} $" {
+ fail "completefilemethod completion (completed filename as wrong command arg)"
+ }
+ -re "^completefilemethod ${testdir_regex}$" {
+ pass "completefilemethod completion"
+ }
+}
+
+# Discarding again
+send_gdb "\n"
+gdb_test "print" ".*"
+
+# Another problematic
+send_gdb "completefilecommandcond ${objdir}/${subdir}/py-completion-t\t"
+gdb_test_multiple "" "completefilecommandcond completion" {
+ -re "^completefilecommandcond ${testdir}$" {
+ fail "completefilecommandcond completion (completed filename instead of command)"
+ }
+ -re "^completefilecommandcond ${objdir}/${subdir}/py-completion-t$" {
+ pass "completefilecommandcond completion"
+ }
+}
Index: gdb-7.7.90.20140627/gdb/testsuite/gdb.python/py-completion.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.7.90.20140627/gdb/testsuite/gdb.python/py-completion.py 2014-07-07 20:53:55.431110209 +0200
@@ -0,0 +1,58 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This testcase tests PR python/16699
+
+import gdb
+
+class CompleteFileInit(gdb.Command):
+ def __init__(self):
+ gdb.Command.__init__(self,'completefileinit',gdb.COMMAND_USER,gdb.COMPLETE_FILENAME)
+
+ def invoke(self,argument,from_tty):
+ raise gdb.GdbError('not implemented')
+
+class CompleteFileMethod(gdb.Command):
+ def __init__(self):
+ gdb.Command.__init__(self,'completefilemethod',gdb.COMMAND_USER)
+
+ def invoke(self,argument,from_tty):
+ raise gdb.GdbError('not implemented')
+
+ def complete(self,text,word):
+ return gdb.COMPLETE_FILENAME
+
+class CompleteFileCommandCond(gdb.Command):
+ def __init__(self):
+ gdb.Command.__init__(self,'completefilecommandcond',gdb.COMMAND_USER)
+
+ def invoke(self,argument,from_tty):
+ raise gdb.GdbError('not implemented')
+
+ def complete(self,text,word):
+ # This is a test made to know if the command
+ # completion still works fine. When the user asks to
+ # complete something like "completefilecommandcond
+ # /path/to/py-completion-t", it should not complete to
+ # "/path/to/py-completion-test/", but instead just
+ # wait for input.
+ if "py-completion-t" in text:
+ return gdb.COMPLETE_COMMAND
+ else:
+ return gdb.COMPLETE_FILENAME
+
+CompleteFileInit()
+CompleteFileMethod()
+CompleteFileCommandCond()