From: Paul Koning <paulkoning@comcast.net>
To: Li Yu <raise.sail@gmail.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH v2] gdb/python: add missing handling for anonymous members of struct and union
Date: Fri, 30 Sep 2011 16:15:00 -0000 [thread overview]
Message-ID: <07654BC2-7955-4858-8AE9-CA9FF895A158@comcast.net> (raw)
In-Reply-To: <4E8595F6.7080004@gmail.com>
On Sep 30, 2011, at 6:12 AM, Li Yu wrote:
> ...
>
> gdb/python/:
> 2011-09-29 Li Yu <raise.sail@gmail.com>
>
> * py-type.c: Add process for anonymous members of struct and union
>
> py-type.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 54 insertions(+), 9 deletions(-)
>
> diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
For some strange reason your patch comes across all messed up. Perhaps your mailer is creating trouble. For one thing, it comes across in Unicode with non-break spaces in it, and spaces at the start of lines are missing. I can't apply the patch with the "patch" tool...
> index 27f8b38..d0d8a94 100644
> --- a/gdb/python/py-type.c
> +++ b/gdb/python/py-type.c
> @@ -56,15 +56,20 @@ typedef struct pyty_field_object
> static PyTypeObject field_object_type;
>
> /* A type iterator object. */
> -typedef struct {
> +struct __typy_iterator_object
> +{
> PyObject_HEAD
> + /* The iterators for support fields of anonymous field */
> + struct __typy_iterator_object *child;
> + struct __typy_iterator_object *parent;
> /* The current field index. */
> int field;
> /* What to return. */
> enum gdbpy_iter_kind kind;
> /* Pointer back to the original source type object. */
> struct pyty_type_object *source;
> -} typy_iterator_object;
> +};
> +typedef struct __typy_iterator_object typy_iterator_object;
You could just write that as typedef struct __typy_iterator_object { ... } typy_iterator_object; without the typedef as a separate line.
>
> static PyTypeObject type_iterator_object_type;
>
> @@ -1201,6 +1206,8 @@ typy_make_iter (PyObject *self, enum gdbpy_iter_kind kind)
> if (typy_iter_obj == NULL)
> return NULL;
>
> + typy_iter_obj->child = NULL;
> + typy_iter_obj->parent = NULL;
> typy_iter_obj->field = 0;
> typy_iter_obj->kind = kind;
> Py_INCREF (self);
> - struct type *type = iter_obj->source->type;
> - int i;
> - PyObject *result;
> -
> - if (iter_obj->field < TYPE_NFIELDS (type))
Something strange here. The diff shows this code directly after the other code in typy_make_iter, but that's not where it is. The code is actually in typy_iterator_iternext, which is several functions later in the source. Is "git diff" malfunctioning or is this a cut & paste glitch?
> + typy_iterator_object *iter_obj = (typy_iterator_object *) self, *child_iter_obj;
> + struct type *type;
> + PyObject *result, *child_pytype;
> + char *name;
> +
> + while (iter_obj->child) /* deepest anonymous member first */
> + {
> + iter_obj = iter_obj->child;
> + }
> + type = iter_obj->source->type;
> +
> +restart:
> + while (iter_obj->field >= TYPE_NFIELDS (type))
> + {
> + iter_obj = iter_obj->parent;
> + if (!iter_obj)
> + return NULL;
> + Py_DECREF(iter_obj->child);
> + iter_obj->child = NULL;
> + type = iter_obj->source->type;
> + }
> +
That whole chunk of code would be simpler and probably easier to understand if you wrote it as a recursion rather than a loop. Something like:
restart:
if (iter_obj->child)
{
result = typy_iterator_iternext (iter_obj->child);
if (result != NULL)
return result;
Py_CLEAR (iter_obj->child);
}
One benefit is that the "parent" member is no longer needed if you do that. Then the existing "if (iter_obj->field < TYPE_NFIELDS (type))" would stay, and the code you have under "abort_clean" is also the "stop iteration" code.
> + name = TYPE_FIELD_NAME (type, iter_obj->field);
> + if (!name)
> + goto abort_clean;
Why is this needed? When is name null as opposed to pointing to an empty string?
> +
> + if (name[0]) /* mostly cases */
> {
> result = make_fielditem (type, iter_obj->field, iter_obj->kind);
> if (result != NULL)
> - iter_obj->field++;
> + iter_obj->field++;
> return result;
> }
>
> + /* handing for anonymous members here */
> + type = TYPE_FIELD_TYPE(type, iter_obj->field++);
> + child_pytype = type_to_type_object(type);
> + if (!child_pytype)
> + goto abort_clean;;
Extra semicolon.
> + child_iter_obj = (typy_iterator_object*)typy_make_iter (child_pytype, iter_obj->kind);
You need an error check (child_iter_obj == NULL) here.
> + iter_obj->child = child_iter_obj;
> + child_iter_obj->parent = iter_obj;
> + iter_obj = child_iter_obj;
> + goto restart;
> +
> +abort_clean:
> + while (iter_obj->parent)
> + {
> + iter_obj = iter_obj->parent;
> + Py_DECREF(iter_obj->child);
> + }
If you use recursion, all this simply becomes Py_CLEAN (iter_obj->child);
> return NULL;
> }
You need to free iter_obj->child in the iterator destructor.
paul
next prev parent reply other threads:[~2011-09-30 15:12 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-30 11:04 Li Yu
2011-09-30 16:15 ` Paul Koning [this message]
2011-10-01 14:01 ` Li Yu
2011-10-01 18:54 ` Paul Koning
2011-10-04 16:37 ` Tom Tromey
2011-10-04 18:05 ` Paul Koning
2011-10-04 20:24 ` Tom Tromey
2011-10-04 20:41 ` Paul Koning
2011-10-19 20:52 ` Tom Tromey
2011-10-19 20:59 ` Paul Koning
2011-10-20 18:49 ` Tom Tromey
2011-10-25 18:34 ` [RFA] Python: iterator for deep traversal of gdb.Type struct/union fields Paul Koning
2011-10-25 19:03 ` Paul Koning
2011-10-25 20:16 ` Eli Zaretskii
2011-10-26 17:14 ` Paul Koning
2011-10-27 13:01 ` Doug Evans
2011-10-27 14:52 ` Paul_Koning
2011-10-27 19:57 ` Tom Tromey
[not found] ` <09787EF419216C41A903FD14EE5506DD030CF168FB@AUSX7MCPC103.AMER.DELL.COM>
2011-10-27 21:56 ` Paul Koning
2011-10-27 22:14 ` Eli Zaretskii
2011-10-28 14:55 ` 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=07654BC2-7955-4858-8AE9-CA9FF895A158@comcast.net \
--to=paulkoning@comcast.net \
--cc=gdb-patches@sourceware.org \
--cc=raise.sail@gmail.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