From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15699 invoked by alias); 2 Aug 2012 11:24:38 -0000 Received: (qmail 15684 invoked by uid 22791); 2 Aug 2012 11:24:35 -0000 X-SWARE-Spam-Status: No, hits=-7.5 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 02 Aug 2012 11:24:14 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q72BO9H3031518 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 2 Aug 2012 07:24:09 -0400 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q72BO81D015020; Thu, 2 Aug 2012 07:24:08 -0400 Message-ID: <501A6357.4070503@redhat.com> Date: Thu, 02 Aug 2012 11:24:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20120717 Thunderbird/14.0 MIME-Version: 1.0 To: Mike Frysinger CC: gdb-patches@sourceware.org Subject: Re: [patch v2] gdb: add completion handler for "handle" References: <201208012353.56496.vapier@gentoo.org> <201208012358.18948.vapier@gentoo.org> In-Reply-To: <201208012358.18948.vapier@gentoo.org> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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 X-SW-Source: 2012-08/txt/msg00063.txt.bz2 On 08/02/2012 04:58 AM, Mike Frysinger wrote: > The command line completion has spoiled me. Thus the lack of completion with > the "handle" command annoys me. Patch! Nice! > This does a few things: > - adds a generic signal completer > - adds a generic completer based on a specified array of strings > - adds a completion handler for the "handle" command > - adds a completion handler for the "signal" command > - improves the "signal" and "handle" help strings slightly > > Signed-off-by: Mike Frysinger > > v2 > - i'm dumb and realized that the "signal" command could easily use the > new signal completer too > > 2012-08-01 Mike Frysinger > > * completer.c: Include gdb_signals.h. > (signal_completer): Define. > (string_array_completer): Define. > * completer.h (signal_completer): Add prototype. > (string_array_completer): Likewise. > * infcmd.c (_initialize_infcmd): Add a reference to "handle" > in the "string" documentation. Assign the command > completer for "signal" to handle_completer. > * infrun.c: Include completer.h. > (handle_completer): Define. > (_initialize_infrun): Declare a new local variable c. Store the > result of add_com("handle") to it. Add simple usage to > the start of the "handle" documentation. Assign the command > completer for "handle" to handle_completer. > > gdb/completer.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > gdb/completer.h | 7 +++++++ > gdb/infcmd.c | 6 ++++-- > gdb/infrun.c | 35 +++++++++++++++++++++++++++++++++-- > 4 files changed, 96 insertions(+), 4 deletions(-) > > diff --git a/gdb/completer.c b/gdb/completer.c > index b9f0699..1d81e36 100644 > --- a/gdb/completer.c > +++ b/gdb/completer.c > @@ -24,6 +24,7 @@ > #include "language.h" > #include "gdb_assert.h" > #include "exceptions.h" > +#include "gdb_signals.h" > > #include "cli/cli-decode.h" > > @@ -797,6 +798,57 @@ command_completer (struct cmd_list_element *ignore, > strlen (text), handle_help); > } > > +/* Complete on signals. */ > + > +VEC (char_ptr) * > +signal_completer (struct cmd_list_element *ignore, > + char *text, char *word) > +{ > + int i; > + VEC (char_ptr) *return_val = NULL; > + size_t len = strlen (word); > + enum gdb_signal signum; > + const char *signame; > + > + for (signum = GDB_SIGNAL_FIRST; signum != GDB_SIGNAL_LAST; ++signum) > + { > + /* Can't handle this, so skip it. */ > + if (signum == GDB_SIGNAL_0) > + continue; > + > + signame = gdb_signal_to_name (signum); > + > + /* Ignore the unknown signal case. */ > + if (!signame || strcmp (signame, "?") == 0) > + continue; > + > + if (strncasecmp (signame, word, len) == 0) > + VEC_safe_push (char_ptr, return_val, xstrdup (signame)); > + } > + > + return return_val; > +} > + > +/* Complete based on an array of strings. */ > + > +VEC (char_ptr) * > +string_array_completer (struct cmd_list_element *ignore, > + char *text, char *word, const char * const strings[], > + size_t num_strings) > +{ > + size_t i; > + VEC (char_ptr) *return_val = NULL; > + size_t len = strlen (word); > + > + for (i = 0; i < num_strings; ++i) > + { > + if (strncasecmp (strings[i], word, len) == 0) > + VEC_safe_push (char_ptr, return_val, xstrdup (strings[i])); > + } > + > + return return_val; > +} > + See complete_on_enum. > /* Get the list of chars that are considered as word breaks > for the current command. */ > > diff --git a/gdb/completer.h b/gdb/completer.h > index 680bc2d..fa1b213 100644 > --- a/gdb/completer.h > +++ b/gdb/completer.h > @@ -41,6 +41,13 @@ extern VEC (char_ptr) *location_completer (struct cmd_list_element *, > extern VEC (char_ptr) *command_completer (struct cmd_list_element *, > char *, char *); > > +extern VEC (char_ptr) *signal_completer (struct cmd_list_element *, > + char *, char *); > + > +extern VEC (char_ptr) *string_array_completer (struct cmd_list_element *, > + char *, char *, > + const char * const[], size_t); > + > extern char *get_gdb_completer_quote_characters (void); > > extern char *gdb_completion_word_break_characters (void); > diff --git a/gdb/infcmd.c b/gdb/infcmd.c > index 635e577..b76ee96 100644 > --- a/gdb/infcmd.c > +++ b/gdb/infcmd.c > @@ -3016,9 +3016,11 @@ Disconnect from a target.\n\ > The target will wait for another debugger to connect. Not available for\n\ > all targets.")); > > - add_com ("signal", class_run, signal_command, _("\ > + c = add_com ("signal", class_run, signal_command, _("\ > Continue program giving it signal specified by the argument.\n\ > -An argument of \"0\" means continue program without giving it a signal.")); > +An argument of \"0\" means continue program without giving it a signal.\n\ > +Use the \"handle\" command to automate signal behavior.")); > + set_cmd_completer (c, signal_completer); > > add_com ("stepi", class_run, stepi_command, _("\ > Step one instruction exactly.\n\ > diff --git a/gdb/infrun.c b/gdb/infrun.c > index efc4162..19fa6ac 100644 > --- a/gdb/infrun.c > +++ b/gdb/infrun.c > @@ -57,6 +57,7 @@ > #include "skip.h" > #include "probe.h" > #include "objfiles.h" > +#include "completer.h" > > /* Prototypes for local functions */ > > @@ -6416,6 +6417,34 @@ Are you sure you want to change it? "), > do_cleanups (old_chain); > } > > +/* Complete the "handle" command. */ > + > +static VEC (char_ptr) * > +handle_completer (struct cmd_list_element *ignore, > + char *text, char *word) > +{ > + /* First word is a signal, while the rest are keywords. */ Actually, "handle" accepts more than one signal. E.g., (gdb) handle SIGCANCEL SIGABRT stop Signal Stop Print Pass to program Description SIGABRT Yes Yes Yes Aborted SIGCANCEL Yes Yes Yes LWP internal signal Can we make that work? Basically, for all but the first arg, you'd accept the union of the signal names, and the possible actions. > + if (text == word) > + return signal_completer (ignore, text, word); > + else > + { > + static const char * const keywords[] = > + { > + "all", > + "stop", > + "ignore", > + "print", > + "pass", > + "nostop", > + "noignore", > + "noprint", > + "nopass", > + }; > + return string_array_completer (ignore, text, word, keywords, > + ARRAY_SIZE (keywords)); You can use the existing complete_on_enum instead. (Just add a NULL terminator to the string array.) > + } > +} > + > static void > xdb_handle_command (char *args, int from_tty) > { > @@ -7059,14 +7088,15 @@ _initialize_infrun (void) > { > int i; > int numsigs; > + struct cmd_list_element *c; > > add_info ("signals", signals_info, _("\ > What debugger does when program gets various signals.\n\ > Specify a signal as argument to print info on that signal only.")); > add_info_alias ("handle", "signals", 0); > > - add_com ("handle", class_run, handle_command, _("\ > -Specify how to handle a signal.\n\ > + c = add_com ("handle", class_run, handle_command, _("\ > +Handle signals: handle SIGNAL [KEYWORDS]\n\ > Args are signals and actions to apply to those signals.\n\ The first line of the doc is special. It's what "apropos" shows. before: (gdb) apropos signals handle -- Specify how to handle a signal info handle -- What debugger does when program gets various signals info signals -- What debugger does when program gets various signals after: (gdb) apropos signals handle -- Handle signals: handle SIGNAL [KEYWORDS] info handle -- What debugger does when program gets various signals info signals -- What debugger does when program gets various signals The old strings looked better here to me. This and the "signal" docu change are a bit of a tangent wrt completion, so split them out, please. > Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\ > from 1-15 are allowed for compatibility with old versions of GDB.\n\ > @@ -7080,6 +7110,7 @@ Print means print a message if this signal happens.\n\ > Pass means let program see this signal; otherwise program doesn't know.\n\ > Ignore is a synonym for nopass and noignore is a synonym for pass.\n\ > Pass and Stop may be combined.")); > + set_cmd_completer (c, handle_completer); > if (xdb_commands) > { > add_com ("lz", class_info, signals_info, _("\ > -- Pedro Alves