old-cross-binutils/gdb/testsuite/gdb.python
Sergio Durigan Junior 7d793aa9f0 PR python/16699: GDB Python command completion with overriden complete vs. completer class
This PR came from a Red Hat bug that was filed recently.  I checked and
it still exists on HEAD, so here's a proposed fix.  Although this is
marked as a Python backend bug, this is really about the completion
mechanism used by GDB.  Since this code reminds me of my first attempt
to make a good noodle, it took me quite some time to fix it in a
non-intrusive way.

The problem is triggered when one registers a completion method inside a
class in a Python script, rather than registering the command using a
completer class directly.  For example, consider the following script:

    class MyFirstCommand(gdb.Command):
          def __init__(self):
              gdb.Command.__init__(self,'myfirstcommand',gdb.COMMAND_USER,gdb.COMPLETE_FILENAME)

              def invoke(self,argument,from_tty):
                  raise gdb.GdbError('not implemented')

    class MySecondCommand(gdb.Command):
          def __init__(self):
              gdb.Command.__init__(self,'mysecondcommand',gdb.COMMAND_USER)

              def invoke(self,argument,from_tty):
                  raise gdb.GdbError('not implemented')

                  def complete(self,text,word):
                      return gdb.COMPLETE_FILENAME

    MyFirstCommand ()
    MySecondCommand ()

When one loads this into GDB and tries to complete filenames for both
myfirstcommand and mysecondcommand, she gets:

    (gdb) myfirstcommand /hom<TAB>
    (gdb) myfirstcommand /home/
                               ^
    ...
    (gdb) mysecondcommand /hom<TAB>
    (gdb) mysecondcommand /home
                                ^

(The "^" marks the final position of the cursor after the TAB).

So we see that myfirstcommand honors the COMPLETE_FILENAME class (as
specified in the command creation), but mysecondcommand does not.  After
some investigation, I found that the problem lies with the set of word
break characters that is used for each case.  The set should be the same
for both commands, but it is not.

During the process of deciding which type of completion should be used,
the code in gdb/completer.c:complete_line_internal analyses the command
that requested the completion and tries to determine the type of
completion wanted by checking which completion function will be called
(e.g., filename_completer for filenames, location_completer for
locations, etc.).

This all works fine for myfirstcommand, because immediately after the
command registration the Python backend already sets its completion
function to filename_completer (which then causes the
complete_line_internal function to choose the right set of word break
chars).  However, for mysecondcommand, this decision is postponed to
when the completer function is evaluated, and the Python backend uses an
internal completer (called cmdpy_completer).  complete_line_internal
doesn't know about this internal completer, and can't choose the right
set of word break chars in time, which then leads to a bad decision when
completing the "/hom" word.

So, after a few attempts, I decided to create another callback in
"struct cmd_list_element" that will be responsible for handling the case
when there is an unknown completer function for complete_line_internal
to work with.  So far, only the Python backend uses this callback, and
only when the user provides a completer method instead of registering
the command directly with a completer class.  I think this is the best
option because it not very intrusive (all the other commands will still
work normally), but especially because the whole completion code is so
messy that it would be hard to fix this without having to redesign
things.

I have regtested this on Fedora 18 x86_64, without regressions.  I also
included a testcase.

gdb/ChangeLog:
2014-09-03  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/ChangeLog:
2014-09-03  Sergio Durigan Junior  <sergiodj@redhat.com>

	PR python/16699
	* gdb.python/py-completion.exp: New file.
	* gdb.python/py-completion.py: Likewise.
2014-09-03 16:30:28 -04:00
..
lib-types.cc Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
lib-types.exp Fix and XFAIL test due to GCC PR55641, passes with clang 2014-04-24 13:22:10 -07:00
Makefile.in
py-arch.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-arch.exp Remove duplicated code on checking address 0x0 is accessiable 2014-08-09 08:46:32 +08:00
py-block.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-block.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-breakpoint.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-breakpoint.exp Extension Language API 2014-02-05 19:27:58 -08:00
py-cmd.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-cmd.exp Skip tests on completion and readline when readline lib isn't used 2014-03-26 21:11:08 +08:00
py-completion.exp PR python/16699: GDB Python command completion with overriden complete vs. completer class 2014-09-03 16:30:28 -04:00
py-completion.py PR python/16699: GDB Python command completion with overriden complete vs. completer class 2014-09-03 16:30:28 -04:00
py-error.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-error.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-events-shlib.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-events.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-events.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-events.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-evsignal.exp enable target async by default; separate MI and target notions of async 2014-05-29 14:38:02 +01:00
py-evthreads.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-evthreads.exp enable target async by default; separate MI and target notions of async 2014-05-29 14:38:02 +01:00
py-explore-cc.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-explore.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-explore.cc Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-explore.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-finish-breakpoint.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-finish-breakpoint.exp Copy .py files to remote host 2014-08-22 13:44:18 +08:00
py-finish-breakpoint.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-finish-breakpoint2.cc Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-finish-breakpoint2.exp Copy .py files to remote host 2014-08-22 13:44:18 +08:00
py-finish-breakpoint2.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-frame-args.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-frame-args.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-frame-args.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-frame-inline.c Fix PR backtrace/15558 2014-04-18 10:34:09 +01:00
py-frame-inline.exp Fix PR backtrace/15558 2014-04-18 10:34:09 +01:00
py-frame.c
py-frame.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-framefilter-gdb.py.in Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-framefilter-mi.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-framefilter-mi.exp fix crash in frame filters 2014-01-23 08:03:50 -07:00
py-framefilter.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-framefilter.exp Fix typo in test name 2014-02-08 10:44:11 +01:00
py-framefilter.py fix erroneous error-handling in frame filter code 2014-01-23 08:03:51 -07:00
py-function.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-inferior.c
py-inferior.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-infthread.c
py-infthread.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-linetable.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-linetable.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-linetable.S Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-mi.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-objfile-script-gdb.py.in Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-objfile-script.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-objfile-script.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-objfile.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-objfile.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-parameter.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-pp-integral.c [python] Add gdb.Type.name attribute. 2014-01-07 07:11:17 +04:00
py-pp-integral.exp Remove path from gdb.python/py-pp-integral.exp "source" test. 2014-01-10 07:57:09 +04:00
py-pp-integral.py [python] Add gdb.Type.name attribute. 2014-01-07 07:11:17 +04:00
py-pp-maint.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-pp-maint.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-pp-maint.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-pp-re-notag.c [Python] Make regexp collection printers work with typedefs as well. 2014-02-26 11:04:12 -08:00
py-pp-re-notag.exp [Python] Make regexp collection printers work with typedefs as well. 2014-02-26 11:04:12 -08:00
py-pp-re-notag.py [Python] Make regexp collection printers work with typedefs as well. 2014-02-26 11:04:12 -08:00
py-prettyprint.c Ensure unreferenced static symbols aren't omitted by clang (either marking them __attribute__((used)) or making them non-static) 2014-04-24 22:33:46 -07:00
py-prettyprint.exp Remove duplicated code on checking address 0x0 is accessiable 2014-08-09 08:46:32 +08:00
py-prettyprint.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-progspace.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-progspace.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-prompt.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-prompt.exp enable target async by default; separate MI and target notions of async 2014-05-29 14:38:02 +01:00
py-section-script.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-section-script.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-section-script.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-shared-sl.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-shared.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-shared.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-strfns.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-strfns.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-symbol.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-symbol.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-symtab.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-sync-interp.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-sync-interp.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-template.cc Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-template.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-type.c Use bitpos and type to lookup a gdb.Field object when its name is 'None'. 2014-01-13 17:35:56 -08:00
py-type.exp Use bitpos and type to lookup a gdb.Field object when its name is 'None'. 2014-01-13 17:35:56 -08:00
py-typeprint.cc Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-typeprint.exp Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-typeprint.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
py-value-cc.cc Call overloaded operators to perform operations on gdb.Value objects. 2014-02-19 15:47:45 -08:00
py-value-cc.exp Call overloaded operators to perform operations on gdb.Value objects. 2014-02-19 15:47:45 -08:00
py-value.c [python] Fix gdb.Value.dynamic_type for reference values. 2014-04-07 14:18:44 -07:00
py-value.exp set print symbol off in py-value.exp and scm-value.exp 2014-08-24 20:21:40 +08:00
py-xmethods.cc Make xmethods tests not to depend on inferior IO. 2014-06-18 04:31:47 -07:00
py-xmethods.exp Align behavior of xmethod commands with that of pretty-printer commands. 2014-06-23 04:57:51 -07:00
py-xmethods.py Fix xmethod Python so that it works with Python3. 2014-08-15 18:04:47 -07:00
python-1.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
python.c Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
python.exp Copy .py files to remote host 2014-08-22 13:44:18 +08:00
source1 Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00
source2.py Update Copyright year range in all files maintained by GDB. 2014-01-01 07:54:24 +04:00