From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5362 invoked by alias); 2 Aug 2012 03:58:31 -0000 Received: (qmail 5353 invoked by uid 22791); 2 Aug 2012 03:58:29 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp.gentoo.org (HELO smtp.gentoo.org) (140.211.166.183) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 02 Aug 2012 03:58:16 +0000 Received: from vapier.localnet (localhost [127.0.0.1]) by smtp.gentoo.org (Postfix) with ESMTP id 4EFBC1B4011 for ; Thu, 2 Aug 2012 03:58:15 +0000 (UTC) From: Mike Frysinger To: gdb-patches@sourceware.org Subject: [patch v2] gdb: add completion handler for "handle" Date: Thu, 02 Aug 2012 03:58:00 -0000 User-Agent: KMail/1.13.7 (Linux/3.5.0; KDE/4.6.5; x86_64; ; ) References: <201208012353.56496.vapier@gentoo.org> In-Reply-To: <201208012353.56496.vapier@gentoo.org> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201208012358.18948.vapier@gentoo.org> X-IsSubscribed: yes 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/msg00050.txt.bz2 The command line completion has spoiled me. Thus the lack of completion with the "handle" command annoys me. Patch! 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; +} + /* 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. */ + 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)); + } +} + 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\ 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, _("\