Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
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


  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