2 * ctf-visitor-generate-io-struct.c
4 * Common Trace Format Metadata Visitor (generate I/O structures).
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <babeltrace/babeltrace-internal.h>
36 #include <babeltrace/list.h>
37 #include <babeltrace/types.h>
38 #include <babeltrace/ctf/metadata.h>
39 #include <babeltrace/compat/uuid.h>
40 #include <babeltrace/endian.h>
41 #include <babeltrace/ctf/events-internal.h>
42 #include "ctf-scanner.h"
43 #include "ctf-parser.h"
46 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
48 #define _bt_list_first_entry(ptr, type, member) \
49 bt_list_entry((ptr)->next, type, member)
51 struct last_enum_value
{
58 int opt_clock_force_correlate
;
61 struct bt_declaration
*ctf_type_specifier_list_visit(FILE *fd
,
62 int depth
, struct ctf_node
*type_specifier_list
,
63 struct declaration_scope
*declaration_scope
,
64 struct ctf_trace
*trace
);
67 int ctf_stream_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
68 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
);
71 int is_unary_string(struct bt_list_head
*head
)
73 struct ctf_node
*node
;
75 bt_list_for_each_entry(node
, head
, siblings
) {
76 if (node
->type
!= NODE_UNARY_EXPRESSION
)
78 if (node
->u
.unary_expression
.type
!= UNARY_STRING
)
85 * String returned must be freed by the caller using g_free.
88 char *concatenate_unary_strings(struct bt_list_head
*head
)
90 struct ctf_node
*node
;
94 str
= g_string_new("");
95 bt_list_for_each_entry(node
, head
, siblings
) {
98 if (node
->type
!= NODE_UNARY_EXPRESSION
99 || node
->u
.unary_expression
.type
!= UNARY_STRING
100 || !((node
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
)
103 switch (node
->u
.unary_expression
.link
) {
105 g_string_append(str
, ".");
107 case UNARY_ARROWLINK
:
108 g_string_append(str
, "->");
110 case UNARY_DOTDOTDOT
:
111 g_string_append(str
, "...");
116 src_string
= node
->u
.unary_expression
.u
.string
;
117 g_string_append(str
, src_string
);
120 return g_string_free(str
, FALSE
);
124 GQuark
get_map_clock_name_value(struct bt_list_head
*head
)
126 struct ctf_node
*node
;
127 const char *name
= NULL
;
130 bt_list_for_each_entry(node
, head
, siblings
) {
133 if (node
->type
!= NODE_UNARY_EXPRESSION
134 || node
->u
.unary_expression
.type
!= UNARY_STRING
135 || !((node
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
)
138 /* needs to be chained with . */
139 switch (node
->u
.unary_expression
.link
) {
142 case UNARY_ARROWLINK
:
143 case UNARY_DOTDOTDOT
:
148 src_string
= node
->u
.unary_expression
.u
.string
;
150 case 0: if (strcmp("clock", src_string
) != 0) {
154 case 1: name
= src_string
;
156 case 2: if (strcmp("value", src_string
) != 0) {
161 return 0; /* extra identifier, unknown */
165 return g_quark_from_string(name
);
169 int is_unary_unsigned(struct bt_list_head
*head
)
171 struct ctf_node
*node
;
173 bt_list_for_each_entry(node
, head
, siblings
) {
174 if (node
->type
!= NODE_UNARY_EXPRESSION
)
176 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
183 int get_unary_unsigned(struct bt_list_head
*head
, uint64_t *value
)
185 struct ctf_node
*node
;
188 bt_list_for_each_entry(node
, head
, siblings
) {
189 if (node
->type
!= NODE_UNARY_EXPRESSION
190 || node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
191 || node
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
194 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
201 int is_unary_signed(struct bt_list_head
*head
)
203 struct ctf_node
*node
;
205 bt_list_for_each_entry(node
, head
, siblings
) {
206 if (node
->type
!= NODE_UNARY_EXPRESSION
)
208 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
)
215 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
217 struct ctf_node
*node
;
220 bt_list_for_each_entry(node
, head
, siblings
) {
221 if (node
->type
!= NODE_UNARY_EXPRESSION
222 || node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
223 || (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
&& node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
)
224 || node
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
227 switch (node
->u
.unary_expression
.type
) {
228 case UNARY_UNSIGNED_CONSTANT
:
229 *value
= (int64_t) node
->u
.unary_expression
.u
.unsigned_constant
;
231 case UNARY_SIGNED_CONSTANT
:
232 *value
= node
->u
.unary_expression
.u
.signed_constant
;
243 int get_unary_uuid(struct bt_list_head
*head
, unsigned char *uuid
)
245 struct ctf_node
*node
;
249 bt_list_for_each_entry(node
, head
, siblings
) {
250 const char *src_string
;
252 if (node
->type
!= NODE_UNARY_EXPRESSION
253 || node
->u
.unary_expression
.type
!= UNARY_STRING
254 || node
->u
.unary_expression
.link
!= UNARY_LINK_UNKNOWN
257 src_string
= node
->u
.unary_expression
.u
.string
;
258 ret
= bt_uuid_parse(src_string
, uuid
);
264 struct ctf_stream_declaration
*trace_stream_lookup(struct ctf_trace
*trace
, uint64_t stream_id
)
266 if (trace
->streams
->len
<= stream_id
)
268 return g_ptr_array_index(trace
->streams
, stream_id
);
272 struct ctf_event_declaration
*stream_event_lookup(struct ctf_stream_declaration
*stream
, uint64_t event_id
)
274 if (stream
->events_by_id
->len
<= event_id
)
276 return g_ptr_array_index(stream
->events_by_id
, event_id
);
280 struct ctf_clock
*trace_clock_lookup(struct ctf_trace
*trace
, GQuark clock_name
)
282 return g_hash_table_lookup(trace
->parent
.clocks
, (gpointer
) (unsigned long) clock_name
);
286 int visit_type_specifier(FILE *fd
, struct ctf_node
*type_specifier
, GString
*str
)
288 if (type_specifier
->type
!= NODE_TYPE_SPECIFIER
)
291 switch (type_specifier
->u
.type_specifier
.type
) {
293 g_string_append(str
, "void");
296 g_string_append(str
, "char");
299 g_string_append(str
, "short");
302 g_string_append(str
, "int");
305 g_string_append(str
, "long");
308 g_string_append(str
, "float");
310 case TYPESPEC_DOUBLE
:
311 g_string_append(str
, "double");
313 case TYPESPEC_SIGNED
:
314 g_string_append(str
, "signed");
316 case TYPESPEC_UNSIGNED
:
317 g_string_append(str
, "unsigned");
320 g_string_append(str
, "bool");
322 case TYPESPEC_COMPLEX
:
323 g_string_append(str
, "_Complex");
325 case TYPESPEC_IMAGINARY
:
326 g_string_append(str
, "_Imaginary");
329 g_string_append(str
, "const");
331 case TYPESPEC_ID_TYPE
:
332 if (type_specifier
->u
.type_specifier
.id_type
)
333 g_string_append(str
, type_specifier
->u
.type_specifier
.id_type
);
335 case TYPESPEC_STRUCT
:
337 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
339 if (!node
->u
._struct
.name
) {
340 fprintf(fd
, "[error] %s: unexpected empty variant name\n", __func__
);
343 g_string_append(str
, "struct ");
344 g_string_append(str
, node
->u
._struct
.name
);
347 case TYPESPEC_VARIANT
:
349 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
351 if (!node
->u
.variant
.name
) {
352 fprintf(fd
, "[error] %s: unexpected empty variant name\n", __func__
);
355 g_string_append(str
, "variant ");
356 g_string_append(str
, node
->u
.variant
.name
);
361 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
363 if (!node
->u
._enum
.enum_id
) {
364 fprintf(fd
, "[error] %s: unexpected empty enum ID\n", __func__
);
367 g_string_append(str
, "enum ");
368 g_string_append(str
, node
->u
._enum
.enum_id
);
371 case TYPESPEC_FLOATING_POINT
:
372 case TYPESPEC_INTEGER
:
373 case TYPESPEC_STRING
:
375 fprintf(fd
, "[error] %s: unknown specifier\n", __func__
);
382 int visit_type_specifier_list(FILE *fd
, struct ctf_node
*type_specifier_list
, GString
*str
)
384 struct ctf_node
*iter
;
385 int alias_item_nr
= 0;
388 bt_list_for_each_entry(iter
, &type_specifier_list
->u
.type_specifier_list
.head
, siblings
) {
389 if (alias_item_nr
!= 0)
390 g_string_append(str
, " ");
392 ret
= visit_type_specifier(fd
, iter
, str
);
400 GQuark
create_typealias_identifier(FILE *fd
, int depth
,
401 struct ctf_node
*type_specifier_list
,
402 struct ctf_node
*node_type_declarator
)
404 struct ctf_node
*iter
;
410 str
= g_string_new("");
411 ret
= visit_type_specifier_list(fd
, type_specifier_list
, str
);
413 g_string_free(str
, TRUE
);
416 bt_list_for_each_entry(iter
, &node_type_declarator
->u
.type_declarator
.pointers
, siblings
) {
417 g_string_append(str
, " *");
418 if (iter
->u
.pointer
.const_qualifier
)
419 g_string_append(str
, " const");
421 str_c
= g_string_free(str
, FALSE
);
422 alias_q
= g_quark_from_string(str_c
);
428 struct bt_declaration
*ctf_type_declarator_visit(FILE *fd
, int depth
,
429 struct ctf_node
*type_specifier_list
,
431 struct ctf_node
*node_type_declarator
,
432 struct declaration_scope
*declaration_scope
,
433 struct bt_declaration
*nested_declaration
,
434 struct ctf_trace
*trace
)
437 * Visit type declarator by first taking care of sequence/array
438 * (recursively). Then, when we get to the identifier, take care
442 if (node_type_declarator
) {
443 if (node_type_declarator
->u
.type_declarator
.type
== TYPEDEC_UNKNOWN
) {
447 /* TODO: gcc bitfields not supported yet. */
448 if (node_type_declarator
->u
.type_declarator
.bitfield_len
!= NULL
) {
449 fprintf(fd
, "[error] %s: gcc bitfields are not supported yet.\n", __func__
);
454 if (!nested_declaration
) {
455 if (node_type_declarator
&& !bt_list_empty(&node_type_declarator
->u
.type_declarator
.pointers
)) {
459 * If we have a pointer declarator, it _has_ to be present in
460 * the typealiases (else fail).
462 alias_q
= create_typealias_identifier(fd
, depth
,
463 type_specifier_list
, node_type_declarator
);
464 nested_declaration
= bt_lookup_declaration(alias_q
, declaration_scope
);
465 if (!nested_declaration
) {
466 fprintf(fd
, "[error] %s: cannot find typealias \"%s\".\n", __func__
, g_quark_to_string(alias_q
));
469 if (nested_declaration
->id
== CTF_TYPE_INTEGER
) {
470 struct declaration_integer
*integer_declaration
=
471 container_of(nested_declaration
, struct declaration_integer
, p
);
472 /* For base to 16 for pointers (expected pretty-print) */
473 if (!integer_declaration
->base
) {
475 * We need to do a copy of the
476 * integer declaration to modify it. There could be other references to
479 integer_declaration
= bt_integer_declaration_new(integer_declaration
->len
,
480 integer_declaration
->byte_order
, integer_declaration
->signedness
,
481 integer_declaration
->p
.alignment
, 16, integer_declaration
->encoding
,
482 integer_declaration
->clock
);
483 nested_declaration
= &integer_declaration
->p
;
487 nested_declaration
= ctf_type_specifier_list_visit(fd
, depth
,
488 type_specifier_list
, declaration_scope
, trace
);
492 if (!node_type_declarator
)
493 return nested_declaration
;
495 if (node_type_declarator
->u
.type_declarator
.type
== TYPEDEC_ID
) {
496 if (node_type_declarator
->u
.type_declarator
.u
.id
)
497 *field_name
= g_quark_from_string(node_type_declarator
->u
.type_declarator
.u
.id
);
500 return nested_declaration
;
502 struct bt_declaration
*declaration
;
503 struct ctf_node
*first
;
507 if (!nested_declaration
) {
508 fprintf(fd
, "[error] %s: nested type is unknown.\n", __func__
);
512 /* create array/sequence, pass nested_declaration as child. */
513 if (bt_list_empty(&node_type_declarator
->u
.type_declarator
.u
.nested
.length
)) {
514 fprintf(fd
, "[error] %s: expecting length field reference or value.\n", __func__
);
517 first
= _bt_list_first_entry(&node_type_declarator
->u
.type_declarator
.u
.nested
.length
,
518 struct ctf_node
, siblings
);
519 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
523 switch (first
->u
.unary_expression
.type
) {
524 case UNARY_UNSIGNED_CONSTANT
:
526 struct declaration_array
*array_declaration
;
529 len
= first
->u
.unary_expression
.u
.unsigned_constant
;
530 array_declaration
= bt_array_declaration_new(len
, nested_declaration
,
533 if (!array_declaration
) {
534 fprintf(fd
, "[error] %s: cannot create array declaration.\n", __func__
);
537 bt_declaration_unref(nested_declaration
);
538 declaration
= &array_declaration
->p
;
543 /* Lookup unsigned integer definition, create sequence */
544 char *length_name
= concatenate_unary_strings(&node_type_declarator
->u
.type_declarator
.u
.nested
.length
);
545 struct declaration_sequence
*sequence_declaration
;
549 sequence_declaration
= bt_sequence_declaration_new(length_name
, nested_declaration
, declaration_scope
);
550 if (!sequence_declaration
) {
551 fprintf(fd
, "[error] %s: cannot create sequence declaration.\n", __func__
);
555 bt_declaration_unref(nested_declaration
);
556 declaration
= &sequence_declaration
->p
;
564 /* Pass it as content of outer container */
565 declaration
= ctf_type_declarator_visit(fd
, depth
,
566 type_specifier_list
, field_name
,
567 node_type_declarator
->u
.type_declarator
.u
.nested
.type_declarator
,
568 declaration_scope
, declaration
, trace
);
574 int ctf_struct_type_declarators_visit(FILE *fd
, int depth
,
575 struct declaration_struct
*struct_declaration
,
576 struct ctf_node
*type_specifier_list
,
577 struct bt_list_head
*type_declarators
,
578 struct declaration_scope
*declaration_scope
,
579 struct ctf_trace
*trace
)
581 struct ctf_node
*iter
;
584 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
585 struct bt_declaration
*field_declaration
;
587 field_declaration
= ctf_type_declarator_visit(fd
, depth
,
590 struct_declaration
->scope
,
592 if (!field_declaration
) {
593 fprintf(fd
, "[error] %s: unable to find struct field declaration type\n", __func__
);
597 /* Check if field with same name already exists */
598 if (bt_struct_declaration_lookup_field_index(struct_declaration
, field_name
) >= 0) {
599 fprintf(fd
, "[error] %s: duplicate field %s in struct\n", __func__
, g_quark_to_string(field_name
));
603 bt_struct_declaration_add_field(struct_declaration
,
604 g_quark_to_string(field_name
),
606 bt_declaration_unref(field_declaration
);
612 int ctf_variant_type_declarators_visit(FILE *fd
, int depth
,
613 struct declaration_untagged_variant
*untagged_variant_declaration
,
614 struct ctf_node
*type_specifier_list
,
615 struct bt_list_head
*type_declarators
,
616 struct declaration_scope
*declaration_scope
,
617 struct ctf_trace
*trace
)
619 struct ctf_node
*iter
;
622 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
623 struct bt_declaration
*field_declaration
;
625 field_declaration
= ctf_type_declarator_visit(fd
, depth
,
628 untagged_variant_declaration
->scope
,
630 if (!field_declaration
) {
631 fprintf(fd
, "[error] %s: unable to find variant field declaration type\n", __func__
);
635 if (bt_untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration
, field_name
) != NULL
) {
636 fprintf(fd
, "[error] %s: duplicate field %s in variant\n", __func__
, g_quark_to_string(field_name
));
640 bt_untagged_variant_declaration_add_field(untagged_variant_declaration
,
641 g_quark_to_string(field_name
),
643 bt_declaration_unref(field_declaration
);
649 int ctf_typedef_visit(FILE *fd
, int depth
, struct declaration_scope
*scope
,
650 struct ctf_node
*type_specifier_list
,
651 struct bt_list_head
*type_declarators
,
652 struct ctf_trace
*trace
)
654 struct ctf_node
*iter
;
657 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
658 struct bt_declaration
*type_declaration
;
661 type_declaration
= ctf_type_declarator_visit(fd
, depth
,
665 if (!type_declaration
) {
666 fprintf(fd
, "[error] %s: problem creating type declaration\n", __func__
);
670 * Don't allow typedef and typealias of untagged
673 if (type_declaration
->id
== CTF_TYPE_UNTAGGED_VARIANT
) {
674 fprintf(fd
, "[error] %s: typedef of untagged variant is not permitted.\n", __func__
);
675 bt_declaration_unref(type_declaration
);
678 ret
= bt_register_declaration(identifier
, type_declaration
, scope
);
680 type_declaration
->declaration_free(type_declaration
);
683 bt_declaration_unref(type_declaration
);
689 int ctf_typealias_visit(FILE *fd
, int depth
, struct declaration_scope
*scope
,
690 struct ctf_node
*target
, struct ctf_node
*alias
,
691 struct ctf_trace
*trace
)
693 struct bt_declaration
*type_declaration
;
694 struct ctf_node
*node
;
699 /* See ctf_visitor_type_declarator() in the semantic validator. */
702 * Create target type declaration.
705 if (bt_list_empty(&target
->u
.typealias_target
.type_declarators
))
708 node
= _bt_list_first_entry(&target
->u
.typealias_target
.type_declarators
,
709 struct ctf_node
, siblings
);
710 type_declaration
= ctf_type_declarator_visit(fd
, depth
,
711 target
->u
.typealias_target
.type_specifier_list
,
714 if (!type_declaration
) {
715 fprintf(fd
, "[error] %s: problem creating type declaration\n", __func__
);
720 * Don't allow typedef and typealias of untagged
723 if (type_declaration
->id
== CTF_TYPE_UNTAGGED_VARIANT
) {
724 fprintf(fd
, "[error] %s: typedef of untagged variant is not permitted.\n", __func__
);
725 bt_declaration_unref(type_declaration
);
729 * The semantic validator does not check whether the target is
730 * abstract or not (if it has an identifier). Check it here.
733 fprintf(fd
, "[error] %s: expecting empty identifier\n", __func__
);
738 * Create alias identifier.
741 node
= _bt_list_first_entry(&alias
->u
.typealias_alias
.type_declarators
,
742 struct ctf_node
, siblings
);
743 alias_q
= create_typealias_identifier(fd
, depth
,
744 alias
->u
.typealias_alias
.type_specifier_list
, node
);
745 err
= bt_register_declaration(alias_q
, type_declaration
, scope
);
748 bt_declaration_unref(type_declaration
);
752 if (type_declaration
) {
753 type_declaration
->declaration_free(type_declaration
);
759 int ctf_struct_declaration_list_visit(FILE *fd
, int depth
,
760 struct ctf_node
*iter
, struct declaration_struct
*struct_declaration
,
761 struct ctf_trace
*trace
)
765 switch (iter
->type
) {
767 /* For each declarator, declare type and add type to struct bt_declaration scope */
768 ret
= ctf_typedef_visit(fd
, depth
,
769 struct_declaration
->scope
,
770 iter
->u
._typedef
.type_specifier_list
,
771 &iter
->u
._typedef
.type_declarators
, trace
);
776 /* Declare type with declarator and add type to struct bt_declaration scope */
777 ret
= ctf_typealias_visit(fd
, depth
,
778 struct_declaration
->scope
,
779 iter
->u
.typealias
.target
,
780 iter
->u
.typealias
.alias
, trace
);
784 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
785 /* Add field to structure declaration */
786 ret
= ctf_struct_type_declarators_visit(fd
, depth
,
788 iter
->u
.struct_or_variant_declaration
.type_specifier_list
,
789 &iter
->u
.struct_or_variant_declaration
.type_declarators
,
790 struct_declaration
->scope
, trace
);
795 fprintf(fd
, "[error] %s: unexpected node type %d\n", __func__
, (int) iter
->type
);
802 int ctf_variant_declaration_list_visit(FILE *fd
, int depth
,
803 struct ctf_node
*iter
,
804 struct declaration_untagged_variant
*untagged_variant_declaration
,
805 struct ctf_trace
*trace
)
809 switch (iter
->type
) {
811 /* For each declarator, declare type and add type to variant declaration scope */
812 ret
= ctf_typedef_visit(fd
, depth
,
813 untagged_variant_declaration
->scope
,
814 iter
->u
._typedef
.type_specifier_list
,
815 &iter
->u
._typedef
.type_declarators
, trace
);
820 /* Declare type with declarator and add type to variant declaration scope */
821 ret
= ctf_typealias_visit(fd
, depth
,
822 untagged_variant_declaration
->scope
,
823 iter
->u
.typealias
.target
,
824 iter
->u
.typealias
.alias
, trace
);
828 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
829 /* Add field to structure declaration */
830 ret
= ctf_variant_type_declarators_visit(fd
, depth
,
831 untagged_variant_declaration
,
832 iter
->u
.struct_or_variant_declaration
.type_specifier_list
,
833 &iter
->u
.struct_or_variant_declaration
.type_declarators
,
834 untagged_variant_declaration
->scope
, trace
);
839 fprintf(fd
, "[error] %s: unexpected node type %d\n", __func__
, (int) iter
->type
);
846 struct bt_declaration
*ctf_declaration_struct_visit(FILE *fd
,
847 int depth
, const char *name
, struct bt_list_head
*declaration_list
,
848 int has_body
, struct bt_list_head
*min_align
,
849 struct declaration_scope
*declaration_scope
,
850 struct ctf_trace
*trace
)
852 struct declaration_struct
*struct_declaration
;
853 struct ctf_node
*iter
;
856 * For named struct (without body), lookup in
857 * declaration scope. Don't take reference on struct
858 * declaration: ref is only taken upon definition.
864 bt_lookup_struct_declaration(g_quark_from_string(name
),
866 bt_declaration_ref(&struct_declaration
->p
);
867 return &struct_declaration
->p
;
869 uint64_t min_align_value
= 0;
871 /* For unnamed struct, create type */
872 /* For named struct (with body), create type and add to declaration scope */
874 if (bt_lookup_struct_declaration(g_quark_from_string(name
),
875 declaration_scope
)) {
876 fprintf(fd
, "[error] %s: struct %s already declared in scope\n", __func__
, name
);
880 if (!bt_list_empty(min_align
)) {
883 ret
= get_unary_unsigned(min_align
, &min_align_value
);
885 fprintf(fd
, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__
);
889 struct_declaration
= bt_struct_declaration_new(declaration_scope
,
891 bt_list_for_each_entry(iter
, declaration_list
, siblings
) {
894 ret
= ctf_struct_declaration_list_visit(fd
, depth
+ 1, iter
,
895 struct_declaration
, trace
);
897 goto error_free_declaration
;
902 ret
= bt_register_struct_declaration(g_quark_from_string(name
),
908 return &struct_declaration
->p
;
910 error_free_declaration
:
911 struct_declaration
->p
.declaration_free(&struct_declaration
->p
);
917 struct bt_declaration
*ctf_declaration_variant_visit(FILE *fd
,
918 int depth
, const char *name
, const char *choice
,
919 struct bt_list_head
*declaration_list
,
920 int has_body
, struct declaration_scope
*declaration_scope
,
921 struct ctf_trace
*trace
)
923 struct declaration_untagged_variant
*untagged_variant_declaration
;
924 struct declaration_variant
*variant_declaration
;
925 struct ctf_node
*iter
;
928 * For named variant (without body), lookup in
929 * declaration scope. Don't take reference on variant
930 * declaration: ref is only taken upon definition.
935 untagged_variant_declaration
=
936 bt_lookup_variant_declaration(g_quark_from_string(name
),
938 bt_declaration_ref(&untagged_variant_declaration
->p
);
940 /* For unnamed variant, create type */
941 /* For named variant (with body), create type and add to declaration scope */
943 if (bt_lookup_variant_declaration(g_quark_from_string(name
),
944 declaration_scope
)) {
945 fprintf(fd
, "[error] %s: variant %s already declared in scope\n", __func__
, name
);
949 untagged_variant_declaration
= bt_untagged_bt_variant_declaration_new(declaration_scope
);
950 bt_list_for_each_entry(iter
, declaration_list
, siblings
) {
953 ret
= ctf_variant_declaration_list_visit(fd
, depth
+ 1, iter
,
954 untagged_variant_declaration
, trace
);
961 ret
= bt_register_variant_declaration(g_quark_from_string(name
),
962 untagged_variant_declaration
,
969 * if tagged, create tagged variant and return. else return
973 return &untagged_variant_declaration
->p
;
975 variant_declaration
= bt_variant_declaration_new(untagged_variant_declaration
, choice
);
976 if (!variant_declaration
)
978 bt_declaration_unref(&untagged_variant_declaration
->p
);
979 return &variant_declaration
->p
;
982 untagged_variant_declaration
->p
.declaration_free(&untagged_variant_declaration
->p
);
987 int ctf_enumerator_list_visit(FILE *fd
, int depth
,
988 struct ctf_node
*enumerator
,
989 struct declaration_enum
*enum_declaration
,
990 struct last_enum_value
*last
)
993 struct ctf_node
*iter
;
995 q
= g_quark_from_string(enumerator
->u
.enumerator
.id
);
996 if (enum_declaration
->integer_declaration
->signedness
) {
997 int64_t start
= 0, end
= 0;
1000 bt_list_for_each_entry(iter
, &enumerator
->u
.enumerator
.values
, siblings
) {
1003 if (iter
->type
!= NODE_UNARY_EXPRESSION
)
1010 switch (iter
->u
.unary_expression
.type
) {
1011 case UNARY_SIGNED_CONSTANT
:
1012 *target
= iter
->u
.unary_expression
.u
.signed_constant
;
1014 case UNARY_UNSIGNED_CONSTANT
:
1015 *target
= iter
->u
.unary_expression
.u
.unsigned_constant
;
1018 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
1022 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
1031 last
->u
.s
= end
+ 1;
1032 bt_enum_signed_insert(enum_declaration
, start
, end
, q
);
1034 uint64_t start
= 0, end
= 0;
1037 bt_list_for_each_entry(iter
, &enumerator
->u
.enumerator
.values
, siblings
) {
1040 if (iter
->type
!= NODE_UNARY_EXPRESSION
)
1047 switch (iter
->u
.unary_expression
.type
) {
1048 case UNARY_UNSIGNED_CONSTANT
:
1049 *target
= iter
->u
.unary_expression
.u
.unsigned_constant
;
1051 case UNARY_SIGNED_CONSTANT
:
1053 * We don't accept signed constants for enums with unsigned
1056 fprintf(fd
, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__
);
1059 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
1063 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
1072 last
->u
.u
= end
+ 1;
1073 bt_enum_unsigned_insert(enum_declaration
, start
, end
, q
);
1079 struct bt_declaration
*ctf_declaration_enum_visit(FILE *fd
, int depth
,
1081 struct ctf_node
*container_type
,
1082 struct bt_list_head
*enumerator_list
,
1084 struct declaration_scope
*declaration_scope
,
1085 struct ctf_trace
*trace
)
1087 struct bt_declaration
*declaration
;
1088 struct declaration_enum
*enum_declaration
;
1089 struct declaration_integer
*integer_declaration
;
1090 struct last_enum_value last_value
;
1091 struct ctf_node
*iter
;
1095 * For named enum (without body), lookup in
1096 * declaration scope. Don't take reference on enum
1097 * declaration: ref is only taken upon definition.
1103 bt_lookup_enum_declaration(g_quark_from_string(name
),
1105 bt_declaration_ref(&enum_declaration
->p
);
1106 return &enum_declaration
->p
;
1108 /* For unnamed enum, create type */
1109 /* For named enum (with body), create type and add to declaration scope */
1111 if (bt_lookup_enum_declaration(g_quark_from_string(name
),
1112 declaration_scope
)) {
1113 fprintf(fd
, "[error] %s: enum %s already declared in scope\n", __func__
, name
);
1117 if (!container_type
) {
1118 declaration
= bt_lookup_declaration(g_quark_from_static_string("int"),
1121 fprintf(fd
, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__
);
1125 declaration
= ctf_type_declarator_visit(fd
, depth
,
1132 fprintf(fd
, "[error] %s: unable to create container type for enumeration\n", __func__
);
1135 if (declaration
->id
!= CTF_TYPE_INTEGER
) {
1136 fprintf(fd
, "[error] %s: container type for enumeration is not integer\n", __func__
);
1139 integer_declaration
= container_of(declaration
, struct declaration_integer
, p
);
1140 enum_declaration
= bt_enum_declaration_new(integer_declaration
);
1141 bt_declaration_unref(&integer_declaration
->p
); /* leave ref to enum */
1142 if (enum_declaration
->integer_declaration
->signedness
) {
1147 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
1150 ret
= ctf_enumerator_list_visit(fd
, depth
+ 1, iter
, enum_declaration
,
1158 ret
= bt_register_enum_declaration(g_quark_from_string(name
),
1163 bt_declaration_unref(&enum_declaration
->p
);
1165 return &enum_declaration
->p
;
1168 enum_declaration
->p
.declaration_free(&enum_declaration
->p
);
1173 struct bt_declaration
*ctf_declaration_type_specifier_visit(FILE *fd
, int depth
,
1174 struct ctf_node
*type_specifier_list
,
1175 struct declaration_scope
*declaration_scope
)
1178 struct bt_declaration
*declaration
;
1183 str
= g_string_new("");
1184 ret
= visit_type_specifier_list(fd
, type_specifier_list
, str
);
1186 (void) g_string_free(str
, TRUE
);
1189 str_c
= g_string_free(str
, FALSE
);
1190 id_q
= g_quark_from_string(str_c
);
1192 declaration
= bt_lookup_declaration(id_q
, declaration_scope
);
1195 bt_declaration_ref(declaration
);
1200 * Returns 0/1 boolean, or < 0 on error.
1203 int get_boolean(FILE *fd
, int depth
, struct ctf_node
*unary_expression
)
1205 if (unary_expression
->type
!= NODE_UNARY_EXPRESSION
) {
1206 fprintf(fd
, "[error] %s: expecting unary expression\n",
1210 switch (unary_expression
->u
.unary_expression
.type
) {
1211 case UNARY_UNSIGNED_CONSTANT
:
1212 if (unary_expression
->u
.unary_expression
.u
.unsigned_constant
== 0)
1216 case UNARY_SIGNED_CONSTANT
:
1217 if (unary_expression
->u
.unary_expression
.u
.signed_constant
== 0)
1222 if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "true"))
1224 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "TRUE"))
1226 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "false"))
1228 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "FALSE"))
1231 fprintf(fd
, "[error] %s: unexpected string \"%s\"\n",
1232 __func__
, unary_expression
->u
.unary_expression
.u
.string
);
1237 fprintf(fd
, "[error] %s: unexpected unary expression type\n",
1245 int get_trace_byte_order(FILE *fd
, int depth
, struct ctf_node
*unary_expression
)
1249 if (unary_expression
->u
.unary_expression
.type
!= UNARY_STRING
) {
1250 fprintf(fd
, "[error] %s: byte_order: expecting string\n",
1254 if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "be"))
1255 byte_order
= BIG_ENDIAN
;
1256 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "le"))
1257 byte_order
= LITTLE_ENDIAN
;
1259 fprintf(fd
, "[error] %s: unexpected string \"%s\". Should be \"be\" or \"le\".\n",
1260 __func__
, unary_expression
->u
.unary_expression
.u
.string
);
1267 int get_byte_order(FILE *fd
, int depth
, struct ctf_node
*unary_expression
,
1268 struct ctf_trace
*trace
)
1272 if (unary_expression
->u
.unary_expression
.type
!= UNARY_STRING
) {
1273 fprintf(fd
, "[error] %s: byte_order: expecting string\n",
1277 if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "native"))
1278 byte_order
= trace
->byte_order
;
1279 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "network"))
1280 byte_order
= BIG_ENDIAN
;
1281 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "be"))
1282 byte_order
= BIG_ENDIAN
;
1283 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "le"))
1284 byte_order
= LITTLE_ENDIAN
;
1286 fprintf(fd
, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1287 __func__
, unary_expression
->u
.unary_expression
.u
.string
);
1294 struct bt_declaration
*ctf_declaration_integer_visit(FILE *fd
, int depth
,
1295 struct bt_list_head
*expressions
,
1296 struct ctf_trace
*trace
)
1298 struct ctf_node
*expression
;
1299 uint64_t alignment
= 1, size
= 0;
1300 int byte_order
= trace
->byte_order
;
1302 int has_alignment
= 0, has_size
= 0;
1304 enum ctf_string_encoding encoding
= CTF_STRING_NONE
;
1305 struct ctf_clock
*clock
= NULL
;
1306 struct declaration_integer
*integer_declaration
;
1308 bt_list_for_each_entry(expression
, expressions
, siblings
) {
1309 struct ctf_node
*left
, *right
;
1311 left
= _bt_list_first_entry(&expression
->u
.ctf_expression
.left
, struct ctf_node
, siblings
);
1312 right
= _bt_list_first_entry(&expression
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
1313 if (left
->u
.unary_expression
.type
!= UNARY_STRING
)
1315 if (!strcmp(left
->u
.unary_expression
.u
.string
, "signed")) {
1316 signedness
= get_boolean(fd
, depth
, right
);
1319 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
1320 byte_order
= get_byte_order(fd
, depth
, right
, trace
);
1323 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "size")) {
1324 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1325 fprintf(fd
, "[error] %s: size: expecting unsigned constant\n",
1329 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
1331 fprintf(fd
, "[error] %s: integer size: expecting non-zero constant\n",
1336 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "align")) {
1337 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1338 fprintf(fd
, "[error] %s: align: expecting unsigned constant\n",
1342 alignment
= right
->u
.unary_expression
.u
.unsigned_constant
;
1343 /* Make sure alignment is a power of two */
1344 if (alignment
== 0 || (alignment
& (alignment
- 1)) != 0) {
1345 fprintf(fd
, "[error] %s: align: expecting power of two\n",
1350 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "base")) {
1351 switch (right
->u
.unary_expression
.type
) {
1352 case UNARY_UNSIGNED_CONSTANT
:
1353 switch (right
->u
.unary_expression
.u
.unsigned_constant
) {
1358 base
= right
->u
.unary_expression
.u
.unsigned_constant
;
1361 fprintf(fd
, "[error] %s: base not supported (%" PRIu64
")\n",
1362 __func__
, right
->u
.unary_expression
.u
.unsigned_constant
);
1368 char *s_right
= concatenate_unary_strings(&expression
->u
.ctf_expression
.right
);
1370 fprintf(fd
, "[error] %s: unexpected unary expression for integer base\n", __func__
);
1374 if (!strcmp(s_right
, "decimal") || !strcmp(s_right
, "dec") || !strcmp(s_right
, "d")
1375 || !strcmp(s_right
, "i") || !strcmp(s_right
, "u")) {
1377 } else if (!strcmp(s_right
, "hexadecimal") || !strcmp(s_right
, "hex")
1378 || !strcmp(s_right
, "x") || !strcmp(s_right
, "X")
1379 || !strcmp(s_right
, "p")) {
1381 } else if (!strcmp(s_right
, "octal") || !strcmp(s_right
, "oct")
1382 || !strcmp(s_right
, "o")) {
1384 } else if (!strcmp(s_right
, "binary") || !strcmp(s_right
, "b")) {
1387 fprintf(fd
, "[error] %s: unexpected expression for integer base (%s)\n", __func__
, s_right
);
1396 fprintf(fd
, "[error] %s: base: expecting unsigned constant or unary string\n",
1400 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
1403 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
1404 fprintf(fd
, "[error] %s: encoding: expecting unary string\n",
1408 s_right
= concatenate_unary_strings(&expression
->u
.ctf_expression
.right
);
1410 fprintf(fd
, "[error] %s: unexpected unary expression for integer base\n", __func__
);
1414 if (!strcmp(s_right
, "UTF8")
1415 || !strcmp(s_right
, "utf8")
1416 || !strcmp(s_right
, "utf-8")
1417 || !strcmp(s_right
, "UTF-8"))
1418 encoding
= CTF_STRING_UTF8
;
1419 else if (!strcmp(s_right
, "ASCII")
1420 || !strcmp(s_right
, "ascii"))
1421 encoding
= CTF_STRING_ASCII
;
1422 else if (!strcmp(s_right
, "none"))
1423 encoding
= CTF_STRING_NONE
;
1425 fprintf(fd
, "[error] %s: unknown string encoding \"%s\"\n", __func__
, s_right
);
1430 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "map")) {
1433 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
1434 fprintf(fd
, "[error] %s: map: expecting identifier\n",
1438 /* currently only support clock.name.value */
1439 clock_name
= get_map_clock_name_value(&expression
->u
.ctf_expression
.right
);
1443 s_right
= concatenate_unary_strings(&expression
->u
.ctf_expression
.right
);
1445 fprintf(fd
, "[error] %s: unexpected unary expression for integer map\n", __func__
);
1449 fprintf(fd
, "[warning] %s: unknown map %s in integer declaration\n", __func__
,
1454 clock
= trace_clock_lookup(trace
, clock_name
);
1456 fprintf(fd
, "[error] %s: map: unable to find clock %s declaration\n",
1457 __func__
, g_quark_to_string(clock_name
));
1461 fprintf(fd
, "[warning] %s: unknown attribute name %s\n",
1462 __func__
, left
->u
.unary_expression
.u
.string
);
1463 /* Fall-through after warning */
1467 fprintf(fd
, "[error] %s: missing size attribute\n", __func__
);
1470 if (!has_alignment
) {
1471 if (size
% CHAR_BIT
) {
1472 /* bit-packed alignment */
1475 /* byte-packed alignment */
1476 alignment
= CHAR_BIT
;
1479 integer_declaration
= bt_integer_declaration_new(size
,
1480 byte_order
, signedness
, alignment
,
1481 base
, encoding
, clock
);
1482 return &integer_declaration
->p
;
1486 struct bt_declaration
*ctf_declaration_floating_point_visit(FILE *fd
, int depth
,
1487 struct bt_list_head
*expressions
,
1488 struct ctf_trace
*trace
)
1490 struct ctf_node
*expression
;
1491 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
1492 int byte_order
= trace
->byte_order
, has_alignment
= 0,
1493 has_exp_dig
= 0, has_mant_dig
= 0;
1494 struct declaration_float
*float_declaration
;
1496 bt_list_for_each_entry(expression
, expressions
, siblings
) {
1497 struct ctf_node
*left
, *right
;
1499 left
= _bt_list_first_entry(&expression
->u
.ctf_expression
.left
, struct ctf_node
, siblings
);
1500 right
= _bt_list_first_entry(&expression
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
1501 if (left
->u
.unary_expression
.type
!= UNARY_STRING
)
1503 if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
1504 byte_order
= get_byte_order(fd
, depth
, right
, trace
);
1507 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "exp_dig")) {
1508 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1509 fprintf(fd
, "[error] %s: exp_dig: expecting unsigned constant\n",
1513 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
1515 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "mant_dig")) {
1516 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1517 fprintf(fd
, "[error] %s: mant_dig: expecting unsigned constant\n",
1521 mant_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
1523 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "align")) {
1524 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1525 fprintf(fd
, "[error] %s: align: expecting unsigned constant\n",
1529 alignment
= right
->u
.unary_expression
.u
.unsigned_constant
;
1530 /* Make sure alignment is a power of two */
1531 if (alignment
== 0 || (alignment
& (alignment
- 1)) != 0) {
1532 fprintf(fd
, "[error] %s: align: expecting power of two\n",
1538 fprintf(fd
, "[warning] %s: unknown attribute name %s\n",
1539 __func__
, left
->u
.unary_expression
.u
.string
);
1540 /* Fall-through after warning */
1543 if (!has_mant_dig
) {
1544 fprintf(fd
, "[error] %s: missing mant_dig attribute\n", __func__
);
1548 fprintf(fd
, "[error] %s: missing exp_dig attribute\n", __func__
);
1551 if (!has_alignment
) {
1552 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
1553 /* bit-packed alignment */
1556 /* byte-packed alignment */
1557 alignment
= CHAR_BIT
;
1560 float_declaration
= bt_float_declaration_new(mant_dig
, exp_dig
,
1561 byte_order
, alignment
);
1562 return &float_declaration
->p
;
1566 struct bt_declaration
*ctf_declaration_string_visit(FILE *fd
, int depth
,
1567 struct bt_list_head
*expressions
,
1568 struct ctf_trace
*trace
)
1570 struct ctf_node
*expression
;
1571 const char *encoding_c
= NULL
;
1572 enum ctf_string_encoding encoding
= CTF_STRING_UTF8
;
1573 struct declaration_string
*string_declaration
;
1575 bt_list_for_each_entry(expression
, expressions
, siblings
) {
1576 struct ctf_node
*left
, *right
;
1578 left
= _bt_list_first_entry(&expression
->u
.ctf_expression
.left
, struct ctf_node
, siblings
);
1579 right
= _bt_list_first_entry(&expression
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
1580 if (left
->u
.unary_expression
.type
!= UNARY_STRING
)
1582 if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
1583 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
1584 fprintf(fd
, "[error] %s: encoding: expecting string\n",
1588 encoding_c
= right
->u
.unary_expression
.u
.string
;
1590 fprintf(fd
, "[warning] %s: unknown attribute name %s\n",
1591 __func__
, left
->u
.unary_expression
.u
.string
);
1592 /* Fall-through after warning */
1595 if (encoding_c
&& !strcmp(encoding_c
, "ASCII"))
1596 encoding
= CTF_STRING_ASCII
;
1597 string_declaration
= bt_string_declaration_new(encoding
);
1598 return &string_declaration
->p
;
1603 struct bt_declaration
*ctf_type_specifier_list_visit(FILE *fd
,
1604 int depth
, struct ctf_node
*type_specifier_list
,
1605 struct declaration_scope
*declaration_scope
,
1606 struct ctf_trace
*trace
)
1608 struct ctf_node
*first
;
1609 struct ctf_node
*node
;
1611 if (type_specifier_list
->type
!= NODE_TYPE_SPECIFIER_LIST
)
1614 first
= _bt_list_first_entry(&type_specifier_list
->u
.type_specifier_list
.head
, struct ctf_node
, siblings
);
1616 if (first
->type
!= NODE_TYPE_SPECIFIER
)
1619 node
= first
->u
.type_specifier
.node
;
1621 switch (first
->u
.type_specifier
.type
) {
1622 case TYPESPEC_FLOATING_POINT
:
1623 return ctf_declaration_floating_point_visit(fd
, depth
,
1624 &node
->u
.floating_point
.expressions
, trace
);
1625 case TYPESPEC_INTEGER
:
1626 return ctf_declaration_integer_visit(fd
, depth
,
1627 &node
->u
.integer
.expressions
, trace
);
1628 case TYPESPEC_STRING
:
1629 return ctf_declaration_string_visit(fd
, depth
,
1630 &node
->u
.string
.expressions
, trace
);
1631 case TYPESPEC_STRUCT
:
1632 return ctf_declaration_struct_visit(fd
, depth
,
1633 node
->u
._struct
.name
,
1634 &node
->u
._struct
.declaration_list
,
1635 node
->u
._struct
.has_body
,
1636 &node
->u
._struct
.min_align
,
1639 case TYPESPEC_VARIANT
:
1640 return ctf_declaration_variant_visit(fd
, depth
,
1641 node
->u
.variant
.name
,
1642 node
->u
.variant
.choice
,
1643 &node
->u
.variant
.declaration_list
,
1644 node
->u
.variant
.has_body
,
1648 return ctf_declaration_enum_visit(fd
, depth
,
1649 node
->u
._enum
.enum_id
,
1650 node
->u
._enum
.container_type
,
1651 &node
->u
._enum
.enumerator_list
,
1652 node
->u
._enum
.has_body
,
1658 case TYPESPEC_SHORT
:
1661 case TYPESPEC_FLOAT
:
1662 case TYPESPEC_DOUBLE
:
1663 case TYPESPEC_SIGNED
:
1664 case TYPESPEC_UNSIGNED
:
1666 case TYPESPEC_COMPLEX
:
1667 case TYPESPEC_IMAGINARY
:
1668 case TYPESPEC_CONST
:
1669 case TYPESPEC_ID_TYPE
:
1670 return ctf_declaration_type_specifier_visit(fd
, depth
,
1671 type_specifier_list
, declaration_scope
);
1673 fprintf(fd
, "[error] %s: unexpected node type %d\n", __func__
, (int) first
->u
.type_specifier
.type
);
1679 int ctf_event_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_event_declaration
*event
, struct ctf_trace
*trace
)
1683 switch (node
->type
) {
1685 ret
= ctf_typedef_visit(fd
, depth
+ 1,
1686 event
->declaration_scope
,
1687 node
->u
._typedef
.type_specifier_list
,
1688 &node
->u
._typedef
.type_declarators
,
1693 case NODE_TYPEALIAS
:
1694 ret
= ctf_typealias_visit(fd
, depth
+ 1,
1695 event
->declaration_scope
,
1696 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
1701 case NODE_CTF_EXPRESSION
:
1705 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
1708 if (!strcmp(left
, "name")) {
1711 if (CTF_EVENT_FIELD_IS_SET(event
, name
)) {
1712 fprintf(fd
, "[error] %s: name already declared in event declaration\n", __func__
);
1716 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
1718 fprintf(fd
, "[error] %s: unexpected unary expression for event name\n", __func__
);
1722 event
->name
= g_quark_from_string(right
);
1724 CTF_EVENT_SET_FIELD(event
, name
);
1725 } else if (!strcmp(left
, "id")) {
1726 if (CTF_EVENT_FIELD_IS_SET(event
, id
)) {
1727 fprintf(fd
, "[error] %s: id already declared in event declaration\n", __func__
);
1731 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->id
);
1733 fprintf(fd
, "[error] %s: unexpected unary expression for event id\n", __func__
);
1737 CTF_EVENT_SET_FIELD(event
, id
);
1738 } else if (!strcmp(left
, "stream_id")) {
1739 if (CTF_EVENT_FIELD_IS_SET(event
, stream_id
)) {
1740 fprintf(fd
, "[error] %s: stream_id already declared in event declaration\n", __func__
);
1744 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->stream_id
);
1746 fprintf(fd
, "[error] %s: unexpected unary expression for event stream_id\n", __func__
);
1750 event
->stream
= trace_stream_lookup(trace
, event
->stream_id
);
1751 if (!event
->stream
) {
1752 fprintf(fd
, "[error] %s: stream id %" PRIu64
" cannot be found\n", __func__
, event
->stream_id
);
1756 CTF_EVENT_SET_FIELD(event
, stream_id
);
1757 } else if (!strcmp(left
, "context")) {
1758 struct bt_declaration
*declaration
;
1760 if (event
->context_decl
) {
1761 fprintf(fd
, "[error] %s: context already declared in event declaration\n", __func__
);
1765 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1766 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1767 struct ctf_node
, siblings
),
1768 event
->declaration_scope
, trace
);
1773 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1777 event
->context_decl
= container_of(declaration
, struct declaration_struct
, p
);
1778 } else if (!strcmp(left
, "fields")) {
1779 struct bt_declaration
*declaration
;
1781 if (event
->fields_decl
) {
1782 fprintf(fd
, "[error] %s: fields already declared in event declaration\n", __func__
);
1786 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1787 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1788 struct ctf_node
, siblings
),
1789 event
->declaration_scope
, trace
);
1794 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1798 event
->fields_decl
= container_of(declaration
, struct declaration_struct
, p
);
1799 } else if (!strcmp(left
, "loglevel")) {
1800 int64_t loglevel
= -1;
1802 if (CTF_EVENT_FIELD_IS_SET(event
, loglevel
)) {
1803 fprintf(fd
, "[error] %s: loglevel already declared in event declaration\n", __func__
);
1807 ret
= get_unary_signed(&node
->u
.ctf_expression
.right
, &loglevel
);
1809 fprintf(fd
, "[error] %s: unexpected unary expression for event loglevel\n", __func__
);
1813 event
->loglevel
= (int) loglevel
;
1814 CTF_EVENT_SET_FIELD(event
, loglevel
);
1815 } else if (!strcmp(left
, "model.emf.uri")) {
1818 if (CTF_EVENT_FIELD_IS_SET(event
, model_emf_uri
)) {
1819 fprintf(fd
, "[error] %s: model.emf.uri already declared in event declaration\n", __func__
);
1823 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
1825 fprintf(fd
, "[error] %s: unexpected unary expression for event model.emf.uri\n", __func__
);
1829 event
->model_emf_uri
= g_quark_from_string(right
);
1831 CTF_EVENT_SET_FIELD(event
, model_emf_uri
);
1833 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__
, left
);
1834 /* Fall-through after warning */
1842 /* TODO: declaration specifier should be added. */
1849 int ctf_event_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
1850 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
1853 struct ctf_node
*iter
;
1854 struct ctf_event_declaration
*event
;
1855 struct bt_ctf_event_decl
*event_decl
;
1861 event_decl
= g_new0(struct bt_ctf_event_decl
, 1);
1862 event
= &event_decl
->parent
;
1863 event
->declaration_scope
= bt_new_declaration_scope(parent_declaration_scope
);
1864 event
->loglevel
= -1;
1865 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
1866 ret
= ctf_event_declaration_visit(fd
, depth
+ 1, iter
, event
, trace
);
1870 if (!CTF_EVENT_FIELD_IS_SET(event
, name
)) {
1872 fprintf(fd
, "[error] %s: missing name field in event declaration\n", __func__
);
1875 if (!CTF_EVENT_FIELD_IS_SET(event
, stream_id
)) {
1876 /* Allow missing stream_id if there is only a single stream */
1877 switch (trace
->streams
->len
) {
1878 case 0: /* Create stream if there was none. */
1879 ret
= ctf_stream_visit(fd
, depth
, NULL
, trace
->root_declaration_scope
, trace
);
1884 event
->stream_id
= 0;
1885 event
->stream
= trace_stream_lookup(trace
, event
->stream_id
);
1889 fprintf(fd
, "[error] %s: missing stream_id field in event declaration\n", __func__
);
1893 /* Allow only one event without id per stream */
1894 if (!CTF_EVENT_FIELD_IS_SET(event
, id
)
1895 && event
->stream
->events_by_id
->len
!= 0) {
1897 fprintf(fd
, "[error] %s: missing id field in event declaration\n", __func__
);
1900 /* Disallow re-using the same event ID in the same stream */
1901 if (stream_event_lookup(event
->stream
, event
->id
)) {
1903 fprintf(fd
, "[error] %s: event ID %" PRIu64
" used more than once in stream %" PRIu64
"\n",
1904 __func__
, event
->id
, event
->stream_id
);
1907 if (event
->stream
->events_by_id
->len
<= event
->id
)
1908 g_ptr_array_set_size(event
->stream
->events_by_id
, event
->id
+ 1);
1909 g_ptr_array_index(event
->stream
->events_by_id
, event
->id
) = event
;
1910 g_hash_table_insert(event
->stream
->event_quark_to_id
,
1911 (gpointer
) (unsigned long) event
->name
,
1913 g_ptr_array_add(trace
->event_declarations
, event_decl
);
1917 if (event
->fields_decl
)
1918 bt_declaration_unref(&event
->fields_decl
->p
);
1919 if (event
->context_decl
)
1920 bt_declaration_unref(&event
->context_decl
->p
);
1921 bt_free_declaration_scope(event
->declaration_scope
);
1928 int ctf_stream_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_stream_declaration
*stream
, struct ctf_trace
*trace
)
1932 switch (node
->type
) {
1934 ret
= ctf_typedef_visit(fd
, depth
+ 1,
1935 stream
->declaration_scope
,
1936 node
->u
._typedef
.type_specifier_list
,
1937 &node
->u
._typedef
.type_declarators
,
1942 case NODE_TYPEALIAS
:
1943 ret
= ctf_typealias_visit(fd
, depth
+ 1,
1944 stream
->declaration_scope
,
1945 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
1950 case NODE_CTF_EXPRESSION
:
1954 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
1957 if (!strcmp(left
, "id")) {
1958 if (CTF_STREAM_FIELD_IS_SET(stream
, stream_id
)) {
1959 fprintf(fd
, "[error] %s: id already declared in stream declaration\n", __func__
);
1963 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &stream
->stream_id
);
1965 fprintf(fd
, "[error] %s: unexpected unary expression for stream id\n", __func__
);
1969 CTF_STREAM_SET_FIELD(stream
, stream_id
);
1970 } else if (!strcmp(left
, "event.header")) {
1971 struct bt_declaration
*declaration
;
1973 if (stream
->event_header_decl
) {
1974 fprintf(fd
, "[error] %s: event.header already declared in stream declaration\n", __func__
);
1978 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1979 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1980 struct ctf_node
, siblings
),
1981 stream
->declaration_scope
, trace
);
1986 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1990 stream
->event_header_decl
= container_of(declaration
, struct declaration_struct
, p
);
1991 } else if (!strcmp(left
, "event.context")) {
1992 struct bt_declaration
*declaration
;
1994 if (stream
->event_context_decl
) {
1995 fprintf(fd
, "[error] %s: event.context already declared in stream declaration\n", __func__
);
1999 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
2000 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
2001 struct ctf_node
, siblings
),
2002 stream
->declaration_scope
, trace
);
2007 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
2011 stream
->event_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
2012 } else if (!strcmp(left
, "packet.context")) {
2013 struct bt_declaration
*declaration
;
2015 if (stream
->packet_context_decl
) {
2016 fprintf(fd
, "[error] %s: packet.context already declared in stream declaration\n", __func__
);
2020 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
2021 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
2022 struct ctf_node
, siblings
),
2023 stream
->declaration_scope
, trace
);
2028 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
2032 stream
->packet_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
2034 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__
, left
);
2035 /* Fall-through after warning */
2044 /* TODO: declaration specifier should be added. */
2051 int ctf_stream_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2052 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
2055 struct ctf_node
*iter
;
2056 struct ctf_stream_declaration
*stream
;
2064 stream
= g_new0(struct ctf_stream_declaration
, 1);
2065 stream
->declaration_scope
= bt_new_declaration_scope(parent_declaration_scope
);
2066 stream
->events_by_id
= g_ptr_array_new();
2067 stream
->event_quark_to_id
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
2068 stream
->streams
= g_ptr_array_new();
2070 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
2071 ret
= ctf_stream_declaration_visit(fd
, depth
+ 1, iter
, stream
, trace
);
2076 if (CTF_STREAM_FIELD_IS_SET(stream
, stream_id
)) {
2077 /* check that packet header has stream_id field. */
2078 if (!trace
->packet_header_decl
2079 || bt_struct_declaration_lookup_field_index(trace
->packet_header_decl
, g_quark_from_static_string("stream_id")) < 0) {
2081 fprintf(fd
, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__
);
2085 /* Allow only one id-less stream */
2086 if (trace
->streams
->len
!= 0) {
2088 fprintf(fd
, "[error] %s: missing id field in stream declaration\n", __func__
);
2091 stream
->stream_id
= 0;
2093 if (trace
->streams
->len
<= stream
->stream_id
)
2094 g_ptr_array_set_size(trace
->streams
, stream
->stream_id
+ 1);
2095 g_ptr_array_index(trace
->streams
, stream
->stream_id
) = stream
;
2096 stream
->trace
= trace
;
2101 if (stream
->event_header_decl
)
2102 bt_declaration_unref(&stream
->event_header_decl
->p
);
2103 if (stream
->event_context_decl
)
2104 bt_declaration_unref(&stream
->event_context_decl
->p
);
2105 if (stream
->packet_context_decl
)
2106 bt_declaration_unref(&stream
->packet_context_decl
->p
);
2107 g_ptr_array_free(stream
->streams
, TRUE
);
2108 g_ptr_array_free(stream
->events_by_id
, TRUE
);
2109 g_hash_table_destroy(stream
->event_quark_to_id
);
2110 bt_free_declaration_scope(stream
->declaration_scope
);
2116 int ctf_trace_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2120 switch (node
->type
) {
2122 ret
= ctf_typedef_visit(fd
, depth
+ 1,
2123 trace
->declaration_scope
,
2124 node
->u
._typedef
.type_specifier_list
,
2125 &node
->u
._typedef
.type_declarators
,
2130 case NODE_TYPEALIAS
:
2131 ret
= ctf_typealias_visit(fd
, depth
+ 1,
2132 trace
->declaration_scope
,
2133 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
2138 case NODE_CTF_EXPRESSION
:
2142 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2145 if (!strcmp(left
, "major")) {
2146 if (CTF_TRACE_FIELD_IS_SET(trace
, major
)) {
2147 fprintf(fd
, "[error] %s: major already declared in trace declaration\n", __func__
);
2151 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->major
);
2153 fprintf(fd
, "[error] %s: unexpected unary expression for trace major number\n", __func__
);
2157 CTF_TRACE_SET_FIELD(trace
, major
);
2158 } else if (!strcmp(left
, "minor")) {
2159 if (CTF_TRACE_FIELD_IS_SET(trace
, minor
)) {
2160 fprintf(fd
, "[error] %s: minor already declared in trace declaration\n", __func__
);
2164 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->minor
);
2166 fprintf(fd
, "[error] %s: unexpected unary expression for trace minor number\n", __func__
);
2170 CTF_TRACE_SET_FIELD(trace
, minor
);
2171 } else if (!strcmp(left
, "uuid")) {
2172 unsigned char uuid
[BABELTRACE_UUID_LEN
];
2174 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
, uuid
);
2176 fprintf(fd
, "[error] %s: unexpected unary expression for trace uuid\n", __func__
);
2180 if (CTF_TRACE_FIELD_IS_SET(trace
, uuid
)
2181 && bt_uuid_compare(uuid
, trace
->uuid
)) {
2182 fprintf(fd
, "[error] %s: uuid mismatch\n", __func__
);
2186 memcpy(trace
->uuid
, uuid
, sizeof(uuid
));
2188 CTF_TRACE_SET_FIELD(trace
, uuid
);
2189 } else if (!strcmp(left
, "byte_order")) {
2190 struct ctf_node
*right
;
2193 right
= _bt_list_first_entry(&node
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
2194 byte_order
= get_trace_byte_order(fd
, depth
, right
);
2195 if (byte_order
< 0) {
2200 if (CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)
2201 && byte_order
!= trace
->byte_order
) {
2202 fprintf(fd
, "[error] %s: endianness mismatch\n", __func__
);
2206 if (byte_order
!= trace
->byte_order
) {
2207 trace
->byte_order
= byte_order
;
2209 * We need to restart
2210 * construction of the
2211 * intermediate representation.
2213 trace
->field_mask
= 0;
2214 CTF_TRACE_SET_FIELD(trace
, byte_order
);
2219 CTF_TRACE_SET_FIELD(trace
, byte_order
);
2220 } else if (!strcmp(left
, "packet.header")) {
2221 struct bt_declaration
*declaration
;
2223 if (trace
->packet_header_decl
) {
2224 fprintf(fd
, "[error] %s: packet.header already declared in trace declaration\n", __func__
);
2228 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
2229 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
2230 struct ctf_node
, siblings
),
2231 trace
->declaration_scope
, trace
);
2236 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
2240 trace
->packet_header_decl
= container_of(declaration
, struct declaration_struct
, p
);
2242 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__
, left
);
2251 /* TODO: declaration specifier should be added. */
2258 int ctf_trace_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2261 struct ctf_node
*iter
;
2263 if (!trace
->restart_root_decl
&& node
->visited
)
2267 if (trace
->declaration_scope
)
2270 trace
->declaration_scope
= bt_new_declaration_scope(trace
->root_declaration_scope
);
2271 trace
->streams
= g_ptr_array_new();
2272 trace
->event_declarations
= g_ptr_array_new();
2273 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
2274 ret
= ctf_trace_declaration_visit(fd
, depth
+ 1, iter
, trace
);
2278 if (!CTF_TRACE_FIELD_IS_SET(trace
, major
)) {
2280 fprintf(fd
, "[error] %s: missing major field in trace declaration\n", __func__
);
2283 if (!CTF_TRACE_FIELD_IS_SET(trace
, minor
)) {
2285 fprintf(fd
, "[error] %s: missing minor field in trace declaration\n", __func__
);
2288 if (!CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)) {
2290 fprintf(fd
, "[error] %s: missing byte_order field in trace declaration\n", __func__
);
2294 if (!CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)) {
2295 /* check that the packet header contains a "magic" field */
2296 if (!trace
->packet_header_decl
2297 || bt_struct_declaration_lookup_field_index(trace
->packet_header_decl
, g_quark_from_static_string("magic")) < 0) {
2299 fprintf(fd
, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__
);
2306 if (trace
->packet_header_decl
) {
2307 bt_declaration_unref(&trace
->packet_header_decl
->p
);
2308 trace
->packet_header_decl
= NULL
;
2310 g_ptr_array_free(trace
->streams
, TRUE
);
2311 g_ptr_array_free(trace
->event_declarations
, TRUE
);
2312 bt_free_declaration_scope(trace
->declaration_scope
);
2313 trace
->declaration_scope
= NULL
;
2318 int ctf_clock_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2319 struct ctf_clock
*clock
, struct ctf_trace
*trace
)
2323 switch (node
->type
) {
2324 case NODE_CTF_EXPRESSION
:
2328 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2331 if (!strcmp(left
, "name")) {
2334 if (CTF_CLOCK_FIELD_IS_SET(clock
, name
)) {
2335 fprintf(fd
, "[error] %s: name already declared in clock declaration\n", __func__
);
2339 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2341 fprintf(fd
, "[error] %s: unexpected unary expression for clock name\n", __func__
);
2345 clock
->name
= g_quark_from_string(right
);
2347 CTF_CLOCK_SET_FIELD(clock
, name
);
2348 } else if (!strcmp(left
, "uuid")) {
2352 fprintf(fd
, "[error] %s: uuid already declared in clock declaration\n", __func__
);
2356 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2358 fprintf(fd
, "[error] %s: unexpected unary expression for clock uuid\n", __func__
);
2362 clock
->uuid
= g_quark_from_string(right
);
2364 } else if (!strcmp(left
, "description")) {
2367 if (clock
->description
) {
2368 fprintf(fd
, "[warning] %s: duplicated clock description\n", __func__
);
2369 goto error
; /* ret is 0, so not an actual error, just warn. */
2371 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2373 fprintf(fd
, "[warning] %s: unexpected unary expression for clock description\n", __func__
);
2374 goto error
; /* ret is 0, so not an actual error, just warn. */
2376 clock
->description
= right
;
2377 } else if (!strcmp(left
, "freq")) {
2378 if (CTF_CLOCK_FIELD_IS_SET(clock
, freq
)) {
2379 fprintf(fd
, "[error] %s: freq already declared in clock declaration\n", __func__
);
2383 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->freq
);
2385 fprintf(fd
, "[error] %s: unexpected unary expression for clock freq\n", __func__
);
2389 CTF_CLOCK_SET_FIELD(clock
, freq
);
2390 } else if (!strcmp(left
, "precision")) {
2391 if (clock
->precision
) {
2392 fprintf(fd
, "[error] %s: precision already declared in clock declaration\n", __func__
);
2396 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->precision
);
2398 fprintf(fd
, "[error] %s: unexpected unary expression for clock precision\n", __func__
);
2402 } else if (!strcmp(left
, "offset_s")) {
2403 if (clock
->offset_s
) {
2404 fprintf(fd
, "[error] %s: offset_s already declared in clock declaration\n", __func__
);
2408 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->offset_s
);
2410 fprintf(fd
, "[error] %s: unexpected unary expression for clock offset_s\n", __func__
);
2414 } else if (!strcmp(left
, "offset")) {
2415 if (clock
->offset
) {
2416 fprintf(fd
, "[error] %s: offset already declared in clock declaration\n", __func__
);
2420 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->offset
);
2422 fprintf(fd
, "[error] %s: unexpected unary expression for clock offset\n", __func__
);
2426 } else if (!strcmp(left
, "absolute")) {
2427 struct ctf_node
*right
;
2429 right
= _bt_list_first_entry(&node
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
2430 ret
= get_boolean(fd
, depth
, right
);
2432 fprintf(fd
, "[error] %s: unexpected \"absolute\" right member\n", __func__
);
2436 clock
->absolute
= ret
;
2439 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__
, left
);
2448 /* TODO: declaration specifier should be added. */
2455 int ctf_clock_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2458 struct ctf_node
*iter
;
2459 struct ctf_clock
*clock
;
2465 clock
= g_new0(struct ctf_clock
, 1);
2466 /* Default clock frequency is set to 1000000000 */
2467 clock
->freq
= 1000000000ULL;
2468 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
2469 ret
= ctf_clock_declaration_visit(fd
, depth
+ 1, iter
, clock
, trace
);
2473 if (opt_clock_force_correlate
) {
2475 * User requested to forcibly correlate the clock
2476 * sources, even if we have no correlation
2479 if (!clock
->absolute
) {
2480 fprintf(fd
, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2482 clock
->absolute
= 1;
2484 if (!CTF_CLOCK_FIELD_IS_SET(clock
, name
)) {
2486 fprintf(fd
, "[error] %s: missing name field in clock declaration\n", __func__
);
2489 if (g_hash_table_size(trace
->parent
.clocks
) > 0) {
2490 fprintf(fd
, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
2494 trace
->parent
.single_clock
= clock
;
2495 g_hash_table_insert(trace
->parent
.clocks
, (gpointer
) (unsigned long) clock
->name
, clock
);
2499 g_free(clock
->description
);
2505 void ctf_clock_default(FILE *fd
, int depth
, struct ctf_trace
*trace
)
2507 struct ctf_clock
*clock
;
2509 clock
= g_new0(struct ctf_clock
, 1);
2510 clock
->name
= g_quark_from_string("monotonic");
2512 clock
->description
= g_strdup("Default clock");
2513 /* Default clock frequency is set to 1000000000 */
2514 clock
->freq
= 1000000000ULL;
2515 if (opt_clock_force_correlate
) {
2517 * User requested to forcibly correlate the clock
2518 * sources, even if we have no correlatation
2521 if (!clock
->absolute
) {
2522 fprintf(fd
, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2524 clock
->absolute
= 1;
2526 clock
->absolute
= 0; /* Not an absolute reference across traces */
2529 trace
->parent
.single_clock
= clock
;
2530 g_hash_table_insert(trace
->parent
.clocks
, (gpointer
) (unsigned long) clock
->name
, clock
);
2534 void clock_free(gpointer data
)
2536 struct ctf_clock
*clock
= data
;
2538 g_free(clock
->description
);
2543 int ctf_callsite_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2544 struct ctf_callsite
*callsite
, struct ctf_trace
*trace
)
2548 switch (node
->type
) {
2549 case NODE_CTF_EXPRESSION
:
2553 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2556 if (!strcmp(left
, "name")) {
2559 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, name
)) {
2560 fprintf(fd
, "[error] %s: name already declared in callsite declaration\n", __func__
);
2564 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2566 fprintf(fd
, "[error] %s: unexpected unary expression for callsite name\n", __func__
);
2570 callsite
->name
= g_quark_from_string(right
);
2572 CTF_CALLSITE_SET_FIELD(callsite
, name
);
2573 } else if (!strcmp(left
, "func")) {
2576 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, func
)) {
2577 fprintf(fd
, "[error] %s: func already declared in callsite declaration\n", __func__
);
2581 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2583 fprintf(fd
, "[error] %s: unexpected unary expression for callsite func\n", __func__
);
2587 callsite
->func
= right
;
2588 CTF_CALLSITE_SET_FIELD(callsite
, func
);
2589 } else if (!strcmp(left
, "file")) {
2592 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, file
)) {
2593 fprintf(fd
, "[error] %s: file already declared in callsite declaration\n", __func__
);
2597 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2599 fprintf(fd
, "[error] %s: unexpected unary expression for callsite file\n", __func__
);
2603 callsite
->file
= right
;
2604 CTF_CALLSITE_SET_FIELD(callsite
, file
);
2605 } else if (!strcmp(left
, "line")) {
2606 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, line
)) {
2607 fprintf(fd
, "[error] %s: line already declared in callsite declaration\n", __func__
);
2611 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &callsite
->line
);
2613 fprintf(fd
, "[error] %s: unexpected unary expression for callsite line\n", __func__
);
2617 CTF_CALLSITE_SET_FIELD(callsite
, line
);
2618 } else if (!strcmp(left
, "ip")) {
2619 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, ip
)) {
2620 fprintf(fd
, "[error] %s: ip already declared in callsite declaration\n", __func__
);
2624 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &callsite
->ip
);
2626 fprintf(fd
, "[error] %s: unexpected unary expression for callsite ip\n", __func__
);
2630 CTF_CALLSITE_SET_FIELD(callsite
, ip
);
2632 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__
, left
);
2641 /* TODO: declaration specifier should be added. */
2648 int ctf_callsite_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2651 struct ctf_node
*iter
;
2652 struct ctf_callsite
*callsite
;
2653 struct ctf_callsite_dups
*cs_dups
;
2659 callsite
= g_new0(struct ctf_callsite
, 1);
2660 bt_list_for_each_entry(iter
, &node
->u
.callsite
.declaration_list
, siblings
) {
2661 ret
= ctf_callsite_declaration_visit(fd
, depth
+ 1, iter
, callsite
, trace
);
2665 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, name
)) {
2667 fprintf(fd
, "[error] %s: missing name field in callsite declaration\n", __func__
);
2670 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, func
)) {
2672 fprintf(fd
, "[error] %s: missing func field in callsite declaration\n", __func__
);
2675 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, file
)) {
2677 fprintf(fd
, "[error] %s: missing file field in callsite declaration\n", __func__
);
2680 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, line
)) {
2682 fprintf(fd
, "[error] %s: missing line field in callsite declaration\n", __func__
);
2686 cs_dups
= g_hash_table_lookup(trace
->callsites
,
2687 (gpointer
) (unsigned long) callsite
->name
);
2689 cs_dups
= g_new0(struct ctf_callsite_dups
, 1);
2690 BT_INIT_LIST_HEAD(&cs_dups
->head
);
2691 g_hash_table_insert(trace
->callsites
,
2692 (gpointer
) (unsigned long) callsite
->name
, cs_dups
);
2694 bt_list_add_tail(&callsite
->node
, &cs_dups
->head
);
2698 g_free(callsite
->func
);
2699 g_free(callsite
->file
);
2705 void callsite_free(gpointer data
)
2707 struct ctf_callsite_dups
*cs_dups
= data
;
2708 struct ctf_callsite
*callsite
, *cs_n
;
2710 bt_list_for_each_entry_safe(callsite
, cs_n
, &cs_dups
->head
, node
) {
2711 g_free(callsite
->func
);
2712 g_free(callsite
->file
);
2719 int ctf_env_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2720 struct ctf_trace
*trace
)
2723 struct ctf_tracer_env
*env
= &trace
->env
;
2725 switch (node
->type
) {
2726 case NODE_CTF_EXPRESSION
:
2730 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2733 if (!strcmp(left
, "vpid")) {
2736 if (env
->vpid
!= -1) {
2737 fprintf(fd
, "[error] %s: vpid already declared in env declaration\n", __func__
);
2738 goto error
; /* ret is 0, so not an actual error, just warn. */
2740 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &v
);
2742 fprintf(fd
, "[error] %s: unexpected unary expression for env vpid\n", __func__
);
2743 goto error
; /* ret is 0, so not an actual error, just warn. */
2745 env
->vpid
= (int) v
;
2746 printf_verbose("env.vpid = %d\n", env
->vpid
);
2747 } else if (!strcmp(left
, "procname")) {