gdb/
authorThiago Jung Bauermann <bauerman@br.ibm.com>
Sat, 21 Mar 2009 03:13:02 +0000 (03:13 +0000)
committerThiago Jung Bauermann <bauerman@br.ibm.com>
Sat, 21 Mar 2009 03:13:02 +0000 (03:13 +0000)
2009-03-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
    Jim Blandy  <jimb@red-bean.com>
    Thiago Jung Bauermann  <bauerman@br.ibm.com>
    Tom Tromey  <tromey@redhat.com>

Miscellaneous fixes to the Python code.
* python/python-cmd.c (cmdpy_init): Accept keyword
arguments.
* python/python-value.c (valpy_string): Accept keyword
arguments.
(valpy_binop): Use `break' to exit from the TRY_CATCH block.
Do not call value_to_value_object on NULL RES_VAL.
(value_object_methods): Change `string' entry to also accept
keyword arguments.
(convert_value_from_python): Return a copy of the value if obj is
a gdb.Value object.
(value_object_methods): Mark the `string' method as accepting
keywords, and show method "prototype" in the doc string.
* python/python.c (get_parameter): Don't return inside a
TRY_CATCH.

gdb/doc/
2009-03-21  Thiago Jung Bauermann  <bauerman@br.ibm.com>

* gdb.texinfo (Values From Inferior): Fix optional arguments
markup.
(Commands In Python): Adjust argument names of gdb.Command.__init__
to what the function accepts as keywords.

gdb/testsuite/
2009-03-21  Thiago Jung Bauermann  <bauerman@br.ibm.com>

* gdb.python/python-cmd.exp: Add tests for keyword arguments.
* gdb.python/python-function.exp: Add test for function returning
a GDB value.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/python/python-cmd.c
gdb/python/python-value.c
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/python-cmd.exp
gdb/testsuite/gdb.python/python-function.exp

index c54203951ed8dcc1f0f466ecc27464a4063c00b0..e9b369538da6e48cbd45906d8fc02f25e786a6b2 100644 (file)
@@ -1,3 +1,24 @@
+2009-03-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
+           Jim Blandy  <jimb@red-bean.com>
+           Thiago Jung Bauermann  <bauerman@br.ibm.com>
+           Tom Tromey  <tromey@redhat.com>
+
+       Miscellaneous fixes to the Python code.
+       * python/python-cmd.c (cmdpy_init): Accept keyword
+       arguments.
+       * python/python-value.c (valpy_string): Accept keyword
+       arguments.
+       (valpy_binop): Use `break' to exit from the TRY_CATCH block.
+       Do not call value_to_value_object on NULL RES_VAL.
+       (value_object_methods): Change `string' entry to also accept
+       keyword arguments.
+       (convert_value_from_python): Return a copy of the value if obj is
+       a gdb.Value object.
+       (value_object_methods): Mark the `string' method as accepting
+       keywords, and show method "prototype" in the doc string.
+       * python/python.c (get_parameter): Don't return inside a
+       TRY_CATCH.
+
 2009-03-20  Tom Tromey  <tromey@redhat.com>
 
        Add support for convenience functions in Python.
index f8ed002ee4d8a8ea01b4fe2d02d8422192a6180a..f8b25723998fc371941182c0dba9264c20438fcb 100644 (file)
@@ -1,3 +1,10 @@
+2009-03-21  Thiago Jung Bauermann  <bauerman@br.ibm.com>
+
+       * gdb.texinfo (Values From Inferior): Fix optional arguments
+       markup.
+       (Commands In Python): Adjust argument names of gdb.Command.__init__
+       to what the function accepts as keywords.
+
 2008-03-20  Tom Tromey  <tromey@redhat.com>
 
        * gdb.texinfo (Convenience Vars): Document convenience functions.
index 7684092122f63c15fc6efb806553b43d914c0269..00ca651bcdca37d477371e0df5e2067ce73b9aa3 100644 (file)
@@ -18348,7 +18348,7 @@ The result @code{bar} will be a @code{gdb.Value} object holding the
 value pointed to by @code{foo}.
 @end defmethod
 
-@defmethod Value string @r{[}encoding @r{[}errors@r{]}@r{]}
+@defmethod Value string @r{[}encoding@r{]} @r{[}errors@r{]}
 If this @code{gdb.Value} represents a string, then this method
 converts the contents to a Python string.  Otherwise, this method will
 throw an exception.
@@ -18384,7 +18384,7 @@ You can implement new @value{GDBN} CLI commands in Python.  A CLI
 command is implemented using an instance of the @code{gdb.Command}
 class, most commonly using a subclass.
 
-@defmethod Command __init__ name @var{command-class} @r{[}@var{completer-class} @var{prefix}@r{]}
+@defmethod Command __init__ name @var{command_class} @r{[}@var{completer_class}@r{]} @r{[}@var{prefix}@r{]}
 The object initializer for @code{Command} registers the new command
 with @value{GDBN}.  This initializer is normally invoked from the
 subclass' own @code{__init__} method.
@@ -18396,11 +18396,11 @@ an exception is raised.
 
 There is no support for multi-line commands.
 
-@var{command-class} should be one of the @samp{COMMAND_} constants
+@var{command_class} should be one of the @samp{COMMAND_} constants
 defined below.  This argument tells @value{GDBN} how to categorize the
 new command in the help system.
 
-@var{completer-class} is an optional argument.  If given, it should be
+@var{completer_class} is an optional argument.  If given, it should be
 one of the @samp{COMPLETE_} constants defined below.  This argument
 tells @value{GDBN} how to perform completion for this command.  If not
 given, @value{GDBN} will attempt to complete using the object's
index 36cde3434989d5de64e1c24893ed1f60f984e489..8f59a2220f14b517976451b6f2cc2aaa5ed0f519 100644 (file)
@@ -336,16 +336,16 @@ parse_command_name (char *text, struct cmd_list_element ***base_list)
 
 /* Object initializer; sets up gdb-side structures for command.
 
-   Use: __init__(NAME, CMDCLASS, [COMPLETERCLASS, [PREFIX]]).
+   Use: __init__(NAME, COMMAND_CLASS [, COMPLETER_CLASS][, PREFIX]]).
 
    NAME is the name of the command.  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_*
+   COMMAND_CLASS is the kind of command.  It should be one of the COMMAND_*
    constants defined in the gdb module.
 
-   COMPLETERCLASS is the kind of completer.  If not given, the
+   COMPLETER_CLASS is the kind of completer.  If not given, the
    "complete" method will be used.  Otherwise, it should be one of the
    COMPLETE_* constants defined in the gdb module.
 
@@ -356,7 +356,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list)
    
 */
 static int
-cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds)
+cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
 {
   cmdpy_object *obj = (cmdpy_object *) self;
   char *name;
@@ -366,6 +366,8 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds)
   volatile struct gdb_exception except;
   struct cmd_list_element **cmd_list;
   char *cmd_name, *pfx_name;
+  static char *keywords[] = { "name", "command_class", "completer_class",
+                             "prefix", NULL };
   PyObject *is_prefix = NULL;
   int cmp;
 
@@ -378,7 +380,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds)
       return -1;
     }
 
-  if (! PyArg_ParseTuple (args, "si|iO", &name, &cmdtype,
+  if (! PyArg_ParseTupleAndKeywords (args, kw, "si|iO", keywords, &name, &cmdtype,
                          &completetype, &is_prefix))
     return -1;
 
index bc077b6736d0eb0cfcf0721f428f1ac2e0b7918c..cbc481fa9826e8736bc494d8895c622b63265a64 100644 (file)
@@ -143,10 +143,11 @@ valpy_address (PyObject *self, PyObject *args)
   return value_to_value_object (res_val);
 }
 
-/* Return Unicode string with value contents (assumed to be encoded in the
-   target's charset).  */
+/* Implementation of gdb.Value.string ([encoding] [, errors]) -> string
+   Return Unicode string with value contents.  If ENCODING is not given,
+   the string is assumed to be encoded in the target's charset.  */
 static PyObject *
-valpy_string (PyObject *self, PyObject *args)
+valpy_string (PyObject *self, PyObject *args, PyObject *kw)
 {
   int length, ret = 0;
   gdb_byte *buffer;
@@ -157,8 +158,10 @@ valpy_string (PyObject *self, PyObject *args)
   const char *errors = NULL;
   const char *user_encoding = NULL;
   const char *la_encoding = NULL;
+  static char *keywords[] = { "encoding", "errors" };
 
-  if (!PyArg_ParseTuple (args, "|ss", &user_encoding, &errors))
+  if (!PyArg_ParseTupleAndKeywords (args, kw, "|ss", keywords,
+                                   &user_encoding, &errors))
     return NULL;
 
   TRY_CATCH (except, RETURN_MASK_ALL)
@@ -306,11 +309,11 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
         a gdb.Value object and need to convert it from python as well.  */
       arg1 = convert_value_from_python (self);
       if (arg1 == NULL)
-       return NULL;
+       break;
 
       arg2 = convert_value_from_python (other);
       if (arg2 == NULL)
-       return NULL;
+       break;
 
       switch (opcode)
        {
@@ -387,7 +390,7 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
-  return value_to_value_object (res_val);
+  return res_val ? value_to_value_object (res_val) : NULL;
 }
 
 static PyObject *
@@ -774,7 +777,7 @@ convert_value_from_python (PyObject *obj)
            }
        }
       else if (PyObject_TypeCheck (obj, &value_object_type))
-       value = ((value_object *) obj)->value;
+       value = value_copy (((value_object *) obj)->value);
       else
        PyErr_Format (PyExc_TypeError, _("Could not convert Python object: %s"),
                      PyString_AsString (PyObject_Str (obj)));
@@ -825,8 +828,9 @@ gdbpy_initialize_values (void)
 static PyMethodDef value_object_methods[] = {
   { "address", valpy_address, METH_NOARGS, "Return the address of the value." },
   { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
-  { "string", valpy_string, METH_VARARGS,
-    "Return Unicode string representation of the value." },
+  { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
+    "string ([encoding] [, errors]) -> string\n\
+Return Unicode string representation of the value." },
   {NULL}  /* Sentinel */
 };
 
index 29f83bb1c39f5246ffdbfa6bff63468f48b6cd31..b48cf05a4e52b9cdbe27f17d23341fc7e076327e 100644 (file)
@@ -206,6 +206,7 @@ get_parameter (PyObject *self, PyObject *args)
 {
   struct cmd_list_element *alias, *prefix, *cmd;
   char *arg, *newarg;
+  int found = -1;
   volatile struct gdb_exception except;
 
   if (! PyArg_ParseTuple (args, "s", &arg))
@@ -215,15 +216,13 @@ get_parameter (PyObject *self, PyObject *args)
 
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
-      if (! lookup_cmd_composition (newarg, &alias, &prefix, &cmd))
-       {
-         xfree (newarg);
-         return PyErr_Format (PyExc_RuntimeError,
-                              "could not find variable `%s'", arg);
-       }
+      found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
     }
   xfree (newarg);
   GDB_PY_HANDLE_EXCEPTION (except);
+  if (!found)
+    return PyErr_Format (PyExc_RuntimeError,
+                        "could not find parameter `%s'", arg);
 
   if (! cmd->var)
     return PyErr_Format (PyExc_RuntimeError, "`%s' is not a variable", arg);
index 2e65c443203bd832bab5d07659e1bd773882592f..3de72c485be33a1768348e54356cdf46672a6f43 100644 (file)
@@ -1,3 +1,9 @@
+2009-03-21  Thiago Jung Bauermann  <bauerman@br.ibm.com>
+
+       * gdb.python/python-cmd.exp: Add tests for keyword arguments.
+       * gdb.python/python-function.exp: Add test for function returning
+       a GDB value.
+
 2009-03-20  Thiago Jung Bauermann  <bauerman@br.ibm.com>
 
        * gdb.python/python-function.exp: New file.
index 6c73ff2473c71402cfdc3a394ef5467ef5ab8063..f6ef938f48af4e40db1e119226670c2100748e01 100644 (file)
@@ -92,6 +92,32 @@ gdb_py_test_multiple "input subcommand" \
 
 gdb_test "prefix_cmd subcmd ugh" "subcmd output, arg = ugh" "call subcmd"
 
+# Test prefix command using keyword arguments.
+
+gdb_py_test_multiple "input prefix command, keyword arguments" \
+  "python" "" \
+  "class prefix_cmd2 (gdb.Command):" "" \
+  "  def __init__ (self):" "" \
+  "    super (prefix_cmd2, self).__init__ (\"prefix_cmd2\", gdb.COMMAND_OBSCURE, prefix = True, completer_class = gdb.COMPLETE_FILENAME)" "" \
+  "  def invoke (self, arg, from_tty):" "" \
+  "    print \"prefix_cmd2 output, arg = %s\" % arg" "" \
+  "prefix_cmd2 ()" "" \
+  "end" ""
+
+gdb_test "prefix_cmd2 argh" "prefix_cmd2 output, arg = argh" "call prefix command, keyword arguments"
+
+gdb_py_test_multiple "input subcommand under prefix_cmd2" \
+  "python" "" \
+  "class subcmd (gdb.Command):" "" \
+  "  def __init__ (self):" "" \
+  "    super (subcmd, self).__init__ (\"prefix_cmd2 subcmd\", gdb.COMMAND_OBSCURE)" "" \
+  "  def invoke (self, arg, from_tty):" "" \
+  "    print \"subcmd output, arg = %s\" % arg" "" \
+  "subcmd ()" "" \
+  "end" ""
+
+gdb_test "prefix_cmd2 subcmd ugh" "subcmd output, arg = ugh" "call subcmd under prefix_cmd2"
+
 # Test a subcommand in an existing GDB prefix.
 
 gdb_py_test_multiple "input new subcommand" \
index 3ffc5aa36f990986dc76c5065f7b9e9cc9886b6d..7feca2b6aad75a7cb0e14c6e5903ed15d81bb178 100644 (file)
@@ -63,3 +63,17 @@ gdb_py_test_multiple "input convenience function" \
   "end" ""
 
 gdb_test "print \$test_func (\"ugh\")" "= \"test_func output, arg = ugh\"" "call function"
+
+# Test returning a gdb.Value from the function. This segfaulted GDB at one point.
+
+gdb_py_test_multiple "input value-returning convenience function" \
+  "python" "" \
+  "class Double (gdb.Function):" "" \
+  "  def __init__ (self):" "" \
+  "    super (Double, self).__init__ (\"double\")" "" \
+  "  def invoke (self, n):" "" \
+  "    return n*2" "" \
+  "Double ()" "" \
+  "end" ""
+
+gdb_test "print \$double (1)" "= 2" "call value-returning function"