Add `set print repeats' tests for C/C++ arrays
[binutils-gdb.git] / gdb / maint.c
index bfdd1d5ca3ef7d2cff682677d1399911cb284781..3584974c9e15e30814f9731dc7f780929eca1422 100644 (file)
@@ -1,6 +1,6 @@
 /* Support for GDB maintenance commands.
 
-   Copyright (C) 1992-2021 Free Software Foundation, Inc.
+   Copyright (C) 1992-2022 Free Software Foundation, Inc.
 
    Written by Fred Fish at Cygnus Support.
 
@@ -40,6 +40,7 @@
 #include "top.h"
 #include "maint.h"
 #include "gdbsupport/selftest.h"
+#include "inferior.h"
 
 #include "cli/cli-decode.h"
 #include "cli/cli-utils.h"
@@ -115,7 +116,7 @@ static void
 maintenance_time_display (const char *args, int from_tty)
 {
   if (args == NULL || *args == '\0')
-    printf_unfiltered (_("\"maintenance time\" takes a numeric argument.\n"));
+    printf_filtered (_("\"maintenance time\" takes a numeric argument.\n"));
   else
     set_per_command_time (strtol (args, NULL, 10));
 }
@@ -124,7 +125,7 @@ static void
 maintenance_space_display (const char *args, int from_tty)
 {
   if (args == NULL || *args == '\0')
-    printf_unfiltered ("\"maintenance space\" takes a numeric argument.\n");
+    printf_filtered ("\"maintenance space\" takes a numeric argument.\n");
   else
     set_per_command_space (strtol (args, NULL, 10));
 }
@@ -318,8 +319,7 @@ print_objfile_section_info (bfd *abfd, struct obj_section *asect,
 
       print_section_index (abfd, asect->the_bfd_section, index_digits);
       maint_print_section_info (name, flags,
-                               obj_section_addr (asect),
-                               obj_section_endaddr (asect),
+                               asect->addr (), asect->endaddr (),
                                asect->the_bfd_section->filepos,
                                addr_size);
     }
@@ -329,7 +329,7 @@ print_objfile_section_info (bfd *abfd, struct obj_section *asect,
    from ABFD.  It might be that no such wrapper exists (for example debug
    sections don't have such wrappers) in which case nullptr is returned.  */
 
-static obj_section *
+obj_section *
 maint_obj_section_from_bfd_section (bfd *abfd,
                                    asection *asection,
                                    objfile *ofile)
@@ -472,7 +472,7 @@ maintenance_info_target_sections (const char *arg, int from_tty)
   bfd *abfd = nullptr;
   int digits = 0;
   const target_section_table *table
-    = target_get_section_table (current_top_target ());
+    = target_get_section_table (current_inferior ()->top_target ());
   if (table == nullptr)
     return;
 
@@ -518,7 +518,6 @@ static void
 maintenance_print_statistics (const char *args, int from_tty)
 {
   print_objfile_statistics ();
-  print_symbol_bcache_statistics ();
 }
 
 static void
@@ -633,7 +632,7 @@ maintenance_deprecate (const char *args, int from_tty)
 {
   if (args == NULL || *args == '\0')
     {
-      printf_unfiltered (_("\"maintenance deprecate\" takes an argument,\n\
+      printf_filtered (_("\"maintenance deprecate\" takes an argument,\n\
 the command you want to deprecate, and optionally the replacement command\n\
 enclosed in quotes.\n"));
     }
@@ -647,7 +646,7 @@ maintenance_undeprecate (const char *args, int from_tty)
 {
   if (args == NULL || *args == '\0')
     {
-      printf_unfiltered (_("\"maintenance undeprecate\" takes an argument, \n\
+      printf_filtered (_("\"maintenance undeprecate\" takes an argument, \n\
 the command you want to undeprecate.\n"));
     }
 
@@ -867,6 +866,30 @@ maintenance_set_worker_threads (const char *args, int from_tty,
   update_thread_pool_size ();
 }
 
+static void
+maintenance_show_worker_threads (struct ui_file *file, int from_tty,
+                                struct cmd_list_element *c,
+                                const char *value)
+{
+#if CXX_STD_THREAD
+  if (n_worker_threads == -1)
+    {
+      fprintf_filtered (file, _("The number of worker threads GDB "
+                               "can use is unlimited (currently %zu).\n"),
+                       gdb::thread_pool::g_thread_pool->thread_count ());
+      return;
+    }
+#endif
+
+  int report_threads = 0;
+#if CXX_STD_THREAD
+  report_threads = n_worker_threads;
+#endif
+  fprintf_filtered (file, _("The number of worker threads GDB "
+                           "can use is %d.\n"),
+                   report_threads);
+}
+
 \f
 /* If true, display time usage both at startup and for each command.  */
 
@@ -1089,14 +1112,41 @@ set_per_command_cmd (const char *args, int from_tty)
     error (_("Bad value for 'mt set per-command no'."));
 
   for (list = per_command_setlist; list != NULL; list = list->next)
-    if (list->var_type == var_boolean)
+    if (list->var->type () == var_boolean)
       {
        gdb_assert (list->type == set_cmd);
        do_set_command (args, from_tty, list);
       }
 }
 
-\f
+/* Options affecting the "maintenance selftest" command.  */
+
+struct maintenance_selftest_options
+{
+  bool verbose = false;
+} user_maintenance_selftest_options;
+
+static const gdb::option::option_def maintenance_selftest_option_defs[] = {
+  gdb::option::boolean_option_def<maintenance_selftest_options> {
+    "verbose",
+    [] (maintenance_selftest_options *opt) { return &opt->verbose; },
+    nullptr,
+    N_("Set whether selftests run in verbose mode."),
+    N_("Show whether selftests run in verbose mode."),
+    N_("\
+When on, selftests may print verbose information."),
+  },
+};
+
+/* Make option groups for the "maintenance selftest" command.  */
+
+static std::array<gdb::option::option_def_group, 1>
+make_maintenance_selftest_option_group (maintenance_selftest_options *opts)
+{
+  return {{
+    {{maintenance_selftest_option_defs}, opts},
+  }};
+}
 
 /* The "maintenance selftest" command.  */
 
@@ -1104,14 +1154,41 @@ static void
 maintenance_selftest (const char *args, int from_tty)
 {
 #if GDB_SELF_TEST
-  gdb_argv argv (args);
-  selftests::run_tests (argv.as_array_view ());
+  maintenance_selftest_options opts = user_maintenance_selftest_options;
+  auto grp = make_maintenance_selftest_option_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
+  const gdb_argv argv (args);
+  selftests::run_tests (argv.as_array_view (), opts.verbose);
 #else
   printf_filtered (_("\
 Selftests have been disabled for this build.\n"));
 #endif
 }
 
+/* Completer for the "maintenance selftest" command.  */
+
+static void
+maintenance_selftest_completer (cmd_list_element *cmd,
+                               completion_tracker &tracker,
+                               const char *text,
+                               const char *word)
+{
+  auto grp = make_maintenance_selftest_option_group (nullptr);
+
+  if (gdb::option::complete_options
+       (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
+    return;
+
+#if GDB_SELF_TEST
+  selftests::for_each_selftest ([&tracker, text] (const std::string &name)
+    {
+      if (startswith (name.c_str (), text))
+       tracker.add_completion (make_unique_xstrdup (name.c_str ()));
+    });
+#endif
+}
+
 static void
 maintenance_info_selftests (const char *arg, int from_tty)
 {
@@ -1133,20 +1210,23 @@ _initialize_maint_cmds ()
 {
   struct cmd_list_element *cmd;
 
-  add_basic_prefix_cmd ("maintenance", class_maintenance, _("\
+  cmd_list_element *maintenance_cmd
+    = add_basic_prefix_cmd ("maintenance", class_maintenance, _("\
 Commands for use by GDB maintainers.\n\
 Includes commands to dump specific internal GDB structures in\n\
 a human readable form, to cause GDB to deliberately dump core, etc."),
-                       &maintenancelist, "maintenance ", 0,
-                       &cmdlist);
+                           &maintenancelist, 0,
+                           &cmdlist);
 
-  add_com_alias ("mt", "maintenance", class_maintenance, 1);
+  add_com_alias ("mt", maintenance_cmd, class_maintenance, 1);
 
-  add_basic_prefix_cmd ("info", class_maintenance, _("\
+  cmd_list_element *maintenance_info_cmd
+    = add_basic_prefix_cmd ("info", class_maintenance, _("\
 Commands for showing internal info about the program being debugged."),
-                       &maintenanceinfolist, "maintenance info ", 0,
-                       &maintenancelist);
-  add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist);
+                           &maintenanceinfolist, 0,
+                           &maintenancelist);
+  add_alias_cmd ("i", maintenance_info_cmd, class_maintenance, 1,
+                &maintenancelist);
 
   const auto opts = make_maint_info_sections_options_def_group (nullptr);
   static std::string maint_info_sections_command_help
@@ -1183,25 +1263,25 @@ sectoins."),
 
   add_basic_prefix_cmd ("print", class_maintenance,
                        _("Maintenance command for printing GDB internal state."),
-                       &maintenanceprintlist, "maintenance print ", 0,
+                       &maintenanceprintlist, 0,
                        &maintenancelist);
 
   add_basic_prefix_cmd ("flush", class_maintenance,
                        _("Maintenance command for flushing GDB internal caches."),
-                       &maintenanceflushlist, "maintenance flush ", 0,
+                       &maintenanceflushlist, 0,
                        &maintenancelist);
 
   add_basic_prefix_cmd ("set", class_maintenance, _("\
 Set GDB internal variables used by the GDB maintainer.\n\
 Configure variables internal to GDB that aid in GDB's maintenance"),
-                       &maintenance_set_cmdlist, "maintenance set ",
+                       &maintenance_set_cmdlist,
                        0/*allow-unknown*/,
                        &maintenancelist);
 
   add_show_prefix_cmd ("show", class_maintenance, _("\
 Show GDB internal variables used by the GDB maintainer.\n\
 Configure variables internal to GDB that aid in GDB's maintenance"),
-                      &maintenance_show_cmdlist, "maintenance show ",
+                      &maintenance_show_cmdlist,
                       0/*allow-unknown*/,
                       &maintenancelist);
 
@@ -1247,12 +1327,12 @@ This command has been moved to \"demangle\"."),
 
   add_prefix_cmd ("per-command", class_maintenance, set_per_command_cmd, _("\
 Per-command statistics settings."),
-                   &per_command_setlist, "maintenance set per-command ",
+                   &per_command_setlist,
                    1/*allow-unknown*/, &maintenance_set_cmdlist);
 
   add_show_prefix_cmd ("per-command", class_maintenance, _("\
 Show per-command statistics settings."),
-                      &per_command_showlist, "maintenance show per-command ",
+                      &per_command_showlist,
                       0/*allow-unknown*/, &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd ("time", class_maintenance,
@@ -1320,7 +1400,7 @@ Takes an optional file parameter."),
 
   add_basic_prefix_cmd ("check", class_maintenance, _("\
 Commands for checking internal gdb state."),
-                       &maintenancechecklist, "maintenance check ", 0,
+                       &maintenancechecklist, 0,
                        &maintenancelist);
 
   add_cmd ("translate-address", class_maintenance,
@@ -1342,12 +1422,15 @@ This is used by the testsuite to check the command deprecator.\n\
 You probably shouldn't use this."),
           &maintenancelist);
 
-  add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
+  cmd_list_element *maintenance_selftest_cmd
+    = add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
 Run gdb's unit tests.\n\
 Usage: maintenance selftest [FILTER]\n\
 This will run any unit tests that were built in to gdb.\n\
 If a filter is given, only the tests with that value in their name will ran."),
-          &maintenancelist);
+              &maintenancelist);
+  set_cmd_completer_handle_brkchars (maintenance_selftest_cmd,
+                                    maintenance_selftest_completer);
 
   add_cmd ("selftests", class_maintenance, maintenance_info_selftests,
         _("List the registered selftests."), &maintenanceinfolist);
@@ -1369,9 +1452,27 @@ Set the number of worker threads GDB can use."), _("\
 Show the number of worker threads GDB can use."), _("\
 GDB may use multiple threads to speed up certain CPU-intensive operations,\n\
 such as demangling symbol names."),
-                                      maintenance_set_worker_threads, NULL,
+                                      maintenance_set_worker_threads,
+                                      maintenance_show_worker_threads,
                                       &maintenance_set_cmdlist,
                                       &maintenance_show_cmdlist);
 
+  /* Add the "maint set/show selftest" commands.  */
+  static cmd_list_element *set_selftest_cmdlist = nullptr;
+  static cmd_list_element *show_selftest_cmdlist = nullptr;
+
+  add_setshow_prefix_cmd ("selftest", class_maintenance,
+                         _("Self tests-related settings."),
+                         _("Self tests-related settings."),
+                         &set_selftest_cmdlist, &show_selftest_cmdlist,
+                         &maintenance_set_cmdlist, &maintenance_show_cmdlist);
+
+  /* Add setting commands matching "maintenance selftest" options.  */
+  gdb::option::add_setshow_cmds_for_options (class_maintenance,
+                                            &user_maintenance_selftest_options,
+                                            maintenance_selftest_option_defs,
+                                            &set_selftest_cmdlist,
+                                            &show_selftest_cmdlist);
+
   update_thread_pool_size ();
 }