[15/24] Introduce rename_cmd

Message ID 20190522205327.2568-16-palves@redhat.com
State New
Headers show
Series
  • gdb::option framework, "print -OPT", other cmd options
Related show

Commit Message

Pedro Alves May 22, 2019, 8:53 p.m.
A following patch will introduce options for the "backtrace" command,
based on some "set print" and "set backtrace" settings.  There's one
setting in particular that is a bit annoying if we want to describe
the backtrace options and the settings commands using the same data
structures:

 "set print raw frame-arguments"

The problem is that space between "raw" and "frame-arguments".

Calling the option

 "bt -raw frame-arguments"

would be odd.  So I'm calling the option

 "bt -raw-frame-arguments"

instead.

IMO, It would be better if the setting was called

 "set print raw-frame-arguments"

instead too, but that ship might have sailed already.

This is the only odd case I found so far, so I'm handling this by
describing the option/setting as "raw-frame-arguments" in the
option_def, and then renaming the set command.

Hence this commit, which includes the new rename_cmd function.  It'll
then be used by the "backtrace" patch.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* cli/cli-decode.c (insert_cmd): New, factored out from ...
	(do_add_cmd): ... this.
	(unlink_cmd): New, factored out from ...
	(delete_cmd): ... this.  Reimplement.
	(rename_cmd): New.
	* command.h (rename_cmd): Declare.
---
 gdb/cli/cli-decode.c | 104 +++++++++++++++++++++++++++++++++++----------------
 gdb/command.h        |   5 +++
 2 files changed, 77 insertions(+), 32 deletions(-)

-- 
2.14.5

Comments

Philippe Waroquiers May 25, 2019, 7:58 p.m. | #1
On Wed, 2019-05-22 at 21:53 +0100, Pedro Alves wrote:

> diff --git a/gdb/command.h b/gdb/command.h

> index 35006cc339e..ed848114b85 100644

> --- a/gdb/command.h

> +++ b/gdb/command.h

> @@ -439,6 +439,11 @@ extern void

>  				       struct cmd_list_element **set_list,

>  				       struct cmd_list_element **show_list);

>  

> +/* Move command OLD_NAME from OLD_LIST to NEW_LIST and rename it from

> +   OLD_NAME to NEW_NAME.  */

> +extern void rename_cmd (const char *old_name, cmd_list_element **old_list,

> +			const char *new_name, cmd_list_element **new_list);

> +

I have some difficulties to understand the idea here.
If the command is moved from one list to another, how is the renamed
command still available via the 'normal' list ?

Effectively, it looks like set/show print raw-frame-arguments commands
are not known.

Why not just keep the old command untouched, and define a new
command via the new framework.

Below is just a patch (based on HEAD) that defines 2 different set/show
changing the same variable:
(gdb) apropos raw form
set print raw frame-arguments -- Set whether to print frame arguments in raw form
set print raw-frame-arguments -- Set whether to print frame arguments in raw form
show print raw frame-arguments -- Show whether to print frame arguments in raw form
show print raw-frame-arguments -- Show whether to print frame arguments in raw form
(gdb) set print raw frame-arguments on
(gdb) show print raw frame-arguments 
Whether to print frame arguments in raw form is on.
(gdb) show print raw-frame-arguments 
Whether to print frame arguments in raw form is on.
(gdb) set print raw-frame-arguments off
(gdb) show print raw frame-arguments
Whether to print frame arguments in raw form is off.
(gdb) show print raw-frame-arguments 
Whether to print frame arguments in raw form is off.
(gdb) 

I guess this should still work if the same variable is changed via
the new framework and/or via add_setshow_boolean_cmd.
The old commands might be marked as obsolete.

Philippe

diff --git a/gdb/stack.c b/gdb/stack.c
index 408c795e38..05b11e6ecb 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -3106,6 +3106,16 @@ Usage: func NAME"));
                        _("Show printing of non-scalar frame arguments"),
                        NULL, NULL, NULL, &setprintlist, &showprintlist);
 
+
+  add_setshow_boolean_cmd ("raw-frame-arguments", no_class,
+                          &print_raw_frame_arguments, _("\
+Set whether to print frame arguments in raw form."), _("\
+Show whether to print frame arguments in raw form."), _("\
+If set, frame arguments are printed in raw form, bypassing any\n\
+pretty-printers for that value."),
+                          NULL, NULL,
+                          &setprintlist, &showprintlist);
+
   add_setshow_boolean_cmd ("frame-arguments", no_class,
                           &print_raw_frame_arguments, _("\
 Set whether to print frame arguments in raw form."), _("\
Pedro Alves May 29, 2019, 4:03 p.m. | #2
On 5/25/19 8:58 PM, Philippe Waroquiers wrote:
> On Wed, 2019-05-22 at 21:53 +0100, Pedro Alves wrote:

> 

>> diff --git a/gdb/command.h b/gdb/command.h

>> index 35006cc339e..ed848114b85 100644

>> --- a/gdb/command.h

>> +++ b/gdb/command.h

>> @@ -439,6 +439,11 @@ extern void

>>  				       struct cmd_list_element **set_list,

>>  				       struct cmd_list_element **show_list);

>>  

>> +/* Move command OLD_NAME from OLD_LIST to NEW_LIST and rename it from

>> +   OLD_NAME to NEW_NAME.  */

>> +extern void rename_cmd (const char *old_name, cmd_list_element **old_list,

>> +			const char *new_name, cmd_list_element **new_list);

>> +

> I have some difficulties to understand the idea here.

> If the command is moved from one list to another, how is the renamed

> command still available via the 'normal' list ?


So the existing command is called 

 "set print raw frame-arguments"

I think "set print raw-frame-arguments" would have been
a better command name, but since that command already exists with
that spelling since gdb 7.7, and I didn't have a huge reason to
change it, in the end I opted to leave it as it was.

With that decision, the next problem is, how to implement both the
option and the set command without duplicating the help bits.
So what I did was, define the option like this:

 +  boolean_option_def {
 +    "raw-frame-arguments",
 +    [] (frame_print_options *opt) { return &opt->print_raw_frame_arguments; },
 +    NULL, /* show_cmd_cb */
 +    N_("Set whether to print frame arguments in raw form."),
 +    N_("Show whether to print frame arguments in raw form."),
 +    N_("If set, frame arguments are printed in raw form, bypassing any\n\
 +pretty-printers for that value.")
 +  },

and then let:

 +  gdb::option::add_setshow_cmds_for_options
 +    (class_stack, &user_frame_print_options,
 +     frame_print_option_defs, &setprintlist, &showprintlist);
 +

create the "set print raw-frame-arguments" command from the option definition
shown above.

And now that's where the renaming takes place, with:

+  /* The above installs a "set print raw-frame-arguments" command,
+     because there's an option called "print -raw-frame-arguments".
+     Rename the command to "set print raw frame-arguments" (space
+     instead of dash), to keep backward compatibility -- the "raw
+     frame-arguments" command already existed when print options were
+     first added.  */
+  rename_cmd ("raw-frame-arguments", &setprintlist,
+             "frame-arguments", &setprintrawlist);
+  rename_cmd ("raw-frame-arguments", &showprintlist,
+             "frame-arguments", &showprintrawlist);


There are other ways to implement this.  I could move the
"raw-frame-arguments" option_def out of the frame_print_option_defs
array, so that it doesn't get installed as a command, and leave the
"set print raw frame-arguments" add_setshow... call in place.
I guess it wouldn't be a big deal.

> 

> Effectively, it looks like set/show print raw-frame-arguments commands

> are not known.


Yes, that was the intention.

> 

> Why not just keep the old command untouched, and define a new

> command via the new framework.

> 


It didn't seem worth it to me.

> Below is just a patch (based on HEAD) that defines 2 different set/show

> changing the same variable:

> (gdb) apropos raw form

> set print raw frame-arguments -- Set whether to print frame arguments in raw form

> set print raw-frame-arguments -- Set whether to print frame arguments in raw form

> show print raw frame-arguments -- Show whether to print frame arguments in raw form

> show print raw-frame-arguments -- Show whether to print frame arguments in raw form

> (gdb) set print raw frame-arguments on

> (gdb) show print raw frame-arguments 

> Whether to print frame arguments in raw form is on.

> (gdb) show print raw-frame-arguments 

> Whether to print frame arguments in raw form is on.

> (gdb) set print raw-frame-arguments off

> (gdb) show print raw frame-arguments

> Whether to print frame arguments in raw form is off.

> (gdb) show print raw-frame-arguments 

> Whether to print frame arguments in raw form is off.

> (gdb) 

> 

> I guess this should still work if the same variable is changed via

> the new framework and/or via add_setshow_boolean_cmd.


TBC, the new framework does not change how the set
commands work at all.  The integration that exists is that
the new gdb::option::add_setshow_cmds_for_options function
goes over the option definitions and calls add_setshow_xxx_cmd
for each option.  The option_def structure has some fields that
only exists for this, such as the show_doc, and the show_cmd_cb.
That was all done as a way to conveniently describe the help
bits for both the options and the commands in a single place.

> The old commands might be marked as obsolete.


Yes, if we add a "raw-frame-arguments", we should deprecate
"raw frame-arguments" so that TAB completion doesn't
suggest the latter, which would get in the way
of "set print raw[TAB]".

I actually tried doing that, and I don't recall the details,
but it didn't seem that easy, because there's more
than one command involved -- "raw" is a command, and then
"frame-arguments" is a subcommand.  I think it was at that
point that I had decided to just leave it as it was.

With the info above, any preference on how to proceed?

Thanks,
Pedro Alves
Pedro Alves May 29, 2019, 6:30 p.m. | #3
On 5/29/19 5:03 PM, Pedro Alves wrote:

> There are other ways to implement this.  I could move the

> "raw-frame-arguments" option_def out of the frame_print_option_defs

> array, so that it doesn't get installed as a command, and leave the

> "set print raw frame-arguments" add_setshow... call in place.

> I guess it wouldn't be a big deal.


So turns out the change would be pretty simple.

I'm undecided which version to use...  I suppose this version
is simpler and a little bit more efficient.  Preferences?

From fcbbc6a33276a8ec59425174f6868379d0a239a3 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>

Date: Wed, 29 May 2019 19:04:05 +0100
Subject: [PATCH] no-rename

---
 gdb/stack.c | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/gdb/stack.c b/gdb/stack.c
index 3054c797c74..2c58b0d728b 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -126,16 +126,16 @@ or both.  Note that one or both of these values may be <optimized out>."),
     N_("Show printing of non-scalar frame arguments"),
     NULL /* help_doc */
   },
+};
 
-  boolean_option_def {
-    "raw-frame-arguments",
-    [] (frame_print_options *opt) { return &opt->print_raw_frame_arguments; },
-    NULL, /* show_cmd_cb */
-    N_("Set whether to print frame arguments in raw form."),
-    N_("Show whether to print frame arguments in raw form."),
-    N_("If set, frame arguments are printed in raw form, bypassing any\n\
-pretty-printers for that value.")
-  },
+/* The "raw-frame-arguments" option.  Defined separately because the
+   corresponding "set" command is called "set print raw
+   frame-arguments", with space instead of dash.  */
+static const boolean_option_def raw_frame_arguments_option_def {
+  "raw-frame-arguments",
+  [] (frame_print_options *opt) { return &opt->print_raw_frame_arguments; },
+  NULL, /* show_cmd_cb */
+  N_("Set whether to print frame arguments in raw form."),
 };
 
 /* Options for the "backtrace" command.  */
@@ -2015,13 +2015,14 @@ backtrace_command_1 (const frame_print_options &fp_opts,
 /* Create an option_def_group array grouping all the "backtrace"
    options, with FP_OPTS, BT_CMD_OPT, SET_BT_OPTS as contexts.  */
 
-static inline std::array<gdb::option::option_def_group, 3>
+static inline std::array<gdb::option::option_def_group, 4>
 make_backtrace_options_def_group (frame_print_options *fp_opts,
 				  backtrace_cmd_options *bt_cmd_opts,
 				  set_backtrace_options *set_bt_opts)
 {
   return {{
     { {frame_print_option_defs}, fp_opts },
+    { raw_frame_arguments_option_def.def (), fp_opts },
     { {set_backtrace_option_defs}, set_bt_opts },
     { {backtrace_command_option_defs}, bt_cmd_opts }
   }};
@@ -3288,14 +3289,17 @@ source line."),
     (class_stack, &user_frame_print_options,
      frame_print_option_defs, &setprintlist, &showprintlist);
 
-  /* The above installs a "set print raw-frame-arguments" command,
-     because there's an option called "print -raw-frame-arguments".
-     Rename the command to "set print raw frame-arguments" (space
-     instead of dash), to keep backward compatibility -- the "raw
-     frame-arguments" command already existed when print options were
-     first added.  */
-  rename_cmd ("raw-frame-arguments", &setprintlist,
-	      "frame-arguments", &setprintrawlist);
-  rename_cmd ("raw-frame-arguments", &showprintlist,
-	      "frame-arguments", &showprintrawlist);
+  /* This one is not defined by the add_setshow_cmds_for_options call
+     above, because the option is called "raw-frame-arguments", while
+     the command is called "set print raw frame-arguments", with space
+     instead of dash.  */
+  add_setshow_boolean_cmd ("frame-arguments", no_class,
+			   &user_frame_print_options.print_raw_frame_arguments,
+			   _("\
+Set whether to print frame arguments in raw form."), _("\
+Show whether to print frame arguments in raw form."), _("\
+If set, frame arguments are printed in raw form, bypassing any\n\
+pretty-printers for that value."),
+			   NULL, NULL,
+			   &setprintrawlist, &showprintrawlist);
 }
-- 
2.14.5
Philippe Waroquiers May 30, 2019, 10:22 a.m. | #4
On Wed, 2019-05-29 at 19:30 +0100, Pedro Alves wrote:
> On 5/29/19 5:03 PM, Pedro Alves wrote:

> 

> > There are other ways to implement this.  I could move the

> > "raw-frame-arguments" option_def out of the frame_print_option_defs

> > array, so that it doesn't get installed as a command, and leave the

> > "set print raw frame-arguments" add_setshow... call in place.

> > I guess it wouldn't be a big deal.

> 

> So turns out the change would be pretty simple.

> 

> I'm undecided which version to use...  I suppose this version

> is simpler and a little bit more efficient.  Preferences?


As 'frame-arguments' is the only command that uses the prefix 'set print raw'
and that this prefix should not be used for further options, I would mark
'set print raw' obsolete, to avoid an inconsistency (at user level)
only for this option.
But not a big deal ...

> 

> From fcbbc6a33276a8ec59425174f6868379d0a239a3 Mon Sep 17 00:00:00 2001

> From: Pedro Alves <palves@redhat.com>

> Date: Wed, 29 May 2019 19:04:05 +0100

> Subject: [PATCH] no-rename

> 

> ---

>  gdb/stack.c | 44 ++++++++++++++++++++++++--------------------

>  1 file changed, 24 insertions(+), 20 deletions(-)

> 

> diff --git a/gdb/stack.c b/gdb/stack.c

> index 3054c797c74..2c58b0d728b 100644

> --- a/gdb/stack.c

> +++ b/gdb/stack.c

> @@ -126,16 +126,16 @@ or both.  Note that one or both of these values may be <optimized out>."),

>      N_("Show printing of non-scalar frame arguments"),

>      NULL /* help_doc */

>    },

> +};

>  

> -  boolean_option_def {

> -    "raw-frame-arguments",

> -    [] (frame_print_options *opt) { return &opt->print_raw_frame_arguments; },

> -    NULL, /* show_cmd_cb */

> -    N_("Set whether to print frame arguments in raw form."),

> -    N_("Show whether to print frame arguments in raw form."),

> -    N_("If set, frame arguments are printed in raw form, bypassing any\n\

> -pretty-printers for that value.")

> -  },

> +/* The "raw-frame-arguments" option.  Defined separately because the

> +   corresponding "set" command is called "set print raw

> +   frame-arguments", with space instead of dash.  */

> +static const boolean_option_def raw_frame_arguments_option_def {

> +  "raw-frame-arguments",

> +  [] (frame_print_options *opt) { return &opt->print_raw_frame_arguments; },

> +  NULL, /* show_cmd_cb */

> +  N_("Set whether to print frame arguments in raw form."),

>  };

>  

>  /* Options for the "backtrace" command.  */

> @@ -2015,13 +2015,14 @@ backtrace_command_1 (const frame_print_options &fp_opts,

>  /* Create an option_def_group array grouping all the "backtrace"

>     options, with FP_OPTS, BT_CMD_OPT, SET_BT_OPTS as contexts.  */

>  

> -static inline std::array<gdb::option::option_def_group, 3>

> +static inline std::array<gdb::option::option_def_group, 4>

>  make_backtrace_options_def_group (frame_print_options *fp_opts,

>  				  backtrace_cmd_options *bt_cmd_opts,

>  				  set_backtrace_options *set_bt_opts)

>  {

>    return {{

>      { {frame_print_option_defs}, fp_opts },

> +    { raw_frame_arguments_option_def.def (), fp_opts },

>      { {set_backtrace_option_defs}, set_bt_opts },

>      { {backtrace_command_option_defs}, bt_cmd_opts }

>    }};

> @@ -3288,14 +3289,17 @@ source line."),

>      (class_stack, &user_frame_print_options,

>       frame_print_option_defs, &setprintlist, &showprintlist);

>  

> -  /* The above installs a "set print raw-frame-arguments" command,

> -     because there's an option called "print -raw-frame-arguments".

> -     Rename the command to "set print raw frame-arguments" (space

> -     instead of dash), to keep backward compatibility -- the "raw

> -     frame-arguments" command already existed when print options were

> -     first added.  */

> -  rename_cmd ("raw-frame-arguments", &setprintlist,

> -	      "frame-arguments", &setprintrawlist);

> -  rename_cmd ("raw-frame-arguments", &showprintlist,

> -	      "frame-arguments", &showprintrawlist);

> +  /* This one is not defined by the add_setshow_cmds_for_options call

> +     above, because the option is called "raw-frame-arguments", while

> +     the command is called "set print raw frame-arguments", with space

> +     instead of dash.  */

> +  add_setshow_boolean_cmd ("frame-arguments", no_class,

> +			   &user_frame_print_options.print_raw_frame_arguments,

> +			   _("\

> +Set whether to print frame arguments in raw form."), _("\

> +Show whether to print frame arguments in raw form."), _("\

> +If set, frame arguments are printed in raw form, bypassing any\n\

> +pretty-printers for that value."),

> +			   NULL, NULL,

> +			   &setprintrawlist, &showprintrawlist);

>  }
Pedro Alves May 30, 2019, 8:01 p.m. | #5
On 5/30/19 11:22 AM, Philippe Waroquiers wrote:
> On Wed, 2019-05-29 at 19:30 +0100, Pedro Alves wrote:

>> On 5/29/19 5:03 PM, Pedro Alves wrote:

>>

>>> There are other ways to implement this.  I could move the

>>> "raw-frame-arguments" option_def out of the frame_print_option_defs

>>> array, so that it doesn't get installed as a command, and leave the

>>> "set print raw frame-arguments" add_setshow... call in place.

>>> I guess it wouldn't be a big deal.

>>

>> So turns out the change would be pretty simple.

>>

>> I'm undecided which version to use...  I suppose this version

>> is simpler and a little bit more efficient.  Preferences?

> 

> As 'frame-arguments' is the only command that uses the prefix 'set print raw'

> and that this prefix should not be used for further options, I would mark

> 'set print raw' obsolete, to avoid an inconsistency (at user level)

> only for this option.

> But not a big deal ...


Alright, you've convinced me.  And it turned out to be quite simple.
I don't remember exactly what problems I had run into the first time...

I've now posted a v2 of the series, 
https://sourceware.org/ml/gdb-patches/2019-05/msg00712.html

Of course I forgot to mention that I pushed it to
users/palves/cli-options-v2...  

I've kept the v1 branch around for now, if someone wants to
compare, renamed to users/palves/cli-options-v1.

Thanks,
Pedro Alves

Patch

diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index be38d9b287a..1a6bea41480 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -171,6 +171,27 @@  set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
   cmd->completer_handle_brkchars = func;
 }
 
+
+/* Insert element C in LIST.  */
+
+static void
+insert_cmd (cmd_list_element *c, cmd_list_element **list)
+{
+  if (*list == NULL || strcmp ((*list)->name, c->name) >= 0)
+    {
+      c->next = *list;
+      *list = c;
+    }
+  else
+    {
+      cmd_list_element *p = *list;
+      while (p->next && strcmp (p->next->name, c->name) <= 0)
+	p = p->next;
+      c->next = p->next;
+      p->next = c;
+    }
+}
+
 /* Add element named NAME.
    Space for NAME and DOC must be allocated by the caller.
    CLASS is the top level category into which commands are broken down
@@ -195,13 +216,12 @@  do_add_cmd (const char *name, enum command_class theclass,
 {
   struct cmd_list_element *c = new struct cmd_list_element (name, theclass,
 							    doc);
-  struct cmd_list_element *p, *iter;
 
   /* Turn each alias of the old command into an alias of the new
      command.  */
   c->aliases = delete_cmd (name, list, &c->hook_pre, &c->hookee_pre,
 			   &c->hook_post, &c->hookee_post);
-  for (iter = c->aliases; iter; iter = iter->alias_chain)
+  for (cmd_list_element *iter = c->aliases; iter; iter = iter->alias_chain)
     iter->cmd_pointer = c;
   if (c->hook_pre)
     c->hook_pre->hookee_pre = c;
@@ -212,22 +232,7 @@  do_add_cmd (const char *name, enum command_class theclass,
   if (c->hookee_post)
     c->hookee_post->hook_post = c;
 
-  if (*list == NULL || strcmp ((*list)->name, name) >= 0)
-    {
-      c->next = *list;
-      *list = c;
-    }
-  else
-    {
-      p = *list;
-      while (p->next && strcmp (p->next->name, name) <= 0)
-	{
-	  p = p->next;
-	}
-      c->next = p->next;
-      p->next = c;
-    }
-
+  insert_cmd (c, list);
   return c;
 }
 
@@ -851,15 +856,13 @@  add_setshow_zuinteger_cmd (const char *name, enum command_class theclass,
   set_cmd_completer (show, nullptr);
 }
 
-/* Remove the command named NAME from the command list.  Return the
-   list commands which were aliased to the deleted command.  If the
-   command had no aliases, return NULL.  The various *HOOKs are set to
-   the pre- and post-hook commands for the deleted command.  If the
-   command does not have a hook, the corresponding out parameter is
-   set to NULL.  */
+/* Remove the command named NAME from the command list, and return it.
+   The various *HOOKs are set to the pre- and post-hook commands for
+   the removed command.  If the command does not have a hook, the
+   corresponding out parameter is set to NULL.  */
 
-static struct cmd_list_element *
-delete_cmd (const char *name, struct cmd_list_element **list,
+static cmd_list_element *
+unlink_cmd (const char *name, struct cmd_list_element **list,
 	    struct cmd_list_element **prehook,
 	    struct cmd_list_element **prehookee,
 	    struct cmd_list_element **posthook,
@@ -867,7 +870,6 @@  delete_cmd (const char *name, struct cmd_list_element **list,
 {
   struct cmd_list_element *iter;
   struct cmd_list_element **previous_chain_ptr;
-  struct cmd_list_element *aliases = NULL;
 
   *prehook = NULL;
   *prehookee = NULL;
@@ -893,8 +895,6 @@  delete_cmd (const char *name, struct cmd_list_element **list,
 	  /* Update the link.  */
 	  *previous_chain_ptr = iter->next;
 
-	  aliases = iter->aliases;
-
 	  /* If this command was an alias, remove it from the list of
 	     aliases.  */
 	  if (iter->cmd_pointer)
@@ -910,17 +910,57 @@  delete_cmd (const char *name, struct cmd_list_element **list,
 	      *prevp = iter->alias_chain;
 	    }
 
-	  delete iter;
-
 	  /* We won't see another command with the same name.  */
-	  break;
+	  return iter;
 	}
       else
 	previous_chain_ptr = &iter->next;
     }
 
+  return nullptr;
+}
+
+/* Remove the command named NAME from the command list and delete it.
+   Return the list commands which were aliased to the deleted command.
+   If the command had no aliases, return NULL.  The various *HOOKs are
+   set to the pre- and post-hook commands for the deleted command.  If
+   the command does not have a hook, the corresponding out parameter
+   is set to NULL.  */
+
+static cmd_list_element *
+delete_cmd (const char *name, cmd_list_element **list,
+	    cmd_list_element **prehook,
+	    cmd_list_element **prehookee,
+	    cmd_list_element **posthook,
+	    cmd_list_element **posthookee)
+{
+  cmd_list_element *cmd = unlink_cmd (name, list,
+				      prehook, prehookee,
+				      posthook, posthookee);
+  if (cmd == nullptr)
+    return nullptr;
+
+  cmd_list_element *aliases = cmd->aliases;
+  delete cmd;
   return aliases;
 }
+
+/* See command.h.  */
+
+void
+rename_cmd (const char *old_name, cmd_list_element **old_list,
+	    const char *new_name, cmd_list_element **new_list)
+{
+  cmd_list_element *prehook, *prehookee, *posthook, *posthookee;
+  cmd_list_element *c = unlink_cmd (old_name, old_list,
+				    &prehook, &prehookee,
+				    &posthook, &posthookee);
+
+  c->name = new_name;
+  insert_cmd (c, new_list);
+  set_cmd_prefix (c, new_list);
+}
+
 
 /* Shorthands to the commands above.  */
 
diff --git a/gdb/command.h b/gdb/command.h
index 35006cc339e..ed848114b85 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -439,6 +439,11 @@  extern void
 				       struct cmd_list_element **set_list,
 				       struct cmd_list_element **show_list);
 
+/* Move command OLD_NAME from OLD_LIST to NEW_LIST and rename it from
+   OLD_NAME to NEW_NAME.  */
+extern void rename_cmd (const char *old_name, cmd_list_element **old_list,
+			const char *new_name, cmd_list_element **new_list);
+
 /* Do a "show" command for each thing on a command list.  */
 
 extern void cmd_show_list (struct cmd_list_element *, int, const char *);