This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] MI: Add new command -complete


Polite ping. 

Jan

On Thu, 2019-01-03 at 22:29 +0000, Jan Vrany wrote:
> There is a CLI command 'complete' intended to use with emacs. Such a command
> would also be useful for MI frontends, when separate CLI and MI channels cannot
> be used. For example, on Windows (because of lack of PTYs) or when GDB is used
> through SSH session.
> 
> This commit adds a new '-complete' MI command which is implemented using
> CLI's 'complete'.
> 
> gdb/Changelog:
> 2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
> 
> 	* cli/cli-cmds.h: Export complete_command.
> 	* cli/cli-cmds.c (complete_command): Update to print completions
> 	on MI channel if requested.
> 	* mi/mi-cmds.c: Define new -complete command implemented using
> 	it CLI command 'complete'.
> 	* NEWS: Mention new -complete command.
> 
> gdb/doc/ChangeLog:
> 2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
> 
> 	* gdb.texinfo (Miscellaneous GDB/MI Commands): Document new
> 	MI command -complete.
> 
> gdb/testsuite/ChangeLog:
> 2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
> 
> 	* gdb.mi/mi-complete.exp: New file.
> ---
>  gdb/ChangeLog                        |  9 +++
>  gdb/NEWS                             |  7 ++
>  gdb/cli/cli-cmds.c                   | 95 +++++++++++++++++++---------
>  gdb/cli/cli-cmds.h                   |  4 ++
>  gdb/doc/ChangeLog                    |  5 ++
>  gdb/doc/gdb.texinfo                  | 32 ++++++++++
>  gdb/mi/mi-cmds.c                     |  3 +
>  gdb/testsuite/ChangeLog              |  4 ++
>  gdb/testsuite/gdb.mi/mi-complete.exp | 71 +++++++++++++++++++++
>  9 files changed, 199 insertions(+), 31 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.mi/mi-complete.exp
> 
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 08c7c6c1f4..322b539417 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,12 @@
> +2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
> +
> +	* cli/cli-cmds.h: Export complete_command.
> +	* cli/cli-cmds.c (complete_command): Update to print completions
> +	on MI channel if requested.
> +	* mi/mi-cmds.c: Define new -complete command implemented using
> +	it CLI command 'complete'.
> +	* NEWS: Mention new -complete command.
> +
>  2018-12-17  Andrew Burgess  <andrew.burgess@embecosm.com>
>  
>  	* dwarf2read.c (struct dwarf2_cu): Convert the fields 'mark',
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 913f3ae3b6..6b561af71f 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -96,6 +96,13 @@ maint show dwarf unwinders
>  info proc files
>    Display a list of open files for a process.
>  
> +* New MI commands
> +
> +-complete
> +  This lists all the possible completions for the rest of the line, if it
> +  were to be given as a command itself.  This is intended for use by MI frontends
> +  in cases when separate CLI and MI channels cannot be used.
> +
>  * Changed commands
>  
>  target remote FILENAME
> diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
> index 135f550b80..468f66dac6 100644
> --- a/gdb/cli/cli-cmds.c
> +++ b/gdb/cli/cli-cmds.c
> @@ -223,16 +223,22 @@ help_command (const char *command, int from_tty)
>  /* Note: The "complete" command is used by Emacs to implement completion.
>     [Is that why this function writes output with *_unfiltered?]  */
>  
> -static void
> +void
>  complete_command (const char *arg, int from_tty)
>  {
> +  struct ui_out *uiout = current_uiout;
> +  bool is_mi_like = uiout->is_mi_like_p ();
> +
>    dont_repeat ();
>  
>    if (max_completions == 0)
>      {
> -      /* Only print this for non-mi frontends.  An MI frontend may not
> -	 be able to handle this.  */
> -      if (!current_uiout->is_mi_like_p ())
> +      if (is_mi_like)
> +        {
> +          error (_("max-completions is zero,"
> +		   " completion is disabled.\n"));
> +        }
> +      else
>  	{
>  	  printf_unfiltered (_("max-completions is zero,"
>  			       " completion is disabled.\n"));
> @@ -278,34 +284,61 @@ complete_command (const char *arg, int from_tty)
>    completion_result result
>      = tracker->build_completion_result (word, word - arg, strlen (arg));
>  
> -  if (result.number_matches != 0)
> -    {
> -      if (result.number_matches == 1)
> -	printf_unfiltered ("%s%s\n", arg_prefix.c_str (), result.match_list[0]);
> -      else
> -	{
> -	  result.sort_match_list ();
> -
> -	  for (size_t i = 0; i < result.number_matches; i++)
> -	    {
> -	      printf_unfiltered ("%s%s",
> -				 arg_prefix.c_str (),
> -				 result.match_list[i + 1]);
> -	      if (quote_char)
> -		printf_unfiltered ("%c", quote_char);
> -	      printf_unfiltered ("\n");
> -	    }
> -	}
> -
> -      if (result.number_matches == max_completions)
> -	{
> -	  /* ARG_PREFIX and WORD are included in the output so that emacs
> -	     will include the message in the output.  */
> -	  printf_unfiltered (_("%s%s %s\n"),
> -			     arg_prefix.c_str (), word,
> -			     get_max_completions_reached_message ());
> -	}
> +  {
> +    ui_out_emit_list completions_emitter (uiout, "completions");
> +    if (result.number_matches != 0)
> +      {
> +        if (result.number_matches == 1)
> +          {
> +	    if (is_mi_like)
> +	      uiout->field_fmt(NULL, "%s%s", arg_prefix.c_str (),
> +                                             result.match_list[0]);
> +	    else
> +	      printf_unfiltered ("%s%s\n", arg_prefix.c_str (),
> +                                           result.match_list[0]);
> +          }
> +        else
> +	  {
> +	    result.sort_match_list ();
> +
> +	    for (size_t i = 0; i < result.number_matches; i++)
> +	      {
> +                if (is_mi_like)
> +	          {
> +	            uiout->field_fmt(NULL, "%s%s", arg_prefix.c_str (),
> +                                                   result.match_list[i + 1]);
> +	          }
> +	        else
> +	          {
> +		    printf_unfiltered ("%s%s", arg_prefix.c_str (),
> +                                               result.match_list[i + 1]);
> +		    if (quote_char)
> +		      printf_unfiltered ("%c", quote_char);
> +		    printf_unfiltered ("\n");
> +	          }
> +	      }
> +	  }
> +      }
>      }
> +
> +    if (result.number_matches == max_completions)
> +      {
> +	if (is_mi_like)
> +	  uiout->field_string("max_completions_reached", "1");
> +	else
> +	  {
> +	    /* ARG_PREFIX and WORD are included in the output so that emacs
> +	       will include the message in the output.  */
> +	    printf_unfiltered (_("%s%s %s\n"),
> +				 arg_prefix.c_str (), word,
> +				 get_max_completions_reached_message ());
> +	  }
> +      }
> +    else
> +      {
> +	if (is_mi_like)
> +	  uiout->field_string("max_completions_reached", "0");
> +      }
>  }
>  
>  int
> diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h
> index 3fa188dba6..bcd12c0c0b 100644
> --- a/gdb/cli/cli-cmds.h
> +++ b/gdb/cli/cli-cmds.h
> @@ -106,6 +106,10 @@ void init_cmd_lists (void);
>  
>  void init_cli_cmds (void);
>  
> +/* Exported to gdb/mi/mi-cmds.c */
> +
> +void complete_command (const char *, int);
> +
>  int is_complete_command (struct cmd_list_element *cmd);
>  
>  /* Exported to gdb/main.c */
> diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
> index 68d3068c72..da81f6a6c1 100644
> --- a/gdb/doc/ChangeLog
> +++ b/gdb/doc/ChangeLog
> @@ -1,3 +1,8 @@
> +2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
> +
> +	* gdb.texinfo (Miscellaneous GDB/MI Commands): Document new
> +	MI command -complete.
> +
>  2018-12-13  John Baldwin  <jhb@FreeBSD.org>
>  
>  	* gdb.texinfo (Set Catchpoints): Add an anchor for 'catch syscall'.
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index d766e44e63..7f88273145 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -34236,6 +34236,38 @@ fullname="/home/nickrob/myprog.c",line="73",arch="i386:x86_64"@}
>  (gdb)
>  @end smallexample
>  
> +@subheading The @code{-complete} Command
> +@findex -complete
> +
> +@subheading Synopsis
> +
> +@smallexample
> +-complete @var{command}
> +@end smallexample
> +
> +Show a list of completions for partially typed CLI @var{command}. The
> +@var{command} should be given in verbatim without any quoting / escaping.
> +
> +This command is intended for @sc{gdb/mi} frontends that cannot use two separate
> +CLI and MI channels - for example: because of lack of PTYs like on Windows or
> +because @sc{gdb} is used remotely via a SSH connection.
> +
> +@subheading @value{GDBN} Command
> +
> +The corresponding @value{GDBN} command is @samp{complete}.
> +
> +@subheading Example
> +
> +@smallexample
> +(gdb)
> +-complete br
> +^done,completions=["break","break-range"],max_completions_reached="0"
> +(gdb)
> +-complete b madv
> +^done,completions=["b madvise"],max_completions_reached="0"
> +(gdb)
> +@end smallexample
> +
>  @node Annotations
>  @chapter @value{GDBN} Annotations
>  
> diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
> index 51014eded2..7b510f71d4 100644
> --- a/gdb/mi/mi-cmds.c
> +++ b/gdb/mi/mi-cmds.c
> @@ -20,9 +20,11 @@
>  
>  #include "defs.h"
>  #include "top.h"
> +#include "cli/cli-cmds.h"
>  #include "mi-cmds.h"
>  #include "mi-main.h"
>  
> +
>  struct mi_cmd;
>  static struct mi_cmd **lookup_table (const char *command);
>  static void build_table (struct mi_cmd *commands);
> @@ -75,6 +77,7 @@ static struct mi_cmd mi_cmds[] =
>                     &mi_suppress_notification.breakpoint),
>    DEF_MI_CMD_MI_1 ("catch-unload", mi_cmd_catch_unload,
>                     &mi_suppress_notification.breakpoint),
> +  DEF_MI_CMD_CLI ("complete", "complete", 1),
>    DEF_MI_CMD_MI ("data-disassemble", mi_cmd_disassemble),
>    DEF_MI_CMD_MI ("data-evaluate-expression", mi_cmd_data_evaluate_expression),
>    DEF_MI_CMD_MI ("data-list-changed-registers",
> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
> index ab3a74fffd..40da71b2c5 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,7 @@
> +2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
> +
> +	* gdb.mi/mi-complete.exp: New file.
> +
>  2018-12-12  Andrew Burgess  <andrew.burgess@embecosm.com>
>  
>  	* gdb.base/annota1.exp: Update a test regexp.
> diff --git a/gdb/testsuite/gdb.mi/mi-complete.exp b/gdb/testsuite/gdb.mi/mi-complete.exp
> new file mode 100644
> index 0000000000..14c763a966
> --- /dev/null
> +++ b/gdb/testsuite/gdb.mi/mi-complete.exp
> @@ -0,0 +1,71 @@
> +# Copyright 2018 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/>;.
> +
> +# Verify -data-evaluate-expression. There are really minimal tests.
> +
> +# The goal is not to test gdb functionality, which is done by other tests,
> +# but to verify the correct output response to MI operations.
> +#
> +
> +load_lib mi-support.exp
> +set MIFLAGS "-i=mi"
> +
> +gdb_exit
> +if [mi_gdb_start] {
> +    continue
> +}
> +
> +standard_testfile basics.c
> +
> +if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
> +     untested "failed to compile"
> +     return -1
> +}
> +
> +mi_run_to_main
> +
> +mi_gdb_test "1-complete br" \
> +            "1\\^done,completions=\\\[.*\"break\",.*\"break-range\".*\\\],max_completions_reached=\"0\"" \
> +            "-complete br"
> +
> +# Check empty completion list
> +mi_gdb_test "5-complete bogus" \
> +            "5\\^done,completions=\\\[\\\],max_completions_reached=\"0\"" \
> +            "-complete bogus"
> +
> +
> +# Check completions for commands with space
> +mi_gdb_test "4-complete b mai" \
> +            "4\\^done,completions=\\\[.*\"b main\".*\\\],max_completions_reached=\"0\"" \
> +            "-complete b mai"
> +
> +mi_gdb_test "-info-gdb-mi-command complete" \
> +            "\\^done,command=\{exists=\"true\"\}" \
> +            "-info-gdb-mi-command complete"
> +
> +# Limit max completions and check that max_completions_reached=\"0\" is set
> +# to 1.
> +send_gdb "set max-completions 1\n"
> +
> +mi_gdb_test "2-complete br" \
> +            ".*2\\^done,completions=\\\[\"br\[A-Za-z0-9-\]+\"\\\],max_completions_reached=\"1\"" \
> +            "-complete br (max-completions 1)"
> +
> +# Disable completions and check an error is returned
> +send_gdb "set max-completions 0\n"
> +
> +mi_gdb_test "3-complete br" \
> +            ".*3\\^error,msg=\".*" \
> +            "-complete br (max-completions 1)"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]