1c50c785cSJohn Marino /* Python interface to inferior thread event registries.
2c50c785cSJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2009-2013 Free Software Foundation, Inc.
4c50c785cSJohn Marino
5c50c785cSJohn Marino This file is part of GDB.
6c50c785cSJohn Marino
7c50c785cSJohn Marino This program is free software; you can redistribute it and/or modify
8c50c785cSJohn Marino it under the terms of the GNU General Public License as published by
9c50c785cSJohn Marino the Free Software Foundation; either version 3 of the License, or
10c50c785cSJohn Marino (at your option) any later version.
11c50c785cSJohn Marino
12c50c785cSJohn Marino This program is distributed in the hope that it will be useful,
13c50c785cSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14c50c785cSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15c50c785cSJohn Marino GNU General Public License for more details.
16c50c785cSJohn Marino
17c50c785cSJohn Marino You should have received a copy of the GNU General Public License
18c50c785cSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19c50c785cSJohn Marino
20c50c785cSJohn Marino #include "defs.h"
21c50c785cSJohn Marino #include "command.h"
22c50c785cSJohn Marino #include "py-events.h"
23c50c785cSJohn Marino
24a45ae5f8SJohn Marino events_object gdb_py_events;
25a45ae5f8SJohn Marino
26c50c785cSJohn Marino static PyTypeObject eventregistry_object_type;
27c50c785cSJohn Marino
28c50c785cSJohn Marino /* Implementation of EventRegistry.connect () -> NULL.
29c50c785cSJohn Marino Add FUNCTION to the list of listeners. */
30c50c785cSJohn Marino
31c50c785cSJohn Marino static PyObject *
evregpy_connect(PyObject * self,PyObject * function)32c50c785cSJohn Marino evregpy_connect (PyObject *self, PyObject *function)
33c50c785cSJohn Marino {
34c50c785cSJohn Marino PyObject *func;
35c50c785cSJohn Marino PyObject *callback_list = (((eventregistry_object *) self)->callbacks);
36c50c785cSJohn Marino
37c50c785cSJohn Marino if (!PyArg_ParseTuple (function, "O", &func))
38c50c785cSJohn Marino return NULL;
39c50c785cSJohn Marino
40c50c785cSJohn Marino if (!PyCallable_Check (func))
41c50c785cSJohn Marino {
42c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError, "Function is not callable");
43c50c785cSJohn Marino return NULL;
44c50c785cSJohn Marino }
45c50c785cSJohn Marino
46c50c785cSJohn Marino if (PyList_Append (callback_list, func) < 0)
47c50c785cSJohn Marino return NULL;
48c50c785cSJohn Marino
49c50c785cSJohn Marino Py_RETURN_NONE;
50c50c785cSJohn Marino }
51c50c785cSJohn Marino
52c50c785cSJohn Marino /* Implementation of EventRegistry.disconnect () -> NULL.
53c50c785cSJohn Marino Remove FUNCTION from the list of listeners. */
54c50c785cSJohn Marino
55c50c785cSJohn Marino static PyObject *
evregpy_disconnect(PyObject * self,PyObject * function)56c50c785cSJohn Marino evregpy_disconnect (PyObject *self, PyObject *function)
57c50c785cSJohn Marino {
58c50c785cSJohn Marino PyObject *func;
59c50c785cSJohn Marino int index;
60c50c785cSJohn Marino PyObject *callback_list = (((eventregistry_object *) self)->callbacks);
61c50c785cSJohn Marino
62c50c785cSJohn Marino if (!PyArg_ParseTuple (function, "O", &func))
63c50c785cSJohn Marino return NULL;
64c50c785cSJohn Marino
65c50c785cSJohn Marino index = PySequence_Index (callback_list, func);
66c50c785cSJohn Marino if (index < 0)
67c50c785cSJohn Marino Py_RETURN_NONE;
68c50c785cSJohn Marino
69c50c785cSJohn Marino if (PySequence_DelItem (callback_list, index) < 0)
70c50c785cSJohn Marino return NULL;
71c50c785cSJohn Marino
72c50c785cSJohn Marino Py_RETURN_NONE;
73c50c785cSJohn Marino }
74c50c785cSJohn Marino
75c50c785cSJohn Marino /* Create a new event registry. This function uses PyObject_New
76c50c785cSJohn Marino and therefore returns a new reference that callers must handle. */
77c50c785cSJohn Marino
78c50c785cSJohn Marino eventregistry_object *
create_eventregistry_object(void)79c50c785cSJohn Marino create_eventregistry_object (void)
80c50c785cSJohn Marino {
81c50c785cSJohn Marino eventregistry_object *eventregistry_obj;
82c50c785cSJohn Marino
83c50c785cSJohn Marino eventregistry_obj = PyObject_New (eventregistry_object,
84c50c785cSJohn Marino &eventregistry_object_type);
85c50c785cSJohn Marino
86c50c785cSJohn Marino if (!eventregistry_obj)
87c50c785cSJohn Marino return NULL;
88c50c785cSJohn Marino
89c50c785cSJohn Marino eventregistry_obj->callbacks = PyList_New (0);
90c50c785cSJohn Marino if (!eventregistry_obj->callbacks)
91c50c785cSJohn Marino return NULL;
92c50c785cSJohn Marino
93c50c785cSJohn Marino return eventregistry_obj;
94c50c785cSJohn Marino }
95c50c785cSJohn Marino
96c50c785cSJohn Marino static void
evregpy_dealloc(PyObject * self)97c50c785cSJohn Marino evregpy_dealloc (PyObject *self)
98c50c785cSJohn Marino {
99c50c785cSJohn Marino Py_XDECREF (((eventregistry_object *) self)->callbacks);
100*ef5ccd6cSJohn Marino Py_TYPE (self)->tp_free (self);
101c50c785cSJohn Marino }
102c50c785cSJohn Marino
103c50c785cSJohn Marino /* Initialize the Python event registry code. */
104c50c785cSJohn Marino
105c50c785cSJohn Marino void
gdbpy_initialize_eventregistry(void)106c50c785cSJohn Marino gdbpy_initialize_eventregistry (void)
107c50c785cSJohn Marino {
108c50c785cSJohn Marino if (PyType_Ready (&eventregistry_object_type) < 0)
109c50c785cSJohn Marino return;
110c50c785cSJohn Marino
111c50c785cSJohn Marino Py_INCREF (&eventregistry_object_type);
112c50c785cSJohn Marino PyModule_AddObject (gdb_module, "EventRegistry",
113c50c785cSJohn Marino (PyObject *) &eventregistry_object_type);
114c50c785cSJohn Marino }
115c50c785cSJohn Marino
116c50c785cSJohn Marino /* Retern the number of listeners currently connected to this
117c50c785cSJohn Marino registry. */
118c50c785cSJohn Marino
119c50c785cSJohn Marino int
evregpy_no_listeners_p(eventregistry_object * registry)120c50c785cSJohn Marino evregpy_no_listeners_p (eventregistry_object *registry)
121c50c785cSJohn Marino {
122c50c785cSJohn Marino return PyList_Size (registry->callbacks) == 0;
123c50c785cSJohn Marino }
124c50c785cSJohn Marino
125c50c785cSJohn Marino static PyMethodDef eventregistry_object_methods[] =
126c50c785cSJohn Marino {
127c50c785cSJohn Marino { "connect", evregpy_connect, METH_VARARGS, "Add function" },
128c50c785cSJohn Marino { "disconnect", evregpy_disconnect, METH_VARARGS, "Remove function" },
129c50c785cSJohn Marino { NULL } /* Sentinel. */
130c50c785cSJohn Marino };
131c50c785cSJohn Marino
132c50c785cSJohn Marino static PyTypeObject eventregistry_object_type =
133c50c785cSJohn Marino {
134*ef5ccd6cSJohn Marino PyVarObject_HEAD_INIT (NULL, 0)
135c50c785cSJohn Marino "gdb.EventRegistry", /* tp_name */
136c50c785cSJohn Marino sizeof (eventregistry_object), /* tp_basicsize */
137c50c785cSJohn Marino 0, /* tp_itemsize */
138c50c785cSJohn Marino evregpy_dealloc, /* tp_dealloc */
139c50c785cSJohn Marino 0, /* tp_print */
140c50c785cSJohn Marino 0, /* tp_getattr */
141c50c785cSJohn Marino 0, /* tp_setattr */
142c50c785cSJohn Marino 0, /* tp_compare */
143c50c785cSJohn Marino 0, /* tp_repr */
144c50c785cSJohn Marino 0, /* tp_as_number */
145c50c785cSJohn Marino 0, /* tp_as_sequence */
146c50c785cSJohn Marino 0, /* tp_as_mapping */
147c50c785cSJohn Marino 0, /* tp_hash */
148c50c785cSJohn Marino 0, /* tp_call */
149c50c785cSJohn Marino 0, /* tp_str */
150c50c785cSJohn Marino 0, /* tp_getattro */
151c50c785cSJohn Marino 0, /* tp_setattro */
152c50c785cSJohn Marino 0, /* tp_as_buffer */
153c50c785cSJohn Marino Py_TPFLAGS_DEFAULT, /* tp_flags */
154c50c785cSJohn Marino "GDB event registry object", /* tp_doc */
155c50c785cSJohn Marino 0, /* tp_traverse */
156c50c785cSJohn Marino 0, /* tp_clear */
157c50c785cSJohn Marino 0, /* tp_richcompare */
158c50c785cSJohn Marino 0, /* tp_weaklistoffset */
159c50c785cSJohn Marino 0, /* tp_iter */
160c50c785cSJohn Marino 0, /* tp_iternext */
161c50c785cSJohn Marino eventregistry_object_methods, /* tp_methods */
162c50c785cSJohn Marino 0, /* tp_members */
163c50c785cSJohn Marino 0, /* tp_getset */
164c50c785cSJohn Marino 0, /* tp_base */
165c50c785cSJohn Marino 0, /* tp_dict */
166c50c785cSJohn Marino 0, /* tp_descr_get */
167c50c785cSJohn Marino 0, /* tp_descr_set */
168c50c785cSJohn Marino 0, /* tp_dictoffset */
169c50c785cSJohn Marino 0, /* tp_init */
170c50c785cSJohn Marino 0 /* tp_alloc */
171c50c785cSJohn Marino };
172