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
);
1745 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__
, left
);
1746 /* Fall-through after warning */
1754 /* TODO: declaration specifier should be added. */
1761 int ctf_event_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
1762 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
1765 struct ctf_node
*iter
;
1766 struct ctf_event_declaration
*event
;
1767 struct bt_ctf_event_decl
*event_decl
;
1769 event_decl
= g_new0(struct bt_ctf_event_decl
, 1);
1770 event
= &event_decl
->parent
;
1771 event
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
1772 event
->loglevel
= -1;
1773 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
1774 ret
= ctf_event_declaration_visit(fd
, depth
+ 1, iter
, event
, trace
);
1778 if (!CTF_EVENT_FIELD_IS_SET(event
, name
)) {
1780 fprintf(fd
, "[error] %s: missing name field in event declaration\n", __func__
);
1783 if (!CTF_EVENT_FIELD_IS_SET(event
, stream_id
)) {
1784 /* Allow missing stream_id if there is only a single stream */
1785 switch (trace
->streams
->len
) {
1786 case 0: /* Create stream if there was none. */
1787 ret
= ctf_stream_visit(fd
, depth
, NULL
, trace
->root_declaration_scope
, trace
);
1792 event
->stream_id
= 0;
1793 event
->stream
= trace_stream_lookup(trace
, event
->stream_id
);
1797 fprintf(fd
, "[error] %s: missing stream_id field in event declaration\n", __func__
);
1801 /* Allow only one event without id per stream */
1802 if (!CTF_EVENT_FIELD_IS_SET(event
, id
)
1803 && event
->stream
->events_by_id
->len
!= 0) {
1805 fprintf(fd
, "[error] %s: missing id field in event declaration\n", __func__
);
1808 if (event
->stream
->events_by_id
->len
<= event
->id
)
1809 g_ptr_array_set_size(event
->stream
->events_by_id
, event
->id
+ 1);
1810 g_ptr_array_index(event
->stream
->events_by_id
, event
->id
) = event
;
1811 g_hash_table_insert(event
->stream
->event_quark_to_id
,
1812 (gpointer
) (unsigned long) event
->name
,
1814 g_ptr_array_add(trace
->event_declarations
, event_decl
);
1818 if (event
->fields_decl
)
1819 declaration_unref(&event
->fields_decl
->p
);
1820 if (event
->context_decl
)
1821 declaration_unref(&event
->context_decl
->p
);
1822 free_declaration_scope(event
->declaration_scope
);
1829 int ctf_stream_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_stream_declaration
*stream
, struct ctf_trace
*trace
)
1833 switch (node
->type
) {
1835 ret
= ctf_typedef_visit(fd
, depth
+ 1,
1836 stream
->declaration_scope
,
1837 node
->u
._typedef
.type_specifier_list
,
1838 &node
->u
._typedef
.type_declarators
,
1843 case NODE_TYPEALIAS
:
1844 ret
= ctf_typealias_visit(fd
, depth
+ 1,
1845 stream
->declaration_scope
,
1846 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
1851 case NODE_CTF_EXPRESSION
:
1855 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
1856 if (!strcmp(left
, "id")) {
1857 if (CTF_STREAM_FIELD_IS_SET(stream
, stream_id
)) {
1858 fprintf(fd
, "[error] %s: id already declared in stream declaration\n", __func__
);
1862 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &stream
->stream_id
);
1864 fprintf(fd
, "[error] %s: unexpected unary expression for stream id\n", __func__
);
1868 CTF_STREAM_SET_FIELD(stream
, stream_id
);
1869 } else if (!strcmp(left
, "event.header")) {
1870 struct declaration
*declaration
;
1872 if (stream
->event_header_decl
) {
1873 fprintf(fd
, "[error] %s: event.header already declared in stream declaration\n", __func__
);
1877 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1878 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1879 struct ctf_node
, siblings
),
1880 stream
->declaration_scope
, trace
);
1885 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1889 stream
->event_header_decl
= container_of(declaration
, struct declaration_struct
, p
);
1890 } else if (!strcmp(left
, "event.context")) {
1891 struct declaration
*declaration
;
1893 if (stream
->event_context_decl
) {
1894 fprintf(fd
, "[error] %s: event.context already declared in stream declaration\n", __func__
);
1898 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1899 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1900 struct ctf_node
, siblings
),
1901 stream
->declaration_scope
, trace
);
1906 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1910 stream
->event_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
1911 } else if (!strcmp(left
, "packet.context")) {
1912 struct declaration
*declaration
;
1914 if (stream
->packet_context_decl
) {
1915 fprintf(fd
, "[error] %s: packet.context already declared in stream declaration\n", __func__
);
1919 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
1920 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
1921 struct ctf_node
, siblings
),
1922 stream
->declaration_scope
, trace
);
1927 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
1931 stream
->packet_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
1933 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__
, left
);
1934 /* Fall-through after warning */
1943 /* TODO: declaration specifier should be added. */
1950 int ctf_stream_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
1951 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
1954 struct ctf_node
*iter
;
1955 struct ctf_stream_declaration
*stream
;
1957 stream
= g_new0(struct ctf_stream_declaration
, 1);
1958 stream
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
1959 stream
->events_by_id
= g_ptr_array_new();
1960 stream
->event_quark_to_id
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
1961 stream
->streams
= g_ptr_array_new();
1963 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
1964 ret
= ctf_stream_declaration_visit(fd
, depth
+ 1, iter
, stream
, trace
);
1969 if (CTF_STREAM_FIELD_IS_SET(stream
, stream_id
)) {
1970 /* check that packet header has stream_id field. */
1971 if (!trace
->packet_header_decl
1972 || struct_declaration_lookup_field_index(trace
->packet_header_decl
, g_quark_from_static_string("stream_id")) < 0) {
1974 fprintf(fd
, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__
);
1978 /* Allow only one id-less stream */
1979 if (trace
->streams
->len
!= 0) {
1981 fprintf(fd
, "[error] %s: missing id field in stream declaration\n", __func__
);
1984 stream
->stream_id
= 0;
1986 if (trace
->streams
->len
<= stream
->stream_id
)
1987 g_ptr_array_set_size(trace
->streams
, stream
->stream_id
+ 1);
1988 g_ptr_array_index(trace
->streams
, stream
->stream_id
) = stream
;
1989 stream
->trace
= trace
;
1994 if (stream
->event_header_decl
)
1995 declaration_unref(&stream
->event_header_decl
->p
);
1996 if (stream
->event_context_decl
)
1997 declaration_unref(&stream
->event_context_decl
->p
);
1998 if (stream
->packet_context_decl
)
1999 declaration_unref(&stream
->packet_context_decl
->p
);
2000 g_ptr_array_free(stream
->streams
, TRUE
);
2001 g_ptr_array_free(stream
->events_by_id
, TRUE
);
2002 g_hash_table_destroy(stream
->event_quark_to_id
);
2003 free_declaration_scope(stream
->declaration_scope
);
2009 int ctf_trace_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2013 switch (node
->type
) {
2015 ret
= ctf_typedef_visit(fd
, depth
+ 1,
2016 trace
->declaration_scope
,
2017 node
->u
._typedef
.type_specifier_list
,
2018 &node
->u
._typedef
.type_declarators
,
2023 case NODE_TYPEALIAS
:
2024 ret
= ctf_typealias_visit(fd
, depth
+ 1,
2025 trace
->declaration_scope
,
2026 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
2031 case NODE_CTF_EXPRESSION
:
2035 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2036 if (!strcmp(left
, "major")) {
2037 if (CTF_TRACE_FIELD_IS_SET(trace
, major
)) {
2038 fprintf(fd
, "[error] %s: major already declared in trace declaration\n", __func__
);
2042 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->major
);
2044 fprintf(fd
, "[error] %s: unexpected unary expression for trace major number\n", __func__
);
2048 CTF_TRACE_SET_FIELD(trace
, major
);
2049 } else if (!strcmp(left
, "minor")) {
2050 if (CTF_TRACE_FIELD_IS_SET(trace
, minor
)) {
2051 fprintf(fd
, "[error] %s: minor already declared in trace declaration\n", __func__
);
2055 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->minor
);
2057 fprintf(fd
, "[error] %s: unexpected unary expression for trace minor number\n", __func__
);
2061 CTF_TRACE_SET_FIELD(trace
, minor
);
2062 } else if (!strcmp(left
, "uuid")) {
2063 unsigned char uuid
[BABELTRACE_UUID_LEN
];
2065 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
, uuid
);
2067 fprintf(fd
, "[error] %s: unexpected unary expression for trace uuid\n", __func__
);
2071 if (CTF_TRACE_FIELD_IS_SET(trace
, uuid
)
2072 && babeltrace_uuid_compare(uuid
, trace
->uuid
)) {
2073 fprintf(fd
, "[error] %s: uuid mismatch\n", __func__
);
2077 memcpy(trace
->uuid
, uuid
, sizeof(uuid
));
2079 CTF_TRACE_SET_FIELD(trace
, uuid
);
2080 } else if (!strcmp(left
, "byte_order")) {
2081 struct ctf_node
*right
;
2084 right
= _bt_list_first_entry(&node
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
2085 byte_order
= get_trace_byte_order(fd
, depth
, right
);
2089 if (CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)
2090 && byte_order
!= trace
->byte_order
) {
2091 fprintf(fd
, "[error] %s: endianness mismatch\n", __func__
);
2095 if (byte_order
!= trace
->byte_order
) {
2096 trace
->byte_order
= byte_order
;
2098 * We need to restart
2099 * construction of the
2100 * intermediate representation.
2102 trace
->field_mask
= 0;
2103 CTF_TRACE_SET_FIELD(trace
, byte_order
);
2108 CTF_TRACE_SET_FIELD(trace
, byte_order
);
2109 } else if (!strcmp(left
, "packet.header")) {
2110 struct declaration
*declaration
;
2112 if (trace
->packet_header_decl
) {
2113 fprintf(fd
, "[error] %s: packet.header already declared in trace declaration\n", __func__
);
2117 declaration
= ctf_type_specifier_list_visit(fd
, depth
,
2118 _bt_list_first_entry(&node
->u
.ctf_expression
.right
,
2119 struct ctf_node
, siblings
),
2120 trace
->declaration_scope
, trace
);
2125 if (declaration
->id
!= CTF_TYPE_STRUCT
) {
2129 trace
->packet_header_decl
= container_of(declaration
, struct declaration_struct
, p
);
2131 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__
, left
);
2140 /* TODO: declaration specifier should be added. */
2147 int ctf_trace_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2150 struct ctf_node
*iter
;
2152 if (trace
->declaration_scope
)
2154 trace
->declaration_scope
= new_declaration_scope(trace
->root_declaration_scope
);
2155 trace
->streams
= g_ptr_array_new();
2156 trace
->event_declarations
= g_ptr_array_new();
2157 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
2158 ret
= ctf_trace_declaration_visit(fd
, depth
+ 1, iter
, trace
);
2162 if (!CTF_TRACE_FIELD_IS_SET(trace
, major
)) {
2164 fprintf(fd
, "[error] %s: missing major field in trace declaration\n", __func__
);
2167 if (!CTF_TRACE_FIELD_IS_SET(trace
, minor
)) {
2169 fprintf(fd
, "[error] %s: missing minor field in trace declaration\n", __func__
);
2172 if (!CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)) {
2174 fprintf(fd
, "[error] %s: missing byte_order field in trace declaration\n", __func__
);
2178 if (!CTF_TRACE_FIELD_IS_SET(trace
, byte_order
)) {
2179 /* check that the packet header contains a "magic" field */
2180 if (!trace
->packet_header_decl
2181 || struct_declaration_lookup_field_index(trace
->packet_header_decl
, g_quark_from_static_string("magic")) < 0) {
2183 fprintf(fd
, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__
);
2190 if (trace
->packet_header_decl
) {
2191 declaration_unref(&trace
->packet_header_decl
->p
);
2192 trace
->packet_header_decl
= NULL
;
2194 g_ptr_array_free(trace
->streams
, TRUE
);
2195 g_ptr_array_free(trace
->event_declarations
, TRUE
);
2196 free_declaration_scope(trace
->declaration_scope
);
2197 trace
->declaration_scope
= NULL
;
2202 int ctf_clock_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2203 struct ctf_clock
*clock
, struct ctf_trace
*trace
)
2207 switch (node
->type
) {
2208 case NODE_CTF_EXPRESSION
:
2212 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2213 if (!strcmp(left
, "name")) {
2216 if (CTF_CLOCK_FIELD_IS_SET(clock
, name
)) {
2217 fprintf(fd
, "[error] %s: name already declared in clock declaration\n", __func__
);
2221 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2223 fprintf(fd
, "[error] %s: unexpected unary expression for clock name\n", __func__
);
2227 clock
->name
= g_quark_from_string(right
);
2229 CTF_CLOCK_SET_FIELD(clock
, name
);
2230 } else if (!strcmp(left
, "uuid")) {
2234 fprintf(fd
, "[error] %s: uuid 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 uuid\n", __func__
);
2244 clock
->uuid
= g_quark_from_string(right
);
2246 } else if (!strcmp(left
, "description")) {
2249 if (clock
->description
) {
2250 fprintf(fd
, "[warning] %s: duplicated clock description\n", __func__
);
2251 goto error
; /* ret is 0, so not an actual error, just warn. */
2253 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2255 fprintf(fd
, "[warning] %s: unexpected unary expression for clock description\n", __func__
);
2256 goto error
; /* ret is 0, so not an actual error, just warn. */
2258 clock
->description
= right
;
2259 } else if (!strcmp(left
, "freq")) {
2260 if (CTF_CLOCK_FIELD_IS_SET(clock
, freq
)) {
2261 fprintf(fd
, "[error] %s: freq already declared in clock declaration\n", __func__
);
2265 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->freq
);
2267 fprintf(fd
, "[error] %s: unexpected unary expression for clock freq\n", __func__
);
2271 CTF_CLOCK_SET_FIELD(clock
, freq
);
2272 } else if (!strcmp(left
, "precision")) {
2273 if (clock
->precision
) {
2274 fprintf(fd
, "[error] %s: precision already declared in clock declaration\n", __func__
);
2278 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->precision
);
2280 fprintf(fd
, "[error] %s: unexpected unary expression for clock precision\n", __func__
);
2284 } else if (!strcmp(left
, "offset_s")) {
2285 if (clock
->offset_s
) {
2286 fprintf(fd
, "[error] %s: offset_s already declared in clock declaration\n", __func__
);
2290 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->offset_s
);
2292 fprintf(fd
, "[error] %s: unexpected unary expression for clock offset_s\n", __func__
);
2296 } else if (!strcmp(left
, "offset")) {
2297 if (clock
->offset
) {
2298 fprintf(fd
, "[error] %s: offset already declared in clock declaration\n", __func__
);
2302 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &clock
->offset
);
2304 fprintf(fd
, "[error] %s: unexpected unary expression for clock offset\n", __func__
);
2308 } else if (!strcmp(left
, "absolute")) {
2309 struct ctf_node
*right
;
2311 right
= _bt_list_first_entry(&node
->u
.ctf_expression
.right
, struct ctf_node
, siblings
);
2312 ret
= get_boolean(fd
, depth
, right
);
2314 fprintf(fd
, "[error] %s: unexpected \"absolute\" right member\n", __func__
);
2318 clock
->absolute
= ret
;
2320 fprintf(fd
, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__
, left
);
2329 /* TODO: declaration specifier should be added. */
2336 int ctf_clock_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2339 struct ctf_node
*iter
;
2340 struct ctf_clock
*clock
;
2342 clock
= g_new0(struct ctf_clock
, 1);
2343 /* Default clock frequency is set to 1000000000 */
2344 clock
->freq
= 1000000000ULL;
2345 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
2346 ret
= ctf_clock_declaration_visit(fd
, depth
+ 1, iter
, clock
, trace
);
2350 if (opt_clock_force_correlate
) {
2352 * User requested to forcibly correlate the clock
2353 * sources, even if we have no correlatation
2356 if (!clock
->absolute
) {
2357 fprintf(fd
, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2359 clock
->absolute
= 1;
2361 if (!CTF_CLOCK_FIELD_IS_SET(clock
, name
)) {
2363 fprintf(fd
, "[error] %s: missing name field in clock declaration\n", __func__
);
2366 if (g_hash_table_size(trace
->clocks
) > 0) {
2367 fprintf(fd
, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
2371 trace
->single_clock
= clock
;
2372 g_hash_table_insert(trace
->clocks
, (gpointer
) (unsigned long) clock
->name
, clock
);
2376 g_free(clock
->description
);
2382 void ctf_clock_default(FILE *fd
, int depth
, struct ctf_trace
*trace
)
2384 struct ctf_clock
*clock
;
2386 clock
= g_new0(struct ctf_clock
, 1);
2387 clock
->name
= g_quark_from_string("monotonic");
2389 clock
->description
= g_strdup("Default clock");
2390 /* Default clock frequency is set to 1000000000 */
2391 clock
->freq
= 1000000000ULL;
2392 if (opt_clock_force_correlate
) {
2394 * User requested to forcibly correlate the clock
2395 * sources, even if we have no correlatation
2398 if (!clock
->absolute
) {
2399 fprintf(fd
, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2401 clock
->absolute
= 1;
2403 clock
->absolute
= 0; /* Not an absolute reference across traces */
2406 trace
->single_clock
= clock
;
2407 g_hash_table_insert(trace
->clocks
, (gpointer
) (unsigned long) clock
->name
, clock
);
2411 void clock_free(gpointer data
)
2413 struct ctf_clock
*clock
= data
;
2415 g_free(clock
->description
);
2420 int ctf_env_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
2421 struct ctf_trace
*trace
)
2424 struct ctf_tracer_env
*env
= &trace
->env
;
2426 switch (node
->type
) {
2427 case NODE_CTF_EXPRESSION
:
2431 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
2432 if (!strcmp(left
, "vpid")) {
2435 if (env
->vpid
!= -1) {
2436 fprintf(fd
, "[error] %s: vpid already declared in env declaration\n", __func__
);
2437 goto error
; /* ret is 0, so not an actual error, just warn. */
2439 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &v
);
2441 fprintf(fd
, "[error] %s: unexpected unary expression for env vpid\n", __func__
);
2442 goto error
; /* ret is 0, so not an actual error, just warn. */
2444 env
->vpid
= (int) v
;
2445 printf_verbose("env.vpid = %d\n", env
->vpid
);
2446 } else if (!strcmp(left
, "procname")) {
2449 if (env
->procname
[0]) {
2450 fprintf(fd
, "[warning] %s: duplicated env procname\n", __func__
);
2451 goto error
; /* ret is 0, so not an actual error, just warn. */
2453 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2455 fprintf(fd
, "[warning] %s: unexpected unary expression for env procname\n", __func__
);
2456 goto error
; /* ret is 0, so not an actual error, just warn. */
2458 strncpy(env
->procname
, right
, TRACER_ENV_LEN
);
2459 env
->procname
[TRACER_ENV_LEN
- 1] = '\0';
2460 printf_verbose("env.procname = \"%s\"\n", env
->procname
);
2461 } else if (!strcmp(left
, "hostname")) {
2464 if (env
->hostname
[0]) {
2465 fprintf(fd
, "[warning] %s: duplicated env hostname\n", __func__
);
2466 goto error
; /* ret is 0, so not an actual error, just warn. */
2468 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2470 fprintf(fd
, "[warning] %s: unexpected unary expression for env hostname\n", __func__
);
2471 goto error
; /* ret is 0, so not an actual error, just warn. */
2473 strncpy(env
->hostname
, right
, TRACER_ENV_LEN
);
2474 env
->hostname
[TRACER_ENV_LEN
- 1] = '\0';
2475 printf_verbose("env.hostname = \"%s\"\n", env
->hostname
);
2476 } else if (!strcmp(left
, "domain")) {
2479 if (env
->domain
[0]) {
2480 fprintf(fd
, "[warning] %s: duplicated env domain\n", __func__
);
2481 goto error
; /* ret is 0, so not an actual error, just warn. */
2483 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2485 fprintf(fd
, "[warning] %s: unexpected unary expression for env domain\n", __func__
);
2486 goto error
; /* ret is 0, so not an actual error, just warn. */
2488 strncpy(env
->domain
, right
, TRACER_ENV_LEN
);
2489 env
->domain
[TRACER_ENV_LEN
- 1] = '\0';
2490 printf_verbose("env.domain = \"%s\"\n", env
->domain
);
2491 } else if (!strcmp(left
, "sysname")) {
2494 if (env
->sysname
[0]) {
2495 fprintf(fd
, "[warning] %s: duplicated env sysname\n", __func__
);
2496 goto error
; /* ret is 0, so not an actual error, just warn. */
2498 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2500 fprintf(fd
, "[warning] %s: unexpected unary expression for env sysname\n", __func__
);
2501 goto error
; /* ret is 0, so not an actual error, just warn. */
2503 strncpy(env
->sysname
, right
, TRACER_ENV_LEN
);
2504 env
->sysname
[TRACER_ENV_LEN
- 1] = '\0';
2505 printf_verbose("env.sysname = \"%s\"\n", env
->sysname
);
2506 } else if (!strcmp(left
, "kernel_release")) {
2509 if (env
->release
[0]) {
2510 fprintf(fd
, "[warning] %s: duplicated env release\n", __func__
);
2511 goto error
; /* ret is 0, so not an actual error, just warn. */
2513 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2515 fprintf(fd
, "[warning] %s: unexpected unary expression for env release\n", __func__
);
2516 goto error
; /* ret is 0, so not an actual error, just warn. */
2518 strncpy(env
->release
, right
, TRACER_ENV_LEN
);
2519 env
->release
[TRACER_ENV_LEN
- 1] = '\0';
2520 printf_verbose("env.release = \"%s\"\n", env
->release
);
2521 } else if (!strcmp(left
, "kernel_version")) {
2524 if (env
->version
[0]) {
2525 fprintf(fd
, "[warning] %s: duplicated env version\n", __func__
);
2526 goto error
; /* ret is 0, so not an actual error, just warn. */
2528 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2530 fprintf(fd
, "[warning] %s: unexpected unary expression for env version\n", __func__
);
2531 goto error
; /* ret is 0, so not an actual error, just warn. */
2533 strncpy(env
->version
, right
, TRACER_ENV_LEN
);
2534 env
->version
[TRACER_ENV_LEN
- 1] = '\0';
2535 printf_verbose("env.version = \"%s\"\n", env
->version
);
2537 if (is_unary_string(&node
->u
.ctf_expression
.right
)) {
2540 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
2541 printf_verbose("env.%s = \"%s\"\n", left
, right
);
2542 } else if (is_unary_unsigned(&node
->u
.ctf_expression
.right
)) {
2546 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &v
);
2548 printf_verbose("env.%s = %" PRIu64
"\n", left
, v
);
2549 } else if (is_unary_signed(&node
->u
.ctf_expression
.right
)) {
2553 ret
= get_unary_signed(&node
->u
.ctf_expression
.right
, &v
);
2555 printf_verbose("env.%s = %" PRId64
"\n", left
, v
);
2557 printf_verbose("%s: attribute \"%s\" has unknown type.\n", __func__
, left
);
2573 int ctf_env_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2576 struct ctf_node
*iter
;
2578 trace
->env
.vpid
= -1;
2579 trace
->env
.procname
[0] = '\0';
2580 trace
->env
.hostname
[0] = '\0';
2581 trace
->env
.domain
[0] = '\0';
2582 trace
->env
.sysname
[0] = '\0';
2583 trace
->env
.release
[0] = '\0';
2584 trace
->env
.version
[0] = '\0';
2585 bt_list_for_each_entry(iter
, &node
->u
.env
.declaration_list
, siblings
) {
2586 ret
= ctf_env_declaration_visit(fd
, depth
+ 1, iter
, trace
);
2595 int ctf_root_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
2599 switch (node
->type
) {
2601 ret
= ctf_typedef_visit(fd
, depth
+ 1,
2602 trace
->root_declaration_scope
,
2603 node
->u
._typedef
.type_specifier_list
,
2604 &node
->u
._typedef
.type_declarators
,
2609 case NODE_TYPEALIAS
:
2610 ret
= ctf_typealias_visit(fd
, depth
+ 1,
2611 trace
->root_declaration_scope
,
2612 node
->u
.typealias
.target
, node
->u
.typealias
.alias
,
2617 case NODE_TYPE_SPECIFIER_LIST
:
2619 struct declaration
*declaration
;
2622 * Just add the type specifier to the root scope
2623 * declaration scope. Release local reference.
2625 declaration
= ctf_type_specifier_list_visit(fd
, depth
+ 1,
2626 node
, trace
->root_declaration_scope
, trace
);
2629 declaration_unref(declaration
);
2639 /* TODO: missing metadata "destroy" (memory leak) */
2640 int ctf_visitor_construct_metadata(FILE *fd
, int depth
, struct ctf_node
*node
,
2641 struct ctf_trace
*trace
, int byte_order
)
2644 struct ctf_node
*iter
;
2645 int env_clock_done
= 0;
2647 printf_verbose("CTF visitor: metadata construction... ");
2648 trace
->byte_order
= byte_order
;
2649 trace
->clocks
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
2653 trace
->root_declaration_scope
= new_declaration_scope(NULL
);
2655 switch (node
->type
) {
2657 if (!env_clock_done
) {
2659 * declarations need to query clock hash table,
2660 * so clock need to be treated first.
2662 if (bt_list_empty(&node
->u
.root
.clock
)) {
2663 ctf_clock_default(fd
, depth
+ 1, trace
);
2665 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
2666 ret
= ctf_clock_visit(fd
, depth
+ 1, iter
,
2669 fprintf(fd
, "[error] %s: clock declaration error\n", __func__
);
2676 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
2678 ret
= ctf_root_declaration_visit(fd
, depth
+ 1, iter
, trace
);
2680 fprintf(fd
, "[error] %s: root declaration error\n", __func__
);
2684 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
2685 ret
= ctf_trace_visit(fd
, depth
+ 1, iter
, trace
);
2686 if (ret
== -EINTR
) {
2687 free_declaration_scope(trace
->root_declaration_scope
);
2689 * Need to restart creation of type
2690 * definitions, aliases and
2691 * trace header declarations.
2696 fprintf(fd
, "[error] %s: trace declaration error\n", __func__
);
2700 if (!trace
->streams
) {
2701 fprintf(fd
, "[error] %s: missing trace declaration\n", __func__
);
2705 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
2706 ret
= ctf_env_visit(fd
, depth
+ 1, iter
, trace
);
2708 fprintf(fd
, "[error] %s: env declaration error\n", __func__
);
2712 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
2713 ret
= ctf_stream_visit(fd
, depth
+ 1, iter
,
2714 trace
->root_declaration_scope
, trace
);
2716 fprintf(fd
, "[error] %s: stream declaration error\n", __func__
);
2720 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
2721 ret
= ctf_event_visit(fd
, depth
+ 1, iter
,
2722 trace
->root_declaration_scope
, trace
);
2724 fprintf(fd
, "[error] %s: event declaration error\n", __func__
);
2731 fprintf(fd
, "[error] %s: unknown node type %d\n", __func__
,
2736 printf_verbose("done.\n");
2740 free_declaration_scope(trace
->root_declaration_scope
);
2741 g_hash_table_destroy(trace
->clocks
);