From 54d6600669256d2b3582d7088d11ab18f6f21f0d Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 2 Jul 2019 16:34:31 +0100 Subject: [PATCH] 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 * 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 * gdb.base/options.exp (test-info-threads): New procedure. (top level): Call it. --- gdb/ChangeLog | 10 ++++ gdb/NEWS | 2 + gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.base/options.exp | 18 +++++++ gdb/thread.c | 82 +++++++++++++++++++++++++----- 5 files changed, 105 insertions(+), 12 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 96011784922..35f1baefb99 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2019-07-02 Pedro Alves + + * 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 * defs.h (generic_load): Move from here... diff --git a/gdb/NEWS b/gdb/NEWS index 2cc82e86560..62521ed75a1 100644 --- 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. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 8b52d445baf..f38efbe515b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-02 Pedro Alves + + * gdb.base/options.exp (test-info-threads): New procedure. + (top level): Call it. + 2019-06-28 Tom Tromey * gdb.dwarf2/ada-linkage-name.c: New file. diff --git a/gdb/testsuite/gdb.base/options.exp b/gdb/testsuite/gdb.base/options.exp index 4570c2a93d4..f88e6a87d3e 100644 --- a/gdb/testsuite/gdb.base/options.exp +++ b/gdb/testsuite/gdb.base/options.exp @@ -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 diff --git a/gdb/thread.c b/gdb/thread.c index 695572f3fb9..d13298f5c6f 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -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 { + "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\ -- 2.30.2