From: Paul Koning <paulkoning@comcast.net>
To: Doug Evans <dje@google.com>
Cc: Eli Zaretskii <eliz@gnu.org>,
tromey@redhat.com, gdb-patches@sourceware.org
Subject: Re: [RFA] Python: raise exception on field-related gdb.Type methods if it's not struct or union
Date: Wed, 09 Nov 2011 18:10:00 -0000 [thread overview]
Message-ID: <087A1A82-39F0-4C58-94BA-07E179DEF564@comcast.net> (raw)
In-Reply-To: <CADPb22RGzLX6_GKXk4KqCBtLE2Z12gn7Hdhokd72WgqxKNeCsg@mail.gmail.com>
This got a bit more complicated once I looked at the testcases.
First, it's not just struct and union types that have fields; enum types also do. So the common code that checks for valid types has to allow those three.
Second, the fields method is also defined for array types, where it returns a list with a single entry that's a range type. I made that a special case since everything else doesn't apply to array types.
Attached is an updated patch including new test cases.
paul
ChangeLog:
2011-11-09 Paul Koning <paul_koning@dell.com>
* python/py-type.c (typy_get_composite): New function.
(typy_nonzero): New function.
(typy_values): Rename from typy_fields.
(typy_fields): New function.
(typy_length): Raise exception if not struct, union, or enum type.
(typy_getitem): Ditto.
(typy_has_key): Ditto.
(typy_make_iter): Ditto.
testsuite/ChangeLog:
2011-11-09 Paul Koning <paul_koning@dell.com>
* gdb.python/py-type.exp: New testcases for exceptions on scalar
types.
Index: gdb/python/py-type.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-type.c,v
retrieving revision 1.28
diff -u -r1.28 py-type.c
--- gdb/python/py-type.c 4 Nov 2011 11:57:04 -0000 1.28
+++ gdb/python/py-type.c 9 Nov 2011 17:36:12 -0000
@@ -308,11 +308,41 @@
/* Return a sequence of all fields. Each field is a gdb.Field object. */
static PyObject *
-typy_fields (PyObject *self, PyObject *args)
+typy_values (PyObject *self, PyObject *args)
{
return typy_fields_items (self, iter_values);
}
+/* Return a sequence of all fields. Each field is a gdb.Field object.
+ This method is similar to typy_values, except where the supplied
+ gdb.Type is an array, in which case it returns a list of one entry
+ which is a gdb.Field object for a range (the array bounds). */
+
+static PyObject *
+typy_fields (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+ PyObject *r, *rl;
+
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
+ return typy_fields_items (self, iter_values);
+
+ /* Array type. Handle this as a special case because the common
+ machinery wants struct or union or enum types. Build a list of
+ one entry which is the range for the array. */
+ r = convert_field (type, 0);
+ if (r == NULL)
+ return NULL;
+
+ rl = Py_BuildValue ("[O]", r);
+ if (rl == NULL)
+ {
+ Py_DECREF (r);
+ }
+
+ return rl;
+}
+
/* Return a sequence of all field names. Each field is a gdb.Field object. */
static PyObject *
@@ -350,6 +380,48 @@
return type_to_type_object (check_typedef (type));
}
+/* Strip typedefs and pointers/reference from a type. Then check that
+ it is a struct, union, or enum type. If not, raise TypeError. */
+
+static struct type *
+typy_get_composite (struct type *type)
+{
+ volatile struct gdb_exception except;
+
+ for (;;)
+ {
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ CHECK_TYPEDEF (type);
+ }
+ /* Don't use GDB_PY_HANDLE_EXCEPTION here because that returns
+ a (NULL) pointer of the wrong type. */
+ if (except.reason < 0)
+ {
+ gdbpy_convert_exception (except);
+ return NULL;
+ }
+
+ if (TYPE_CODE (type) != TYPE_CODE_PTR
+ && TYPE_CODE (type) != TYPE_CODE_REF)
+ break;
+ type = TYPE_TARGET_TYPE (type);
+ }
+
+ /* If this is not a struct, union, or enum type, raise TypeError
+ exception. */
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION
+ && TYPE_CODE (type) != TYPE_CODE_ENUM)
+ {
+ PyErr_SetString (PyExc_TypeError,
+ "Type is not a structure, union, or enum type.");
+ return NULL;
+ }
+
+ return type;
+}
+
/* Return an array type. */
static PyObject *
@@ -1124,9 +1196,23 @@
{
struct type *type = ((type_object *) self)->type;
+ type = typy_get_composite (type);
+ if (type == NULL)
+ return -1;
+
return TYPE_NFIELDS (type);
}
+/* Implements boolean evaluation of gdb.Type. Handle this like other
+ Python objects that don't have a meaningful truth value -- all
+ values are true. */
+
+static int
+typy_nonzero (PyObject *self)
+{
+ return 1;
+}
+
/* Return a gdb.Field object for the field named by the argument. */
static PyObject *
@@ -1145,20 +1231,10 @@
using lookup_struct_elt_type, portions of that function are
copied here. */
- for (;;)
- {
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- CHECK_TYPEDEF (type);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- if (TYPE_CODE (type) != TYPE_CODE_PTR
- && TYPE_CODE (type) != TYPE_CODE_REF)
- break;
- type = TYPE_TARGET_TYPE (type);
- }
-
+ type = typy_get_composite (type);
+ if (type == NULL)
+ return NULL;
+
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
@@ -1216,18 +1292,9 @@
using lookup_struct_elt_type, portions of that function are
copied here. */
- for (;;)
- {
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- CHECK_TYPEDEF (type);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- if (TYPE_CODE (type) != TYPE_CODE_PTR
- && TYPE_CODE (type) != TYPE_CODE_REF)
- break;
- type = TYPE_TARGET_TYPE (type);
- }
+ type = typy_get_composite (type);
+ if (type == NULL)
+ return NULL;
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
@@ -1246,6 +1313,10 @@
{
typy_iterator_object *typy_iter_obj;
+ /* Check that "self" is a structure or union type. */
+ if (typy_get_composite (((type_object *) self)->type) == NULL)
+ return NULL;
+
typy_iter_obj = PyObject_New (typy_iterator_object,
&type_iterator_object_type);
if (typy_iter_obj == NULL)
@@ -1489,7 +1560,7 @@
{ "unqualified", typy_unqualified, METH_NOARGS,
"unqualified () -> Type\n\
Return a variant of this type without const or volatile attributes." },
- { "values", typy_fields, METH_NOARGS,
+ { "values", typy_values, METH_NOARGS,
"values () -> list\n\
Return a list holding all the fields of this type.\n\
Each field is a gdb.Field object." },
@@ -1499,6 +1570,32 @@
{ NULL }
};
+static PyNumberMethods type_object_as_number = {
+ NULL, /* nb_add */
+ NULL, /* nb_subtract */
+ NULL, /* nb_multiply */
+ NULL, /* nb_divide */
+ NULL, /* nb_remainder */
+ NULL, /* nb_divmod */
+ NULL, /* nb_power */
+ NULL, /* nb_negative */
+ NULL, /* nb_positive */
+ NULL, /* nb_absolute */
+ typy_nonzero, /* nb_nonzero */
+ NULL, /* nb_invert */
+ NULL, /* nb_lshift */
+ NULL, /* nb_rshift */
+ NULL, /* nb_and */
+ NULL, /* nb_xor */
+ NULL, /* nb_or */
+ NULL, /* nb_coerce */
+ NULL, /* nb_int */
+ NULL, /* nb_long */
+ NULL, /* nb_float */
+ NULL, /* nb_oct */
+ NULL /* nb_hex */
+};
+
static PyMappingMethods typy_mapping = {
typy_length,
typy_getitem,
@@ -1518,7 +1615,7 @@
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
- 0, /*tp_as_number*/
+ &type_object_as_number, /*tp_as_number*/
0, /*tp_as_sequence*/
&typy_mapping, /*tp_as_mapping*/
0, /*tp_hash */
Index: gdb/testsuite/gdb.python/py-type.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-type.exp,v
retrieving revision 1.14
diff -u -r1.14 py-type.exp
--- gdb/testsuite/gdb.python/py-type.exp 28 Sep 2011 20:06:01 -0000 1.14
+++ gdb/testsuite/gdb.python/py-type.exp 9 Nov 2011 17:36:13 -0000
@@ -93,6 +93,16 @@
gdb_test "python print \[(n, v.bitpos) for (n, v) in st.type.items()\]" {\[\('a', 0L\), \('b', 32L\)\]} "Check fields items list"
gdb_test "python print 'a' in st.type" "True" "Check field name exists test"
gdb_test "python print 'nosuch' in st.type" "False" "Check field name nonexists test"
+ gdb_test "python print not not st.type" "True" "Check conversion to bool"
+
+ # Test rejection of mapping operations on scalar types
+ gdb_test "python print len (st.type\['a'\].type)" "TypeError: Type is not a structure, union, or enum type.*"
+ gdb_test "python print st.type\['a'\].type.has_key ('x')" "TypeError: Type is not a structure, union, or enum type.*"
+ gdb_test "python print st.type\['a'\].type.keys ()" "TypeError: Type is not a structure, union, or enum type.*"
+ gdb_test "python print st.type\['a'\].type\['x'\]" "TypeError: Type is not a structure, union, or enum type.*"
+
+ # Test conversion to bool on scalar types
+ gdb_test "python print not not st.type\['a'\].type" "True"
# Test regression PR python/10805
gdb_py_test_silent_cmd "print ar" "print value" 1
next prev parent reply other threads:[~2011-11-09 18:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-16 4:09 Python: add field access by name and standard python mapping methods to gdb.Type Paul Koning
2011-09-16 7:36 ` Eli Zaretskii
2011-09-16 10:47 ` Phil Muldoon
2011-09-16 14:57 ` Paul Koning
2011-09-16 14:57 ` Phil Muldoon
2011-09-16 15:41 ` Paul Koning
2011-09-23 17:21 ` Doug Evans
2011-09-26 17:15 ` [RFA] " Paul Koning
2011-09-28 19:25 ` Doug Evans
2011-09-28 20:41 ` Paul Koning
2011-10-04 15:14 ` Tom Tromey
2011-10-04 15:30 ` Paul Koning
2011-10-04 15:42 ` Eli Zaretskii
2011-10-04 15:56 ` Paul Koning
2011-11-04 17:42 ` Doug Evans
2011-11-04 20:41 ` Paul Koning
2011-11-04 23:05 ` Doug Evans
2011-11-05 14:36 ` Paul Koning
2011-11-05 21:04 ` Doug Evans
2011-11-08 21:40 ` [RFA] Python: raise exception on field-related gdb.Type methods if it's not struct or union Paul Koning
2011-11-09 0:29 ` Doug Evans
2011-11-09 1:53 ` Paul Koning
2011-11-09 18:10 ` Paul Koning [this message]
2011-11-15 19:01 ` [PING] " Paul Koning
2011-11-15 20:57 ` Doug Evans
2011-11-15 21:21 ` Paul Koning
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=087A1A82-39F0-4C58-94BA-07E179DEF564@comcast.net \
--to=paulkoning@comcast.net \
--cc=dje@google.com \
--cc=eliz@gnu.org \
--cc=gdb-patches@sourceware.org \
--cc=tromey@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox