1 /*
2  * python-complements.c
3  *
4  * Babeltrace Python module complements, required for Python bindings
5  *
6  * Copyright 2012 EfficiOS Inc.
7  *
8  * Author: Danny Serres <danny.serres@efficios.com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  */
20 
21 #include "python-complements.h"
22 #include <babeltrace/ctf-ir/field-types-internal.h>
23 #include <babeltrace/ctf-ir/fields-internal.h>
24 #include <babeltrace/iterator.h>
25 #include <babeltrace/ctf/iterator.h>
26 #include <babeltrace/ctf/events-internal.h>
27 #include <glib.h>
28 
29 /* FILE functions
30    ----------------------------------------------------
31 */
32 
_bt_file_open(char * file_path,char * mode)33 FILE *_bt_file_open(char *file_path, char *mode)
34 {
35 	FILE *fp = stdout;
36 	if (file_path != NULL)
37 		fp = fopen(file_path, mode);
38 	return fp;
39 }
40 
_bt_file_close(FILE * fp)41 void _bt_file_close(FILE *fp)
42 {
43 	if (fp != NULL)
44 		fclose(fp);
45 }
46 
47 
48 /* List-related functions
49    ----------------------------------------------------
50 */
51 
52 /* ctf-field-list */
_bt_python_field_listcaller(const struct bt_ctf_event * ctf_event,const struct bt_definition * scope,unsigned int * len)53 struct bt_definition **_bt_python_field_listcaller(
54 		const struct bt_ctf_event *ctf_event,
55 		const struct bt_definition *scope,
56 		unsigned int *len)
57 {
58 	struct bt_definition **list;
59 	int ret;
60 
61 	ret = bt_ctf_get_field_list(ctf_event, scope,
62 		(const struct bt_definition * const **)&list, len);
63 
64 	if (ret < 0)	/* For python to know an error occured */
65 		list = NULL;
66 
67 	return list;
68 }
69 
_bt_python_field_one_from_list(struct bt_definition ** list,int index)70 struct bt_definition *_bt_python_field_one_from_list(
71 		struct bt_definition **list, int index)
72 {
73 	return list[index];
74 }
75 
76 /* event_decl_list */
_bt_python_event_decl_listcaller(int handle_id,struct bt_context * ctx,unsigned int * len)77 struct bt_ctf_event_decl **_bt_python_event_decl_listcaller(
78 		int handle_id,
79 		struct bt_context *ctx,
80 		unsigned int *len)
81 {
82 	struct bt_ctf_event_decl **list;
83 	int ret;
84 
85 	ret = bt_ctf_get_event_decl_list(handle_id, ctx,
86 		(struct bt_ctf_event_decl * const **)&list, len);
87 
88 	if (ret < 0)	/* For python to know an error occured */
89 		list = NULL;
90 
91 	return list;
92 }
93 
_bt_python_decl_one_from_list(struct bt_ctf_event_decl ** list,int index)94 struct bt_ctf_event_decl *_bt_python_decl_one_from_list(
95 		struct bt_ctf_event_decl **list, int index)
96 {
97 	return list[index];
98 }
99 
100 /* decl_fields */
_by_python_field_decl_listcaller(struct bt_ctf_event_decl * event_decl,enum bt_ctf_scope scope,unsigned int * len)101 struct bt_ctf_field_decl **_by_python_field_decl_listcaller(
102 		struct bt_ctf_event_decl *event_decl,
103 		enum bt_ctf_scope scope,
104 		unsigned int *len)
105 {
106 	struct bt_ctf_field_decl **list;
107 	int ret;
108 
109 	ret = bt_ctf_get_decl_fields(event_decl, scope,
110 		(const struct bt_ctf_field_decl * const **)&list, len);
111 
112 	if (ret < 0)	/* For python to know an error occured */
113 		list = NULL;
114 
115 	return list;
116 }
117 
_bt_python_field_decl_one_from_list(struct bt_ctf_field_decl ** list,int index)118 struct bt_ctf_field_decl *_bt_python_field_decl_one_from_list(
119 		struct bt_ctf_field_decl **list, int index)
120 {
121 	return list[index];
122 }
123 
_bt_python_get_array_from_def(struct bt_definition * field)124 struct definition_array *_bt_python_get_array_from_def(
125 		struct bt_definition *field)
126 {
127 	const struct bt_declaration *array_decl;
128 	struct definition_array *array = NULL;
129 
130 	if (!field) {
131 		goto end;
132 	}
133 
134 	array_decl = bt_ctf_get_decl_from_def(field);
135 	if (bt_ctf_field_type(array_decl) == CTF_TYPE_ARRAY) {
136 		array = container_of(field, struct definition_array, p);
137 	}
138 end:
139 	return array;
140 }
141 
_bt_python_get_array_element_declaration(struct bt_declaration * field)142 struct bt_declaration *_bt_python_get_array_element_declaration(
143 		struct bt_declaration *field)
144 {
145 	struct declaration_array *array_decl;
146 	struct bt_declaration *ret = NULL;
147 
148 	if (!field) {
149 		goto end;
150 	}
151 
152 	array_decl = container_of(field, struct declaration_array, p);
153 	ret = array_decl->elem;
154 end:
155 	return ret;
156 }
157 
_bt_python_get_sequence_element_declaration(struct bt_declaration * field)158 struct bt_declaration *_bt_python_get_sequence_element_declaration(
159 		struct bt_declaration *field)
160 {
161 	struct declaration_sequence *sequence_decl;
162 	struct bt_declaration *ret = NULL;
163 
164 	if (!field) {
165 		goto end;
166 	}
167 
168 	sequence_decl = container_of(field, struct declaration_sequence, p);
169 	ret = sequence_decl->elem;
170 end:
171 	return ret;
172 }
173 
_bt_python_get_array_string(struct bt_definition * field)174 const char *_bt_python_get_array_string(struct bt_definition *field)
175 {
176 	struct definition_array *array;
177 	const char *ret = NULL;
178 
179 	if (!field) {
180 		goto end;
181 	}
182 
183 	array = container_of(field, struct definition_array, p);
184 	ret = array->string->str;
185 end:
186 	return ret;
187 }
188 
_bt_python_get_sequence_string(struct bt_definition * field)189 const char *_bt_python_get_sequence_string(struct bt_definition *field)
190 {
191 	struct definition_sequence *sequence;
192 	const char *ret = NULL;
193 
194 	if (!field) {
195 		goto end;
196 	}
197 
198 	sequence = container_of(field, struct definition_sequence, p);
199 	ret = sequence->string->str;
200 end:
201 	return ret;
202 }
203 
_bt_python_get_sequence_from_def(struct bt_definition * field)204 struct definition_sequence *_bt_python_get_sequence_from_def(
205 		struct bt_definition *field)
206 {
207 	if (field && bt_ctf_field_type(
208 		bt_ctf_get_decl_from_def(field)) == CTF_TYPE_SEQUENCE) {
209 		return container_of(field, struct definition_sequence, p);
210 	}
211 
212 	return NULL;
213 }
214 
_bt_python_field_integer_get_signedness(const struct bt_ctf_field * field)215 int _bt_python_field_integer_get_signedness(const struct bt_ctf_field *field)
216 {
217 	int ret;
218 
219 	if (!field || field->type->declaration->id != CTF_TYPE_INTEGER) {
220 		ret = -1;
221 		goto end;
222 	}
223 
224 	const struct bt_ctf_field_type_integer *type = container_of(field->type,
225 		const struct bt_ctf_field_type_integer, parent);
226 	ret = type->declaration.signedness;
227 end:
228 	return ret;
229 }
230 
_bt_python_get_field_type(const struct bt_ctf_field * field)231 enum ctf_type_id _bt_python_get_field_type(const struct bt_ctf_field *field)
232 {
233 	enum ctf_type_id type_id = CTF_TYPE_UNKNOWN;
234 
235 	if (!field) {
236 		goto end;
237 	}
238 
239 	type_id = field->type->declaration->id;
240 end:
241 	return type_id;
242 }
243 
244 /*
245  * Python 3.5 changes the StopIteration exception clearing behaviour which
246  * erroneously marks swig clean-up function as having failed. This explicit
247  * allocation function is intended as a work-around so SWIG doesn't manage
248  * the lifetime of a "temporary" object by itself.
249  */
_bt_python_create_iter_pos(void)250 struct bt_iter_pos *_bt_python_create_iter_pos(void)
251 {
252 	return g_new0(struct bt_iter_pos, 1);
253 }
254 
_bt_python_ctf_iter_create_intersect(struct bt_context * ctx,struct bt_iter_pos * inter_begin_pos,struct bt_iter_pos * inter_end_pos)255 struct bt_ctf_iter *_bt_python_ctf_iter_create_intersect(
256 		struct bt_context *ctx,
257 		struct bt_iter_pos *inter_begin_pos,
258 		struct bt_iter_pos *inter_end_pos)
259 {
260 	return bt_ctf_iter_create_intersect(ctx, &inter_begin_pos,
261 			&inter_end_pos);
262 }
263 
_bt_python_trace_collection_has_intersection(struct bt_context * ctx)264 int _bt_python_trace_collection_has_intersection(struct bt_context *ctx)
265 {
266 	int ret;
267 	uint64_t begin, end;
268 
269 	ret = ctf_find_tc_stream_packet_intersection_union(ctx, &begin, &end);
270 
271 	return ret == 0 ? 1 : 0;
272 }
273