From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24051 invoked by alias); 9 Sep 2011 18:36:58 -0000 Received: (qmail 24043 invoked by uid 22791); 9 Sep 2011 18:36:56 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Sep 2011 18:36:39 +0000 Received: from hpaq2.eem.corp.google.com (hpaq2.eem.corp.google.com [172.25.149.2]) by smtp-out.google.com with ESMTP id p89IacQK032056 for ; Fri, 9 Sep 2011 11:36:38 -0700 Received: from ruffy.mtv.corp.google.com (ruffy.mtv.corp.google.com [172.18.110.50]) by hpaq2.eem.corp.google.com with ESMTP id p89Iaar4012985 for ; Fri, 9 Sep 2011 11:36:37 -0700 Received: by ruffy.mtv.corp.google.com (Postfix, from userid 67641) id 444932461B1; Fri, 9 Sep 2011 11:36:36 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [RFA, doc RFA] Add gdb.add_command_alias Message-Id: <20110909183636.444932461B1@ruffy.mtv.corp.google.com> Date: Fri, 09 Sep 2011 19:25:00 -0000 From: dje@google.com (Doug Evans) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-09/txt/msg00166.txt.bz2 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 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" \