GDB (xrefs)
py-evtregistry.c
Go to the documentation of this file.
1 /* Python interface to inferior thread event registries.
2 
3  Copyright (C) 2009-2015 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 "command.h"
22 #include "py-events.h"
23 
25 
26 extern PyTypeObject eventregistry_object_type
27  CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("eventregistry_object");
28 
29 /* Implementation of EventRegistry.connect () -> NULL.
30  Add FUNCTION to the list of listeners. */
31 
32 static PyObject *
33 evregpy_connect (PyObject *self, PyObject *function)
34 {
35  PyObject *func;
36  PyObject *callback_list = (((eventregistry_object *) self)->callbacks);
37 
38  if (!PyArg_ParseTuple (function, "O", &func))
39  return NULL;
40 
41  if (!PyCallable_Check (func))
42  {
43  PyErr_SetString (PyExc_RuntimeError, "Function is not callable");
44  return NULL;
45  }
46 
47  if (PyList_Append (callback_list, func) < 0)
48  return NULL;
49 
50  Py_RETURN_NONE;
51 }
52 
53 /* Implementation of EventRegistry.disconnect () -> NULL.
54  Remove FUNCTION from the list of listeners. */
55 
56 static PyObject *
57 evregpy_disconnect (PyObject *self, PyObject *function)
58 {
59  PyObject *func;
60  int index;
61  PyObject *callback_list = (((eventregistry_object *) self)->callbacks);
62 
63  if (!PyArg_ParseTuple (function, "O", &func))
64  return NULL;
65 
66  index = PySequence_Index (callback_list, func);
67  if (index < 0)
68  Py_RETURN_NONE;
69 
70  if (PySequence_DelItem (callback_list, index) < 0)
71  return NULL;
72 
73  Py_RETURN_NONE;
74 }
75 
76 /* Create a new event registry. This function uses PyObject_New
77  and therefore returns a new reference that callers must handle. */
78 
81 {
82  eventregistry_object *eventregistry_obj;
83 
84  eventregistry_obj = PyObject_New (eventregistry_object,
86 
87  if (!eventregistry_obj)
88  return NULL;
89 
90  eventregistry_obj->callbacks = PyList_New (0);
91  if (!eventregistry_obj->callbacks)
92  {
93  Py_DECREF (eventregistry_obj);
94  return NULL;
95  }
96 
97  return eventregistry_obj;
98 }
99 
100 static void
101 evregpy_dealloc (PyObject *self)
102 {
103  Py_XDECREF (((eventregistry_object *) self)->callbacks);
104  Py_TYPE (self)->tp_free (self);
105 }
106 
107 /* Initialize the Python event registry code. */
108 
109 int
111 {
112  if (PyType_Ready (&eventregistry_object_type) < 0)
113  return -1;
114 
115  return gdb_pymodule_addobject (gdb_module, "EventRegistry",
116  (PyObject *) &eventregistry_object_type);
117 }
118 
119 /* Retern the number of listeners currently connected to this
120  registry. */
121 
122 int
124 {
125  return PyList_Size (registry->callbacks) == 0;
126 }
127 
128 static PyMethodDef eventregistry_object_methods[] =
129 {
130  { "connect", evregpy_connect, METH_VARARGS, "Add function" },
131  { "disconnect", evregpy_disconnect, METH_VARARGS, "Remove function" },
132  { NULL } /* Sentinel. */
133 };
134 
136 {
137  PyVarObject_HEAD_INIT (NULL, 0)
138  "gdb.EventRegistry", /* tp_name */
139  sizeof (eventregistry_object), /* tp_basicsize */
140  0, /* tp_itemsize */
141  evregpy_dealloc, /* tp_dealloc */
142  0, /* tp_print */
143  0, /* tp_getattr */
144  0, /* tp_setattr */
145  0, /* tp_compare */
146  0, /* tp_repr */
147  0, /* tp_as_number */
148  0, /* tp_as_sequence */
149  0, /* tp_as_mapping */
150  0, /* tp_hash */
151  0, /* tp_call */
152  0, /* tp_str */
153  0, /* tp_getattro */
154  0, /* tp_setattro */
155  0, /* tp_as_buffer */
156  Py_TPFLAGS_DEFAULT, /* tp_flags */
157  "GDB event registry object", /* tp_doc */
158  0, /* tp_traverse */
159  0, /* tp_clear */
160  0, /* tp_richcompare */
161  0, /* tp_weaklistoffset */
162  0, /* tp_iter */
163  0, /* tp_iternext */
164  eventregistry_object_methods, /* tp_methods */
165  0, /* tp_members */
166  0, /* tp_getset */
167  0, /* tp_base */
168  0, /* tp_dict */
169  0, /* tp_descr_get */
170  0, /* tp_descr_set */
171  0, /* tp_dictoffset */
172  0, /* tp_init */
173  0 /* tp_alloc */
174 };
int gdb_pymodule_addobject(PyObject *module, const char *name, PyObject *object)
Definition: py-utils.c:437
#define Py_DECREF(op)
static void evregpy_dealloc(PyObject *self)
eventregistry_object * create_eventregistry_object(void)
void(* func)(char *)
PyObject_HEAD PyObject * callbacks
Definition: py-events.h:37
static PyObject * evregpy_connect(PyObject *self, PyObject *function)
int evregpy_no_listeners_p(eventregistry_object *registry)
PyTypeObject eventregistry_object_type
events_object gdb_py_events
PyTypeObject eventregistry_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF("eventregistry_object")
static PyObject * evregpy_disconnect(PyObject *self, PyObject *function)
PyObject * gdb_module
Definition: python.c:112
int gdbpy_initialize_eventregistry(void)
static PyMethodDef eventregistry_object_methods[]
#define Py_TYPE(ob)
#define PyVarObject_HEAD_INIT(type, size)