public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
From: pmuldoon@sourceware.org
To: archer-commits@sourceware.org
Subject: [SCM]  archer-pmuldoon-python-backtrace: Implement gdb.FrameIterator
Date: Mon, 02 Apr 2012 15:01:00 -0000	[thread overview]
Message-ID: <20120402150143.8422.qmail@sourceware.org> (raw)

The branch, archer-pmuldoon-python-backtrace has been updated
       via  313ec1898851d0162bb917768a2fa517220649fa (commit)
      from  ec9f7997ebf301d320fe4c9293788f7cc55feac1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 313ec1898851d0162bb917768a2fa517220649fa
Author: Phil Muldoon <pmuldoon@redhat.com>
Date:   Mon Apr 2 16:01:20 2012 +0100

    Implement gdb.FrameIterator

-----------------------------------------------------------------------

Summary of changes:
 gdb/python/py-frame.c |  154 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 150 insertions(+), 4 deletions(-)

First 500 lines of diff:
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 12a54e8..f02c9a1 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -29,7 +29,7 @@
 #include "symfile.h"
 #include "objfiles.h"
 
-typedef struct {
+typedef struct frapy_type_object {
   PyObject_HEAD
   struct frame_id frame_id;
   struct gdbarch *gdbarch;
@@ -45,6 +45,13 @@ typedef struct {
   int frame_id_is_next;
 } frame_object;
 
+/* A frame iterator object.  */
+typedef struct {
+  PyObject_HEAD
+  struct frapy_type_object *source;
+  struct frapy_type_object *current;
+} frame_iterator_object;
+
 /* Require a valid frame.  This must be called inside a TRY_CATCH, or
    another context in which a gdb exception is allowed.  */
 #define FRAPY_REQUIRE_VALID(frame_obj, frame)		\
@@ -54,6 +61,8 @@ typedef struct {
 	error (_("Frame is invalid."));			\
     } while (0)
 
+static PyTypeObject frame_iterator_object_type;
+
 /* Returns the frame_info object corresponding to the given Python Frame
    object.  If the frame doesn't exist anymore (the frame id doesn't
    correspond to any frame in the inferior), returns NULL.  */
@@ -589,6 +598,95 @@ frapy_richcompare (PyObject *self, PyObject *other, int op)
   Py_RETURN_FALSE;
 }
 
+static PyObject *
+frapy_iter (PyObject *self)
+{
+  struct frame_info *fi;
+  frame_iterator_object *frame_iter_obj;
+  FRAPY_REQUIRE_VALID (self, fi);
+
+  frame_iter_obj = PyObject_New (frame_iterator_object,
+				 &frame_iterator_object_type);
+  if (frame_iter_obj == NULL)
+      return NULL;
+
+  Py_INCREF (self);
+  frame_iter_obj->source = (frame_object *) self;
+  frame_iter_obj->current = NULL;
+  return (PyObject *) frame_iter_obj;
+}
+
+
+static PyObject *
+frapy_iternext (PyObject *self)
+{
+  frame_iterator_object *iter_obj = (frame_iterator_object *) self;
+  PyObject *result;
+  struct frame_info *prev;
+
+  /* If the user does: foo = gdb.FrameIterator(gdb.newest_frame()) the
+     next iteration will return the next oldest frame.  But we want to
+     account for the first frame in iterations also.  */
+  if (iter_obj->current != NULL)
+      result = frapy_older ((PyObject *)iter_obj->current, NULL);
+  else
+      result = (PyObject *) iter_obj->source;
+
+  /* Iteration stops on error (preserve the exception), or when
+     frapy_older returns None.  */
+  if (result == NULL)
+    return NULL;
+
+  iter_obj->current = (frame_object *)result;
+  if (result == Py_None)
+    return NULL;
+
+  return result;
+}
+
+/* Return a reference to the block iterator.  */
+static PyObject *
+frapy_frame_iter (PyObject *self)
+{
+  frame_iterator_object *iter_obj = (frame_iterator_object *) self;
+
+  Py_INCREF (self);
+  return self;
+}
+
+static void
+frapy_iterator_dealloc (PyObject *obj)
+{
+  frame_iterator_object *iter_obj = (frame_iterator_object *) obj;
+
+  Py_XDECREF (iter_obj->current);
+}
+
+static int
+frapy_frame_iter_init (PyObject *self, PyObject *args, PyObject *kw)
+{
+  static char *keywords[] = { "frame", NULL };
+  frame_iterator_object *iter_obj = (frame_iterator_object *) self;
+  PyObject *frame;
+
+  if (! PyArg_ParseTupleAndKeywords (args, kw, "O",
+				     keywords, &frame))
+    return -1;
+
+  iter_obj->current = NULL;
+  iter_obj->source = NULL;
+
+  if (frapy_is_valid (frame, NULL))
+    {
+      Py_INCREF (frame);
+      iter_obj->source = (frame_object *)frame;
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
 /* Sets up the Frame API in the gdb module.  */
 
 void
@@ -598,6 +696,10 @@ gdbpy_initialize_frames (void)
   if (PyType_Ready (&frame_object_type) < 0)
     return;
 
+  frame_iterator_object_type.tp_new = PyType_GenericNew;
+  if (PyType_Ready (&frame_iterator_object_type) < 0)
+    return;
+
   /* Note: These would probably be best exposed as class attributes of
      Frame, but I don't know how to do it except by messing with the
      type's dictionary.  That seems too messy.  */
@@ -617,7 +719,10 @@ gdbpy_initialize_frames (void)
 #undef SET
 
   Py_INCREF (&frame_object_type);
+  Py_INCREF (&frame_iterator_object_type);
+
   PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type);
+  PyModule_AddObject (gdb_module, "FrameIterator", (PyObject *) &frame_iterator_object_type);  
 }
 
 \f
@@ -682,14 +787,14 @@ PyTypeObject frame_object_type = {
   0,				  /* tp_getattro */
   0,				  /* tp_setattro */
   0,				  /* tp_as_buffer */
-  Py_TPFLAGS_DEFAULT,		  /* tp_flags */
+  Py_TPFLAGS_DEFAULT| Py_TPFLAGS_HAVE_ITER,		  /* tp_flags */
   "GDB frame object",		  /* tp_doc */
   0,				  /* tp_traverse */
   0,				  /* tp_clear */
   frapy_richcompare,		  /* tp_richcompare */
   0,				  /* tp_weaklistoffset */
-  0,				  /* tp_iter */
-  0,				  /* tp_iternext */
+  frapy_iter,			  /* tp_iter */
+  0,		  /* tp_iternext */
   frame_object_methods,		  /* tp_methods */
   0,				  /* tp_members */
   0,				  /* tp_getset */
@@ -701,3 +806,44 @@ PyTypeObject frame_object_type = {
   0,				  /* tp_init */
   0,				  /* tp_alloc */
 };
+
+static PyTypeObject frame_iterator_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.FrameIterator",		  /*tp_name*/
+  sizeof (frame_iterator_object),	      /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  frapy_iterator_dealloc,	  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
+  "GDB frame iterator object",	  /*tp_doc */
+  0,				  /*tp_traverse */
+  0,				  /*tp_clear */
+  0,				  /*tp_richcompare */
+  0,				  /*tp_weaklistoffset */
+  frapy_frame_iter,               /*tp_iter */
+  frapy_iternext,                 /*tp_iternext */
+  0,                              /*tp_methods */
+  0,				  /* tp_members */
+  0,				  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  frapy_frame_iter_init,	  /* tp_init */
+  0,				  /* tp_alloc */
+};


hooks/post-receive
--
Repository for Project Archer.


                 reply	other threads:[~2012-04-02 15:01 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20120402150143.8422.qmail@sourceware.org \
    --to=pmuldoon@sourceware.org \
    --cc=archer-commits@sourceware.org \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).