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