Make "info threads" use the gdb::option framework
authorPedro Alves <palves@redhat.com>
Tue, 2 Jul 2019 15:34:31 +0000 (16:34 +0100)
committerPedro Alves <palves@redhat.com>
Tue, 2 Jul 2019 15:34:31 +0000 (16:34 +0100)
This makes "info threads" use the gdb::option framework to process
options.  There's only one option today (-gid), and it isn't used much
frequently unless you're looking at matching MI output.  Still, this
was in the neighborhood of "thread apply" so I had converted it.

The main advantage is that TAB completion now shows you the available
options, and gives you a hint to what the command accepts as operand
argument, including showing a metasyntactic variable:

  (gdb) info threads [TAB]
  -gid  ID

  (gdb) help info threads
  Display currently known threads.
  Usage: info threads [OPTION]... [ID]...

  Options:
    -gid
      Show global thread IDs.

  If ID is given, it is a space-separated list of IDs of threads to display.
  Otherwise, all threads are displayed.
  (gdb)

gdb/ChangeLog:
2019-07-02  Pedro Alves  <palves@redhat.com>

* NEWS (Completion improvements): Mention "info threads".
* thread.c (struct info_threads_opts, info_threads_option_defs)
(make_info_threads_options_def_group): New.
(info_threads_command): Use gdb::option::process_options.
(info_threads_command_completer): New.
(_initialize_thread): Use gdb::option::build_help to build the
help text for "info threads".

gdb/testsuite/ChangeLog:
2019-07-02  Pedro Alves  <palves@redhat.com>

* gdb.base/options.exp (test-info-threads): New procedure.
(top level): Call it.

gdb/ChangeLog
gdb/NEWS
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/options.exp
gdb/thread.c

index 9601178492227b34b20a05f98187c6ca18657151..35f1baefb997ef4c43664ee0fc6c2bf1786d87df 100644 (file)
@@ -1,3 +1,13 @@
+2019-07-02  Pedro Alves  <palves@redhat.com>
+
+       * NEWS (Completion improvements): Mention "info threads".
+       * thread.c (struct info_threads_opts, info_threads_option_defs)
+       (make_info_threads_options_def_group): New.
+       (info_threads_command): Use gdb::option::process_options.
+       (info_threads_command_completer): New.
+       (_initialize_thread): Use gdb::option::build_help to build the
+       help text for "info threads".
+
 2019-07-02  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * defs.h (generic_load): Move from here...
index 2cc82e86560260b2d33bd40cab504a109e064437..62521ed75a13bef85cc9dd948e4e187cb3fc383a 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -194,6 +194,8 @@ maint show test-options-completion-result
      "taas" commands, and their "-ascending" option can now be
      abbreviated.
 
+  ** GDB can now complete the options of the "info threads" command.
+
   ** GDB can now complete the options of the "compile file" and
      "compile code" commands.  The "compile file" command now
      completes on filenames.
index 8b52d445baf4b78216e9e7354ceb3b21bcf17f5d..f38efbe515b0d1e9f969405f2b800f66e0b939a7 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-02  Pedro Alves  <palves@redhat.com>
+
+       * gdb.base/options.exp (test-info-threads): New procedure.
+       (top level): Call it.
+
 2019-06-28  Tom Tromey  <tromey@adacore.com>
 
        * gdb.dwarf2/ada-linkage-name.c: New file.
index 4570c2a93d4d91b821e4f9673ef8d100933b0a66..f88e6a87d3e6caa5ac959c953f1c184ac1caf1d1 100644 (file)
@@ -454,6 +454,21 @@ proc_with_prefix test-thread-apply {} {
     }
 }
 
+# Basic option-machinery + "info threads" command integration tests.
+proc_with_prefix test-info-threads {} {
+    test_gdb_complete_multiple "info threads " "" "" {
+       "-gid"
+       "ID"
+    }
+
+    test_gdb_complete_unique \
+       "info threads -" \
+       "info threads -gid"
+
+    # "ID" isn't really something the user can type.
+    test_gdb_complete_none "info threads I"
+}
+
 # Miscellaneous tests.
 proc_with_prefix test-misc {variant} {
     global all_options
@@ -921,3 +936,6 @@ test-frame-apply
 
 # Basic "thread apply" integration tests.
 test-thread-apply
+
+# Basic "info threads" integration tests.
+test-info-threads
index 695572f3fb91b13611f3c250f6be2fb492c59946..d13298f5c6f5401478c704ecebe9b197ac118408 100644 (file)
@@ -1199,6 +1199,33 @@ print_thread_info (struct ui_out *uiout, const char *requested_threads,
   print_thread_info_1 (uiout, requested_threads, 1, pid, 0);
 }
 
+/* The options for the "info threads" command.  */
+
+struct info_threads_opts
+{
+  /* For "-gid".  */
+  int show_global_ids = 0;
+};
+
+static const gdb::option::option_def info_threads_option_defs[] = {
+
+  gdb::option::flag_option_def<info_threads_opts> {
+    "gid",
+    [] (info_threads_opts *opts) { return &opts->show_global_ids; },
+    N_("Show global thread IDs."),
+  },
+
+};
+
+/* Create an option_def_group for the "info threads" options, with
+   IT_OPTS as context.  */
+
+static inline gdb::option::option_def_group
+make_info_threads_options_def_group (info_threads_opts *it_opts)
+{
+  return {{info_threads_option_defs}, it_opts};
+}
+
 /* Implementation of the "info threads" command.
 
    Note: this has the drawback that it _really_ switches
@@ -1208,16 +1235,36 @@ print_thread_info (struct ui_out *uiout, const char *requested_threads,
 static void
 info_threads_command (const char *arg, int from_tty)
 {
-  int show_global_ids = 0;
+  info_threads_opts it_opts;
 
-  if (arg != NULL
-      && check_for_argument (&arg, "-gid", sizeof ("-gid") - 1))
+  auto grp = make_info_threads_options_def_group (&it_opts);
+  gdb::option::process_options
+    (&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
+
+  print_thread_info_1 (current_uiout, arg, 0, -1, it_opts.show_global_ids);
+}
+
+/* Completer for the "info threads" command.  */
+
+static void
+info_threads_command_completer (struct cmd_list_element *ignore,
+                               completion_tracker &tracker,
+                               const char *text, const char *word_ignored)
+{
+  const auto grp = make_info_threads_options_def_group (nullptr);
+
+  if (gdb::option::complete_options
+      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
+    return;
+
+  /* Convenience to let the user know what the option can accept.  */
+  if (*text == '\0')
     {
-      arg = skip_spaces (arg);
-      show_global_ids = 1;
+      gdb::option::complete_on_all_options (tracker, grp);
+      /* Keep this "ID" in sync with what "help info threads"
+        says.  */
+      tracker.add_completion (make_unique_xstrdup ("ID"));
     }
-
-  print_thread_info_1 (current_uiout, arg, 0, -1, show_global_ids);
 }
 
 /* See gdbthread.h.  */
@@ -2068,12 +2115,23 @@ _initialize_thread (void)
   static struct cmd_list_element *thread_apply_list = NULL;
   cmd_list_element *c;
 
-  add_info ("threads", info_threads_command,
-           _("Display currently known threads.\n\
-Usage: info threads [-gid] [ID]...\n\
--gid: Show global thread IDs.\n\
+  const auto info_threads_opts = make_info_threads_options_def_group (nullptr);
+
+  /* Note: keep this "ID" in sync with what "info threads [TAB]"
+     suggests.  */
+  static std::string info_threads_help
+    = gdb::option::build_help (_("\
+Display currently known threads.\n\
+Usage: info threads [OPTION]... [ID]...\n\
+\n\
+Options:\n\
+%OPTIONS%\
 If ID is given, it is a space-separated list of IDs of threads to display.\n\
-Otherwise, all threads are displayed."));
+Otherwise, all threads are displayed."),
+                              info_threads_opts);
+
+  c = add_info ("threads", info_threads_command, info_threads_help.c_str ());
+  set_cmd_completer_handle_brkchars (c, info_threads_command_completer);
 
   add_prefix_cmd ("thread", class_run, thread_command, _("\
 Use this command to switch between threads.\n\