From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22636 invoked by alias); 22 Jan 2016 21:47:03 -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 22617 invoked by uid 89); 22 Jan 2016 21:47:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=2.3 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=principles, H*F:D*be, escaped, H*f:sk:001a114 X-HELO: mailsec112.isp.belgacom.be Received: from mailsec112.isp.belgacom.be (HELO mailsec112.isp.belgacom.be) (195.238.20.108) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 22 Jan 2016 21:46:59 +0000 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2C6CAB4oqJW/5dbgG1YBoM6hCSFcrIVgWKGDwKBQTsSAQEBAQEBAYEKQRIBg24BAQQjMyMQCAMOCgICJgICOR4GiDKvRY8bAQEBBwIeGGOFN4RthCUWgxGBOgWWdog3hR+BXodrhTCKbINTJwoxgX4YgVE7gh2De4E5AQEB Received: from 151.91-128-109.adsl-dyn.isp.belgacom.be (HELO soleil) ([109.128.91.151]) by relay.skynet.be with ESMTP/TLS/AES128-GCM-SHA256; 22 Jan 2016 22:46:56 +0100 Message-ID: <1453499357.2097.18.camel@skynet.be> Subject: Re: RFC: block of commands From: Philippe Waroquiers To: Doug Evans Cc: gdb-patches Date: Fri, 22 Jan 2016 21:47:00 -0000 In-Reply-To: <001a1143804e6a9e8f0529ce089a@google.com> References: <001a1143804e6a9e8f0529ce089a@google.com> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2016-01/txt/msg00590.txt.bz2 I think that effectively, the principles you suggest below should allow to make a reasonable syntax, and no backward incompatibility. So basically: * trailing } is mandatory * inside a block of commands, { } and ; must be escaped * a command block is limited to be on a single line I guess multiple lines will be ok if each line is terminated by a \. The above principles should also allow to extend if/while/... to have 'one line' if/while/... I also think that 'one line if' will allow to do things such as: thread apply all if $ebp -$esp > 1000000 { echo big frame in this thread } (today, trying to use an 'if' in thread apply gives a quite strange behaviour : the rest of the 'if' command is read during each execution for each thread, which is not very user friendly :). I will work based on the above idea, and resubmit a draft patch but that will for sure have to wait after FOSDEM, which will already consume the night and week-end free time :). Thanks for the comments/help/nice suggestions Philippe On Thu, 2016-01-21 at 01:29 +0000, Doug Evans wrote: > Philippe Waroquiers writes: > > On Mon, 2016-01-11 at 21:40 +0000, Doug Evans wrote: > > > Heya. > > > > > > One feature I've always wanted gdb's cli to have is the > > > ability to catch errors and be able to continue. > > > There's always a tension of whether to add things to the cli > > > or just say "do it in python". gdb scripts are still useful > > > and thus sometimes I think it's ok to extend the cli, such > > > as in this case. > > > Thus instead of /c in this patch I'd prefer something > > > along the lines of "try ... end". > > > ["end" is gdb's canonical "trailing }", and I'm all for > > > Consistency Is Good here.] > > > The actual details and semantics of "try" I would > > > leave to a separate thread. For one, I'd have to think > > > about it some more :-), but I would support someone > > > wanting to go down that path. > > > > > > OTOH, trying to extend the cli's syntax with { and ; is not > > > something I can support, at least not without more discussion. > > > This example: > > > > > > thread apply all { set $prevsp = $sp; bt \{ p $ebp - $prevsp\; set > > > $prevsp = $sp \} } > > > => print the size of each frame > > > > > > suggests things could be better; having to escape braces within > > > subcommands feels excessively error prone. > > > gdb has one line per command, and changing that > > > may make things too unwieldly. > > The { (and have the terminating } optional) was chosen in order > > to make the interactive typing of a block of command faster/easier. > > I agree that this new syntax is very different of the > > 'usual gdb multi-lines terminated by end'. > > > > However, multi-lines with end means the user cannot simply type e.g. > > thread apply all { p i; p j} > > Instead, the user must type: > > define pij > > p i > > p j > > end > > thread apply all pij > > And after, if the user wants to also print k, > > then the pij sequence must be retyped (I do not know a way > > to change/edit/complete a user defined command). > > Yeah. I recognize the difficulty. > But adding {...; ...} on top of what's there now > is going to be a slippery slope I fear. > [maybe not, but we're adding syntax to what > has until now been pretty free form] > I want to make sure that if we add this, > we don't some day end up regretting it. > > Note that at least within emacs I can repeat/edit > multi-line commands by going back through the history. > Plus one can redefine user-defined commands > from the keyboard. So it's possible, if tedious. > > > An alternative might be to make the terminating } mandatory. > > Then I think we could get rid of the { and } escaping > > I'd prefer to be strict (e.g., require }), at least for now. > Once we add { ...; ... }, someone is going to want to extend it, > and then we've got if/while/etc. that can all be done as one-liners. > [If we're going to make interactive use easier, why can't > if/while/etc. be done as one-liners? It feels like if a > compelling argument can't be made to allow them to be one-liners, > then supporting one-liners in a more restricted fashion > isn't very compelling and maybe we should just punt.] > Let's think this through. > > > So, the question is how much we want to make the block of commands > > easy to use interactively ? > > > > Maybe it is not that unusual to have 2 concepts > > of 'list of commands' : > > one command per line, with some 'begin/end' keywords > > several commands per lines, separated by ; > > (i.e. similar to what a shell is providing with if/fi and ;). > > > > The ; separated list versus multi-lines is clearly the main > > point of discussion. > > > > Note that if ever the {}; idea survives, we have to take care > > about parsing of existing scripts that would do e.g. > > echo { is an open bracket > > Not too sure it will be easy to make the {}; idea fully backward > > compatible :( > > That's going to be a tricky part, yeah. > > Existing "echo {" may not be so bad, as echo doesn't take a command > as an argument. While less than ideal, we could defer parsing > { ... } until we're parsing a command that takes a command as > an argument (either literally, as in "thread apply ...", > or conceptually, as in "if expr ..."). > Of course, extending "if/while" like this would be problematic if > a language allowed { in an expression. > > Another thought is: If we extend this to if/while/etc. > then it'd be odd to not be able to terminate a multi-line "if" > with }, except that there is no opening { in a multi-line "if". > So does that mean { ... } is restricted to one line? > Probably, but it may trip people up from time to time. > > Another thought: What does this do? > > if a == b { echo foo } > > If we don't enforce a trailing } then is that "echo foo" or "echo foo }"? > Maybe a good example to suggest we should indeed require a trailing }? > > Similarly with ; > > if a == b { echo foo; } > > These questions apply even if we don't extend "if": > > thread apply all { echo foo; } > > > > There are still > > > macros so one could still do "thread apply all print-frame-size", > > > and put the guts of frame size computation in a macro named > > > print-frame-size. > > True, but that makes the interactive use and editing > > not so easy (cfr above). > > Yep. > This is a significant addition, > I'm just asking for a thorough vetting of it. > > Deciding how to parse embedded {/;/} is probably > the important part (as you've mentioned). > > E.g., if a == b { if c == d { echo foo; }; echo bar } > > or > > thread apply all { frame apply all { echo \{foo\}; printf "\{foo\}"; } } > > We have to find the outer } so we know what command to > execute for each thread, but in order to do that we > have to do some parsing of the inner command in order > to handle the nesting. > Plus, as you've mentioned, we'll need some kind of escaping; > when we run the "frame apply all" command is it: > echo {foo}; printf "\{foo\}" > ? > > Since this is new syntax, we're free to define things > however we like, within reason. > > > > Also, I'd prefer to have generally composable commands > > > over extending individual commands. > > > E.g., one common thing to do with "thread apply" is backtrace, > > > as in "thread apply all bt". I like that much better than > > > if we had extended backtrace to work on each thread. > > > > > > Following "Consistency Is Good", and given that we have > > > "thread apply", for your "bt {/c p i" case how about > > > something like: > > > > > > frame apply all foo > > Yes, that looks better than adding an optional command to > > backtrace.