lib: strictly type function return status enumerations
[babeltrace.git] / src / bindings / python / bt2 / bt2 / native_bt_graph.i
1 /*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 /* Output argument typemap for connection output (always appends) */
26 %typemap(in, numinputs=0)
27 (const bt_connection **)
28 (bt_connection *temp_conn = NULL) {
29 $1 = &temp_conn;
30 }
31
32 %typemap(argout)
33 (const bt_connection **) {
34 if (*$1) {
35 /* SWIG_Python_AppendOutput() steals the created object */
36 $result = SWIG_Python_AppendOutput($result,
37 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
38 SWIGTYPE_p_bt_connection, 0));
39 } else {
40 /* SWIG_Python_AppendOutput() steals Py_None */
41 Py_INCREF(Py_None);
42 $result = SWIG_Python_AppendOutput($result, Py_None);
43 }
44 }
45
46 /* Output argument typemap for component output (always appends) */
47 %typemap(in, numinputs=0)
48 (const bt_component_source **)
49 (bt_component_source *temp_comp = NULL) {
50 $1 = &temp_comp;
51 }
52
53 %typemap(in, numinputs=0)
54 (const bt_component_filter **)
55 (bt_component_filter *temp_comp = NULL) {
56 $1 = &temp_comp;
57 }
58
59 %typemap(in, numinputs=0)
60 (const bt_component_sink **)
61 (bt_component_sink *temp_comp = NULL) {
62 $1 = &temp_comp;
63 }
64
65 %typemap(argout) (const bt_component_source **) {
66 if (*$1) {
67 /* SWIG_Python_AppendOutput() steals the created object */
68 $result = SWIG_Python_AppendOutput($result,
69 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
70 SWIGTYPE_p_bt_component_source, 0));
71 } else {
72 /* SWIG_Python_AppendOutput() steals Py_None */
73 Py_INCREF(Py_None);
74 $result = SWIG_Python_AppendOutput($result, Py_None);
75 }
76 }
77
78 %typemap(argout) (const bt_component_filter **) {
79 if (*$1) {
80 /* SWIG_Python_AppendOutput() steals the created object */
81 $result = SWIG_Python_AppendOutput($result,
82 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
83 SWIGTYPE_p_bt_component_filter, 0));
84 } else {
85 /* SWIG_Python_AppendOutput() steals Py_None */
86 Py_INCREF(Py_None);
87 $result = SWIG_Python_AppendOutput($result, Py_None);
88 }
89 }
90
91 %typemap(argout) (const bt_component_sink **) {
92 if (*$1) {
93 /* SWIG_Python_AppendOutput() steals the created object */
94 $result = SWIG_Python_AppendOutput($result,
95 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
96 SWIGTYPE_p_bt_component_sink, 0));
97 } else {
98 /* SWIG_Python_AppendOutput() steals Py_None */
99 Py_INCREF(Py_None);
100 $result = SWIG_Python_AppendOutput($result, Py_None);
101 }
102 }
103
104 %include <babeltrace2/graph/graph-const.h>
105 %include <babeltrace2/graph/graph.h>
106
107 /* Helper functions for Python */
108
109 %{
110 static
111 void graph_listener_removed(void *py_callable)
112 {
113 BT_ASSERT(py_callable);
114 Py_DECREF(py_callable);
115 }
116
117 static bt_graph_listener_func_status port_added_listener(
118 const void *component,
119 swig_type_info *component_swig_type,
120 bt_component_class_type component_class_type,
121 const void *port,
122 swig_type_info *port_swig_type,
123 bt_port_type port_type,
124 void *py_callable)
125 {
126 PyObject *py_component_ptr = NULL;
127 PyObject *py_port_ptr = NULL;
128 PyObject *py_res = NULL;
129 bt_graph_listener_func_status status;
130
131 py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0);
132 if (!py_component_ptr) {
133 BT_LOGF_STR("Failed to create component SWIG pointer object.");
134 status = __BT_FUNC_STATUS_MEMORY_ERROR;
135 goto end;
136 }
137
138 py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port), port_swig_type, 0);
139 if (!py_port_ptr) {
140 BT_LOGF_STR("Failed to create port SWIG pointer object.");
141 status = __BT_FUNC_STATUS_MEMORY_ERROR;
142 goto end;
143 }
144
145 py_res = PyObject_CallFunction(py_callable, "(OiOi)",
146 py_component_ptr, component_class_type, py_port_ptr, port_type);
147 if (!py_res) {
148 loge_exception();
149 PyErr_Clear();
150 status = __BT_FUNC_STATUS_ERROR;
151 goto end;
152 }
153
154 BT_ASSERT(py_res == Py_None);
155 status = __BT_FUNC_STATUS_OK;
156
157 end:
158 Py_XDECREF(py_res);
159 Py_XDECREF(py_port_ptr);
160 Py_XDECREF(py_component_ptr);
161 return status;
162 }
163
164 static
165 bt_graph_listener_func_status
166 source_component_output_port_added_listener(const bt_component_source *component_source,
167 const bt_port_output *port_output, void *py_callable)
168 {
169 return port_added_listener(
170 component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
171 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
172 }
173
174 static
175 bt_graph_listener_func_status
176 filter_component_input_port_added_listener(const bt_component_filter *component_filter,
177 const bt_port_input *port_input, void *py_callable)
178 {
179 return port_added_listener(
180 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
181 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
182 }
183
184 static
185 bt_graph_listener_func_status
186 filter_component_output_port_added_listener(const bt_component_filter *component_filter,
187 const bt_port_output *port_output, void *py_callable)
188 {
189 return port_added_listener(
190 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
191 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
192 }
193
194 static
195 bt_graph_listener_func_status
196 sink_component_input_port_added_listener(const bt_component_sink *component_sink,
197 const bt_port_input *port_input, void *py_callable)
198 {
199 return port_added_listener(
200 component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
201 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
202 }
203
204 static
205 PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph,
206 PyObject *py_callable)
207 {
208 PyObject *py_listener_ids = NULL;
209 PyObject *py_listener_id = NULL;
210 int listener_id;
211 bt_graph_add_listener_status status;
212
213 BT_ASSERT(graph);
214 BT_ASSERT(py_callable);
215
216 /*
217 * Behind the scene, we will be registering 4 different listeners and
218 * return all of their ids.
219 */
220 py_listener_ids = PyTuple_New(4);
221 if (!py_listener_ids) {
222 goto error;
223 }
224
225 /* source output port */
226 status = bt_graph_add_source_component_output_port_added_listener(
227 graph, source_component_output_port_added_listener,
228 graph_listener_removed, py_callable, &listener_id);
229 if (status != __BT_FUNC_STATUS_OK) {
230 goto error;
231 }
232
233 py_listener_id = PyLong_FromLong(listener_id);
234 if (!py_listener_id) {
235 goto error;
236 }
237
238 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
239 py_listener_id = NULL;
240
241 /* filter input port */
242 status = bt_graph_add_filter_component_input_port_added_listener(
243 graph, filter_component_input_port_added_listener,
244 graph_listener_removed, py_callable, &listener_id);
245 if (status != __BT_FUNC_STATUS_OK) {
246 goto error;
247 }
248
249 py_listener_id = PyLong_FromLong(listener_id);
250 if (!py_listener_id) {
251 goto error;
252 }
253
254 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
255 py_listener_id = NULL;
256
257 /* filter output port */
258 status = bt_graph_add_filter_component_output_port_added_listener(
259 graph, filter_component_output_port_added_listener,
260 graph_listener_removed, py_callable, &listener_id);
261 if (status != __BT_FUNC_STATUS_OK) {
262 goto error;
263 }
264
265 py_listener_id = PyLong_FromLong(listener_id);
266 if (!py_listener_id) {
267 goto error;
268 }
269
270 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
271 py_listener_id = NULL;
272
273 /* sink input port */
274 status = bt_graph_add_sink_component_input_port_added_listener(
275 graph, sink_component_input_port_added_listener,
276 graph_listener_removed, py_callable, &listener_id);
277 if (status != __BT_FUNC_STATUS_OK) {
278 goto error;
279 }
280
281 py_listener_id = PyLong_FromLong(listener_id);
282 if (!py_listener_id) {
283 goto error;
284 }
285
286
287 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
288 py_listener_id = NULL;
289
290 Py_INCREF(py_callable);
291 Py_INCREF(py_callable);
292 Py_INCREF(py_callable);
293 Py_INCREF(py_callable);
294
295 goto end;
296
297 error:
298 Py_XDECREF(py_listener_ids);
299 py_listener_ids = Py_None;
300 Py_INCREF(py_listener_ids);
301
302 end:
303
304 Py_XDECREF(py_listener_id);
305 return py_listener_ids;
306 }
307
308 static
309 bt_graph_listener_func_status ports_connected_listener(
310 const void *upstream_component,
311 swig_type_info *upstream_component_swig_type,
312 bt_component_class_type upstream_component_class_type,
313 const bt_port_output *upstream_port,
314 const void *downstream_component,
315 swig_type_info *downstream_component_swig_type,
316 bt_component_class_type downstream_component_class_type,
317 const bt_port_input *downstream_port,
318 void *py_callable)
319 {
320 PyObject *py_upstream_component_ptr = NULL;
321 PyObject *py_upstream_port_ptr = NULL;
322 PyObject *py_downstream_component_ptr = NULL;
323 PyObject *py_downstream_port_ptr = NULL;
324 PyObject *py_res = NULL;
325 bt_graph_listener_func_status status;
326
327 py_upstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(upstream_component),
328 upstream_component_swig_type, 0);
329 if (!py_upstream_component_ptr) {
330 BT_LOGF_STR("Failed to create upstream component SWIG pointer object.");
331 status = __BT_FUNC_STATUS_MEMORY_ERROR;
332 goto end;
333 }
334
335 py_upstream_port_ptr = SWIG_NewPointerObj(
336 SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0);
337 if (!py_upstream_port_ptr) {
338 BT_LOGF_STR("Failed to create upstream port SWIG pointer object.");
339 status = __BT_FUNC_STATUS_MEMORY_ERROR;
340 goto end;
341 }
342
343 py_downstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(downstream_component),
344 downstream_component_swig_type, 0);
345 if (!py_downstream_component_ptr) {
346 BT_LOGF_STR("Failed to create downstream component SWIG pointer object.");
347 status = __BT_FUNC_STATUS_MEMORY_ERROR;
348 goto end;
349 }
350
351 py_downstream_port_ptr = SWIG_NewPointerObj(
352 SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port_input, 0);
353 if (!py_downstream_port_ptr) {
354 BT_LOGF_STR("Failed to create downstream port SWIG pointer object.");
355 status = __BT_FUNC_STATUS_MEMORY_ERROR;
356 goto end;
357 }
358
359 py_res = PyObject_CallFunction(py_callable, "(OiOOiO)",
360 py_upstream_component_ptr, upstream_component_class_type,
361 py_upstream_port_ptr,
362 py_downstream_component_ptr, downstream_component_class_type,
363 py_downstream_port_ptr);
364 if (!py_res) {
365 loge_exception();
366 PyErr_Clear();
367 status = __BT_FUNC_STATUS_ERROR;
368 goto end;
369 }
370
371 BT_ASSERT(py_res == Py_None);
372 status = __BT_FUNC_STATUS_OK;
373
374 end:
375 Py_XDECREF(py_upstream_component_ptr);
376 Py_XDECREF(py_upstream_port_ptr);
377 Py_XDECREF(py_downstream_component_ptr);
378 Py_XDECREF(py_downstream_port_ptr);
379 Py_XDECREF(py_res);
380 return status;
381 }
382
383 static
384 bt_graph_listener_func_status source_filter_component_ports_connected_listener(
385 const bt_component_source *source_component,
386 const bt_component_filter *filter_component,
387 const bt_port_output *upstream_port,
388 const bt_port_input *downstream_port, void *py_callable)
389 {
390 return ports_connected_listener(
391 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
392 upstream_port,
393 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
394 downstream_port,
395 py_callable);
396 }
397
398 static
399 bt_graph_listener_func_status source_sink_component_ports_connected_listener(
400 const bt_component_source *source_component,
401 const bt_component_sink *sink_component,
402 const bt_port_output *upstream_port,
403 const bt_port_input *downstream_port, void *py_callable)
404 {
405 return ports_connected_listener(
406 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
407 upstream_port,
408 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
409 downstream_port,
410 py_callable);
411 }
412
413 static
414 bt_graph_listener_func_status filter_filter_component_ports_connected_listener(
415 const bt_component_filter *filter_component_left,
416 const bt_component_filter *filter_component_right,
417 const bt_port_output *upstream_port,
418 const bt_port_input *downstream_port, void *py_callable)
419 {
420 return ports_connected_listener(
421 filter_component_left, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
422 upstream_port,
423 filter_component_right, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
424 downstream_port,
425 py_callable);
426 }
427
428 static
429 bt_graph_listener_func_status filter_sink_component_ports_connected_listener(
430 const bt_component_filter *filter_component,
431 const bt_component_sink *sink_component,
432 const bt_port_output *upstream_port,
433 const bt_port_input *downstream_port, void *py_callable)
434 {
435 return ports_connected_listener(
436 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
437 upstream_port,
438 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
439 downstream_port,
440 py_callable);
441 }
442
443 static
444 PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph,
445 PyObject *py_callable)
446 {
447 PyObject *py_listener_ids = NULL;
448 PyObject *py_listener_id = NULL;
449 int listener_id;
450 bt_graph_add_listener_status status;
451
452 BT_ASSERT(graph);
453 BT_ASSERT(py_callable);
454
455 /* Behind the scene, we will be registering 4 different listeners and
456 * return all of their ids. */
457 py_listener_ids = PyTuple_New(4);
458 if (!py_listener_ids) {
459 goto error;
460 }
461
462 /* source -> filter connection */
463 status = bt_graph_add_source_filter_component_ports_connected_listener(
464 graph, source_filter_component_ports_connected_listener,
465 graph_listener_removed, py_callable, &listener_id);
466 if (status != __BT_FUNC_STATUS_OK) {
467 goto error;
468 }
469
470 py_listener_id = PyLong_FromLong(listener_id);
471 if (!py_listener_id) {
472 goto error;
473 }
474
475 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
476 py_listener_id = NULL;
477
478 /* source -> sink connection */
479 status = bt_graph_add_source_sink_component_ports_connected_listener(
480 graph, source_sink_component_ports_connected_listener,
481 graph_listener_removed, py_callable, &listener_id);
482 if (status != __BT_FUNC_STATUS_OK) {
483 goto error;
484 }
485
486 py_listener_id = PyLong_FromLong(listener_id);
487 if (!py_listener_id) {
488 goto error;
489 }
490
491 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
492 py_listener_id = NULL;
493
494 /* filter -> filter connection */
495 status = bt_graph_add_filter_filter_component_ports_connected_listener(
496 graph, filter_filter_component_ports_connected_listener,
497 graph_listener_removed, py_callable, &listener_id);
498 if (status != __BT_FUNC_STATUS_OK) {
499 goto error;
500 }
501
502 py_listener_id = PyLong_FromLong(listener_id);
503 if (!py_listener_id) {
504 goto error;
505 }
506
507 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
508 py_listener_id = NULL;
509
510 /* filter -> sink connection */
511 status = bt_graph_add_filter_sink_component_ports_connected_listener(
512 graph, filter_sink_component_ports_connected_listener,
513 graph_listener_removed, py_callable, &listener_id);
514 if (status != __BT_FUNC_STATUS_OK) {
515 goto error;
516 }
517
518 py_listener_id = PyLong_FromLong(listener_id);
519 if (!py_listener_id) {
520 goto error;
521 }
522
523 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
524 py_listener_id = NULL;
525
526 Py_INCREF(py_callable);
527 Py_INCREF(py_callable);
528 Py_INCREF(py_callable);
529 Py_INCREF(py_callable);
530
531 goto end;
532
533 error:
534 Py_XDECREF(py_listener_ids);
535 py_listener_ids = Py_None;
536 Py_INCREF(py_listener_ids);
537
538 end:
539
540 Py_XDECREF(py_listener_id);
541 return py_listener_ids;
542 }
543 %}
544
545 PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph,
546 PyObject *py_callable);
547 PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph,
548 PyObject *py_callable);
This page took 0.040972 seconds and 4 git commands to generate.