This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/7] [python] API for macros: Add gdb.Macro class.


2011-08-23  Matt Rice  <ratmice@gmail.com>

	PR python/10807
	* Makefile.in:  Add python/py-macro.c.
	* python/py-macro.c: New file.
	* python/py-macro.h: Ditto.
	* python/python-internal.h: Declare gdbpy_initialize_macros.
	* python/python.c (_initialize_python): Call gdbpy_initialize_macros.
---
 gdb/Makefile.in              |    6 +
 gdb/python/py-macro.c        |  782 ++++++++++++++++++++++++++++++++++++++++++
 gdb/python/py-macro.h        |   62 ++++
 gdb/python/python-internal.h |    1 +
 gdb/python/python.c          |    1 +
 5 files changed, 852 insertions(+), 0 deletions(-)
 create mode 100644 gdb/python/py-macro.c
 create mode 100644 gdb/python/py-macro.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index bd00644..71389a6 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -289,6 +289,7 @@ SUBDIR_PYTHON_OBS = \
 	py-inferior.o \
 	py-infthread.o \
 	py-lazy-string.o \
+	py-macro.o \
 	py-objfile.o \
 	py-param.o \
 	py-prettyprint.o \
@@ -319,6 +320,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-inferior.c \
 	python/py-infthread.c \
 	python/py-lazy-string.c \
+	python/py-macro.c \
 	python/py-objfile.c \
 	python/py-param.c \
 	python/py-prettyprint.c \
@@ -2110,6 +2112,10 @@ py-lazy-string.o: $(srcdir)/python/py-lazy-string.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-lazy-string.c
 	$(POSTCOMPILE)
 
+py-macro.o: $(srcdir)/python/py-macro.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-macro.c
+	$(POSTCOMPILE)
+
 py-objfile.o: $(srcdir)/python/py-objfile.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-objfile.c
 	$(POSTCOMPILE)
diff --git a/gdb/python/py-macro.c b/gdb/python/py-macro.c
new file mode 100644
index 0000000..184be02
--- /dev/null
+++ b/gdb/python/py-macro.c
@@ -0,0 +1,782 @@
+/* Python interface to macros.
+
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "py-macro.h"
+#include "macrotab.h"
+#include "bcache.h"
+#include "objfiles.h"
+
+/* The macro_object_validator type has the ability to detect when an object
+   has been invalidated and nothing more.  The more featured validation
+   methods of pyst, pysal, provide no benefit for macros because once
+   we have been invalidated, we have no way to know what macro the object
+   once represented.  */
+typedef struct
+{
+  PyObject_HEAD;
+  int is_valid;
+  struct objfile *objfile;
+} macro_validator_object;
+
+typedef struct
+{
+  PyObject_HEAD;
+
+  /* A macro definition object representing this macro.  */
+  const struct macro_definition *def;
+  /* The name of the macro */
+  const char *name;
+  /* The file where the macro resides and its include trail.  */
+  struct macro_source_file *src;
+  /* the line location in the 'SRC' file.  */
+  int line;
+  /* This is used to tell us if the macro has been invalidated
+     The objfile who's obstack and bcache the mdef, and src, and name
+     fields reside in is stored here.  Those fields may be dangling
+     pointers if the objfile is NULL.
+     An invalid macro cannot become valid once again.  */
+  macro_validator_object *objfile_validator;
+} macro_object;
+
+static const struct objfile_data *macropy_objfile_data_key;
+
+static PyTypeObject macro_object_type;
+static PyTypeObject macro_validator_object_type;
+
+
+
+/* Internal methods for converting macros to python objects.  */
+
+static PyObject *
+macropy__definition_to_py (const struct macro_definition *macro)
+{
+  if (macro->replacement)
+    return PyString_FromString (macro->replacement);
+  else
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+macropy__is_function_like_to_py (const struct macro_definition *macro)
+{
+  if (macro->kind == macro_function_like)
+    Py_RETURN_TRUE;
+  else
+    Py_RETURN_FALSE;
+}
+
+static PyObject *
+macropy__argv_to_py (const struct macro_definition *macro)
+{
+  PyObject *ret;
+
+  if (macro->kind == macro_function_like)
+    {
+      Py_ssize_t i;
+      ret = PyList_New (macro->argc);
+
+      if (ret == NULL)
+	goto err_ret;
+
+      for (i = 0; i < macro->argc; i++)
+        {
+	  PyObject *item = PyString_FromString (macro->argv[i]);
+
+	  if (!item)
+	    goto err_ret;
+
+	  if (PyList_SetItem (ret, i, item) != 0)
+            goto err_ret;
+        }
+
+      return ret;
+    }
+
+  Py_RETURN_NONE;
+
+  err_ret:
+    Py_XDECREF (ret);
+    return NULL;
+}
+
+
+static PyObject *
+macropy__include_trail_to_py (const struct macro_definition *macro,
+			      struct macro_source_file *file,
+			      int line)
+{
+  PyObject *tuple = NULL;
+  PyObject *result;
+  PyObject *tmp;
+
+  result = PyList_New (0);
+  if (!result)
+    goto err_ret;
+
+  tuple = PyTuple_New (2);
+  if (!tuple)
+    goto err_ret;
+
+  tmp = PyString_FromString (file->filename);
+  if (!tmp)
+    goto err_ret;
+  if (PyTuple_SetItem (tuple, 0, tmp) != 0)
+    goto err_ret;
+
+  tmp = PyInt_FromLong (line);
+  if (!tmp)
+    goto err_ret;
+  if (PyTuple_SetItem (tuple, 1, tmp) != 0)
+    goto err_ret;
+
+  if (PyList_Append (result, tuple) != 0)
+    goto err_ret;
+  Py_DECREF (tuple);
+
+  while (file->included_by)
+    {
+      tuple = PyTuple_New (2);
+
+      if (!tuple)
+        goto err_ret;
+
+      tmp = PyString_FromString (file->included_by->filename);
+      if (!tmp)
+        goto err_ret;
+      if (PyTuple_SetItem (tuple, 0, tmp) != 0)
+        goto err_ret;
+
+      tmp = PyInt_FromLong (file->included_at_line);
+      if (!tmp)
+        goto err_ret;
+      if (PyTuple_SetItem (tuple, 1, tmp) != 0)
+        goto err_ret;
+
+      if (PyList_Append (result, tuple) != 0)
+	goto err_ret;
+      Py_DECREF (tuple);
+
+      file = file->included_by;
+    }
+
+  return result;
+
+  err_ret:
+    Py_XDECREF (tuple);
+    Py_XDECREF (result);
+    return NULL;
+}
+
+static PyObject *
+macropy__name_to_py (const char *name)
+{
+  return PyString_FromString (name);
+}
+
+
+
+/* Publicly declared functions. */
+
+/* A macro_callback_fn for use with macro_foreach that adds
+   the macro to a python list.  */
+enum macro_walk_status
+pymacro_add_macro_to_list (const char *name,
+		   const struct macro_definition *definition,
+		   struct macro_source_file *source,
+		   int line,
+		   void *user_data)
+{
+  PyObject *tmp = NULL;
+  struct macropy_user_data *mud = user_data;
+  PyObject *list = (PyObject *) mud->list;
+
+  if (! PyObject_TypeCheck (list, &PyList_Type))
+    goto fail;
+
+  tmp = macropy_object_create (mud->objfile, name, definition, source, line);
+  if (!tmp)
+    goto fail;
+
+  if (PyList_Append (list, tmp) != 0)
+    goto fail;
+
+  Py_DECREF (tmp);
+  return macro_walk_continue;
+
+  fail:
+    Py_XDECREF (tmp);
+    return macro_walk_abort;
+}
+
+/* Create a new macro (gdb.Macro) object that encapsulates
+   the gdb macro representation.  */
+PyObject *
+macropy_object_create (struct objfile *objfile,
+		       const char *name,
+		       const struct macro_definition *def,
+		       struct macro_source_file *src,
+		       int line)
+{
+  macro_object *macro_obj;
+
+  macro_obj = PyObject_New (macro_object, &macro_object_type);
+
+  if (macro_obj)
+    {
+      macro_validator_object *validator;
+
+      macro_obj->objfile_validator = NULL;
+
+      /* check our arguments, Don't check line because 0 is a valid line.  */
+      if (!objfile)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   _("Invalid objfile initializing gdb.Macro"));
+	  goto err_ret;
+	}
+
+      if (!name)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   _("Invalid macro name initializing gdb.Macro"));
+	  goto err_ret;
+	}
+
+      if (!def)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   _("Invalid macro definition initializing gdb.Macro"));
+	  goto err_ret;
+	}
+
+      if (!src)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   _("Invalid macro source file initializing gdb.Macro"));
+	  goto err_ret;
+	}
+
+      validator = objfile_data (objfile, macropy_objfile_data_key);
+      if (!validator)
+        {
+          validator = PyObject_New (macro_validator_object,
+				    &macro_validator_object_type);
+	  if (!validator)
+	    goto err_ret;
+
+	  validator->is_valid = 1;
+	  validator->objfile = objfile;
+          set_objfile_data (objfile, macropy_objfile_data_key, validator);
+        }
+      else
+        Py_INCREF (validator);
+
+      macro_obj->name = bcache (name, strlen (name) + 1, objfile->macro_cache);
+      macro_obj->objfile_validator = validator;
+      macro_obj->def = def;
+      macro_obj->src = src;
+      macro_obj->line = line;
+
+      return (PyObject *) macro_obj;
+
+      err_ret:
+	Py_DECREF (macro_obj);
+	return NULL;
+    }
+  return NULL;
+}
+
+static void
+macropy_dealloc (PyObject *obj)
+{
+  macro_object *me = (macro_object *) obj;
+
+  Py_XDECREF (me->objfile_validator);
+
+  obj->ob_type->tp_free (obj);
+}
+
+static void
+macropy_validator_dealloc (PyObject *obj)
+{
+  macro_validator_object *me = (macro_validator_object *) obj;
+
+  if (me->objfile)
+    set_objfile_data (me->objfile, macropy_objfile_data_key, NULL);
+
+  obj->ob_type->tp_free (obj);
+}
+
+static void
+del_objfile_macro (struct objfile *objfile, void *datum)
+{
+  macro_validator_object *validator = datum;
+
+  if (validator)
+    {
+      validator->is_valid = 0;
+      validator->objfile = NULL;
+    }
+  else
+   PyErr_SetString (PyExc_RuntimeError,
+		    _("Internal inconsistency invalidating objfile macros."));
+}
+
+
+
+/* Helper function for macro validation */
+
+static inline macro_object *
+macropy__validate_self (PyObject *self)
+{
+  macro_object *me;
+
+  if (! PyObject_TypeCheck (self, &macro_object_type))
+    {
+      PyErr_SetString (PyExc_RuntimeError,
+			 _("Typecheck failure converting macro."));
+      return NULL;
+    }
+
+  me = (macro_object *) self;
+
+  if (me->objfile_validator->is_valid == 0)
+    {
+      PyErr_SetString (PyExc_RuntimeError, _("Macro is invalid."));
+      return NULL;
+    }
+
+  return me;
+}
+
+/* Macro object methods */
+
+static PyObject *
+macropy_name_method (PyObject *self, PyObject *args)
+{
+  macro_object *me = macropy__validate_self (self);
+
+  if (!me)
+    return NULL;
+
+  return macropy__name_to_py (me->name);
+}
+
+static PyObject *
+macropy_definition_method (PyObject *self, PyObject *args)
+{
+  macro_object *me = macropy__validate_self (self);
+
+  if (!me)
+    return NULL;
+
+  return macropy__definition_to_py (me->def);
+}
+
+static PyObject *
+macropy_is_function_like_method (PyObject *self, PyObject *args)
+{
+  macro_object *me = macropy__validate_self (self);
+
+  if (!me)
+    return NULL;
+
+  return macropy__is_function_like_to_py (me->def);
+}
+
+static PyObject *
+macropy_argv_method (PyObject *self, PyObject *args)
+{
+  macro_object *me = macropy__validate_self (self);
+
+  if (!me)
+    return NULL;
+
+  return macropy__argv_to_py (me->def);
+}
+
+static PyObject *
+macropy_include_trail_method (PyObject *self, PyObject *args)
+{
+  macro_object *me = macropy__validate_self (self);
+
+  if (!me)
+    return NULL;
+
+  return macropy__include_trail_to_py (me->def, me->src, me->line);
+}
+
+/* For future API compatibility. */
+static PyObject *
+macropy_is_valid_method (PyObject *self, PyObject *args)
+{
+  macro_object *me = (macro_object *) self;
+
+  if (!me)
+    return NULL;
+
+  if (me->objfile_validator->is_valid)
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+/* Helpers for the macropy_str method.  */
+static int
+macropy__concat_chars (PyObject **result, const char *stuff)
+{
+  PyObject *tmp = PyString_FromString (stuff);
+
+  if (!tmp)
+    return -1;
+
+  PyString_ConcatAndDel (result, tmp);
+  if (*result == NULL)
+    return -1;
+
+  return 0;
+}
+
+static int
+macropy__concat_py_obj (PyObject **result, PyObject *stuff)
+{
+  PyObject *tmp;
+
+  if (PyObject_TypeCheck (stuff, &PyString_Type))
+    {
+      PyString_Concat (result, stuff);
+      return *result ? 0 : -1;
+    }
+
+  tmp = PyObject_Str (stuff);
+  if (!tmp)
+    return -1;
+
+  PyString_ConcatAndDel (result, tmp);
+  return *result ? 0 : -1;
+}
+
+static PyObject *
+macropy_str (PyObject *self)
+{
+  PyObject *result = NULL;
+  PyObject *argv = NULL;
+  PyObject *definition = NULL;
+  PyObject *include_trail = NULL;
+  PyObject *is_function_like = NULL;
+  PyObject *name = NULL;
+  macro_object *me = macropy__validate_self (self);
+
+  if (!me)
+    goto err_ret;
+
+  result = PyString_FromString ("<gdb.Macro ");
+  if (!result)
+    goto err_ret;
+
+  argv = macropy__argv_to_py (me->def);
+  if (!argv)
+    goto err_ret;
+
+  definition = macropy__definition_to_py (me->def);
+  if (!definition)
+    goto err_ret;
+
+  include_trail = macropy__include_trail_to_py (me->def, me->src, me->line);
+  if (!include_trail)
+    goto err_ret;
+
+  is_function_like = macropy__is_function_like_to_py (me->def);
+  if (!is_function_like)
+    goto err_ret;
+
+  name = macropy__name_to_py (me->name);
+  if (!name)
+    goto err_ret;
+
+  if (macropy__concat_py_obj (&result, name) != 0)
+    goto err_ret;
+
+  if (is_function_like == Py_True)
+    {
+      Py_ssize_t sz = PyList_Size (argv);
+      Py_ssize_t i;
+
+      if (macropy__concat_chars (&result, "(") != 0)
+        goto err_ret;
+
+      for (i = 0; i < sz; i++)
+        {
+				      /* borrowed */
+	  if (macropy__concat_py_obj (&result, PyList_GetItem (argv, i)) != 0)
+	    goto err_ret;
+
+	  if (i < sz - 1)
+            if (macropy__concat_chars (&result, ", ") != 0)
+	      goto err_ret;
+        }
+
+      if (macropy__concat_chars (&result, ")") != 0)
+	goto err_ret;
+    }
+
+  if (definition != Py_None && PyString_Size (definition))
+    {
+      if (macropy__concat_chars (&result, "=") != 0)
+        goto err_ret;
+
+      if (macropy__concat_py_obj (&result, definition) != 0)
+	goto err_ret;
+    }
+
+  if (macropy__concat_chars (&result, " ") != 0)
+    goto err_ret;
+  if (macropy__concat_chars (&result, "include_trail=") != 0)
+    goto err_ret;
+  if (macropy__concat_py_obj (&result, include_trail) != 0)
+    goto err_ret;
+
+  if (macropy__concat_chars (&result, ">") != 0)
+    goto err_ret;
+
+  goto normal_ret;
+
+  err_ret:
+    Py_XDECREF (result);
+    result = NULL;
+  normal_ret:
+    Py_XDECREF (argv);
+    Py_XDECREF (definition);
+    Py_XDECREF (include_trail);
+    Py_XDECREF (is_function_like);
+    Py_XDECREF (name);
+    return result;
+}
+
+static int
+macropy_compare (PyObject *self, PyObject *o2)
+{
+  PyObject *my_str = macropy_str (self);
+  PyObject *other_str = NULL;
+  PyObject *an_error;
+  int err_code = -1;
+  int comparison_result = -1;
+
+  if (!my_str)
+    goto check_for_errors_and_return;
+
+  if (PyObject_TypeCheck (o2, &macro_object_type))
+    {
+      other_str = macropy_str (o2);
+      if (!other_str)
+	goto check_for_errors_and_return;
+
+      err_code = PyObject_Cmp (my_str, other_str, &comparison_result);
+    }
+  else
+    {
+      err_code = PyObject_Cmp (my_str, o2, &comparison_result);
+    }
+
+  check_for_errors_and_return:
+    Py_XDECREF (my_str);
+    Py_XDECREF (other_str);
+
+    /* Because -1 is also Less Than we cannot use gdbpy_print_stack ()
+       which clears the error if set python print-stack is off.
+       Which would lead to (gdb) python print x == x
+       returning False with no error message displayed.
+
+       alternately if an error is set and the return value is not 1,
+       python will complain.
+
+       Thus if there is an error, we must normalize it
+       making sure that both an error and the return
+       value are -1. Should we encounter one.  */
+    an_error = PyErr_Occurred ();
+    if (an_error == NULL && err_code != -1)
+      {
+        /* a valid comparison */
+        return comparison_result;
+      }
+    else if (an_error == NULL && err_code == -1)
+      {
+	/* an unknown error */
+	PyErr_SetString (PyExc_RuntimeError,
+			 _("mystery error during macro comparison."));
+        return -1;
+      }
+    else /* a known error */
+      return -1;
+}
+
+static long
+macropy_hash (PyObject *o)
+{
+  long result = -1;
+  PyObject *my_str = macropy_str (o);
+
+  if (my_str)
+    result = PyObject_Hash (my_str);
+
+  /* The docs say PyObject_Hash should return -1 on error,
+     Don't believe it because it is not always true,
+     The exception gets raised regardless of return value,
+     But we should follow the documented return strategy of -1 on error.
+
+     gdbpy_print_stack () clears the error if set python print-stack is off,
+     which would cause python later to complain that we returned -1
+     without an error set.  We don't want that.  */
+  if (PyErr_Occurred ())
+    result = -1;
+  Py_XDECREF (my_str);
+  return result;
+}
+
+
+
+void
+gdbpy_initialize_macros (void)
+{
+  macro_object_type.tp_new = PyType_GenericNew;
+  macro_validator_object_type.tp_new = PyType_GenericNew;
+
+  if (PyType_Ready (&macro_validator_object_type) < 0)
+    return;
+
+  if (PyType_Ready (&macro_object_type) < 0)
+    return;
+
+  macropy_objfile_data_key
+    = register_objfile_data_with_cleanup (NULL, del_objfile_macro);
+
+  Py_INCREF (&macro_object_type);
+  PyModule_AddObject (gdb_module, "Macro",
+		      (PyObject *) &macro_object_type);
+
+  Py_INCREF (&macro_validator_object_type);
+  PyModule_AddObject (gdb_module, "MacroValidator",
+		      (PyObject *) &macro_validator_object_type);
+}
+
+static PyGetSetDef macro_validator_object_getset[] = {
+  {NULL}  /* Sentinel */
+};
+
+static PyMethodDef macro_validator_object_methods[] = {
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject macro_validator_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,					  /*ob_size*/
+  "gdb.MacroValidator",			  /*tp_name*/
+  sizeof (macro_validator_object),	  /*tp_basicsize*/
+  0,					  /*tp_itemsize*/
+  macropy_validator_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,			  /*tp_flags*/
+  "GDB macro validator object",		  /*tp_doc */
+  0,					  /*tp_traverse */
+  0,					  /*tp_clear */
+  0,					  /*tp_richcompare */
+  0,					  /*tp_weaklistoffset */
+  0,					  /*tp_iter */
+  0,					  /*tp_iternext */
+  macro_validator_object_methods,	  /*tp_methods */
+  0,					  /*tp_members */
+  macro_validator_object_getset,	  /*tp_getset */
+};
+
+static PyGetSetDef macro_object_getset[] = {
+  {NULL}  /* Sentinel */
+};
+
+static PyMethodDef macro_object_methods[] = {
+  { "argv", macropy_argv_method, METH_NOARGS,
+    "argv () -> List.\n\
+Return a list containing the names of the arguments for a function like \
+macro." },
+  { "definition", macropy_definition_method, METH_NOARGS,
+    "definition () -> String.\n\
+Return the macro's definition." },
+  { "include_trail", macropy_include_trail_method, METH_NOARGS,
+    "include_trail () -> List.\n\
+Return a list containing tuples with the filename and line number describing \
+how and where this macro came to be defined." },
+  { "is_function_like", macropy_is_function_like_method, METH_NOARGS,
+    "is_function_like () -> Bool.\n\
+Return True if the macro is function like, False otherwise." },
+  { "name", macropy_name_method, METH_NOARGS,
+    "name () -> String.\n\
+Return the macro's name." },
+  { "is_valid", macropy_is_valid_method, METH_NOARGS,
+    "is_valid () -> Bool.\n\
+Return whether the macro is valid." },
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject macro_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Macro",			  /*tp_name*/
+  sizeof (macro_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  macropy_dealloc,		  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  macropy_compare,		  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  macropy_hash,			  /*tp_hash */
+  0,				  /*tp_call*/
+  macropy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB macro object",		  /*tp_doc */
+  0,				  /*tp_traverse */
+  0,				  /*tp_clear */
+  0,				  /*tp_richcompare */
+  0,				  /*tp_weaklistoffset */
+  0,				  /*tp_iter */
+  0,				  /*tp_iternext */
+  macro_object_methods,		  /*tp_methods */
+  0,				  /*tp_members */
+  macro_object_getset,		  /*tp_getset */
+};
diff --git a/gdb/python/py-macro.h b/gdb/python/py-macro.h
new file mode 100644
index 0000000..46b0293
--- /dev/null
+++ b/gdb/python/py-macro.h
@@ -0,0 +1,62 @@
+/* Python interface to macros.
+
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_PY_MACRO_H
+#define GDB_PY_MACRO_H
+
+#include "objfiles.h"
+#include "macrotab.h"
+
+struct macropy_user_data {
+  PyObject *list;
+  struct objfile *objfile;
+};
+
+/* A macro_callback_fn for use with macro_foreach and friends that adds
+   a gdb.Macro object to the python list USER_DATA->LIST.
+   USER_DATA should be of type struct macropy_user_data.
+
+   A null USER_DATA->OBJFILE is currently be considered an error,
+   this is subject to change.
+
+   Aborts the iteration on error, and forces the macro iterator function
+   to return macro_walk_aborted check the iterators macro_walk_result.
+   On error it is the callers responsibility to dispose of the USER_DATA
+   structure and its contents.  The appropriate python exception
+   that caused the error has already been set.
+*/
+enum macro_walk_status
+pymacro_add_macro_to_list (const char *name,
+		   const struct macro_definition *definition,
+		   struct macro_source_file *source,
+		   int line,
+		   void *user_data);
+
+/* Create a new macro (gdb.Macro) object that encapsulates
+   the gdb macro representation.  OBJFILE is the objfile that contains
+   the macro table.  NAME is the name of the macro.  DEF the macros definition
+   SRC the source file containing the macro. LINE definitions location.  */
+PyObject *
+macropy_object_create (struct objfile *objfile,
+		       const char *name,
+		       const struct macro_definition *def,
+		       struct macro_source_file *src,
+		       int line);
+
+#endif /* GDB_PY_MACRO_H */
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 996b23b..532552a 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -211,6 +211,7 @@ void gdbpy_initialize_breakpoint_event (void);
 void gdbpy_initialize_continue_event (void);
 void gdbpy_initialize_exited_event (void);
 void gdbpy_initialize_thread_event (void);
+void gdbpy_initialize_macros (void);
 
 struct cleanup *make_cleanup_py_decref (PyObject *py);
 
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 03edce9..092b354 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1198,6 +1198,7 @@ Enables or disables printing of Python stack traces."),
   gdbpy_initialize_lazy_string ();
   gdbpy_initialize_thread ();
   gdbpy_initialize_inferior ();
+  gdbpy_initialize_macros ();
   gdbpy_initialize_events ();
 
   gdbpy_initialize_eventregistry ();
-- 
1.7.4.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]