Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Phil Muldoon <pmuldoon@redhat.com>
To: Paul Koning <paulkoning@comcast.net>
Cc: gdb-patches@sourceware.org
Subject: Re: Python: add field access by name and standard python mapping methods to gdb.Type
Date: Fri, 16 Sep 2011 10:47:00 -0000	[thread overview]
Message-ID: <m3hb4c935j.fsf@redhat.com> (raw)
In-Reply-To: <A3E6FC3B-1E11-4F34-817E-897C74B2A669@comcast.net> (Paul Koning's	message of "Thu, 15 Sep 2011 16:38:33 -0400")

Paul Koning <paulkoning@comcast.net> writes:

> The attached proposed patch adds access to struct and enum fields by their name, just as field names can be used on gdb.Value objects.  It also adds the standard Python methods for mappings (dictionary-like objects), so that the kind of things that Python programmers would expect to work on objects that can be indexed by name indeed do work.  For example, you can iterate through the fields, or query if a field name exists.  
>
> For a change like this that adds a new feature which uses a whole pile
> of new functions, is the sort of ChangeLog entry shown below the right
> way to document the change, or should I write this in a different way?

Other than one small nit, your ChangeLog is perfectly acceptable.  I
think you should on the py-type.c line, list the functions first, then
the comment.

>  
> -/* Return a sequence of all fields.  Each field is a dictionary with
> -   some pre-defined keys.  */
> +/* Helper function to return the name of a field, as a Python object.
> */

"Or None." to document what happens if a name cannot be found.

>  static PyObject *
> -typy_fields (PyObject *self, PyObject *args)
> +field_name (struct type *type, int field)
>  {
>    PyObject *result;
> +
> +  if (TYPE_FIELD_NAME (type, field)) 
> +    result = PyString_FromString (TYPE_FIELD_NAME (type, field));
> +  else
> +    {
> +      result = Py_None;
> +      Py_INCREF (result);
> +    }
> +  return result;
> +}



> +static PyObject *
> +make_fielditem (struct type *type, int i, enum gdbpy_iter_kind kind)
> +{
> +  PyObject *item = NULL, *key = NULL, *value = NULL;
> +
> +  switch (kind)
> +    {
> +    case iter_items:
> +      key = field_name (type, i);
> +      if (key == NULL)
> +	goto fail;
> +      value = convert_field (type, i);
> +      if (value == NULL)
> +	goto fail;
> +      item = PyTuple_New (2);
> +      if (item == NULL)
> +	goto fail;
> +      PyTuple_SET_ITEM (item, 0, key);
> +      PyTuple_SET_ITEM (item, 1, value);
> +      break;
> +    case iter_keys:
> +      item = field_name (type, i);
> +      break;
> +    case iter_values:
> +      item =  convert_field (type, i);
> +      break;
> +    }
> +  return item;
> +  
> + fail:
> +  Py_XDECREF (key);
> +  Py_XDECREF (value);
> +  Py_XDECREF (item);
> +  return NULL;
> +}

Because this function returns a value that is not simple (it returns a
tuple) a brief comment on the return type and the contents would be
great. 

> +typy_getitem (PyObject *self, PyObject *key)
> +{
> +  struct type *type = ((type_object *) self)->type;
> +  char *field;
> +  int i;
> +  
> +  field = python_string_to_host_string (key);
> +  if (field == NULL)
> +    return NULL;
> +
> +  /* We want just fields of this type, not of base types, so instead of 
> +     using lookup_struct_elt_type, portions of that function are
> +     copied here.  */
> +
> +  for (;;)
> +    {
> +      CHECK_TYPEDEF (type);
> +      if (TYPE_CODE (type) != TYPE_CODE_PTR
> +	  && TYPE_CODE (type) != TYPE_CODE_REF)
> +	break;
> +      type = TYPE_TARGET_TYPE (type);
> +    }

This gives me pause, not because it is wrong, but because I wonder if
there is a possibility that this loop will never exit.  I presume it
will eventually find the base_type, just by continually walking the
TARGET_TYPE until it reaches bottom.  

Can you check how this is done in other parts of GDB (this must happen
quite often?).

> +typy_get (PyObject *self, PyObject *args)
> +{
> +  PyObject *key, *defval = Py_None, *result;
> +  
> +  if (!PyArg_UnpackTuple (args, "get", 1, 2, &key, &defval))
> +    return NULL;
> +  
> +  result = typy_getitem (self, key);
> +  if (result != NULL)
> +    return result;
> +  
> +  /* getitem returned error, clear the exception status and
> +     return the defval instead.  */
> +  PyErr_Clear ();

Given that typy_getitem can raise errors that do not relate directly to
a lookup (the string conversion call in there might indicate some
other conditions, like out of memory, for example), should we only clear
exceptions in some specific case?


> +/* Implement the "has_key" method on the type object.  */
> +static PyObject *
> +typy_has_key (PyObject *self, PyObject *args)
> +{
> +  struct type *type = ((type_object *) self)->type;
> +  char *field;
> +  int i;
> +  
> +  if (!PyArg_ParseTuple (args, "s", &field))
> +    return NULL;
> +
> +  /* We want just fields of this type, not of base types, so instead of 
> +     using lookup_struct_elt_type, portions of that function are
> +     copied here.  */
> +
> +  for (;;)
> +    {
> +      CHECK_TYPEDEF (type);
> +      if (TYPE_CODE (type) != TYPE_CODE_PTR
> +	  && TYPE_CODE (type) != TYPE_CODE_REF)
> +	break;
> +      type = TYPE_TARGET_TYPE (type);
> +    }

See above for the comment on this loop.  If GDB does not have a helper
macro to this already, you might consider just adding one.

Thanks for this patch, I think it is very useful

Phil


  parent reply	other threads:[~2011-09-16 10:45 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-16  4:09 Paul Koning
2011-09-16  7:36 ` Eli Zaretskii
2011-09-16 10:47 ` Phil Muldoon [this message]
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
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=m3hb4c935j.fsf@redhat.com \
    --to=pmuldoon@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=paulkoning@comcast.net \
    /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