This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC/Patch] PR 16113: Allow gdb.Field objects as subscripts on gdb.Value objects


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]