Replace most calls to help_list and cmd_show_list

Message ID 20200417132940.3978-1-tromey@adacore.com
State New
Headers show
Series
  • Replace most calls to help_list and cmd_show_list
Related show

Commit Message

Tom Tromey April 17, 2020, 1:29 p.m.
Currently there are many prefix commands that do nothing but call
either help_list or cmd_show_list.  I happened to notice that one such
call, for "set print type", used the wrong command list parameter,
causing incorrect output.

Rather than fix this bug in isolation, I decided to eliminate this
possibility by adding two new ways to add prefix commands, which
simply route the call to help_list or cmd_show_list, as appropriate.
This makes it impossible for a mismatch to occur.

In some cases, a bit of output was remove; however, I don't think this
output in general was very useful.  It seemed redundant with what's
already printed by help_list.

This simplified the CLI style set/show commands quite a bit, and
allowed the deletion of a macro.

This also cleans up some unusual code in windows-tdep.c.

Tested on x86-64 Fedora 30.  Note that I have no way to build the
go32-nat.c change.

gdb/ChangeLog
2020-04-17  Tom Tromey  <tromey@adacore.com>

	* auto-load.c (show_auto_load_cmd): Remove.
	(auto_load_show_cmdlist_get): Use add_show_prefix_cmd.
	* arc-tdep.c (_initialize_arc_tdep): Use add_show_prefix_cmd.
	(maintenance_print_arc_command): Remove.
	* tui/tui-win.c (tui_command): Remove.
	(tui_get_cmd_list): Use add_basic_prefix_cmd.
	* tui/tui-layout.c (tui_layout_command): Remove.
	(_initialize_tui_layout): Use add_basic_prefix_cmd.
	* python/python.c (user_set_python, user_show_python): Remove.
	(_initialize_python): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* guile/guile.c (set_guile_command, show_guile_command): Remove.
	(install_gdb_commands): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	(info_guile_command): Remove.
	* dwarf2/read.c (set_dwarf_cmd, show_dwarf_cmd): Remove.
	(_initialize_dwarf2_read): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* cli/cli-style.h (class cli_style_option) <add_setshow_commands>:
	Remove do_set and do_show parameters.
	* cli/cli-style.c (set_style, show_style): Remove.
	(_initialize_cli_style): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	(cli_style_option::add_setshow_commands): Remove do_set and
	do_show parameters.
	(cli_style_option::add_setshow_commands): Use
	add_basic_prefix_cmd, add_show_prefix_cmd.
	(STYLE_ADD_SETSHOW_COMMANDS): Remove macro.
	(set_style_name): Remove.
	* cli/cli-dump.c (dump_command, append_command): Remove.
	(srec_dump_command, ihex_dump_command, verilog_dump_command)
	(tekhex_dump_command, binary_dump_command)
	(binary_append_command): Remove.
	(_initialize_cli_dump): Use add_basic_prefix_cmd.
	* windows-tdep.c (w32_prefix_command_valid): Remove global.
	(init_w32_command_list): Remove; move into ...
	(_initialize_windows_tdep): ... here.  Use add_basic_prefix_cmd.
	* valprint.c (set_print, show_print, set_print_raw)
	(show_print_raw): Remove.
	(_initialize_valprint): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* typeprint.c (set_print_type, show_print_type): Remove.
	(_initialize_typeprint): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* record.c (set_record_command, show_record_command): Remove.
	(_initialize_record): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* cli/cli-cmds.c (_initialize_cli_cmds): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	(info_command, show_command, set_debug, show_debug): Remove.
	* top.h (set_history, show_history): Don't declare.
	* top.c (set_history, show_history): Remove.
	* target-descriptions.c (set_tdesc_cmd, show_tdesc_cmd)
	(unset_tdesc_cmd): Remove.
	(_initialize_target_descriptions): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* symtab.c (info_module_command): Remove.
	(_initialize_symtab): Use add_basic_prefix_cmd.
	* symfile.c (overlay_command): Remove.
	(_initialize_symfile): Use add_basic_prefix_cmd.
	* sparc64-tdep.c (info_adi_command): Remove.
	(_initialize_sparc64_adi_tdep): Use add_basic_prefix_cmd.
	* sh-tdep.c (show_sh_command, set_sh_command): Remove.
	(_initialize_sh_tdep): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* serial.c (serial_set_cmd, serial_show_cmd): Remove.
	(_initialize_serial): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* ser-tcp.c (set_tcp_cmd, show_tcp_cmd): Remove.
	(_initialize_ser_tcp): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* rs6000-tdep.c (set_powerpc_command, show_powerpc_command)
	(_initialize_rs6000_tdep): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* riscv-tdep.c (show_riscv_command, set_riscv_command)
	(show_debug_riscv_command, set_debug_riscv_command): Remove.
	(_initialize_riscv_tdep): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* remote.c (remote_command, set_remote_cmd): Remove.
	(_initialize_remote): Use add_basic_prefix_cmd.
	* record-full.c (set_record_full_command)
	(show_record_full_command): Remove.
	(_initialize_record_full): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* record-btrace.c (cmd_set_record_btrace)
	(cmd_show_record_btrace, cmd_set_record_btrace_bts)
	(cmd_show_record_btrace_bts, cmd_set_record_btrace_pt)
	(cmd_show_record_btrace_pt): Remove.
	(_initialize_record_btrace): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* ravenscar-thread.c (set_ravenscar_command)
	(show_ravenscar_command): Remove.
	(_initialize_ravenscar): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* mips-tdep.c (show_mips_command, set_mips_command)
	(_initialize_mips_tdep): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* maint.c (maintenance_command, maintenance_info_command)
	(maintenance_check_command, maintenance_print_command)
	(maintenance_set_cmd, maintenance_show_cmd): Remove.
	(_initialize_maint_cmds): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	(show_per_command_cmd): Remove.
	* maint-test-settings.c (maintenance_set_test_settings_cmd):
	Remove.
	(maintenance_show_test_settings_cmd): Remove.
	(_initialize_maint_test_settings): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* maint-test-options.c (maintenance_test_options_command):
	Remove.
	(_initialize_maint_test_options): Use add_basic_prefix_cmd.
	* macrocmd.c (macro_command): Remove
	(_initialize_macrocmd): Use add_basic_prefix_cmd.
	* language.c (set_check, show_check): Remove.
	(_initialize_language): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* infcmd.c (unset_command): Remove.
	(_initialize_infcmd): Use add_basic_prefix_cmd.
	* i386-tdep.c (set_mpx_cmd, show_mpx_cmd): Remove.
	(_initialize_i386_tdep): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* go32-nat.c (go32_info_dos_command): Remove.
	(_initialize_go32_nat): Use add_basic_prefix_cmd.
	* cli/cli-decode.c (do_prefix_cmd, add_basic_prefix_cmd)
	(do_show_prefix_cmd, add_show_prefix_cmd): New functions.
	* frame.c (set_backtrace_cmd, show_backtrace_cmd): Remove.
	(_initialize_frame): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* dcache.c (set_dcache_command, show_dcache_command): Remove.
	(_initialize_dcache): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* cp-support.c (maint_cplus_command): Remove.
	(_initialize_cp_support): Use add_basic_prefix_cmd.
	* btrace.c (maint_btrace_cmd, maint_btrace_set_cmd)
	(maint_btrace_show_cmd, maint_btrace_pt_set_cmd)
	(maint_btrace_pt_show_cmd, _initialize_btrace): Use
	add_basic_prefix_cmd, add_show_prefix_cmd.
	* breakpoint.c (save_command): Remove.
	(_initialize_breakpoint): Use add_basic_prefix_cmd.
	* arm-tdep.c (set_arm_command, show_arm_command): Remove.
	(_initialize_arm_tdep): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* ada-lang.c (maint_set_ada_cmd, maint_show_ada_cmd)
	(set_ada_command, show_ada_command): Remove.
	(_initialize_ada_language): Use add_basic_prefix_cmd,
	add_show_prefix_cmd.
	* command.h (add_basic_prefix_cmd, add_show_prefix_cmd): Declare.

gdb/testsuite/ChangeLog
2020-04-17  Tom Tromey  <tromey@adacore.com>

	* gdb.cp/maint.exp (test_help): Simplify multiple_help_body.
	Update tests.
	* gdb.btrace/cpu.exp: Update tests.
	* gdb.base/maint.exp: Update tests.
	* gdb.base/default.exp: Update tests.
	* gdb.base/completion.exp: Update tests.
---
 gdb/ChangeLog                         | 150 ++++++++++++++++++++++++++
 gdb/ada-lang.c                        |  63 +++--------
 gdb/arc-tdep.c                        |  18 +---
 gdb/arm-tdep.c                        |  26 ++---
 gdb/auto-load.c                       |  15 +--
 gdb/breakpoint.c                      |  16 +--
 gdb/btrace.c                          |  79 ++++----------
 gdb/cli/cli-cmds.c                    |  69 ++++--------
 gdb/cli/cli-decode.c                  |  52 +++++++++
 gdb/cli/cli-dump.c                    | 147 ++++++++-----------------
 gdb/cli/cli-style.c                   | 126 ++++++++--------------
 gdb/cli/cli-style.h                   |   2 -
 gdb/command.h                         |  14 +++
 gdb/cp-support.c                      |  23 +---
 gdb/dcache.c                          |  24 ++---
 gdb/dwarf2/read.c                     |  25 ++---
 gdb/frame.c                           |  25 ++---
 gdb/go32-nat.c                        |  10 +-
 gdb/guile/guile.c                     |  51 +++------
 gdb/i386-tdep.c                       |  28 ++---
 gdb/infcmd.c                          |  14 +--
 gdb/language.c                        |  25 ++---
 gdb/macrocmd.c                        |  15 +--
 gdb/maint-test-options.c              |  22 +---
 gdb/maint-test-settings.c             |  44 +++-----
 gdb/maint.c                           | 120 +++++----------------
 gdb/mips-tdep.c                       |  29 ++---
 gdb/python/python.c                   |  35 ++----
 gdb/ravenscar-thread.c                |  30 ++----
 gdb/record-btrace.c                   | 107 +++++-------------
 gdb/record-full.c                     |  31 ++----
 gdb/record.c                          |  29 ++---
 gdb/remote.c                          |  24 ++---
 gdb/riscv-tdep.c                      |  64 +++--------
 gdb/rs6000-tdep.c                     |  28 ++---
 gdb/ser-tcp.c                         |  26 ++---
 gdb/serial.c                          |  30 ++----
 gdb/sh-tdep.c                         |  22 +---
 gdb/sparc64-tdep.c                    |  15 +--
 gdb/symfile.c                         |  17 +--
 gdb/symtab.c                          |  15 +--
 gdb/target-descriptions.c             |  36 ++-----
 gdb/testsuite/ChangeLog               |   9 ++
 gdb/testsuite/gdb.base/completion.exp |   6 +-
 gdb/testsuite/gdb.base/default.exp    |  32 +++---
 gdb/testsuite/gdb.base/maint.exp      |   6 +-
 gdb/testsuite/gdb.btrace/cpu.exp      |   4 +-
 gdb/testsuite/gdb.cp/maint.exp        |   4 +-
 gdb/top.c                             |  14 ---
 gdb/top.h                             |   4 -
 gdb/tui/tui-layout.c                  |  13 +--
 gdb/tui/tui-win.c                     |  14 +--
 gdb/typeprint.c                       |  28 ++---
 gdb/valprint.c                        |  56 +++-------
 gdb/windows-tdep.c                    |  24 +----
 55 files changed, 656 insertions(+), 1299 deletions(-)

-- 
2.21.1

Comments

Simon Marchi April 17, 2020, 9:02 p.m. | #1
On 2020-04-17 9:29 a.m., Tom Tromey wrote:
> Currently there are many prefix commands that do nothing but call

> either help_list or cmd_show_list.  I happened to notice that one such

> call, for "set print type", used the wrong command list parameter,

> causing incorrect output.

> 

> Rather than fix this bug in isolation, I decided to eliminate this

> possibility by adding two new ways to add prefix commands, which

> simply route the call to help_list or cmd_show_list, as appropriate.

> This makes it impossible for a mismatch to occur.

> 

> In some cases, a bit of output was remove; however, I don't think this


removed

> output in general was very useful.  It seemed redundant with what's

> already printed by help_list.


Could you mention here an example of command for which the output changed?

> 

> This simplified the CLI style set/show commands quite a bit, and

> allowed the deletion of a macro.

> 

> This also cleans up some unusual code in windows-tdep.c.

> 

> Tested on x86-64 Fedora 30.  Note that I have no way to build the

> go32-nat.c change.


I did not read it all, but I glanced at some files.  It removes a lot of
duplicated code and boilerplate, and therefore chances of inconsistencies,
which is nice.

Simon
Tom Tromey April 17, 2020, 9:14 p.m. | #2
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:


>> In some cases, a bit of output was remove; however, I don't think this


Simon> removed

Fixed.

>> output in general was very useful.  It seemed redundant with what's

>> already printed by help_list.


Simon> Could you mention here an example of command for which the output changed?

I've updated the commit message with an example.

Simon> I did not read it all, but I glanced at some files.  It removes a lot of
Simon> duplicated code and boilerplate, and therefore chances of inconsistencies,
Simon> which is nice.

Thanks.  I'm going to push it in shortly.

Tom

Patch

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 029a7912a03..49f2280198e 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -332,23 +332,6 @@  static const char *known_auxiliary_function_name_patterns[] = {
 static struct cmd_list_element *maint_set_ada_cmdlist;
 static struct cmd_list_element *maint_show_ada_cmdlist;
 
-/* Implement the "maintenance set ada" (prefix) command.  */
-
-static void
-maint_set_ada_cmd (const char *args, int from_tty)
-{
-  help_list (maint_set_ada_cmdlist, "maintenance set ada ", all_commands,
-	     gdb_stdout);
-}
-
-/* Implement the "maintenance show ada" (prefix) command.  */
-
-static void
-maint_show_ada_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (maint_show_ada_cmdlist, from_tty, "");
-}
-
 /* The "maintenance ada set/show ignore-descriptive-type" value.  */
 
 static bool ada_ignore_descriptive_types_p = false;
@@ -14139,24 +14122,6 @@  extern const struct language_defn ada_language_defn = {
 static struct cmd_list_element *set_ada_list;
 static struct cmd_list_element *show_ada_list;
 
-/* Implement the "set ada" prefix command.  */
-
-static void
-set_ada_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_(\
-"\"set ada\" must be followed by the name of a setting.\n"));
-  help_list (set_ada_list, "set ada ", all_commands, gdb_stdout);
-}
-
-/* Implement the "show ada" prefix command.  */
-
-static void
-show_ada_command (const char *args, int from_tty)
-{
-  cmd_show_list (show_ada_list, from_tty, "");
-}
-
 static void
 initialize_ada_catchpoint_ops (void)
 {
@@ -14227,13 +14192,13 @@  _initialize_ada_language ()
 {
   initialize_ada_catchpoint_ops ();
 
-  add_prefix_cmd ("ada", no_class, set_ada_command,
-                  _("Prefix command for changing Ada-specific settings."),
-                  &set_ada_list, "set ada ", 0, &setlist);
+  add_basic_prefix_cmd ("ada", no_class,
+			_("Prefix command for changing Ada-specific settings."),
+			&set_ada_list, "set ada ", 0, &setlist);
 
-  add_prefix_cmd ("ada", no_class, show_ada_command,
-                  _("Generic command for showing Ada-specific settings."),
-                  &show_ada_list, "show ada ", 0, &showlist);
+  add_show_prefix_cmd ("ada", no_class,
+		       _("Generic command for showing Ada-specific settings."),
+		       &show_ada_list, "show ada ", 0, &showlist);
 
   add_setshow_boolean_cmd ("trust-PAD-over-XVS", class_obscure,
                            &trust_pad_over_xvs, _("\
@@ -14310,15 +14275,15 @@  Usage: info exceptions [REGEXP]\n\
 If a regular expression is passed as an argument, only those matching\n\
 the regular expression are listed."));
 
-  add_prefix_cmd ("ada", class_maintenance, maint_set_ada_cmd,
-		  _("Set Ada maintenance-related variables."),
-                  &maint_set_ada_cmdlist, "maintenance set ada ",
-                  0/*allow-unknown*/, &maintenance_set_cmdlist);
+  add_basic_prefix_cmd ("ada", class_maintenance,
+			_("Set Ada maintenance-related variables."),
+			&maint_set_ada_cmdlist, "maintenance set ada ",
+			0/*allow-unknown*/, &maintenance_set_cmdlist);
 
-  add_prefix_cmd ("ada", class_maintenance, maint_show_ada_cmd,
-		  _("Show Ada maintenance-related variables."),
-                  &maint_show_ada_cmdlist, "maintenance show ada ",
-                  0/*allow-unknown*/, &maintenance_show_cmdlist);
+  add_show_prefix_cmd ("ada", class_maintenance,
+		       _("Show Ada maintenance-related variables."),
+		       &maint_show_ada_cmdlist, "maintenance show ada ",
+		       0/*allow-unknown*/, &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd
     ("ignore-descriptive-types", class_maintenance,
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 3020099c335..b690e6e24b6 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -2111,14 +2111,6 @@  arc_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file, "arc_dump_tdep: jb_pc = %i\n", tdep->jb_pc);
 }
 
-/* Wrapper for "maintenance print arc" list of commands.  */
-
-static void
-maintenance_print_arc_command (const char *args, int from_tty)
-{
-  cmd_show_list (maintenance_print_arc_list, from_tty, "");
-}
-
 /* This command accepts single argument - address of instruction to
    disassemble.  */
 
@@ -2180,11 +2172,11 @@  _initialize_arc_tdep ()
   /* Register ARC-specific commands with gdb.  */
 
   /* Add root prefix command for "maintenance print arc" commands.  */
-  add_prefix_cmd ("arc", class_maintenance, maintenance_print_arc_command,
-		  _("ARC-specific maintenance commands for printing GDB "
-		    "internal state."),
-		  &maintenance_print_arc_list, "maintenance print arc ", 0,
-		  &maintenanceprintlist);
+  add_show_prefix_cmd ("arc", class_maintenance,
+		       _("ARC-specific maintenance commands for printing GDB "
+			 "internal state."),
+		       &maintenance_print_arc_list, "maintenance print arc ",
+		       0, &maintenanceprintlist);
 
   add_cmd ("arc-instruction", class_maintenance,
 	   dump_arc_instruction_command,
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 44c439a85f5..d881791bf20 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8325,20 +8325,6 @@  arm_skip_stub (struct frame_info *frame, CORE_ADDR pc)
   return 0;			/* not a stub */
 }
 
-static void
-set_arm_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\
-\"set arm\" must be followed by an apporpriate subcommand.\n"));
-  help_list (setarmcmdlist, "set arm ", all_commands, gdb_stdout);
-}
-
-static void
-show_arm_command (const char *args, int from_tty)
-{
-  cmd_show_list (showarmcmdlist, from_tty, "");
-}
-
 static void
 arm_update_current_architecture (void)
 {
@@ -9517,13 +9503,13 @@  _initialize_arm_tdep ()
 				  arm_elf_osabi_sniffer);
 
   /* Add root prefix command for all "set arm"/"show arm" commands.  */
-  add_prefix_cmd ("arm", no_class, set_arm_command,
-		  _("Various ARM-specific commands."),
-		  &setarmcmdlist, "set arm ", 0, &setlist);
+  add_basic_prefix_cmd ("arm", no_class,
+			_("Various ARM-specific commands."),
+			&setarmcmdlist, "set arm ", 0, &setlist);
 
-  add_prefix_cmd ("arm", no_class, show_arm_command,
-		  _("Various ARM-specific commands."),
-		  &showarmcmdlist, "show arm ", 0, &showlist);
+  add_show_prefix_cmd ("arm", no_class,
+		       _("Various ARM-specific commands."),
+		       &showarmcmdlist, "show arm ", 0, &showlist);
 
 
   arm_disassembler_options = xstrdup ("reg-names-std");
diff --git a/gdb/auto-load.c b/gdb/auto-load.c
index 36ec0d11b40..99bd96b971a 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -1460,15 +1460,6 @@  automatic loading of Python scripts."),
   return &retval;
 }
 
-/* Command "show auto-load" displays summary of all the current
-   "show auto-load " settings.  */
-
-static void
-show_auto_load_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (*auto_load_show_cmdlist_get (), from_tty, "");
-}
-
 /* Initialize "show auto-load " commands prefix and return it.  */
 
 struct cmd_list_element **
@@ -1477,12 +1468,12 @@  auto_load_show_cmdlist_get (void)
   static struct cmd_list_element *retval;
 
   if (retval == NULL)
-    add_prefix_cmd ("auto-load", class_maintenance, show_auto_load_cmd, _("\
+    add_show_prefix_cmd ("auto-load", class_maintenance, _("\
 Show auto-loading specific settings.\n\
 Show configuration of various auto-load-specific variables such as\n\
 automatic loading of Python scripts."),
-		    &retval, "show auto-load ",
-		    0/*allow-unknown*/, &showlist);
+			 &retval, "show auto-load ",
+			 0/*allow-unknown*/, &showlist);
 
   return &retval;
 }
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index e49025461ba..89eb29628b1 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -15118,14 +15118,6 @@  add_catch_command (const char *name, const char *docstring,
   set_cmd_completer (command, completer);
 }
 
-static void
-save_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"save\" must be followed by "
-		       "the name of a save subcommand.\n"));
-  help_list (save_cmdlist, "save ", all_commands, gdb_stdout);
-}
-
 struct breakpoint *
 iterate_over_breakpoints (gdb::function_view<bool (breakpoint *)> callback)
 {
@@ -15785,10 +15777,10 @@  The trace will end when the tracepoint has been passed 'count' times.\n\
 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
 if TPNUM is omitted, passcount refers to the last tracepoint defined."));
 
-  add_prefix_cmd ("save", class_breakpoint, save_command,
-		  _("Save breakpoint definitions as a script."),
-		  &save_cmdlist, "save ",
-		  0/*allow-unknown*/, &cmdlist);
+  add_basic_prefix_cmd ("save", class_breakpoint,
+			_("Save breakpoint definitions as a script."),
+			&save_cmdlist, "save ",
+			0/*allow-unknown*/, &cmdlist);
 
   c = add_cmd ("breakpoints", class_breakpoint, save_breakpoints_command, _("\
 Save current breakpoint definitions as a script.\n\
diff --git a/gdb/btrace.c b/gdb/btrace.c
index bbf87496497..9f90d59e2b5 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -3358,51 +3358,6 @@  maint_btrace_clear_cmd (const char *args, int from_tty)
   btrace_clear (tp);
 }
 
-/* The "maintenance btrace" command.  */
-
-static void
-maint_btrace_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_cmdlist, "maintenance btrace ", all_commands,
-	     gdb_stdout);
-}
-
-/* The "maintenance set btrace" command.  */
-
-static void
-maint_btrace_set_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_set_cmdlist, "maintenance set btrace ", all_commands,
-	     gdb_stdout);
-}
-
-/* The "maintenance show btrace" command.  */
-
-static void
-maint_btrace_show_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_show_cmdlist, "maintenance show btrace ",
-	     all_commands, gdb_stdout);
-}
-
-/* The "maintenance set btrace pt" command.  */
-
-static void
-maint_btrace_pt_set_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
-	     all_commands, gdb_stdout);
-}
-
-/* The "maintenance show btrace pt" command.  */
-
-static void
-maint_btrace_pt_show_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
-	     all_commands, gdb_stdout);
-}
-
 /* The "maintenance info btrace" command.  */
 
 static void
@@ -3478,30 +3433,32 @@  _initialize_btrace ()
   add_cmd ("btrace", class_maintenance, maint_info_btrace_cmd,
 	   _("Info about branch tracing data."), &maintenanceinfolist);
 
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_cmd,
-		  _("Branch tracing maintenance commands."),
-		  &maint_btrace_cmdlist, "maintenance btrace ",
-		  0, &maintenancelist);
+  add_basic_prefix_cmd ("btrace", class_maintenance,
+			_("Branch tracing maintenance commands."),
+			&maint_btrace_cmdlist, "maintenance btrace ",
+			0, &maintenancelist);
 
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_set_cmd, _("\
+  add_basic_prefix_cmd ("btrace", class_maintenance, _("\
 Set branch tracing specific variables."),
-                  &maint_btrace_set_cmdlist, "maintenance set btrace ",
-                  0, &maintenance_set_cmdlist);
+			&maint_btrace_set_cmdlist, "maintenance set btrace ",
+			0, &maintenance_set_cmdlist);
 
-  add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_set_cmd, _("\
+  add_basic_prefix_cmd ("pt", class_maintenance, _("\
 Set Intel Processor Trace specific variables."),
-                  &maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
-                  0, &maint_btrace_set_cmdlist);
+			&maint_btrace_pt_set_cmdlist,
+			"maintenance set btrace pt ",
+			0, &maint_btrace_set_cmdlist);
 
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_show_cmd, _("\
+  add_show_prefix_cmd ("btrace", class_maintenance, _("\
 Show branch tracing specific variables."),
-                  &maint_btrace_show_cmdlist, "maintenance show btrace ",
-                  0, &maintenance_show_cmdlist);
+		       &maint_btrace_show_cmdlist, "maintenance show btrace ",
+		       0, &maintenance_show_cmdlist);
 
-  add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_show_cmd, _("\
+  add_show_prefix_cmd ("pt", class_maintenance, _("\
 Show Intel Processor Trace specific variables."),
-                  &maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
-                  0, &maint_btrace_show_cmdlist);
+		       &maint_btrace_pt_show_cmdlist,
+		       "maintenance show btrace pt ",
+		       0, &maint_btrace_show_cmdlist);
 
   add_setshow_boolean_cmd ("skip-pad", class_maintenance,
 			   &maint_btrace_pt_skip_pad, _("\
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 6f324410e16..f7178510878 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -191,26 +191,6 @@  error_no_arg (const char *why)
   error (_("Argument required (%s)."), why);
 }
 
-/* The "info" command is defined as a prefix, with allow_unknown = 0.
-   Therefore, its own definition is called only for "info" with no
-   args.  */
-
-static void
-info_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"info\" must be followed by "
-		       "the name of an info command.\n"));
-  help_list (infolist, "info ", all_commands, gdb_stdout);
-}
-
-/* The "show" command with no arguments shows all the settings.  */
-
-static void
-show_command (const char *arg, int from_tty)
-{
-  cmd_show_list (showlist, from_tty, "");
-}
-
 /* See cli/cli-cmds.h.  */
 
 void
@@ -1852,20 +1832,6 @@  filter_sals (std::vector<symtab_and_line> &sals)
   sals.erase (from, sals.end ());
 }
 
-static void
-set_debug (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"set debug\" must be followed by "
-		       "the name of a debug subcommand.\n"));
-  help_list (setdebuglist, "set debug ", all_commands, gdb_stdout);
-}
-
-static void
-show_debug (const char *args, int from_tty)
-{
-  cmd_show_list (showdebuglist, from_tty, "");
-}
-
 void
 init_cmd_lists (void)
 {
@@ -2208,12 +2174,12 @@  Show verbosity."), NULL,
 			   show_info_verbose,
 			   &setlist, &showlist);
 
-  add_prefix_cmd ("history", class_support, set_history,
-		  _("Generic command for setting command history parameters."),
-		  &sethistlist, "set history ", 0, &setlist);
-  add_prefix_cmd ("history", class_support, show_history,
-		  _("Generic command for showing command history parameters."),
-		  &showhistlist, "show history ", 0, &showlist);
+  add_basic_prefix_cmd ("history", class_support, _("\
+Generic command for setting command history parameters."),
+			&sethistlist, "set history ", 0, &setlist);
+  add_show_prefix_cmd ("history", class_support, _("\
+Generic command for showing command history parameters."),
+		       &showhistlist, "show history ", 0, &showlist);
 
   add_setshow_boolean_cmd ("expansion", no_class, &history_expansion_p, _("\
 Set history expansion on command input."), _("\
@@ -2223,20 +2189,21 @@  Without an argument, history expansion is enabled."),
 			   show_history_expansion_p,
 			   &sethistlist, &showhistlist);
 
-  add_prefix_cmd ("info", class_info, info_command, _("\
+  add_basic_prefix_cmd ("info", class_info, _("\
 Generic command for showing things about the program being debugged."),
-		  &infolist, "info ", 0, &cmdlist);
+			&infolist, "info ", 0, &cmdlist);
   add_com_alias ("i", "info", class_info, 1);
   add_com_alias ("inf", "info", class_info, 1);
 
   add_com ("complete", class_obscure, complete_command,
 	   _("List the completions for the rest of the line as a command."));
 
-  add_prefix_cmd ("show", class_info, show_command, _("\
+  add_show_prefix_cmd ("show", class_info, _("\
 Generic command for showing things about the debugger."),
-		  &showlist, "show ", 0, &cmdlist);
+		       &showlist, "show ", 0, &cmdlist);
   /* Another way to get at the same thing.  */
-  add_info ("set", show_command, _("Show all GDB settings."));
+  add_show_prefix_cmd ("set", class_info, _("Show all GDB settings."),
+		       &showlist, "info set ", 0, &infolist);
 
   c = add_com ("with", class_vars, with_command, _("\
 Temporarily set SETTING to VALUE, run COMMAND, and restore SETTING.\n\
@@ -2324,13 +2291,13 @@  from the target."),
 				       show_remote_timeout,
 				       &setlist, &showlist);
 
-  add_prefix_cmd ("debug", no_class, set_debug,
-		  _("Generic command for setting gdb debugging flags."),
-		  &setdebuglist, "set debug ", 0, &setlist);
+  add_basic_prefix_cmd ("debug", no_class,
+			_("Generic command for setting gdb debugging flags."),
+			&setdebuglist, "set debug ", 0, &setlist);
 
-  add_prefix_cmd ("debug", no_class, show_debug,
-		  _("Generic command for showing gdb debugging flags."),
-		  &showdebuglist, "show debug ", 0, &showlist);
+  add_show_prefix_cmd ("debug", no_class,
+		       _("Generic command for showing gdb debugging flags."),
+		       &showdebuglist, "show debug ", 0, &showlist);
 
   c = add_com ("shell", class_support, shell_command, _("\
 Execute the rest of the line as a shell command.\n\
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 7aecd9897e2..17f49ec80e4 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -380,6 +380,58 @@  add_prefix_cmd (const char *name, enum command_class theclass,
   return c;
 }
 
+/* A helper function for add_basic_prefix_cmd.  This is a command
+   function that just forwards to help_list.  */
+
+static void
+do_prefix_cmd (const char *args, int from_tty, struct cmd_list_element *c)
+{
+  /* Look past all aliases.  */
+  while (c->cmd_pointer != nullptr)
+    c = c->cmd_pointer;
+
+  help_list (*c->prefixlist, c->prefixname, all_commands, gdb_stdout);
+}
+
+/* See command.h.  */
+
+struct cmd_list_element *
+add_basic_prefix_cmd (const char *name, enum command_class theclass,
+		      const char *doc, struct cmd_list_element **prefixlist,
+		      const char *prefixname, int allow_unknown,
+		      struct cmd_list_element **list)
+{
+  struct cmd_list_element *cmd = add_prefix_cmd (name, theclass, nullptr,
+						 doc, prefixlist, prefixname,
+						 allow_unknown, list);
+  set_cmd_sfunc (cmd, do_prefix_cmd);
+  return cmd;
+}
+
+/* A helper function for add_show_prefix_cmd.  This is a command
+   function that just forwards to cmd_show_list.  */
+
+static void
+do_show_prefix_cmd (const char *args, int from_tty, struct cmd_list_element *c)
+{
+  cmd_show_list (*c->prefixlist, from_tty, "");
+}
+
+/* See command.h.  */
+
+struct cmd_list_element *
+add_show_prefix_cmd (const char *name, enum command_class theclass,
+		     const char *doc, struct cmd_list_element **prefixlist,
+		     const char *prefixname, int allow_unknown,
+		     struct cmd_list_element **list)
+{
+  struct cmd_list_element *cmd = add_prefix_cmd (name, theclass, nullptr,
+						 doc, prefixlist, prefixname,
+						 allow_unknown, list);
+  set_cmd_sfunc (cmd, do_show_prefix_cmd);
+  return cmd;
+}
+
 /* Like ADD_PREFIX_CMD but sets the suppress_notification pointer on the
    new command list element.  */
 
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
index ae047ac75de..567ef2eeded 100644
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -128,20 +128,6 @@  static struct cmd_list_element *tekhex_cmdlist;
 static struct cmd_list_element *binary_dump_cmdlist;
 static struct cmd_list_element *binary_append_cmdlist;
 
-static void
-dump_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n"));
-  help_list (dump_cmdlist, "dump ", all_commands, gdb_stdout);
-}
-
-static void
-append_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"append\" must be followed by a subcommand.\n\n"));
-  help_list (dump_cmdlist, "append ", all_commands, gdb_stdout);
-}
-
 static void
 dump_binary_file (const char *filename, const char *mode, 
 		  const bfd_byte *buf, ULONGEST len)
@@ -579,65 +565,22 @@  restore_command (const char *args, int from_tty)
     }
 }
 
-static void
-srec_dump_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"dump srec\" must be followed by a subcommand.\n"));
-  help_list (srec_cmdlist, "dump srec ", all_commands, gdb_stdout);
-}
-
-static void
-ihex_dump_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"dump ihex\" must be followed by a subcommand.\n"));
-  help_list (ihex_cmdlist, "dump ihex ", all_commands, gdb_stdout);
-}
-
-static void
-verilog_dump_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"dump verilog\" must be followed by a subcommand.\n"));
-  help_list (verilog_cmdlist, "dump verilog ", all_commands, gdb_stdout);
-}
-
-static void
-tekhex_dump_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"dump tekhex\" must be followed by a subcommand.\n"));
-  help_list (tekhex_cmdlist, "dump tekhex ", all_commands, gdb_stdout);
-}
-
-static void
-binary_dump_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"dump binary\" must be followed by a subcommand.\n"));
-  help_list (binary_dump_cmdlist, "dump binary ", all_commands, gdb_stdout);
-}
-
-static void
-binary_append_command (const char *cmd, int from_tty)
-{
-  printf_unfiltered (_("\"append binary\" must be followed by a subcommand.\n"));
-  help_list (binary_append_cmdlist, "append binary ", all_commands,
-	     gdb_stdout);
-}
-
 void _initialize_cli_dump ();
 void
 _initialize_cli_dump ()
 {
   struct cmd_list_element *c;
 
-  add_prefix_cmd ("dump", class_vars, dump_command,
-		  _("Dump target code/data to a local file."),
-		  &dump_cmdlist, "dump ",
-		  0/*allow-unknown*/,
-		  &cmdlist);
-  add_prefix_cmd ("append", class_vars, append_command,
-		  _("Append target code/data to a local file."),
-		  &append_cmdlist, "append ",
-		  0/*allow-unknown*/,
-		  &cmdlist);
+  add_basic_prefix_cmd ("dump", class_vars,
+			_("Dump target code/data to a local file."),
+			&dump_cmdlist, "dump ",
+			0/*allow-unknown*/,
+			&cmdlist);
+  add_basic_prefix_cmd ("append", class_vars,
+			_("Append target code/data to a local file."),
+			&append_cmdlist, "append ",
+			0/*allow-unknown*/,
+			&cmdlist);
 
   add_dump_command ("memory", dump_memory_command, "\
 Write contents of memory to a raw binary file.\n\
@@ -649,41 +592,41 @@  Write the value of an expression to a raw binary file.\n\
 Arguments are FILE EXPRESSION.  Writes the value of EXPRESSION to\n\
 the specified FILE in raw target ordered bytes.");
 
-  add_prefix_cmd ("srec", all_commands, srec_dump_command,
-		  _("Write target code/data to an srec file."),
-		  &srec_cmdlist, "dump srec ", 
-		  0 /*allow-unknown*/, 
-		  &dump_cmdlist);
-
-  add_prefix_cmd ("ihex", all_commands, ihex_dump_command,
-		  _("Write target code/data to an intel hex file."),
-		  &ihex_cmdlist, "dump ihex ", 
-		  0 /*allow-unknown*/, 
-		  &dump_cmdlist);
-
-  add_prefix_cmd ("verilog", all_commands, verilog_dump_command,
-		  _("Write target code/data to a verilog hex file."),
-		  &verilog_cmdlist, "dump verilog ",
-		  0 /*allow-unknown*/,
-		  &dump_cmdlist);
-
-  add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command,
-		  _("Write target code/data to a tekhex file."),
-		  &tekhex_cmdlist, "dump tekhex ", 
-		  0 /*allow-unknown*/, 
-		  &dump_cmdlist);
-
-  add_prefix_cmd ("binary", all_commands, binary_dump_command,
-		  _("Write target code/data to a raw binary file."),
-		  &binary_dump_cmdlist, "dump binary ", 
-		  0 /*allow-unknown*/, 
-		  &dump_cmdlist);
-
-  add_prefix_cmd ("binary", all_commands, binary_append_command,
-		  _("Append target code/data to a raw binary file."),
-		  &binary_append_cmdlist, "append binary ", 
-		  0 /*allow-unknown*/, 
-		  &append_cmdlist);
+  add_basic_prefix_cmd ("srec", all_commands,
+			_("Write target code/data to an srec file."),
+			&srec_cmdlist, "dump srec ", 
+			0 /*allow-unknown*/, 
+			&dump_cmdlist);
+
+  add_basic_prefix_cmd ("ihex", all_commands,
+			_("Write target code/data to an intel hex file."),
+			&ihex_cmdlist, "dump ihex ", 
+			0 /*allow-unknown*/, 
+			&dump_cmdlist);
+
+  add_basic_prefix_cmd ("verilog", all_commands,
+			_("Write target code/data to a verilog hex file."),
+			&verilog_cmdlist, "dump verilog ",
+			0 /*allow-unknown*/,
+			&dump_cmdlist);
+
+  add_basic_prefix_cmd ("tekhex", all_commands,
+			_("Write target code/data to a tekhex file."),
+			&tekhex_cmdlist, "dump tekhex ", 
+			0 /*allow-unknown*/, 
+			&dump_cmdlist);
+
+  add_basic_prefix_cmd ("binary", all_commands,
+			_("Write target code/data to a raw binary file."),
+			&binary_dump_cmdlist, "dump binary ", 
+			0 /*allow-unknown*/, 
+			&dump_cmdlist);
+
+  add_basic_prefix_cmd ("binary", all_commands,
+			_("Append target code/data to a raw binary file."),
+			&binary_append_cmdlist, "append binary ", 
+			0 /*allow-unknown*/, 
+			&append_cmdlist);
 
   add_cmd ("memory", all_commands, dump_srec_memory, _("\
 Write contents of memory to an srec file.\n\
diff --git a/gdb/cli/cli-style.c b/gdb/cli/cli-style.c
index d2d9928acd5..a0c3cc51801 100644
--- a/gdb/cli/cli-style.c
+++ b/gdb/cli/cli-style.c
@@ -215,20 +215,16 @@  void
 cli_style_option::add_setshow_commands (enum command_class theclass,
 					const char *prefix_doc,
 					struct cmd_list_element **set_list,
-					void (*do_set) (const char *args,
-							int from_tty),
 					struct cmd_list_element **show_list,
-					void (*do_show) (const char *args,
-							 int from_tty),
 					bool skip_intensity)
 {
   m_set_prefix = std::string ("set style ") + m_name + " ";
   m_show_prefix = std::string ("show style ") + m_name + " ";
 
-  add_prefix_cmd (m_name, no_class, do_set, prefix_doc, &m_set_list,
-		  m_set_prefix.c_str (), 0, set_list);
-  add_prefix_cmd (m_name, no_class, do_show, prefix_doc, &m_show_list,
-		  m_show_prefix.c_str (), 0, show_list);
+  add_basic_prefix_cmd (m_name, no_class, prefix_doc, &m_set_list,
+			m_set_prefix.c_str (), 0, set_list);
+  add_show_prefix_cmd (m_name, no_class, prefix_doc, &m_show_list,
+		       m_show_prefix.c_str (), 0, show_list);
 
   add_setshow_enum_cmd ("foreground", theclass, cli_colors,
 			&m_foreground,
@@ -260,20 +256,6 @@  cli_style_option::add_setshow_commands (enum command_class theclass,
 static cmd_list_element *style_set_list;
 static cmd_list_element *style_show_list;
 
-static void
-set_style (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"set style\" must be followed "
-		       "by an appropriate subcommand.\n"));
-  help_list (style_set_list, "set style ", all_commands, gdb_stdout);
-}
-
-static void
-show_style (const char *arg, int from_tty)
-{
-  cmd_show_list (style_show_list, from_tty, "");
-}
-
 static void
 set_style_enabled  (const char *args, int from_tty, struct cmd_list_element *c)
 {
@@ -301,27 +283,15 @@  show_style_sources (struct ui_file *file, int from_tty,
     fprintf_filtered (file, _("Source code styling is disabled.\n"));
 }
 
-/* Builds the "set style NAME " prefix.  */
-
-static std::string
-set_style_name (const char *name)
-{
-  std::string result ("set style ");
-
-  result += name;
-  result += " ";
-  return result;
-}
-
 void _initialize_cli_style ();
 void
 _initialize_cli_style ()
 {
-  add_prefix_cmd ("style", no_class, set_style, _("\
+  add_basic_prefix_cmd ("style", no_class, _("\
 Style-specific settings.\n\
 Configure various style-related variables, such as colors"),
 		  &style_set_list, "set style ", 0, &setlist);
-  add_prefix_cmd ("style", no_class, show_style, _("\
+  add_show_prefix_cmd ("style", no_class, _("\
 Style-specific settings.\n\
 Configure various style-related variables, such as colors"),
 		  &style_show_list, "show style ", 0, &showlist);
@@ -348,78 +318,68 @@  available if the appropriate extension is available at runtime."
 			   ), set_style_enabled, show_style_sources,
 			   &style_set_list, &style_show_list);
 
-#define STYLE_ADD_SETSHOW_COMMANDS(STYLE, PREFIX_DOC, SKIP)		\
-  STYLE.add_setshow_commands (no_class, PREFIX_DOC,		\
-			      &style_set_list,				\
-			      [] (const char *args, int from_tty)	\
-			      {						\
-				help_list				\
-				  (STYLE.set_list (),			\
-				   set_style_name (STYLE.name ()).c_str (), \
-				   all_commands,			\
-				   gdb_stdout);				\
-			      },					\
-			      &style_show_list,				\
-			      [] (const char *args, int from_tty)	\
-			      {						\
-				cmd_show_list				\
-				  (STYLE.show_list (),			\
-				   from_tty,				\
-				   "");					\
-			      }, SKIP)
-
-  STYLE_ADD_SETSHOW_COMMANDS (file_name_style,
-			      _("\
+  file_name_style.add_setshow_commands (no_class, _("\
 Filename display styling.\n\
-Configure filename colors and display intensity."), false);
+Configure filename colors and display intensity."),
+					&style_set_list, &style_show_list,
+					false);
 
-  STYLE_ADD_SETSHOW_COMMANDS (function_name_style,
-			      _("\
+  function_name_style.add_setshow_commands (no_class, _("\
 Function name display styling.\n\
-Configure function name colors and display intensity"), false);
+Configure function name colors and display intensity"),
+					    &style_set_list, &style_show_list,
+					    false);
 
-  STYLE_ADD_SETSHOW_COMMANDS (variable_name_style,
-			      _("\
+  variable_name_style.add_setshow_commands (no_class, _("\
 Variable name display styling.\n\
-Configure variable name colors and display intensity"), false);
+Configure variable name colors and display intensity"),
+					    &style_set_list, &style_show_list,
+					    false);
 
-  STYLE_ADD_SETSHOW_COMMANDS (address_style,
-			      _("\
+  address_style.add_setshow_commands (no_class, _("\
 Address display styling.\n\
-Configure address colors and display intensity"), false);
+Configure address colors and display intensity"),
+				      &style_set_list, &style_show_list,
+				      false);
 
-  STYLE_ADD_SETSHOW_COMMANDS (title_style,
-			      _("\
+  title_style.add_setshow_commands (no_class, _("\
 Title display styling.\n\
 Configure title colors and display intensity\n\
 Some commands (such as \"apropos -v REGEXP\") use the title style to improve\n\
-readability."), false);
+readability."),
+				    &style_set_list, &style_show_list,
+				    false);
 
-  STYLE_ADD_SETSHOW_COMMANDS (highlight_style,
-			      _("\
+  highlight_style.add_setshow_commands (no_class, _("\
 Highlight display styling.\n\
 Configure highlight colors and display intensity\n\
 Some commands use the highlight style to draw the attention to a part\n\
-of their output."), false);
+of their output."),
+					&style_set_list, &style_show_list,
+					false);
 
-  STYLE_ADD_SETSHOW_COMMANDS (metadata_style,
-			      _("\
+  metadata_style.add_setshow_commands (no_class, _("\
 Metadata display styling.\n\
 Configure metadata colors and display intensity\n\
 The \"metadata\" style is used when GDB displays information about\n\
-your data, for example \"<unavailable>\""), false);
+your data, for example \"<unavailable>\""),
+				       &style_set_list, &style_show_list,
+				       false);
 
-  STYLE_ADD_SETSHOW_COMMANDS (tui_border_style,
-			      _("\
+  tui_border_style.add_setshow_commands (no_class, _("\
 TUI border display styling.\n\
 Configure TUI border colors\n\
 The \"tui-border\" style is used when GDB displays the border of a\n\
-TUI window that does not have the focus."), true);
+TUI window that does not have the focus."),
+					 &style_set_list, &style_show_list,
+					 true);
 
-  STYLE_ADD_SETSHOW_COMMANDS (tui_active_border_style,
-			      _("\
+  tui_active_border_style.add_setshow_commands (no_class, _("\
 TUI active border display styling.\n\
 Configure TUI active border colors\n\
 The \"tui-active-border\" style is used when GDB displays the border of a\n\
-TUI window that does have the focus."), true);
+TUI window that does have the focus."),
+						&style_set_list,
+						&style_show_list,
+						true);
 }
diff --git a/gdb/cli/cli-style.h b/gdb/cli/cli-style.h
index 04009aa3615..6422e5296a3 100644
--- a/gdb/cli/cli-style.h
+++ b/gdb/cli/cli-style.h
@@ -46,9 +46,7 @@  class cli_style_option
   void add_setshow_commands (enum command_class theclass,
 			     const char *prefix_doc,
 			     struct cmd_list_element **set_list,
-			     void (*do_set) (const char *args, int from_tty),
 			     struct cmd_list_element **show_list,
-			     void (*do_show) (const char *args, int from_tty),
 			     bool skip_intensity);
 
   /* Return the 'set style NAME' command list, that can be used
diff --git a/gdb/command.h b/gdb/command.h
index 7f436c72c98..b9b94227b9f 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -179,6 +179,20 @@  extern struct cmd_list_element *add_prefix_cmd (const char *, enum command_class
 						const char *, int,
 						struct cmd_list_element **);
 
+/* Like add_prefix_cmd, but sets the callback to a function that
+   simply calls help_list.  */
+
+extern struct cmd_list_element *add_basic_prefix_cmd
+  (const char *, enum command_class, const char *, struct cmd_list_element **,
+   const char *, int, struct cmd_list_element **);
+
+/* Like add_prefix_cmd, but useful for "show" prefixes.  This sets the
+   callback to a function that simply calls cmd_show_list.  */
+
+extern struct cmd_list_element *add_show_prefix_cmd
+  (const char *, enum command_class, const char *, struct cmd_list_element **,
+   const char *, int, struct cmd_list_element **);
+
 extern struct cmd_list_element *add_prefix_cmd_suppress_notification
 			(const char *name, enum command_class theclass,
 			 cmd_const_cfunc_ftype *fun,
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 91e7d2ddc68..6601272e717 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -2118,18 +2118,6 @@  test_cp_remove_params ()
 
 #endif /* GDB_SELF_CHECK */
 
-/* Don't allow just "maintenance cplus".  */
-
-static  void
-maint_cplus_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"maintenance cplus\" must be followed "
-		       "by the name of a command.\n"));
-  help_list (maint_cplus_cmd_list,
-	     "maintenance cplus ",
-	     all_commands, gdb_stdout);
-}
-
 /* This is a front end for cp_find_first_component, for unit testing.
    Be careful when using it: see the NOTE above
    cp_find_first_component.  */
@@ -2167,12 +2155,11 @@  void _initialize_cp_support ();
 void
 _initialize_cp_support ()
 {
-  add_prefix_cmd ("cplus", class_maintenance,
-		  maint_cplus_command,
-		  _("C++ maintenance commands."),
-		  &maint_cplus_cmd_list,
-		  "maintenance cplus ",
-		  0, &maintenancelist);
+  add_basic_prefix_cmd ("cplus", class_maintenance,
+			_("C++ maintenance commands."),
+			&maint_cplus_cmd_list,
+			"maintenance cplus ",
+			0, &maintenancelist);
   add_alias_cmd ("cp", "cplus",
 		 class_maintenance, 1,
 		 &maintenancelist);
diff --git a/gdb/dcache.c b/gdb/dcache.c
index f018882bf95..c0c26998c95 100644
--- a/gdb/dcache.c
+++ b/gdb/dcache.c
@@ -670,20 +670,6 @@  set_dcache_line_size (const char *args, int from_tty,
   target_dcache_invalidate ();
 }
 
-static void
-set_dcache_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (
-     "\"set dcache\" must be followed by the name of a subcommand.\n");
-  help_list (dcache_set_list, "set dcache ", all_commands, gdb_stdout);
-}
-
-static void
-show_dcache_command (const char *args, int from_tty)
-{
-  cmd_show_list (dcache_show_list, from_tty, "");
-}
-
 void _initialize_dcache ();
 void
 _initialize_dcache ()
@@ -708,12 +694,14 @@  With no arguments, this command prints the cache configuration and a\n\
 summary of each line in the cache.  With an argument, dump\"\n\
 the contents of the given line."));
 
-  add_prefix_cmd ("dcache", class_obscure, set_dcache_command, _("\
+  add_basic_prefix_cmd ("dcache", class_obscure, _("\
 Use this command to set number of lines in dcache and line-size."),
-		  &dcache_set_list, "set dcache ", /*allow_unknown*/0, &setlist);
-  add_prefix_cmd ("dcache", class_obscure, show_dcache_command, _("\
+			&dcache_set_list, "set dcache ", /*allow_unknown*/0,
+			&setlist);
+  add_show_prefix_cmd ("dcache", class_obscure, _("\
 Show dcachesettings."),
-		  &dcache_show_list, "show dcache ", /*allow_unknown*/0, &showlist);
+		       &dcache_show_list, "show dcache ", /*allow_unknown*/0,
+		       &showlist);
 
   add_setshow_zuinteger_cmd ("line-size", class_obscure,
 			     &dcache_line_size, _("\
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4910c9b6fc7..9cc0e1b59ed 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23481,19 +23481,6 @@  partial_die_eq (const void *item_lhs, const void *item_rhs)
 struct cmd_list_element *set_dwarf_cmdlist;
 struct cmd_list_element *show_dwarf_cmdlist;
 
-static void
-set_dwarf_cmd (const char *args, int from_tty)
-{
-  help_list (set_dwarf_cmdlist, "maintenance set dwarf ", all_commands,
-	     gdb_stdout);
-}
-
-static void
-show_dwarf_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (show_dwarf_cmdlist, from_tty, "");
-}
-
 static void
 show_check_physname (struct ui_file *file, int from_tty,
 		     struct cmd_list_element *c, const char *value)
@@ -23507,17 +23494,17 @@  void _initialize_dwarf2_read ();
 void
 _initialize_dwarf2_read ()
 {
-  add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
+  add_basic_prefix_cmd ("dwarf", class_maintenance, _("\
 Set DWARF specific variables.\n\
 Configure DWARF variables such as the cache size."),
-                  &set_dwarf_cmdlist, "maintenance set dwarf ",
-                  0/*allow-unknown*/, &maintenance_set_cmdlist);
+			&set_dwarf_cmdlist, "maintenance set dwarf ",
+			0/*allow-unknown*/, &maintenance_set_cmdlist);
 
-  add_prefix_cmd ("dwarf", class_maintenance, show_dwarf_cmd, _("\
+  add_show_prefix_cmd ("dwarf", class_maintenance, _("\
 Show DWARF specific variables.\n\
 Show DWARF variables such as the cache size."),
-                  &show_dwarf_cmdlist, "maintenance show dwarf ",
-                  0/*allow-unknown*/, &maintenance_show_cmdlist);
+		       &show_dwarf_cmdlist, "maintenance show dwarf ",
+		       0/*allow-unknown*/, &maintenance_show_cmdlist);
 
   add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
 			    &dwarf_max_cache_age, _("\
diff --git a/gdb/frame.c b/gdb/frame.c
index d74d1d5c7c5..ac1016b083f 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -2913,19 +2913,6 @@  frame_prepare_for_sniffer (struct frame_info *frame,
 static struct cmd_list_element *set_backtrace_cmdlist;
 static struct cmd_list_element *show_backtrace_cmdlist;
 
-static void
-set_backtrace_cmd (const char *args, int from_tty)
-{
-  help_list (set_backtrace_cmdlist, "set backtrace ", all_commands,
-	     gdb_stdout);
-}
-
-static void
-show_backtrace_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (show_backtrace_cmdlist, from_tty, "");
-}
-
 /* Definition of the "set backtrace" settings that are exposed as
    "backtrace" command options.  */
 
@@ -2969,16 +2956,16 @@  _initialize_frame ()
 
   gdb::observers::target_changed.attach (frame_observer_target_changed);
 
-  add_prefix_cmd ("backtrace", class_maintenance, set_backtrace_cmd, _("\
+  add_basic_prefix_cmd ("backtrace", class_maintenance, _("\
 Set backtrace specific variables.\n\
 Configure backtrace variables such as the backtrace limit"),
-		  &set_backtrace_cmdlist, "set backtrace ",
-		  0/*allow-unknown*/, &setlist);
-  add_prefix_cmd ("backtrace", class_maintenance, show_backtrace_cmd, _("\
+			&set_backtrace_cmdlist, "set backtrace ",
+			0/*allow-unknown*/, &setlist);
+  add_show_prefix_cmd ("backtrace", class_maintenance, _("\
 Show backtrace specific variables.\n\
 Show backtrace variables such as the backtrace limit."),
-		  &show_backtrace_cmdlist, "show backtrace ",
-		  0/*allow-unknown*/, &showlist);
+		       &show_backtrace_cmdlist, "show backtrace ",
+		       0/*allow-unknown*/, &showlist);
 
   add_setshow_uinteger_cmd ("limit", class_obscure,
 			    &user_set_backtrace_options.backtrace_limit, _("\
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index b3ebd6cf229..881decf0789 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -2075,12 +2075,6 @@  go32_pte_for_address (const char *arg, int from_tty)
 
 static struct cmd_list_element *info_dos_cmdlist = NULL;
 
-static void
-go32_info_dos_command (const char *args, int from_tty)
-{
-  help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
-}
-
 void _initialize_go32_nat ();
 void
 _initialize_go32_nat ()
@@ -2107,9 +2101,9 @@  _initialize_go32_nat ()
   /* We are always processing GCC-compiled programs.  */
   processing_gcc_compilation = 2;
 
-  add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
+  add_basic_prefix_cmd ("dos", class_info, _("\
 Print information specific to DJGPP (aka MS-DOS) debugging."),
-		  &info_dos_cmdlist, "info dos ", 0, &infolist);
+			&info_dos_cmdlist, "info dos ", 0, &infolist);
 
   add_cmd ("sysinfo", class_info, go32_sysinfo, _("\
 Display information about the target system, including CPU, OS, DPMI, etc."),
diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c
index 4b0103c9346..2b82f82820f 100644
--- a/gdb/guile/guile.c
+++ b/gdb/guile/guile.c
@@ -396,33 +396,6 @@  static struct cmd_list_element *set_guile_list;
 static struct cmd_list_element *show_guile_list;
 static struct cmd_list_element *info_guile_list;
 
-/* Function for use by 'set guile' prefix command.  */
-
-static void
-set_guile_command (const char *args, int from_tty)
-{
-  help_list (set_guile_list, "set guile ", all_commands, gdb_stdout);
-}
-
-/* Function for use by 'show guile' prefix command.  */
-
-static void
-show_guile_command (const char *args, int from_tty)
-{
-  cmd_show_list (show_guile_list, from_tty, "");
-}
-
-/* The "info scheme" command is defined as a prefix, with
-   allow_unknown 0.  Therefore, its own definition is called only for
-   "info scheme" with no args.  */
-
-static void
-info_guile_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"info guile\" must be followed"
-		       " by the name of an info command.\n"));
-  help_list (info_guile_list, "info guile ", all_commands, gdb_stdout);
-}
 
 /* Initialization.  */
 
@@ -761,22 +734,22 @@  This command is only a placeholder.")
 	   );
   add_com_alias ("gu", "guile", class_obscure, 1);
 
-  add_prefix_cmd ("guile", class_obscure, set_guile_command,
-		  _("Prefix command for Guile preference settings."),
-		  &set_guile_list, "set guile ", 0,
-		  &setlist);
+  add_basic_prefix_cmd ("guile", class_obscure,
+			_("Prefix command for Guile preference settings."),
+			&set_guile_list, "set guile ", 0,
+			&setlist);
   add_alias_cmd ("gu", "guile", class_obscure, 1, &setlist);
 
-  add_prefix_cmd ("guile", class_obscure, show_guile_command,
-		  _("Prefix command for Guile preference settings."),
-		  &show_guile_list, "show guile ", 0,
-		  &showlist);
+  add_show_prefix_cmd ("guile", class_obscure,
+		       _("Prefix command for Guile preference settings."),
+		       &show_guile_list, "show guile ", 0,
+		       &showlist);
   add_alias_cmd ("gu", "guile", class_obscure, 1, &showlist);
 
-  add_prefix_cmd ("guile", class_obscure, info_guile_command,
-		  _("Prefix command for Guile info displays."),
-		  &info_guile_list, "info guile ", 0,
-		  &infolist);
+  add_basic_prefix_cmd ("guile", class_obscure,
+			_("Prefix command for Guile info displays."),
+			&info_guile_list, "info guile ", 0,
+			&infolist);
   add_info_alias ("gu", "guile", 1);
 
   /* The name "print-stack" is carried over from Python.
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 19876c35535..84edb3649e9 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -9018,22 +9018,6 @@  i386_mpx_set_bounds (const char *args, int from_tty)
 
 static struct cmd_list_element *mpx_set_cmdlist, *mpx_show_cmdlist;
 
-/* Helper function for the CLI commands.  */
-
-static void
-set_mpx_cmd (const char *args, int from_tty)
-{
-  help_list (mpx_set_cmdlist, "set mpx ", all_commands, gdb_stdout);
-}
-
-/* Helper function for the CLI commands.  */
-
-static void
-show_mpx_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (mpx_show_cmdlist, from_tty, "");
-}
-
 void _initialize_i386_tdep ();
 void
 _initialize_i386_tdep ()
@@ -9064,17 +9048,17 @@  is \"default\"."),
 
   /* Add "mpx" prefix for the set commands.  */
 
-  add_prefix_cmd ("mpx", class_support, set_mpx_cmd, _("\
+  add_basic_prefix_cmd ("mpx", class_support, _("\
 Set Intel Memory Protection Extensions specific variables."),
-		  &mpx_set_cmdlist, "set mpx ",
-		  0 /* allow-unknown */, &setlist);
+			&mpx_set_cmdlist, "set mpx ",
+			0 /* allow-unknown */, &setlist);
 
   /* Add "mpx" prefix for the show commands.  */
 
-  add_prefix_cmd ("mpx", class_support, show_mpx_cmd, _("\
+  add_show_prefix_cmd ("mpx", class_support, _("\
 Show Intel Memory Protection Extensions specific variables."),
-		  &mpx_show_cmdlist, "show mpx ",
-		  0 /* allow-unknown */, &showlist);
+		       &mpx_show_cmdlist, "show mpx ",
+		       0 /* allow-unknown */, &showlist);
 
   /* Add "bound" command for the show mpx commands list.  */
 
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index d78374c6deb..9bbb413d4e4 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -3041,14 +3041,6 @@  info_float_command (const char *args, int from_tty)
   gdbarch_print_float_info (get_frame_arch (frame), gdb_stdout, frame, args);
 }
 
-static void
-unset_command (const char *args, int from_tty)
-{
-  printf_filtered (_("\"unset\" must be followed by the "
-		     "name of an unset subcommand.\n"));
-  help_list (unsetlist, "unset ", all_commands, gdb_stdout);
-}
-
 /* Implement `info proc' family of commands.  */
 
 static void
@@ -3229,9 +3221,9 @@  give the program being debugged.  With no arguments, prints the entire\n\
 environment to be given to the program."), &showlist);
   set_cmd_completer (c, noop_completer);
 
-  add_prefix_cmd ("unset", no_class, unset_command,
-		  _("Complement to certain \"set\" commands."),
-		  &unsetlist, "unset ", 0, &cmdlist);
+  add_basic_prefix_cmd ("unset", no_class,
+			_("Complement to certain \"set\" commands."),
+			&unsetlist, "unset ", 0, &cmdlist);
 
   c = add_cmd ("environment", class_run, unset_environment_command, _("\
 Cancel environment variable VAR for the program.\n\
diff --git a/gdb/language.c b/gdb/language.c
index c13fd1a406a..769b3299793 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -500,19 +500,6 @@  language_str (enum language lang)
   return languages[lang]->la_name;
 }
 
-static void
-set_check (const char *ignore, int from_tty)
-{
-  printf_unfiltered (
-     "\"set check\" must be followed by the name of a check subcommand.\n");
-  help_list (setchecklist, "set check ", all_commands, gdb_stdout);
-}
-
-static void
-show_check (const char *ignore, int from_tty)
-{
-  cmd_show_list (showchecklist, from_tty, "");
-}
 
 
 /* Build and install the "set language LANG" command.  */
@@ -1149,15 +1136,15 @@  _initialize_language ()
 
   /* GDB commands for language specific stuff.  */
 
-  add_prefix_cmd ("check", no_class, set_check,
-		  _("Set the status of the type/range checker."),
-		  &setchecklist, "set check ", 0, &setlist);
+  add_basic_prefix_cmd ("check", no_class,
+			_("Set the status of the type/range checker."),
+			&setchecklist, "set check ", 0, &setlist);
   add_alias_cmd ("c", "check", no_class, 1, &setlist);
   add_alias_cmd ("ch", "check", no_class, 1, &setlist);
 
-  add_prefix_cmd ("check", no_class, show_check,
-		  _("Show the status of the type/range checker."),
-		  &showchecklist, "show check ", 0, &showlist);
+  add_show_prefix_cmd ("check", no_class,
+		       _("Show the status of the type/range checker."),
+		       &showchecklist, "show check ", 0, &showlist);
   add_alias_cmd ("c", "check", no_class, 1, &showlist);
   add_alias_cmd ("ch", "check", no_class, 1, &showlist);
 
diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
index 54aa35e72fe..42915db9044 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -33,15 +33,6 @@ 
 
 static struct cmd_list_element *macrolist;
 
-static void
-macro_command (const char *arg, int from_tty)
-{
-  printf_unfiltered
-    ("\"macro\" must be followed by the name of a macro command.\n");
-  help_list (macrolist, "macro ", all_commands, gdb_stdout);
-}
-
-
 
 /* Macro expansion commands.  */
 
@@ -464,9 +455,9 @@  _initialize_macrocmd ()
 {
   /* We introduce a new command prefix, `macro', under which we'll put
      the various commands for working with preprocessor macros.  */
-  add_prefix_cmd ("macro", class_info, macro_command,
-		  _("Prefix for commands dealing with C preprocessor macros."),
-		  &macrolist, "macro ", 0, &cmdlist);
+  add_basic_prefix_cmd ("macro", class_info,
+			_("Prefix for commands dealing with C preprocessor macros."),
+			&macrolist, "macro ", 0, &cmdlist);
 
   add_cmd ("expand", no_class, macro_expand_command, _("\
 Fully expand any C/C++ preprocessor macro invocations in EXPRESSION.\n\
diff --git a/gdb/maint-test-options.c b/gdb/maint-test-options.c
index 2cbdc7c1a20..df75e37361f 100644
--- a/gdb/maint-test-options.c
+++ b/gdb/maint-test-options.c
@@ -411,18 +411,6 @@  maintenance_test_options_unknown_is_operand_command_completer
 /* Command list for maint test-options.  */
 struct cmd_list_element *maintenance_test_options_list;
 
-/* The "maintenance test-options" prefix command.  */
-
-static void
-maintenance_test_options_command (const char *arg, int from_tty)
-{
-  printf_unfiltered
-    (_("\"maintenance test-options\" must be followed "
-       "by the name of a subcommand.\n"));
-  help_list (maintenance_test_options_list, "maintenance test-options ",
-	     all_commands, gdb_stdout);
-}
-
 
 void _initialize_maint_test_options ();
 void
@@ -430,12 +418,12 @@  _initialize_maint_test_options ()
 {
   cmd_list_element *cmd;
 
-  add_prefix_cmd ("test-options", no_class, maintenance_test_options_command,
-		  _("\
+  add_basic_prefix_cmd ("test-options", no_class,
+			_("\
 Generic command for testing the options infrastructure."),
-		  &maintenance_test_options_list,
-		  "maintenance test-options ", 0,
-		  &maintenancelist);
+			&maintenance_test_options_list,
+			"maintenance test-options ", 0,
+			&maintenancelist);
 
   const auto def_group = make_test_options_options_def_group (nullptr);
 
diff --git a/gdb/maint-test-settings.c b/gdb/maint-test-settings.c
index e8e8874e9a8..48333e55c51 100644
--- a/gdb/maint-test-settings.c
+++ b/gdb/maint-test-settings.c
@@ -27,26 +27,6 @@  static cmd_list_element *maintenance_set_test_settings_list;
 /* Command list for "maint show test-settings".  */
 static cmd_list_element *maintenance_show_test_settings_list;
 
-/* The "maintenance set test-settings" prefix command.  */
-
-static void
-maintenance_set_test_settings_cmd (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"maintenance set test-settings\" must be followed "
-		       "by the name of a set command.\n"));
-  help_list (maintenance_set_test_settings_list,
-	     "maintenance set test-settings ",
-	     all_commands, gdb_stdout);
-}
-
-/* The "maintenance show test-settings" prefix command.  */
-
-static void
-maintenance_show_test_settings_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (maintenance_show_test_settings_list, from_tty, "");
-}
-
 /* Control variables for all the "maintenance set/show test-settings
    xxx" commands.  */
 
@@ -105,21 +85,21 @@  _initialize_maint_test_settings ()
 {
   maintenance_test_settings_filename = xstrdup ("/foo/bar");
 
-  add_prefix_cmd ("test-settings", class_maintenance,
-		  maintenance_set_test_settings_cmd, _("\
+  add_basic_prefix_cmd ("test-settings", class_maintenance,
+			_("\
 Set GDB internal variables used for set/show command infrastructure testing."),
-		  &maintenance_set_test_settings_list,
-		  "maintenance set test-settings ",
-		  0/*allow-unknown*/,
-		  &maintenance_set_cmdlist);
+			&maintenance_set_test_settings_list,
+			"maintenance set test-settings ",
+			0/*allow-unknown*/,
+			&maintenance_set_cmdlist);
 
-  add_prefix_cmd ("test-settings", class_maintenance,
-		  maintenance_show_test_settings_cmd, _("\
+  add_show_prefix_cmd ("test-settings", class_maintenance,
+		       _("\
 Show GDB internal variables used for set/show command infrastructure testing."),
-		  &maintenance_show_test_settings_list,
-		  "maintenance show test-settings ",
-		  0/*allow-unknown*/,
-		  &maintenance_show_cmdlist);
+		       &maintenance_show_test_settings_list,
+		       "maintenance show test-settings ",
+		       0/*allow-unknown*/,
+		       &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd ("boolean", class_maintenance,
 			   &maintenance_test_settings_boolean, _("\
diff --git a/gdb/maint.c b/gdb/maint.c
index e8e0f287731..b4890c34cab 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -52,16 +52,6 @@ 
 
 static void maintenance_do_deprecate (const char *, int);
 
-/* Access the maintenance subcommands.  */
-
-static void
-maintenance_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"maintenance\" must be followed by "
-		       "the name of a maintenance command.\n"));
-  help_list (maintenancelist, "maintenance ", all_commands, gdb_stdout);
-}
-
 #ifndef _WIN32
 static void
 maintenance_dump_me (const char *args, int from_tty)
@@ -139,32 +129,6 @@  maintenance_space_display (const char *args, int from_tty)
     set_per_command_space (strtol (args, NULL, 10));
 }
 
-/* The "maintenance info" command is defined as a prefix, with
-   allow_unknown 0.  Therefore, its own definition is called only for
-   "maintenance info" with no args.  */
-
-static void
-maintenance_info_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"maintenance info\" must be followed "
-		       "by the name of an info command.\n"));
-  help_list (maintenanceinfolist, "maintenance info ", all_commands,
-	     gdb_stdout);
-}
-
-/* The "maintenance check" command is defined as a prefix, with
-   allow_unknown 0.  Therefore, its own definition is called only for
-   "maintenance check" with no args.  */
-
-static void
-maintenance_check_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"maintenance check\" must be followed "
-		       "by the name of a check command.\n"));
-  help_list (maintenancechecklist, "maintenance check ", all_commands,
-	     gdb_stdout);
-}
-
 /* Mini tokenizing lexer for 'maint info sections' command.  */
 
 static int
@@ -511,19 +475,6 @@  maintenance_print_architecture (const char *args, int from_tty)
     }
 }
 
-/* The "maintenance print" command is defined as a prefix, with
-   allow_unknown 0.  Therefore, its own definition is called only for
-   "maintenance print" with no args.  */
-
-static void
-maintenance_print_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"maintenance print\" must be followed "
-		       "by the name of a print command.\n"));
-  help_list (maintenanceprintlist, "maintenance print ", all_commands,
-	     gdb_stdout);
-}
-
 /* The "maintenance translate-address" command converts a section and address
    to a symbol.  This can be called in two ways:
    maintenance translate-address <secname> <addr>
@@ -739,21 +690,6 @@  maintenance_do_deprecate (const char *text, int deprecate)
 struct cmd_list_element *maintenance_set_cmdlist;
 struct cmd_list_element *maintenance_show_cmdlist;
 
-static void
-maintenance_set_cmd (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"maintenance set\" must be followed "
-		       "by the name of a set command.\n"));
-  help_list (maintenance_set_cmdlist, "maintenance set ", all_commands,
-	     gdb_stdout);
-}
-
-static void
-maintenance_show_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (maintenance_show_cmdlist, from_tty, "");
-}
-
 /* "maintenance with" command.  */
 
 static void
@@ -1097,14 +1033,6 @@  set_per_command_cmd (const char *args, int from_tty)
       }
 }
 
-/* Command "show per-command" displays summary of all the current
-   "show per-command " settings.  */
-
-static void
-show_per_command_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (per_command_showlist, from_tty, "");
-}
 
 
 /* The "maintenance selftest" command.  */
@@ -1141,19 +1069,19 @@  _initialize_maint_cmds ()
 {
   struct cmd_list_element *cmd;
 
-  add_prefix_cmd ("maintenance", class_maintenance, maintenance_command, _("\
+  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, "maintenance ", 0,
+			&cmdlist);
 
   add_com_alias ("mt", "maintenance", class_maintenance, 1);
 
-  add_prefix_cmd ("info", class_maintenance, maintenance_info_command, _("\
+  add_basic_prefix_cmd ("info", class_maintenance, _("\
 Commands for showing internal info about the program being debugged."),
-		  &maintenanceinfolist, "maintenance info ", 0,
-		  &maintenancelist);
+			&maintenanceinfolist, "maintenance info ", 0,
+			&maintenancelist);
   add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist);
 
   add_cmd ("sections", class_maintenance, maintenance_info_sections, _("\
@@ -1168,24 +1096,24 @@  implies all sections).  In addition, the special argument\n\
 lists all sections from all object files, including shared libraries."),
 	   &maintenanceinfolist);
 
-  add_prefix_cmd ("print", class_maintenance, maintenance_print_command,
-		  _("Maintenance command for printing GDB internal state."),
-		  &maintenanceprintlist, "maintenance print ", 0,
-		  &maintenancelist);
+  add_basic_prefix_cmd ("print", class_maintenance,
+			_("Maintenance command for printing GDB internal state."),
+			&maintenanceprintlist, "maintenance print ", 0,
+			&maintenancelist);
 
-  add_prefix_cmd ("set", class_maintenance, maintenance_set_cmd, _("\
+  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 ",
-		  0/*allow-unknown*/,
-		  &maintenancelist);
+			&maintenance_set_cmdlist, "maintenance set ",
+			0/*allow-unknown*/,
+			&maintenancelist);
 
-  add_prefix_cmd ("show", class_maintenance, maintenance_show_cmd, _("\
+  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 ",
-		  0/*allow-unknown*/,
-		  &maintenancelist);
+		       &maintenance_show_cmdlist, "maintenance show ",
+		       0/*allow-unknown*/,
+		       &maintenancelist);
 
   cmd = add_cmd ("with", class_maintenance, maintenance_with_cmd, _("\
 Like \"with\", but works with \"maintenance set\" variables.\n\
@@ -1232,10 +1160,10 @@  Per-command statistics settings."),
 		    &per_command_setlist, "maintenance set per-command ",
 		    1/*allow-unknown*/, &maintenance_set_cmdlist);
 
-  add_prefix_cmd ("per-command", class_maintenance, show_per_command_cmd, _("\
+  add_show_prefix_cmd ("per-command", class_maintenance, _("\
 Show per-command statistics settings."),
-		    &per_command_showlist, "maintenance show per-command ",
-		    0/*allow-unknown*/, &maintenance_show_cmdlist);
+		       &per_command_showlist, "maintenance show per-command ",
+		       0/*allow-unknown*/, &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd ("time", class_maintenance,
 			   &per_command_time, _("\
@@ -1299,10 +1227,10 @@  Print the internal architecture configuration.\n\
 Takes an optional file parameter."),
 	   &maintenanceprintlist);
 
-  add_prefix_cmd ("check", class_maintenance, maintenance_check_command, _("\
+  add_basic_prefix_cmd ("check", class_maintenance, _("\
 Commands for checking internal gdb state."),
-		  &maintenancechecklist, "maintenance check ", 0,
-		  &maintenancelist);
+			&maintenancechecklist, "maintenance check ", 0,
+			&maintenancelist);
 
   add_cmd ("translate-address", class_maintenance,
 	   maintenance_translate_address,
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index c6952a5ba3f..2e93f9e5fd3 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -6877,23 +6877,6 @@  mips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
     return mips32_stack_frame_destroyed_p (gdbarch, pc);
 }
 
-/* Root of all "set mips "/"show mips " commands.  This will eventually be
-   used for all MIPS-specific commands.  */
-
-static void
-show_mips_command (const char *args, int from_tty)
-{
-  help_list (showmipscmdlist, "show mips ", all_commands, gdb_stdout);
-}
-
-static void
-set_mips_command (const char *args, int from_tty)
-{
-  printf_unfiltered
-    ("\"set mips\" must be followed by an appropriate subcommand.\n");
-  help_list (setmipscmdlist, "set mips ", all_commands, gdb_stdout);
-}
-
 /* Commands to show/set the MIPS FPU type.  */
 
 static void
@@ -8990,13 +8973,13 @@  _initialize_mips_tdep ()
   set_tdesc_property (mips_tdesc_gp64, PROPERTY_GP64, "");
 
   /* Add root prefix command for all "set mips"/"show mips" commands.  */
-  add_prefix_cmd ("mips", no_class, set_mips_command,
-		  _("Various MIPS specific commands."),
-		  &setmipscmdlist, "set mips ", 0, &setlist);
+  add_basic_prefix_cmd ("mips", no_class,
+			_("Various MIPS specific commands."),
+			&setmipscmdlist, "set mips ", 0, &setlist);
 
-  add_prefix_cmd ("mips", no_class, show_mips_command,
-		  _("Various MIPS specific commands."),
-		  &showmipscmdlist, "show mips ", 0, &showlist);
+  add_show_prefix_cmd ("mips", no_class,
+		       _("Various MIPS specific commands."),
+		       &showmipscmdlist, "show mips ", 0, &showlist);
 
   /* Allow the user to override the ABI.  */
   add_setshow_enum_cmd ("abi", class_obscure, mips_abi_strings,
diff --git a/gdb/python/python.c b/gdb/python/python.c
index e56520ab11a..d252646c02c 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1590,23 +1590,6 @@  python_command (const char *arg, int from_tty)
 static struct cmd_list_element *user_set_python_list;
 static struct cmd_list_element *user_show_python_list;
 
-/* Function for use by 'set python' prefix command.  */
-
-static void
-user_set_python (const char *args, int from_tty)
-{
-  help_list (user_set_python_list, "set python ", all_commands,
-	     gdb_stdout);
-}
-
-/* Function for use by 'show python' prefix command.  */
-
-static void
-user_show_python (const char *args, int from_tty)
-{
-  cmd_show_list (user_show_python_list, from_tty, "");
-}
-
 /* Initialize the Python code.  */
 
 #ifdef HAVE_PYTHON
@@ -1871,15 +1854,15 @@  This command is only a placeholder.")
   add_com_alias ("py", "python", class_obscure, 1);
 
   /* Add set/show python print-stack.  */
-  add_prefix_cmd ("python", no_class, user_show_python,
-		  _("Prefix command for python preference settings."),
-		  &user_show_python_list, "show python ", 0,
-		  &showlist);
-
-  add_prefix_cmd ("python", no_class, user_set_python,
-		  _("Prefix command for python preference settings."),
-		  &user_set_python_list, "set python ", 0,
-		  &setlist);
+  add_basic_prefix_cmd ("python", no_class,
+			_("Prefix command for python preference settings."),
+			&user_show_python_list, "show python ", 0,
+			&showlist);
+
+  add_show_prefix_cmd ("python", no_class,
+		       _("Prefix command for python preference settings."),
+		       &user_set_python_list, "set python ", 0,
+		       &setlist);
 
   add_setshow_enum_cmd ("print-stack", no_class, python_excp_enums,
 			&gdbpy_should_print_stack, _("\
diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index fd3beb03ec3..f3b4ecf8706 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -563,24 +563,6 @@  ravenscar_thread_target::get_ada_task_ptid (long lwp, long thread)
 static struct cmd_list_element *set_ravenscar_list;
 static struct cmd_list_element *show_ravenscar_list;
 
-/* Implement the "set ravenscar" prefix command.  */
-
-static void
-set_ravenscar_command (const char *arg, int from_tty)
-{
-  printf_unfiltered (_(\
-"\"set ravenscar\" must be followed by the name of a setting.\n"));
-  help_list (set_ravenscar_list, "set ravenscar ", all_commands, gdb_stdout);
-}
-
-/* Implement the "show ravenscar" prefix command.  */
-
-static void
-show_ravenscar_command (const char *args, int from_tty)
-{
-  cmd_show_list (show_ravenscar_list, from_tty, "");
-}
-
 /* Implement the "show ravenscar task-switching" command.  */
 
 static void
@@ -607,13 +589,13 @@  _initialize_ravenscar ()
      ravenscar ops if needed.  */
   gdb::observers::inferior_created.attach (ravenscar_inferior_created);
 
-  add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command,
-                  _("Prefix command for changing Ravenscar-specific settings."),
-                  &set_ravenscar_list, "set ravenscar ", 0, &setlist);
+  add_basic_prefix_cmd ("ravenscar", no_class,
+			_("Prefix command for changing Ravenscar-specific settings."),
+			&set_ravenscar_list, "set ravenscar ", 0, &setlist);
 
-  add_prefix_cmd ("ravenscar", no_class, show_ravenscar_command,
-                  _("Prefix command for showing Ravenscar-specific settings."),
-                  &show_ravenscar_list, "show ravenscar ", 0, &showlist);
+  add_show_prefix_cmd ("ravenscar", no_class,
+		       _("Prefix command for showing Ravenscar-specific settings."),
+		       &show_ravenscar_list, "show ravenscar ", 0, &showlist);
 
   add_setshow_boolean_cmd ("task-switching", class_obscure,
                            &ravenscar_task_support, _("\
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 2ca9a61457a..fe2ab8ad9a9 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -2962,25 +2962,6 @@  cmd_record_btrace_start (const char *args, int from_tty)
     }
 }
 
-/* The "set record btrace" command.  */
-
-static void
-cmd_set_record_btrace (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set record btrace\" must be followed "
-		       "by an appropriate subcommand.\n"));
-  help_list (set_record_btrace_cmdlist, "set record btrace ",
-	     all_commands, gdb_stdout);
-}
-
-/* The "show record btrace" command.  */
-
-static void
-cmd_show_record_btrace (const char *args, int from_tty)
-{
-  cmd_show_list (show_record_btrace_cmdlist, from_tty, "");
-}
-
 /* The "show record btrace replay-memory-access" command.  */
 
 static void
@@ -3095,44 +3076,6 @@  cmd_show_record_btrace_cpu (const char *args, int from_tty)
   error (_("Internal error: bad cpu state."));
 }
 
-/* The "s record btrace bts" command.  */
-
-static void
-cmd_set_record_btrace_bts (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set record btrace bts\" must be followed "
-		       "by an appropriate subcommand.\n"));
-  help_list (set_record_btrace_bts_cmdlist, "set record btrace bts ",
-	     all_commands, gdb_stdout);
-}
-
-/* The "show record btrace bts" command.  */
-
-static void
-cmd_show_record_btrace_bts (const char *args, int from_tty)
-{
-  cmd_show_list (show_record_btrace_bts_cmdlist, from_tty, "");
-}
-
-/* The "set record btrace pt" command.  */
-
-static void
-cmd_set_record_btrace_pt (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set record btrace pt\" must be followed "
-		       "by an appropriate subcommand.\n"));
-  help_list (set_record_btrace_pt_cmdlist, "set record btrace pt ",
-	     all_commands, gdb_stdout);
-}
-
-/* The "show record btrace pt" command.  */
-
-static void
-cmd_show_record_btrace_pt (const char *args, int from_tty)
-{
-  cmd_show_list (show_record_btrace_pt_cmdlist, from_tty, "");
-}
-
 /* The "record bts buffer-size" show value function.  */
 
 static void
@@ -3181,13 +3124,13 @@  This format may not be available on all processors."),
 	   &record_btrace_cmdlist);
   add_alias_cmd ("pt", "btrace pt", class_obscure, 1, &record_cmdlist);
 
-  add_prefix_cmd ("btrace", class_support, cmd_set_record_btrace,
-		  _("Set record options."), &set_record_btrace_cmdlist,
-		  "set record btrace ", 0, &set_record_cmdlist);
+  add_basic_prefix_cmd ("btrace", class_support,
+			_("Set record options."), &set_record_btrace_cmdlist,
+			"set record btrace ", 0, &set_record_cmdlist);
 
-  add_prefix_cmd ("btrace", class_support, cmd_show_record_btrace,
-		  _("Show record options."), &show_record_btrace_cmdlist,
-		  "show record btrace ", 0, &show_record_cmdlist);
+  add_show_prefix_cmd ("btrace", class_support,
+		       _("Show record options."), &show_record_btrace_cmdlist,
+		       "show record btrace ", 0, &show_record_cmdlist);
 
   add_setshow_enum_cmd ("replay-memory-access", no_class,
 			replay_memory_access_types, &replay_memory_access, _("\
@@ -3230,15 +3173,17 @@  Do not enable errata workarounds for trace decode."),
 Show the cpu to be used for trace decode."),
 	   &show_record_btrace_cmdlist);
 
-  add_prefix_cmd ("bts", class_support, cmd_set_record_btrace_bts,
-		  _("Set record btrace bts options."),
-		  &set_record_btrace_bts_cmdlist,
-		  "set record btrace bts ", 0, &set_record_btrace_cmdlist);
+  add_basic_prefix_cmd ("bts", class_support,
+			_("Set record btrace bts options."),
+			&set_record_btrace_bts_cmdlist,
+			"set record btrace bts ", 0,
+			&set_record_btrace_cmdlist);
 
-  add_prefix_cmd ("bts", class_support, cmd_show_record_btrace_bts,
-		  _("Show record btrace bts options."),
-		  &show_record_btrace_bts_cmdlist,
-		  "show record btrace bts ", 0, &show_record_btrace_cmdlist);
+  add_show_prefix_cmd ("bts", class_support,
+		       _("Show record btrace bts options."),
+		       &show_record_btrace_bts_cmdlist,
+		       "show record btrace bts ", 0,
+		       &show_record_btrace_cmdlist);
 
   add_setshow_uinteger_cmd ("buffer-size", no_class,
 			    &record_btrace_conf.bts.size,
@@ -3254,15 +3199,17 @@  The trace buffer size may not be changed while recording."), NULL,
 			    &set_record_btrace_bts_cmdlist,
 			    &show_record_btrace_bts_cmdlist);
 
-  add_prefix_cmd ("pt", class_support, cmd_set_record_btrace_pt,
-		  _("Set record btrace pt options."),
-		  &set_record_btrace_pt_cmdlist,
-		  "set record btrace pt ", 0, &set_record_btrace_cmdlist);
-
-  add_prefix_cmd ("pt", class_support, cmd_show_record_btrace_pt,
-		  _("Show record btrace pt options."),
-		  &show_record_btrace_pt_cmdlist,
-		  "show record btrace pt ", 0, &show_record_btrace_cmdlist);
+  add_basic_prefix_cmd ("pt", class_support,
+			_("Set record btrace pt options."),
+			&set_record_btrace_pt_cmdlist,
+			"set record btrace pt ", 0,
+			&set_record_btrace_cmdlist);
+
+  add_show_prefix_cmd ("pt", class_support,
+		       _("Show record btrace pt options."),
+		       &show_record_btrace_pt_cmdlist,
+		       "show record btrace pt ", 0,
+		       &show_record_btrace_cmdlist);
 
   add_setshow_uinteger_cmd ("buffer-size", no_class,
 			    &record_btrace_conf.pt.size,
diff --git a/gdb/record-full.c b/gdb/record-full.c
index 9c8bd18149b..9d6e403e576 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -2794,25 +2794,6 @@  set_record_full_insn_max_num (const char *args, int from_tty,
     }
 }
 
-/* The "set record full" command.  */
-
-static void
-set_record_full_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set record full\" must be followed "
-		       "by an appropriate subcommand.\n"));
-  help_list (set_record_full_cmdlist, "set record full ", all_commands,
-	     gdb_stdout);
-}
-
-/* The "show record full" command.  */
-
-static void
-show_record_full_command (const char *args, int from_tty)
-{
-  cmd_show_list (show_record_full_cmdlist, from_tty, "");
-}
-
 void _initialize_record_full ();
 void
 _initialize_record_full ()
@@ -2844,13 +2825,13 @@  Argument is filename.  File must be created with 'record save'."),
   set_cmd_completer (c, filename_completer);
   deprecate_cmd (c, "record full restore");
 
-  add_prefix_cmd ("full", class_support, set_record_full_command,
-		  _("Set record options."), &set_record_full_cmdlist,
-		  "set record full ", 0, &set_record_cmdlist);
+  add_basic_prefix_cmd ("full", class_support,
+			_("Set record options."), &set_record_full_cmdlist,
+			"set record full ", 0, &set_record_cmdlist);
 
-  add_prefix_cmd ("full", class_support, show_record_full_command,
-		  _("Show record options."), &show_record_full_cmdlist,
-		  "show record full ", 0, &show_record_cmdlist);
+  add_show_prefix_cmd ("full", class_support,
+		       _("Show record options."), &show_record_full_cmdlist,
+		       "show record full ", 0, &show_record_cmdlist);
 
   /* Record instructions number limit command.  */
   add_setshow_boolean_cmd ("stop-at-limit", no_class,
diff --git a/gdb/record.c b/gdb/record.c
index 94600eb5e7e..759395d5bcd 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -314,23 +314,6 @@  cmd_record_stop (const char *args, int from_tty)
   gdb::observers::record_changed.notify (current_inferior (), 0, NULL, NULL);
 }
 
-/* The "set record" command.  */
-
-static void
-set_record_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set record\" must be followed "
-		       "by an appropriate subcommand.\n"));
-  help_list (set_record_cmdlist, "set record ", all_commands, gdb_stdout);
-}
-
-/* The "show record" command.  */
-
-static void
-show_record_command (const char *args, int from_tty)
-{
-  cmd_show_list (show_record_cmdlist, from_tty, "");
-}
 
 /* The "info record" command.  */
 
@@ -808,13 +791,13 @@  A size of \"unlimited\" means unlimited lines.  The default is 10."),
   set_cmd_completer (c, filename_completer);
 
   add_com_alias ("rec", "record", class_obscure, 1);
-  add_prefix_cmd ("record", class_support, set_record_command,
-		  _("Set record options."), &set_record_cmdlist,
-		  "set record ", 0, &setlist);
+  add_basic_prefix_cmd ("record", class_support,
+			_("Set record options."), &set_record_cmdlist,
+			"set record ", 0, &setlist);
   add_alias_cmd ("rec", "record", class_obscure, 1, &setlist);
-  add_prefix_cmd ("record", class_support, show_record_command,
-		  _("Show record options."), &show_record_cmdlist,
-		  "show record ", 0, &showlist);
+  add_show_prefix_cmd ("record", class_support,
+		       _("Show record options."), &show_record_cmdlist,
+		       "show record ", 0, &showlist);
   add_alias_cmd ("rec", "record", class_obscure, 1, &showlist);
   add_prefix_cmd ("record", class_support, info_record_command,
 		  _("Info record options."), &info_record_cmdlist,
diff --git a/gdb/remote.c b/gdb/remote.c
index 495f9680c1e..5db406e045c 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -12700,12 +12700,6 @@  remote_delete_command (const char *args, int from_tty)
   remote_file_delete (argv[0], from_tty);
 }
 
-static void
-remote_command (const char *args, int from_tty)
-{
-  help_list (remote_cmdlist, "remote ", all_commands, gdb_stdout);
-}
-
 bool
 remote_target::can_execute_reverse ()
 {
@@ -14224,12 +14218,6 @@  remote_target::thread_events (int enable)
     }
 }
 
-static void
-set_remote_cmd (const char *args, int from_tty)
-{
-  help_list (remote_set_cmdlist, "set remote ", all_commands, gdb_stdout);
-}
-
 static void
 show_remote_cmd (const char *args, int from_tty)
 {
@@ -14382,12 +14370,12 @@  _initialize_remote ()
 
   /* set/show remote ...  */
 
-  add_prefix_cmd ("remote", class_maintenance, set_remote_cmd, _("\
+  add_basic_prefix_cmd ("remote", class_maintenance, _("\
 Remote protocol specific variables.\n\
 Configure various remote-protocol specific variables such as\n\
 the packets being used."),
-		  &remote_set_cmdlist, "set remote ",
-		  0 /* allow-unknown */, &setlist);
+			&remote_set_cmdlist, "set remote ",
+			0 /* allow-unknown */, &setlist);
   add_prefix_cmd ("remote", class_maintenance, show_remote_cmd, _("\
 Remote protocol specific variables.\n\
 Configure various remote-protocol specific variables such as\n\
@@ -14808,11 +14796,11 @@  packets."),
 				   `Z' packets is %s.  */
 				&remote_set_cmdlist, &remote_show_cmdlist);
 
-  add_prefix_cmd ("remote", class_files, remote_command, _("\
+  add_basic_prefix_cmd ("remote", class_files, _("\
 Manipulate files on the remote system.\n\
 Transfer files to and from the remote target system."),
-		  &remote_cmdlist, "remote ",
-		  0 /* allow-unknown */, &cmdlist);
+			&remote_cmdlist, "remote ",
+			0 /* allow-unknown */, &cmdlist);
 
   add_cmd ("put", class_files, remote_put_command,
 	   _("Copy a local file to the remote system."),
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 0423e6abf30..1bb824eef54 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -284,47 +284,11 @@  show_use_compressed_breakpoints (struct ui_file *file, int from_tty,
 static struct cmd_list_element *setriscvcmdlist = NULL;
 static struct cmd_list_element *showriscvcmdlist = NULL;
 
-/* The show callback for the 'show riscv' prefix command.  */
-
-static void
-show_riscv_command (const char *args, int from_tty)
-{
-  help_list (showriscvcmdlist, "show riscv ", all_commands, gdb_stdout);
-}
-
-/* The set callback for the 'set riscv' prefix command.  */
-
-static void
-set_riscv_command (const char *args, int from_tty)
-{
-  printf_unfiltered
-    (_("\"set riscv\" must be followed by an appropriate subcommand.\n"));
-  help_list (setriscvcmdlist, "set riscv ", all_commands, gdb_stdout);
-}
-
 /* The set and show lists for 'set riscv' and 'show riscv' prefixes.  */
 
 static struct cmd_list_element *setdebugriscvcmdlist = NULL;
 static struct cmd_list_element *showdebugriscvcmdlist = NULL;
 
-/* The show callback for the 'show debug riscv' prefix command.  */
-
-static void
-show_debug_riscv_command (const char *args, int from_tty)
-{
-  help_list (showdebugriscvcmdlist, "show debug riscv ", all_commands, gdb_stdout);
-}
-
-/* The set callback for the 'set debug riscv' prefix command.  */
-
-static void
-set_debug_riscv_command (const char *args, int from_tty)
-{
-  printf_unfiltered
-    (_("\"set debug riscv\" must be followed by an appropriate subcommand.\n"));
-  help_list (setdebugriscvcmdlist, "set debug riscv ", all_commands, gdb_stdout);
-}
-
 /* The show callback for all 'show debug riscv VARNAME' variables.  */
 
 static void
@@ -3527,15 +3491,15 @@  _initialize_riscv_tdep ()
 
   /* Add root prefix command for all "set debug riscv" and "show debug
      riscv" commands.  */
-  add_prefix_cmd ("riscv", no_class, set_debug_riscv_command,
-		  _("RISC-V specific debug commands."),
-		  &setdebugriscvcmdlist, "set debug riscv ", 0,
-		  &setdebuglist);
+  add_basic_prefix_cmd ("riscv", no_class,
+			_("RISC-V specific debug commands."),
+			&setdebugriscvcmdlist, "set debug riscv ", 0,
+			&setdebuglist);
 
-  add_prefix_cmd ("riscv", no_class, show_debug_riscv_command,
-		  _("RISC-V specific debug commands."),
-		  &showdebugriscvcmdlist, "show debug riscv ", 0,
-		  &showdebuglist);
+  add_show_prefix_cmd ("riscv", no_class,
+		       _("RISC-V specific debug commands."),
+		       &showdebugriscvcmdlist, "show debug riscv ", 0,
+		       &showdebuglist);
 
   add_setshow_zuinteger_cmd ("breakpoints", class_maintenance,
 			     &riscv_debug_breakpoints,  _("\
@@ -3578,13 +3542,13 @@  initialisation process."),
 			     &setdebugriscvcmdlist, &showdebugriscvcmdlist);
 
   /* Add root prefix command for all "set riscv" and "show riscv" commands.  */
-  add_prefix_cmd ("riscv", no_class, set_riscv_command,
-		  _("RISC-V specific commands."),
-		  &setriscvcmdlist, "set riscv ", 0, &setlist);
+  add_basic_prefix_cmd ("riscv", no_class,
+			_("RISC-V specific commands."),
+			&setriscvcmdlist, "set riscv ", 0, &setlist);
 
-  add_prefix_cmd ("riscv", no_class, show_riscv_command,
-		  _("RISC-V specific commands."),
-		  &showriscvcmdlist, "show riscv ", 0, &showlist);
+  add_show_prefix_cmd ("riscv", no_class,
+		       _("RISC-V specific commands."),
+		       &showriscvcmdlist, "show riscv ", 0, &showlist);
 
 
   use_compressed_breakpoints = AUTO_BOOLEAN_AUTO;
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 2c41e1c858b..1e1fbc7022b 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -7172,22 +7172,6 @@  rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
   /* FIXME: Dump gdbarch_tdep.  */
 }
 
-/* PowerPC-specific commands.  */
-
-static void
-set_powerpc_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\
-\"set powerpc\" must be followed by an appropriate subcommand.\n"));
-  help_list (setpowerpccmdlist, "set powerpc ", all_commands, gdb_stdout);
-}
-
-static void
-show_powerpc_command (const char *args, int from_tty)
-{
-  cmd_show_list (showpowerpccmdlist, from_tty, "");
-}
-
 static void
 powerpc_set_soft_float (const char *args, int from_tty,
 			struct cmd_list_element *c)
@@ -7338,13 +7322,13 @@  _initialize_rs6000_tdep ()
 
   /* Add root prefix command for all "set powerpc"/"show powerpc"
      commands.  */
-  add_prefix_cmd ("powerpc", no_class, set_powerpc_command,
-		  _("Various PowerPC-specific commands."),
-		  &setpowerpccmdlist, "set powerpc ", 0, &setlist);
+  add_basic_prefix_cmd ("powerpc", no_class,
+			_("Various PowerPC-specific commands."),
+			&setpowerpccmdlist, "set powerpc ", 0, &setlist);
 
-  add_prefix_cmd ("powerpc", no_class, show_powerpc_command,
-		  _("Various PowerPC-specific commands."),
-		  &showpowerpccmdlist, "show powerpc ", 0, &showlist);
+  add_show_prefix_cmd ("powerpc", no_class,
+		       _("Various PowerPC-specific commands."),
+		       &showpowerpccmdlist, "show powerpc ", 0, &showlist);
 
   /* Add a command to allow the user to force the ABI.  */
   add_setshow_auto_boolean_cmd ("soft-float", class_support,
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
index 1c6d5a346c6..7dd903dfaad 100644
--- a/gdb/ser-tcp.c
+++ b/gdb/ser-tcp.c
@@ -424,20 +424,6 @@  ser_tcp_send_break (struct serial *scb)
   return (serial_write (scb, "\377\363", 2));
 }
 
-/* Support for "set tcp" and "show tcp" commands.  */
-
-static void
-set_tcp_cmd (const char *args, int from_tty)
-{
-  help_list (tcp_set_cmdlist, "set tcp ", all_commands, gdb_stdout);
-}
-
-static void
-show_tcp_cmd (const char *args, int from_tty)
-{
-  help_list (tcp_show_cmdlist, "show tcp ", all_commands, gdb_stdout);
-}
-
 #ifndef USE_WIN32API
 
 /* The TCP ops.  */
@@ -480,16 +466,16 @@  _initialize_ser_tcp ()
   serial_add_interface (&tcp_ops);
 #endif /* USE_WIN32API */
 
-  add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\
+  add_basic_prefix_cmd ("tcp", class_maintenance, _("\
 TCP protocol specific variables.\n\
 Configure variables specific to remote TCP connections."),
-		  &tcp_set_cmdlist, "set tcp ",
-		  0 /* allow-unknown */, &setlist);
-  add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\
+			&tcp_set_cmdlist, "set tcp ",
+			0 /* allow-unknown */, &setlist);
+  add_show_prefix_cmd ("tcp", class_maintenance, _("\
 TCP protocol specific variables.\n\
 Configure variables specific to remote TCP connections."),
-		  &tcp_show_cmdlist, "show tcp ",
-		  0 /* allow-unknown */, &showlist);
+		       &tcp_show_cmdlist, "show tcp ",
+		       0 /* allow-unknown */, &showlist);
 
   add_setshow_boolean_cmd ("auto-retry", class_obscure,
 			   &tcp_auto_retry, _("\
diff --git a/gdb/serial.c b/gdb/serial.c
index e0d64dd627f..e253c0ec44a 100644
--- a/gdb/serial.c
+++ b/gdb/serial.c
@@ -623,20 +623,6 @@  serial_pipe (struct serial *scbs[2])
 static struct cmd_list_element *serial_set_cmdlist;
 static struct cmd_list_element *serial_show_cmdlist;
 
-static void
-serial_set_cmd (const char *args, int from_tty)
-{
-  printf_unfiltered ("\"set serial\" must be followed "
-		     "by the name of a command.\n");
-  help_list (serial_set_cmdlist, "set serial ", all_commands, gdb_stdout);
-}
-
-static void
-serial_show_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (serial_show_cmdlist, from_tty, "");
-}
-
 /* Baud rate specified for talking to serial target systems.  Default
    is left as -1, so targets can choose their own defaults.  */
 /* FIXME: This means that "show serial baud" and gr_files_info can
@@ -686,17 +672,17 @@  Connect the terminal directly up to the command monitor.\n\
 Use <CR>~. or <CR>~^D to break out."));
 #endif /* 0 */
 
-  add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
+  add_basic_prefix_cmd ("serial", class_maintenance, _("\
 Set default serial/parallel port configuration."),
-		  &serial_set_cmdlist, "set serial ",
-		  0/*allow-unknown*/,
-		  &setlist);
+			&serial_set_cmdlist, "set serial ",
+			0/*allow-unknown*/,
+			&setlist);
 
-  add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
+  add_show_prefix_cmd ("serial", class_maintenance, _("\
 Show default serial/parallel port configuration."),
-		  &serial_show_cmdlist, "show serial ",
-		  0/*allow-unknown*/,
-		  &showlist);
+		       &serial_show_cmdlist, "show serial ",
+		       0/*allow-unknown*/,
+		       &showlist);
 
   /* If target is open when baud changes, it doesn't take effect until
      the next open (I think, not sure).  */
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 9e831fb42e0..5b322ea2d5a 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -2408,30 +2408,16 @@  sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   return gdbarch;
 }
 
-static void
-show_sh_command (const char *args, int from_tty)
-{
-  help_list (showshcmdlist, "show sh ", all_commands, gdb_stdout);
-}
-
-static void
-set_sh_command (const char *args, int from_tty)
-{
-  printf_unfiltered
-    ("\"set sh\" must be followed by an appropriate subcommand.\n");
-  help_list (setshcmdlist, "set sh ", all_commands, gdb_stdout);
-}
-
 void _initialize_sh_tdep ();
 void
 _initialize_sh_tdep ()
 {
   gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
 
-  add_prefix_cmd ("sh", no_class, set_sh_command, "SH specific commands.",
-                  &setshcmdlist, "set sh ", 0, &setlist);
-  add_prefix_cmd ("sh", no_class, show_sh_command, "SH specific commands.",
-                  &showshcmdlist, "show sh ", 0, &showlist);
+  add_basic_prefix_cmd ("sh", no_class, "SH specific commands.",
+			&setshcmdlist, "set sh ", 0, &setlist);
+  add_show_prefix_cmd ("sh", no_class, "SH specific commands.",
+		       &showshcmdlist, "show sh ", 0, &showlist);
   
   add_setshow_enum_cmd ("calling-convention", class_vars, sh_cc_enum,
 			&sh_active_calling_convention,
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index ac915d468fd..593db364003 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -186,14 +186,6 @@  sparc64_forget_process (pid_t pid)
 
 }
 
-static void
-info_adi_command (const char *args, int from_tty)
-{
-  printf_unfiltered ("\"adi\" must be followed by \"examine\" "
-                     "or \"assign\".\n");
-  help_list (sparc64adilist, "adi ", all_commands, gdb_stdout);
-}
-
 /* Read attributes of a maps entry in /proc/[pid]/adi/maps.  */
 
 static void
@@ -538,10 +530,9 @@  void _initialize_sparc64_adi_tdep ();
 void
 _initialize_sparc64_adi_tdep ()
 {
-
-  add_prefix_cmd ("adi", class_support, info_adi_command,
-                  _("ADI version related commands."),
-                  &sparc64adilist, "adi ", 0, &cmdlist);
+  add_basic_prefix_cmd ("adi", class_support,
+			_("ADI version related commands."),
+			&sparc64adilist, "adi ", 0, &cmdlist);
   add_cmd ("examine", class_support, adi_examine_command,
            _("Examine ADI versions."), &sparc64adilist);
   add_alias_cmd ("x", "examine", no_class, 1, &sparc64adilist);
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 8c002ebfabe..40753444525 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -3349,20 +3349,9 @@  overlay_load_command (const char *args, int from_tty)
     error (_("This target does not know how to read its overlay state."));
 }
 
-/* Function: overlay_command
-   A place-holder for a mis-typed command.  */
-
 /* Command list chain containing all defined "overlay" subcommands.  */
 static struct cmd_list_element *overlaylist;
 
-static void
-overlay_command (const char *args, int from_tty)
-{
-  printf_unfiltered
-    ("\"overlay\" must be followed by the name of an overlay command.\n");
-  help_list (overlaylist, "overlay ", all_commands, gdb_stdout);
-}
-
 /* Target Overlays for the "Simplest" overlay manager:
 
    This is GDB's default target overlay layer.  It works with the
@@ -3913,9 +3902,9 @@  When OFFSET is provided, FILE must also be provided.  FILE can be provided\n\
 on its own."), &cmdlist);
   set_cmd_completer (c, filename_completer);
 
-  add_prefix_cmd ("overlay", class_support, overlay_command,
-		  _("Commands for debugging overlays."), &overlaylist,
-		  "overlay ", 0, &cmdlist);
+  add_basic_prefix_cmd ("overlay", class_support,
+			_("Commands for debugging overlays."), &overlaylist,
+			"overlay ", 0, &cmdlist);
 
   add_com_alias ("ovly", "overlay", class_alias, 1);
   add_com_alias ("ov", "overlay", class_alias, 1);
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 45d75a3cd11..6354a8b0d20 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -6479,15 +6479,6 @@  get_msymbol_address (struct objfile *objf, const struct minimal_symbol *minsym)
 
 static struct cmd_list_element *info_module_cmdlist = NULL;
 
-/* Implement the 'info module' command, just displays some help text for
-   the available sub-commands.  */
-
-static void
-info_module_command (const char *args, int from_tty)
-{
-  help_list (info_module_cmdlist, "info module ", class_info, gdb_stdout);
-}
-
 /* See symtab.h.  */
 
 std::vector<module_symbol_search>
@@ -6846,10 +6837,10 @@  Options:\n\
 		_("All module names, or those matching REGEXP."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
-  add_prefix_cmd ("module", class_info, info_module_command, _("\
+  add_basic_prefix_cmd ("module", class_info, _("\
 Print information about modules."),
-		  &info_module_cmdlist, "info module ",
-		  0, &infolist);
+			&info_module_cmdlist, "info module ",
+			0, &infolist);
 
   c = add_cmd ("functions", class_info, info_module_functions_command, _("\
 Display functions arranged by modules.\n\
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 4194819d9ab..2ec07a3e3bd 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -1217,24 +1217,6 @@  static struct cmd_list_element *tdesc_unset_cmdlist;
 
 /* Helper functions for the CLI commands.  */
 
-static void
-set_tdesc_cmd (const char *args, int from_tty)
-{
-  help_list (tdesc_set_cmdlist, "set tdesc ", all_commands, gdb_stdout);
-}
-
-static void
-show_tdesc_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (tdesc_show_cmdlist, from_tty, "");
-}
-
-static void
-unset_tdesc_cmd (const char *args, int from_tty)
-{
-  help_list (tdesc_unset_cmdlist, "unset tdesc ", all_commands, gdb_stdout);
-}
-
 static void
 set_tdesc_filename_cmd (const char *args, int from_tty,
 			struct cmd_list_element *c)
@@ -1831,18 +1813,18 @@  _initialize_target_descriptions ()
 {
   tdesc_data = gdbarch_data_register_pre_init (tdesc_data_init);
 
-  add_prefix_cmd ("tdesc", class_maintenance, set_tdesc_cmd, _("\
+  add_basic_prefix_cmd ("tdesc", class_maintenance, _("\
 Set target description specific variables."),
-		  &tdesc_set_cmdlist, "set tdesc ",
-		  0 /* allow-unknown */, &setlist);
-  add_prefix_cmd ("tdesc", class_maintenance, show_tdesc_cmd, _("\
+			&tdesc_set_cmdlist, "set tdesc ",
+			0 /* allow-unknown */, &setlist);
+  add_show_prefix_cmd ("tdesc", class_maintenance, _("\
 Show target description specific variables."),
-		  &tdesc_show_cmdlist, "show tdesc ",
-		  0 /* allow-unknown */, &showlist);
-  add_prefix_cmd ("tdesc", class_maintenance, unset_tdesc_cmd, _("\
+		       &tdesc_show_cmdlist, "show tdesc ",
+		       0 /* allow-unknown */, &showlist);
+  add_basic_prefix_cmd ("tdesc", class_maintenance, _("\
 Unset target description specific variables."),
-		  &tdesc_unset_cmdlist, "unset tdesc ",
-		  0 /* allow-unknown */, &unsetlist);
+			&tdesc_unset_cmdlist, "unset tdesc ",
+			0 /* allow-unknown */, &unsetlist);
 
   add_setshow_filename_cmd ("filename", class_obscure,
 			    &tdesc_filename_cmd_string,
diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp
index 998bf80abf0..ac7f61ddfbc 100644
--- a/gdb/testsuite/gdb.base/completion.exp
+++ b/gdb/testsuite/gdb.base/completion.exp
@@ -310,7 +310,7 @@  gdb_test_multiple "" "$test" {
     -re "^info $" {
 	send_gdb "\n"
 	gdb_test_multiple "" "$test" {
-	    -re "\"info\" must be followed by the name of an info command\\.\r\nList of info subcommands.*$gdb_prompt $" {
+	    -re "List of info subcommands.*$gdb_prompt $" {
 		pass "$test"
 	    }
 	}
@@ -323,7 +323,7 @@  gdb_test_multiple "" "$test" {
     -re "^info \\\x07$" {
 	send_gdb "\n"
 	gdb_test_multiple "" "$test" {
-	    -re "\"info\" must be followed by the name of an info command\\.\r\nList of info subcommands:\r\n\r\n.*$gdb_prompt $" {
+	    -re "List of info subcommands:\r\n\r\n.*$gdb_prompt $" {
 		pass "$test"
 	    }
 	}
@@ -339,7 +339,7 @@  gdb_test_multiple "" "$test" {
 	    -re "address.*types.*$gdb_prompt " {
 		send_gdb "\n"
 		gdb_test_multiple "" "$test" {
-		    -re "\"info\".*unambiguous\\..*$gdb_prompt $" {
+		    -re "allowed if unambiguous\\..*$gdb_prompt $" {
 			pass "$test"
 		    }
 		}
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index c51ec63eccf..846c91af6bc 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -28,8 +28,8 @@  set timeout 60
 gdb_test "add-symbol-file" "add-symbol-file takes a file name and an address"
 
 # test append
-gdb_test "append" "\"append\" must be followed by a subcommand\.\[\r\n\]+List of append subcommands:.*" 
-gdb_test "append binary" "\"append binary\" must be followed by a subcommand\.\[\r\n\]+List of append binary subcommands:.*" 
+gdb_test "append" "List of append subcommands:.*" 
+gdb_test "append binary" "List of append binary subcommands:.*" 
 gdb_test "append memory" "Missing filename\." 
 gdb_test "append value"  "Missing filename\." 
 gdb_test "append binary memory" "Missing filename\." 
@@ -147,12 +147,12 @@  gdb_test "down" "No stack.*"
 #test down-silently
 gdb_test "down-silently" "No stack."
 # test dump
-gdb_test "dump" "\"dump\" must be followed by a subcommand\.\[\r\n\]+List of dump subcommands:.*" 
-gdb_test "dump binary" "\"dump binary\" must be followed by a subcommand\.\[\r\n\]+List of dump binary subcommands:.*" 
-gdb_test "dump ihex" "\"dump ihex\" must be followed by a subcommand\.\[\r\n\]+List of dump ihex subcommands:.*" 
+gdb_test "dump" "List of dump subcommands:.*" 
+gdb_test "dump binary" "List of dump binary subcommands:.*" 
+gdb_test "dump ihex" "List of dump ihex subcommands:.*" 
 gdb_test "dump memory" "Missing filename\." 
-gdb_test "dump srec" "\"dump srec\" must be followed by a subcommand\.\[\r\n\]+List of dump srec subcommands:.*" 
-gdb_test "dump tekhex" "\"dump tekhex\" must be followed by a subcommand\.\[\r\n\]+List of dump tekhex subcommands:.*" 
+gdb_test "dump srec" "List of dump srec subcommands:.*" 
+gdb_test "dump tekhex" "List of dump tekhex subcommands:.*" 
 gdb_test "dump value" "Missing filename\." 
 gdb_test "dump binary memory" "Missing filename\." 
 gdb_test "dump binary value"  "Missing filename\." 
@@ -253,9 +253,9 @@  gdb_test "help" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- Ali
 #test handle
 gdb_test "handle" "Argument required .signal to handle.*"
 #test info "i" abbreviation 
-gdb_test "i" "\"info\" must be followed by the name of an info command.(\[^\r\n\]*\[\r\n\])+List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info \"i\" abbreviation"
+gdb_test "i" "List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info \"i\" abbreviation"
 #test info
-gdb_test "info" "\"info\" must be followed by the name of an info command.(\[^\r\n\]*\[\r\n\])+List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
+gdb_test "info" "List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
 #test ignore
 gdb_test "ignore" "Argument required .a breakpoint number.*"
 #test info address
@@ -378,7 +378,7 @@  gdb_test "nexti" "The program is not being run."
 gdb_test "output" "Argument required .expression to compute.*"
 
 #test overlay
-gdb_test "overlay" "\"overlay\" must be followed by the name of .*"
+gdb_test "overlay" "List of overlay subcommands:.*"
 #test a non-existant overlay subcommand
 gdb_test "overlay on"     "Undefined overlay command.* Try \"help overlay\"."
 gdb_test_no_output "overlay manual" "overlay manual #1"
@@ -475,7 +475,7 @@  gdb_test_no_output "set args" "set args"
 
 # Test set check abbreviations
 foreach x {"c" "ch" "check"} {
-    gdb_test "set $x" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set strict type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." \
+    gdb_test "set $x" "List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set strict type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." \
 	"set check \"$x\" abbreviation"
 }
 
@@ -505,17 +505,17 @@  gdb_test_no_output "set history save" "set history save"
 #test set history size
 gdb_test "set history size" "Argument required .integer to set it to.*"
 #test set history
-gdb_test "set history" "\"set history\" must be followed by the name of a history subcommand.(\[^\r\n\]*\[\r\n\])+List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
+gdb_test "set history" "List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
 #test set language
 gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, asm, c, c.., d, fortran, go, minimal, modula-2, objective-c, opencl, pascal, rust."
 #test set listsize
 gdb_test "set listsize" "Argument required .integer to set it to.*"
 #test set print "p" abbreviation
-gdb_test "set p" "\"set print\" must be followed by the name of a print subcommand.(\[^\r\n\]*\[\r\n\])+List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"p\" abbreviation"
+gdb_test "set p" "List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"p\" abbreviation"
 #test set print "pr" abbreviation
-gdb_test "set pr" "\"set print\" must be followed by the name of a print subcommand.(\[^\r\n\]*\[\r\n\])+List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"pr\" abbreviation"
+gdb_test "set pr" "List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"pr\" abbreviation"
 #test set print
-gdb_test "set print" "\"set print\" must be followed by the name of a print subcommand.(\[^\r\n\]*\[\r\n\])+List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
+gdb_test "set print" "List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
 #test set print address
 gdb_test_no_output "set print address" "set print address"
 #test set print array
@@ -827,7 +827,7 @@  gdb_test "unset environment" \
     "y"
 
 #test unset
-gdb_test "unset" "\"unset\" must be followed by the name of an unset subcommand.(\[^\r\n\]*\[\r\n\])+List of unset subcommands:(\[^\r\n\]*\[\r\n\])+unset environment -- Cancel environment variable VAR for the program(\[^\r\n\]*\[\r\n\])+Type \"help unset\" followed by unset subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
+gdb_test "unset" "List of unset subcommands:(\[^\r\n\]*\[\r\n\])+unset environment -- Cancel environment variable VAR for the program(\[^\r\n\]*\[\r\n\])+Type \"help unset\" followed by unset subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
 #test up
 #test up-silently
 gdb_test "up-silently" "No stack."
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
index 3431f2c6dc5..00fe8c296cd 100644
--- a/gdb/testsuite/gdb.base/maint.exp
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -487,15 +487,15 @@  gdb_test_multiple "maint info breakpoints" "maint info breakpoints" {
 }
 
 gdb_test "maint print" \
-    "\"maintenance print\" must be followed by the name of a print command\\.\r\nList.*unambiguous\\..*" \
+    "List.*unambiguous\\..*" \
     "maint print w/o args" 
 
 gdb_test "maint info" \
-    "\"maintenance info\" must be followed by the name of an info command\\.\r\nList.*unambiguous\\..*" \
+    "List.*unambiguous\\..*" \
     "maint info w/o args"
 
 gdb_test "maint" \
-    "\"maintenance\" must be followed by the name of a maintenance command\\.\r\nList.*unambiguous\\..*" \
+    "List.*unambiguous\\..*" \
     "maint w/o args"
 
 # Test that "main info line-table" w/o a file name shows the symtab for
diff --git a/gdb/testsuite/gdb.btrace/cpu.exp b/gdb/testsuite/gdb.btrace/cpu.exp
index 23e896d5cfa..a3f7317915b 100644
--- a/gdb/testsuite/gdb.btrace/cpu.exp
+++ b/gdb/testsuite/gdb.btrace/cpu.exp
@@ -42,9 +42,9 @@  proc test_junk { arg junk current } {
 gdb_test "show record btrace cpu" "btrace cpu is 'auto'\." "default cpu"
 
 gdb_test "set record" \
-    "\"set record\" must be followed by an appropriate subcommand.*"
+    "List of set record subcommands.*"
 gdb_test "set record btrace" \
-    "\"set record btrace\" must be followed by an appropriate subcommand.*"
+    "List of set record btrace subcommands.*"
 test_bad "" "auto"
 
 test_good "intel: 0/0"
diff --git a/gdb/testsuite/gdb.cp/maint.exp b/gdb/testsuite/gdb.cp/maint.exp
index df0a143480a..5d0eabe42dc 100644
--- a/gdb/testsuite/gdb.cp/maint.exp
+++ b/gdb/testsuite/gdb.cp/maint.exp
@@ -32,9 +32,9 @@  proc test_help {} {
         "C\\+\\+ maintenance commands.\r\n\r\n"
     }
 
-    set multiple_help_body "List of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- ${first_component_help}\r\nmaintenance cplus namespace -- ${namespace_help}\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
+    set multiple_help_body "List of maintenance cplus subcommands:.*Command name abbreviations are allowed if unambiguous."
 
-    gdb_test "maint cp" "\"maintenance cplus\" must be followed by the name of a command.\r\n.*"
+    gdb_test "maint cp" $multiple_help_body
 
     gdb_test "help maint cp first_component" "${first_component_help}."
     gdb_test "help maint cp namespace" "${namespace_help}."
diff --git a/gdb/top.c b/gdb/top.c
index 8b82bd3c038..9fb9d5cb5c7 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1949,20 +1949,6 @@  set_history_size_command (const char *args,
   set_readline_history_size (history_size_setshow_var);
 }
 
-void
-set_history (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set history\" must be followed "
-		       "by the name of a history subcommand.\n"));
-  help_list (sethistlist, "set history ", all_commands, gdb_stdout);
-}
-
-void
-show_history (const char *args, int from_tty)
-{
-  cmd_show_list (showhistlist, from_tty, "");
-}
-
 bool info_verbose = false;	/* Default verbose msgs off.  */
 
 /* Called by do_set_command.  An elaborate joke.  */
diff --git a/gdb/top.h b/gdb/top.h
index 2147e2d4b48..0cbb244c551 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -288,10 +288,6 @@  extern void gdb_add_history (const char *);
 
 extern void show_commands (const char *args, int from_tty);
 
-extern void set_history (const char *, int);
-
-extern void show_history (const char *, int);
-
 extern void set_verbose (const char *, int, struct cmd_list_element *);
 
 extern char *handle_line_of_input (struct buffer *cmd_line_buffer,
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index 9014889a765..491ce275acb 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -45,7 +45,6 @@ 
 #include "tui/tui-source.h"
 #include "gdb_curses.h"
 
-static void tui_layout_command (const char *, int);
 static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *);
 
 /* The layouts.  */
@@ -1023,14 +1022,6 @@  tui_new_layout_command (const char *spec, int from_tty)
   new_layout.release ();
 }
 
-/* Base command for "layout".  */
-
-static void
-tui_layout_command (const char *layout_name, int from_tty)
-{
-  help_list (layout_list, "layout ", all_commands, gdb_stdout);
-}
-
 /* Function to initialize gdb commands, for tui window layout
    manipulation.  */
 
@@ -1038,10 +1029,10 @@  void _initialize_tui_layout ();
 void
 _initialize_tui_layout ()
 {
-  add_prefix_cmd ("layout", class_tui, tui_layout_command, _("\
+  add_basic_prefix_cmd ("layout", class_tui, _("\
 Change the layout of windows.\n\
 Usage: layout prev | next | LAYOUT-NAME"),
-		  &layout_list, "layout ", 0, &cmdlist);
+			&layout_list, "layout ", 0, &cmdlist);
 
   add_cmd ("next", class_tui, tui_next_layout_command,
 	   _("Apply the next TUI layout."),
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index 7cb4aa9bbd4..6546793d6bd 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -310,21 +310,13 @@  show_tui_cmd (const char *args, int from_tty)
 
 static struct cmd_list_element *tuilist;
 
-static void
-tui_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"tui\" must be followed by the name of a "
-                     "tui command.\n"));
-  help_list (tuilist, "tui ", all_commands, gdb_stdout);
-}
-
 struct cmd_list_element **
 tui_get_cmd_list (void)
 {
   if (tuilist == 0)
-    add_prefix_cmd ("tui", class_tui, tui_command,
-                    _("Text User Interface commands."),
-                    &tuilist, "tui ", 0, &cmdlist);
+    add_basic_prefix_cmd ("tui", class_tui,
+			  _("Text User Interface commands."),
+			  &tuilist, "tui ", 0, &cmdlist);
   return &tuilist;
 }
 
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index e58cd5da289..87da8e3e932 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -715,20 +715,6 @@  struct cmd_list_element *setprinttypelist;
 
 struct cmd_list_element *showprinttypelist;
 
-static void
-set_print_type (const char *arg, int from_tty)
-{
-  printf_unfiltered (
-     "\"set print type\" must be followed by the name of a subcommand.\n");
-  help_list (setprintlist, "set print type ", all_commands, gdb_stdout);
-}
-
-static void
-show_print_type (const char *args, int from_tty)
-{
-  cmd_show_list (showprinttypelist, from_tty, "");
-}
-
 static bool print_methods = true;
 
 static void
@@ -827,12 +813,14 @@  Available FLAGS are:\n\
 Only one level of typedefs is unrolled.  See also \"ptype\"."));
   set_cmd_completer (c, expression_completer);
 
-  add_prefix_cmd ("type", no_class, show_print_type,
-		  _("Generic command for showing type-printing settings."),
-		  &showprinttypelist, "show print type ", 0, &showprintlist);
-  add_prefix_cmd ("type", no_class, set_print_type,
-		  _("Generic command for setting how types print."),
-		  &setprinttypelist, "set print type ", 0, &setprintlist);
+  add_show_prefix_cmd ("type", no_class,
+		       _("Generic command for showing type-printing settings."),
+		       &showprinttypelist, "show print type ", 0,
+		       &showprintlist);
+  add_basic_prefix_cmd ("type", no_class,
+			_("Generic command for setting how types print."),
+			&setprinttypelist, "set print type ", 0,
+			&setprintlist);
 
   add_setshow_boolean_cmd ("methods", no_class, &print_methods,
 			   _("\
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 80b7514b7e3..0be7c6071b7 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -2942,34 +2942,6 @@  show_radix (const char *arg, int from_tty)
 }
 
 
-static void
-set_print (const char *arg, int from_tty)
-{
-  printf_unfiltered (
-     "\"set print\" must be followed by the name of a print subcommand.\n");
-  help_list (setprintlist, "set print ", all_commands, gdb_stdout);
-}
-
-static void
-show_print (const char *args, int from_tty)
-{
-  cmd_show_list (showprintlist, from_tty, "");
-}
-
-static void
-set_print_raw (const char *arg, int from_tty)
-{
-  printf_unfiltered (
-     "\"set print raw\" must be followed by the name of a \"print raw\" subcommand.\n");
-  help_list (setprintrawlist, "set print raw ", all_commands, gdb_stdout);
-}
-
-static void
-show_print_raw (const char *args, int from_tty)
-{
-  cmd_show_list (showprintrawlist, from_tty, "");
-}
-
 /* Controls printing of vtbl's.  */
 static void
 show_vtblprint (struct ui_file *file, int from_tty,
@@ -3161,30 +3133,30 @@  _initialize_valprint ()
 {
   cmd_list_element *cmd;
 
-  add_prefix_cmd ("print", no_class, set_print,
-		  _("Generic command for setting how things print."),
-		  &setprintlist, "set print ", 0, &setlist);
+  add_basic_prefix_cmd ("print", no_class,
+			_("Generic command for setting how things print."),
+			&setprintlist, "set print ", 0, &setlist);
   add_alias_cmd ("p", "print", no_class, 1, &setlist);
   /* Prefer set print to set prompt.  */
   add_alias_cmd ("pr", "print", no_class, 1, &setlist);
 
-  add_prefix_cmd ("print", no_class, show_print,
-		  _("Generic command for showing print settings."),
-		  &showprintlist, "show print ", 0, &showlist);
+  add_show_prefix_cmd ("print", no_class,
+		       _("Generic command for showing print settings."),
+		       &showprintlist, "show print ", 0, &showlist);
   add_alias_cmd ("p", "print", no_class, 1, &showlist);
   add_alias_cmd ("pr", "print", no_class, 1, &showlist);
 
-  cmd = add_prefix_cmd ("raw", no_class, set_print_raw,
-			_("\
+  cmd = add_basic_prefix_cmd ("raw", no_class,
+			      _("\
 Generic command for setting what things to print in \"raw\" mode."),
-			&setprintrawlist, "set print raw ", 0,
-			&setprintlist);
+			      &setprintrawlist, "set print raw ", 0,
+			      &setprintlist);
   deprecate_cmd (cmd, nullptr);
 
-  cmd = add_prefix_cmd ("raw", no_class, show_print_raw,
-			_("Generic command for showing \"print raw\" settings."),
-			&showprintrawlist, "show print raw ", 0,
-			&showprintlist);
+  cmd = add_show_prefix_cmd ("raw", no_class,
+			     _("Generic command for showing \"print raw\" settings."),
+			     &showprintrawlist, "show print raw ", 0,
+			     &showprintlist);
   deprecate_cmd (cmd, nullptr);
 
   gdb::option::add_setshow_cmds_for_options
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index d1894ca0888..c2dbbdd631c 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -602,25 +602,6 @@  show_maint_show_all_tib (struct ui_file *file, int from_tty,
 			    "Thread Information Block is %s.\n"), value);
 }
 
-static void
-info_w32_command (const char *args, int from_tty)
-{
-  help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
-}
-
-static int w32_prefix_command_valid = 0;
-void
-init_w32_command_list (void)
-{
-  if (!w32_prefix_command_valid)
-    {
-      add_prefix_cmd ("w32", class_info, info_w32_command,
-		      _("Print information specific to Win32 debugging."),
-		      &info_w32_cmdlist, "info w32 ", 0, &infolist);
-      w32_prefix_command_valid = 1;
-    }
-}
-
 /* Implementation of `gdbarch_gdb_signal_to_target' for Windows.  */
 
 static int
@@ -1073,7 +1054,10 @@  _initialize_windows_tdep ()
   windows_gdbarch_data_handle
     = gdbarch_data_register_post_init (init_windows_gdbarch_data);
 
-  init_w32_command_list ();
+  add_basic_prefix_cmd ("w32", class_info,
+			_("Print information specific to Win32 debugging."),
+			&info_w32_cmdlist, "info w32 ", 0, &infolist);
+
   add_cmd ("thread-information-block", class_info, display_tib,
 	   _("Display thread information block."),
 	   &info_w32_cmdlist);