From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25554 invoked by alias); 24 Aug 2011 15:12:00 -0000 Received: (qmail 25366 invoked by uid 22791); 24 Aug 2011 15:11:54 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,TW_BJ,TW_RG,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-gy0-f169.google.com (HELO mail-gy0-f169.google.com) (209.85.160.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 24 Aug 2011 15:11:18 +0000 Received: by gyg10 with SMTP id 10so1011822gyg.0 for ; Wed, 24 Aug 2011 08:11:17 -0700 (PDT) Received: by 10.91.126.13 with SMTP id d13mr5024192agn.19.1314198677312; Wed, 24 Aug 2011 08:11:17 -0700 (PDT) Received: from localhost.localdomain (c-98-232-221-4.hsd1.or.comcast.net [98.232.221.4]) by mx.google.com with ESMTPS id d7sm968071anb.40.2011.08.24.08.11.15 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 24 Aug 2011 08:11:16 -0700 (PDT) From: matt rice To: gdb-patches@sourceware.org Cc: matt rice Subject: [PATCH 3/7] [python] API for macros: Add gdb.Macro class. Date: Wed, 24 Aug 2011 15:12:00 -0000 Message-Id: <1314198654-9008-4-git-send-email-ratmice@gmail.com> In-Reply-To: <1314198654-9008-1-git-send-email-ratmice@gmail.com> References: <1314198654-9008-1-git-send-email-ratmice@gmail.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-08/txt/msg00448.txt.bz2 2011-08-23 Matt Rice 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 . */ + +#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, ¯o_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, + ¯o_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, ¯o_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 ("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, ¯o_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 (¯o_validator_object_type) < 0) + return; + + if (PyType_Ready (¯o_object_type) < 0) + return; + + macropy_objfile_data_key + = register_objfile_data_with_cleanup (NULL, del_objfile_macro); + + Py_INCREF (¯o_object_type); + PyModule_AddObject (gdb_module, "Macro", + (PyObject *) ¯o_object_type); + + Py_INCREF (¯o_validator_object_type); + PyModule_AddObject (gdb_module, "MacroValidator", + (PyObject *) ¯o_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 . */ + +#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