[RFA, doc RFA] Add gdb.add_command_alias
Doug Evans
dje@google.com
Fri Sep 9 19:25:00 GMT 2011
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;
}
+
+
+
+/* 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" \
More information about the Gdb-patches
mailing list