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