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.
27 #include <babeltrace/babeltrace-internal.h>
28 #include <babeltrace/list.h>
29 #include <babeltrace/types.h>
30 #include <babeltrace/ctf/metadata.h>
31 #include <babeltrace/uuid.h>
32 #include <babeltrace/endian.h>
33 #include <babeltrace/ctf/events-internal.h>
34 #include "ctf-scanner.h"
35 #include "ctf-parser.h"
38 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
40 #define _bt_list_first_entry(ptr, type, member) \
41 bt_list_entry((ptr)->next, type, member)
43 struct last_enum_value
{
50 int opt_clock_force_correlate
;
53 struct declaration
*ctf_type_specifier_list_visit(FILE *fd
,
54 int depth
, struct ctf_node
*type_specifier_list
,
55 struct declaration_scope
*declaration_scope
,
56 struct ctf_trace
*trace
);
59 int ctf_stream_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
60 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
);
63 int is_unary_string(struct bt_list_head
*head
)
65 struct ctf_node
*node
;
67 bt_list_for_each_entry(node
, head
, siblings
) {
68 if (node
->type
!= NODE_UNARY_EXPRESSION
)
70 if (node
->u
.unary_expression
.type
!= UNARY_STRING
)
77 * String returned must be freed by the caller using g_free.
80 char *concatenate_unary_strings(struct bt_list_head
*head
)
82 struct ctf_node
*node
;
86 str
= g_string_new("");
87 bt_list_for_each_entry(node
, head
, siblings
) {
90 assert(node
->type
== NODE_UNARY_EXPRESSION
);
91 assert(node
->u
.unary_expression
.type
== UNARY_STRING
);
92 assert((node
->u
.unary_expression
.link
== UNARY_LINK_UNKNOWN
)
94 switch (node
->u
.unary_expression
.link
) {
96 g_string_append(str
, ".");
99 g_string_append(str
, "->");
101 case UNARY_DOTDOTDOT
:
102 g_string_append(str
, "...");
107 src_string
= node
->u
.unary_expression
.u
.string
;
108 g_string_append(str
, src_string
);
111 return g_string_free(str
, FALSE
);
115 GQuark
get_map_clock_name_value(struct bt_list_head
*head
)
117 struct ctf_node
*node
;
118 const char *name
= NULL
;
121 bt_list_for_each_entry(node
, head
, siblings
) {
124 assert(node
->type
== NODE_UNARY_EXPRESSION
);
125 assert(node
->u
.unary_expression
.type
== UNARY_STRING
);
126 assert((node
->u
.unary_expression
.link
== UNARY_LINK_UNKNOWN
)
128 /* needs to be chained with . */
129 switch (node
->u
.unary_expression
.link
) {
132 case UNARY_ARROWLINK
:
133 case UNARY_DOTDOTDOT
:
138 src_string
= node
->u
.unary_expression
.u
.string
;
140 case 0: if (strcmp("clock", src_string
) != 0) {
144 case 1: name
= src_string
;
146 case 2: if (strcmp("value", src_string
) != 0) {
151 return 0; /* extra identifier, unknown */
155 return g_quark_from_string(name
);
159 int is_unary_unsigned(struct bt_list_head
*head
)
161 struct ctf_node
*node
;
163 bt_list_for_each_entry(node
, head
, siblings
) {
164 if (node
->type
!= NODE_UNARY_EXPRESSION
)
166 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
)
173 int get_unary_unsigned(struct bt_list_head
*head
, uint64_t *value
)
175 struct ctf_node
*node
;
178 bt_list_for_each_entry(node
, head
, siblings
) {
179 assert(node
->type
== NODE_UNARY_EXPRESSION
);
180 assert(node
->u
.unary_expression
.type
== UNARY_UNSIGNED_CONSTANT
);
181 assert(node
->u
.unary_expression
.link
== UNARY_LINK_UNKNOWN
);
183 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
190 int is_unary_signed(struct bt_list_head
*head
)
192 struct ctf_node
*node
;
194 bt_list_for_each_entry(node
, head
, siblings
) {
195 if (node
->type
!= NODE_UNARY_EXPRESSION
)
197 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
)
204 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
206 struct ctf_node
*node
;
209 bt_list_for_each_entry(node
, head
, siblings
) {
210 assert(node
->type
== NODE_UNARY_EXPRESSION
);
211 assert(node
->u
.unary_expression
.type
== UNARY_UNSIGNED_CONSTANT
212 || node
->u
.unary_expression
.type
== UNARY_SIGNED_CONSTANT
);
213 assert(node
->u
.unary_expression
.link
== UNARY_LINK_UNKNOWN
);
215 switch (node
->u
.unary_expression
.type
) {
216 case UNARY_UNSIGNED_CONSTANT
:
217 *value
= (int64_t) node
->u
.unary_expression
.u
.unsigned_constant
;
219 case UNARY_SIGNED_CONSTANT
:
220 *value
= node
->u
.unary_expression
.u
.signed_constant
;
231 int get_unary_uuid(struct bt_list_head
*head
, unsigned char *uuid
)
233 struct ctf_node
*node
;
237 bt_list_for_each_entry(node
, head
, siblings
) {
238 const char *src_string
;
240 assert(node
->type
== NODE_UNARY_EXPRESSION
);
241 assert(node
->u
.unary_expression
.type
== UNARY_STRING
);
242 assert(node
->u
.unary_expression
.link
== UNARY_LINK_UNKNOWN
);
244 src_string
= node
->u
.unary_expression
.u
.string
;
245 ret
= babeltrace_uuid_parse(src_string
, uuid
);
251 struct ctf_stream_declaration
*trace_stream_lookup(struct ctf_trace
*trace
, uint64_t stream_id
)
253 if (trace
->streams
->len
<= stream_id
)
255 return g_ptr_array_index(trace
->streams
, stream_id
);
259 struct ctf_clock
*trace_clock_lookup(struct ctf_trace
*trace
, GQuark clock_name
)
261 return g_hash_table_lookup(trace
->clocks
, (gpointer
) (unsigned long) clock_name
);
265 int visit_type_specifier(FILE *fd
, struct ctf_node
*type_specifier
, GString
*str
)
267 assert(type_specifier
->type
== NODE_TYPE_SPECIFIER
);
269 switch (type_specifier
->u
.type_specifier
.type
) {
271 g_string_append(str
, "void");
274 g_string_append(str
, "char");
277 g_string_append(str
, "short");
280 g_string_append(str
, "int");
283 g_string_append(str
, "long");
286 g_string_append(str
, "float");
288 case TYPESPEC_DOUBLE
:
289 g_string_append(str
, "double");
291 case TYPESPEC_SIGNED
:
292 g_string_append(str
, "signed");
294 case TYPESPEC_UNSIGNED
:
295 g_string_append(str
, "unsigned");
298 g_string_append(str
, "bool");
300 case TYPESPEC_COMPLEX
:
301 g_string_append(str
, "_Complex");
303 case TYPESPEC_IMAGINARY
:
304 g_string_append(str
, "_Imaginary");
307 g_string_append(str
, "const");
309 case TYPESPEC_ID_TYPE
:
310 if (type_specifier
->u
.type_specifier
.id_type
)
311 g_string_append(str
, type_specifier
->u
.type_specifier
.id_type
);
313 case TYPESPEC_STRUCT
:
315 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
317 if (!node
->u
._struct
.name
) {
318 fprintf(fd
, "[error] %s: unexpected empty variant name\n", __func__
);
321 g_string_append(str
, "struct ");
322 g_string_append(str
, node
->u
._struct
.name
);
325 case TYPESPEC_VARIANT
:
327 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
329 if (!node
->u
.variant
.name
) {
330 fprintf(fd
, "[error] %s: unexpected empty variant name\n", __func__
);
333 g_string_append(str
, "variant ");
334 g_string_append(str
, node
->u
.variant
.name
);
339 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
341 if (!node
->u
._enum
.enum_id
) {
342 fprintf(fd
, "[error] %s: unexpected empty enum ID\n", __func__
);
345 g_string_append(str
, "enum ");
346 g_string_append(str
, node
->u
._enum
.enum_id
);
349 case TYPESPEC_FLOATING_POINT
:
350 case TYPESPEC_INTEGER
:
351 case TYPESPEC_STRING
:
353 fprintf(fd
, "[error] %s: unknown specifier\n", __func__
);
360 int visit_type_specifier_list(FILE *fd
, struct ctf_node
*type_specifier_list
, GString
*str
)
362 struct ctf_node
*iter
;
363 int alias_item_nr
= 0;
366 bt_list_for_each_entry(iter
, &type_specifier_list
->u
.type_specifier_list
.head
, siblings
) {
367 if (alias_item_nr
!= 0)
368 g_string_append(str
, " ");
370 ret
= visit_type_specifier(fd
, iter
, str
);
378 GQuark
create_typealias_identifier(FILE *fd
, int depth
,
379 struct ctf_node
*type_specifier_list
,
380 struct ctf_node
*node_type_declarator
)
382 struct ctf_node
*iter
;
388 str
= g_string_new("");
389 ret
= visit_type_specifier_list(fd
, type_specifier_list
, str
);
391 g_string_free(str
, TRUE
);
394 bt_list_for_each_entry(iter
, &node_type_declarator
->u
.type_declarator
.pointers
, siblings
) {
395 g_string_append(str
, " *");
396 if (iter
->u
.pointer
.const_qualifier
)
397 g_string_append(str
, " const");
399 str_c
= g_string_free(str
, FALSE
);
400 alias_q
= g_quark_from_string(str_c
);
406 struct declaration
*ctf_type_declarator_visit(FILE *fd
, int depth
,
407 struct ctf_node
*type_specifier_list
,
409 struct ctf_node
*node_type_declarator
,
410 struct declaration_scope
*declaration_scope
,
411 struct declaration
*nested_declaration
,
412 struct ctf_trace
*trace
)
415 * Visit type declarator by first taking care of sequence/array
416 * (recursively). Then, when we get to the identifier, take care
420 if (node_type_declarator
) {
421 assert(node_type_declarator
->u
.type_declarator
.type
!= TYPEDEC_UNKNOWN
);
423 /* TODO: gcc bitfields not supported yet. */
424 if (node_type_declarator
->u
.type_declarator
.bitfield_len
!= NULL
) {
425 fprintf(fd
, "[error] %s: gcc bitfields are not supported yet.\n", __func__
);
430 if (!nested_declaration
) {
431 if (node_type_declarator
&& !bt_list_empty(&node_type_declarator
->u
.type_declarator
.pointers
)) {
435 * If we have a pointer declarator, it _has_ to be present in
436 * the typealiases (else fail).
438 alias_q
= create_typealias_identifier(fd
, depth
,
439 type_specifier_list
, node_type_declarator
);
440 nested_declaration
= lookup_declaration(alias_q
, declaration_scope
);
441 if (!nested_declaration
) {
442 fprintf(fd
, "[error] %s: cannot find typealias \"%s\".\n", __func__
, g_quark_to_string(alias_q
));
445 if (nested_declaration
->id
== CTF_TYPE_INTEGER
) {
446 struct declaration_integer
*integer_declaration
=
447 container_of(nested_declaration
, struct declaration_integer
, p
);
448 /* For base to 16 for pointers (expected pretty-print) */
449 if (!integer_declaration
->base
) {
451 * We need to do a copy of the
452 * integer declaration to modify it. There could be other references to
455 integer_declaration
= integer_declaration_new(integer_declaration
->len
,
456 integer_declaration
->byte_order
, integer_declaration
->signedness
,
457 integer_declaration
->p
.alignment
, 16, integer_declaration
->encoding
,
458 integer_declaration
->clock
);
459 nested_declaration
= &integer_declaration
->p
;
463 nested_declaration
= ctf_type_specifier_list_visit(fd
, depth
,
464 type_specifier_list
, declaration_scope
, trace
);
468 if (!node_type_declarator
)
469 return nested_declaration
;
471 if (node_type_declarator
->u
.type_declarator
.type
== TYPEDEC_ID
) {
472 if (node_type_declarator
->u
.type_declarator
.u
.id
)
473 *field_name
= g_quark_from_string(node_type_declarator
->u
.type_declarator
.u
.id
);
476 return nested_declaration
;
478 struct declaration
*declaration
;
479 struct ctf_node
*first
;
483 if (!nested_declaration
) {
484 fprintf(fd
, "[error] %s: nested type is unknown.\n", __func__
);
488 /* create array/sequence, pass nested_declaration as child. */
489 if (bt_list_empty(&node_type_declarator
->u
.type_declarator
.u
.nested
.length
)) {
490 fprintf(fd
, "[error] %s: expecting length field reference or value.\n", __func__
);
493 first
= _bt_list_first_entry(&node_type_declarator
->u
.type_declarator
.u
.nested
.length
,
494 struct ctf_node
, siblings
);
495 assert(first
->type
== NODE_UNARY_EXPRESSION
);
497 switch (first
->u
.unary_expression
.type
) {
498 case UNARY_UNSIGNED_CONSTANT
:
500 struct declaration_array
*array_declaration
;
503 len
= first
->u
.unary_expression
.u
.unsigned_constant
;
504 array_declaration
= array_declaration_new(len
, nested_declaration
,
507 if (!array_declaration
) {
508 fprintf(fd
, "[error] %s: cannot create array declaration.\n", __func__
);
511 declaration
= &array_declaration
->p
;
516 /* Lookup unsigned integer definition, create sequence */
517 char *length_name
= concatenate_unary_strings(&node_type_declarator
->u
.type_declarator
.u
.nested
.length
);
518 struct declaration_sequence
*sequence_declaration
;
520 sequence_declaration
= sequence_declaration_new(length_name
, nested_declaration
, declaration_scope
);
521 if (!sequence_declaration
) {
522 fprintf(fd
, "[error] %s: cannot create sequence declaration.\n", __func__
);
525 declaration
= &sequence_declaration
->p
;
532 /* Pass it as content of outer container */
533 declaration
= ctf_type_declarator_visit(fd
, depth
,
534 type_specifier_list
, field_name
,
535 node_type_declarator
->u
.type_declarator
.u
.nested
.type_declarator
,
536 declaration_scope
, declaration
, trace
);
542 int ctf_struct_type_declarators_visit(FILE *fd
, int depth
,
543 struct declaration_struct
*struct_declaration
,
544 struct ctf_node
*type_specifier_list
,
545 struct bt_list_head
*type_declarators
,
546 struct declaration_scope
*declaration_scope
,
547 struct ctf_trace
*trace
)
549 struct ctf_node
*iter
;
552 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
553 struct declaration
*field_declaration
;
555 field_declaration
= ctf_type_declarator_visit(fd
, depth
,
558 struct_declaration
->scope
,
560 if (!field_declaration
) {
561 fprintf(fd
, "[error] %s: unable to find struct field declaration type\n", __func__
);
565 /* Check if field with same name already exists */
566 if (struct_declaration_lookup_field_index(struct_declaration
, field_name
) >= 0) {
567 fprintf(fd
, "[error] %s: duplicate field %s in struct\n", __func__
, g_quark_to_string(field_name
));
571 struct_declaration_add_field(struct_declaration
,
572 g_quark_to_string(field_name
),
579 int ctf_variant_type_declarators_visit(FILE *fd
, int depth
,
580 struct declaration_untagged_variant
*untagged_variant_declaration
,
581 struct ctf_node
*type_specifier_list
,
582 struct bt_list_head
*type_declarators
,
583 struct declaration_scope
*declaration_scope
,
584 struct ctf_trace
*trace
)
586 struct ctf_node
*iter
;
589 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
590 struct declaration
*field_declaration
;
592 field_declaration
= ctf_type_declarator_visit(fd
, depth
,
595 untagged_variant_declaration
->scope
,
597 if (!field_declaration
) {
598 fprintf(fd
, "[error] %s: unable to find variant field declaration type\n", __func__
);
602 if (untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration
, field_name
) != NULL
) {
603 fprintf(fd
, "[error] %s: duplicate field %s in variant\n", __func__
, g_quark_to_string(field_name
));
608 untagged_variant_declaration_add_field(untagged_variant_declaration
,
609 g_quark_to_string(field_name
),
616 int ctf_typedef_visit(FILE *fd
, int depth
, struct declaration_scope
*scope
,
617 struct ctf_node
*type_specifier_list
,
618 struct bt_list_head
*type_declarators
,
619 struct ctf_trace
*trace
)
621 struct ctf_node
*iter
;
624 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
625 struct declaration
*type_declaration
;
628 type_declaration
= ctf_type_declarator_visit(fd
, depth
,
632 if (!type_declaration
) {
633 fprintf(fd
, "[error] %s: problem creating type declaration\n", __func__
);
637 * Don't allow typedef and typealias of untagged
640 if (type_declaration
->id
== CTF_TYPE_UNTAGGED_VARIANT
) {
641 fprintf(fd
, "[error] %s: typedef of untagged variant is not permitted.\n", __func__
);
642 declaration_unref(type_declaration
);
645 ret
= register_declaration(identifier
, type_declaration
, scope
);
647 type_declaration
->declaration_free(type_declaration
);
655 int ctf_typealias_visit(FILE *fd
, int depth
, struct declaration_scope
*scope
,
656 struct ctf_node
*target
, struct ctf_node
*alias
,
657 struct ctf_trace
*trace
)
659 struct declaration
*type_declaration
;
660 struct ctf_node
*node
;
665 /* See ctf_visitor_type_declarator() in the semantic validator. */
668 * Create target type declaration.
671 if (bt_list_empty(&target
->u
.typealias_target
.type_declarators
))
674 node
= _bt_list_first_entry(&target
->u
.typealias_target
.type_declarators
,
675 struct ctf_node
, siblings
);
676 type_declaration
= ctf_type_declarator_visit(fd
, depth
,
677 target
->u
.typealias_target
.type_specifier_list
,
680 if (!type_declaration
) {
681 fprintf(fd
, "[error] %s: problem creating type declaration\n", __func__
);
686 * Don't allow typedef and typealias of untagged
689 if (type_declaration
->id
== CTF_TYPE_UNTAGGED_VARIANT
) {
690 fprintf(fd
, "[error] %s: typedef of untagged variant is not permitted.\n", __func__
);
691 declaration_unref(type_declaration
);
695 * The semantic validator does not check whether the target is
696 * abstract or not (if it has an identifier). Check it here.
699 fprintf(fd
, "[error] %s: expecting empty identifier\n", __func__
);
704 * Create alias identifier.
707 node
= _bt_list_first_entry(&alias
->u
.typealias_alias
.type_declarators
,
708 struct ctf_node
, siblings
);
709 alias_q
= create_typealias_identifier(fd
, depth
,
710 alias
->u
.typealias_alias
.type_specifier_list
, node
);
711 err
= register_declaration(alias_q
, type_declaration
, scope
);
717 if (type_declaration
) {
718 type_declaration
->declaration_free(type_declaration
);
724 int ctf_struct_declaration_list_visit(FILE *fd
, int depth
,
725 struct ctf_node
*iter
, struct declaration_struct
*struct_declaration
,
726 struct ctf_trace
*trace
)
730 switch (iter
->type
) {
732 /* For each declarator, declare type and add type to struct declaration scope */
733 ret
= ctf_typedef_visit(fd
, depth
,
734 struct_declaration
->scope
,
735 iter
->u
._typedef
.type_specifier_list
,
736 &iter
->u
._typedef
.type_declarators
, trace
);
741 /* Declare type with declarator and add type to struct declaration scope */
742 ret
= ctf_typealias_visit(fd
, depth
,
743 struct_declaration
->scope
,
744 iter
->u
.typealias
.target
,
745 iter
->u
.typealias
.alias
, trace
);
749 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
750 /* Add field to structure declaration */
751 ret
= ctf_struct_type_declarators_visit(fd
, depth
,
753 iter
->u
.struct_or_variant_declaration
.type_specifier_list
,
754 &iter
->u
.struct_or_variant_declaration
.type_declarators
,
755 struct_declaration
->scope
, trace
);
760 fprintf(fd
, "[error] %s: unexpected node type %d\n", __func__
, (int) iter
->type
);
767 int ctf_variant_declaration_list_visit(FILE *fd
, int depth
,
768 struct ctf_node
*iter
,
769 struct declaration_untagged_variant
*untagged_variant_declaration
,
770 struct ctf_trace
*trace
)
774 switch (iter
->type
) {
776 /* For each declarator, declare type and add type to variant declaration scope */
777 ret
= ctf_typedef_visit(fd
, depth
,
778 untagged_variant_declaration
->scope
,
779 iter
->u
._typedef
.type_specifier_list
,
780 &iter
->u
._typedef
.type_declarators
, trace
);
785 /* Declare type with declarator and add type to variant declaration scope */
786 ret
= ctf_typealias_visit(fd
, depth
,
787 untagged_variant_declaration
->scope
,
788 iter
->u
.typealias
.target
,
789 iter
->u
.typealias
.alias
, trace
);
793 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
794 /* Add field to structure declaration */
795 ret
= ctf_variant_type_declarators_visit(fd
, depth
,
796 untagged_variant_declaration
,
797 iter
->u
.struct_or_variant_declaration
.type_specifier_list
,
798 &iter
->u
.struct_or_variant_declaration
.type_declarators
,
799 untagged_variant_declaration
->scope
, trace
);
804 fprintf(fd
, "[error] %s: unexpected node type %d\n", __func__
, (int) iter
->type
);
811 struct declaration
*ctf_declaration_struct_visit(FILE *fd
,
812 int depth
, const char *name
, struct bt_list_head
*declaration_list
,
813 int has_body
, struct bt_list_head
*min_align
,
814 struct declaration_scope
*declaration_scope
,
815 struct ctf_trace
*trace
)
817 struct declaration_struct
*struct_declaration
;
818 struct ctf_node
*iter
;
822 * For named struct (without body), lookup in
823 * declaration scope. Don't take reference on struct
824 * declaration: ref is only taken upon definition.
829 lookup_struct_declaration(g_quark_from_string(name
),
831 return &struct_declaration
->p
;
833 uint64_t min_align_value
= 0;
835 /* For unnamed struct, create type */
836 /* For named struct (with body), create type and add to declaration scope */
838 if (lookup_struct_declaration(g_quark_from_string(name
),
839 declaration_scope
)) {
841 fprintf(fd
, "[error] %s: struct %s already declared in scope\n", __func__
, name
);
845 if (!bt_list_empty(min_align
)) {
846 ret
= get_unary_unsigned(min_align
, &min_align_value
);
848 fprintf(fd
, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__
);
853 struct_declaration
= struct_declaration_new(declaration_scope
,
855 bt_list_for_each_entry(iter
, declaration_list
, siblings
) {
856 ret
= ctf_struct_declaration_list_visit(fd
, depth
+ 1, iter
,
857 struct_declaration
, trace
);
859 goto error_free_declaration
;
862 ret
= register_struct_declaration(g_quark_from_string(name
),
867 return &struct_declaration
->p
;
869 error_free_declaration
:
870 struct_declaration
->p
.declaration_free(&struct_declaration
->p
);
876 struct declaration
*ctf_declaration_variant_visit(FILE *fd
,
877 int depth
, const char *name
, const char *choice
,
878 struct bt_list_head
*declaration_list
,
879 int has_body
, struct declaration_scope
*declaration_scope
,
880 struct ctf_trace
*trace
)
882 struct declaration_untagged_variant
*untagged_variant_declaration
;
883 struct declaration_variant
*variant_declaration
;
884 struct ctf_node
*iter
;
888 * For named variant (without body), lookup in
889 * declaration scope. Don't take reference on variant
890 * declaration: ref is only taken upon definition.
894 untagged_variant_declaration
=
895 lookup_variant_declaration(g_quark_from_string(name
),
898 /* For unnamed variant, create type */
899 /* For named variant (with body), create type and add to declaration scope */
901 if (lookup_variant_declaration(g_quark_from_string(name
),
902 declaration_scope
)) {
904 fprintf(fd
, "[error] %s: variant %s already declared in scope\n", __func__
, name
);
908 untagged_variant_declaration
= untagged_variant_declaration_new(declaration_scope
);
909 bt_list_for_each_entry(iter
, declaration_list
, siblings
) {
910 ret
= ctf_variant_declaration_list_visit(fd
, depth
+ 1, iter
,
911 untagged_variant_declaration
, trace
);
916 ret
= register_variant_declaration(g_quark_from_string(name
),
917 untagged_variant_declaration
,
923 * if tagged, create tagged variant and return. else return
927 return &untagged_variant_declaration
->p
;
929 variant_declaration
= variant_declaration_new(untagged_variant_declaration
, choice
);
930 if (!variant_declaration
)
932 declaration_unref(&untagged_variant_declaration
->p
);
933 return &variant_declaration
->p
;
936 untagged_variant_declaration
->p
.declaration_free(&untagged_variant_declaration
->p
);
941 int ctf_enumerator_list_visit(FILE *fd
, int depth
,
942 struct ctf_node
*enumerator
,
943 struct declaration_enum
*enum_declaration
,
944 struct last_enum_value
*last
)
947 struct ctf_node
*iter
;
949 q
= g_quark_from_string(enumerator
->u
.enumerator
.id
);
950 if (enum_declaration
->integer_declaration
->signedness
) {
954 bt_list_for_each_entry(iter
, &enumerator
->u
.enumerator
.values
, siblings
) {
957 assert(iter
->type
== NODE_UNARY_EXPRESSION
);
963 switch (iter
->u
.unary_expression
.type
) {
964 case UNARY_SIGNED_CONSTANT
:
965 *target
= iter
->u
.unary_expression
.u
.signed_constant
;
967 case UNARY_UNSIGNED_CONSTANT
:
968 *target
= iter
->u
.unary_expression
.u
.unsigned_constant
;
971 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
975 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
985 enum_signed_insert(enum_declaration
, start
, end
, q
);
990 bt_list_for_each_entry(iter
, &enumerator
->u
.enumerator
.values
, siblings
) {
993 assert(iter
->type
== NODE_UNARY_EXPRESSION
);
999 switch (iter
->u
.unary_expression
.type
) {
1000 case UNARY_UNSIGNED_CONSTANT
:
1001 *target
= iter
->u
.unary_expression
.u
.unsigned_constant
;
1003 case UNARY_SIGNED_CONSTANT
:
1005 * We don't accept signed constants for enums with unsigned
1008 fprintf(fd
, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__
);
1011 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
1015 fprintf(fd
, "[error] %s: invalid enumerator\n", __func__
);
1024 last
->u
.u
= end
+ 1;
1025 enum_unsigned_insert(enum_declaration
, start
, end
, q
);
1031 struct declaration
*ctf_declaration_enum_visit(FILE *fd
, int depth
,
1033 struct ctf_node
*container_type
,
1034 struct bt_list_head
*enumerator_list
,
1036 struct declaration_scope
*declaration_scope
,
1037 struct ctf_trace
*trace
)
1039 struct declaration
*declaration
;
1040 struct declaration_enum
*enum_declaration
;
1041 struct declaration_integer
*integer_declaration
;
1042 struct last_enum_value last_value
;
1043 struct ctf_node
*iter
;
1048 * For named enum (without body), lookup in
1049 * declaration scope. Don't take reference on enum
1050 * declaration: ref is only taken upon definition.
1055 lookup_enum_declaration(g_quark_from_string(name
),
1057 return &enum_declaration
->p
;
1059 /* For unnamed enum, create type */
1060 /* For named enum (with body), create type and add to declaration scope */
1062 if (lookup_enum_declaration(g_quark_from_string(name
),
1063 declaration_scope
)) {
1065 fprintf(fd
, "[error] %s: enum %s already declared in scope\n", __func__
, name
);
1069 if (!container_type
) {
1070 declaration
= lookup_declaration(g_quark_from_static_string("int"),
1073 fprintf(fd
, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__
);
1077 declaration
= ctf_type_declarator_visit(fd
, depth
,
1084 fprintf(fd
, "[error] %s: unable to create container type for enumeration\n", __func__
);
1087 if (declaration
->id
!= CTF_TYPE_INTEGER
) {
1088 fprintf(fd
, "[error] %s: container type for enumeration is not integer\n", __func__
);
1091 integer_declaration
= container_of(declaration
, struct declaration_integer
, p
);
1092 enum_declaration
= enum_declaration_new(integer_declaration
);
1093 declaration_unref(&integer_declaration
->p
); /* leave ref to enum */
1094 if (enum_declaration
->integer_declaration
->signedness
) {
1099 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
1100 ret
= ctf_enumerator_list_visit(fd
, depth
+ 1, iter
, enum_declaration
,
1106 ret
= register_enum_declaration(g_quark_from_string(name
),
1111 return &enum_declaration
->p
;
1114 enum_declaration
->p
.declaration_free(&enum_declaration
->p
);
1119 struct declaration
*ctf_declaration_type_specifier_visit(FILE *fd
, int depth
,
1120 struct ctf_node
*type_specifier_list
,
1121 struct declaration_scope
*declaration_scope
)
1124 struct declaration
*declaration
;
1129 str
= g_string_new("");
1130 ret
= visit_type_specifier_list(fd
, type_specifier_list
, str
);
1133 str_c
= g_string_free(str
, FALSE
);
1134 id_q
= g_quark_from_string(str_c
);
1136 declaration
= lookup_declaration(id_q
, declaration_scope
);
1141 * Returns 0/1 boolean, or < 0 on error.
1144 int get_boolean(FILE *fd
, int depth
, struct ctf_node
*unary_expression
)
1146 if (unary_expression
->type
!= NODE_UNARY_EXPRESSION
) {
1147 fprintf(fd
, "[error] %s: expecting unary expression\n",
1151 switch (unary_expression
->u
.unary_expression
.type
) {
1152 case UNARY_UNSIGNED_CONSTANT
:
1153 if (unary_expression
->u
.unary_expression
.u
.unsigned_constant
== 0)
1157 case UNARY_SIGNED_CONSTANT
:
1158 if (unary_expression
->u
.unary_expression
.u
.signed_constant
== 0)
1163 if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "true"))
1165 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "TRUE"))
1167 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "false"))
1169 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "FALSE"))
1172 fprintf(fd
, "[error] %s: unexpected string \"%s\"\n",
1173 __func__
, unary_expression
->u
.unary_expression
.u
.string
);
1178 fprintf(fd
, "[error] %s: unexpected unary expression type\n",
1186 int get_trace_byte_order(FILE *fd
, int depth
, struct ctf_node
*unary_expression
)
1190 if (unary_expression
->u
.unary_expression
.type
!= UNARY_STRING
) {
1191 fprintf(fd
, "[error] %s: byte_order: expecting string\n",
1195 if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "be"))
1196 byte_order
= BIG_ENDIAN
;
1197 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "le"))
1198 byte_order
= LITTLE_ENDIAN
;
1200 fprintf(fd
, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1201 __func__
, unary_expression
->u
.unary_expression
.u
.string
);
1208 int get_byte_order(FILE *fd
, int depth
, struct ctf_node
*unary_expression
,
1209 struct ctf_trace
*trace
)
1213 if (unary_expression
->u
.unary_expression
.type
!= UNARY_STRING
) {
1214 fprintf(fd
, "[error] %s: byte_order: expecting string\n",
1218 if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "native"))
1219 byte_order
= trace
->byte_order
;
1220 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "network"))
1221 byte_order
= BIG_ENDIAN
;
1222 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "be"))
1223 byte_order
= BIG_ENDIAN
;
1224 else if (!strcmp(unary_expression
->u
.unary_expression
.u
.string
, "le"))
1225 byte_order
= LITTLE_ENDIAN
;
1227 fprintf(fd
, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1228 __func__
, unary_expression
->u
.unary_expression
.u
.string
);
1235 struct declaration
*ctf_declaration_integer_visit(FILE *fd
, int depth
,
1236 struct bt_list_head
*expressions
,
1237 struct ctf_trace
*trace
)
1239 struct ctf_node
*expression
;
1240 uint64_t alignment
= 1, size
= 0;
1241 int byte_order
= trace
->byte_order
;
1243 int has_alignment
= 0, has_size
= 0;
1245 enum ctf_string_encoding encoding
= CTF_STRING_NONE
;
1246 struct ctf_clock
*clock
= NULL
;
1247 struct declaration_integer
*integer_declaration
;
1249 bt_list_for_each_entry(expression
, expressions
, siblings
) {
1250 struct ctf_node
*left
, *right
;
1252 left
= _bt_list_first_entry(&expression
->u
.ctf_expression
.left
, struct ctf_node
, siblings
);
1253 right
= _bt_list_first_entry(&expression
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
1254 assert(left
->u
.unary_expression
.type
== UNARY_STRING
);
1255 if (!strcmp(left
->u
.unary_expression
.u
.string
, "signed")) {
1256 signedness
= get_boolean(fd
, depth
, right
);
1259 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
1260 byte_order
= get_byte_order(fd
, depth
, right
, trace
);
1263 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "size")) {
1264 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1265 fprintf(fd
, "[error] %s: size: expecting unsigned constant\n",
1269 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
1271 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "align")) {
1272 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1273 fprintf(fd
, "[error] %s: align: expecting unsigned constant\n",
1277 alignment
= right
->u
.unary_expression
.u
.unsigned_constant
;
1278 /* Make sure alignment is a power of two */
1279 if (alignment
== 0 || (alignment
& (alignment
- 1)) != 0) {
1280 fprintf(fd
, "[error] %s: align: expecting power of two\n",
1285 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "base")) {
1286 switch (right
->u
.unary_expression
.type
) {
1287 case UNARY_UNSIGNED_CONSTANT
:
1288 switch (right
->u
.unary_expression
.u
.unsigned_constant
) {
1293 base
= right
->u
.unary_expression
.u
.unsigned_constant
;
1296 fprintf(fd
, "[error] %s: base not supported (%" PRIu64
")\n",
1297 __func__
, right
->u
.unary_expression
.u
.unsigned_constant
);
1303 char *s_right
= concatenate_unary_strings(&expression
->u
.ctf_expression
.right
);
1305 fprintf(fd
, "[error] %s: unexpected unary expression for integer base\n", __func__
);
1309 if (!strcmp(s_right
, "decimal") || !strcmp(s_right
, "dec") || !strcmp(s_right
, "d")
1310 || !strcmp(s_right
, "i") || !strcmp(s_right
, "u")) {
1312 } else if (!strcmp(s_right
, "hexadecimal") || !strcmp(s_right
, "hex")
1313 || !strcmp(s_right
, "x") || !strcmp(s_right
, "X")
1314 || !strcmp(s_right
, "p")) {
1316 } else if (!strcmp(s_right
, "octal") || !strcmp(s_right
, "oct")
1317 || !strcmp(s_right
, "o")) {
1319 } else if (!strcmp(s_right
, "binary") || !strcmp(s_right
, "b")) {
1322 fprintf(fd
, "[error] %s: unexpected expression for integer base (%s)\n", __func__
, s_right
);
1331 fprintf(fd
, "[error] %s: base: expecting unsigned constant or unary string\n",
1335 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
1338 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
1339 fprintf(fd
, "[error] %s: encoding: expecting unary string\n",
1343 s_right
= concatenate_unary_strings(&expression
->u
.ctf_expression
.right
);
1345 fprintf(fd
, "[error] %s: unexpected unary expression for integer base\n", __func__
);
1349 if (!strcmp(s_right
, "UTF8")
1350 || !strcmp(s_right
, "utf8")
1351 || !strcmp(s_right
, "utf-8")
1352 || !strcmp(s_right
, "UTF-8"))
1353 encoding
= CTF_STRING_UTF8
;
1354 else if (!strcmp(s_right
, "ASCII")
1355 || !strcmp(s_right
, "ascii"))
1356 encoding
= CTF_STRING_ASCII
;
1357 else if (!strcmp(s_right
, "none"))
1358 encoding
= CTF_STRING_NONE
;
1360 fprintf(fd
, "[error] %s: unknown string encoding \"%s\"\n", __func__
, s_right
);
1365 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "map")) {
1368 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
1369 fprintf(fd
, "[error] %s: map: expecting identifier\n",
1373 /* currently only support clock.name.value */
1374 clock_name
= get_map_clock_name_value(&expression
->u
.ctf_expression
.right
);
1378 s_right
= concatenate_unary_strings(&expression
->u
.ctf_expression
.right
);
1380 fprintf(fd
, "[error] %s: unexpected unary expression for integer map\n", __func__
);
1384 fprintf(fd
, "[warning] %s: unknown map %s in integer declaration\n", __func__
,
1389 clock
= trace_clock_lookup(trace
, clock_name
);
1391 fprintf(fd
, "[error] %s: map: unable to find clock %s declaration\n",
1392 __func__
, g_quark_to_string(clock_name
));
1396 fprintf(fd
, "[warning] %s: unknown attribute name %s\n",
1397 __func__
, left
->u
.unary_expression
.u
.string
);
1398 /* Fall-through after warning */
1402 fprintf(fd
, "[error] %s: missing size attribute\n", __func__
);
1405 if (!has_alignment
) {
1406 if (size
% CHAR_BIT
) {
1407 /* bit-packed alignment */
1410 /* byte-packed alignment */
1411 alignment
= CHAR_BIT
;
1414 integer_declaration
= integer_declaration_new(size
,
1415 byte_order
, signedness
, alignment
,
1416 base
, encoding
, clock
);
1417 return &integer_declaration
->p
;
1421 struct declaration
*ctf_declaration_floating_point_visit(FILE *fd
, int depth
,
1422 struct bt_list_head
*expressions
,
1423 struct ctf_trace
*trace
)
1425 struct ctf_node
*expression
;
1426 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0,
1427 byte_order
= trace
->byte_order
;
1428 int has_alignment
= 0, has_exp_dig
= 0, has_mant_dig
= 0;
1429 struct declaration_float
*float_declaration
;
1431 bt_list_for_each_entry(expression
, expressions
, siblings
) {
1432 struct ctf_node
*left
, *right
;
1434 left
= _bt_list_first_entry(&expression
->u
.ctf_expression
.left
, struct ctf_node
, siblings
);
1435 right
= _bt_list_first_entry(&expression
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
1436 assert(left
->u
.unary_expression
.type
== UNARY_STRING
);
1437 if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
1438 byte_order
= get_byte_order(fd
, depth
, right
, trace
);
1441 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "exp_dig")) {
1442 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1443 fprintf(fd
, "[error] %s: exp_dig: expecting unsigned constant\n",
1447 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
1449 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "mant_dig")) {
1450 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1451 fprintf(fd
, "[error] %s: mant_dig: expecting unsigned constant\n",
1455 mant_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
1457 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "align")) {
1458 if (right
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
1459 fprintf(fd
, "[error] %s: align: expecting unsigned constant\n",
1463 alignment
= right
->u
.unary_expression
.u
.unsigned_constant
;
1464 /* Make sure alignment is a power of two */
1465 if (alignment
== 0 || (alignment
& (alignment
- 1)) != 0) {
1466 fprintf(fd
, "[error] %s: align: expecting power of two\n",
1472 fprintf(fd
, "[warning] %s: unknown attribute name %s\n",
1473 __func__
, left
->u
.unary_expression
.u
.string
);
1474 /* Fall-through after warning */
1477 if (!has_mant_dig
) {
1478 fprintf(fd
, "[error] %s: missing mant_dig attribute\n", __func__
);
1482 fprintf(fd
, "[error] %s: missing exp_dig attribute\n", __func__
);
1485 if (!has_alignment
) {
1486 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
1487 /* bit-packed alignment */
1490 /* byte-packed alignment */
1491 alignment
= CHAR_BIT
;
1494 float_declaration
= float_declaration_new(mant_dig
, exp_dig
,
1495 byte_order
, alignment
);
1496 return &float_declaration
->p
;
1500 struct declaration
*ctf_declaration_string_visit(FILE *fd
, int depth
,
1501 struct bt_list_head
*expressions
,
1502 struct ctf_trace
*trace
)
1504 struct ctf_node
*expression
;
1505 const char *encoding_c
= NULL
;
1506 enum ctf_string_encoding encoding
= CTF_STRING_UTF8
;
1507 struct declaration_string
*string_declaration
;
1509 bt_list_for_each_entry(expression
, expressions
, siblings
) {
1510 struct ctf_node
*left
, *right
;
1512 left
= _bt_list_first_entry(&expression
->u
.ctf_expression
.left
, struct ctf_node
, siblings
);
1513 right
= _bt_list_first_entry(&expression
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
1514 assert(left
->u
.unary_expression
.type
== UNARY_STRING
);
1515 if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
1516 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
1517 fprintf(fd
, "[error] %s: encoding: expecting string\n",
1521 encoding_c
= right
->u
.unary_expression
.u
.string
;
1523 fprintf(fd
, "[warning] %s: unknown attribute name %s\n",
1524 __func__
, left
->u
.unary_expression
.u
.string
);
1525 /* Fall-through after warning */
1528 if (encoding_c
&& !strcmp(encoding_c
, "ASCII"))
1529 encoding
= CTF_STRING_ASCII
;
1530 string_declaration
= string_declaration_new(encoding
);
1531 return &string_declaration
->p
;
1536 struct declaration
*ctf_type_specifier_list_visit(FILE *fd
,
1537 int depth
, struct ctf_node
*type_specifier_list
,
1538 struct declaration_scope
*declaration_scope
,
1539 struct ctf_trace
*trace
)
1541 struct ctf_node
*first
;
1542 struct ctf_node
*node
;
1544 assert(type_specifier_list
->type
== NODE_TYPE_SPECIFIER_LIST
);
1546 first
= _bt_list_first_entry(&type_specifier_list
->u
.type_specifier_list
.head
, struct ctf_node
, siblings
);
1548 assert(first
->type
== NODE_TYPE_SPECIFIER
);
1550 node
= first
->u
.type_specifier
.node
;
1552 switch (first
->u
.type_specifier
.type
) {
1553 case TYPESPEC_FLOATING_POINT
:
1554 return ctf_declaration_floating_point_visit(fd
, depth
,
1555 &node
->u
.floating_point
.expressions
, trace
);
1556 case TYPESPEC_INTEGER
:
1557 return ctf_declaration_integer_visit(fd
, depth
,
1558 &node
->u
.integer
.expressions
, trace
);
1559 case TYPESPEC_STRING
:
1560 return ctf_declaration_string_visit(fd
, depth
,
1561 &node
->u
.string
.expressions
, trace
);
1562 case TYPESPEC_STRUCT
:
1563 return ctf_declaration_struct_visit(fd
, depth
,
1564 node
->u
._struct
.name
,
1565 &node
->u
._struct
.declaration_list
,
1566 node
->u
._struct
.has_body
,
1567 &node
->u
._struct
.min_align
,
1570 case TYPESPEC_VARIANT
:
1571 return ctf_declaration_variant_visit(fd
, depth
,
1572 node
->u
.variant
.name
,
1573 node
->u
.variant
.choice
,
1574 &node
->u
.variant
.declaration_list
,
1575 node
->u
.variant
.has_body
,
1579 return ctf_declaration_enum_visit(fd
, depth
,
1580 node
->u
._enum
.enum_id
,
1581 node
->u
._enum
.container_type
,
1582 &node
->u
._enum
.enumerator_list
,
1583 node
->u
._enum
.has_body
,
1589 case TYPESPEC_SHORT
:
1592 case TYPESPEC_FLOAT
:
1593 case TYPESPEC_DOUBLE
:
1594 case TYPESPEC_SIGNED
:
1595 case TYPESPEC_UNSIGNED
:
1597 case TYPESPEC_COMPLEX
:
1598 case TYPESPEC_IMAGINARY
:
1599 case TYPESPEC_CONST
:
1600 case TYPESPEC_ID_TYPE
:
1601 return ctf_declaration_type_specifier_visit(fd
, depth
,
1602 type_specifier_list
, declaration_scope
);
1604 fprintf(fd
, "[error] %s: unexpected node type %d\n", __func__
, (int) first
->u
.type_specifier
.type
);
1610 int ctf_event_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_event_declaration
*event
, struct ctf_trace
*trace
)
1614 switch (node
->type
) {
1616 ret
= ctf_typedef_visit(fd
, depth
+ 1,
1617 event
->declaration_scope
,
1618 node
->u
._typedef
.type_specifier_list
,
1619 &node
->u
._typedef
.type_declarators
,
1624 case NODE_TYPEALIAS
:
1625 ret
= ctf_typealias_visit(fd
, depth
+ 1,
1626 event
->declaration_scope
,
1627 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
1632 case NODE_CTF_EXPRESSION
:
1636 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
1637 if (!strcmp(left
, "name")) {
1640 if (CTF_EVENT_FIELD_IS_SET(event
, name
)) {
1641 fprintf(fd
, "[error] %s: name already declared in event declaration\n", __func__
);
1645 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
1647 fprintf(fd
, "[error] %s: unexpected unary expression for event name\n", __func__
);
1651 event
->name
= g_quark_from_string(right
);
1653 CTF_EVENT_SET_FIELD(event
, name
);
1654 } else if (!strcmp(left
, "id")) {
1655 if (CTF_EVENT_FIELD_IS_SET(event
, id
)) {
1656 fprintf(fd
, "[error] %s: id already declared in event declaration\n", __func__
);
1660 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->id
);
1662 fprintf(fd
, "[error] %s: unexpected unary expression for event id\n", __func__
);
1666 CTF_EVENT_SET_FIELD(event
, id
);
1667 } else if (!strcmp(left
, "stream_id")) {
1668 if (CTF_EVENT_FIELD_IS_SET(event
, stream_id
)) {
1669 fprintf(fd
, "[error] %s: stream_id already declared in event declaration\n", __func__
);
1673 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->stream_id
);
1675 fprintf(fd
, "[error] %s: unexpected unary expression for event stream_id\n", __func__
);
1679 event
->stream
= trace_stream_lookup(trace
, event
->stream_id
);
1680 if (!event
->stream
) {
1681 fprintf(fd
, "[error] %s: stream id %" PRIu64
" cannot be found\n", __func__
, event
->stream_id
);
1685 CTF_EVENT_SET_FIELD(event
, stream_id
);
1686 } else if (!strcmp(left
, "context")) {
1687 struct declaration
*declaration
;
1689 if (event
->context_decl
) {
1690 fprintf(fd
, "[error] %s: context already declared in event declaration\n", __func__
);
1694 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1695 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1696 struct ctf_node
, siblings
),
1697 event
->declaration_scope
, trace
);
1702 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1706 event
->context_decl
= container_of(declaration
, struct declaration_struct
, p
);
1707 } else if (!strcmp(left
, "fields")) {
1708 struct declaration
*declaration
;
1710 if (event
->fields_decl
) {
1711 fprintf(fd
, "[error] %s: fields already declared in event declaration\n", __func__
);
1715 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1716 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1717 struct ctf_node
, siblings
),
1718 event
->declaration_scope
, trace
);
1723 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1727 event
->fields_decl
= container_of(declaration
, struct declaration_struct
, p
);
1728 } else if (!strcmp(left
, "loglevel")) {
1729 int64_t loglevel
= -1;
1731 if (CTF_EVENT_FIELD_IS_SET(event
, loglevel
)) {
1732 fprintf(fd
, "[error] %s: loglevel already declared in event declaration\n", __func__
);
1736 ret
= get_unary_signed(&node
->u
.ctf_expression
.right
, &loglevel
);
1738 fprintf(fd
, "[error] %s: unexpected unary expression for event loglevel\n", __func__
);
1742 event
->loglevel
= (int) loglevel
;
1743 CTF_EVENT_SET_FIELD(event
, loglevel
);
1744 } else if (!strcmp(left
, "model.emf.uri")) {
1747 if (CTF_EVENT_FIELD_IS_SET(event
, model_emf_uri
)) {
1748 fprintf(fd
, "[error] %s: model.emf.uri already declared in event declaration\n", __func__
);
1752 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
1754 fprintf(fd
, "[error] %s: unexpected unary expression for event model.emf.uri\n", __func__
);
1758 event
->model_emf_uri
= g_quark_from_string(right
);
1760 CTF_EVENT_SET_FIELD(event
, model_emf_uri
);
1762 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__
, left
);
1763 /* Fall-through after warning */
1771 /* TODO: declaration specifier should be added. */
1778 int ctf_event_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
1779 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
1782 struct ctf_node
*iter
;
1783 struct ctf_event_declaration
*event
;
1784 struct bt_ctf_event_decl
*event_decl
;
1786 event_decl
= g_new0(struct bt_ctf_event_decl
, 1);
1787 event
= &event_decl
->parent
;
1788 event
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
1789 event
->loglevel
= -1;
1790 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
1791 ret
= ctf_event_declaration_visit(fd
, depth
+ 1, iter
, event
, trace
);
1795 if (!CTF_EVENT_FIELD_IS_SET(event
, name
)) {
1797 fprintf(fd
, "[error] %s: missing name field in event declaration\n", __func__
);
1800 if (!CTF_EVENT_FIELD_IS_SET(event
, stream_id
)) {
1801 /* Allow missing stream_id if there is only a single stream */
1802 switch (trace
->streams
->len
) {
1803 case 0: /* Create stream if there was none. */
1804 ret
= ctf_stream_visit(fd
, depth
, NULL
, trace
->root_declaration_scope
, trace
);
1809 event
->stream_id
= 0;
1810 event
->stream
= trace_stream_lookup(trace
, event
->stream_id
);
1814 fprintf(fd
, "[error] %s: missing stream_id field in event declaration\n", __func__
);
1818 /* Allow only one event without id per stream */
1819 if (!CTF_EVENT_FIELD_IS_SET(event
, id
)
1820 && event
->stream
->events_by_id
->len
!= 0) {
1822 fprintf(fd
, "[error] %s: missing id field in event declaration\n", __func__
);
1825 if (event
->stream
->events_by_id
->len
<= event
->id
)
1826 g_ptr_array_set_size(event
->stream
->events_by_id
, event
->id
+ 1);
1827 g_ptr_array_index(event
->stream
->events_by_id
, event
->id
) = event
;
1828 g_hash_table_insert(event
->stream
->event_quark_to_id
,
1829 (gpointer
) (unsigned long) event
->name
,
1831 g_ptr_array_add(trace
->event_declarations
, event_decl
);
1835 if (event
->fields_decl
)
1836 declaration_unref(&event
->fields_decl
->p
);
1837 if (event
->context_decl
)
1838 declaration_unref(&event
->context_decl
->p
);
1839 free_declaration_scope(event
->declaration_scope
);
1846 int ctf_stream_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_stream_declaration
*stream
, struct ctf_trace
*trace
)
1850 switch (node
->type
) {
1852 ret
= ctf_typedef_visit(fd
, depth
+ 1,
1853 stream
->declaration_scope
,
1854 node
->u
._typedef
.type_specifier_list
,
1855 &node
->u
._typedef
.type_declarators
,
1860 case NODE_TYPEALIAS
:
1861 ret
= ctf_typealias_visit(fd
, depth
+ 1,
1862 stream
->declaration_scope
,
1863 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
1868 case NODE_CTF_EXPRESSION
:
1872 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
1873 if (!strcmp(left
, "id")) {
1874 if (CTF_STREAM_FIELD_IS_SET(stream
, stream_id
)) {
1875 fprintf(fd
, "[error] %s: id already declared in stream declaration\n", __func__
);
1879 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &stream
->stream_id
);
1881 fprintf(fd
, "[error] %s: unexpected unary expression for stream id\n", __func__
);
1885 CTF_STREAM_SET_FIELD(stream
, stream_id
);
1886 } else if (!strcmp(left
, "event.header")) {
1887 struct declaration
*declaration
;
1889 if (stream
->event_header_decl
) {
1890 fprintf(fd
, "[error] %s: event.header already declared in stream declaration\n", __func__
);
1894 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1895 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1896 struct ctf_node
, siblings
),
1897 stream
->declaration_scope
, trace
);
1902 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1906 stream
->event_header_decl
= container_of(declaration
, struct declaration_struct
, p
);
1907 } else if (!strcmp(left
, "event.context")) {
1908 struct declaration
*declaration
;
1910 if (stream
->event_context_decl
) {
1911 fprintf(fd
, "[error] %s: event.context already declared in stream declaration\n", __func__
);
1915 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1916 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1917 struct ctf_node
, siblings
),
1918 stream
->declaration_scope
, trace
);
1923 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1927 stream
->event_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
1928 } else if (!strcmp(left
, "packet.context")) {
1929 struct declaration
*declaration
;
1931 if (stream
->packet_context_decl
) {
1932 fprintf(fd
, "[error] %s: packet.context already declared in stream declaration\n", __func__
);
1936 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1937 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1938 struct ctf_node
, siblings
),
1939 stream
->declaration_scope
, trace
);
1944 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1948 stream
->packet_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
1950 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__
, left
);
1951 /* Fall-through after warning */
1960 /* TODO: declaration specifier should be added. */
1967 int ctf_stream_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
1968 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
1971 struct ctf_node
*iter
;
1972 struct ctf_stream_declaration
*stream
;
1974 stream
= g_new0(struct ctf_stream_declaration
, 1);
1975 stream
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
1976 stream
->events_by_id
= g_ptr_array_new();
1977 stream
->event_quark_to_id
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
1978 stream
->streams
= g_ptr_array_new();
1980 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
1981 ret
= ctf_stream_declaration_visit(fd
, depth
+ 1, iter
, stream
, trace
);
1986 if (CTF_STREAM_FIELD_IS_SET(stream
, stream_id
)) {
1987 /* check that packet header has stream_id field. */
1988 if (!trace
->packet_header_decl
1989 || struct_declaration_lookup_field_index(trace
->packet_header_decl
, g_quark_from_static_string("stream_id")) < 0) {
1991 fprintf(fd
, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__
);
1995 /* Allow only one id-less stream */
1996 if (trace
->streams
->len
!= 0) {
1998 fprintf(fd
, "[error] %s: missing id field in stream declaration\n", __func__
);
2001 stream
->stream_id
= 0;
2003 if (trace
->streams
->len
<= stream
->stream_id
)
2004 g_ptr_array_set_size(trace
->streams
, stream
->stream_id
+ 1);
2005 g_ptr_array_index(trace
->streams
, stream
->stream_id
) = stream
;
2006 stream
->trace
= trace
;
2011 if (stream
->event_header_decl
)
2012 declaration_unref(&stream
->event_header_decl
->p
);
2013 if (stream
->event_context_decl
)
2014 declaration_unref(&stream
->event_context_decl
->p
);
2015 if (stream
->packet_context_decl
)
2016 declaration_unref(&stream
->packet_context_decl
->p
);
2017 g_ptr_array_free(stream
->streams
, TRUE
);
2018 g_ptr_array_free(stream
->events_by_id
, TRUE
);
2019 g_hash_table_destroy(stream
->event_quark_to_id
);
2020 free_declaration_scope(stream
->declaration_scope
);
2026 int ctf_trace_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2030 switch (node
->type
) {
2032 ret
= ctf_typedef_visit(fd
, depth
+ 1,
2033 trace
->declaration_scope
,
2034 node
->u
._typedef
.type_specifier_list
,
2035 &node
->u
._typedef
.type_declarators
,
2040 case NODE_TYPEALIAS
:
2041 ret
= ctf_typealias_visit(fd
, depth
+ 1,
2042 trace
->declaration_scope
,
2043 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
2048 case NODE_CTF_EXPRESSION
:
2052 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2053 if (!strcmp(left
, "major")) {
2054 if (CTF_TRACE_FIELD_IS_SET(trace
, major
)) {
2055 fprintf(fd
, "[error] %s: major already declared in trace declaration\n", __func__
);
2059 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->major
);
2061 fprintf(fd
, "[error] %s: unexpected unary expression for trace major number\n", __func__
);
2065 CTF_TRACE_SET_FIELD(trace
, major
);
2066 } else if (!strcmp(left
, "minor")) {
2067 if (CTF_TRACE_FIELD_IS_SET(trace
, minor
)) {
2068 fprintf(fd
, "[error] %s: minor already declared in trace declaration\n", __func__
);
2072 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->minor
);
2074 fprintf(fd
, "[error] %s: unexpected unary expression for trace minor number\n", __func__
);
2078 CTF_TRACE_SET_FIELD(trace
, minor
);
2079 } else if (!strcmp(left
, "uuid")) {
2080 unsigned char uuid
[BABELTRACE_UUID_LEN
];
2082 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
, uuid
);
2084 fprintf(fd
, "[error] %s: unexpected unary expression for trace uuid\n", __func__
);
2088 if (CTF_TRACE_FIELD_IS_SET(trace
, uuid
)
2089 && babeltrace_uuid_compare(uuid
, trace
->uuid
)) {
2090 fprintf(fd
, "[error] %s: uuid mismatch\n", __func__
);
2094 memcpy(trace
->uuid
, uuid
, sizeof(uuid
));
2096 CTF_TRACE_SET_FIELD(trace
, uuid
);
2097 } else if (!strcmp(left
, "byte_order")) {
2098 struct ctf_node
*right
;
2101 right
= _bt_list_first_entry(&node
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
2102 byte_order
= get_trace_byte_order(fd
, depth
, right
);
2106 if (CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)
2107 && byte_order
!= trace
->byte_order
) {
2108 fprintf(fd
, "[error] %s: endianness mismatch\n", __func__
);
2112 if (byte_order
!= trace
->byte_order
) {
2113 trace
->byte_order
= byte_order
;
2115 * We need to restart
2116 * construction of the
2117 * intermediate representation.
2119 trace
->field_mask
= 0;
2120 CTF_TRACE_SET_FIELD(trace
, byte_order
);
2125 CTF_TRACE_SET_FIELD(trace
, byte_order
);
2126 } else if (!strcmp(left
, "packet.header")) {
2127 struct declaration
*declaration
;
2129 if (trace
->packet_header_decl
) {
2130 fprintf(fd
, "[error] %s: packet.header already declared in trace declaration\n", __func__
);
2134 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
2135 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
2136 struct ctf_node
, siblings
),
2137 trace
->declaration_scope
, trace
);
2142 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
2146 trace
->packet_header_decl
= container_of(declaration
, struct declaration_struct
, p
);
2148 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__
, left
);
2157 /* TODO: declaration specifier should be added. */
2164 int ctf_trace_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2167 struct ctf_node
*iter
;
2169 if (trace
->declaration_scope
)
2171 trace
->declaration_scope
= new_declaration_scope(trace
->root_declaration_scope
);
2172 trace
->streams
= g_ptr_array_new();
2173 trace
->event_declarations
= g_ptr_array_new();
2174 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
2175 ret
= ctf_trace_declaration_visit(fd
, depth
+ 1, iter
, trace
);
2179 if (!CTF_TRACE_FIELD_IS_SET(trace
, major
)) {
2181 fprintf(fd
, "[error] %s: missing major field in trace declaration\n", __func__
);
2184 if (!CTF_TRACE_FIELD_IS_SET(trace
, minor
)) {
2186 fprintf(fd
, "[error] %s: missing minor field in trace declaration\n", __func__
);
2189 if (!CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)) {
2191 fprintf(fd
, "[error] %s: missing byte_order field in trace declaration\n", __func__
);
2195 if (!CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)) {
2196 /* check that the packet header contains a "magic" field */
2197 if (!trace
->packet_header_decl
2198 || struct_declaration_lookup_field_index(trace
->packet_header_decl
, g_quark_from_static_string("magic")) < 0) {
2200 fprintf(fd
, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__
);
2207 if (trace
->packet_header_decl
) {
2208 declaration_unref(&trace
->packet_header_decl
->p
);
2209 trace
->packet_header_decl
= NULL
;
2211 g_ptr_array_free(trace
->streams
, TRUE
);
2212 g_ptr_array_free(trace
->event_declarations
, TRUE
);
2213 free_declaration_scope(trace
->declaration_scope
);
2214 trace
->declaration_scope
= NULL
;
2219 int ctf_clock_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2220 struct ctf_clock
*clock
, struct ctf_trace
*trace
)
2224 switch (node
->type
) {
2225 case NODE_CTF_EXPRESSION
:
2229 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2230 if (!strcmp(left
, "name")) {
2233 if (CTF_CLOCK_FIELD_IS_SET(clock
, name
)) {
2234 fprintf(fd
, "[error] %s: name already declared in clock declaration\n", __func__
);
2238 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2240 fprintf(fd
, "[error] %s: unexpected unary expression for clock name\n", __func__
);
2244 clock
->name
= g_quark_from_string(right
);
2246 CTF_CLOCK_SET_FIELD(clock
, name
);
2247 } else if (!strcmp(left
, "uuid")) {
2251 fprintf(fd
, "[error] %s: uuid already declared in clock declaration\n", __func__
);
2255 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2257 fprintf(fd
, "[error] %s: unexpected unary expression for clock uuid\n", __func__
);
2261 clock
->uuid
= g_quark_from_string(right
);
2263 } else if (!strcmp(left
, "description")) {
2266 if (clock
->description
) {
2267 fprintf(fd
, "[warning] %s: duplicated clock description\n", __func__
);
2268 goto error
; /* ret is 0, so not an actual error, just warn. */
2270 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2272 fprintf(fd
, "[warning] %s: unexpected unary expression for clock description\n", __func__
);
2273 goto error
; /* ret is 0, so not an actual error, just warn. */
2275 clock
->description
= right
;
2276 } else if (!strcmp(left
, "freq")) {
2277 if (CTF_CLOCK_FIELD_IS_SET(clock
, freq
)) {
2278 fprintf(fd
, "[error] %s: freq already declared in clock declaration\n", __func__
);
2282 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->freq
);
2284 fprintf(fd
, "[error] %s: unexpected unary expression for clock freq\n", __func__
);
2288 CTF_CLOCK_SET_FIELD(clock
, freq
);
2289 } else if (!strcmp(left
, "precision")) {
2290 if (clock
->precision
) {
2291 fprintf(fd
, "[error] %s: precision already declared in clock declaration\n", __func__
);
2295 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->precision
);
2297 fprintf(fd
, "[error] %s: unexpected unary expression for clock precision\n", __func__
);
2301 } else if (!strcmp(left
, "offset_s")) {
2302 if (clock
->offset_s
) {
2303 fprintf(fd
, "[error] %s: offset_s already declared in clock declaration\n", __func__
);
2307 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->offset_s
);
2309 fprintf(fd
, "[error] %s: unexpected unary expression for clock offset_s\n", __func__
);
2313 } else if (!strcmp(left
, "offset")) {
2314 if (clock
->offset
) {
2315 fprintf(fd
, "[error] %s: offset already declared in clock declaration\n", __func__
);
2319 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->offset
);
2321 fprintf(fd
, "[error] %s: unexpected unary expression for clock offset\n", __func__
);
2325 } else if (!strcmp(left
, "absolute")) {
2326 struct ctf_node
*right
;
2328 right
= _bt_list_first_entry(&node
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
2329 ret
= get_boolean(fd
, depth
, right
);
2331 fprintf(fd
, "[error] %s: unexpected \"absolute\" right member\n", __func__
);
2335 clock
->absolute
= ret
;
2337 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__
, left
);
2346 /* TODO: declaration specifier should be added. */
2353 int ctf_clock_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2356 struct ctf_node
*iter
;
2357 struct ctf_clock
*clock
;
2359 clock
= g_new0(struct ctf_clock
, 1);
2360 /* Default clock frequency is set to 1000000000 */
2361 clock
->freq
= 1000000000ULL;
2362 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
2363 ret
= ctf_clock_declaration_visit(fd
, depth
+ 1, iter
, clock
, trace
);
2367 if (opt_clock_force_correlate
) {
2369 * User requested to forcibly correlate the clock
2370 * sources, even if we have no correlatation
2373 if (!clock
->absolute
) {
2374 fprintf(fd
, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2376 clock
->absolute
= 1;
2378 if (!CTF_CLOCK_FIELD_IS_SET(clock
, name
)) {
2380 fprintf(fd
, "[error] %s: missing name field in clock declaration\n", __func__
);
2383 if (g_hash_table_size(trace
->clocks
) > 0) {
2384 fprintf(fd
, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
2388 trace
->single_clock
= clock
;
2389 g_hash_table_insert(trace
->clocks
, (gpointer
) (unsigned long) clock
->name
, clock
);
2393 g_free(clock
->description
);
2399 void ctf_clock_default(FILE *fd
, int depth
, struct ctf_trace
*trace
)
2401 struct ctf_clock
*clock
;
2403 clock
= g_new0(struct ctf_clock
, 1);
2404 clock
->name
= g_quark_from_string("monotonic");
2406 clock
->description
= g_strdup("Default clock");
2407 /* Default clock frequency is set to 1000000000 */
2408 clock
->freq
= 1000000000ULL;
2409 if (opt_clock_force_correlate
) {
2411 * User requested to forcibly correlate the clock
2412 * sources, even if we have no correlatation
2415 if (!clock
->absolute
) {
2416 fprintf(fd
, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2418 clock
->absolute
= 1;
2420 clock
->absolute
= 0; /* Not an absolute reference across traces */
2423 trace
->single_clock
= clock
;
2424 g_hash_table_insert(trace
->clocks
, (gpointer
) (unsigned long) clock
->name
, clock
);
2428 void clock_free(gpointer data
)
2430 struct ctf_clock
*clock
= data
;
2432 g_free(clock
->description
);
2437 int ctf_callsite_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2438 struct ctf_callsite
*callsite
, struct ctf_trace
*trace
)
2442 switch (node
->type
) {
2443 case NODE_CTF_EXPRESSION
:
2447 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2448 if (!strcmp(left
, "name")) {
2451 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, name
)) {
2452 fprintf(fd
, "[error] %s: name already declared in callsite declaration\n", __func__
);
2456 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2458 fprintf(fd
, "[error] %s: unexpected unary expression for callsite name\n", __func__
);
2462 callsite
->name
= g_quark_from_string(right
);
2464 CTF_CALLSITE_SET_FIELD(callsite
, name
);
2465 } else if (!strcmp(left
, "func")) {
2468 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, func
)) {
2469 fprintf(fd
, "[error] %s: func already declared in callsite declaration\n", __func__
);
2473 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2475 fprintf(fd
, "[error] %s: unexpected unary expression for callsite func\n", __func__
);
2479 callsite
->func
= right
;
2480 CTF_CALLSITE_SET_FIELD(callsite
, func
);
2481 } else if (!strcmp(left
, "file")) {
2484 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, file
)) {
2485 fprintf(fd
, "[error] %s: file already declared in callsite declaration\n", __func__
);
2489 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2491 fprintf(fd
, "[error] %s: unexpected unary expression for callsite file\n", __func__
);
2495 callsite
->file
= right
;
2496 CTF_CALLSITE_SET_FIELD(callsite
, file
);
2497 } else if (!strcmp(left
, "line")) {
2498 if (CTF_CALLSITE_FIELD_IS_SET(callsite
, line
)) {
2499 fprintf(fd
, "[error] %s: line already declared in callsite declaration\n", __func__
);
2503 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &callsite
->line
);
2505 fprintf(fd
, "[error] %s: unexpected unary expression for callsite line\n", __func__
);
2509 CTF_CALLSITE_SET_FIELD(callsite
, line
);
2511 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__
, left
);
2520 /* TODO: declaration specifier should be added. */
2527 int ctf_callsite_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2530 struct ctf_node
*iter
;
2531 struct ctf_callsite
*callsite
;
2532 struct ctf_callsite_dups
*cs_dups
;
2534 callsite
= g_new0(struct ctf_callsite
, 1);
2535 bt_list_for_each_entry(iter
, &node
->u
.callsite
.declaration_list
, siblings
) {
2536 ret
= ctf_callsite_declaration_visit(fd
, depth
+ 1, iter
, callsite
, trace
);
2540 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, name
)) {
2542 fprintf(fd
, "[error] %s: missing name field in callsite declaration\n", __func__
);
2545 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, func
)) {
2547 fprintf(fd
, "[error] %s: missing func field in callsite declaration\n", __func__
);
2550 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, file
)) {
2552 fprintf(fd
, "[error] %s: missing file field in callsite declaration\n", __func__
);
2555 if (!CTF_CALLSITE_FIELD_IS_SET(callsite
, line
)) {
2557 fprintf(fd
, "[error] %s: missing line field in callsite declaration\n", __func__
);
2561 cs_dups
= g_hash_table_lookup(trace
->callsites
,
2562 (gpointer
) (unsigned long) callsite
->name
);
2564 cs_dups
= g_new0(struct ctf_callsite_dups
, 1);
2565 BT_INIT_LIST_HEAD(&cs_dups
->head
);
2566 g_hash_table_insert(trace
->callsites
,
2567 (gpointer
) (unsigned long) callsite
->name
, cs_dups
);
2569 bt_list_add_tail(&callsite
->node
, &cs_dups
->head
);
2573 g_free(callsite
->func
);
2574 g_free(callsite
->file
);
2580 void callsite_free(gpointer data
)
2582 struct ctf_callsite_dups
*cs_dups
= data
;
2583 struct ctf_callsite
*callsite
, *cs_n
;
2585 bt_list_for_each_entry_safe(callsite
, cs_n
, &cs_dups
->head
, node
) {
2586 g_free(callsite
->func
);
2587 g_free(callsite
->file
);
2593 int ctf_env_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2594 struct ctf_trace
*trace
)
2597 struct ctf_tracer_env
*env
= &trace
->env
;
2599 switch (node
->type
) {
2600 case NODE_CTF_EXPRESSION
:
2604 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2605 if (!strcmp(left
, "vpid")) {
2608 if (env
->vpid
!= -1) {
2609 fprintf(fd
, "[error] %s: vpid already declared in env declaration\n", __func__
);
2610 goto error
; /* ret is 0, so not an actual error, just warn. */
2612 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &v
);
2614 fprintf(fd
, "[error] %s: unexpected unary expression for env vpid\n", __func__
);
2615 goto error
; /* ret is 0, so not an actual error, just warn. */
2617 env
->vpid
= (int) v
;
2618 printf_verbose("env.vpid = %d\n", env
->vpid
);
2619 } else if (!strcmp(left
, "procname")) {
2622 if (env
->procname
[0]) {
2623 fprintf(fd
, "[warning] %s: duplicated env procname\n", __func__
);
2624 goto error
; /* ret is 0, so not an actual error, just warn. */
2626 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2628 fprintf(fd
, "[warning] %s: unexpected unary expression for env procname\n", __func__
);
2629 goto error
; /* ret is 0, so not an actual error, just warn. */
2631 strncpy(env
->procname
, right
, TRACER_ENV_LEN
);
2632 env
->procname
[TRACER_ENV_LEN
- 1] = '\0';
2633 printf_verbose("env.procname = \"%s\"\n", env
->procname
);
2634 } else if (!strcmp(left
, "hostname")) {
2637 if (env
->hostname
[0]) {
2638 fprintf(fd
, "[warning] %s: duplicated env hostname\n", __func__
);
2639 goto error
; /* ret is 0, so not an actual error, just warn. */
2641 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2643 fprintf(fd
, "[warning] %s: unexpected unary expression for env hostname\n", __func__
);
2644 goto error
; /* ret is 0, so not an actual error, just warn. */
2646 strncpy(env
->hostname
, right
, TRACER_ENV_LEN
);
2647 env
->hostname
[TRACER_ENV_LEN
- 1] = '\0';
2648 printf_verbose("env.hostname = \"%s\"\n", env
->hostname
);
2649 } else if (!strcmp(left
, "domain")) {
2652 if (env
->domain
[0]) {
2653 fprintf(fd
, "[warning] %s: duplicated env domain\n", __func__
);
2654 goto error
; /* ret is 0, so not an actual error, just warn. */
2656 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2658 fprintf(fd
, "[warning] %s: unexpected unary expression for env domain\n", __func__
);
2659 goto error
; /* ret is 0, so not an actual error, just warn. */
2661 strncpy(env
->domain
, right
, TRACER_ENV_LEN
);
2662 env
->domain
[TRACER_ENV_LEN
- 1] = '\0';
2663 printf_verbose("env.domain = \"%s\"\n", env
->domain
);
2664 } else if (!strcmp(left
, "sysname")) {
2667 if (env
->sysname
[0]) {
2668 fprintf(fd
, "[warning] %s: duplicated env sysname\n", __func__
);
2669 goto error
; /* ret is 0, so not an actual error, just warn. */
2671 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2673 fprintf(fd
, "[warning] %s: unexpected unary expression for env sysname\n", __func__
);
2674 goto error
; /* ret is 0, so not an actual error, just warn. */
2676 strncpy(env
->sysname
, right
, TRACER_ENV_LEN
);
2677 env
->sysname
[TRACER_ENV_LEN
- 1] = '\0';
2678 printf_verbose("env.sysname = \"%s\"\n", env
->sysname
);
2679 } else if (!strcmp(left
, "kernel_release")) {
2682 if (env
->release
[0]) {
2683 fprintf(fd
, "[warning] %s: duplicated env release\n", __func__
);
2684 goto error
; /* ret is 0, so not an actual error, just warn. */
2686 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2688 fprintf(fd
, "[warning] %s: unexpected unary expression for env release\n", __func__
);
2689 goto error
; /* ret is 0, so not an actual error, just warn. */
2691 strncpy(env
->release
, right
, TRACER_ENV_LEN
);
2692 env
->release
[TRACER_ENV_LEN
- 1] = '\0';
2693 printf_verbose("env.release = \"%s\"\n", env
->release
);
2694 } else if (!strcmp(left
, "kernel_version")) {
2697 if (env
->version
[0]) {
2698 fprintf(fd
, "[warning] %s: duplicated env version\n", __func__
);
2699 goto error
; /* ret is 0, so not an actual error, just warn. */
2701 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2703 fprintf(fd
, "[warning] %s: unexpected unary expression for env version\n", __func__
);
2704 goto error
; /* ret is 0, so not an actual error, just warn. */
2706 strncpy(env
->version
, right
, TRACER_ENV_LEN
);
2707 env
->version
[TRACER_ENV_LEN
- 1] = '\0';
2708 printf_verbose("env.version = \"%s\"\n", env
->version
);
2710 if (is_unary_string(&node
->u
.ctf_expression
.right
)) {
2713 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2714 printf_verbose("env.%s = \"%s\"\n", left
, right
);
2715 } else if (is_unary_unsigned(&node
->u
.ctf_expression
.right
)) {
2719 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &v
);
2721 printf_verbose("env.%s = %" PRIu64
"\n", left
, v
);
2722 } else if (is_unary_signed(&node
->u
.ctf_expression
.right
)) {
2726 ret
= get_unary_signed(&node
->u
.ctf_expression
.right
, &v
);
2728 printf_verbose("env.%s = %" PRId64
"\n", left
, v
);
2730 printf_verbose("%s: attribute \"%s\" has unknown type.\n", __func__
, left
);
2746 int ctf_env_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2749 struct ctf_node
*iter
;
2751 trace
->env
.vpid
= -1;
2752 trace
->env
.procname
[0] = '\0';
2753 trace
->env
.hostname
[0] = '\0';
2754 trace
->env
.domain
[0] = '\0';
2755 trace
->env
.sysname
[0] = '\0';
2756 trace
->env
.release
[0] = '\0';
2757 trace
->env
.version
[0] = '\0';
2758 bt_list_for_each_entry(iter
, &node
->u
.env
.declaration_list
, siblings
) {
2759 ret
= ctf_env_declaration_visit(fd
, depth
+ 1, iter
, trace
);
2768 int ctf_root_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2772 switch (node
->type
) {
2774 ret
= ctf_typedef_visit(fd
, depth
+ 1,
2775 trace
->root_declaration_scope
,
2776 node
->u
._typedef
.type_specifier_list
,
2777 &node
->u
._typedef
.type_declarators
,
2782 case NODE_TYPEALIAS
:
2783 ret
= ctf_typealias_visit(fd
, depth
+ 1,
2784 trace
->root_declaration_scope
,
2785 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
2790 case NODE_TYPE_SPECIFIER_LIST
:
2792 struct declaration
*declaration
;
2795 * Just add the type specifier to the root scope
2796 * declaration scope. Release local reference.
2798 declaration
= ctf_type_specifier_list_visit(fd
, depth
+ 1,
2799 node
, trace
->root_declaration_scope
, trace
);
2802 declaration_unref(declaration
);
2812 /* TODO: missing metadata "destroy" (memory leak) */
2813 int ctf_visitor_construct_metadata(FILE *fd
, int depth
, struct ctf_node
*node
,
2814 struct ctf_trace
*trace
, int byte_order
)
2817 struct ctf_node
*iter
;
2818 int env_clock_done
= 0;
2820 printf_verbose("CTF visitor: metadata construction... ");
2821 trace
->byte_order
= byte_order
;
2822 trace
->clocks
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
2824 trace
->callsites
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
2825 NULL
, callsite_free
);
2828 trace
->root_declaration_scope
= new_declaration_scope(NULL
);
2830 switch (node
->type
) {
2832 if (!env_clock_done
) {
2834 * declarations need to query clock hash table,
2835 * so clock need to be treated first.
2837 if (bt_list_empty(&node
->u
.root
.clock
)) {
2838 ctf_clock_default(fd
, depth
+ 1, trace
);
2840 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
2841 ret
= ctf_clock_visit(fd
, depth
+ 1, iter
,
2844 fprintf(fd
, "[error] %s: clock declaration error\n", __func__
);
2851 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
2853 ret
= ctf_root_declaration_visit(fd
, depth
+ 1, iter
, trace
);
2855 fprintf(fd
, "[error] %s: root declaration error\n", __func__
);
2859 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
2860 ret
= ctf_trace_visit(fd
, depth
+ 1, iter
, trace
);
2861 if (ret
== -EINTR
) {
2862 free_declaration_scope(trace
->root_declaration_scope
);
2864 * Need to restart creation of type
2865 * definitions, aliases and
2866 * trace header declarations.
2871 fprintf(fd
, "[error] %s: trace declaration error\n", __func__
);
2875 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
2876 ret
= ctf_callsite_visit(fd
, depth
+ 1, iter
,
2879 fprintf(fd
, "[error] %s: callsite declaration error\n", __func__
);
2883 if (!trace
->streams
) {
2884 fprintf(fd
, "[error] %s: missing trace declaration\n", __func__
);
2888 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
2889 ret
= ctf_env_visit(fd
, depth
+ 1, iter
, trace
);
2891 fprintf(fd
, "[error] %s: env declaration error\n", __func__
);
2895 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
2896 ret
= ctf_stream_visit(fd
, depth
+ 1, iter
,
2897 trace
->root_declaration_scope
, trace
);
2899 fprintf(fd
, "[error] %s: stream declaration error\n", __func__
);
2903 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
2904 ret
= ctf_event_visit(fd
, depth
+ 1, iter
,
2905 trace
->root_declaration_scope
, trace
);
2907 fprintf(fd
, "[error] %s: event declaration error\n", __func__
);
2914 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
2919 printf_verbose("done.\n");
2923 free_declaration_scope(trace
->root_declaration_scope
);
2924 g_hash_table_destroy(trace
->callsites
);
2925 g_hash_table_destroy(trace
->clocks
);