Make "info threads" use the gdb::option framework

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.
This commit is contained in:
Pedro Alves 2019-07-02 16:34:31 +01:00
parent 1faa385ff6
commit 54d6600669
5 changed files with 105 additions and 12 deletions

View 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> 2019-07-02 Simon Marchi <simon.marchi@polymtl.ca>
* defs.h (generic_load): Move from here... * defs.h (generic_load): Move from here...

View File

@ -194,6 +194,8 @@ maint show test-options-completion-result
"taas" commands, and their "-ascending" option can now be "taas" commands, and their "-ascending" option can now be
abbreviated. abbreviated.
** GDB can now complete the options of the "info threads" command.
** GDB can now complete the options of the "compile file" and ** GDB can now complete the options of the "compile file" and
"compile code" commands. The "compile file" command now "compile code" commands. The "compile file" command now
completes on filenames. completes on filenames.

View 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> 2019-06-28 Tom Tromey <tromey@adacore.com>
* gdb.dwarf2/ada-linkage-name.c: New file. * gdb.dwarf2/ada-linkage-name.c: New file.

View 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. # Miscellaneous tests.
proc_with_prefix test-misc {variant} { proc_with_prefix test-misc {variant} {
global all_options global all_options
@ -921,3 +936,6 @@ test-frame-apply
# Basic "thread apply" integration tests. # Basic "thread apply" integration tests.
test-thread-apply test-thread-apply
# Basic "info threads" integration tests.
test-info-threads

View 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); 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. /* Implementation of the "info threads" command.
Note: this has the drawback that it _really_ switches 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 static void
info_threads_command (const char *arg, int from_tty) info_threads_command (const char *arg, int from_tty)
{ {
int show_global_ids = 0; info_threads_opts it_opts;
if (arg != NULL auto grp = make_info_threads_options_def_group (&it_opts);
&& check_for_argument (&arg, "-gid", sizeof ("-gid") - 1)) 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); gdb::option::complete_on_all_options (tracker, grp);
show_global_ids = 1; /* 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. */ /* See gdbthread.h. */
@ -2068,12 +2115,23 @@ _initialize_thread (void)
static struct cmd_list_element *thread_apply_list = NULL; static struct cmd_list_element *thread_apply_list = NULL;
cmd_list_element *c; cmd_list_element *c;
add_info ("threads", info_threads_command, const auto info_threads_opts = make_info_threads_options_def_group (nullptr);
_("Display currently known threads.\n\
Usage: info threads [-gid] [ID]...\n\ /* Note: keep this "ID" in sync with what "info threads [TAB]"
-gid: Show global thread IDs.\n\ 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\ 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, _("\ add_prefix_cmd ("thread", class_run, thread_command, _("\
Use this command to switch between threads.\n\ Use this command to switch between threads.\n\