From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15764 invoked by alias); 25 Aug 2018 20:53:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 15750 invoked by uid 89); 25 Aug 2018 20:53:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=aim, 201807, 2018-07 X-HELO: mailsec101.isp.belgacom.be Received: from mailsec101.isp.belgacom.be (HELO mailsec101.isp.belgacom.be) (195.238.20.97) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 25 Aug 2018 20:53:26 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skynet.be; i=@skynet.be; q=dns/txt; s=securemail; t=1535230406; x=1566766406; h=message-id:subject:from:to:date:in-reply-to:references: mime-version:content-transfer-encoding; bh=PD57Tu+wheLJfTSYP9jbYcWTQb2KWTJJbTg7nuKOy4w=; b=X6STRRgsKvL34Hh5wYgujlhj2DkFEFdlows0g9BlhiufCjf+2hWQFxkt LA/pE/uFqUZEZcH/ku2PYi+/StWFJg==; Received: from 217.24-133-109.adsl-dyn.isp.belgacom.be (HELO md) ([109.133.24.217]) by relay.skynet.be with ESMTP/TLS/AES256-GCM-SHA384; 25 Aug 2018 22:53:23 +0200 Message-ID: <1535230403.1438.10.camel@skynet.be> Subject: Re: [PATCH 2/2] gdb: Allow parenthesis to group arguments to user-defined commands From: Philippe Waroquiers To: Andrew Burgess , gdb-patches@sourceware.org Date: Sat, 25 Aug 2018 20:53:00 -0000 In-Reply-To: <1535225533.1438.5.camel@skynet.be> References: <1535225533.1438.5.camel@skynet.be> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2018-08/txt/msg00619.txt.bz2 On Sat, 2018-08-25 at 21:32 +0200, Philippe Waroquiers wrote: > Woudn't it be more 'usual' (and maybe simpler) to use a \ for this ? > e.g. like the shell: > ls ab\ cd > ls: cannot access 'ab cd': No such file or directory > > Philippe See also the RFA (in 'review needed status') https://sourceware.org/ml/gdb-patches/2018-07/msg00131.html where I (inconsistently with my comment above but still consistent with the shell) have used single quotes for such purposes. Like for the level versus number, we should aim at a single approach in gdb for such things ... Philippe > > > On Wed, 2018-08-15 at 15:39 +0100, Andrew Burgess wrote: > > When calling a user-defined command then currently, arguments are > > whitespace separated. This means that it is impossible to pass a > > single argument that contains a whitespace. > > > > The exception to the no whitespace rule is strings, a string argument, > > enclosed in double, or single quotes, can contain whitespace. > > > > However, if a user wants to reference, for example, a type name that > > contains a space, as in these examples: > > > > user_command *((unsigned long long *) some_pointer) > > > > user_command {unsigned long long}some_pointer > > > > then this will not work, as the whitespace between 'unsigned' and > > 'long', as well as the whitespace between 'long' and 'long', will mean > > GDB interprets this as many arguments. > > > > The solution proposed in this patch is to allow parenthesis to be used > > to group arguments, so the use could now write: > > > > user_command (*((unsigned long long *) some_pointer)) > > > > user_command ({unsigned long long}some_pointer) > > > > And GDB will interpret these as a single argument. > > > > gdb/ChangeLog: > > > > * cli/cli-script.c (user_args::user_args): Allow parenthesis to > > group arguments. > > > > gdb/testsuite/ChangeLog: > > > > * gdb.base/commands.exp (args_with_whitespace): New proc, which is > > added to the list of procs to call. > > * gdb.base/run.c (global_var): Defined global. > > > > gdb/doc/ChangeLog: > > > > * gdb.texinfo (Define): Additional documentation about argument > > syntax. > > --- > > gdb/ChangeLog | 5 ++++ > > gdb/cli/cli-script.c | 8 +++++- > > gdb/doc/ChangeLog | 5 ++++ > > gdb/doc/gdb.texinfo | 54 +++++++++++++++++++++++++++++++++---- > > gdb/testsuite/ChangeLog | 6 +++++ > > gdb/testsuite/gdb.base/commands.exp | 36 +++++++++++++++++++++++++ > > gdb/testsuite/gdb.base/run.c | 3 +++ > > 7 files changed, 111 insertions(+), 6 deletions(-) > > > > diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c > > index 6f31a400197..fd80ab9fbcf 100644 > > --- a/gdb/cli/cli-script.c > > +++ b/gdb/cli/cli-script.c > > @@ -758,6 +758,7 @@ user_args::user_args (const char *command_line) > > int squote = 0; > > int dquote = 0; > > int bsquote = 0; > > + int pdepth = 0; > > > > /* Strip whitespace. */ > > while (*p == ' ' || *p == '\t') > > @@ -769,7 +770,8 @@ user_args::user_args (const char *command_line) > > /* Get to the end of this argument. */ > > while (*p) > > { > > - if (((*p == ' ' || *p == '\t')) && !squote && !dquote && !bsquote) > > + if (((*p == ' ' || *p == '\t')) > > + && !squote && !dquote && !bsquote && pdepth == 0) > > break; > > else > > { > > @@ -793,6 +795,10 @@ user_args::user_args (const char *command_line) > > squote = 1; > > else if (*p == '"') > > dquote = 1; > > + else if (*p == '(') > > + pdepth++; > > + else if (*p == ')') > > + pdepth--; > > } > > p++; > > } > > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > > index 433a2698a92..11cbef97b8f 100644 > > --- a/gdb/doc/gdb.texinfo > > +++ b/gdb/doc/gdb.texinfo > > @@ -25219,14 +25219,58 @@ > > > > @noindent > > This defines the command @code{adder}, which prints the sum of > > -its three arguments. Note the arguments are text substitutions, so they may > > -reference variables, use complex expressions, or even perform inferior > > -functions calls. > > +its three arguments. > > + > > +The arguments to user-defined commands are text substitutions, so they > > +may reference variables, use complex expressions, or even perform > > +inferior functions calls. Each argument is separated with whitespace, > > +so in the previous example three arguments were passed. The following > > +example also passes three arguments, though the arguments are more > > +complex: > > + > > +@smallexample > > +adder 10+1 10+2 10+3 > > +@end smallexample > > + > > +@noindent > > +However, if whitespace were added around the @code{+} characters, then > > +9 arguments would be passed, @code{adder} only uses the first 3 of > > +these arguments, and the others would be silently ignored: > > + > > +@smallexample > > +adder 10 + 1 10 + 2 10 + 3 > > +@end smallexample > > + > > +@noindent > > +Parenthesis can be uses to group complex expressions that include > > +whitespace into a single argument, so the previous example can be > > +modified to pass just 3 arguments again, like this: > > + > > +@smallexample > > +adder (10 + 1) (10 + 2) (10 + 3) > > +@end smallexample > > + > > +@noindent > > +The parenthesis are passed through as part of the argument, so the > > +previous example causes @value{GDBN} to evaluate: > > + > > +@smallexample > > +print (10 + 1) + (10 + 2) + (10 + 3) > > +@end smallexample > > + > > +@noindent > > +Nested parenthesis are also allowed within an argument, in the > > +following example 3 arguments are still passed: > > + > > +@smallexample > > +adder (10 + 1) (10 + (1 + 1)) (10 + (1 + (1 + 1))) > > +@end smallexample > > > > @cindex argument count in user-defined commands > > @cindex how many arguments (user-defined commands) > > -In addition, @code{$argc} may be used to find out how many arguments have > > -been passed. > > +@noindent > > +Within a user-defined command @code{$argc} may be used to find out how > > +many arguments have been passed. > > > > @smallexample > > define adder > > diff --git a/gdb/testsuite/gdb.base/commands.exp b/gdb/testsuite/gdb.base/commands.exp > > index 7ce33fdefa9..42ffd6fa0af 100644 > > --- a/gdb/testsuite/gdb.base/commands.exp > > +++ b/gdb/testsuite/gdb.base/commands.exp > > @@ -1125,6 +1125,41 @@ proc_with_prefix backslash_in_multi_line_command_test {} { > > gdb_test "print 1" "" "run command" > > } > > > > +proc_with_prefix args_with_whitespace {} { > > + gdb_test_multiple "define show_args" "define show_args" { > > + -re "End with" { > > + pass "define show_args" > > + } > > + } > > + > > + # This test should alternate between 0xdeadbeef and 0xfeedface two times. > > + gdb_test \ > > + [multi_line_input \ > > + {printf "nargs=%d:", $argc} \ > > + {set $i = 0} \ > > + {while $i < $argc} \ > > + {printf " "} \ > > + {eval "echo '$arg%d'", $i} \ > > + {set $i = $i + 1} \ > > + {end} \ > > + {printf "\n"} \ > > + {end}] \ > > + "" \ > > + "enter commands" > > + > > + gdb_test "show_args 1 2 3" \ > > + "nargs=3: '1' '2' '3'" > > + > > + gdb_test "show_args 1 (1 + 1) (1 + (1 + 1))" \ > > + "nargs=3: '1' '\\(1 \\+ 1\\)' '\\(1 \\+ \\(1 \\+ 1\\)\\)'" > > + > > + gdb_test "show_args ({unsigned long long} &global_var)" \ > > + "nargs=1: '\\({unsigned long long} &global_var\\)'" > > + > > + gdb_test "show_args (*((unsigned long long *) &global_var))" \ > > + "nargs=1: '\\(\\*\\(\\(unsigned long long \\*\\) &global_var\\)\\)'" > > +} > > + > > gdbvar_simple_if_test > > gdbvar_simple_while_test > > gdbvar_complex_if_while_test > > @@ -1154,5 +1189,6 @@ backslash_in_multi_line_command_test > > define_if_without_arg_test > > loop_break_test > > loop_continue_test > > +args_with_whitespace > > # This one should come last, as it redefines "backtrace". > > redefine_backtrace_test > > diff --git a/gdb/testsuite/gdb.base/run.c b/gdb/testsuite/gdb.base/run.c > > index 614b018260d..d89bad78bb4 100644 > > --- a/gdb/testsuite/gdb.base/run.c > > +++ b/gdb/testsuite/gdb.base/run.c > > @@ -8,6 +8,9 @@ > > > > #include "../lib/unbuffer_output.c" > > > > +/* Used by commands.exp test script. */ > > +volatile unsigned long long global_var = 34; > > + > > int factorial (int); > > > > int