* [RFA, doc RFA] Add gdb.add_command_alias
@ 2011-09-09 19:25 Doug Evans
2011-09-09 21:15 ` Eli Zaretskii
0 siblings, 1 reply; 14+ messages in thread
From: Doug Evans @ 2011-09-09 19:25 UTC (permalink / raw)
To: gdb-patches
Hi.
Per discussion on IRC, here is a patch to add support for adding
command aliases.
Ok to check in?
valid_cmd_name_p is more restrictive than it could be.
E.g. gdb allows a user-defined command named "42", but
"it's easier to relax restrictions than it is to impose them after the fact",
so I'm going with this.
2011-09-09 Doug Evans <dje@google.com>
Add support for adding command aliases from python.
* NEWS: Mention gdb.add_command_alias.
* command.h (valid_cmd_name_p): Declare.
* cli/cli-decode.c (valid_cmd_name_p): New function.
* python/py-cmd.c (gdbpy_add_com_alias): New function.
* python/python-internal.h (gdbpy_add_com_alias): Declare.
* python/python.c (GdbMethods): Add add_command_alias.
doc/
* gdb.texinfo (Commands In Python): Document add_command_alias.
testsuite/
* gdb.python/py-cmd.exp: Add tests for gdb.add_command_alias.
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.452
diff -u -p -r1.452 NEWS
--- NEWS 4 Sep 2011 17:48:51 -0000 1.452
+++ NEWS 9 Sep 2011 18:07:50 -0000
@@ -38,6 +38,8 @@
** Symbols now provide the "type" attribute, the type of the symbol.
+ ** Command aliases can now be defined with the add_command_alias function.
+
* libthread-db-search-path now supports two special values: $sdir and $pdir.
$sdir specifies the default system locations of shared libraries.
$pdir specifies the directory where the libpthread used by the application
Index: command.h
===================================================================
RCS file: /cvs/src/src/gdb/command.h,v
retrieving revision 1.74
diff -u -p -r1.74 command.h
--- command.h 14 Feb 2011 23:41:33 -0000 1.74
+++ command.h 9 Sep 2011 18:07:50 -0000
@@ -106,6 +106,8 @@ struct cmd_list_element;
/* Forward-declarations of the entry-points of cli/cli-decode.c. */
+extern int valid_cmd_name_p (const char *name);
+
extern struct cmd_list_element *add_cmd (char *, enum command_class,
void (*fun) (char *, int), char *,
struct cmd_list_element **);
Index: cli/cli-decode.c
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-decode.c,v
retrieving revision 1.97
diff -u -p -r1.97 cli-decode.c
--- cli/cli-decode.c 8 Sep 2011 17:20:43 -0000 1.97
+++ cli/cli-decode.c 9 Sep 2011 18:07:50 -0000
@@ -126,6 +126,38 @@ set_cmd_completer (struct cmd_list_eleme
cmd->completer = completer; /* Ok. */
}
+/* Return TRUE if NAME is a valid command name.
+
+ NOTE: TUI has a few special commands, +, <, >.
+ We don't watch for those here. */
+
+int
+valid_cmd_name_p (const char *name)
+{
+ const char *p;
+
+ /* First character must be a letter, -, or _. */
+ if (*name == '\0')
+ return FALSE;
+ if (isalpha (*name)
+ || *name == '-'
+ || *name == '_')
+ ; /* Ok. */
+ else
+ return FALSE;
+
+ for (p = name + 1; *p != '\0'; ++p)
+ {
+ if (isalnum (*p)
+ || *p == '-'
+ || *p == '_')
+ ; /* Ok. */
+ else
+ return FALSE;
+ }
+
+ return TRUE;
+}
/* Add element named NAME.
Space for NAME and DOC must be allocated by the caller.
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.858
diff -u -p -r1.858 gdb.texinfo
--- doc/gdb.texinfo 4 Sep 2011 17:08:56 -0000 1.858
+++ doc/gdb.texinfo 9 Sep 2011 18:07:51 -0000
@@ -22668,6 +22668,35 @@ registration of the command with @value{
Python code is read into @value{GDBN}, you may need to import the
@code{gdb} module explicitly.
+@findex gdb.add_command_alias
+@defun add_command_alias name aliased_name command_class abbrev_flag
+Command aliases can be defined with the @code{gdb.add_command_alias} function.
+This is useful, for example, when you want to be able to type a command
+with a long name using fewer characters, and the contraction is otherwise
+ambiguous. It can also we used when you want to give a command an alternate
+spelling.
+
+@var{name} is the name of the new command.
+@var{aliased_name} is the name of the command that is being aliased.
+Command names must begin with a letter, dash or underscore,
+and must consist of letters, numbers, dashes and underscores.
+
+@var{command_class} should be one of the @samp{COMMAND_} constants.
+
+@var{abbrev_flag} is a boolean flag specifying whether to treat the alias
+as an abbreviation of the original command or not.
+If the alias is an abbreviation it will not appear in @code{help}
+command list output.
+
+Here is an example where we make @code{e} an alternate spelling of the
+@code{x} command.
+
+@smallexample
+(gdb) python gdb.add_command_alias ("e", "x", gdb.COMMAND_DATA, 0)
+(gdb) e/10i main
+@end smallexample
+@end defun
+
@node Parameters In Python
@subsubsection Parameters In Python
Index: python/py-cmd.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-cmd.c,v
retrieving revision 1.16
diff -u -p -r1.16 py-cmd.c
--- python/py-cmd.c 8 Sep 2011 19:51:27 -0000 1.16
+++ python/py-cmd.c 9 Sep 2011 18:07:51 -0000
@@ -698,3 +698,34 @@ gdbpy_string_to_argv (PyObject *self, Py
return py_argv;
}
+
+\f
+
+/* Wrapper around add_com_alias. */
+
+PyObject *
+gdbpy_add_com_alias (PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *keywords[] = {
+ "name", "aliased_name", "command_class", "abbrev_flag", NULL
+ };
+ char *name, *aliased_name;
+ int command_class, abbrev_flag;
+
+ if (! PyArg_ParseTupleAndKeywords (args, kw, "ssii", keywords,
+ &name, &aliased_name,
+ &command_class, &abbrev_flag))
+ return NULL;
+
+ if (! valid_cmd_name_p (name))
+ return PyErr_Format (PyExc_RuntimeError,
+ _("Invalid command name `%s'."), name);
+ if (! valid_cmd_name_p (aliased_name))
+ return PyErr_Format (PyExc_RuntimeError,
+ _("Invalid aliased command name `%s'."), aliased_name);
+
+ /* add_cmd requires *we* allocate space for name, hence the xstrdup. */
+ add_com_alias (xstrdup (name), aliased_name, command_class, abbrev_flag);
+
+ Py_RETURN_NONE;
+}
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.47
diff -u -p -r1.47 python-internal.h
--- python/python-internal.h 8 Sep 2011 19:51:27 -0000 1.47
+++ python/python-internal.h 9 Sep 2011 18:07:52 -0000
@@ -152,6 +152,7 @@ PyObject *gdbpy_create_lazy_string_objec
PyObject *gdbpy_inferiors (PyObject *unused, PyObject *unused2);
PyObject *gdbpy_selected_thread (PyObject *self, PyObject *args);
PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args);
+PyObject *gdbpy_add_com_alias (PyObject *self, PyObject *args, PyObject *kw);
PyObject *gdbpy_parameter (PyObject *self, PyObject *args);
PyObject *gdbpy_parameter_value (enum var_types type, void *var);
char *gdbpy_parse_command_name (const char *name,
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.71
diff -u -p -r1.71 python.c
--- python/python.c 6 Sep 2011 14:49:00 -0000 1.71
+++ python/python.c 9 Sep 2011 18:07:52 -0000
@@ -1426,6 +1426,10 @@ Return the selected thread object." },
{ "inferiors", gdbpy_inferiors, METH_NOARGS,
"inferiors () -> (gdb.Inferior, ...).\n\
Return a tuple containing all inferiors." },
+ { "add_command_alias", (PyCFunction)gdbpy_add_com_alias,
+ METH_VARARGS | METH_KEYWORDS,
+ "Add an alias for an existing command." },
+
{NULL, NULL, 0, NULL}
};
Index: testsuite/gdb.python/py-cmd.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-cmd.exp,v
retrieving revision 1.6
diff -u -p -r1.6 py-cmd.exp
--- testsuite/gdb.python/py-cmd.exp 10 Jan 2011 11:00:23 -0000 1.6
+++ testsuite/gdb.python/py-cmd.exp 9 Sep 2011 18:07:52 -0000
@@ -45,6 +45,20 @@ gdb_py_test_multiple "input simple comma
gdb_test "test_cmd ugh" "test_cmd output, arg = ugh" "call simple command"
+# Test an alias command.
+
+gdb_test_no_output "python gdb.add_command_alias (\"test_alias_cmd\", \"test_cmd\", gdb.COMMAND_OBSCURE, 0)" "add_command_alias"
+
+gdb_test "test_alias_cmd ugh" "test_cmd output, arg = ugh" "call alias command"
+
+gdb_test "python gdb.add_command_alias (\"(bad name)\", \"test_cmd\", gdb.COMMAND_OBSCURE, 0)" \
+ "RuntimeError: Invalid command name.*" \
+ "bad alias command name"
+
+gdb_test "python gdb.add_command_alias (\"test_alias_cmd\", \"(bad name)\", gdb.COMMAND_OBSCURE, 0)" \
+ "RuntimeError: Invalid aliased command name.*" \
+ "bad aliased command name"
+
# Test a prefix command, and a subcommand within it.
gdb_py_test_multiple "input prefix command" \
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-09 19:25 [RFA, doc RFA] Add gdb.add_command_alias Doug Evans @ 2011-09-09 21:15 ` Eli Zaretskii 2011-09-13 17:40 ` Doug Evans 0 siblings, 1 reply; 14+ messages in thread From: Eli Zaretskii @ 2011-09-09 21:15 UTC (permalink / raw) To: Doug Evans; +Cc: gdb-patches > Date: Fri, 9 Sep 2011 11:36:36 -0700 (PDT) > From: dje@google.com (Doug Evans) > > Per discussion on IRC, here is a patch to add support for adding > command aliases. I wish people would discuss such issues here, not on IRC. These discussions should be recorded, for one thing. Me, I don't understand the need for this feature, especially not why it should be a Python-only feature. Moreover, why do we need to have this, when one can easily write a command that just calls an existing one, to have the same effect. > valid_cmd_name_p is more restrictive than it could be. > E.g. gdb allows a user-defined command named "42", but > "it's easier to relax restrictions than it is to impose them after the fact", > so I'm going with this. Sorry, I don't understand what this is about. I guess that was again discussed "on IRC" or wherever. > + NOTE: TUI has a few special commands, +, <, >. > + We don't watch for those here. */ Why not? And what does that mean in terms of user expectations? > +This is useful, for example, when you want to be able to type a command > +with a long name using fewer characters, and the contraction is otherwise > +ambiguous. It can also we used when you want to give a command an alternate ^^ "be" > +@var{name} is the name of the new command. > [..] > +Command names must begin with a letter, dash or underscore, > +and must consist of letters, numbers, dashes and underscores. @var{name} is the name of the new command; it must begin with a letter, dash or underscore, and must consist of letters, numbers, dashes and underscores. > +@var{command_class} should be one of the @samp{COMMAND_} constants. Please add here a cross-reference to where these constants are documented. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-09 21:15 ` Eli Zaretskii @ 2011-09-13 17:40 ` Doug Evans 2011-09-13 17:47 ` Pedro Alves 2011-09-13 18:49 ` Pedro Alves 0 siblings, 2 replies; 14+ messages in thread From: Doug Evans @ 2011-09-13 17:40 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 7802 bytes --] On Fri, Sep 9, 2011 at 2:13 PM, Eli Zaretskii <eliz@gnu.org> wrote: >> Date: Fri, 9 Sep 2011 11:36:36 -0700 (PDT) >> From: dje@google.com (Doug Evans) >> >> Per discussion on IRC, here is a patch to add support for adding >> command aliases. > > I wish people would discuss such issues here, not on IRC. These > discussions should be recorded, for one thing. Whatever additional discussion one wants to have we can have here. No worries. > Me, I don't understand the need for this feature, especially not why > it should be a Python-only feature. Moreover, why do we need to have > this, when one can easily write a command that just calls an existing > one, to have the same effect. Conversely, why does gdb have cli-decode.c:add_com_alias? IOW, it's more than just writing a command that just calls an existing one. Python is our extension language and we want to, for example, allow users to add new functionality to gdb that is on par with gdb's own internal functionality. In the case of gdb commands, take for example the "run" and "print" commands. There are alias commands of these ("r" and "p") for good reasons. This patch extends this capability to commands created in python. [For completeness sake, There is still a capability that internal gdb commands have that python commands don't: one can add an alias for more than just simple commands. E.g. valprint.c:2177: add_alias_cmd ("p", "print", no_class, 1, &setlist); valprint.c:2184: add_alias_cmd ("p", "print", no_class, 1, &showlist); We've been extending python incrementally, and I'm doing that here as well.] btw, I've been debating whether to implement command aliases with a python object (akin to how gdb commands are implemented with gdb.Command). It's not clear an object-oriented approach for command aliases really brings any functional utility to the table. It would be consistent with how commands are treated, at the expense of extra complexity. I'm open to thoughts on which way to go. I've also been debating whether to use the name define_command_alias instead of add_command_alias. I don't have a strong enough preference to not go with what gdb uses internally. >> valid_cmd_name_p is more restrictive than it could be. >> E.g. gdb allows a user-defined command named "42", but >> "it's easier to relax restrictions than it is to impose them after the fact", >> so I'm going with this. > > Sorry, I don't understand what this is about. I guess that was again > discussed "on IRC" or wherever. Actually it's just a restriction I've added on my own. I'm not entirely comfortable with gdb's allowing one to define user-commands like that, and I don't want to allow this in python if I don't have to. At least not in the first pass. If someone comes up with a compelling argument for relaxing what valid_cmd_name_p accepts we can cross that bridge at that time. >> + NOTE: TUI has a few special commands, +, <, >. >> + We don't watch for those here. */ > > Why not? And what does that mean in terms of user expectations? This is another case of not wanting to have valid_cmd_name_p accept as legitimate names I'm not comfortable with. At least not in the first pass. As far as user expectation goes, I don't see a problem. What are valid command names is documented, and the current set of valid names is completely within reason IMO. [I was thinking of disallowing "-foo", but didn't have a strong enough opinion so I left it.] Note that we *can* relax things later if a compelling argument presents itself, I don't mind taking these particular kinds of things one step at a time (and often prefer it). IWBN to allow "!" be an alias for shell, for example, but gdb currently doesn't allow it. What special characters are valid and what are not, and why not? That discussion needn't block this. [For completeness sake, Having gdb.Command validate the command name is left for another patch. E.g., I can define a command named "!" and it will appear in "help" output, but I can't execute it. If/when we fix that we can relax valid_cmd_name_p: again, I don't mind taking these particular kinds of things one step at a time. bash$ cat foo.py import gdb class PlayCommand (gdb.Command): """Command to play with.""" def __init__(self): super(PlayCommand, self).__init__("!", gdb.COMMAND_OBSCURE) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" gdb.execute("shell %s" % arg) PlayCommand() class Play2Command (gdb.Command): """Command to play with.""" def __init__(self): super(Play2Command, self).__init__("bang", gdb.COMMAND_OBSCURE) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" gdb.execute("shell %s" % arg) Play2Command() bash$ gdb (gdb) source foo.py (gdb) help obscure Obscure features. List of commands: ! -- Command to play with bang -- Command to play with checkpoint -- Fork a duplicate process (experimental) compare-sections -- Compare section data on target to the exec file complete -- List the completions for the rest of the line as a command monitor -- Send a command to the remote monitor (remote targets only) python -- Evaluate a Python command record -- Abbreviated form of "target record" command record delete -- Delete the rest of execution log and start recording it anew record goto -- Restore the program to its state at instruction number N record restore -- Restore the execution log from a file record save -- Save the execution log to a file record stop -- Stop the record/replay target restart -- Restart <n>: restore program context from a checkpoint stop -- There is no `stop' command Type "help" followed by command name for full documentation. Type "apropos word" to search for commands related to "word". Command name abbreviations are allowed if unambiguous. (gdb) ! pwd Undefined command: "". Try "help". (gdb) bang pwd /home/dje/src/play (gdb) >> +This is useful, for example, when you want to be able to type a command >> +with a long name using fewer characters, and the contraction is otherwise >> +ambiguous. It can also we used when you want to give a command an alternate > ^^ > "be" Righto, thanks. >> +@var{name} is the name of the new command. >> [..] >> +Command names must begin with a letter, dash or underscore, >> +and must consist of letters, numbers, dashes and underscores. > > @var{name} is the name of the new command; it must begin with a > letter, dash or underscore, and must consist of letters, numbers, > dashes and underscores. Ok. >> +@var{command_class} should be one of the @samp{COMMAND_} constants. > > Please add here a cross-reference to where these constants are > documented. I was going to do that but since the values are documented preceding this item on the same page, and the existing text doesn't use a cross-reference (and since I forgot how to label the text so that I could cross-reference it :-)) I punted. Here's a revised patch. 2011-09-13 Doug Evans <dje@google.com> Add support for adding command aliases from python. * NEWS: Mention gdb.add_command_alias. * command.h (valid_cmd_name_p): Declare. * cli/cli-decode.c (valid_cmd_name_p): New function. * python/py-cmd.c (gdbpy_add_com_alias): New function. * python/python-internal.h (gdbpy_add_com_alias): Declare. * python/python.c (GdbMethods): Add add_command_alias. doc/ * gdb.texinfo (Commands In Python): Document add_command_alias. testsuite/ * gdb.python/py-cmd.exp: Add tests for gdb.add_command_alias. [-- Attachment #2: gdb-110913-add-command-alias-2.patch.txt --] [-- Type: text/plain, Size: 8548 bytes --] 2011-09-09 Doug Evans <dje@google.com> Add support for adding command aliases from python. * NEWS: Mention gdb.add_command_alias. * command.h (valid_cmd_name_p): Declare. * cli/cli-decode.c (valid_cmd_name_p): New function. * python/py-cmd.c (gdbpy_add_com_alias): New function. * python/python-internal.h (gdbpy_add_com_alias): Declare. * python/python.c (GdbMethods): Add add_command_alias. doc/ * gdb.texinfo (Commands In Python): Document add_command_alias. testsuite/ * gdb.python/py-cmd.exp: Add tests for gdb.add_command_alias. Index: NEWS =================================================================== RCS file: /cvs/src/src/gdb/NEWS,v retrieving revision 1.452 diff -u -p -r1.452 NEWS --- NEWS 4 Sep 2011 17:48:51 -0000 1.452 +++ NEWS 9 Sep 2011 18:07:50 -0000 @@ -38,6 +38,8 @@ ** Symbols now provide the "type" attribute, the type of the symbol. + ** Command aliases can now be defined with the add_command_alias function. + * libthread-db-search-path now supports two special values: $sdir and $pdir. $sdir specifies the default system locations of shared libraries. $pdir specifies the directory where the libpthread used by the application Index: command.h =================================================================== RCS file: /cvs/src/src/gdb/command.h,v retrieving revision 1.74 diff -u -p -r1.74 command.h --- command.h 14 Feb 2011 23:41:33 -0000 1.74 +++ command.h 9 Sep 2011 18:07:50 -0000 @@ -106,6 +106,8 @@ struct cmd_list_element; /* Forward-declarations of the entry-points of cli/cli-decode.c. */ +extern int valid_cmd_name_p (const char *name); + extern struct cmd_list_element *add_cmd (char *, enum command_class, void (*fun) (char *, int), char *, struct cmd_list_element **); Index: cli/cli-decode.c =================================================================== RCS file: /cvs/src/src/gdb/cli/cli-decode.c,v retrieving revision 1.97 diff -u -p -r1.97 cli-decode.c --- cli/cli-decode.c 8 Sep 2011 17:20:43 -0000 1.97 +++ cli/cli-decode.c 9 Sep 2011 18:07:50 -0000 @@ -126,6 +126,38 @@ set_cmd_completer (struct cmd_list_eleme cmd->completer = completer; /* Ok. */ } +/* Return TRUE if NAME is a valid command name. + + NOTE: TUI has a few special commands, +, <, >. + We don't watch for those here. */ + +int +valid_cmd_name_p (const char *name) +{ + const char *p; + + /* First character must be a letter, -, or _. */ + if (*name == '\0') + return FALSE; + if (isalpha (*name) + || *name == '-' + || *name == '_') + ; /* Ok. */ + else + return FALSE; + + for (p = name + 1; *p != '\0'; ++p) + { + if (isalnum (*p) + || *p == '-' + || *p == '_') + ; /* Ok. */ + else + return FALSE; + } + + return TRUE; +} /* Add element named NAME. Space for NAME and DOC must be allocated by the caller. Index: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.858 diff -u -p -r1.858 gdb.texinfo --- doc/gdb.texinfo 4 Sep 2011 17:08:56 -0000 1.858 +++ doc/gdb.texinfo 9 Sep 2011 18:07:51 -0000 @@ -22668,6 +22668,35 @@ registration of the command with @value{ Python code is read into @value{GDBN}, you may need to import the @code{gdb} module explicitly. +@findex gdb.add_command_alias +@defun add_command_alias name aliased_name command_class abbrev_flag +Command aliases can be defined with the @code{gdb.add_command_alias} function. +This is useful, for example, when you want to be able to type a command +with a long name using fewer characters, and the contraction is otherwise +ambiguous. It can also we used when you want to give a command an alternate +spelling. + +@var{name} is the name of the new command. +@var{aliased_name} is the name of the command that is being aliased. +Command names must begin with a letter, dash or underscore, +and must consist of letters, numbers, dashes and underscores. + +@var{command_class} should be one of the @samp{COMMAND_} constants. + +@var{abbrev_flag} is a boolean flag specifying whether to treat the alias +as an abbreviation of the original command or not. +If the alias is an abbreviation it will not appear in @code{help} +command list output. + +Here is an example where we make @code{e} an alternate spelling of the +@code{x} command. + +@smallexample +(gdb) python gdb.add_command_alias ("e", "x", gdb.COMMAND_DATA, 0) +(gdb) e/10i main +@end smallexample +@end defun + @node Parameters In Python @subsubsection Parameters In Python Index: python/py-cmd.c =================================================================== RCS file: /cvs/src/src/gdb/python/py-cmd.c,v retrieving revision 1.16 diff -u -p -r1.16 py-cmd.c --- python/py-cmd.c 8 Sep 2011 19:51:27 -0000 1.16 +++ python/py-cmd.c 9 Sep 2011 18:07:51 -0000 @@ -698,3 +698,34 @@ gdbpy_string_to_argv (PyObject *self, Py return py_argv; } + +\f + +/* Wrapper around add_com_alias. */ + +PyObject * +gdbpy_add_com_alias (PyObject *self, PyObject *args, PyObject *kw) +{ + static char *keywords[] = { + "name", "aliased_name", "command_class", "abbrev_flag", NULL + }; + char *name, *aliased_name; + int command_class, abbrev_flag; + + if (! PyArg_ParseTupleAndKeywords (args, kw, "ssii", keywords, + &name, &aliased_name, + &command_class, &abbrev_flag)) + return NULL; + + if (! valid_cmd_name_p (name)) + return PyErr_Format (PyExc_RuntimeError, + _("Invalid command name `%s'."), name); + if (! valid_cmd_name_p (aliased_name)) + return PyErr_Format (PyExc_RuntimeError, + _("Invalid aliased command name `%s'."), aliased_name); + + /* add_cmd requires *we* allocate space for name, hence the xstrdup. */ + add_com_alias (xstrdup (name), aliased_name, command_class, abbrev_flag); + + Py_RETURN_NONE; +} Index: python/python-internal.h =================================================================== RCS file: /cvs/src/src/gdb/python/python-internal.h,v retrieving revision 1.47 diff -u -p -r1.47 python-internal.h --- python/python-internal.h 8 Sep 2011 19:51:27 -0000 1.47 +++ python/python-internal.h 9 Sep 2011 18:07:52 -0000 @@ -152,6 +152,7 @@ PyObject *gdbpy_create_lazy_string_objec PyObject *gdbpy_inferiors (PyObject *unused, PyObject *unused2); PyObject *gdbpy_selected_thread (PyObject *self, PyObject *args); PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args); +PyObject *gdbpy_add_com_alias (PyObject *self, PyObject *args, PyObject *kw); PyObject *gdbpy_parameter (PyObject *self, PyObject *args); PyObject *gdbpy_parameter_value (enum var_types type, void *var); char *gdbpy_parse_command_name (const char *name, Index: python/python.c =================================================================== RCS file: /cvs/src/src/gdb/python/python.c,v retrieving revision 1.71 diff -u -p -r1.71 python.c --- python/python.c 6 Sep 2011 14:49:00 -0000 1.71 +++ python/python.c 9 Sep 2011 18:07:52 -0000 @@ -1426,6 +1426,10 @@ Return the selected thread object." }, { "inferiors", gdbpy_inferiors, METH_NOARGS, "inferiors () -> (gdb.Inferior, ...).\n\ Return a tuple containing all inferiors." }, + { "add_command_alias", (PyCFunction)gdbpy_add_com_alias, + METH_VARARGS | METH_KEYWORDS, + "Add an alias for an existing command." }, + {NULL, NULL, 0, NULL} }; Index: testsuite/gdb.python/py-cmd.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-cmd.exp,v retrieving revision 1.6 diff -u -p -r1.6 py-cmd.exp --- testsuite/gdb.python/py-cmd.exp 10 Jan 2011 11:00:23 -0000 1.6 +++ testsuite/gdb.python/py-cmd.exp 9 Sep 2011 18:07:52 -0000 @@ -45,6 +45,20 @@ gdb_py_test_multiple "input simple comma gdb_test "test_cmd ugh" "test_cmd output, arg = ugh" "call simple command" +# Test an alias command. + +gdb_test_no_output "python gdb.add_command_alias (\"test_alias_cmd\", \"test_cmd\", gdb.COMMAND_OBSCURE, 0)" "add_command_alias" + +gdb_test "test_alias_cmd ugh" "test_cmd output, arg = ugh" "call alias command" + +gdb_test "python gdb.add_command_alias (\"(bad name)\", \"test_cmd\", gdb.COMMAND_OBSCURE, 0)" \ + "RuntimeError: Invalid command name.*" \ + "bad alias command name" + +gdb_test "python gdb.add_command_alias (\"test_alias_cmd\", \"(bad name)\", gdb.COMMAND_OBSCURE, 0)" \ + "RuntimeError: Invalid aliased command name.*" \ + "bad aliased command name" + # Test a prefix command, and a subcommand within it. gdb_py_test_multiple "input prefix command" \ ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-13 17:40 ` Doug Evans @ 2011-09-13 17:47 ` Pedro Alves 2011-09-13 19:15 ` Doug Evans 2011-09-13 18:49 ` Pedro Alves 1 sibling, 1 reply; 14+ messages in thread From: Pedro Alves @ 2011-09-13 17:47 UTC (permalink / raw) To: gdb-patches; +Cc: Doug Evans, Eli Zaretskii On Tuesday 13 September 2011 18:20:16, Doug Evans wrote: > On Fri, Sep 9, 2011 at 2:13 PM, Eli Zaretskii <eliz@gnu.org> wrote: > >> Date: Fri, 9 Sep 2011 11:36:36 -0700 (PDT) > >> From: dje@google.com (Doug Evans) > >> > >> Per discussion on IRC, here is a patch to add support for adding > >> command aliases. > > > > I wish people would discuss such issues here, not on IRC. These > > discussions should be recorded, for one thing. > > Whatever additional discussion one wants to have we can have here. > No worries. > > > Me, I don't understand the need for this feature, especially not why > > it should be a Python-only feature. Moreover, why do we need to have > > this, when one can easily write a command that just calls an existing > > one, to have the same effect. IMO, since this is really about aliasing new CLI spellings for existing CLI commands, it'd make sense to have a way to alias commands in the CLI, without python. E.g., (gdb) alias isl info shared library (gdb) isl <list shared libraries> Python could then of course just do gdb.execute("alias ..."). -- Pedro Alves ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-13 17:47 ` Pedro Alves @ 2011-09-13 19:15 ` Doug Evans 2011-09-13 19:32 ` Pedro Alves 0 siblings, 1 reply; 14+ messages in thread From: Doug Evans @ 2011-09-13 19:15 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Eli Zaretskii On Tue, Sep 13, 2011 at 10:39 AM, Pedro Alves <pedro@codesourcery.com> wrote: > On Tuesday 13 September 2011 18:20:16, Doug Evans wrote: >> On Fri, Sep 9, 2011 at 2:13 PM, Eli Zaretskii <eliz@gnu.org> wrote: >> >> Date: Fri, 9 Sep 2011 11:36:36 -0700 (PDT) >> >> From: dje@google.com (Doug Evans) >> >> >> >> Per discussion on IRC, here is a patch to add support for adding >> >> command aliases. >> > >> > I wish people would discuss such issues here, not on IRC. These >> > discussions should be recorded, for one thing. >> >> Whatever additional discussion one wants to have we can have here. >> No worries. >> >> > Me, I don't understand the need for this feature, especially not why >> > it should be a Python-only feature. Moreover, why do we need to have >> > this, when one can easily write a command that just calls an existing >> > one, to have the same effect. > > IMO, since this is really about aliasing new CLI spellings for > existing CLI commands, it'd make sense to have a way to alias commands > in the CLI, without python. E.g., > > (gdb) alias isl info shared library > (gdb) isl > <list shared libraries> > > Python could then of course just do gdb.execute("alias ..."). [s/shared library/sharedlibrary/ It's not clear how general you intended this to be. E.g., handle an arbitrary number of prefixes?] If the intent is to handle an arbitrary number of prefixes then that's a different kind of alias than how gdb uses the word today. E.g. (gdb) alias spe set print elements (gdb) spe 20 # set print elements = 20 That's fine, just checking ... IWBN to add aliases from the CLI for anything, (e.g., grep for add_alias_cmd in mips-tdep.c, sheesh!) but that will require a bit more syntax. One would need to distinguish aliasing "spe" --> "set print elements" from "set print foobars" --> "set print elements". ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-13 19:15 ` Doug Evans @ 2011-09-13 19:32 ` Pedro Alves 2011-09-13 21:42 ` Doug Evans 0 siblings, 1 reply; 14+ messages in thread From: Pedro Alves @ 2011-09-13 19:32 UTC (permalink / raw) To: Doug Evans; +Cc: gdb-patches, Eli Zaretskii On Tuesday 13 September 2011 19:48:45, Doug Evans wrote: > On Tue, Sep 13, 2011 at 10:39 AM, Pedro Alves <pedro@codesourcery.com> wrote: > > IMO, since this is really about aliasing new CLI spellings for > > existing CLI commands, it'd make sense to have a way to alias commands > > in the CLI, without python. E.g., > > > > (gdb) alias isl info shared library > > (gdb) isl > > <list shared libraries> > > > > Python could then of course just do gdb.execute("alias ..."). > > [s/shared library/sharedlibrary/ > It's not clear how general you intended this to be. I was just throwing out the idea. Hadn't though much on such details. :-) > > E.g., handle an arbitrary number of prefixes?] > > If the intent is to handle an arbitrary number of prefixes > then that's a different kind of > alias than how gdb uses the word today. Hmm, you mean prefixes on the alias name? Cause we have aliases that expand to prefixed commands: infcmd.c:2797: add_com_alias ("tty", "set inferior-tty", class_alias, 0); > E.g. > (gdb) alias spe set print elements > (gdb) spe 20 # set print elements = 20 Right. > That's fine, just checking ... > > IWBN to add aliases from the CLI for anything, > (e.g., grep for add_alias_cmd in mips-tdep.c, sheesh!) Hmm, what's the advantage of add_alias_cmd over add_com_alias (or vice versa)? Are these really two use cases from the user's perpective, or just two ways to end up with the same thing? > but that will require a bit more syntax. > One would need to distinguish aliasing > "spe" --> "set print elements" > from > "set print foobars" --> "set print elements". Ah, right, yes, of course. That sounds useful. Irrespective of what we do know, do you think it _shouldn't_ work? Maybe it's useful. E.g., `alias -f FROM -t TO' would work for me. E.g., (gdb) alias -f "set print foobars" -t "set print elements" The command would fail if "set" or "set print" in FROM don't exist, or TO doesn't exist. But if that's hard, we can just not support it (yet at least), as long as we leave the door open in terms of syntax. -- Pedro Alves ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-13 19:32 ` Pedro Alves @ 2011-09-13 21:42 ` Doug Evans 2011-09-21 21:46 ` Doug Evans 0 siblings, 1 reply; 14+ messages in thread From: Doug Evans @ 2011-09-13 21:42 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Eli Zaretskii On Tue, Sep 13, 2011 at 12:15 PM, Pedro Alves <pedro@codesourcery.com> wrote: > Hmm, what's the advantage of add_alias_cmd over add_com_alias > (or vice versa)? add_com_alias is just a wrapper on add_alias_cmd for a particular case. [or did I misunderstand?] >> but that will require a bit more syntax. >> One would need to distinguish aliasing >> "spe" --> "set print elements" >> from >> "set print foobars" --> "set print elements". > > Ah, right, yes, of course. That sounds useful. Irrespective > of what we do know, [s/know/now/ I presume] > do you think it _shouldn't_ work? Eh? > Maybe it's useful. I think so. > E.g., `alias -f FROM -t TO' would work for me. E.g., > > (gdb) alias -f "set print foobars" -t "set print elements" > > The command would fail if "set" or "set print" in FROM > don't exist, or TO doesn't exist. But if that's hard, > we can just not support it (yet at least), as long as > we leave the door open in terms of syntax. -f and -t seem inconsistent with the existing u/i. I'm guessing they're there so people don't have to deal with remembering FROM/TO ordering (a la bcopy vs memcpy, intel vs att, etc.) If there was a consensus on the order one could remove requiring -f/-t later. I think I will punt on handling `alias -f "set foobars" -t "set print elements"' for now. [If it falls out, great, but I'm not going to worry about it.] btw, "!pwd" would work if find_command_name_length recognized it as a 1-char command. But the range of acceptable command spellings still bugs me. If TUI doesn't use +,<,> for more than single-character length commands, I wouldn't mind at least restricting +,<,> for only single-character commands, and then add '!' as a single char command (if only when they're the first character). ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-13 21:42 ` Doug Evans @ 2011-09-21 21:46 ` Doug Evans 2011-09-22 14:08 ` Pedro Alves 2011-09-22 18:13 ` Eli Zaretskii 0 siblings, 2 replies; 14+ messages in thread From: Doug Evans @ 2011-09-21 21:46 UTC (permalink / raw) To: Pedro Alves, Eli Zaretskii, gdb-patches [-- Attachment #1: Type: text/plain, Size: 999 bytes --] How about this version? It depends on a patch to libiberty. I'll wait before that gets resolved before checking in of course. I can think of one doc issue. For command syntax in an @item existing usage would say to write something like @item alias [-a] -f @var{from} -t @var{to} instead of what I've written: @item alias [-a] -f FROM -t TO But I don't know how to properly refer to -f from in subsequent text except as @samp{-f FROM} which is why I wrote what I wrote. Suggestions welcome. 2011-09-21 Doug Evans <dje@google.com> Add new "alias" command. * NEWS: Mention new command. * command.h (valid_user_defined_cmd_name_p): Declare. * cli/cli-decode.c (valid_user_defined_cmd_name_p): New function. * cli/cli-cmds.c (alias_command): New function. (init_cli_cmds): Add new command. doc/ * gdb.texinfo (Extending GDB): Document alias command. testsuite/ * gdb.base/alias.exp: Add tests for alias command. [-- Attachment #2: gdb-110921-alias-1.patch.txt --] [-- Type: text/plain, Size: 15139 bytes --] 2011-09-21 Doug Evans <dje@google.com> Add new "alias" command. * NEWS: Mention new command. * command.h (valid_user_defined_cmd_name_p): Declare. * cli/cli-decode.c (valid_user_defined_cmd_name_p): New function. * cli/cli-cmds.c (alias_command): New function. (init_cli_cmds): Add new command. doc/ * gdb.texinfo (Extending GDB): Document alias command. testsuite/ * gdb.base/alias.exp: Add tests for alias command. Index: NEWS =================================================================== RCS file: /cvs/src/src/gdb/NEWS,v retrieving revision 1.453 diff -u -p -r1.453 NEWS --- NEWS 15 Sep 2011 12:27:18 -0000 1.453 +++ NEWS 21 Sep 2011 20:16:02 -0000 @@ -73,7 +73,8 @@ the first connection is made. The listening port used by GDBserver will become available after that. -* New commands "info macros", and "info definitions" have been added. +* New commands "info macros", and "info definitions", + and "alias" have been added. * Changed commands Index: command.h =================================================================== RCS file: /cvs/src/src/gdb/command.h,v retrieving revision 1.74 diff -u -p -r1.74 command.h --- command.h 14 Feb 2011 23:41:33 -0000 1.74 +++ command.h 21 Sep 2011 20:16:02 -0000 @@ -106,6 +106,8 @@ struct cmd_list_element; /* Forward-declarations of the entry-points of cli/cli-decode.c. */ +extern int valid_user_defined_cmd_name_p (const char *name); + extern struct cmd_list_element *add_cmd (char *, enum command_class, void (*fun) (char *, int), char *, struct cmd_list_element **); Index: cli/cli-cmds.c =================================================================== RCS file: /cvs/src/src/gdb/cli/cli-cmds.c,v retrieving revision 1.115 diff -u -p -r1.115 cli-cmds.c --- cli/cli-cmds.c 4 Aug 2011 19:10:13 -0000 1.115 +++ cli/cli-cmds.c 21 Sep 2011 20:16:02 -0000 @@ -21,6 +21,7 @@ #include "defs.h" #include "exceptions.h" #include "arch-utils.h" +#include "dyn-string.h" #include "readline/readline.h" #include "readline/tilde.h" #include "completer.h" @@ -1272,6 +1273,134 @@ apropos_command (char *searchstr, int fr error (_("Error in regular expression: %s"), err); } } + +/* Make an alias of an existing command. */ + +static void +alias_command (char *args, int from_tty) +{ + int i; + int abbrev_flag = 0; + char **argv, **from_argv, **to_argv; + char *from = NULL; + char *to = NULL; + static const char usage[] = "Usage: alias [-a] -f FROM -t TO"; + + if (args == NULL) + error (_(usage)); + + argv = gdb_buildargv (args); + make_cleanup_freeargv (argv); + + for (i = 0; argv[i] != NULL; ++i) + { + if (strcmp (argv[i], "-a") == 0) + abbrev_flag = 1; + else if (strcmp (argv[i], "-f") == 0) + { + if (from != NULL || argv[i + 1] == NULL) + error (_(usage)); + from = argv[++i]; + } + else if (strcmp (argv[i], "-t") == 0) + { + if (to != NULL || argv[i + 1] == NULL) + error (_(usage)); + to = argv[++i]; + } + else + error (_(usage)); + } + + if (from == NULL) + error (_(usage)); + if (to == NULL) + error (_(usage)); + + from_argv = gdb_buildargv (from); + make_cleanup_freeargv (from_argv); + to_argv = gdb_buildargv (to); + make_cleanup_freeargv (to_argv); + + if (from_argv[0] == NULL) + error (_("Empty FROM command.")); + if (to_argv[0] == NULL) + error (_("Empty TO command.")); + + for (i = 0; to_argv[i] != NULL; ++i) + { + if (! valid_user_defined_cmd_name_p (to_argv[i])) + { + if (i == 0) + error (_("Invalid command name: %s"), to_argv[i]); + else + error (_("Invalid command element name: %s"), to_argv[i]); + } + } + + /* If TO is one word, it is an alias for the entire FROM command. + Example: alias -t spe -f "set print elements". + + Otherwise FROM and TO must have the same number of words, + and every word except the last must match; and the last word of + TO is made an alias of the last word of FROM. + Example: alias -t "set pr elms" -f "set p elem" + Note that unambiguous abbreviations are allowed. */ + + if (to_argv[1] == NULL) + { + /* add_cmd requires *we* allocate space for name, hence the xstrdup. */ + add_com_alias (xstrdup (to_argv[0]), from, class_alias, abbrev_flag); + } + else + { + int i; + dyn_string_t from_prefix, to_prefix; + char *from_prefix_cstr, *to_prefix_cstr; + struct cmd_list_element *c_from, *c_to; + int argc = countargv (from_argv); + + if (countargv (to_argv) != argc) + error (_("Mismatched command length between FROM and TO.")); + c_from = lookup_cmd_1 (& from, cmdlist, NULL, 1); + if (c_from == NULL || c_from == (struct cmd_list_element *) -1) + error (_("Invalid FROM command: %s"), from); + + /* Create copies of FROM and TO without the last word, + and use that to verify the leading elements match. */ + from_prefix = dyn_string_new (10); + make_cleanup ((make_cleanup_ftype *) dyn_string_delete, from_prefix); + to_prefix = dyn_string_new (10); + make_cleanup ((make_cleanup_ftype *) dyn_string_delete, to_prefix); + + for (i = 0; i < argc - 1; ++i) + { + if (i > 0) + dyn_string_append_char (from_prefix, ' '); + dyn_string_append_cstr (from_prefix, from_argv[i]); + } + from_prefix_cstr = dyn_string_buf (from_prefix); + for (i = 0; i < argc - 1; ++i) + { + if (i > 0) + dyn_string_append_char (to_prefix, ' '); + dyn_string_append_cstr (to_prefix, to_argv[i]); + } + to_prefix_cstr = dyn_string_buf (to_prefix); + + c_from = lookup_cmd_1 (& from_prefix_cstr, cmdlist, NULL, 1); + /* We've already tried to look up FROM. */ + gdb_assert (c_from != NULL && c_from != (struct cmd_list_element *) -1); + gdb_assert (c_from->prefixlist != NULL); + c_to = lookup_cmd_1 (& to_prefix_cstr, cmdlist, NULL, 1); + if (c_to != c_from) + error (_("FROM and TO command prefixes do not match.")); + + /* add_cmd requires *we* allocate space for name, hence the xstrdup. */ + add_alias_cmd (xstrdup (to_argv[argc - 1]), from_argv[argc - 1], + class_alias, abbrev_flag, c_from->prefixlist); + } +} \f /* Print a list of files and line numbers which a user may choose from in order to list a function which was specified ambiguously (as @@ -1674,4 +1803,19 @@ When 'on', each command is displayed as NULL, NULL, &setlist, &showlist); + + c = add_com ("alias", class_support, alias_command, _("\ +Define a new command that is an alias of an existing command.\n\ +Usage: alias [-a] -f FROM -t TO\n\ +FROM is the command to alias from.\n\ +TO is the new command being defined.\n\ +\"-f FROM\" and \"-t TO\" may appear in either order.\n\ +If \"-a\" is specified, the command is an abbreviation,\n\ +and will not appear in help command list output.\n\ +\n\ +Examples:\n\ +Make \"spe\" an alias of \"set print elements\":\n\ + alias -f \"set print elements\" -t spe\n\ +Make \"elms\" an alias of \"elements\" in the \"set print\" command:\n\ + alias -f \"set print elements\" -t \"set print elms\"")); } Index: cli/cli-decode.c =================================================================== RCS file: /cvs/src/src/gdb/cli/cli-decode.c,v retrieving revision 1.97 diff -u -p -r1.97 cli-decode.c --- cli/cli-decode.c 8 Sep 2011 17:20:43 -0000 1.97 +++ cli/cli-decode.c 21 Sep 2011 20:16:02 -0000 @@ -126,7 +126,6 @@ set_cmd_completer (struct cmd_list_eleme cmd->completer = completer; /* Ok. */ } - /* 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 @@ -1138,6 +1137,31 @@ find_command_name_length (const char *te return p - text; } +/* Return TRUE if NAME is a valid user-defined command name. + This is a stricter subset of all gdb commands, + see find_command_name_length. */ + +int +valid_user_defined_cmd_name_p (const char *name) +{ + const char *p; + + /* Alas "42" is a legitimate user-defined command. + In the interests of not breaking anything we preserve that. */ + + for (p = name; *p != '\0'; ++p) + { + if (isalnum (*p) + || *p == '-' + || *p == '_') + ; /* Ok. */ + else + return FALSE; + } + + return TRUE; +} + /* This routine takes a line of TEXT and a CLIST in which to start the lookup. When it returns it will have incremented the text pointer past the section of text it matched, set *RESULT_LIST to point to the list in Index: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.862 diff -u -p -r1.862 gdb.texinfo --- doc/gdb.texinfo 16 Sep 2011 09:07:01 -0000 1.862 +++ doc/gdb.texinfo 21 Sep 2011 20:16:02 -0000 @@ -20321,11 +20321,12 @@ Displays whether the debugger is operati @chapter Extending @value{GDBN} @cindex extending GDB -@value{GDBN} provides two mechanisms for extension. The first is based -on composition of @value{GDBN} commands, and the second is based on the -Python scripting language. +@value{GDBN} provides three mechanisms for extension. The first is based +on composition of @value{GDBN} commands, the second is based on the +Python scripting language, and the third is defining new aliases of +existing commands. -To facilitate the use of these extensions, @value{GDBN} is capable +To facilitate the use of the first two extensions, @value{GDBN} is capable of evaluating the contents of a file. When doing so, @value{GDBN} can recognize which scripting language is being used by looking at the filename extension. Files with an unrecognized filename extension @@ -20360,6 +20361,7 @@ Display the current value of the @code{s @menu * Sequences:: Canned Sequences of Commands * Python:: Scripting @value{GDBN} using Python +* Aliases:: Creating new spellings of existing commands @end menu @node Sequences @@ -24058,6 +24060,90 @@ substitute_prompt (``frame: \f, @end smallexample @end table +@node Aliases +@section Creating new spellings of existing commands + +It is often useful to define alternate spellings of existing commands. +For example, if a new @value{GDBN} command defined in Python has +a long name to type, it is handy to have an abbreviated version of it +that involves less typing. + +@value{GDBN} itself uses aliases. For example @samp{s} is an alias +of the @samp{step} command even though it is otherwise an ambiguous +abbreviation of other commands like @samp{set} and @samp{show}. + +Aliases are also used to provide shortened or more common versions +of multi-word commands. For example, @value{GDBN} provides the +@samp{tty} alias of the @samp{set inferior-tty} command. + +Define a new alias with the @samp{alias} command. + +@table @code + +@kindex alias +@item alias [-a] -f FROM -t TO + +@end table + +@samp{-f FROM} and @samp{-t TO} may be specified in either order. + +The @samp{-f FROM} option specifies the name of an existing command +that is being aliased. + +The @samp{-t TO} option specifies the name of the new alias. + +The @samp{-a} option specifies that the new alias is an abbreviation +of the @samp{FROM} command, and will not appear in help command lists. + +Here is a simple example showing how to make an abbreviation +of a command so that there is less to type. +Suppose you were tired of typing @samp{disas}, the current +shortest unambiguous abbreviation of the @samp{disassemble} command +and you wanted an even shorter version named @samp{di}. +The following will accomplish this. + +@smallexample +(gdb) alias -f disas -t di +@end smallexample + +Note that aliases are different than user-defined commands. +With a user-defined command, you also need to write documentation +for it with the @samp{document} command. +An alias automatically picks up the documentation of the existing command. + +Here is an example where we make @samp{elms} an abbreviation of +@samp{elements} in the @samp{set print elements} command. +This is to show that you can make an abbreviation of any part +of a command. + +@smallexample +(gdb) alias -f "set print elements" -t "set print elms" +(gdb) alias -f "show print elements" -t "show print elms" +(gdb) set p elms 20 +(gdb) show p elms +Limit on string chars or array elements to print is 200. +@end smallexample + +Note that if you are defining an alias of a @samp{set} command, +you also need to define the alias of the corresponding @samp{show} +command, if desired. + +Unambiguously abbreviated commands are allowed in @samp{FROM} and +@samp{TO}, just as they are normally. + +@smallexample +(gdb) alias -f "set p ele" -t "set pr elms" +@end smallexample + +Finally, here is an example showing the creation of a one word +alias for a more complex command. +This creates alias @samp{spe} of the command @samp{set print elements}. + +@smallexample +(gdb) alias -f "set print elements" -t spe +(gdb) spe 20 +@end smallexample + @node Interpreters @chapter Command Interpreters @cindex command interpreters Index: testsuite/gdb.base/alias.exp =================================================================== RCS file: testsuite/gdb.base/alias.exp diff -N testsuite/gdb.base/alias.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/alias.exp 21 Sep 2011 20:16:03 -0000 @@ -0,0 +1,52 @@ +# Test the alias command. +# Copyright 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +proc test_abbrev_not_present { alias_name } { + global gdb_prompt + set alias_present 0 + set test_name "abbrev $alias_name not present in help command list" + gdb_test_multiple "help aliases" $test_name { + -re "\[\r\n\]$alias_name \[^\r\n\]*" { + set alias_present 1 + exp_continue + } + -re ".*$gdb_prompt $" { + if { !$alias_present } then { + pass $test_name + } else { + fail $test_name + } + } + } +} + +gdb_test_no_output "alias -a -f set -t set2" +gdb_test_no_output "set2 print elements 42" +gdb_test "show print elements" "Limit .* is 42\[.\]" +test_abbrev_not_present set2 + +gdb_test_no_output "alias -f \"set p elem\" -t spe" +gdb_test_no_output "spe 43" +gdb_test "show print elements" "Limit .* is 43\[.\]" + +gdb_test_no_output "alias -f \"set p elem\" -t \"set pr elm2\"" +gdb_test_no_output "set pr elm2 44" +gdb_test "show print elements" "Limit .* is 44\[.\]" +gdb_test "help set print" "set print elm2 .*" ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-21 21:46 ` Doug Evans @ 2011-09-22 14:08 ` Pedro Alves 2011-09-22 17:45 ` Doug Evans 2011-09-22 18:13 ` Eli Zaretskii 1 sibling, 1 reply; 14+ messages in thread From: Pedro Alves @ 2011-09-22 14:08 UTC (permalink / raw) To: Doug Evans; +Cc: Eli Zaretskii, gdb-patches Thanks! On Wednesday 21 September 2011 22:12:11, Doug Evans wrote: > + make_cleanup ((make_cleanup_ftype *) dyn_string_delete, from_prefix); > + to_prefix = dyn_string_new (10); > + make_cleanup ((make_cleanup_ftype *) dyn_string_delete, to_prefix); Please don't add more casts to make_cleanup_ftype. /* NOTE: cagney/2000-03-04: This typedef is strictly for the make_cleanup function declarations below. Do not use this typedef as a cast when passing functions into the make_cleanup() code. Instead either use a bounce function or add a wrapper function. Calling a f(char*) function with f(void*) is non-portable. */ typedef void (make_cleanup_ftype) (void *); Any special reason `-f "maint bah foo" -t "info bar"' is forbidden? I was thinking that we'd only verify whether "info" exists. But maybe that shouldn't either be verified. Having aliases not erroring out if the destination doesn't exist allows one putting aliases in .gdbinit without worrying if the gdb that'll load has FROM already (it may be too old, but not old enough to not support "alias"). It's fine with me to put this in as in. I'll try to change this at some point if I feel so inclined. I realize the alias mechanism as is today does not even create the alias if the FROM does not exist. So this branch ... > + if (to_argv[1] == NULL) > + { > + /* add_cmd requires we allocate space for name, hence the xstrdup. */ > + add_com_alias (xstrdup (to_argv[0]), from, class_alias, abbrev_flag); > + } is silent if FROM does not exist, though the other branch errors out. Just pointing it out -- not sure it was on purpose. With the make_cleahup_ftype thing fixed, this is fine with me. Thanks again! -- Pedro Alves ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-22 14:08 ` Pedro Alves @ 2011-09-22 17:45 ` Doug Evans 0 siblings, 0 replies; 14+ messages in thread From: Doug Evans @ 2011-09-22 17:45 UTC (permalink / raw) To: Pedro Alves; +Cc: Eli Zaretskii, gdb-patches On Thu, Sep 22, 2011 at 6:54 AM, Pedro Alves <pedro@codesourcery.com> wrote: > On Wednesday 21 September 2011 22:12:11, Doug Evans wrote: >> + make_cleanup ((make_cleanup_ftype *) dyn_string_delete, from_prefix); >> + to_prefix = dyn_string_new (10); >> + make_cleanup ((make_cleanup_ftype *) dyn_string_delete, to_prefix); > > Please don't add more casts to make_cleanup_ftype. /me wishes all existing uses got cleaned up - monkey see monkey do ... > Any special reason `-f "maint bah foo" -t "info bar"' is forbidden? Couldn't think of a use for it. Support can be added later if/when warranted. > I was thinking that we'd only verify whether "info" exists. But maybe > that shouldn't either be verified. Having aliases not erroring out if the > destination doesn't exist allows one putting aliases in .gdbinit > without worrying if the gdb that'll load has FROM already (it may be > too old, but not old enough to not support "alias"). I like being restrictive in error catching, at least in the early stages. btw, if the gdb has python one could wrap it and catch alias failure. Not that this helps people with older gdb's, but maybe cli should have its own "try" command (or we could just require python for such things). > So this branch ... > >> + if (to_argv[1] == NULL) >> + { >> + /* add_cmd requires we allocate space for name, hence the xstrdup. */ >> + add_com_alias (xstrdup (to_argv[0]), from, class_alias, abbrev_flag); >> + } > > is silent if FROM does not exist, though the other branch errors out. > Just pointing it out -- not sure it was on purpose. Oversight, thanks. Now I just need a doc RFA. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-21 21:46 ` Doug Evans 2011-09-22 14:08 ` Pedro Alves @ 2011-09-22 18:13 ` Eli Zaretskii 2011-09-22 21:48 ` Doug Evans 1 sibling, 1 reply; 14+ messages in thread From: Eli Zaretskii @ 2011-09-22 18:13 UTC (permalink / raw) To: Doug Evans; +Cc: pedro, gdb-patches > Date: Wed, 21 Sep 2011 14:12:11 -0700 > From: Doug Evans <dje@google.com> > > @item alias [-a] -f @var{from} -t @var{to} > > instead of what I've written: > > @item alias [-a] -f FROM -t TO > > But I don't know how to properly refer to -f from in subsequent text > except as @samp{-f FROM} which is why I wrote what I wrote. > Suggestions welcome. Sorry, I don't understand the problem. Or maybe I do, see below. > -* New commands "info macros", and "info definitions" have been added. > +* New commands "info macros", and "info definitions", > + and "alias" have been added.^^^ Redundant "and". > +Python scripting language, and the third is defining new aliases of > +existing commands. ^^ "for", I think. > +@node Aliases > +@section Creating new spellings of existing commands Please add here an index entry: @cindex aliases for commands > +Define a new alias with the @samp{alias} command. You can define a new alias with the @samp{alias} command. > +@item alias [-a] -f FROM -t TO > + > +@end table > + > +@samp{-f FROM} and @samp{-t TO} may be specified in either order. If by "refer" above you mean refer to "-f FROM" etc., then what's wrong with @samp{-f @var{from}} ? > +The @samp{-f FROM} option specifies the name of an existing command > +that is being aliased. > + > +The @samp{-t TO} option specifies the name of the new alias. Btw, I'm not sure FROM and TO are a good idea; it's not like you are copying something. How about COMMAND and ALIAS instead? > +The @samp{-a} option specifies that the new alias is an abbreviation > +of the @samp{FROM} command, and will not appear in help command lists. Suggest a rewording: The @samp{-a} option specifies that the new alias is an abbreviation of the @samp{FROM} command. Abbreviations are not shown in command lists displayed by the @samp{help} command. > +Note that aliases are different than user-defined commands. ^^^^ "from" > +Here is an example where we make @samp{elms} an abbreviation of > +@samp{elements} in the @samp{set print elements} command. > +This is to show that you can make an abbreviation of any part > +of a command. > + > +@smallexample > +(gdb) alias -f "set print elements" -t "set print elms" > +(gdb) alias -f "show print elements" -t "show print elms" For didactic purposes, shouldn't these examples use -a? > +Note that if you are defining an alias of a @samp{set} command, > +you also need to define the alias of the corresponding @samp{show} > +command, if desired. "Need" and "if desired" are in contradiction. Which is it? Thanks. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-22 18:13 ` Eli Zaretskii @ 2011-09-22 21:48 ` Doug Evans 2011-09-23 11:40 ` Eli Zaretskii 0 siblings, 1 reply; 14+ messages in thread From: Doug Evans @ 2011-09-22 21:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: pedro, gdb-patches On Thu, Sep 22, 2011 at 11:09 AM, Eli Zaretskii <eliz@gnu.org> wrote: >> -* New commands "info macros", and "info definitions" have been added. >> +* New commands "info macros", and "info definitions", >> + and "alias" have been added.^^^ > > Redundant "and". Blech, I thought I had removed that. Will fix. >> +Python scripting language, and the third is defining new aliases of >> +existing commands. ^^ > > "for", I think. Ok. >> +@node Aliases >> +@section Creating new spellings of existing commands > > Please add here an index entry: > > @cindex aliases for commands Ok. >> +Define a new alias with the @samp{alias} command. > > You can define a new alias with the @samp{alias} command. Ok. >> +@item alias [-a] -f FROM -t TO >> + >> +@end table >> + >> +@samp{-f FROM} and @samp{-t TO} may be specified in either order. > > If by "refer" above you mean refer to "-f FROM" etc., then what's > wrong with > > @samp{-f @var{from}} That works. >> +The @samp{-f FROM} option specifies the name of an existing command >> +that is being aliased. >> + >> +The @samp{-t TO} option specifies the name of the new alias. > > Btw, I'm not sure FROM and TO are a good idea; it's not like you are > copying something. How about COMMAND and ALIAS instead? Ok, but then I have to wonder about -f and -t. -c and -a? [setting aside -a collides with the current -a for abbreviation] But if you're happy with -f COMMAND -t ALIAS, great. >> +The @samp{-a} option specifies that the new alias is an abbreviation >> +of the @samp{FROM} command, and will not appear in help command lists. > > Suggest a rewording: > > The @samp{-a} option specifies that the new alias is an abbreviation > of the @samp{FROM} command. Abbreviations are not shown in command > lists displayed by the @samp{help} command. Ok. >> +Note that aliases are different than user-defined commands. > ^^^^ > "from" Ok. >> +Here is an example where we make @samp{elms} an abbreviation of >> +@samp{elements} in the @samp{set print elements} command. >> +This is to show that you can make an abbreviation of any part >> +of a command. >> + >> +@smallexample >> +(gdb) alias -f "set print elements" -t "set print elms" >> +(gdb) alias -f "show print elements" -t "show print elms" > > For didactic purposes, shouldn't these examples use -a? Ok. >> +Note that if you are defining an alias of a @samp{set} command, >> +you also need to define the alias of the corresponding @samp{show} >> +command, if desired. > > > "Need" and "if desired" are in contradiction. Which is it? How about if I reword it to: Note that if you are defining an alias of a @samp{set} command, and you want to have an alias for the corresponding @samp{show} command, then you need to define the latter separately. [i.e. it may be confusing, but it's not a contradiction] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-22 21:48 ` Doug Evans @ 2011-09-23 11:40 ` Eli Zaretskii 0 siblings, 0 replies; 14+ messages in thread From: Eli Zaretskii @ 2011-09-23 11:40 UTC (permalink / raw) To: Doug Evans; +Cc: pedro, gdb-patches > Date: Thu, 22 Sep 2011 11:22:26 -0700 > From: Doug Evans <dje@google.com> > Cc: pedro@codesourcery.com, gdb-patches@sourceware.org > > >> +The @samp{-f FROM} option specifies the name of an existing command > >> +that is being aliased. > >> + > >> +The @samp{-t TO} option specifies the name of the new alias. > > > > Btw, I'm not sure FROM and TO are a good idea; it's not like you are > > copying something. Â How about COMMAND and ALIAS instead? > > Ok, but then I have to wonder about -f and -t. > -c and -a? [setting aside -a collides with the current -a for abbreviation] > > But if you're happy with -f COMMAND -t ALIAS, great. I'm not happy about that, either, FWIW. Why not use the popular syntax used by other programs that offer aliases? E.g., (gdb) alias ALIAS=COMMAND But that's just MO, FWIW. If everyone else is happy with these letter switches, I can live with that. > >> +Note that if you are defining an alias of a @samp{set} command, > >> +you also need to define the alias of the corresponding @samp{show} > >> +command, if desired. > > > > > > "Need" and "if desired" are in contradiction. Â Which is it? > > How about if I reword it to: > > Note that if you are defining an alias of a @samp{set} command, > and you want to have an alias for the corresponding @samp{show} > command, then you need to define the latter separately. Works for me, thanks. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFA, doc RFA] Add gdb.add_command_alias 2011-09-13 17:40 ` Doug Evans 2011-09-13 17:47 ` Pedro Alves @ 2011-09-13 18:49 ` Pedro Alves 1 sibling, 0 replies; 14+ messages in thread From: Pedro Alves @ 2011-09-13 18:49 UTC (permalink / raw) To: gdb-patches; +Cc: Doug Evans, Eli Zaretskii On Tuesday 13 September 2011 18:20:16, Doug Evans wrote: > IWBN to allow "!" be an alias for shell, for example, > but gdb currently doesn't allow it. Yeah, actually, I found this in cli/cli-cmds.c:init_cli_cmds: /* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would be a really useful feature. Unfortunately, the below wont do this. Instead it adds support for the form ``(gdb) ! ls'' (i.e. the space is required). If the ``!'' command below is added the complains about no ``!'' command would be replaced by complains about how the ``!'' command is broken :-) */ if (xdb_commands) add_com_alias ("!", "shell", class_support, 0); -- Pedro Alves ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2011-09-23 10:27 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-09-09 19:25 [RFA, doc RFA] Add gdb.add_command_alias Doug Evans 2011-09-09 21:15 ` Eli Zaretskii 2011-09-13 17:40 ` Doug Evans 2011-09-13 17:47 ` Pedro Alves 2011-09-13 19:15 ` Doug Evans 2011-09-13 19:32 ` Pedro Alves 2011-09-13 21:42 ` Doug Evans 2011-09-21 21:46 ` Doug Evans 2011-09-22 14:08 ` Pedro Alves 2011-09-22 17:45 ` Doug Evans 2011-09-22 18:13 ` Eli Zaretskii 2011-09-22 21:48 ` Doug Evans 2011-09-23 11:40 ` Eli Zaretskii 2011-09-13 18:49 ` Pedro Alves
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox