| 1 | /* Python interface to inferior events. |
| 2 | |
| 3 | Copyright (C) 2009-2012 Free Software Foundation, Inc. |
| 4 | |
| 5 | This file is part of GDB. |
| 6 | |
| 7 | This program is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation; either version 3 of the License, or |
| 10 | (at your option) any later version. |
| 11 | |
| 12 | This program is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. |
| 16 | |
| 17 | You should have received a copy of the GNU General Public License |
| 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | |
| 20 | #include "defs.h" |
| 21 | #include "py-event.h" |
| 22 | |
| 23 | void |
| 24 | evpy_dealloc (PyObject *self) |
| 25 | { |
| 26 | Py_XDECREF (((event_object *) self)->dict); |
| 27 | Py_TYPE (self)->tp_free (self); |
| 28 | } |
| 29 | |
| 30 | PyObject * |
| 31 | create_event_object (PyTypeObject *py_type) |
| 32 | { |
| 33 | event_object *event_obj; |
| 34 | |
| 35 | event_obj = PyObject_New (event_object, py_type); |
| 36 | if (!event_obj) |
| 37 | goto fail; |
| 38 | |
| 39 | event_obj->dict = PyDict_New (); |
| 40 | if (!event_obj->dict) |
| 41 | goto fail; |
| 42 | |
| 43 | return (PyObject*) event_obj; |
| 44 | |
| 45 | fail: |
| 46 | Py_XDECREF (event_obj); |
| 47 | return NULL; |
| 48 | } |
| 49 | |
| 50 | /* Add the attribute ATTR to the event object EVENT. In |
| 51 | python this attribute will be accessible by the name NAME. |
| 52 | returns 0 if the operation succeeds and -1 otherwise. This |
| 53 | function acquires a new reference to ATTR. */ |
| 54 | |
| 55 | int |
| 56 | evpy_add_attribute (PyObject *event, char *name, PyObject *attr) |
| 57 | { |
| 58 | return PyObject_SetAttrString (event, name, attr); |
| 59 | } |
| 60 | |
| 61 | /* Initialize the Python event code. */ |
| 62 | |
| 63 | void |
| 64 | gdbpy_initialize_event (void) |
| 65 | { |
| 66 | gdbpy_initialize_event_generic (&event_object_type, |
| 67 | "Event"); |
| 68 | } |
| 69 | |
| 70 | /* Initialize the given event type. If BASE is not NULL it will |
| 71 | be set as the types base. |
| 72 | Returns 0 if initialization was successful -1 otherwise. */ |
| 73 | |
| 74 | int |
| 75 | gdbpy_initialize_event_generic (PyTypeObject *type, |
| 76 | char *name) |
| 77 | { |
| 78 | if (PyType_Ready (type) < 0) |
| 79 | goto fail; |
| 80 | |
| 81 | Py_INCREF (type); |
| 82 | if (PyModule_AddObject (gdb_module, name, (PyObject *) type) < 0) |
| 83 | goto fail; |
| 84 | |
| 85 | return 0; |
| 86 | |
| 87 | fail: |
| 88 | Py_XDECREF (type); |
| 89 | return -1; |
| 90 | } |
| 91 | |
| 92 | |
| 93 | /* Notify the list of listens that the given EVENT has occurred. |
| 94 | returns 0 if emit is successful -1 otherwise. */ |
| 95 | |
| 96 | int |
| 97 | evpy_emit_event (PyObject *event, |
| 98 | eventregistry_object *registry) |
| 99 | { |
| 100 | PyObject *callback_list_copy = NULL; |
| 101 | Py_ssize_t i; |
| 102 | |
| 103 | /* Create a copy of call back list and use that for |
| 104 | notifying listeners to avoid skipping callbacks |
| 105 | in the case of a callback being disconnected during |
| 106 | a notification. */ |
| 107 | callback_list_copy = PySequence_List (registry->callbacks); |
| 108 | if (!callback_list_copy) |
| 109 | goto fail; |
| 110 | |
| 111 | for (i = 0; i < PyList_Size (callback_list_copy); i++) |
| 112 | { |
| 113 | PyObject *func = PyList_GetItem (callback_list_copy, i); |
| 114 | |
| 115 | if (func == NULL) |
| 116 | goto fail; |
| 117 | |
| 118 | if (!PyObject_CallFunctionObjArgs (func, event, NULL)) |
| 119 | { |
| 120 | /* Print the trace here, but keep going -- we want to try to |
| 121 | call all of the callbacks even if one is broken. */ |
| 122 | gdbpy_print_stack (); |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | Py_XDECREF (callback_list_copy); |
| 127 | Py_XDECREF (event); |
| 128 | return 0; |
| 129 | |
| 130 | fail: |
| 131 | gdbpy_print_stack (); |
| 132 | Py_XDECREF (callback_list_copy); |
| 133 | Py_XDECREF (event); |
| 134 | return -1; |
| 135 | } |
| 136 | |
| 137 | static PyGetSetDef event_object_getset[] = |
| 138 | { |
| 139 | { "__dict__", gdb_py_generic_dict, NULL, |
| 140 | "The __dict__ for this event.", &event_object_type }, |
| 141 | { NULL } |
| 142 | }; |
| 143 | |
| 144 | PyTypeObject event_object_type = |
| 145 | { |
| 146 | PyVarObject_HEAD_INIT (NULL, 0) |
| 147 | "gdb.Event", /* tp_name */ |
| 148 | sizeof (event_object), /* tp_basicsize */ |
| 149 | 0, /* tp_itemsize */ |
| 150 | evpy_dealloc, /* tp_dealloc */ |
| 151 | 0, /* tp_print */ |
| 152 | 0, /* tp_getattr */ |
| 153 | 0, /* tp_setattr */ |
| 154 | 0, /* tp_compare */ |
| 155 | 0, /* tp_repr */ |
| 156 | 0, /* tp_as_number */ |
| 157 | 0, /* tp_as_sequence */ |
| 158 | 0, /* tp_as_mapping */ |
| 159 | 0, /* tp_hash */ |
| 160 | 0, /* tp_call */ |
| 161 | 0, /* tp_str */ |
| 162 | 0, /* tp_getattro */ |
| 163 | 0, /* tp_setattro */ |
| 164 | 0, /* tp_as_buffer */ |
| 165 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
| 166 | "GDB event object", /* tp_doc */ |
| 167 | 0, /* tp_traverse */ |
| 168 | 0, /* tp_clear */ |
| 169 | 0, /* tp_richcompare */ |
| 170 | 0, /* tp_weaklistoffset */ |
| 171 | 0, /* tp_iter */ |
| 172 | 0, /* tp_iternext */ |
| 173 | 0, /* tp_methods */ |
| 174 | 0, /* tp_members */ |
| 175 | event_object_getset, /* tp_getset */ |
| 176 | 0, /* tp_base */ |
| 177 | 0, /* tp_dict */ |
| 178 | 0, /* tp_descr_get */ |
| 179 | 0, /* tp_descr_set */ |
| 180 | offsetof (event_object, dict), /* tp_dictoffset */ |
| 181 | 0, /* tp_init */ |
| 182 | 0 /* tp_alloc */ |
| 183 | }; |