* [python][patch] Add GDB Parameters functionality
@ 2010-04-26 13:19 Phil Muldoon
2010-04-26 17:56 ` Eli Zaretskii
2010-04-26 21:45 ` Tom Tromey
0 siblings, 2 replies; 17+ messages in thread
From: Phil Muldoon @ 2010-04-26 13:19 UTC (permalink / raw)
To: gdb-patches ml
This patch brings over GDB Parameter functionality from the Archer
project/repository. This functionality remains largely the same; I've
reintroduced some functionality back into py-cmd that was stripped
from the last FSF import, and fixed several bugs related to enum
parameters. It also introduces a new testsuite.
OK?
Cheers,
Phil Muldoon
--
2010-04-26 Phil Muldoon <pmuldoon@redhat.com>
Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
* Makefile.in (SUBDIR_PYTHON_OBS): Add py-parameter.
(SUBDIR_PYTHON_SRCS): Likewise.
(py-parameter.o): New rule.
* python/py-parameter.c: New file.
* python/python-internal.h (gdbpy_initialize_parameter)
(gdbpy_parameter, gdbpy_parameter_value)
(gdbpy_parse_command_name): Declare.
* python/py-cmd.c (parse_command_name): Rename to
gdbpy_parse_command_name.
(gdbpy_parse_command_name): Accept a starting list parameter and
use over cmdlist.
(cmdpy_init): Use gdbpy_parse_command_name.
* python/python.c (parameter_to_python): Rename to
gdbpy_parameter_to_python. Accept enum var_types and value.
(gdbpy_parameter): Use gdbpy_parameter_value.
(_initialize_python): Call gdbpy_initialize_parameters.
2010-04-26 Phil Muldoon <pmuldoon@redhat.com>
* gdb.python/py-param.exp: New File.
2010-04-26 Phil Muldoon <pmuldoon@redhat.com>
Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
* gdb.texinfo (Parameters In Python): New Node.
--
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index fc148fe..4d12f96 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -275,6 +275,7 @@ SUBDIR_PYTHON_OBS = \
py-function.o \
py-lazy-string.o \
py-objfile.o \
+ py-param.o \
py-prettyprint.o \
py-progspace.o \
py-symbol.o \
@@ -292,6 +293,7 @@ SUBDIR_PYTHON_SRCS = \
python/py-function.c \
python/py-lazy-string.c \
python/py-objfile.c \
+ python/py-param.c \
python/py-prettyprint.c \
python/py-progspace.c \
python/py-symbol.c \
@@ -2021,6 +2023,10 @@ py-objfile.o: $(srcdir)/python/py-objfile.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-objfile.c
$(POSTCOMPILE)
+py-param.o: $(srcdir)/python/py-param.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-param.c
+ $(POSTCOMPILE)
+
py-prettyprint.o: $(srcdir)/python/py-prettyprint.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
$(POSTCOMPILE)
diff --git a/gdb/NEWS b/gdb/NEWS
index 696da2e..fe6b3fc 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -80,7 +80,9 @@ is now deprecated.
* Python scripting
** The GDB Python API now has access to breakpoints, symbols, symbol
- tables, program spaces, and frame's code blocks.
+ tables, program spaces, and frame's code blocks. Additionally, GDB
+ Parameters can now be created from the API, and manipulated via
+ set/show in the CLI.
** New functions gdb.target_charset, gdb.target_wide_charset,
gdb.progspaces, and gdb.current_progspace.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3bb8ef9..16aeaba 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19926,6 +19926,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
* Pretty Printing API:: Pretty-printing values.
* Selecting Pretty-Printers:: How GDB chooses a pretty-printer.
* Commands In Python:: Implementing new commands in Python.
+* Parameters In Python:: Adding new @value{GDBN} parameters.
* Functions In Python:: Writing new convenience functions.
* Progspaces In Python:: Program spaces.
* Objfiles In Python:: Object files.
@@ -20947,6 +20948,135 @@ registration of the command with @value{GDBN}. Depending on how the
Python code is read into @value{GDBN}, you may need to import the
@code{gdb} module explicitly.
+@node Parameters In Python
+@subsubsection Parameters In Python
+
+@cindex parameters in python
+@cindex python parameters
+@tindex gdb.Parameter
+@tindex Parameter
+You can implement new @value{GDBN} parameters using Python. A new
+parameter is implemented as an instance of the @code{gdb.Parameter}
+class. Parameters are exposed to the user via the @code{set} and
+@code{show} commands.
+
+@defmethod Parameter __init__ name @var{command-class} @var{parameter-class} @r{[}@var{enum-sequence}@r{]}
+The object initializer for @code{Parameter} registers the new
+parameter with @value{GDBN}. This initializer is normally invoked
+from the subclass' own @code{__init__} method.
+
+@var{name} is the name of the new parameter. If @var{name} consists
+of multiple words, then the initial words are looked for as prefix
+commands. In this case, if one of the prefix commands does not exist,
+an exception is raised.
+
+@var{command-class} should be one of the @samp{COMMAND_} constants
+(@pxref{Commands In Python}). This argument tells @value{GDBN} how to
+categorize the new parameter in the help system.
+
+@var{parameter-class} should be one of the @samp{PARAM_} constants
+defined below. This argument tells @value{GDBN} the type of the new
+parameter; this information is used for input validation and
+completion.
+
+If @var{parameter-class} is @code{PARAM_ENUM}, then
+@var{enum-sequence} must be a sequence of strings. These strings
+represent the possible values for the parameter.
+
+If @var{parameter-class} is not @code{PARAM_ENUM}, then the presence
+of a fourth argument will cause an exception to be thrown.
+
+The help text for the new parameter is taken from the Python
+documentation string for the parameter's class, if there is one. If
+there is no documentation string, a default value is used.
+@end defmethod
+
+@defivar Parameter set_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{set} command. The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter show_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{show} command. The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter value
+The @code{value} attribute holds the underlying value of the
+parameter. It can be read and assigned to just as any other
+attribute. @value{GDBN} does validation when assignments are made.
+@end defivar
+
+
+When a new parameter is defined, its type must be specified. The
+available types are represented by constants defined in the @code{gdb}
+module:
+
+@table @code
+@findex PARAM_BOOLEAN
+@findex gdb.PARAM_BOOLEAN
+@item PARAM_BOOLEAN
+The value is a plain boolean. The Python boolean values, @code{True}
+and @code{False} are the only valid values.
+
+@findex PARAM_AUTO_BOOLEAN
+@findex gdb.PARAM_AUTO_BOOLEAN
+@item PARAM_AUTO_BOOLEAN
+The value has three possible states: true, false, and @samp{auto}. In
+Python, true and false are represented using boolean constants, and
+@samp{auto} is represented using @code{None}.
+
+@findex PARAM_UINTEGER
+@findex gdb.PARAM_UINTEGER
+@item PARAM_UINTEGER
+The value is an unsigned integer. The value of 0 should be
+interpreted to mean ``unlimited''.
+
+@findex PARAM_INTEGER
+@findex gdb.PARAM_INTEGER
+@item PARAM_INTEGER
+The value is a signed integer. The value of 0 should be interpreted
+to mean ``unlimited''.
+
+@findex PARAM_STRING
+@findex gdb.PARAM_STRING
+@item PARAM_STRING
+The value is a string. When the user modifies the string, escapes are
+translated.
+
+@findex PARAM_STRING_NOESCAPE
+@findex gdb.PARAM_STRING_NOESCAPE
+@item PARAM_STRING_NOESCAPE
+The value is a string. When the user modifies the string, escapes are
+passed through untranslated.
+
+@findex PARAM_OPTIONAL_FILENAME
+@findex gdb.PARAM_OPTIONAL_FILENAME
+@item PARAM_OPTIONAL_FILENAME
+The value is a either a filename (a string), or @code{None}.
+
+@findex PARAM_FILENAME
+@findex gdb.PARAM_FILENAME
+@item PARAM_FILENAME
+The value is a filename (a string).
+
+@findex PARAM_ZINTEGER
+@findex gdb.PARAM_ZINTEGER
+@item PARAM_ZINTEGER
+The value is an integer. This is like @code{PARAM_INTEGER}, except 0
+is interpreted as itself.
+
+@findex PARAM_ENUM
+@findex gdb.PARAM_ENUM
+@item PARAM_ENUM
+The value is a string, which must be one of a collection string
+constants provided when the parameter is created.
+@end table
+
@node Functions In Python
@subsubsection Writing new convenience functions
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index d187d16..7679ef3 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -263,10 +263,14 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
*BASE_LIST is set to the final prefix command's list of
*sub-commands.
+ START_LIST is the list in which the search starts.
+
This function returns the xmalloc()d name of the new command. On
error sets the Python error and returns NULL. */
-static char *
-parse_command_name (char *text, struct cmd_list_element ***base_list)
+char *
+gdbpy_parse_command_name (char *text,
+ struct cmd_list_element ***base_list,
+ struct cmd_list_element **start_list)
{
struct cmd_list_element *elt;
int len = strlen (text);
@@ -299,7 +303,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list)
;
if (i < 0)
{
- *base_list = &cmdlist;
+ *base_list = start_list;
return result;
}
@@ -308,7 +312,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list)
prefix_text[i + 1] = '\0';
text = prefix_text;
- elt = lookup_cmd_1 (&text, cmdlist, NULL, 1);
+ elt = lookup_cmd_1 (&text, *start_list, NULL, 1);
if (!elt || elt == (struct cmd_list_element *) -1)
{
PyErr_Format (PyExc_RuntimeError, _("Could not find command prefix %s."),
@@ -399,7 +403,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
return -1;
}
- cmd_name = parse_command_name (name, &cmd_list);
+ cmd_name = gdbpy_parse_command_name (name, &cmd_list, &cmdlist);
if (! cmd_name)
return -1;
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
new file mode 100644
index 0000000..5bcdaae
--- /dev/null
+++ b/gdb/python/py-param.c
@@ -0,0 +1,617 @@
+/* GDB parameters implemented in Python
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+
+#include "defs.h"
+#include "value.h"
+#include "exceptions.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "gdbcmd.h"
+#include "cli/cli-decode.h"
+#include "completer.h"
+
+/* Parameter constants and their values. */
+struct parm_constant
+{
+ char *name;
+ int value;
+};
+
+struct parm_constant parm_constants[] =
+{
+ { "PARAM_BOOLEAN", var_boolean },
+ { "PARAM_AUTO_BOOLEAN", var_auto_boolean },
+ { "PARAM_UINTEGER", var_uinteger },
+ { "PARAM_INTEGER", var_integer },
+ { "PARAM_STRING", var_string },
+ { "PARAM_STRING_NOESCAPE", var_string_noescape },
+ { "PARAM_OPTIONAL_FILENAME", var_optional_filename },
+ { "PARAM_FILENAME", var_filename },
+ { "PARAM_ZINTEGER", var_zinteger },
+ { "PARAM_ENUM", var_enum },
+ { NULL, 0 }
+};
+
+/* A union that can hold anything described by enum var_types. */
+union parmpy_variable
+{
+ /* Hold an integer value, for boolean and integer types. */
+ int intval;
+
+ /* Hold an auto_boolean. */
+ enum auto_boolean autoboolval;
+
+ /* Hold an unsigned integer value, for uinteger. */
+ unsigned int uintval;
+
+ /* Hold a string, for the various string types. */
+ char *stringval;
+
+ /* Hold a string, for enums. */
+ const char *cstringval;
+};
+
+/* A GDB parameter. */
+struct parmpy_object
+{
+ PyObject_HEAD
+
+ /* The type of the parameter. */
+ enum var_types type;
+
+ /* The value of the parameter. */
+ union parmpy_variable value;
+
+ /* For an enum command, the possible values. The vector is
+ allocated with xmalloc, as is each element. It is
+ NULL-terminated. */
+ const char **enumeration;
+};
+
+typedef struct parmpy_object parmpy_object;
+
+static PyTypeObject parmpy_object_type;
+
+/* Some handy string constants. */
+static PyObject *set_doc_cst;
+static PyObject *show_doc_cst;
+
+\f
+
+/* Get an attribute. */
+static PyObject *
+get_attr (PyObject *obj, PyObject *attr_name)
+{
+ if (PyString_Check (attr_name)
+ && ! strcmp (PyString_AsString (attr_name), "value"))
+ {
+ parmpy_object *self = (parmpy_object *) obj;
+ return gdbpy_parameter_value (self->type, &self->value);
+ }
+
+ return PyObject_GenericGetAttr (obj, attr_name);
+}
+
+/* Set a parameter value from a Python value. Return 0 on success, -1
+ on failure. */
+static int
+set_parameter_value (parmpy_object *self, PyObject *value)
+{
+ int cmp;
+
+ switch (self->type)
+ {
+ case var_string:
+ case var_string_noescape:
+ case var_optional_filename:
+ case var_filename:
+ if (! gdbpy_is_string (value)
+ && (self->type == var_filename
+ || value != Py_None))
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("String required for filename."));
+
+ return -1;
+ }
+ if (self->value.stringval)
+ xfree (self->value.stringval);
+ if (value == Py_None)
+ {
+ if (self->type == var_optional_filename)
+ self->value.stringval = xstrdup ("");
+ else
+ self->value.stringval = NULL;
+ }
+ else
+ self->value.stringval = python_string_to_host_string (value);
+ break;
+
+ case var_enum:
+ {
+ int i;
+ char *str;
+
+ if (! gdbpy_is_string (value))
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("ENUM arguments must be a string."));
+ return -1;
+ }
+
+ str = python_string_to_host_string (value);
+ for (i = 0; self->enumeration[i]; ++i)
+ if (! strcmp (self->enumeration[i], str))
+ break;
+ xfree (str);
+ if (! self->enumeration[i])
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("The value must be member of enumeration."));
+ return -1;
+ }
+ self->value.cstringval = self->enumeration[i];
+ break;
+ }
+
+ case var_boolean:
+ if (! PyBool_Check (value))
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("A boolean argument is required."));
+ return -1;
+ }
+ cmp = PyObject_IsTrue (value);
+ if (cmp < 0)
+ return -1;
+ self->value.intval = cmp;
+ break;
+
+ case var_auto_boolean:
+ if (! PyBool_Check (value) && value != Py_None)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("A boolean or None is required"));
+ return -1;
+ }
+
+ if (value == Py_None)
+ self->value.autoboolval = AUTO_BOOLEAN_AUTO;
+ else
+ {
+ cmp = PyObject_IsTrue (value);
+ if (cmp < 0 )
+ return -1;
+ if (cmp == 1)
+ self->value.autoboolval = AUTO_BOOLEAN_TRUE;
+ else
+ self->value.autoboolval = AUTO_BOOLEAN_FALSE;
+
+ break;
+ }
+
+ case var_integer:
+ case var_zinteger:
+ case var_uinteger:
+ {
+ long l;
+ int ok;
+
+ if (! PyInt_Check (value))
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("The value must be integer."));
+ return -1;
+ }
+
+ l = PyInt_AsLong (value);
+ if (self->type == var_uinteger)
+ {
+ ok = (l >= 0 && l <= UINT_MAX);
+ if (l == 0)
+ l = UINT_MAX;
+ }
+ else if (self->type == var_integer)
+ {
+ ok = (l >= INT_MIN && l <= INT_MAX);
+ if (l == 0)
+ l = INT_MAX;
+ }
+ else
+ ok = (l >= INT_MIN && l <= INT_MAX);
+
+ if (! ok)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Range exceeded."));
+ return -1;
+ }
+
+ self->value.intval = (int) l;
+ break;
+ }
+
+ default:
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Unhandled type in parameter value."));
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Set an attribute. */
+static int
+set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
+{
+ if (PyString_Check (attr_name)
+ && ! strcmp (PyString_AsString (attr_name), "value"))
+ {
+ if (!val)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Cannot delete a parameter's value."));
+ return -1;
+ }
+ return set_parameter_value ((parmpy_object *) obj, val);
+ }
+
+ return PyObject_GenericSetAttr (obj, attr_name, val);
+}
+
+\f
+
+/* A helper function that dispatches to the appropriate add_setshow
+ function. */
+static void
+add_setshow_generic (int parmclass, enum command_class cmdclass,
+ char *cmd_name, parmpy_object *self,
+ char *set_doc, char *show_doc, char *help_doc,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list)
+{
+ switch (parmclass)
+ {
+ case var_boolean:
+ add_setshow_boolean_cmd (cmd_name, cmdclass, &self->value.intval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_auto_boolean:
+ add_setshow_auto_boolean_cmd (cmd_name, cmdclass,
+ &self->value.autoboolval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_uinteger:
+ add_setshow_uinteger_cmd (cmd_name, cmdclass, &self->value.uintval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_integer:
+ add_setshow_integer_cmd (cmd_name, cmdclass, &self->value.intval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_string:
+ add_setshow_string_cmd (cmd_name, cmdclass, &self->value.stringval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_string_noescape:
+ add_setshow_string_noescape_cmd (cmd_name, cmdclass,
+ &self->value.stringval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_optional_filename:
+ add_setshow_optional_filename_cmd (cmd_name, cmdclass,
+ &self->value.stringval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_filename:
+ add_setshow_filename_cmd (cmd_name, cmdclass, &self->value.stringval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_zinteger:
+ add_setshow_zinteger_cmd (cmd_name, cmdclass, &self->value.intval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ break;
+
+ case var_enum:
+ add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration,
+ &self->value.cstringval,
+ set_doc, show_doc, help_doc,
+ NULL, NULL, set_list, show_list);
+ /* Initialize the value, just in case. */
+ self->value.cstringval = self->enumeration[0];
+ break;
+ }
+}
+
+/* A helper which computes enum values. Returns 1 on success, 0 on
+ error. */
+static int
+compute_enum_values (parmpy_object *self, PyObject *enum_values)
+{
+ Py_ssize_t size, i;
+
+ if (! enum_values)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("An enumeration is required for PARAM_ENUM."));
+ return 0;
+ }
+
+ if (! PySequence_Check (enum_values))
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("The enumeration is not a sequence."));
+ return 0;
+ }
+
+ size = PySequence_Size (enum_values);
+ if (size < 0)
+ return 0;
+ if (size == 0)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("The enumeration is empty."));
+ return 0;
+ }
+
+ self->enumeration = xmalloc ((size + 1) * sizeof (char *));
+ memset (self->enumeration, 0, (size + 1) * sizeof (char *));
+
+ for (i = 0; i < size; ++i)
+ {
+ PyObject *item = PySequence_GetItem (enum_values, i);
+ if (! item)
+ return 0;
+ if (! gdbpy_is_string (item))
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("The enumeration item not a string."));
+ return 0;
+ }
+ self->enumeration[i] = python_string_to_host_string (item);
+ }
+
+ return 1;
+}
+
+/* A helper function which returns a documentation string for an
+ object. */
+static char *
+get_doc_string (PyObject *object, PyObject *attr)
+{
+ char *result = NULL;
+ if (PyObject_HasAttr (object, attr))
+ {
+ PyObject *ds_obj = PyObject_GetAttr (object, attr);
+ if (ds_obj && gdbpy_is_string (ds_obj))
+ result = python_string_to_host_string (ds_obj);
+ }
+ if (! result)
+ result = xstrdup (_("This command is not documented."));
+ return result;
+}
+
+/* Object initializer; sets up gdb-side structures for command.
+
+ Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
+
+ NAME is the name of the parameter. It may consist of multiple
+ words, in which case the final word is the name of the new command,
+ and earlier words must be prefix commands.
+
+ CMDCLASS is the kind of command. It should be one of the COMMAND_*
+ constants defined in the gdb module.
+
+ PARMCLASS is the type of the parameter. It should be one of the
+ PARAM_* constants defined in the gdb module.
+
+ If PARMCLASS is PARAM_ENUM, then the final argument should be a
+ collection of strings. These strings are the valid values for this
+ parameter.
+
+ The documentation for the parameter is taken from the doc string
+ for the python class.
+
+*/
+static int
+parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
+{
+ parmpy_object *obj = (parmpy_object *) self;
+ char *name;
+ char *set_doc, *show_doc, *doc;
+ char *cmd_name;
+ int parmclass, cmdtype;
+ PyObject *enum_values = NULL;
+ struct cmd_list_element *cmd_list;
+ struct cmd_list_element **set_list, **show_list;
+ volatile struct gdb_exception except;
+
+ if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
+ &enum_values))
+ return -1;
+
+ if (cmdtype != no_class && cmdtype != class_run
+ && cmdtype != class_vars && cmdtype != class_stack
+ && cmdtype != class_files && cmdtype != class_support
+ && cmdtype != class_info && cmdtype != class_breakpoint
+ && cmdtype != class_trace && cmdtype != class_obscure
+ && cmdtype != class_maintenance)
+ {
+ PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
+ return -1;
+ }
+
+ if (parmclass != var_boolean && parmclass != var_auto_boolean
+ && parmclass != var_uinteger && parmclass != var_integer
+ && parmclass != var_string && parmclass != var_string_noescape
+ && parmclass != var_optional_filename && parmclass != var_filename
+ && parmclass != var_zinteger && parmclass != var_enum)
+ {
+ PyErr_SetString (PyExc_RuntimeError, _("Invalid parameter class argument."));
+ return -1;
+ }
+
+ if (enum_values && parmclass != var_enum)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Only PARAM_ENUM accepts a fourth argument."));
+ return -1;
+ }
+ if (parmclass == var_enum)
+ {
+ if (! compute_enum_values (obj, enum_values))
+ return -1;
+ }
+ else
+ obj->enumeration = NULL;
+ obj->type = (enum var_types) parmclass;
+ memset (&obj->value, 0, sizeof (obj->value));
+
+ cmd_name = gdbpy_parse_command_name (name, &set_list,
+ &setlist);
+
+ if (! cmd_name)
+ return -1;
+ xfree (cmd_name);
+ cmd_name = gdbpy_parse_command_name (name, &show_list,
+ &showlist);
+ if (! cmd_name)
+ return -1;
+
+ set_doc = get_doc_string (self, set_doc_cst);
+ show_doc = get_doc_string (self, show_doc_cst);
+ doc = get_doc_string (self, gdbpy_doc_cst);
+
+ Py_INCREF (self);
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ add_setshow_generic (parmclass, (enum command_class) cmdtype,
+ cmd_name, obj,
+ set_doc, show_doc,
+ doc, set_list, show_list);
+ }
+ if (except.reason < 0)
+ {
+ xfree (cmd_name);
+ xfree (set_doc);
+ xfree (show_doc);
+ xfree (doc);
+ Py_DECREF (self);
+ PyErr_Format (except.reason == RETURN_QUIT
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+ "%s", except.message);
+ return -1;
+ }
+ return 0;
+}
+
+\f
+
+/* Initialize the 'parameters' module. */
+void
+gdbpy_initialize_parameters (void)
+{
+ int i;
+
+ if (PyType_Ready (&parmpy_object_type) < 0)
+ return;
+
+ set_doc_cst = PyString_FromString ("set_doc");
+ if (! set_doc_cst)
+ return;
+ show_doc_cst = PyString_FromString ("show_doc");
+ if (! show_doc_cst)
+ return;
+
+ for (i = 0; parm_constants[i].name; ++i)
+ {
+ if (PyModule_AddIntConstant (gdb_module,
+ parm_constants[i].name,
+ parm_constants[i].value) < 0)
+ return;
+ }
+
+ Py_INCREF (&parmpy_object_type);
+ PyModule_AddObject (gdb_module, "Parameter",
+ (PyObject *) &parmpy_object_type);
+}
+
+\f
+
+static PyTypeObject parmpy_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.Parameter", /*tp_name*/
+ sizeof (parmpy_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ get_attr, /*tp_getattro*/
+ set_attr, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "GDB parameter object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ parmpy_init, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew /* tp_new */
+};
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index d27c5d2..25c4171 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -67,6 +67,9 @@ typedef int Py_ssize_t;
a real symtab_and_line structure is needed. */
#include "symtab.h"
+/* Also needed to parse enum var_types. */
+#include "command.h"
+
struct block;
struct value;
struct language_defn;
@@ -90,6 +93,11 @@ PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
PyObject *gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
const char *encoding, struct type *type);
PyObject *gdbpy_get_hook_function (const char *);
+PyObject *gdbpy_parameter (PyObject *self, PyObject *args);
+PyObject *gdbpy_parameter_value (enum var_types type, void *var);
+char *gdbpy_parse_command_name (char *text,
+ struct cmd_list_element ***base_list,
+ struct cmd_list_element **start_list);
PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal);
PyObject *symtab_to_symtab_object (struct symtab *symtab);
@@ -126,6 +134,7 @@ void gdbpy_initialize_pspace (void);
void gdbpy_initialize_objfile (void);
void gdbpy_initialize_breakpoints (void);
void gdbpy_initialize_lazy_string (void);
+void gdbpy_initialize_parameters (void);
struct cleanup *make_cleanup_py_decref (PyObject *py);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index a1c1d8c..cf87b66 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -192,11 +192,10 @@ python_command (char *arg, int from_tty)
/* Transform a gdb parameters's value into a Python value. May return
NULL (and set a Python exception) on error. Helper function for
get_parameter. */
-
-static PyObject *
-parameter_to_python (struct cmd_list_element *cmd)
+PyObject *
+gdbpy_parameter_value (enum var_types type, void *var)
{
- switch (cmd->var_type)
+ switch (type)
{
case var_string:
case var_string_noescape:
@@ -204,7 +203,7 @@ parameter_to_python (struct cmd_list_element *cmd)
case var_filename:
case var_enum:
{
- char *str = * (char **) cmd->var;
+ char *str = * (char **) var;
if (! str)
str = "";
return PyString_Decode (str, strlen (str), host_charset (), NULL);
@@ -212,7 +211,7 @@ parameter_to_python (struct cmd_list_element *cmd)
case var_boolean:
{
- if (* (int *) cmd->var)
+ if (* (int *) var)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
@@ -220,7 +219,7 @@ parameter_to_python (struct cmd_list_element *cmd)
case var_auto_boolean:
{
- enum auto_boolean ab = * (enum auto_boolean *) cmd->var;
+ enum auto_boolean ab = * (enum auto_boolean *) var;
if (ab == AUTO_BOOLEAN_TRUE)
Py_RETURN_TRUE;
else if (ab == AUTO_BOOLEAN_FALSE)
@@ -230,15 +229,15 @@ parameter_to_python (struct cmd_list_element *cmd)
}
case var_integer:
- if ((* (int *) cmd->var) == INT_MAX)
+ if ((* (int *) var) == INT_MAX)
Py_RETURN_NONE;
/* Fall through. */
case var_zinteger:
- return PyLong_FromLong (* (int *) cmd->var);
+ return PyLong_FromLong (* (int *) var);
case var_uinteger:
{
- unsigned int val = * (unsigned int *) cmd->var;
+ unsigned int val = * (unsigned int *) var;
if (val == UINT_MAX)
Py_RETURN_NONE;
return PyLong_FromUnsignedLong (val);
@@ -252,7 +251,7 @@ parameter_to_python (struct cmd_list_element *cmd)
/* A Python function which returns a gdb parameter's value as a Python
value. */
-static PyObject *
+PyObject *
gdbpy_parameter (PyObject *self, PyObject *args)
{
struct cmd_list_element *alias, *prefix, *cmd;
@@ -278,7 +277,7 @@ gdbpy_parameter (PyObject *self, PyObject *args)
if (! cmd->var)
return PyErr_Format (PyExc_RuntimeError,
_("`%s' is not a parameter."), arg);
- return parameter_to_python (cmd);
+ return gdbpy_parameter_value (cmd->var_type, cmd->var);
}
/* Wrapper for target_charset. */
@@ -645,6 +644,7 @@ Enables or disables printing of Python stack traces."),
gdbpy_initialize_symtabs ();
gdbpy_initialize_blocks ();
gdbpy_initialize_functions ();
+ gdbpy_initialize_parameters ();
gdbpy_initialize_types ();
gdbpy_initialize_pspace ();
gdbpy_initialize_objfile ();
diff --git a/gdb/testsuite/gdb.python/py-param.exp b/gdb/testsuite/gdb.python/py-param.exp
new file mode 100644
index 0000000..2dfe96a
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-param.exp
@@ -0,0 +1,141 @@
+# Copyright (C) 2010 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/>.
+
+# This file is part of the GDB testsuite. It tests the mechanism
+# exposing convenience functions to Python.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}...
+# Run a test named NAME, consisting of multiple lines of input.
+# After each input line INPUT, search for result line RESULT.
+# Succeed if all results are seen; fail otherwise.
+proc gdb_py_test_multiple {name args} {
+ global gdb_prompt
+ foreach {input result} $args {
+ if {[gdb_test_multiple $input "$name - $input" {
+ -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" {
+ pass "$name - $input"
+ }
+ }]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+# Run a command in GDB, and report a failure if a Python exception is thrown.
+# If report_pass is true, report a pass if no exception is thrown.
+proc gdb_py_test_silent_cmd {cmd name report_pass} {
+ global gdb_prompt
+
+ gdb_test_multiple $cmd $name {
+ -re "Traceback.*$gdb_prompt $" { fail $name }
+ -re "$gdb_prompt $" { if $report_pass { pass $name } }
+ }
+}
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+# Test a simple boolean parameter.
+gdb_py_test_multiple "Simple gdb booleanparameter" \
+ "python" "" \
+ "class TestParam (gdb.Parameter):" "" \
+ " \"\"\"When enabled, test param does something useful. When disabled, does nothing.\"\"\"" "" \
+ " show_doc = \"Show whether the state of the Test Parameter does something useful\"" ""\
+ " set_doc = \"Set whether the state of the Test Parameter does something useful\"" "" \
+ " def __init__ (self, name):" "" \
+ " super (TestParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)" "" \
+ " self.value = True" "" \
+ "test_param = TestParam ('print test-param')" ""\
+ "end"
+
+gdb_test "python print test_param.value" "True" "Test parameter value"
+gdb_test "show print test-param" "Whether the state of the Test Parameter does something useful is on.*" "Show parameter on"
+gdb_py_test_silent_cmd "set print test-param off" "Turn off parameter" 1
+gdb_test "show print test-param" "Whether the state of the Test Parameter does something useful is off.*" "Show parameter off"
+gdb_test "python print test_param.value" "False" "Test parameter value"
+gdb_test "help show print test-param" "Show whether the state of the Test Parameter does something useful.*" "Test show help"
+gdb_test "help set print test-param" "Set whether the state of the Test Parameter does something useful.*" "Test set help"
+gdb_test "help set print" "set print test-param -- Set whether the state of the Test Parameter.*" "Test general help"
+
+# Test an enum parameter.
+gdb_py_test_multiple "enum gdb parameter" \
+ "python" "" \
+ "class TestEnumParam (gdb.Parameter):" "" \
+ " \"\"\"When set, test param does something useful. When disabled, does nothing.\"\"\"" "" \
+ " show_doc = \"Show the state of the enum\"" ""\
+ " set_doc = \"Set the state of the enum\"" "" \
+ " def __init__ (self, name):" "" \
+ " super (TestEnumParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_ENUM, \[\"one\", \"two\"\])" "" \
+ " self.value = \"one\"" "" \
+ "test_enum_param = TestEnumParam ('print test-enum-param')" ""\
+ "end"
+
+gdb_test "python print test_enum_param.value" "one" "Test enum parameter value"
+gdb_test "show print test-enum-param" "The state of the enum is \"one\".*" "Show parameter is initial value"
+gdb_py_test_silent_cmd "set print test-enum-param two" "Set parameter to enum value" 1
+gdb_test "show print test-enum-param" "The state of the enum is \"two\".*" "Show parameter is new value"
+gdb_test "python print test_enum_param.value" "two" "Test enum parameter value"
+gdb_test "set print test-enum-param three" "Undefined item: \"three\".*" "Set invalid enum parameter"
+
+# Test a file parameter.
+gdb_py_test_multiple "file gdb parameter" \
+ "python" "" \
+ "class TestFileParam (gdb.Parameter):" "" \
+ " \"\"\"When set, test param does something useful. When disabled, does nothing.\"\"\"" "" \
+ " show_doc = \"Show the name of the file\"" ""\
+ " set_doc = \"Set the name of the file\"" "" \
+ " def __init__ (self, name):" "" \
+ " super (TestFileParam, self).__init__ (name, gdb.COMMAND_FILES, gdb.PARAM_FILENAME)" "" \
+ " self.value = \"foo.txt\"" "" \
+ "test_file_param = TestFileParam ('test-file-param')" ""\
+ "end"
+
+gdb_test "python print test_file_param.value" "foo.txt" "Test file parameter value"
+gdb_test "show test-file-param" "The name of the file is \"foo.txt\".*" "Show initial file value"
+gdb_py_test_silent_cmd "set test-file-param bar.txt" "Set new file parameter" 1
+gdb_test "show test-file-param" "The name of the file is \"bar.txt\".*" "Show new file value"
+gdb_test "python print test_file_param.value" "bar.txt" "Test new file parameter value"
+gdb_test "set test-file-param" "Argument required.*"
+
+# Test a file parameter.
+gdb_py_test_multiple "file gdb parameter" \
+ "python" "" \
+ "class TestFileParam (gdb.Parameter):" "" \
+ " \"\"\"When set, test param does something useful. When disabled, does nothing.\"\"\"" "" \
+ " show_doc = \"Show the name of the file\"" ""\
+ " set_doc = \"Set the name of the file\"" "" \
+ " def __init__ (self, name):" "" \
+ " super (TestFileParam, self).__init__ (name, gdb.COMMAND_FILES, gdb.PARAM_FILENAME)" "" \
+ " self.value = \"foo.txt\"" "" \
+ "test_file_param = TestFileParam ('test-file-param')" ""\
+ "end"
+
+gdb_test "python print test_file_param.value" "foo.txt" "Test parameter value"
+gdb_test "show test-file-param" "The name of the file is \"foo.txt\".*" "Show parameter on"
+gdb_py_test_silent_cmd "set test-file-param bar.txt" "Turn off parameter" 1
+gdb_test "show test-file-param" "The name of the file is \"bar.txt\".*" "Show parameter on"
+gdb_test "python print test_file_param.value" "bar.txt" "Test parameter value"
+gdb_test "set test-file-param" "Argument required.*"
+gdb_test "set test-file-param None" "Argument required.*"
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-26 13:19 [python][patch] Add GDB Parameters functionality Phil Muldoon
@ 2010-04-26 17:56 ` Eli Zaretskii
2010-04-27 12:26 ` Phil Muldoon
2010-04-26 21:45 ` Tom Tromey
1 sibling, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2010-04-26 17:56 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches
> Date: Mon, 26 Apr 2010 14:19:21 +0100
> From: Phil Muldoon <pmuldoon@redhat.com>
>
> This patch brings over GDB Parameter functionality from the Archer
> project/repository. This functionality remains largely the same; I've
> reintroduced some functionality back into py-cmd that was stripped
> from the last FSF import, and fixed several bugs related to enum
> parameters. It also introduces a new testsuite.
Thanks.
> 2010-04-26 Phil Muldoon <pmuldoon@redhat.com>
> Tom Tromey <tromey@redhat.com>
> Thiago Jung Bauermann <bauerman@br.ibm.com>
>
> * gdb.texinfo (Parameters In Python): New Node.
A few minor comments about this part.
> +You can implement new @value{GDBN} parameters using Python.
This should have a cross-reference to where GDB parameters are
described in the manual (in the "Help" node). Alternatively, add here
a short explanation what are they. (The name is unfortunate; I'd
prefer "options" or "settings", but since we already use "parameters",
so be it.)
> +@var{name} is the name of the new parameter. If @var{name} consists
> +of multiple words, then the initial words are looked for as prefix
> +commands.
An example here would help greatly. I would also suggest to drop the
"commands" part, because we are not talking about commands here.
> +@item PARAM_STRING
> +The value is a string. When the user modifies the string, escapes are
> +translated.
It's not clear what escapes are meant here, and what translation does
to them. I suggest an example or a few words of clarification.
> +@findex PARAM_FILENAME
> +@findex gdb.PARAM_FILENAME
> +@item PARAM_FILENAME
> +The value is a filename (a string).
Is that just a string, or is it somehow different from a string? If
the latter, let's tell what is the difference.
Okay with these changes.
Maybe we should consider mentioning this in NEWS.
Thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-26 13:19 [python][patch] Add GDB Parameters functionality Phil Muldoon
2010-04-26 17:56 ` Eli Zaretskii
@ 2010-04-26 21:45 ` Tom Tromey
2010-04-26 21:52 ` Phil Muldoon
1 sibling, 1 reply; 17+ messages in thread
From: Tom Tromey @ 2010-04-26 21:45 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches ml
>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:
Phil> This patch brings over GDB Parameter functionality from the Archer
Phil> project/repository. This functionality remains largely the same; I've
Phil> reintroduced some functionality back into py-cmd that was stripped
Phil> from the last FSF import, and fixed several bugs related to enum
Phil> parameters. It also introduces a new testsuite.
Phil> OK?
Very nice. Thanks for doing this.
Phil> +gdb_test "set test-file-param None" "Argument required.*"
I don't understand this test. From my reading, test-file-param is a
filename parameter. And, "None" is a valid file name. So why would
this be expected to print an error message?
Tom
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-26 21:45 ` Tom Tromey
@ 2010-04-26 21:52 ` Phil Muldoon
2010-04-27 3:09 ` Tom Tromey
0 siblings, 1 reply; 17+ messages in thread
From: Phil Muldoon @ 2010-04-26 21:52 UTC (permalink / raw)
To: tromey; +Cc: gdb-patches ml
On 04/26/2010 10:45 PM, Tom Tromey wrote:
> Phil> +gdb_test "set test-file-param None" "Argument required.*"
>
> I don't understand this test. From my reading, test-file-param is a
> filename parameter. And, "None" is a valid file name. So why would
> this be expected to print an error message?
Oops it is bogus, should not be there. I was experimenting with
setting None in GDB, but abandoned it. I've removed it from the
testsuite.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-26 21:52 ` Phil Muldoon
@ 2010-04-27 3:09 ` Tom Tromey
0 siblings, 0 replies; 17+ messages in thread
From: Tom Tromey @ 2010-04-27 3:09 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches ml
>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:
Phil> On 04/26/2010 10:45 PM, Tom Tromey wrote:
Phil> +gdb_test "set test-file-param None" "Argument required.*"
>>
>> I don't understand this test. From my reading, test-file-param is a
>> filename parameter. And, "None" is a valid file name. So why would
>> this be expected to print an error message?
Phil> Oops it is bogus, should not be there. I was experimenting with
Phil> setting None in GDB, but abandoned it. I've removed it from the
Phil> testsuite.
Thanks. The updated patch is ok provided the new .exp runs without any
fails.
Tom
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-26 17:56 ` Eli Zaretskii
@ 2010-04-27 12:26 ` Phil Muldoon
2010-04-27 17:45 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Phil Muldoon @ 2010-04-27 12:26 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
On 04/26/2010 06:55 PM, Eli Zaretskii wrote:
>> Date: Mon, 26 Apr 2010 14:19:21 +0100
>> From: Phil Muldoon <pmuldoon@redhat.com>
>>
>> This patch brings over GDB Parameter functionality from the Archer
>> project/repository. This functionality remains largely the same; I've
>> reintroduced some functionality back into py-cmd that was stripped
>> from the last FSF import, and fixed several bugs related to enum
>> parameters. It also introduces a new testsuite.
>
> Thanks.
>
>> 2010-04-26 Phil Muldoon <pmuldoon@redhat.com>
>> Tom Tromey <tromey@redhat.com>
>> Thiago Jung Bauermann <bauerman@br.ibm.com>
>>
>> * gdb.texinfo (Parameters In Python): New Node.
>
> A few minor comments about this part.
>
> Okay with these changes.
Thanks, I've made the changes. I would like you to have another look
at them.
> Maybe we should consider mentioning this in NEWS.
I thought I attached this to the original patch. Here it is in this
patch.
Cheers,
Phil
--
diff --git a/gdb/NEWS b/gdb/NEWS
index 696da2e..fe6b3fc 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -80,7 +80,9 @@ is now deprecated.
* Python scripting
** The GDB Python API now has access to breakpoints, symbols, symbol
- tables, program spaces, and frame's code blocks.
+ tables, program spaces, and frame's code blocks. Additionally, GDB
+ Parameters can now be created from the API, and manipulated via
+ set/show in the CLI.
** New functions gdb.target_charset, gdb.target_wide_charset,
gdb.progspaces, and gdb.current_progspace.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3bb8ef9..e7e8e08 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19926,6 +19926,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
* Pretty Printing API:: Pretty-printing values.
* Selecting Pretty-Printers:: How GDB chooses a pretty-printer.
* Commands In Python:: Implementing new commands in Python.
+* Parameters In Python:: Adding new @value{GDBN} parameters.
* Functions In Python:: Writing new convenience functions.
* Progspaces In Python:: Program spaces.
* Objfiles In Python:: Object files.
@@ -20947,6 +20948,150 @@ registration of the command with @value{GDBN}. Depending on how the
Python code is read into @value{GDBN}, you may need to import the
@code{gdb} module explicitly.
+@node Parameters In Python
+@subsubsection Parameters In Python
+
+@cindex parameters in python
+@cindex python parameters
+@tindex gdb.Parameter
+@tindex Parameter
+You can implement new @value{GDBN} parameters using Python. A new
+parameter is implemented as an instance of the @code{gdb.Parameter}
+class.
+
+Parameters are exposed to the user via the @code{set} and
+@code{show} commands. @xref{Help}.
+
+There are many parameters that already exist and can be set in
+@value{GDBN}. Two examples are: @code{set follow fork} and
+@code{set charset}. Setting these parameters influences certain
+behavior in @value{GDBN}. Similarly, you can define parameters that
+can be used to influence behavior in custom Python scripts and commands.
+
+@defmethod Parameter __init__ name @var{command-class} @var{parameter-class} @r{[}@var{enum-sequence}@r{]}
+The object initializer for @code{Parameter} registers the new
+parameter with @value{GDBN}. This initializer is normally invoked
+from the subclass' own @code{__init__} method.
+
+@var{name} is the name of the new parameter. If @var{name} consists
+of multiple words, then the initial words are looked for as prefix
+parameters. An example of this can be illustrated with the
+@code{set print} set of parameters. If @var{name} is
+@code{print foo}, then @code{print} will be searched as the prefix
+parameter. In this case the parameter can subsequently be accessed in
+@value{GDBN} as @code{set print foo}.
+
+If @var{name} consists of multiple words, and no prefix parameter group
+can be found, an exception is raised.
+
+@var{command-class} should be one of the @samp{COMMAND_} constants
+(@pxref{Commands In Python}). This argument tells @value{GDBN} how to
+categorize the new parameter in the help system.
+
+@var{parameter-class} should be one of the @samp{PARAM_} constants
+defined below. This argument tells @value{GDBN} the type of the new
+parameter; this information is used for input validation and
+completion.
+
+If @var{parameter-class} is @code{PARAM_ENUM}, then
+@var{enum-sequence} must be a sequence of strings. These strings
+represent the possible values for the parameter.
+
+If @var{parameter-class} is not @code{PARAM_ENUM}, then the presence
+of a fourth argument will cause an exception to be thrown.
+
+The help text for the new parameter is taken from the Python
+documentation string for the parameter's class, if there is one. If
+there is no documentation string, a default value is used.
+@end defmethod
+
+@defivar Parameter set_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{set} command. The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter show_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{show} command. The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter value
+The @code{value} attribute holds the underlying value of the
+parameter. It can be read and assigned to just as any other
+attribute. @value{GDBN} does validation when assignments are made.
+@end defivar
+
+
+When a new parameter is defined, its type must be specified. The
+available types are represented by constants defined in the @code{gdb}
+module:
+
+@table @code
+@findex PARAM_BOOLEAN
+@findex gdb.PARAM_BOOLEAN
+@item PARAM_BOOLEAN
+The value is a plain boolean. The Python boolean values, @code{True}
+and @code{False} are the only valid values.
+
+@findex PARAM_AUTO_BOOLEAN
+@findex gdb.PARAM_AUTO_BOOLEAN
+@item PARAM_AUTO_BOOLEAN
+The value has three possible states: true, false, and @samp{auto}. In
+Python, true and false are represented using boolean constants, and
+@samp{auto} is represented using @code{None}.
+
+@findex PARAM_UINTEGER
+@findex gdb.PARAM_UINTEGER
+@item PARAM_UINTEGER
+The value is an unsigned integer. The value of 0 should be
+interpreted to mean ``unlimited''.
+
+@findex PARAM_INTEGER
+@findex gdb.PARAM_INTEGER
+@item PARAM_INTEGER
+The value is a signed integer. The value of 0 should be interpreted
+to mean ``unlimited''.
+
+@findex PARAM_STRING
+@findex gdb.PARAM_STRING
+@item PARAM_STRING
+The value is a string. When the user modifies the string, any escapes
+sequences are translated and encoded by @value{GDBN}.
+
+@findex PARAM_STRING_NOESCAPE
+@findex gdb.PARAM_STRING_NOESCAPE
+@item PARAM_STRING_NOESCAPE
+The value is a string. When the user modifies the string, escapes are
+passed through untranslated.
+
+@findex PARAM_OPTIONAL_FILENAME
+@findex gdb.PARAM_OPTIONAL_FILENAME
+@item PARAM_OPTIONAL_FILENAME
+The value is a either a filename (a string), or @code{None}.
+
+@findex PARAM_FILENAME
+@findex gdb.PARAM_FILENAME
+@item PARAM_FILENAME
+The value is a filename (a string). This value is has to be a valid
+filename.
+
+@findex PARAM_ZINTEGER
+@findex gdb.PARAM_ZINTEGER
+@item PARAM_ZINTEGER
+The value is an integer. This is like @code{PARAM_INTEGER}, except 0
+is interpreted as itself.
+
+@findex PARAM_ENUM
+@findex gdb.PARAM_ENUM
+@item PARAM_ENUM
+The value is a string, which must be one of a collection string
+constants provided when the parameter is created.
+@end table
+
@node Functions In Python
@subsubsection Writing new convenience functions
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-27 12:26 ` Phil Muldoon
@ 2010-04-27 17:45 ` Eli Zaretskii
2010-04-27 19:25 ` Phil Muldoon
0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2010-04-27 17:45 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches
> Date: Mon, 26 Apr 2010 14:19:21 +0100
> From: Phil Muldoon <pmuldoon@redhat.com>
>
> Thanks, I've made the changes. I would like you to have another look
> at them.
See below.
> > Maybe we should consider mentioning this in NEWS.
>
>
> I thought I attached this to the original patch.
Indeed, you did. Sorry that I missed it. It is okay.
> +Parameters are exposed to the user via the @code{set} and
> +@code{show} commands. @xref{Help}.
^^
Two spaces, please.
> +@item PARAM_STRING
> +The value is a string. When the user modifies the string, any escapes
> +sequences are translated and encoded by @value{GDBN}.
I asked to say something about this translation, or provide an
example.
> +@item PARAM_FILENAME
> +The value is a filename (a string). This value is has to be a valid
> +filename. ^^
The "is" part is probably redundant. Also, what does it mean "a valid
filename"? Does it have to exist, for example? If not, what makes a
file name "invalid"?
Thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-27 17:45 ` Eli Zaretskii
@ 2010-04-27 19:25 ` Phil Muldoon
2010-04-27 19:36 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Phil Muldoon @ 2010-04-27 19:25 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
On 04/27/2010 06:44 PM, Eli Zaretskii wrote:
>> +@item PARAM_STRING
>> +The value is a string. When the user modifies the string, any escapes
>> +sequences are translated and encoded by @value{GDBN}.
>
> I asked to say something about this translation, or provide an
> example.
I'm just not sure what to say other than GDB will translate and encode
any escape sequences in the string. In fact, 'encoded' will probably
just do here without the 'translated' verb - it seems redundant with
the new encoded text. I think that is clearer. How about that with a
cross-reference to encoding (pxref{Character Sets})?
>> +@item PARAM_FILENAME
>> +The value is a filename (a string). This value is has to be a valid
>> +filename. ^^
>
> The "is" part is probably redundant. Also, what does it mean "a valid
> filename"? Does it have to exist, for example? If not, what makes a
> file name "invalid"?
I looked a little deeper at this. There is no validation (I was
initially wrong, apologies). Furthermore, it does not have to be a
valid filename at all -- just a string. Validation is presumably
offloaded to the Parameter to check. Anyway, it is a simple
string. The classification of Parameter type in these cases is purely
to do with how completion works -- if the user chooses to use
completion. So 'set foo somefil<tab>' will complete looking for
filenames:
Eg:
(gdb) set logging file ~/log<TAB>
log.txt log2.txt
Whereas for a Parameter with the type PARAM_BOOLEAN (like set verbose)
it would complete like so:
(gdb) set verbose o<TAB>
off on
Now that being said, I'm a little stumped how to explain all of this
within the context of these parameter types. Do you have any input
here?
Cheers
Phil
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-27 19:25 ` Phil Muldoon
@ 2010-04-27 19:36 ` Eli Zaretskii
2010-04-27 20:05 ` Phil Muldoon
0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2010-04-27 19:36 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches
> Date: Tue, 27 Apr 2010 20:24:55 +0100
> From: Phil Muldoon <pmuldoon@redhat.com>
> CC: gdb-patches@sourceware.org
>
> On 04/27/2010 06:44 PM, Eli Zaretskii wrote:
>
> >> +@item PARAM_STRING
> >> +The value is a string. When the user modifies the string, any escapes
> >> +sequences are translated and encoded by @value{GDBN}.
> >
> > I asked to say something about this translation, or provide an
> > example.
>
> I'm just not sure what to say other than GDB will translate and encode
> any escape sequences in the string. In fact, 'encoded' will probably
> just do here without the 'translated' verb - it seems redundant with
> the new encoded text. I think that is clearer. How about that with a
> cross-reference to encoding (pxref{Character Sets})?
Can you give me a couple of examples of this "translation"? Then I
could suggest some simple explanation.
> The classification of Parameter type in these cases is purely
> to do with how completion works -- if the user chooses to use
> completion. So 'set foo somefil<tab>' will complete looking for
> filenames:
>
> Eg:
>
> (gdb) set logging file ~/log<TAB>
> log.txt log2.txt
>
> Whereas for a Parameter with the type PARAM_BOOLEAN (like set verbose)
> it would complete like so:
>
> (gdb) set verbose o<TAB>
> off on
>
> Now that being said, I'm a little stumped how to explain all of this
> within the context of these parameter types. Do you have any input
> here?
How about
The value is a filename. This is just like @code{PARAM_STRING}, but
uses file names for completion.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-27 19:36 ` Eli Zaretskii
@ 2010-04-27 20:05 ` Phil Muldoon
2010-04-28 2:59 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Phil Muldoon @ 2010-04-27 20:05 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
On 04/27/2010 08:36 PM, Eli Zaretskii wrote:
>>> I asked to say something about this translation, or provide an
>>> example.
>>
>> I'm just not sure what to say other than GDB will translate and encode
>> any escape sequences in the string. In fact, 'encoded' will probably
>> just do here without the 'translated' verb - it seems redundant with
>> the new encoded text. I think that is clearer. How about that with a
>> cross-reference to encoding (pxref{Character Sets})?
>
> Can you give me a couple of examples of this "translation"? Then I
> could suggest some simple explanation.
The simplest example I can think of is escaping octal to print
characters. So take this super simple string parameter:
class TestStringParam (gdb.Parameter):
show_doc = "Show some string"
set_doc = "Set some string"
def __init__ (self, name):
super (TestStringParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_STRING)
self.value = "foo"
test_file_param = TestStringParam ('test-string-param')
Invoke it in GDB via the python command:
(gdb) python
>class TestStringParam (gdb.Parameter):
> show_doc = "Show some string"
> set_doc = "Set some string"
> def __init__ (self, name):
> super (TestStringParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_STRING)
> self.value = "foo"
>test_file_param = TestStringParam ('test-string-param')
>end
Now test it:
(gdb) set test-string-param plain old text
(gdb) show test-string-para
Some string is "plain old text".
(gdb) set test-string-param \107\157\157\144\040\104\141\171 sir!
(gdb) show test-string-para
Some string is "Good Day sir!".
Does that help?
Cheers,
Phil
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-27 20:05 ` Phil Muldoon
@ 2010-04-28 2:59 ` Eli Zaretskii
2010-04-28 6:28 ` Phil Muldoon
0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2010-04-28 2:59 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches
> Date: Tue, 27 Apr 2010 21:05:35 +0100
> From: Phil Muldoon <pmuldoon@redhat.com>
> CC: gdb-patches@sourceware.org
>
> > Can you give me a couple of examples of this "translation"? Then I
> > could suggest some simple explanation.
>
> The simplest example I can think of is escaping octal to print
> characters.
Thanks, but I'm sure this feature was not introduced for such trivial
uses. Can you give a slightly more useful example? Is this similar
to C escapes in strings, such as \f, \n, etc., for example?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-28 2:59 ` Eli Zaretskii
@ 2010-04-28 6:28 ` Phil Muldoon
2010-04-28 9:18 ` Phil Muldoon
0 siblings, 1 reply; 17+ messages in thread
From: Phil Muldoon @ 2010-04-28 6:28 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
On 04/28/2010 03:58 AM, Eli Zaretskii wrote:
>> Date: Tue, 27 Apr 2010 21:05:35 +0100
>> From: Phil Muldoon <pmuldoon@redhat.com>
>> CC: gdb-patches@sourceware.org
>>
>>> Can you give me a couple of examples of this "translation"? Then I
>>> could suggest some simple explanation.
>>
>> The simplest example I can think of is escaping octal to print
>> characters.
>
> Thanks, but I'm sure this feature was not introduced for such trivial
> uses. Can you give a slightly more useful example? Is this similar
> to C escapes in strings, such as \f, \n, etc., for example?
It does not do anything beyond what GDB does normally to strings that
have escape sequences, (that is, the Parameter functionality is
decoupled from the escape translation itself, this is GDB's encoding
mechanism).
A simple print command:
(gdb) print "\107\157\157\144\040\104\141\171"
$1 = "Good Day"
This is the same behaviour as the PARAM_STRING sequence in the
previous email.
This is different to PARAM_STRING_NOESCAPE. This just takes escape
sequences as literal, I.E.:
(gdb) set test-nestring-param \107\157\157\144\040\104\141\171
(gdb) show test-nestring-param
Some string is "\107\157\157\144\040\104\141\171".
I've no idea what escapes are allowed in the print/set/show
output commands, over what is allowed in say the echo command (for
example /t /n are just literals in the print command above, but have
meaning in the echo command). I suspect this is just a mechanism to
allow multi-byte characters to be passed to a Parameter, but that is
just a guess. I've looked and looked into the manual for a node
explaining this, but cannot find it. From the point of view of
parameters the difference is clear, PARAM_STRING will allow escapes to
be translated (or encoded or whatever verb we apply here), whereas
PARAM_STRING_NOESCAPE will not. I'm not sure what node to point to
too explain this or what example to give.
Cheers,
Phil
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-28 6:28 ` Phil Muldoon
@ 2010-04-28 9:18 ` Phil Muldoon
2010-04-28 17:15 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Phil Muldoon @ 2010-04-28 9:18 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
On 04/28/2010 07:28 AM, Phil Muldoon wrote:
> I've no idea what escapes are allowed in the print/set/show
> output commands,
I decided after I wrote this to decipher how GDB prints and interprets
escape sequences in strings.
When a set or a show command is invoked from the command line,
'do_setshow_command' is called from cli/cli-setshow.c. This handles
the set and show commands. Depending on the parameter type, the input
passed to the set/show command from the CLI is handled in different
ways.
In the case of PARAM_STRING (which directly maps to the GDB enum
var_type {var_string} (found in command.h)), the string is parsed one
character at a time. If the character being currently processed equals
a '\', parse_escape (utils.c) is called with the pointer to the string
that points to this character as an argument. The parse_escape
function seems to be called during most output emitted by GDB. In
parse escape, the character after the '\' is fetched, and that
character runs through an a switch.
If the case is a literal octal, the next two characters are fetched
and converted to the character the octal escape sequence
represents. (i.e. in our example \107 will be translated to 'G')
If the character is an a,b,f,n,r,t, or v then that character is
returned as '\a', or '\b', or '\f' and so on. This means that in the
string 'Good\tDay', \t will be processed and returned as it is. So C
escape characters are acknowledged and returned intact.
If the character is a null (\0), parse_escape will return with a -2.
With the corresponding show command, do_setshow_command is also
called. In this case if the parameter type is PARAM_STRING the output
is processed via fputstr_filtered (utils.c). Even though the C control
characters have been processed and kept intact with the set_command,
this function (fputstr_filtered) will quote as literals any embedded
escape sequences in the string. For example, if you 'set foo
\107ood\nMorning', the corresponding output from 'show foo' will be
"Good\nMorning". The control character is there, and is valid, but
fputstr_filtered ignores it and prints it literally. If this output
were to be captured some other way and processed via echo, the escape
sequence is translated into an action and you would get:
"Good
Morning"
I hope this helps. Trying to understand when and how and why
different escape sequences are handled within GDB (in different ways,
at seemingly different times) is a bit cryptic.
Cheers,
Phil
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-28 9:18 ` Phil Muldoon
@ 2010-04-28 17:15 ` Eli Zaretskii
2010-04-28 20:31 ` Phil Muldoon
0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2010-04-28 17:15 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches
> Date: Wed, 28 Apr 2010 10:17:50 +0100
> From: Phil Muldoon <pmuldoon@redhat.com>
> CC: gdb-patches@sourceware.org
>
> In the case of PARAM_STRING (which directly maps to the GDB enum
> var_type {var_string} (found in command.h)), the string is parsed one
> character at a time. If the character being currently processed equals
> a '\', parse_escape (utils.c) is called with the pointer to the string
> that points to this character as an argument. The parse_escape
> function seems to be called during most output emitted by GDB. In
> parse escape, the character after the '\' is fetched, and that
> character runs through an a switch.
>
> If the case is a literal octal, the next two characters are fetched
> and converted to the character the octal escape sequence
> represents. (i.e. in our example \107 will be translated to 'G')
>
> If the character is an a,b,f,n,r,t, or v then that character is
> returned as '\a', or '\b', or '\f' and so on. This means that in the
> string 'Good\tDay', \t will be processed and returned as it is. So C
> escape characters are acknowledged and returned intact.
Thank you for your effort. In that case, I suggest the following
text:
@item PARAM_STRING
The value is a string. When the user modifies the string, any escape
sequences, such as @samp{\t}, @samp{\f}, and octal escapes, are
translated into corresponding characters and encoded into the current
host charset.
(Is it true that GDB encodes into host charset? If not, please modify
as appropriate.)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-28 17:15 ` Eli Zaretskii
@ 2010-04-28 20:31 ` Phil Muldoon
2010-04-29 3:06 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Phil Muldoon @ 2010-04-28 20:31 UTC (permalink / raw)
To: Eli Zaretskii, gdb-patches ml
On 04/28/2010 06:15 PM, Eli Zaretskii wrote:
>
> Thank you for your effort. In that case, I suggest the following
> text:
>
> @item PARAM_STRING
Thanks for looking at it. I've included a modified patch encompassing
all of the requested changes. Is this OK?
Cheers,
Phil
---
diff --git a/gdb/NEWS b/gdb/NEWS
index 696da2e..fe6b3fc 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -80,7 +80,9 @@ is now deprecated.
* Python scripting
** The GDB Python API now has access to breakpoints, symbols, symbol
- tables, program spaces, and frame's code blocks.
+ tables, program spaces, and frame's code blocks. Additionally, GDB
+ Parameters can now be created from the API, and manipulated via
+ set/show in the CLI.
** New functions gdb.target_charset, gdb.target_wide_charset,
gdb.progspaces, and gdb.current_progspace.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3bb8ef9..e5bf0f5 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19926,6 +19926,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
* Pretty Printing API:: Pretty-printing values.
* Selecting Pretty-Printers:: How GDB chooses a pretty-printer.
* Commands In Python:: Implementing new commands in Python.
+* Parameters In Python:: Adding new @value{GDBN} parameters.
* Functions In Python:: Writing new convenience functions.
* Progspaces In Python:: Program spaces.
* Objfiles In Python:: Object files.
@@ -20947,6 +20948,152 @@ registration of the command with @value{GDBN}. Depending on how the
Python code is read into @value{GDBN}, you may need to import the
@code{gdb} module explicitly.
+@node Parameters In Python
+@subsubsection Parameters In Python
+
+@cindex parameters in python
+@cindex python parameters
+@tindex gdb.Parameter
+@tindex Parameter
+You can implement new @value{GDBN} parameters using Python. A new
+parameter is implemented as an instance of the @code{gdb.Parameter}
+class.
+
+Parameters are exposed to the user via the @code{set} and
+@code{show} commands. @xref{Help}.
+
+There are many parameters that already exist and can be set in
+@value{GDBN}. Two examples are: @code{set follow fork} and
+@code{set charset}. Setting these parameters influences certain
+behavior in @value{GDBN}. Similarly, you can define parameters that
+can be used to influence behavior in custom Python scripts and commands.
+
+@defmethod Parameter __init__ name @var{command-class} @var{parameter-class} @r{[}@var{enum-sequence}@r{]}
+The object initializer for @code{Parameter} registers the new
+parameter with @value{GDBN}. This initializer is normally invoked
+from the subclass' own @code{__init__} method.
+
+@var{name} is the name of the new parameter. If @var{name} consists
+of multiple words, then the initial words are looked for as prefix
+parameters. An example of this can be illustrated with the
+@code{set print} set of parameters. If @var{name} is
+@code{print foo}, then @code{print} will be searched as the prefix
+parameter. In this case the parameter can subsequently be accessed in
+@value{GDBN} as @code{set print foo}.
+
+If @var{name} consists of multiple words, and no prefix parameter group
+can be found, an exception is raised.
+
+@var{command-class} should be one of the @samp{COMMAND_} constants
+(@pxref{Commands In Python}). This argument tells @value{GDBN} how to
+categorize the new parameter in the help system.
+
+@var{parameter-class} should be one of the @samp{PARAM_} constants
+defined below. This argument tells @value{GDBN} the type of the new
+parameter; this information is used for input validation and
+completion.
+
+If @var{parameter-class} is @code{PARAM_ENUM}, then
+@var{enum-sequence} must be a sequence of strings. These strings
+represent the possible values for the parameter.
+
+If @var{parameter-class} is not @code{PARAM_ENUM}, then the presence
+of a fourth argument will cause an exception to be thrown.
+
+The help text for the new parameter is taken from the Python
+documentation string for the parameter's class, if there is one. If
+there is no documentation string, a default value is used.
+@end defmethod
+
+@defivar Parameter set_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{set} command. The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter show_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{show} command. The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter value
+The @code{value} attribute holds the underlying value of the
+parameter. It can be read and assigned to just as any other
+attribute. @value{GDBN} does validation when assignments are made.
+@end defivar
+
+
+When a new parameter is defined, its type must be specified. The
+available types are represented by constants defined in the @code{gdb}
+module:
+
+@table @code
+@findex PARAM_BOOLEAN
+@findex gdb.PARAM_BOOLEAN
+@item PARAM_BOOLEAN
+The value is a plain boolean. The Python boolean values, @code{True}
+and @code{False} are the only valid values.
+
+@findex PARAM_AUTO_BOOLEAN
+@findex gdb.PARAM_AUTO_BOOLEAN
+@item PARAM_AUTO_BOOLEAN
+The value has three possible states: true, false, and @samp{auto}. In
+Python, true and false are represented using boolean constants, and
+@samp{auto} is represented using @code{None}.
+
+@findex PARAM_UINTEGER
+@findex gdb.PARAM_UINTEGER
+@item PARAM_UINTEGER
+The value is an unsigned integer. The value of 0 should be
+interpreted to mean ``unlimited''.
+
+@findex PARAM_INTEGER
+@findex gdb.PARAM_INTEGER
+@item PARAM_INTEGER
+The value is a signed integer. The value of 0 should be interpreted
+to mean ``unlimited''.
+
+@findex PARAM_STRING
+@findex gdb.PARAM_STRING
+@item PARAM_STRING
+The value is a string. When the user modifies the string, any escape
+sequences, such as @samp{\t}, @samp{\f}, and octal escapes, are
+translated into corresponding characters and encoded into the current
+host charset.
+
+@findex PARAM_STRING_NOESCAPE
+@findex gdb.PARAM_STRING_NOESCAPE
+@item PARAM_STRING_NOESCAPE
+The value is a string. When the user modifies the string, escapes are
+passed through untranslated.
+
+@findex PARAM_OPTIONAL_FILENAME
+@findex gdb.PARAM_OPTIONAL_FILENAME
+@item PARAM_OPTIONAL_FILENAME
+The value is a either a filename (a string), or @code{None}.
+
+@findex PARAM_FILENAME
+@findex gdb.PARAM_FILENAME
+@item PARAM_FILENAME
+The value is a filename. This is just like
+@code{PARAM_STRING_NOESCAPE}, but uses file names for completion.
+
+@findex PARAM_ZINTEGER
+@findex gdb.PARAM_ZINTEGER
+@item PARAM_ZINTEGER
+The value is an integer. This is like @code{PARAM_INTEGER}, except 0
+is interpreted as itself.
+
+@findex PARAM_ENUM
+@findex gdb.PARAM_ENUM
+@item PARAM_ENUM
+The value is a string, which must be one of a collection string
+constants provided when the parameter is created.
+@end table
+
@node Functions In Python
@subsubsection Writing new convenience functions
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-28 20:31 ` Phil Muldoon
@ 2010-04-29 3:06 ` Eli Zaretskii
2010-04-29 16:13 ` Phil Muldoon
0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2010-04-29 3:06 UTC (permalink / raw)
To: Phil Muldoon; +Cc: gdb-patches
> Date: Wed, 28 Apr 2010 21:31:20 +0100
> From: Phil Muldoon <pmuldoon@redhat.com>
>
> Thanks for looking at it. I've included a modified patch encompassing
> all of the requested changes. Is this OK?
Yes, thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [python][patch] Add GDB Parameters functionality
2010-04-29 3:06 ` Eli Zaretskii
@ 2010-04-29 16:13 ` Phil Muldoon
0 siblings, 0 replies; 17+ messages in thread
From: Phil Muldoon @ 2010-04-29 16:13 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches, tromey
On Thu, Apr 29, 2010 at 06:06:00AM +0300, Eli Zaretskii wrote:
> > Thanks for looking at it. I've included a modified patch encompassing
> > all of the requested changes. Is this OK?
>
> Yes, thanks.
On Mon, Apr 26, 2010 at 09:09:45PM -0600, Tom Tromey wrote:
> Thanks. The updated patch is ok provided the new .exp runs without any
> fails.
So committed. Thanks for the reviews.
Cheers,
Phil
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2010-04-29 16:13 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-26 13:19 [python][patch] Add GDB Parameters functionality Phil Muldoon
2010-04-26 17:56 ` Eli Zaretskii
2010-04-27 12:26 ` Phil Muldoon
2010-04-27 17:45 ` Eli Zaretskii
2010-04-27 19:25 ` Phil Muldoon
2010-04-27 19:36 ` Eli Zaretskii
2010-04-27 20:05 ` Phil Muldoon
2010-04-28 2:59 ` Eli Zaretskii
2010-04-28 6:28 ` Phil Muldoon
2010-04-28 9:18 ` Phil Muldoon
2010-04-28 17:15 ` Eli Zaretskii
2010-04-28 20:31 ` Phil Muldoon
2010-04-29 3:06 ` Eli Zaretskii
2010-04-29 16:13 ` Phil Muldoon
2010-04-26 21:45 ` Tom Tromey
2010-04-26 21:52 ` Phil Muldoon
2010-04-27 3:09 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox