Fix: Python bindings array access functions write out of bounds
[babeltrace.git] / bindings / python / babeltrace.i.in
1 /*
2 * babeltrace.i.in
3 *
4 * Babeltrace Python Module interface file
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
22 %define DOCSTRING
23 "BABELTRACE_VERSION_STR
24
25 Babeltrace is a trace viewer and converter reading and writing the
26 Common Trace Format (CTF). Its main use is to pretty-print CTF
27 traces into a human-readable text output.
28
29 To use this module, the first step is to create a Context and add a
30 trace to it."
31 %enddef
32
33 %module(docstring=DOCSTRING) babeltrace
34
35 %include "typemaps.i"
36 %{
37 #define SWIG_FILE_WITH_INIT
38 #include <babeltrace/babeltrace.h>
39 #include <babeltrace/babeltrace-internal.h>
40 #include <babeltrace/trace-handle.h>
41 #include <babeltrace/trace-handle-internal.h>
42 #include <babeltrace/context.h>
43 #include <babeltrace/context-internal.h>
44 #include <babeltrace/iterator.h>
45 #include <babeltrace/iterator-internal.h>
46 #include <babeltrace/format.h>
47 #include <babeltrace/list.h>
48 #include <babeltrace/types.h>
49 #include <babeltrace/ctf/iterator.h>
50 #include "python-complements.h"
51 %}
52
53 typedef unsigned long long uint64_t;
54 typedef long long int64_t;
55 typedef int bt_intern_str;
56
57 /* =================================================================
58 PYTHON-COMPLEMENTS.H
59 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
60 */
61
62 FILE *_bt_file_open(char *file_path, char *mode);
63 void _bt_file_close(FILE *fp);
64 struct bt_definition **_bt_python_field_listcaller(
65 const struct bt_ctf_event *ctf_event,
66 const struct bt_definition *scope,
67 unsigned int *OUTPUT);
68 struct bt_definition *_bt_python_field_one_from_list(
69 struct bt_definition **list, int index);
70 struct bt_ctf_event_decl **_bt_python_event_decl_listcaller(
71 int handle_id,
72 struct bt_context *ctx,
73 unsigned int *OUTPUT);
74 struct bt_ctf_event_decl *_bt_python_decl_one_from_list(
75 struct bt_ctf_event_decl **list, int index);
76 struct bt_ctf_field_decl **_by_python_field_decl_listcaller(
77 struct bt_ctf_event_decl *event_decl,
78 enum bt_ctf_scope scope,
79 unsigned int *OUTPUT);
80 struct bt_ctf_field_decl *_bt_python_field_decl_one_from_list(
81 struct bt_ctf_field_decl **list, int index);
82 struct definition_array *_bt_python_get_array_from_def(
83 struct bt_definition *field);
84 struct definition_sequence *_bt_python_get_sequence_from_def(
85 struct bt_definition *field);
86
87 /* =================================================================
88 CONTEXT.H, CONTEXT-INTERNAL.H
89 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
90 */
91
92 %rename("_bt_context_create") bt_context_create(void);
93 %rename("_bt_context_add_trace") bt_context_add_trace(
94 struct bt_context *ctx, const char *path, const char *format,
95 void (*packet_seek)(struct bt_stream_pos *pos, size_t index, int whence),
96 struct bt_mmap_stream_list *stream_list, FILE *metadata);
97 %rename("_bt_context_remove_trace") bt_context_remove_trace(
98 struct bt_context *ctx, int trace_id);
99 %rename("_bt_context_get") bt_context_get(struct bt_context *ctx);
100 %rename("_bt_context_put") bt_context_put(struct bt_context *ctx);
101 %rename("_bt_ctf_event_get_context") bt_ctf_event_get_context(
102 const struct bt_ctf_event *event);
103
104 struct bt_context *bt_context_create(void);
105 int bt_context_add_trace(struct bt_context *ctx, const char *path, const char *format,
106 void (*packet_seek)(struct bt_stream_pos *pos, size_t index, int whence),
107 struct bt_mmap_stream_list *stream_list, FILE *metadata);
108 void bt_context_remove_trace(struct bt_context *ctx, int trace_id);
109 void bt_context_get(struct bt_context *ctx);
110 void bt_context_put(struct bt_context *ctx);
111 struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *event);
112
113 // class Context to prevent direct access to struct bt_context
114 %pythoncode%{
115 class Context:
116 """
117 The context represents the object in which a trace_collection is
118 open. As long as this structure is allocated, the trace_collection
119 is open and the traces it contains can be read and seeked by the
120 iterators and callbacks.
121 """
122
123 def __init__(self):
124 self._c = _bt_context_create()
125
126 def __del__(self):
127 _bt_context_put(self._c)
128
129 def add_trace(self, path, format_str,
130 packet_seek=None, stream_list=None, metadata=None):
131 """
132 Add a trace by path to the context.
133
134 Open a trace.
135
136 path is the path to the trace, it is not recursive.
137 If "path" is None, stream_list is used instead as a list
138 of mmap streams to open for the trace.
139
140 format is a string containing the format name in which the trace was
141 produced.
142
143 packet_seek is not implemented for Python. Should be left None to
144 use the default packet_seek handler provided by the trace format.
145
146 stream_list is a linked list of streams, it is used to open a trace
147 where the trace data is located in memory mapped areas instead of
148 trace files, this argument should be None when path is not None.
149
150 The metadata parameter acts as a metadata override when not None,
151 otherwise the format handles the metadata opening.
152
153 Return: the corresponding TraceHandle on success or None on error.
154 """
155 if metadata is not None:
156 metadata = metadata._file
157
158 ret = _bt_context_add_trace(self._c, path, format_str, packet_seek,
159 stream_list, metadata)
160 if ret < 0:
161 return None
162
163 th = TraceHandle.__new__(TraceHandle)
164 th._id = ret
165 return th
166
167 def add_traces_recursive(self, path, format_str):
168 """
169 Open a trace recursively.
170
171 Find each trace present in the subdirectory starting from the given
172 path, and add them to the context.
173
174 Return a dict of TraceHandle instances (the full path is the key).
175 Return None on error.
176 """
177
178 import os
179
180 trace_handles = {}
181
182 noTrace = True
183 error = False
184
185 for fullpath, dirs, files in os.walk(path):
186 if "metadata" in files:
187 trace_handle = self.add_trace(fullpath, format_str)
188 if trace_handle is None:
189 error = True
190 continue
191
192 trace_handles[fullpath] = trace_handle
193 noTrace = False
194
195 if noTrace and error:
196 return None
197 return trace_handles
198
199 def remove_trace(self, trace_handle):
200 """
201 Remove a trace from the context.
202 Effectively closing the trace.
203 """
204 try:
205 _bt_context_remove_trace(self._c, trace_handle._id)
206 except AttributeError:
207 raise TypeError("in remove_trace, "
208 "argument 2 must be a TraceHandle instance")
209 %}
210
211
212
213 /* =================================================================
214 FORMAT.H, REGISTRY
215 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
216 */
217
218 %rename("lookup_format") bt_lookup_format(bt_intern_str qname);
219 %rename("_bt_print_format_list") bt_fprintf_format_list(FILE *fp);
220 %rename("register_format") bt_register_format(struct format *format);
221 %rename("unregister_format") bt_unregister_format(struct bt_format *format);
222
223 extern struct format *bt_lookup_format(bt_intern_str qname);
224 extern void bt_fprintf_format_list(FILE *fp);
225 extern int bt_register_format(struct bt_format *format);
226 extern void bt_unregister_format(struct bt_format *format);
227
228 %pythoncode %{
229
230 def print_format_list(babeltrace_file):
231 """
232 Print a list of available formats to file.
233
234 babeltrace_file must be a File instance opened in write mode.
235 """
236 try:
237 if babeltrace_file._file is not None:
238 _bt_print_format_list(babeltrace_file._file)
239 except AttributeError:
240 raise TypeError("in print_format_list, "
241 "argument 1 must be a File instance")
242
243 %}
244
245
246 /* =================================================================
247 ITERATOR.H, ITERATOR-INTERNAL.H
248 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
249 */
250
251 %rename("_bt_iter_create") bt_iter_create(struct bt_context *ctx,
252 const struct bt_iter_pos *begin_pos, const struct bt_iter_pos *end_pos);
253 %rename("_bt_iter_destroy") bt_iter_destroy(struct bt_iter *iter);
254 %rename("_bt_iter_next") bt_iter_next(struct bt_iter *iter);
255 %rename("_bt_iter_get_pos") bt_iter_get_pos(struct bt_iter *iter);
256 %rename("_bt_iter_free_pos") bt_iter_free_pos(struct bt_iter_pos *pos);
257 %rename("_bt_iter_set_pos") bt_iter_set_pos(struct bt_iter *iter,
258 const struct bt_iter_pos *pos);
259 %rename("_bt_iter_create_time_pos") bt_iter_create_time_pos(struct bt_iter *iter,
260 uint64_t timestamp);
261
262 struct bt_iter *bt_iter_create(struct bt_context *ctx,
263 const struct bt_iter_pos *begin_pos, const struct bt_iter_pos *end_pos);
264 void bt_iter_destroy(struct bt_iter *iter);
265 int bt_iter_next(struct bt_iter *iter);
266 struct bt_iter_pos *bt_iter_get_pos(struct bt_iter *iter);
267 void bt_iter_free_pos(struct bt_iter_pos *pos);
268 int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *pos);
269 struct bt_iter_pos *bt_iter_create_time_pos(struct bt_iter *iter, uint64_t timestamp);
270
271 %rename("_bt_iter_pos") bt_iter_pos;
272 %rename("SEEK_TIME") BT_SEEK_TIME;
273 %rename("SEEK_RESTORE") BT_SEEK_RESTORE;
274 %rename("SEEK_CUR") BT_SEEK_CUR;
275 %rename("SEEK_BEGIN") BT_SEEK_BEGIN;
276 %rename("SEEK_LAST") BT_SEEK_LAST;
277
278 // This struct is taken from iterator.h
279 // All changes to the struct must also be made here
280 struct bt_iter_pos {
281 enum {
282 BT_SEEK_TIME, /* uses u.seek_time */
283 BT_SEEK_RESTORE, /* uses u.restore */
284 BT_SEEK_CUR,
285 BT_SEEK_BEGIN,
286 BT_SEEK_LAST
287 } type;
288 union {
289 uint64_t seek_time;
290 struct bt_saved_pos *restore;
291 } u;
292 };
293
294
295 %pythoncode%{
296
297 class IterPos:
298 """This class represents the position where to set an iterator."""
299
300 __can_access = False
301
302 def __init__(self, seek_type, seek_time = None):
303 """
304 seek_type represents the type of seek to use.
305 seek_time is the timestamp to seek to when using SEEK_TIME, it
306 is expressed in nanoseconds
307 Only use SEEK_RESTORE on IterPos obtained from the get_pos function
308 in Iter class.
309 """
310
311 self._pos = _bt_iter_pos()
312 self._pos.type = seek_type
313 if seek_time and seek_type == SEEK_TIME:
314 self._pos.u.seek_time = seek_time
315 self.__can_access = True
316
317 def __del__(self):
318 if not self.__can_access:
319 _bt_iter_free_pos(self._pos)
320
321 def _get_type(self):
322 if not __can_access:
323 raise AttributeError("seek_type is not available")
324 return self._pos.type
325
326 def _set_type(self, seek_type):
327 if not __can_access:
328 raise AttributeError("seek_type is not available")
329 self._pos.type = seek_type
330
331 def _get_time(self):
332 if not __can_access:
333 raise AttributeError("seek_time is not available")
334
335 elif self._pos.type is not SEEK_TIME:
336 raise TypeError("seek_type is not SEEK_TIME")
337
338 return self._pos.u.seek_time
339
340 def _set_time(self, time):
341 if not __can_access:
342 raise AttributeError("seek_time is not available")
343
344 elif self._pos.type is not SEEK_TIME:
345 raise TypeError("seek_type is not SEEK_TIME")
346
347 self._pos.u.seek_time = time
348
349 def _get_pos(self):
350 return self._pos
351
352
353 seek_type = property(_get_type, _set_type)
354 seek_time = property(_get_time, _set_time)
355
356
357 class Iterator:
358
359 __with_init = False
360
361 def __init__(self, context, begin_pos = None, end_pos = None, _no_init = None):
362 """
363 Allocate a trace collection iterator.
364
365 begin_pos and end_pos are optional parameters to specify the
366 position at which the trace collection should be seeked upon
367 iterator creation, and the position at which iteration will
368 start returning "EOF".
369
370 By default, if begin_pos is None, a BT_SEEK_CUR is performed at
371 creation. By default, if end_pos is None, a BT_SEEK_END (end of
372 trace) is the EOF criterion.
373 """
374 if _no_init is None:
375 if begin_pos is None:
376 bp = None
377 else:
378 try:
379 bp = begin_pos._pos
380 except AttributeError:
381 raise TypeError("in __init__, "
382 "argument 3 must be a IterPos instance")
383
384 if end_pos is None:
385 ep = None
386 else:
387 try:
388 ep = end_pos._pos
389 except AttributeError:
390 raise TypeError("in __init__, "
391 "argument 4 must be a IterPos instance")
392
393 try:
394 self._bi = _bt_iter_create(context._c, bp, ep)
395 except AttributeError:
396 raise TypeError("in __init__, "
397 "argument 2 must be a Context instance")
398
399 self.__with_init = True
400
401 else:
402 self._bi = _no_init
403
404 def __del__(self):
405 if self.__with_init:
406 _bt_iter_destroy(self._bi)
407
408 def next(self):
409 """
410 Move trace collection position to the next event.
411 Returns 0 on success, a negative value on error.
412 """
413 return _bt_iter_next(self._bi)
414
415 def get_pos(self):
416 """Return a IterPos class of the current iterator position."""
417 ret = IterPos(0)
418 ret.__can_access = False
419 ret._pos = _bt_iter_get_pos(self._bi)
420 return ret
421
422 def set_pos(self, pos):
423 """
424 Move the iterator to a given position.
425
426 On error, the stream_heap is reinitialized and returned empty.
427 Return 0 for success.
428 Return EOF if the position requested is after the last event of the
429 trace collection.
430 Return -EINVAL when called with invalid parameter.
431 Return -ENOMEM if the stream_heap could not be properly initialized.
432 """
433 try:
434 return _bt_iter_set_pos(self._bi, pos._pos)
435 except AttributeError:
436 raise TypeError("in set_pos, "
437 "argument 2 must be a IterPos instance")
438
439 def create_time_pos(self, timestamp):
440 """
441 Create a position based on time
442 This function allocates and returns a new IterPos to be able to
443 restore an iterator position based on a timestamp.
444 """
445
446 if timestamp < 0:
447 raise TypeError("timestamp must be an unsigned int")
448
449 ret = IterPos(0)
450 ret.__can_access = False
451 ret._pos = _bt_iter_create_time_pos(self._bi, timestamp)
452 return ret
453 %}
454
455
456 /* =================================================================
457 CLOCK-TYPE.H
458 ¯¯¯¯¯¯¯¯¯¯¯¯
459 *** Enum copied from clock-type.h­
460 All changes must also be made here
461 */
462 %rename("CLOCK_CYCLES") BT_CLOCK_CYCLES;
463 %rename("CLOCK_REAL") BT_CLOCK_REAL;
464
465 enum bt_clock_type {
466 BT_CLOCK_CYCLES = 0,
467 BT_CLOCK_REAL
468 };
469
470 /* =================================================================
471 TRACE-HANDLE.H, TRACE-HANDLE-INTERNAL.H
472 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
473 */
474
475 %rename("_bt_trace_handle_create") bt_trace_handle_create(struct bt_context *ctx);
476 %rename("_bt_trace_handle_destroy") bt_trace_handle_destroy(struct bt_trace_handle *bt);
477 struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx);
478 void bt_trace_handle_destroy(struct bt_trace_handle *bt);
479
480 %rename("_bt_trace_handle_get_path") bt_trace_handle_get_path(struct bt_context *ctx,
481 int handle_id);
482 %rename("_bt_trace_handle_get_timestamp_begin") bt_trace_handle_get_timestamp_begin(
483 struct bt_context *ctx, int handle_id, enum bt_clock_type type);
484 %rename("_bt_trace_handle_get_timestamp_end") bt_trace_handle_get_timestamp_end(
485 struct bt_context *ctx, int handle_id, enum bt_clock_type type);
486 const char *bt_trace_handle_get_path(struct bt_context *ctx, int handle_id);
487 uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx, int handle_id,
488 enum bt_clock_type type);
489 uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx, int handle_id,
490 enum bt_clock_type type);
491
492 %rename("_bt_ctf_event_get_handle_id") bt_ctf_event_get_handle_id(
493 const struct bt_ctf_event *event);
494 int bt_ctf_event_get_handle_id(const struct bt_ctf_event *event);
495
496
497 %pythoncode%{
498
499 class TraceHandle(object):
500 """
501 The TraceHandle allows the user to manipulate a trace file directly.
502 It is a unique identifier representing a trace file.
503 Do not instantiate.
504 """
505
506 def __init__(self):
507 raise NotImplementedError("TraceHandle cannot be instantiated")
508
509 def __repr__(self):
510 return "Babeltrace TraceHandle: trace_id('{0}')".format(self._id)
511
512 def get_id(self):
513 """Return the TraceHandle id."""
514 return self._id
515
516 def get_path(self, context):
517 """Return the path of a TraceHandle."""
518 try:
519 return _bt_trace_handle_get_path(context._c, self._id)
520 except AttributeError:
521 raise TypeError("in get_path, "
522 "argument 2 must be a Context instance")
523
524 def get_timestamp_begin(self, context, clock_type):
525 """Return the creation time of the buffers of a trace."""
526 try:
527 return _bt_trace_handle_get_timestamp_begin(
528 context._c, self._id,clock_type)
529 except AttributeError:
530 raise TypeError("in get_timestamp_begin, "
531 "argument 2 must be a Context instance")
532
533 def get_timestamp_end(self, context, clock_type):
534 """Return the destruction timestamp of the buffers of a trace."""
535 try:
536 return _bt_trace_handle_get_timestamp_end(
537 context._c, self._id, clock_type)
538 except AttributeError:
539 raise TypeError("in get_timestamp_end, "
540 "argument 2 must be a Context instance")
541
542 %}
543
544
545
546 // =================================================================
547 // CTF
548 // =================================================================
549
550 /* =================================================================
551 ITERATOR.H, EVENTS.H
552 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
553 */
554
555 //Iterator
556 %rename("_bt_ctf_iter_create") bt_ctf_iter_create(struct bt_context *ctx,
557 const struct bt_iter_pos *begin_pos,
558 const struct bt_iter_pos *end_pos);
559 %rename("_bt_ctf_get_iter") bt_ctf_get_iter(struct bt_ctf_iter *iter);
560 %rename("_bt_ctf_iter_destroy") bt_ctf_iter_destroy(struct bt_ctf_iter *iter);
561 %rename("_bt_ctf_iter_read_event") bt_ctf_iter_read_event(struct bt_ctf_iter *iter);
562
563 struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx,
564 const struct bt_iter_pos *begin_pos,
565 const struct bt_iter_pos *end_pos);
566 struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter);
567 void bt_ctf_iter_destroy(struct bt_ctf_iter *iter);
568 struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter);
569
570
571 //Events
572
573 %rename("_bt_ctf_get_top_level_scope") bt_ctf_get_top_level_scope(const struct
574 bt_ctf_event *event, enum bt_ctf_scope scope);
575 %rename("_bt_ctf_event_name") bt_ctf_event_name(const struct bt_ctf_event *ctf_event);
576 %rename("_bt_ctf_get_timestamp") bt_ctf_get_timestamp(
577 const struct bt_ctf_event *ctf_event);
578 %rename("_bt_ctf_get_cycles") bt_ctf_get_cycles(
579 const struct bt_ctf_event *ctf_event);
580
581 %rename("_bt_ctf_get_field") bt_ctf_get_field(const struct bt_ctf_event *ctf_event,
582 const struct bt_definition *scope, const char *field);
583 %rename("_bt_ctf_get_index") bt_ctf_get_index(const struct bt_ctf_event *ctf_event,
584 const struct bt_definition *field, unsigned int index);
585 %rename("_bt_ctf_field_name") bt_ctf_field_name(const struct bt_definition *field);
586 %rename("_bt_ctf_field_type") bt_ctf_field_type(const struct bt_declaration *field);
587 %rename("_bt_ctf_get_int_signedness") bt_ctf_get_int_signedness(
588 const struct bt_declaration *field);
589 %rename("_bt_ctf_get_int_base") bt_ctf_get_int_base(const struct bt_declaration *field);
590 %rename("_bt_ctf_get_int_byte_order") bt_ctf_get_int_byte_order(
591 const struct bt_declaration *field);
592 %rename("_bt_ctf_get_int_len") bt_ctf_get_int_len(const struct bt_declaration *field);
593 %rename("_bt_ctf_get_enum_int") bt_ctf_get_enum_int(const struct bt_definition *field);
594 %rename("_bt_ctf_get_enum_str") bt_ctf_get_enum_str(const struct bt_definition *field);
595 %rename("_bt_ctf_get_encoding") bt_ctf_get_encoding(const struct bt_declaration *field);
596 %rename("_bt_ctf_get_array_len") bt_ctf_get_array_len(const struct bt_declaration *field);
597 %rename("_bt_ctf_get_uint64") bt_ctf_get_uint64(const struct bt_definition *field);
598 %rename("_bt_ctf_get_int64") bt_ctf_get_int64(const struct bt_definition *field);
599 %rename("_bt_ctf_get_char_array") bt_ctf_get_char_array(const struct bt_definition *field);
600 %rename("_bt_ctf_get_string") bt_ctf_get_string(const struct bt_definition *field);
601 %rename("_bt_ctf_get_float") bt_ctf_get_float(const struct bt_definition *field);
602 %rename("_bt_ctf_get_variant") bt_ctf_get_variant(const struct bt_definition *field);
603 %rename("_bt_ctf_field_get_error") bt_ctf_field_get_error(void);
604 %rename("_bt_ctf_get_decl_event_name") bt_ctf_get_decl_event_name(const struct
605 bt_ctf_event_decl *event);
606 %rename("_bt_ctf_get_decl_field_name") bt_ctf_get_decl_field_name(
607 const struct bt_ctf_field_decl *field);
608 %rename("_bt_ctf_get_decl_from_def") bt_ctf_get_decl_from_def(
609 const struct bt_definition *field);
610 %rename("_bt_array_index") bt_array_index(struct definition_array *array, uint64_t i);
611 %rename("_bt_sequence_len") bt_sequence_len(struct definition_sequence *sequence);
612 %rename("_bt_sequence_index") bt_sequence_index(struct definition_sequence *sequence, uint64_t i);
613 %rename("_bt_ctf_get_struct_field_count") bt_ctf_get_struct_field_count(const struct bt_definition *structure);
614 %rename("_bt_ctf_get_struct_field_index") bt_ctf_get_struct_field_index(const struct bt_definition *structure, uint64_t i);
615
616 const struct bt_definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event,
617 enum bt_ctf_scope scope);
618 const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event);
619 uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event);
620 uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event);
621 const struct bt_definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event,
622 const struct bt_definition *scope,
623 const char *field);
624 const struct bt_definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event,
625 const struct bt_definition *field,
626 unsigned int index);
627 const char *bt_ctf_field_name(const struct bt_definition *field);
628 enum ctf_type_id bt_ctf_field_type(const struct bt_declaration *field);
629 int bt_ctf_get_int_signedness(const struct bt_declaration *field);
630 int bt_ctf_get_int_base(const struct bt_declaration *field);
631 int bt_ctf_get_int_byte_order(const struct bt_declaration *field);
632 ssize_t bt_ctf_get_int_len(const struct bt_declaration *field);
633 const struct bt_definition *bt_ctf_get_enum_int(const struct bt_definition *field);
634 const char *bt_ctf_get_enum_str(const struct bt_definition *field);
635 enum ctf_string_encoding bt_ctf_get_encoding(const struct bt_declaration *field);
636 int bt_ctf_get_array_len(const struct bt_declaration *field);
637 struct bt_definition *bt_array_index(struct definition_array *array, uint64_t i);
638 uint64_t bt_ctf_get_uint64(const struct bt_definition *field);
639 int64_t bt_ctf_get_int64(const struct bt_definition *field);
640 char *bt_ctf_get_char_array(const struct bt_definition *field);
641 char *bt_ctf_get_string(const struct bt_definition *field);
642 double bt_ctf_get_float(const struct bt_definition *field);
643 const struct bt_definition *bt_ctf_get_variant(const struct bt_definition *field);
644 int bt_ctf_field_get_error(void);
645 const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event);
646 const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field);
647 const struct bt_declaration *bt_ctf_get_decl_from_def(const struct bt_definition *field);
648 uint64_t bt_sequence_len(struct definition_sequence *sequence);
649 struct bt_definition *bt_sequence_index(struct definition_sequence *sequence, uint64_t i);
650 uint64_t bt_ctf_get_struct_field_count(const struct bt_definition *structure);
651 const struct bt_definition *bt_ctf_get_struct_field_index(const struct bt_definition *structure, uint64_t i);
652
653 %pythoncode%{
654
655 class ctf:
656
657 #enum equivalent, accessible constants
658 #These are taken directly from ctf/events.h
659 #All changes to enums must also be made here
660 class type_id:
661 UNKNOWN = 0
662 INTEGER = 1
663 FLOAT = 2
664 ENUM = 3
665 STRING = 4
666 STRUCT = 5
667 UNTAGGED_VARIANT = 6
668 VARIANT = 7
669 ARRAY = 8
670 SEQUENCE = 9
671 NR_CTF_TYPES = 10
672
673 def get_type_id_name(id):
674 name = "UNKNOWN"
675 constants = [attr for attr in dir(ctf.type_id) if not callable(getattr(ctf.type_id, attr)) and not attr.startswith("__")]
676 for attr in constants:
677 if getattr(ctf.type_id, attr) == id:
678 name = attr
679 break
680 return name
681
682 class scope:
683 TRACE_PACKET_HEADER = 0
684 STREAM_PACKET_CONTEXT = 1
685 STREAM_EVENT_HEADER = 2
686 STREAM_EVENT_CONTEXT = 3
687 EVENT_CONTEXT = 4
688 EVENT_FIELDS = 5
689
690 class string_encoding:
691 NONE = 0
692 UTF8 = 1
693 ASCII = 2
694 UNKNOWN = 3
695
696 class Iterator(Iterator, object):
697 """
698 Allocate a CTF trace collection iterator.
699
700 begin_pos and end_pos are optional parameters to specify the
701 position at which the trace collection should be seeked upon
702 iterator creation, and the position at which iteration will
703 start returning "EOF".
704
705 By default, if begin_pos is None, a SEEK_CUR is performed at
706 creation. By default, if end_pos is None, a SEEK_END (end of
707 trace) is the EOF criterion.
708
709 Only one iterator can be created against a context. If more than one
710 iterator is being created for the same context, the second creation
711 will return None. The previous iterator must be destroyed before
712 creation of the new iterator for this function to succeed.
713 """
714
715 def __new__(cls, context, begin_pos = None, end_pos = None):
716 # __new__ is used to control the return value
717 # as the ctf.Iterator class should return None
718 # if bt_ctf_iter_create returns NULL
719
720 if begin_pos is None:
721 bp = None
722 else:
723 bp = begin_pos._pos
724 if end_pos is None:
725 ep = None
726 else:
727 ep = end_pos._pos
728 try:
729 it = _bt_ctf_iter_create(context._c, bp, ep)
730 except AttributeError:
731 raise TypeError("in __init__, "
732 "argument 2 must be a Context instance")
733 if it is None:
734 return None
735
736 ret_class = super(ctf.Iterator, cls).__new__(cls)
737 ret_class._i = it
738 return ret_class
739
740 def __init__(self, context, begin_pos = None, end_pos = None):
741 Iterator.__init__(self, None, None, None,
742 _bt_ctf_get_iter(self._i))
743
744 def __del__(self):
745 _bt_ctf_iter_destroy(self._i)
746
747 def read_event(self):
748 """
749 Read the iterator's current event data.
750 Return current event on success, None on end of trace.
751 """
752 ret = _bt_ctf_iter_read_event(self._i)
753 if ret is None:
754 return ret
755 ev = ctf.Event.__new__(ctf.Event)
756 ev._e = ret
757 return ev
758
759
760 class Event(object):
761 """
762 This class represents an event from the trace.
763 It is obtained with read_event() from ctf.Iterator.
764 Do not instantiate.
765 """
766
767 def __init__(self):
768 raise NotImplementedError("ctf.Event cannot be instantiated")
769
770 def get_top_level_scope(self, scope):
771 """
772 Return a definition of the top-level scope
773 Top-level scopes are defined in ctf.scope.
774 In order to get a field or a field list, the user needs to pass a
775 scope as argument, this scope can be a top-level scope or a scope
776 relative to an arbitrary field. This function provides the mapping
777 between the scope and the actual definition of top-level scopes.
778 On error return None.
779 """
780 evDef = ctf.Definition.__new__(ctf.Definition)
781 evDef._d = _bt_ctf_get_top_level_scope(self._e, scope)
782 if evDef._d is None:
783 return None
784 return evDef
785
786 def get_name(self):
787 """Return the name of the event or None on error."""
788 return _bt_ctf_event_name(self._e)
789
790 def get_cycles(self):
791 """
792 Return the timestamp of the event as written in
793 the packet (in cycles) or -1ULL on error.
794 """
795 return _bt_ctf_get_cycles(self._e)
796
797 def get_timestamp(self):
798 """
799 Return the timestamp of the event offsetted with the
800 system clock source or -1ULL on error.
801 """
802 return _bt_ctf_get_timestamp(self._e)
803
804 def get_field_with_scope(self, scope, field):
805 """
806 Return the definition of a specific field.
807 Return None on error.
808 """
809 evDef = ctf.Definition.__new__(ctf.Definition)
810 try:
811 evDef._d = _bt_ctf_get_field(self._e, scope._d, field)
812 except AttributeError:
813 raise TypeError("in get_field, argument 2 must be a "
814 "Definition (scope) instance")
815 if evDef._d is None:
816 return None
817 evDef._s = scope
818 return evDef
819
820 def get_field(self, field):
821 """
822 Return the definition of fields by a name
823 Return None on error
824 """
825 eventScope = self.get_top_level_scope(ctf.scope.EVENT_FIELDS)
826 streamScope = self.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT)
827 fields_by_name = []
828
829 if eventScope is not None:
830 evDef = self.get_field_with_scope(eventScope, field)
831 if evDef is not None:
832 fields_by_name.append(evDef)
833
834 if streamScope is not None:
835 evDef = self.get_field_with_scope(streamScope, field)
836 if evDef is not None:
837 fields_by_name.append(evDef);
838
839 if not fields_by_name:
840 return None
841 return fields_by_name
842
843 def get_field_list_with_scope(self, scope):
844 """
845 Return a list of Definitions associated with the scope
846 Return None on error.
847 """
848 try:
849 field_lc, count = _bt_python_field_listcaller(self._e, scope._d)
850 except AttributeError:
851 raise TypeError("in get_field_list, argument 2 must be a "
852 "Definition (scope) instance")
853
854 if field_lc is None:
855 return None
856
857 def_list = []
858 for i in range(count):
859 tmp = ctf.Definition.__new__(ctf.Definition)
860 tmp._d = _bt_python_field_one_from_list(field_lc, i)
861 tmp._s = scope
862 def_list.append(tmp)
863
864 return def_list
865
866 def get_field_list(self):
867 """Return a list of Definitions or None on error."""
868 eventScope = self.get_top_level_scope(ctf.scope.EVENT_FIELDS)
869 streamScope = self.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT)
870
871 def_list = []
872 if eventScope is not None:
873 event_field_list = self.get_field_list_with_scope(eventScope)
874 if event_field_list is not None:
875 def_list = event_field_list
876
877 if streamScope is not None:
878 event_field_list = self.get_field_list_with_scope(streamScope)
879 if event_field_list is not None:
880 def_list.extend(event_field_list)
881
882 if not def_list:
883 return None
884 return def_list
885
886 def get_index(self, field, index):
887 """
888 If the field is an array or a sequence, return the element
889 at position index, otherwise return None
890 """
891 evDef = ctf.Definition.__new__(ctf.Definition)
892 try:
893 evDef._d = _bt_ctf_get_index(self._e, field._d, index)
894 except AttributeError:
895 raise TypeError("in get_index, argument 2 must be a "
896 "Definition (field) instance")
897
898 if evDef._d is None:
899 return None
900 return evDef
901
902 def get_handle(self):
903 """
904 Get the TraceHandle associated with an event
905 Return None on error
906 """
907 ret = _bt_ctf_event_get_handle_id(self._e)
908 if ret < 0:
909 return None
910
911 th = TraceHandle.__new__(TraceHandle)
912 th._id = ret
913 return th
914
915 def get_context(self):
916 """
917 Get the context associated with an event.
918 Return None on error.
919 """
920 ctx = Context()
921 ctx._c = _bt_ctf_event_get_context(self._e);
922 if ctx._c is None:
923 return None
924 else:
925 return ctx
926
927 class FieldError(Exception):
928 def __init__(self, value):
929 self.value = value
930
931 def __str__(self):
932 return repr(self.value)
933
934 class Definition(object):
935 """Definition class. Do not instantiate."""
936
937 def __init__(self):
938 raise NotImplementedError("ctf.Definition cannot be instantiated")
939
940 def __repr__(self):
941 return "Babeltrace Definition: name('{0}'), type({1})".format(
942 self.field_name(), self.field_type())
943
944 def field_name(self):
945 """Return the name of a field or None on error."""
946 return _bt_ctf_field_name(self._d)
947
948 def field_type(self):
949 """Return the type of a field or -1 if unknown."""
950 return _bt_ctf_field_type(_bt_ctf_get_decl_from_def(self._d))
951
952 def get_int_signedness(self):
953 """
954 Return the signedness of an integer:
955 0 if unsigned; 1 if signed; -1 on error.
956 """
957 return _bt_ctf_get_int_signedness(_bt_ctf_get_decl_from_def(self._d))
958
959 def get_int_base(self):
960 """Return the base of an int or a negative value on error."""
961 return _bt_ctf_get_int_base(_bt_ctf_get_decl_from_def(self._d))
962
963 def get_int_byte_order(self):
964 """
965 Return the byte order of an int or a negative
966 value on error.
967 """
968 return _bt_ctf_get_int_byte_order(_bt_ctf_get_decl_from_def(self._d))
969
970 def get_int_len(self):
971 """
972 Return the size, in bits, of an int or a negative
973 value on error.
974 """
975 return _bt_ctf_get_int_len(_bt_ctf_get_decl_from_def(self._d))
976
977 def get_enum_str(self):
978 """
979 Return the string matching the current enumeration.
980 Return None on error.
981 """
982 return _bt_ctf_get_enum_str(self._d)
983
984 def get_encoding(self):
985 """
986 Return the encoding of an int or a string.
987 Return a negative value on error.
988 """
989 return _bt_ctf_get_encoding(_bt_ctf_get_decl_from_def(self._d))
990
991 def get_array_len(self):
992 """
993 Return the len of an array or a negative
994 value on error.
995 """
996 return _bt_ctf_get_array_len(_bt_ctf_get_decl_from_def(self._d))
997
998 def get_array_element_at(self, index):
999 """
1000 Return the array's element at position index.
1001 Return None on error
1002 """
1003 array = _bt_python_get_array_from_def(self._d)
1004 if array is None:
1005 return None
1006
1007 element = ctf.Definition.__new__(ctf.Definition)
1008 element._d = _bt_array_index(array, index)
1009 if element._d is None:
1010 return None
1011 return element
1012
1013 def get_sequence_len(self):
1014 """
1015 Return the len of a sequence or a negative
1016 value on error.
1017 """
1018 seq = _bt_python_get_sequence_from_def(self._d)
1019 return _bt_sequence_len(seq)
1020
1021 def get_sequence_element_at(self, index):
1022 """
1023 Return the sequence's element at position index,
1024 otherwise return None
1025 """
1026 seq = _bt_python_get_sequence_from_def(self._d)
1027 if seq is not None:
1028 element = ctf.Definition.__new__(ctf.Definition)
1029 element._d = _bt_sequence_index(seq, index)
1030 if element._d is not None:
1031 return element
1032 return None
1033
1034 def get_uint64(self):
1035 """
1036 Return the value associated with the field.
1037 If the field does not exist or is not of the type requested,
1038 the value returned is undefined. To check if an error occured,
1039 use the ctf.field_error() function after accessing a field.
1040 """
1041 return _bt_ctf_get_uint64(self._d)
1042
1043 def get_int64(self):
1044 """
1045 Return the value associated with the field.
1046 If the field does not exist or is not of the type requested,
1047 the value returned is undefined. To check if an error occured,
1048 use the ctf.field_error() function after accessing a field.
1049 """
1050 return _bt_ctf_get_int64(self._d)
1051
1052 def get_char_array(self):
1053 """
1054 Return the value associated with the field.
1055 If the field does not exist or is not of the type requested,
1056 the value returned is undefined. To check if an error occured,
1057 use the ctf.field_error() function after accessing a field.
1058 """
1059 return _bt_ctf_get_char_array(self._d)
1060
1061 def get_str(self):
1062 """
1063 Return the value associated with the field.
1064 If the field does not exist or is not of the type requested,
1065 the value returned is undefined. To check if an error occured,
1066 use the ctf.field_error() function after accessing a field.
1067 """
1068 return _bt_ctf_get_string(self._d)
1069
1070 def get_float(self):
1071 """
1072 Return the value associated with the field.
1073 If the field does not exist or is not of the type requested,
1074 the value returned is undefined. To check if an error occured,
1075 use the ctf.field_error() function after accessing a field.
1076 """
1077 return _bt_ctf_get_float(self._d)
1078
1079 def get_variant(self):
1080 """
1081 Return the variant's selected field.
1082 If the field does not exist or is not of the type requested,
1083 the value returned is undefined. To check if an error occured,
1084 use the ctf.field_error() function after accessing a field.
1085 """
1086 return _bt_ctf_get_variant(self._d)
1087
1088 def get_struct_field_count(self):
1089 """
1090 Return the number of fields contained in the structure.
1091 If the field does not exist or is not of the type requested,
1092 the value returned is undefined.
1093 """
1094 return _bt_ctf_get_struct_field_count(self._d)
1095
1096 def get_struct_field_at(self, i):
1097 """
1098 Return the structure's field at position i.
1099 If the field does not exist or is not of the type requested,
1100 the value returned is undefined. To check if an error occured,
1101 use the ctf.field_error() function after accessing a field.
1102 """
1103 return _bt_ctf_get_struct_field_index(self._d, i)
1104
1105 def get_value(self):
1106 """
1107 Return the value associated with the field according to its type.
1108 Return None on error.
1109 """
1110 id = self.field_type()
1111 value = None
1112 if id == ctf.type_id.STRING:
1113 value = self.get_str()
1114 elif id == ctf.type_id.ARRAY:
1115 value = []
1116 for i in range(self.get_array_len()):
1117 element = self.get_array_element_at(i)
1118 value.append(element.get_value())
1119 elif id == ctf.type_id.INTEGER:
1120 if self.get_int_signedness() == 0:
1121 value = self.get_uint64()
1122 else:
1123 value = self.get_int64()
1124 elif id == ctf.type_id.ENUM:
1125 value = self.get_enum_str()
1126 elif id == ctf.type_id.SEQUENCE:
1127 seq_len = self.get_sequence_len()
1128 value = []
1129 for i in range(seq_len):
1130 evDef = self.get_sequence_element_at(i)
1131 value.append(evDef.get_value())
1132 elif id == ctf.type_id.FLOAT:
1133 value = self.get_float()
1134 elif id == ctf.type_id.VARIANT:
1135 variant = ctf.Definition.__new__(ctf.Definition)
1136 variant._d = self.get_variant();
1137 value = variant.get_value()
1138 elif id == ctf.type_id.STRUCT:
1139 value = {}
1140 for i in range(self.get_struct_field_count()):
1141 member = ctf.Definition.__new__(ctf.Definition)
1142 member._d = self.get_struct_field_at(i);
1143 value[member.field_name()] = member.get_value()
1144
1145 if ctf.field_error():
1146 raise ctf.FieldError("Error occured while accessing field {} of type {}".format(self.field_name(), ctf.type_id.get_type_id_name(self.field_type())))
1147 return value
1148
1149 def get_scope(self):
1150 """Return the scope of a field or None on error."""
1151 return self._s
1152
1153 class EventDecl(object):
1154 """Event declaration class. Do not instantiate."""
1155
1156 def __init__(self):
1157 raise NotImplementedError("ctf.EventDecl cannot be instantiated")
1158
1159 def __repr__(self):
1160 return "Babeltrace EventDecl: name {0}".format(self.get_name())
1161
1162 def get_name(self):
1163 """Return the name of the event or None on error"""
1164 return _bt_ctf_get_decl_event_name(self._d)
1165
1166 def get_decl_fields(self, scope):
1167 """
1168 Return a list of ctf.FieldDecl
1169 Return None on error.
1170 """
1171 ptr_list = _by_python_field_decl_listcaller(self._d, scope)
1172
1173 if ptr_list is None:
1174 return None
1175
1176 decl_list = []
1177 i = 0
1178 while True:
1179 tmp = ctf.FieldDecl.__new__(ctf.FieldDecl)
1180 tmp._d = _bt_python_field_decl_one_from_list(
1181 ptr_list, i)
1182
1183 if tmp._d is None:
1184 #Last item of list is None
1185 break
1186
1187 decl_list.append(tmp)
1188 i += 1
1189 return decl_list
1190
1191
1192 class FieldDecl(object):
1193 """Field declaration class. Do not instantiate."""
1194
1195 def __init__(self):
1196 raise NotImplementedError("ctf.FieldDecl cannot be instantiated")
1197
1198 def __repr__(self):
1199 return "Babeltrace FieldDecl: name {0}".format(self.get_name())
1200
1201 def get_name(self):
1202 """Return the name of a FieldDecl or None on error"""
1203 return _bt_ctf_get_decl_field_name(self._d)
1204
1205
1206 @staticmethod
1207 def field_error():
1208 """
1209 Return the last error code encountered while
1210 accessing a field and reset the error flag.
1211 Return 0 if no error, a negative value otherwise.
1212 """
1213 return _bt_ctf_field_get_error()
1214
1215 @staticmethod
1216 def get_event_decl_list(trace_handle, context):
1217 """
1218 Return a list of ctf.EventDecl
1219 Return None on error.
1220 """
1221 try:
1222 handle_id = trace_handle._id
1223 except AttributeError:
1224 raise TypeError("in get_event_decl_list, "
1225 "argument 1 must be a TraceHandle instance")
1226 try:
1227 ptr_list, count = _bt_python_event_decl_listcaller(handle_id, context._c)
1228 except AttributeError:
1229 raise TypeError("in get_event_decl_list, "
1230 "argument 2 must be a Context instance")
1231
1232 if ptr_list is None:
1233 return None
1234
1235 decl_list = []
1236 for i in range(count):
1237 tmp = ctf.EventDecl.__new__(ctf.EventDecl)
1238 tmp._d = _bt_python_decl_one_from_list(ptr_list, i)
1239 decl_list.append(tmp)
1240
1241 return decl_list
1242
1243 %}
1244
1245
1246
1247 // =================================================================
1248 // NEW FUNCTIONS
1249 // File and list-related
1250 // python-complements.h
1251 // =================================================================
1252
1253 %pythoncode %{
1254
1255 class File(object):
1256 """
1257 Open a file for babeltrace.
1258
1259 file_path is a string containing the path or None to use the
1260 standard output in writing mode.
1261
1262 The mode can be 'r', 'w' or 'a' for reading (default), writing or
1263 appending. The file will be created if it doesn't exist when
1264 opened for writing or appending; it will be truncated when opened
1265 for writing. Add a 'b' to the mode for binary files. Add a '+'
1266 to the mode to allow simultaneous reading and writing.
1267 """
1268
1269 def __new__(cls, file_path, mode='r'):
1270 # __new__ is used to control the return value
1271 # as the File class should return None
1272 # if _bt_file_open returns NULL
1273
1274 # Type check
1275 if file_path is not None and type(file_path) is not str:
1276 raise TypeError("in method __init__, argument 2 of type 'str'")
1277 if type(mode) is not str:
1278 raise TypeError("in method __init__, argument 3 of type 'str'")
1279
1280 # Opening file
1281 file_ptr = _bt_file_open(file_path, mode)
1282 if file_ptr is None:
1283 return None
1284
1285 # Class instantiation
1286 file_inst = super(File, cls).__new__(cls)
1287 file_inst._file = file_ptr
1288 return file_inst
1289
1290 def __init__(self, file_path, mode='r'):
1291 self._opened = True
1292 self._use_stdout = False
1293
1294 if file_path is None:
1295 # use stdout
1296 file_path = "stdout"
1297 mode = 'w'
1298 self._use_stdout = True
1299
1300 self._file_path = file_path
1301 self._mode = mode
1302
1303 def __del__(self):
1304 self.close()
1305
1306 def __repr__(self):
1307 if self._opened:
1308 stat = 'opened'
1309 else:
1310 stat = 'closed'
1311 return "{0} babeltrace File; file_path('{1}'), mode('{2}')".format(
1312 stat, self._file_path, self._mode)
1313
1314 def close(self):
1315 """Close the file. Is also called using del."""
1316 if self._opened and not self._use_stdout:
1317 _bt_file_close(self._file)
1318 self._opened = False
1319 %}
This page took 0.086062 seconds and 4 git commands to generate.