1 #ifndef BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H
2 #define BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H
5 * Copyright 2018-2019 - Philippe Proulx <pproulx@efficios.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
18 #include <babeltrace2/babeltrace.h>
19 #include "common/common.h"
20 #include "common/assert.h"
21 #include "compat/uuid.h"
28 enum fs_sink_ctf_field_class_type
{
29 FS_SINK_CTF_FIELD_CLASS_TYPE_INT
,
30 FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT
,
31 FS_SINK_CTF_FIELD_CLASS_TYPE_STRING
,
32 FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT
,
33 FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY
,
34 FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE
,
35 FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT
,
38 struct fs_sink_ctf_field_class
{
39 enum fs_sink_ctf_field_class_type type
;
42 const bt_field_class
*ir_fc
;
44 unsigned int alignment
;
46 /* Index of the field class within its own parent */
47 uint64_t index_in_parent
;
50 struct fs_sink_ctf_field_class_bit_array
{
51 struct fs_sink_ctf_field_class base
;
55 struct fs_sink_ctf_field_class_int
{
56 struct fs_sink_ctf_field_class_bit_array base
;
60 struct fs_sink_ctf_field_class_float
{
61 struct fs_sink_ctf_field_class_bit_array base
;
64 struct fs_sink_ctf_field_class_string
{
65 struct fs_sink_ctf_field_class base
;
68 struct fs_sink_ctf_named_field_class
{
72 struct fs_sink_ctf_field_class
*fc
;
75 struct fs_sink_ctf_field_class_struct
{
76 struct fs_sink_ctf_field_class base
;
78 /* Array of `struct fs_sink_ctf_named_field_class` */
82 struct fs_sink_ctf_field_class_variant
{
83 struct fs_sink_ctf_field_class base
;
87 /* Array of `struct fs_sink_ctf_named_field_class` */
91 struct fs_sink_ctf_field_class_array_base
{
92 struct fs_sink_ctf_field_class base
;
93 struct fs_sink_ctf_field_class
*elem_fc
;
96 struct fs_sink_ctf_field_class_array
{
97 struct fs_sink_ctf_field_class_array_base base
;
101 struct fs_sink_ctf_field_class_sequence
{
102 struct fs_sink_ctf_field_class_array_base base
;
104 bool length_is_before
;
107 struct fs_sink_ctf_stream_class
;
109 struct fs_sink_ctf_event_class
{
111 const bt_event_class
*ir_ec
;
114 struct fs_sink_ctf_stream_class
*sc
;
117 struct fs_sink_ctf_field_class
*spec_context_fc
;
120 struct fs_sink_ctf_field_class
*payload_fc
;
123 struct fs_sink_ctf_trace
;
125 struct fs_sink_ctf_stream_class
{
127 struct fs_sink_ctf_trace
*trace
;
130 const bt_stream_class
*ir_sc
;
133 const bt_clock_class
*default_clock_class
;
135 GString
*default_clock_class_name
;
136 bool packets_have_ts_begin
;
137 bool packets_have_ts_end
;
138 bool has_discarded_events
;
139 bool discarded_events_has_ts
;
140 bool discarded_packets_has_ts
;
143 struct fs_sink_ctf_field_class
*packet_context_fc
;
146 struct fs_sink_ctf_field_class
*event_common_context_fc
;
148 /* Array of `struct fs_sink_ctf_event_class *` (owned by this) */
149 GPtrArray
*event_classes
;
152 * `const bt_event_class *` (weak) ->
153 * `struct fs_sink_ctf_event_class *` (weak)
155 GHashTable
*event_classes_from_ir
;
158 struct fs_sink_ctf_trace
{
160 const bt_trace
*ir_trace
;
163 const bt_trace_class
*ir_tc
;
165 unsigned char uuid
[BABELTRACE_UUID_LEN
];
167 /* Array of `struct fs_sink_ctf_stream_class *` (owned by this) */
168 GPtrArray
*stream_classes
;
172 void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class
*fc
);
175 void _fs_sink_ctf_field_class_init(struct fs_sink_ctf_field_class
*fc
,
176 enum fs_sink_ctf_field_class_type type
,
177 const bt_field_class
*ir_fc
, unsigned int alignment
,
178 uint64_t index_in_parent
)
183 fc
->alignment
= alignment
;
184 fc
->index_in_parent
= index_in_parent
;
188 void _fs_sink_ctf_field_class_bit_array_init(
189 struct fs_sink_ctf_field_class_bit_array
*fc
,
190 enum fs_sink_ctf_field_class_type type
,
191 const bt_field_class
*ir_fc
, unsigned int size
,
192 uint64_t index_in_parent
)
194 _fs_sink_ctf_field_class_init((void *) fc
, type
, ir_fc
,
195 size
% 8 == 0 ? 8 : 1, index_in_parent
);
200 void _fs_sink_ctf_field_class_int_init(struct fs_sink_ctf_field_class_int
*fc
,
201 enum fs_sink_ctf_field_class_type type
,
202 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
204 bt_field_class_type ir_fc_type
= bt_field_class_get_type(ir_fc
);
206 _fs_sink_ctf_field_class_bit_array_init((void *) fc
, type
, ir_fc
,
207 (unsigned int) bt_field_class_integer_get_field_value_range(
210 fc
->is_signed
= (ir_fc_type
== BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
||
211 ir_fc_type
== BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
);
215 void _fs_sink_ctf_named_field_class_init(
216 struct fs_sink_ctf_named_field_class
*named_fc
)
219 named_fc
->name
= g_string_new(NULL
);
220 BT_ASSERT(named_fc
->name
);
224 void _fs_sink_ctf_named_field_class_fini(
225 struct fs_sink_ctf_named_field_class
*named_fc
)
229 if (named_fc
->name
) {
230 g_string_free(named_fc
->name
, TRUE
);
231 named_fc
->name
= NULL
;
234 fs_sink_ctf_field_class_destroy(named_fc
->fc
);
239 struct fs_sink_ctf_field_class_int
*fs_sink_ctf_field_class_int_create(
240 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
242 struct fs_sink_ctf_field_class_int
*fc
=
243 g_new0(struct fs_sink_ctf_field_class_int
, 1);
246 _fs_sink_ctf_field_class_int_init(fc
, FS_SINK_CTF_FIELD_CLASS_TYPE_INT
,
247 ir_fc
, index_in_parent
);
252 struct fs_sink_ctf_field_class_float
*fs_sink_ctf_field_class_float_create(
253 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
255 struct fs_sink_ctf_field_class_float
*fc
=
256 g_new0(struct fs_sink_ctf_field_class_float
, 1);
259 _fs_sink_ctf_field_class_bit_array_init((void *) fc
,
260 FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT
,
261 ir_fc
, bt_field_class_real_is_single_precision(ir_fc
) ? 32 : 64,
267 struct fs_sink_ctf_field_class_string
*fs_sink_ctf_field_class_string_create(
268 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
270 struct fs_sink_ctf_field_class_string
*fc
=
271 g_new0(struct fs_sink_ctf_field_class_string
, 1);
274 _fs_sink_ctf_field_class_init((void *) fc
,
275 FS_SINK_CTF_FIELD_CLASS_TYPE_STRING
, ir_fc
,
281 struct fs_sink_ctf_field_class_struct
*fs_sink_ctf_field_class_struct_create_empty(
282 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
284 struct fs_sink_ctf_field_class_struct
*fc
=
285 g_new0(struct fs_sink_ctf_field_class_struct
, 1);
288 _fs_sink_ctf_field_class_init((void *) fc
,
289 FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT
, ir_fc
, 1, index_in_parent
);
290 fc
->members
= g_array_new(FALSE
, TRUE
,
291 sizeof(struct fs_sink_ctf_named_field_class
));
292 BT_ASSERT(fc
->members
);
297 struct fs_sink_ctf_field_class_variant
*fs_sink_ctf_field_class_variant_create_empty(
298 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
300 struct fs_sink_ctf_field_class_variant
*fc
=
301 g_new0(struct fs_sink_ctf_field_class_variant
, 1);
304 _fs_sink_ctf_field_class_init((void *) fc
,
305 FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT
, ir_fc
,
307 fc
->options
= g_array_new(FALSE
, TRUE
,
308 sizeof(struct fs_sink_ctf_named_field_class
));
309 BT_ASSERT(fc
->options
);
310 fc
->tag_ref
= g_string_new(NULL
);
311 BT_ASSERT(fc
->tag_ref
);
313 bt_field_class_variant_borrow_selector_field_path_const(ir_fc
) ==
319 struct fs_sink_ctf_field_class_array
*fs_sink_ctf_field_class_array_create_empty(
320 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
322 struct fs_sink_ctf_field_class_array
*fc
=
323 g_new0(struct fs_sink_ctf_field_class_array
, 1);
326 _fs_sink_ctf_field_class_init((void *) fc
,
327 FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY
, ir_fc
,
329 fc
->length
= bt_field_class_static_array_get_length(ir_fc
);
334 struct fs_sink_ctf_field_class_sequence
*fs_sink_ctf_field_class_sequence_create_empty(
335 const bt_field_class
*ir_fc
, uint64_t index_in_parent
)
337 struct fs_sink_ctf_field_class_sequence
*fc
=
338 g_new0(struct fs_sink_ctf_field_class_sequence
, 1);
341 _fs_sink_ctf_field_class_init((void *) fc
,
342 FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE
,
343 ir_fc
, 1, index_in_parent
);
344 fc
->length_ref
= g_string_new(NULL
);
345 BT_ASSERT(fc
->length_ref
);
346 fc
->length_is_before
=
347 bt_field_class_dynamic_array_borrow_length_field_path_const(ir_fc
) ==
353 struct fs_sink_ctf_named_field_class
*
354 fs_sink_ctf_field_class_struct_borrow_member_by_index(
355 struct fs_sink_ctf_field_class_struct
*fc
, uint64_t index
);
358 struct fs_sink_ctf_named_field_class
*
359 fs_sink_ctf_field_class_variant_borrow_option_by_index(
360 struct fs_sink_ctf_field_class_variant
*fc
, uint64_t index
);
363 void _fs_sink_ctf_field_class_fini(struct fs_sink_ctf_field_class
*fc
)
369 void _fs_sink_ctf_field_class_int_destroy(
370 struct fs_sink_ctf_field_class_int
*fc
)
373 _fs_sink_ctf_field_class_fini((void *) fc
);
378 void _fs_sink_ctf_field_class_float_destroy(
379 struct fs_sink_ctf_field_class_float
*fc
)
382 _fs_sink_ctf_field_class_fini((void *) fc
);
387 void _fs_sink_ctf_field_class_string_destroy(
388 struct fs_sink_ctf_field_class_string
*fc
)
391 _fs_sink_ctf_field_class_fini((void *) fc
);
396 void _fs_sink_ctf_field_class_struct_destroy(
397 struct fs_sink_ctf_field_class_struct
*fc
)
400 _fs_sink_ctf_field_class_fini((void *) fc
);
405 for (i
= 0; i
< fc
->members
->len
; i
++) {
406 struct fs_sink_ctf_named_field_class
*named_fc
=
407 fs_sink_ctf_field_class_struct_borrow_member_by_index(
410 _fs_sink_ctf_named_field_class_fini(named_fc
);
413 g_array_free(fc
->members
, TRUE
);
421 void _fs_sink_ctf_field_class_array_base_fini(
422 struct fs_sink_ctf_field_class_array_base
*fc
)
425 _fs_sink_ctf_field_class_fini((void *) fc
);
426 fs_sink_ctf_field_class_destroy(fc
->elem_fc
);
431 void _fs_sink_ctf_field_class_array_destroy(
432 struct fs_sink_ctf_field_class_array
*fc
)
435 _fs_sink_ctf_field_class_array_base_fini((void *) fc
);
440 void _fs_sink_ctf_field_class_sequence_destroy(
441 struct fs_sink_ctf_field_class_sequence
*fc
)
444 _fs_sink_ctf_field_class_array_base_fini((void *) fc
);
446 if (fc
->length_ref
) {
447 g_string_free(fc
->length_ref
, TRUE
);
448 fc
->length_ref
= NULL
;
455 void _fs_sink_ctf_field_class_variant_destroy(
456 struct fs_sink_ctf_field_class_variant
*fc
)
459 _fs_sink_ctf_field_class_fini((void *) fc
);
464 for (i
= 0; i
< fc
->options
->len
; i
++) {
465 struct fs_sink_ctf_named_field_class
*named_fc
=
466 fs_sink_ctf_field_class_variant_borrow_option_by_index(
469 _fs_sink_ctf_named_field_class_fini(named_fc
);
472 g_array_free(fc
->options
, TRUE
);
477 g_string_free(fc
->tag_ref
, TRUE
);
485 void fs_sink_ctf_field_class_destroy(struct fs_sink_ctf_field_class
*fc
)
492 case FS_SINK_CTF_FIELD_CLASS_TYPE_INT
:
493 _fs_sink_ctf_field_class_int_destroy((void *) fc
);
495 case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT
:
496 _fs_sink_ctf_field_class_float_destroy((void *) fc
);
498 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING
:
499 _fs_sink_ctf_field_class_string_destroy((void *) fc
);
501 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT
:
502 _fs_sink_ctf_field_class_struct_destroy((void *) fc
);
504 case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY
:
505 _fs_sink_ctf_field_class_array_destroy((void *) fc
);
507 case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE
:
508 _fs_sink_ctf_field_class_sequence_destroy((void *) fc
);
510 case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT
:
511 _fs_sink_ctf_field_class_variant_destroy((void *) fc
);
519 struct fs_sink_ctf_named_field_class
*
520 fs_sink_ctf_field_class_struct_borrow_member_by_index(
521 struct fs_sink_ctf_field_class_struct
*fc
, uint64_t index
)
524 BT_ASSERT(index
< fc
->members
->len
);
525 return &g_array_index(fc
->members
, struct fs_sink_ctf_named_field_class
,
530 struct fs_sink_ctf_named_field_class
*
531 fs_sink_ctf_field_class_struct_borrow_member_by_name(
532 struct fs_sink_ctf_field_class_struct
*fc
, const char *name
)
535 struct fs_sink_ctf_named_field_class
*ret_named_fc
= NULL
;
540 for (i
= 0; i
< fc
->members
->len
; i
++) {
541 struct fs_sink_ctf_named_field_class
*named_fc
=
542 fs_sink_ctf_field_class_struct_borrow_member_by_index(
545 if (strcmp(name
, named_fc
->name
->str
) == 0) {
546 ret_named_fc
= named_fc
;
556 struct fs_sink_ctf_field_class
*
557 fs_sink_ctf_field_class_struct_borrow_member_field_class_by_name(
558 struct fs_sink_ctf_field_class_struct
*struct_fc
, const char *name
)
560 struct fs_sink_ctf_named_field_class
*named_fc
= NULL
;
561 struct fs_sink_ctf_field_class
*fc
= NULL
;
567 named_fc
= fs_sink_ctf_field_class_struct_borrow_member_by_name(
580 struct fs_sink_ctf_field_class_int
*
581 fs_sink_ctf_field_class_struct_borrow_member_int_field_class_by_name(
582 struct fs_sink_ctf_field_class_struct
*struct_fc
,
585 struct fs_sink_ctf_field_class_int
*int_fc
= NULL
;
588 fs_sink_ctf_field_class_struct_borrow_member_field_class_by_name(
594 if (int_fc
->base
.base
.type
!= FS_SINK_CTF_FIELD_CLASS_TYPE_INT
) {
604 void fs_sink_ctf_field_class_struct_align_at_least(
605 struct fs_sink_ctf_field_class_struct
*fc
,
606 unsigned int alignment
)
608 if (alignment
> fc
->base
.alignment
) {
609 fc
->base
.alignment
= alignment
;
614 void fs_sink_ctf_field_class_struct_append_member(
615 struct fs_sink_ctf_field_class_struct
*fc
,
616 const char *name
, struct fs_sink_ctf_field_class
*member_fc
)
618 struct fs_sink_ctf_named_field_class
*named_fc
;
622 g_array_set_size(fc
->members
, fc
->members
->len
+ 1);
624 named_fc
= &g_array_index(fc
->members
,
625 struct fs_sink_ctf_named_field_class
, fc
->members
->len
- 1);
626 _fs_sink_ctf_named_field_class_init(named_fc
);
627 g_string_assign(named_fc
->name
, name
);
628 named_fc
->fc
= member_fc
;
629 fs_sink_ctf_field_class_struct_align_at_least(fc
, member_fc
->alignment
);
633 struct fs_sink_ctf_named_field_class
*
634 fs_sink_ctf_field_class_variant_borrow_option_by_index(
635 struct fs_sink_ctf_field_class_variant
*fc
, uint64_t index
)
638 BT_ASSERT(index
< fc
->options
->len
);
639 return &g_array_index(fc
->options
, struct fs_sink_ctf_named_field_class
,
644 struct fs_sink_ctf_named_field_class
*
645 fs_sink_ctf_field_class_variant_borrow_option_by_name(
646 struct fs_sink_ctf_field_class_variant
*fc
, const char *name
)
649 struct fs_sink_ctf_named_field_class
*ret_named_fc
= NULL
;
654 for (i
= 0; i
< fc
->options
->len
; i
++) {
655 struct fs_sink_ctf_named_field_class
*named_fc
=
656 fs_sink_ctf_field_class_variant_borrow_option_by_index(
659 if (strcmp(name
, named_fc
->name
->str
) == 0) {
660 ret_named_fc
= named_fc
;
670 void fs_sink_ctf_field_class_variant_append_option(
671 struct fs_sink_ctf_field_class_variant
*fc
,
672 const char *name
, struct fs_sink_ctf_field_class
*option_fc
)
674 struct fs_sink_ctf_named_field_class
*named_fc
;
678 g_array_set_size(fc
->options
, fc
->options
->len
+ 1);
680 named_fc
= &g_array_index(fc
->options
,
681 struct fs_sink_ctf_named_field_class
, fc
->options
->len
- 1);
682 _fs_sink_ctf_named_field_class_init(named_fc
);
683 g_string_assign(named_fc
->name
, name
);
684 named_fc
->fc
= option_fc
;
688 struct fs_sink_ctf_event_class
*fs_sink_ctf_event_class_create(
689 struct fs_sink_ctf_stream_class
*sc
,
690 const bt_event_class
*ir_ec
)
692 struct fs_sink_ctf_event_class
*ec
=
693 g_new0(struct fs_sink_ctf_event_class
, 1);
700 g_ptr_array_add(sc
->event_classes
, ec
);
701 g_hash_table_insert(sc
->event_classes_from_ir
, (gpointer
) ir_ec
, ec
);
706 void fs_sink_ctf_event_class_destroy(struct fs_sink_ctf_event_class
*ec
)
712 fs_sink_ctf_field_class_destroy(ec
->spec_context_fc
);
713 ec
->spec_context_fc
= NULL
;
714 fs_sink_ctf_field_class_destroy(ec
->payload_fc
);
715 ec
->payload_fc
= NULL
;
720 struct fs_sink_ctf_stream_class
*fs_sink_ctf_stream_class_create(
721 struct fs_sink_ctf_trace
*trace
,
722 const bt_stream_class
*ir_sc
)
724 struct fs_sink_ctf_stream_class
*sc
=
725 g_new0(struct fs_sink_ctf_stream_class
, 1);
732 sc
->default_clock_class
=
733 bt_stream_class_borrow_default_clock_class_const(ir_sc
);
734 sc
->default_clock_class_name
= g_string_new(NULL
);
735 BT_ASSERT(sc
->default_clock_class_name
);
736 sc
->event_classes
= g_ptr_array_new_with_free_func(
737 (GDestroyNotify
) fs_sink_ctf_event_class_destroy
);
738 BT_ASSERT(sc
->event_classes
);
739 sc
->event_classes_from_ir
= g_hash_table_new(g_direct_hash
,
741 BT_ASSERT(sc
->event_classes_from_ir
);
742 sc
->packets_have_ts_begin
=
743 bt_stream_class_packets_have_beginning_default_clock_snapshot(
745 sc
->packets_have_ts_end
=
746 bt_stream_class_packets_have_end_default_clock_snapshot(ir_sc
);
747 sc
->has_discarded_events
=
748 bt_stream_class_supports_discarded_events(ir_sc
);
750 if (sc
->has_discarded_events
) {
751 sc
->discarded_events_has_ts
=
752 bt_stream_class_discarded_events_have_default_clock_snapshots(
756 if (bt_stream_class_supports_discarded_packets(ir_sc
)) {
757 sc
->discarded_packets_has_ts
=
758 bt_stream_class_discarded_packets_have_default_clock_snapshots(
762 g_ptr_array_add(trace
->stream_classes
, sc
);
767 void fs_sink_ctf_stream_class_destroy(struct fs_sink_ctf_stream_class
*sc
)
773 if (sc
->default_clock_class_name
) {
774 g_string_free(sc
->default_clock_class_name
, TRUE
);
775 sc
->default_clock_class_name
= NULL
;
778 if (sc
->event_classes
) {
779 g_ptr_array_free(sc
->event_classes
, TRUE
);
780 sc
->event_classes
= NULL
;
783 if (sc
->event_classes_from_ir
) {
784 g_hash_table_destroy(sc
->event_classes_from_ir
);
785 sc
->event_classes_from_ir
= NULL
;
788 fs_sink_ctf_field_class_destroy(sc
->packet_context_fc
);
789 sc
->packet_context_fc
= NULL
;
790 fs_sink_ctf_field_class_destroy(sc
->event_common_context_fc
);
791 sc
->event_common_context_fc
= NULL
;
796 void fs_sink_ctf_stream_class_append_event_class(
797 struct fs_sink_ctf_stream_class
*sc
,
798 struct fs_sink_ctf_event_class
*ec
)
800 g_ptr_array_add(sc
->event_classes
, ec
);
804 void fs_sink_ctf_trace_destroy(struct fs_sink_ctf_trace
*trace
)
810 if (trace
->stream_classes
) {
811 g_ptr_array_free(trace
->stream_classes
, TRUE
);
812 trace
->stream_classes
= NULL
;
819 struct fs_sink_ctf_trace
*fs_sink_ctf_trace_create(const bt_trace
*ir_trace
)
821 struct fs_sink_ctf_trace
*trace
=
822 g_new0(struct fs_sink_ctf_trace
, 1);
826 if (bt_uuid_generate(trace
->uuid
)) {
827 fs_sink_ctf_trace_destroy(trace
);
832 trace
->ir_trace
= ir_trace
;
833 trace
->ir_tc
= bt_trace_borrow_class_const(ir_trace
);
834 trace
->stream_classes
= g_ptr_array_new_with_free_func(
835 (GDestroyNotify
) fs_sink_ctf_stream_class_destroy
);
836 BT_ASSERT(trace
->stream_classes
);
843 bool fs_sink_ctf_ist_valid_identifier(const char *name
)
847 bool ist_valid
= true;
848 static const char *reserved_keywords
[] = {
879 /* Make sure the name is not a reserved keyword */
880 for (i
= 0; i
< sizeof(reserved_keywords
) / sizeof(*reserved_keywords
);
882 if (strcmp(name
, reserved_keywords
[i
]) == 0) {
888 /* Make sure the name is not an empty string */
889 if (strlen(name
) == 0) {
894 /* Make sure the name starts with a letter or `_` */
895 if (!isalpha(name
[0]) && name
[0] != '_') {
900 /* Make sure the name only contains letters, digits, and `_` */
901 for (at
= name
; *at
!= '\0'; at
++) {
902 if (!isalnum(*at
) && *at
!= '_') {
913 int fs_sink_ctf_protect_name(GString
*name
)
917 if (!fs_sink_ctf_ist_valid_identifier(name
->str
)) {
922 /* Prepend `_` to protect it */
923 g_string_prepend_c(name
, '_');
929 #endif /* BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H */