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]

[patch v2] gdb: add completion handler for "handle"


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 <vapier@gentoo.org>

v2
	- i'm dumb and realized that the "signal" command could easily use the
	new signal completer too

2012-08-01  Mike Frysinger  <vapier@gentoo.org>

        * 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, _("\


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