This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC/Patch] PR 16113: Allow gdb.Field objects as subscripts on gdb.Value objects
- From: Phil Muldoon <pmuldoon at redhat dot com>
- To: Siva Chandra <sivachandra at google dot com>, gdb-patches <gdb-patches at sourceware dot org>
- Date: Mon, 09 Dec 2013 10:30:28 +0000
- Subject: Re: [RFC/Patch] PR 16113: Allow gdb.Field objects as subscripts on gdb.Value objects
- Authentication-results: sourceware.org; auth=none
- References: <CAGyQ6gxKWjkXGA9FXZL=_HfpBDF0q9c5vCyGq3R4nn2VnPWh0A at mail dot gmail dot com> <CAGyQ6gyxMSf7kp940ts-B8BSRewDh9ke+0HheDS-8zkXa79Row at mail dot gmail dot com>
On 09/12/13 01:04, Siva Chandra wrote:
> Sorry for double posting, I missed attaching the patch with the previous post.
>
> 2013-12-08 Siva Chandra Reddy <sivachandra@google.com>
>
> PR 16113: Allow gdb.Field objects with the subscript operator on
> gdb.Value objects of struct/class values.
> * NEWS (Python Scripting): Add entry for the new feature.
> * python/py-type.c (gdbpy_is_field): New function
> * python/py-value.c (valpy_getitem): Allow subscript value to be
> a gdb.Field object.
> (value_has_field): New function
> (get_field_flag): New function
> * python/python-internal.h (gdbpy_is_field): Add declaration.
> @@ -515,6 +567,54 @@ valpy_getitem (PyObject *self, PyObject *key)
> if (field == NULL)
> return NULL;
> }
> + else if (gdbpy_is_field (key))
> + {
> + int artificial, is_base_class, valid_field;
> +
> + valid_field = value_has_field (self_value->value, key);
> + if (valid_field < 0)
> + return NULL;
> + else if (valid_field == 0)
> + {
> + PyErr_SetString (PyExc_TypeError,
> + _("Invalid lookup for a field not contained in "
> + "the value."));
> +
> + return NULL;
> + }
> +
> + artificial = get_field_flag (key, "artificial");
> + if (artificial < 0)
> + return NULL;
> + else if (artificial > 0)
> + {
> + PyErr_SetString (PyExc_ValueError,
> + _("Cannot lookup artificial fields."));
> + return NULL;
> + }
> +
> + is_base_class = get_field_flag (key, "is_base_class");
> + if (is_base_class < 0)
> + return NULL;
> + else if (is_base_class > 0)
> + {
> + base_class_type_object = PyObject_GetAttrString (key, "type");
> + if (base_class_type_object == NULL)
> + return NULL;
> + }
> + else
> + {
> + PyObject *name_obj = PyObject_GetAttrString (key, "name");
> +
> + if (name_obj == NULL)
> + return NULL;
> +
> + field = python_string_to_host_string (name_obj);
> + Py_DECREF (name_obj);
> + if (field == NULL)
> + return NULL;
> + }
> + }
>
> TRY_CATCH (except, RETURN_MASK_ALL)
> {
If it is not already wrapped in a TRY_CATCH scope (it does not look
like it as following this hunk starts the beginning of a
TRY_CATCH block), this hunk needs either its own exception handling or
be hoisted into an existing scope. Whichever is most appropriate.
Any calls to check_typedef needs to be handled for GDB errors, and
converted to Python exceptions.
> diff --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp
> index 55c3b97..f652bad 100644
> --- a/gdb/testsuite/gdb.python/py-value-cc.exp
> +++ b/gdb/testsuite/gdb.python/py-value-cc.exp
> @@ -44,3 +44,33 @@ gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").dereference().ty
> gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().type))" "int_ptr"
> gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().dereference()))" "10"
> gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().referenced_value()))" "10"
> +
> +# Tests for gdb.Value[gdb.Field]
> +gdb_test_no_output "python b = gdb.parse_and_eval('b')" "init b"
> +gdb_test_no_output "python b_fields = b.type.fields()" "init b_fields"
> +gdb_test_no_output "python b_obj = gdb.parse_and_eval('b_obj')" "init b_obj"
> +gdb_test_no_output "python b_ref = gdb.parse_and_eval('b_ref')" "init b_ref"
> +gdb_test_no_output "python b_td = gdb.parse_and_eval('b_td')" "init b_td"
> +
> +gdb_test "python print b\[b_fields\[1\]\]" "97 'a'" "b.a via field"
> +gdb_test "python print b\[b_fields\[0\]\].type" "A" \
> + "type of b's base class via field"
> +gdb_test "python print b\[b_fields\[0\]\]\['a'\]" "10" "b.A::a via field"
> +
> +gdb_test "python print b_obj\[b_fields\[1\]\]" "98 'b'" "b_obj->a via field"
> +gdb_test "python print b_obj\[b_fields\[0\]\].type.target()" "A" \
> + "type of b_obj's base class via field"
> +gdb_test "python print b_obj\[b_fields\[0\]\]\['a'\]" "100" \
> + "b_obj->A::a via field"
> +
> +gdb_test "python print b_ref\[b_fields\[1\]\]" "98 'b'" "b_ref.a via field"
> +gdb_test "python print b_ref\[b_fields\[0\]\].type.target()" "A" \
> + "type of b_ref's base class via field"
> +gdb_test "python print b_ref\[b_fields\[0\]\]\['a'\]" "100" \
> + "b_ref.A::a via field"
> +
> +gdb_test "python print b_td\[b_fields\[1\]\]" "98 'b'" "b_td.a via field"
> +gdb_test "python print b_td\[b_fields\[0\]\].type.target()" "A" \
> + "type of b_td's base class via field"
> +gdb_test "python print b_td\[b_fields\[0\]\]\['a'\]" "100" \
> + "b_td.A::a via field"
The print statements need to be compatible with Python 3:
IE,
>>> foo = 42
>>> print foo
File "<stdin>", line 1
print foo
^
SyntaxError: invalid syntax
>>> print(foo)
42
>>>
Cheers,
Phil