2 * ctf-visitor-generate-ir.c
4 * Common Trace Format metadata visitor (generates CTF IR objects).
6 * Based on older ctf-visitor-generate-io-struct.c.
8 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Copyright 2015-2016 - Philippe Proulx <philippe.proulx@efficios.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39 #include <babeltrace/compat/uuid.h>
40 #include <babeltrace/endian.h>
41 #include <babeltrace/ref.h>
42 #include <babeltrace/ctf-ir/trace.h>
43 #include <babeltrace/ctf-ir/stream-class.h>
44 #include <babeltrace/ctf-ir/event.h>
45 #include <babeltrace/ctf-ir/event-class.h>
46 #include <babeltrace/ctf-ir/field-types.h>
47 #include <babeltrace/ctf-ir/field-types-internal.h>
48 #include <babeltrace/ctf-ir/clock-class.h>
54 /* Bit value (left shift) */
55 #define _BV(_val) (1 << (_val))
57 /* Bit is set in a set of bits */
58 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
60 /* Set bit in a set of bits */
61 #define _SET(_set, _mask) (*(_set) |= (_mask))
63 /* Bits for verifying existing attributes in various declarations */
65 _CLOCK_NAME_SET
= _BV(0),
66 _CLOCK_UUID_SET
= _BV(1),
67 _CLOCK_FREQ_SET
= _BV(2),
68 _CLOCK_PRECISION_SET
= _BV(3),
69 _CLOCK_OFFSET_S_SET
= _BV(4),
70 _CLOCK_OFFSET_SET
= _BV(5),
71 _CLOCK_ABSOLUTE_SET
= _BV(6),
72 _CLOCK_DESCRIPTION_SET
= _BV(7),
76 _INTEGER_ALIGN_SET
= _BV(0),
77 _INTEGER_SIZE_SET
= _BV(1),
78 _INTEGER_BASE_SET
= _BV(2),
79 _INTEGER_ENCODING_SET
= _BV(3),
80 _INTEGER_BYTE_ORDER_SET
= _BV(4),
81 _INTEGER_SIGNED_SET
= _BV(5),
82 _INTEGER_MAP_SET
= _BV(6),
86 _FLOAT_ALIGN_SET
= _BV(0),
87 _FLOAT_MANT_DIG_SET
= _BV(1),
88 _FLOAT_EXP_DIG_SET
= _BV(2),
89 _FLOAT_BYTE_ORDER_SET
= _BV(3),
93 _STRING_ENCODING_SET
= _BV(0),
97 _TRACE_MINOR_SET
= _BV(0),
98 _TRACE_MAJOR_SET
= _BV(1),
99 _TRACE_BYTE_ORDER_SET
= _BV(2),
100 _TRACE_UUID_SET
= _BV(3),
101 _TRACE_PACKET_HEADER_SET
= _BV(4),
105 _STREAM_ID_SET
= _BV(0),
106 _STREAM_PACKET_CONTEXT_SET
= _BV(1),
107 _STREAM_EVENT_HEADER_SET
= _BV(2),
108 _STREAM_EVENT_CONTEXT_SET
= _BV(3),
112 _EVENT_NAME_SET
= _BV(0),
113 _EVENT_ID_SET
= _BV(1),
114 _EVENT_MODEL_EMF_URI_SET
= _BV(2),
115 _EVENT_STREAM_ID_SET
= _BV(3),
116 _EVENT_LOGLEVEL_SET
= _BV(4),
117 _EVENT_CONTEXT_SET
= _BV(5),
118 _EVENT_FIELDS_SET
= _BV(6),
126 LOGLEVEL_WARNING
= 4,
129 LOGLEVEL_DEBUG_SYSTEM
= 7,
130 LOGLEVEL_DEBUG_PROGRAM
= 8,
131 LOGLEVEL_DEBUG_PROCESS
= 9,
132 LOGLEVEL_DEBUG_MODULE
= 10,
133 LOGLEVEL_DEBUG_UNIT
= 11,
134 LOGLEVEL_DEBUG_FUNCTION
= 12,
135 LOGLEVEL_DEBUG_LINE
= 13,
140 /* Prefixes of type aliases */
141 #define _PREFIX_ALIAS 'a'
142 #define _PREFIX_ENUM 'e'
143 #define _PREFIX_STRUCT 's'
144 #define _PREFIX_VARIANT 'v'
146 /* First entry in a BT list */
147 #define _BT_LIST_FIRST_ENTRY(_ptr, _type, _member) \
148 bt_list_entry((_ptr)->next, _type, _member)
150 #define _BT_CTF_FIELD_TYPE_INIT(_name) struct bt_ctf_field_type *_name = NULL;
152 /* Error printing wrappers */
153 #define _PERROR(_fmt, ...) \
155 fprintf(ctx->efd, "[error] %s: " _fmt "\n", \
156 __func__, __VA_ARGS__); \
159 #define _PWARNING(_fmt, ...) \
161 fprintf(ctx->efd, "[warning] %s: " _fmt "\n", \
162 __func__, __VA_ARGS__); \
165 #define _FPERROR(_stream, _fmt, ...) \
167 fprintf(_stream, "[error] %s: " _fmt "\n", \
168 __func__, __VA_ARGS__); \
171 #define _FPWARNING(_stream, _fmt, ...) \
173 fprintf(_stream, "[warning] %s: " _fmt "\n", \
174 __func__, __VA_ARGS__); \
177 #define _PERROR_DUP_ATTR(_attr, _entity) \
180 "[error] %s: duplicate attribute \"" \
181 _attr "\" in " _entity "\n", __func__); \
185 * Declaration scope of a visitor context. This represents a TSDL
186 * lexical scope, so that aliases and named structures, variants,
187 * and enumerations may be registered and looked up hierarchically.
189 struct ctx_decl_scope
{
191 * Alias name to field type.
193 * GQuark -> struct bt_ctf_field_type *
195 GHashTable
*decl_map
;
197 /* Parent scope; NULL if this is the root declaration scope */
198 struct ctx_decl_scope
*parent_scope
;
205 /* Trace being filled (weak ref.) */
206 struct bt_ctf_trace
*trace
;
208 /* Error stream to use during visit */
211 /* Current declaration scope (top of the stack) */
212 struct ctx_decl_scope
*current_scope
;
214 /* 1 if trace declaration is visited */
215 int is_trace_visited
;
217 /* Trace attributes */
218 uint64_t trace_major
;
219 uint64_t trace_minor
;
220 unsigned char trace_uuid
[BABELTRACE_UUID_LEN
];
223 * Stream IDs to stream classes.
225 * int64_t -> struct bt_ctf_stream_class *
227 GHashTable
*stream_classes
;
231 const char *loglevel_str
[] = {
232 [ LOGLEVEL_EMERG
] = "TRACE_EMERG",
233 [ LOGLEVEL_ALERT
] = "TRACE_ALERT",
234 [ LOGLEVEL_CRIT
] = "TRACE_CRIT",
235 [ LOGLEVEL_ERR
] = "TRACE_ERR",
236 [ LOGLEVEL_WARNING
] = "TRACE_WARNING",
237 [ LOGLEVEL_NOTICE
] = "TRACE_NOTICE",
238 [ LOGLEVEL_INFO
] = "TRACE_INFO",
239 [ LOGLEVEL_DEBUG_SYSTEM
] = "TRACE_DEBUG_SYSTEM",
240 [ LOGLEVEL_DEBUG_PROGRAM
] = "TRACE_DEBUG_PROGRAM",
241 [ LOGLEVEL_DEBUG_PROCESS
] = "TRACE_DEBUG_PROCESS",
242 [ LOGLEVEL_DEBUG_MODULE
] = "TRACE_DEBUG_MODULE",
243 [ LOGLEVEL_DEBUG_UNIT
] = "TRACE_DEBUG_UNIT",
244 [ LOGLEVEL_DEBUG_FUNCTION
] = "TRACE_DEBUG_FUNCTION",
245 [ LOGLEVEL_DEBUG_LINE
] = "TRACE_DEBUG_LINE",
246 [ LOGLEVEL_DEBUG
] = "TRACE_DEBUG",
250 const char *print_loglevel(int64_t value
)
255 if (value
>= _NR_LOGLEVELS
) {
256 return "<<UNKNOWN>>";
258 return loglevel_str
[value
];
262 * Creates a new declaration scope.
264 * @param par_scope Parent scope (NULL if creating a root scope)
265 * @returns New declaration scope, or NULL on error
268 struct ctx_decl_scope
*ctx_decl_scope_create(struct ctx_decl_scope
*par_scope
)
270 struct ctx_decl_scope
*scope
;
272 scope
= g_new(struct ctx_decl_scope
, 1);
277 scope
->decl_map
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
278 NULL
, (GDestroyNotify
) bt_ctf_field_type_put
);
279 scope
->parent_scope
= par_scope
;
286 * Destroys a declaration scope.
288 * This function does not destroy the parent scope.
290 * @param scope Scope to destroy
293 void ctx_decl_scope_destroy(struct ctx_decl_scope
*scope
)
299 g_hash_table_destroy(scope
->decl_map
);
307 * Returns the GQuark of a prefixed alias.
309 * @param prefix Prefix character
311 * @returns Associated GQuark, or 0 on error
314 GQuark
get_prefixed_named_quark(char prefix
, const char *name
)
320 /* Prefix character + original string + '\0' */
321 char *prname
= g_new(char, strlen(name
) + 2);
326 sprintf(prname
, "%c%s", prefix
, name
);
327 qname
= g_quark_from_string(prname
);
335 * Looks up a prefixed type alias within a declaration scope.
337 * @param scope Declaration scope
338 * @param prefix Prefix character
339 * @param name Alias name
340 * @param level Number of levels to dig (-1 means infinite)
341 * @returns Declaration, or NULL if not found
344 struct bt_ctf_field_type
*ctx_decl_scope_lookup_prefix_alias(
345 struct ctx_decl_scope
*scope
, char prefix
,
346 const char *name
, int levels
)
350 _BT_CTF_FIELD_TYPE_INIT(decl
);
351 struct ctx_decl_scope
*cur_scope
= scope
;
355 qname
= get_prefixed_named_quark(prefix
, name
);
364 while (cur_scope
&& cur_levels
< levels
) {
365 decl
= g_hash_table_lookup(cur_scope
->decl_map
,
366 (gconstpointer
) (unsigned long) qname
);
368 /* Caller's reference */
373 cur_scope
= cur_scope
->parent_scope
;
384 * Looks up a type alias within a declaration scope.
386 * @param scope Declaration scope
387 * @param name Alias name
388 * @param level Number of levels to dig (-1 means infinite)
389 * @returns Declaration, or NULL if not found
392 struct bt_ctf_field_type
*ctx_decl_scope_lookup_alias(
393 struct ctx_decl_scope
*scope
, const char *name
, int levels
)
395 return ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ALIAS
,
400 * Looks up an enumeration within a declaration scope.
402 * @param scope Declaration scope
403 * @param name Enumeration name
404 * @param level Number of levels to dig (-1 means infinite)
405 * @returns Declaration, or NULL if not found
408 struct bt_ctf_field_type
*ctx_decl_scope_lookup_enum(
409 struct ctx_decl_scope
*scope
, const char *name
, int levels
)
411 return ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_ENUM
,
416 * Looks up a structure within a declaration scope.
418 * @param scope Declaration scope
419 * @param name Structure name
420 * @param level Number of levels to dig (-1 means infinite)
421 * @returns Declaration, or NULL if not found
424 struct bt_ctf_field_type
*ctx_decl_scope_lookup_struct(
425 struct ctx_decl_scope
*scope
, const char *name
, int levels
)
427 return ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_STRUCT
,
432 * Looks up a variant within a declaration scope.
434 * @param scope Declaration scope
435 * @param name Variant name
436 * @param level Number of levels to dig (-1 means infinite)
437 * @returns Declaration, or NULL if not found
440 struct bt_ctf_field_type
*ctx_decl_scope_lookup_variant(
441 struct ctx_decl_scope
*scope
, const char *name
, int levels
)
443 return ctx_decl_scope_lookup_prefix_alias(scope
, _PREFIX_VARIANT
,
448 * Registers a prefixed type alias within a declaration scope.
450 * @param scope Declaration scope
451 * @param prefix Prefix character
452 * @param name Alias name (non-NULL)
453 * @param decl Declaration to register
454 * @returns 0 if registration went okay, negative value otherwise
457 int ctx_decl_scope_register_prefix_alias(struct ctx_decl_scope
*scope
,
458 char prefix
, const char *name
, struct bt_ctf_field_type
*decl
)
462 _BT_CTF_FIELD_TYPE_INIT(edecl
);
467 qname
= get_prefixed_named_quark(prefix
, name
);
473 /* Make sure alias does not exist in local scope */
474 edecl
= ctx_decl_scope_lookup_prefix_alias(scope
, prefix
, name
, 1);
481 g_hash_table_insert(scope
->decl_map
,
482 (gpointer
) (unsigned long) qname
, decl
);
484 /* Hash table's reference */
494 * Registers a type alias within a declaration scope.
496 * @param scope Declaration scope
497 * @param name Alias name (non-NULL)
498 * @param decl Declaration to register
499 * @returns 0 if registration went okay, negative value otherwise
502 int ctx_decl_scope_register_alias(struct ctx_decl_scope
*scope
,
503 const char *name
, struct bt_ctf_field_type
*decl
)
505 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ALIAS
,
510 * Registers an enumeration declaration within a declaration scope.
512 * @param scope Declaration scope
513 * @param name Enumeration name (non-NULL)
514 * @param decl Enumeration declaration to register
515 * @returns 0 if registration went okay, negative value otherwise
518 int ctx_decl_scope_register_enum(struct ctx_decl_scope
*scope
,
519 const char *name
, struct bt_ctf_field_type
*decl
)
521 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_ENUM
,
526 * Registers a structure declaration within a declaration scope.
528 * @param scope Declaration scope
529 * @param name Structure name (non-NULL)
530 * @param decl Structure declaration to register
531 * @returns 0 if registration went okay, negative value otherwise
534 int ctx_decl_scope_register_struct(struct ctx_decl_scope
*scope
,
535 const char *name
, struct bt_ctf_field_type
*decl
)
537 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_STRUCT
,
542 * Registers a variant declaration within a declaration scope.
544 * @param scope Declaration scope
545 * @param name Variant name (non-NULL)
546 * @param decl Variant declaration to register
547 * @returns 0 if registration went okay, negative value otherwise
550 int ctx_decl_scope_register_variant(struct ctx_decl_scope
*scope
,
551 const char *name
, struct bt_ctf_field_type
*decl
)
553 return ctx_decl_scope_register_prefix_alias(scope
, _PREFIX_VARIANT
,
558 * Creates a new visitor context.
560 * @param trace Associated trace
561 * @param efd Error stream
562 * @returns New visitor context, or NULL on error
565 struct ctx
*ctx_create(struct bt_ctf_trace
*trace
, FILE *efd
)
567 struct ctx
*ctx
= NULL
;
568 struct ctx_decl_scope
*scope
= NULL
;
570 ctx
= g_new(struct ctx
, 1);
575 /* Root declaration scope */
576 scope
= ctx_decl_scope_create(NULL
);
581 ctx
->stream_classes
= g_hash_table_new_full(g_direct_hash
,
582 g_direct_equal
, NULL
, (GDestroyNotify
) bt_put
);
583 if (!ctx
->stream_classes
) {
589 ctx
->current_scope
= scope
;
590 ctx
->is_trace_visited
= FALSE
;
596 ctx_decl_scope_destroy(scope
);
602 * Destroys a visitor context.
604 * @param ctx Visitor context to destroy
607 void ctx_destroy(struct ctx
*ctx
)
609 struct ctx_decl_scope
*scope
;
611 * Destroy all scopes, from current one to the root scope.
618 scope
= ctx
->current_scope
;
621 struct ctx_decl_scope
*parent_scope
= scope
->parent_scope
;
623 ctx_decl_scope_destroy(scope
);
624 scope
= parent_scope
;
627 g_hash_table_destroy(ctx
->stream_classes
);
635 * Pushes a new declaration scope on top of a visitor context's
636 * declaration scope stack.
638 * @param ctx Visitor context
639 * @returns 0 on success, or a negative value on error
642 int ctx_push_scope(struct ctx
*ctx
)
645 struct ctx_decl_scope
*new_scope
;
648 new_scope
= ctx_decl_scope_create(ctx
->current_scope
);
654 ctx
->current_scope
= new_scope
;
661 void ctx_pop_scope(struct ctx
*ctx
)
663 struct ctx_decl_scope
*parent_scope
= NULL
;
667 if (!ctx
->current_scope
) {
671 parent_scope
= ctx
->current_scope
->parent_scope
;
672 ctx_decl_scope_destroy(ctx
->current_scope
);
673 ctx
->current_scope
= parent_scope
;
680 int visit_type_specifier_list(struct ctx
*ctx
, struct ctf_node
*ts_list
,
681 struct bt_ctf_field_type
**decl
);
684 int is_unary_string(struct bt_list_head
*head
)
687 struct ctf_node
*node
;
689 bt_list_for_each_entry(node
, head
, siblings
) {
690 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
694 if (node
->u
.unary_expression
.type
!= UNARY_STRING
) {
703 char *concatenate_unary_strings(struct bt_list_head
*head
)
707 struct ctf_node
*node
;
709 str
= g_string_new(NULL
);
711 bt_list_for_each_entry(node
, head
, siblings
) {
715 node
->type
!= NODE_UNARY_EXPRESSION
||
716 node
->u
.unary_expression
.type
!= UNARY_STRING
||
719 node
->u
.unary_expression
.link
!=
727 switch (node
->u
.unary_expression
.link
) {
729 g_string_append(str
, ".");
731 case UNARY_ARROWLINK
:
732 g_string_append(str
, "->");
734 case UNARY_DOTDOTDOT
:
735 g_string_append(str
, "...");
741 src_string
= node
->u
.unary_expression
.u
.string
;
742 g_string_append(str
, src_string
);
746 /* Destroys the container, returns the underlying string */
747 return g_string_free(str
, FALSE
);
750 /* This always returns NULL */
751 return g_string_free(str
, TRUE
);
755 const char *get_map_clock_name_value(struct bt_list_head
*head
)
758 struct ctf_node
*node
;
759 const char *name
= NULL
;
761 bt_list_for_each_entry(node
, head
, siblings
) {
763 int uexpr_type
= node
->u
.unary_expression
.type
;
764 int uexpr_link
= node
->u
.unary_expression
.link
;
765 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
766 uexpr_type
!= UNARY_STRING
||
767 !((uexpr_link
!= UNARY_LINK_UNKNOWN
) ^ (i
== 0));
772 /* Needs to be chained with . */
773 switch (node
->u
.unary_expression
.link
) {
776 case UNARY_ARROWLINK
:
777 case UNARY_DOTDOTDOT
:
783 src_string
= node
->u
.unary_expression
.u
.string
;
787 if (strcmp("clock", src_string
)) {
795 if (strcmp("value", src_string
)) {
800 /* Extra identifier, unknown */
814 int is_unary_unsigned(struct bt_list_head
*head
)
817 struct ctf_node
*node
;
819 bt_list_for_each_entry(node
, head
, siblings
) {
820 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
824 if (node
->u
.unary_expression
.type
!= UNARY_UNSIGNED_CONSTANT
) {
833 int get_unary_unsigned(struct bt_list_head
*head
, uint64_t *value
)
837 struct ctf_node
*node
;
839 bt_list_for_each_entry(node
, head
, siblings
) {
840 int uexpr_type
= node
->u
.unary_expression
.type
;
841 int uexpr_link
= node
->u
.unary_expression
.link
;
842 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
843 uexpr_type
!= UNARY_UNSIGNED_CONSTANT
||
844 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
850 *value
= node
->u
.unary_expression
.u
.unsigned_constant
;
859 int is_unary_signed(struct bt_list_head
*head
)
862 struct ctf_node
*node
;
864 bt_list_for_each_entry(node
, head
, siblings
) {
865 if (node
->type
!= NODE_UNARY_EXPRESSION
) {
869 if (node
->u
.unary_expression
.type
!= UNARY_SIGNED_CONSTANT
) {
878 int get_unary_signed(struct bt_list_head
*head
, int64_t *value
)
882 struct ctf_node
*node
;
884 bt_list_for_each_entry(node
, head
, siblings
) {
885 int uexpr_type
= node
->u
.unary_expression
.type
;
886 int uexpr_link
= node
->u
.unary_expression
.link
;
887 int cond
= node
->type
!= NODE_UNARY_EXPRESSION
||
888 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
) ||
889 (uexpr_type
!= UNARY_UNSIGNED_CONSTANT
&&
890 uexpr_type
!= UNARY_SIGNED_CONSTANT
) ||
891 uexpr_link
!= UNARY_LINK_UNKNOWN
|| i
!= 0;
897 switch (node
->u
.unary_expression
.type
) {
898 case UNARY_UNSIGNED_CONSTANT
:
900 node
->u
.unary_expression
.u
.unsigned_constant
;
902 case UNARY_SIGNED_CONSTANT
:
903 *value
= node
->u
.unary_expression
.u
.signed_constant
;
918 int get_unary_uuid(struct bt_list_head
*head
, unsigned char *uuid
)
922 struct ctf_node
*node
;
924 bt_list_for_each_entry(node
, head
, siblings
) {
925 int uexpr_type
= node
->u
.unary_expression
.type
;
926 int uexpr_link
= node
->u
.unary_expression
.link
;
927 const char *src_string
;
929 if (node
->type
!= NODE_UNARY_EXPRESSION
||
930 uexpr_type
!= UNARY_STRING
||
931 uexpr_link
!= UNARY_LINK_UNKNOWN
||
937 src_string
= node
->u
.unary_expression
.u
.string
;
938 ret
= bt_uuid_parse(src_string
, uuid
);
949 int get_boolean(FILE *efd
, struct ctf_node
*unary_expr
)
953 if (unary_expr
->type
!= NODE_UNARY_EXPRESSION
) {
954 _FPERROR(efd
, "%s", "expecting unary expression");
959 switch (unary_expr
->u
.unary_expression
.type
) {
960 case UNARY_UNSIGNED_CONSTANT
:
961 ret
= (unary_expr
->u
.unary_expression
.u
.unsigned_constant
!= 0);
963 case UNARY_SIGNED_CONSTANT
:
964 ret
= (unary_expr
->u
.unary_expression
.u
.signed_constant
!= 0);
968 const char *str
= unary_expr
->u
.unary_expression
.u
.string
;
970 if (!strcmp(str
, "true") || !strcmp(str
, "TRUE")) {
972 } else if (!strcmp(str
, "false") || !strcmp(str
, "FALSE")) {
975 _FPERROR(efd
, "unexpected string \"%s\"", str
);
982 _FPERROR(efd
, "%s", "unexpected unary expression type");
992 enum bt_ctf_byte_order
byte_order_from_unary_expr(FILE *efd
,
993 struct ctf_node
*unary_expr
)
996 enum bt_ctf_byte_order bo
= BT_CTF_BYTE_ORDER_UNKNOWN
;
998 if (unary_expr
->u
.unary_expression
.type
!= UNARY_STRING
) {
1000 "\"byte_order\" attribute: expecting string");
1004 str
= unary_expr
->u
.unary_expression
.u
.string
;
1006 if (!strcmp(str
, "be") || !strcmp(str
, "network")) {
1007 bo
= BT_CTF_BYTE_ORDER_BIG_ENDIAN
;
1008 } else if (!strcmp(str
, "le")) {
1009 bo
= BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
;
1010 } else if (!strcmp(str
, "native")) {
1011 bo
= BT_CTF_BYTE_ORDER_NATIVE
;
1013 _FPERROR(efd
, "unexpected \"byte_order\" attribute value \"%s\"; should be \"be\", \"le\", \"network\", or \"native\"",
1023 enum bt_ctf_byte_order
get_real_byte_order(struct ctx
*ctx
,
1024 struct ctf_node
*uexpr
)
1026 enum bt_ctf_byte_order bo
= byte_order_from_unary_expr(ctx
->efd
, uexpr
);
1028 if (bo
== BT_CTF_BYTE_ORDER_NATIVE
) {
1029 bo
= bt_ctf_trace_get_byte_order(ctx
->trace
);
1036 int is_align_valid(uint64_t align
)
1038 return (align
!= 0) && !(align
& (align
- 1));
1042 int get_type_specifier_name(struct ctx
*ctx
, struct ctf_node
*type_specifier
,
1047 if (type_specifier
->type
!= NODE_TYPE_SPECIFIER
) {
1052 switch (type_specifier
->u
.type_specifier
.type
) {
1054 g_string_append(str
, "void");
1057 g_string_append(str
, "char");
1059 case TYPESPEC_SHORT
:
1060 g_string_append(str
, "short");
1063 g_string_append(str
, "int");
1066 g_string_append(str
, "long");
1068 case TYPESPEC_FLOAT
:
1069 g_string_append(str
, "float");
1071 case TYPESPEC_DOUBLE
:
1072 g_string_append(str
, "double");
1074 case TYPESPEC_SIGNED
:
1075 g_string_append(str
, "signed");
1077 case TYPESPEC_UNSIGNED
:
1078 g_string_append(str
, "unsigned");
1081 g_string_append(str
, "bool");
1083 case TYPESPEC_COMPLEX
:
1084 g_string_append(str
, "_Complex");
1086 case TYPESPEC_IMAGINARY
:
1087 g_string_append(str
, "_Imaginary");
1089 case TYPESPEC_CONST
:
1090 g_string_append(str
, "const");
1092 case TYPESPEC_ID_TYPE
:
1093 if (type_specifier
->u
.type_specifier
.id_type
) {
1094 g_string_append(str
,
1095 type_specifier
->u
.type_specifier
.id_type
);
1098 case TYPESPEC_STRUCT
:
1100 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
1102 if (!node
->u
._struct
.name
) {
1103 _PERROR("%s", "unexpected empty structure name");
1108 g_string_append(str
, "struct ");
1109 g_string_append(str
, node
->u
._struct
.name
);
1112 case TYPESPEC_VARIANT
:
1114 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
1116 if (!node
->u
.variant
.name
) {
1117 _PERROR("%s", "unexpected empty variant name");
1122 g_string_append(str
, "variant ");
1123 g_string_append(str
, node
->u
.variant
.name
);
1128 struct ctf_node
*node
= type_specifier
->u
.type_specifier
.node
;
1130 if (!node
->u
._enum
.enum_id
) {
1131 _PERROR("%s", "unexpected empty enum name");
1136 g_string_append(str
, "enum ");
1137 g_string_append(str
, node
->u
._enum
.enum_id
);
1140 case TYPESPEC_FLOATING_POINT
:
1141 case TYPESPEC_INTEGER
:
1142 case TYPESPEC_STRING
:
1144 _PERROR("%s", "unknown specifier");
1154 int get_type_specifier_list_name(struct ctx
*ctx
,
1155 struct ctf_node
*type_specifier_list
, GString
*str
)
1158 struct ctf_node
*iter
;
1159 int alias_item_nr
= 0;
1160 struct bt_list_head
*head
=
1161 &type_specifier_list
->u
.type_specifier_list
.head
;
1163 bt_list_for_each_entry(iter
, head
, siblings
) {
1164 if (alias_item_nr
!= 0) {
1165 g_string_append(str
, " ");
1169 ret
= get_type_specifier_name(ctx
, iter
, str
);
1180 GQuark
create_typealias_identifier(struct ctx
*ctx
,
1181 struct ctf_node
*type_specifier_list
,
1182 struct ctf_node
*node_type_declarator
)
1188 struct ctf_node
*iter
;
1189 struct bt_list_head
*pointers
=
1190 &node_type_declarator
->u
.type_declarator
.pointers
;
1192 str
= g_string_new("");
1193 ret
= get_type_specifier_list_name(ctx
, type_specifier_list
, str
);
1195 g_string_free(str
, TRUE
);
1199 bt_list_for_each_entry(iter
, pointers
, siblings
) {
1200 g_string_append(str
, " *");
1202 if (iter
->u
.pointer
.const_qualifier
) {
1203 g_string_append(str
, " const");
1207 str_c
= g_string_free(str
, FALSE
);
1208 qalias
= g_quark_from_string(str_c
);
1216 int visit_type_declarator(struct ctx
*ctx
, struct ctf_node
*type_specifier_list
,
1217 GQuark
*field_name
, struct ctf_node
*node_type_declarator
,
1218 struct bt_ctf_field_type
**field_decl
,
1219 struct bt_ctf_field_type
*nested_decl
)
1222 * During this whole function, nested_decl is always OURS,
1223 * whereas field_decl is an output which we create, but
1224 * belongs to the caller (it is moved).
1230 /* Validate type declarator node */
1231 if (node_type_declarator
) {
1232 if (node_type_declarator
->u
.type_declarator
.type
==
1238 /* TODO: GCC bitfields not supported yet */
1239 if (node_type_declarator
->u
.type_declarator
.bitfield_len
!=
1241 _PERROR("%s", "GCC bitfields are not supported as of this version");
1247 /* Find the right nested declaration if not provided */
1249 struct bt_list_head
*pointers
=
1250 &node_type_declarator
->u
.type_declarator
.pointers
;
1252 if (node_type_declarator
&& !bt_list_empty(pointers
)) {
1254 _BT_CTF_FIELD_TYPE_INIT(nested_decl_copy
);
1257 * If we have a pointer declarator, it HAS to
1258 * be present in the typealiases (else fail).
1260 qalias
= create_typealias_identifier(ctx
,
1261 type_specifier_list
, node_type_declarator
);
1263 ctx_decl_scope_lookup_alias(ctx
->current_scope
,
1264 g_quark_to_string(qalias
), -1);
1266 _PERROR("cannot find typealias \"%s\"",
1267 g_quark_to_string(qalias
));
1272 /* Make a copy of it */
1273 nested_decl_copy
= bt_ctf_field_type_copy(nested_decl
);
1274 BT_PUT(nested_decl
);
1275 if (!nested_decl_copy
) {
1276 _PERROR("%s", "cannot copy nested declaration");
1281 BT_MOVE(nested_decl
, nested_decl_copy
);
1283 /* Force integer's base to 16 since it's a pointer */
1284 if (bt_ctf_field_type_is_integer(nested_decl
)) {
1285 bt_ctf_field_type_integer_set_base(nested_decl
,
1286 BT_CTF_INTEGER_BASE_HEXADECIMAL
);
1289 ret
= visit_type_specifier_list(ctx
,
1290 type_specifier_list
, &nested_decl
);
1292 assert(!nested_decl
);
1298 assert(nested_decl
);
1300 if (!node_type_declarator
) {
1301 BT_MOVE(*field_decl
, nested_decl
);
1305 if (node_type_declarator
->u
.type_declarator
.type
== TYPEDEC_ID
) {
1306 if (node_type_declarator
->u
.type_declarator
.u
.id
) {
1308 node_type_declarator
->u
.type_declarator
.u
.id
;
1310 *field_name
= g_quark_from_string(id
);
1315 BT_MOVE(*field_decl
, nested_decl
);
1318 struct ctf_node
*first
;
1319 _BT_CTF_FIELD_TYPE_INIT(decl
);
1320 _BT_CTF_FIELD_TYPE_INIT(outer_field_decl
);
1321 struct bt_list_head
*length
=
1322 &node_type_declarator
->
1323 u
.type_declarator
.u
.nested
.length
;
1325 /* Create array/sequence, pass nested_decl as child */
1326 if (bt_list_empty(length
)) {
1328 "expecting length field reference or value");
1333 first
= _BT_LIST_FIRST_ENTRY(length
, struct ctf_node
, siblings
);
1334 if (first
->type
!= NODE_UNARY_EXPRESSION
) {
1339 switch (first
->u
.unary_expression
.type
) {
1340 case UNARY_UNSIGNED_CONSTANT
:
1343 _BT_CTF_FIELD_TYPE_INIT(array_decl
);
1345 len
= first
->u
.unary_expression
.u
.unsigned_constant
;
1346 array_decl
= bt_ctf_field_type_array_create(nested_decl
,
1348 BT_PUT(nested_decl
);
1351 "cannot create array declaration");
1356 BT_MOVE(decl
, array_decl
);
1361 /* Lookup unsigned integer definition, create seq. */
1362 _BT_CTF_FIELD_TYPE_INIT(seq_decl
);
1363 char *length_name
= concatenate_unary_strings(length
);
1370 seq_decl
= bt_ctf_field_type_sequence_create(
1371 nested_decl
, length_name
);
1372 g_free(length_name
);
1373 BT_PUT(nested_decl
);
1376 "cannot create sequence declaration");
1381 BT_MOVE(decl
, seq_decl
);
1389 assert(!nested_decl
);
1391 assert(!*field_decl
);
1394 * At this point, we found the next nested declaration.
1395 * We currently own this (and lost the ownership of
1396 * nested_decl in the meantime). Pass this next
1397 * nested declaration as the content of the outer
1398 * container, MOVING its ownership.
1400 ret
= visit_type_declarator(ctx
, type_specifier_list
,
1402 node_type_declarator
->
1403 u
.type_declarator
.u
.nested
.type_declarator
,
1404 &outer_field_decl
, decl
);
1407 assert(!outer_field_decl
);
1412 assert(outer_field_decl
);
1413 BT_MOVE(*field_decl
, outer_field_decl
);
1417 BT_PUT(nested_decl
);
1418 assert(*field_decl
);
1423 BT_PUT(nested_decl
);
1424 BT_PUT(*field_decl
);
1430 int visit_struct_decl_field(struct ctx
*ctx
,
1431 struct bt_ctf_field_type
*struct_decl
,
1432 struct ctf_node
*type_specifier_list
,
1433 struct bt_list_head
*type_declarators
)
1436 struct ctf_node
*iter
;
1437 _BT_CTF_FIELD_TYPE_INIT(field_decl
);
1439 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
1442 const char *field_name
;
1443 _BT_CTF_FIELD_TYPE_INIT(efield_decl
);
1445 ret
= visit_type_declarator(ctx
, type_specifier_list
,
1446 &qfield_name
, iter
, &field_decl
, NULL
);
1448 assert(!field_decl
);
1449 _PERROR("%s", "unable to find structure field declaration type");
1454 field_name
= g_quark_to_string(qfield_name
);
1456 /* Check if field with same name already exists */
1458 bt_ctf_field_type_structure_get_field_type_by_name(
1459 struct_decl
, field_name
);
1461 BT_PUT(efield_decl
);
1462 _PERROR("duplicate field \"%s\" in structure",
1468 /* Add field to structure */
1469 ret
= bt_ctf_field_type_structure_add_field(struct_decl
,
1470 field_decl
, field_name
);
1473 _PERROR("cannot add field \"%s\" to structure",
1474 g_quark_to_string(qfield_name
));
1488 int visit_variant_decl_field(struct ctx
*ctx
,
1489 struct bt_ctf_field_type
*variant_decl
,
1490 struct ctf_node
*type_specifier_list
,
1491 struct bt_list_head
*type_declarators
)
1494 struct ctf_node
*iter
;
1495 _BT_CTF_FIELD_TYPE_INIT(field_decl
);
1497 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
1500 const char *field_name
;
1501 _BT_CTF_FIELD_TYPE_INIT(efield_decl
);
1503 ret
= visit_type_declarator(ctx
, type_specifier_list
,
1504 &qfield_name
, iter
, &field_decl
, NULL
);
1506 assert(!field_decl
);
1508 "unable to find variant field declaration type");
1513 field_name
= g_quark_to_string(qfield_name
);
1515 /* Check if field with same name already exists */
1517 bt_ctf_field_type_variant_get_field_type_by_name(
1518 variant_decl
, field_name
);
1520 BT_PUT(efield_decl
);
1521 _PERROR("duplicate field \"%s\" in variant",
1527 /* Add field to structure */
1528 ret
= bt_ctf_field_type_variant_add_field(variant_decl
,
1529 field_decl
, field_name
);
1532 _PERROR("cannot add field \"%s\" to variant",
1533 g_quark_to_string(qfield_name
));
1547 int visit_typedef(struct ctx
*ctx
, struct ctf_node
*type_specifier_list
,
1548 struct bt_list_head
*type_declarators
)
1552 struct ctf_node
*iter
;
1553 _BT_CTF_FIELD_TYPE_INIT(type_decl
);
1555 bt_list_for_each_entry(iter
, type_declarators
, siblings
) {
1556 ret
= visit_type_declarator(ctx
, type_specifier_list
,
1557 &qidentifier
, iter
, &type_decl
, NULL
);
1559 _PERROR("%s", "problem creating type declaration");
1564 /* Do not allow typedef and typealias of untagged variants */
1565 if (bt_ctf_field_type_is_variant(type_decl
)) {
1566 if (bt_ctf_field_type_variant_get_tag_name(type_decl
)) {
1567 _PERROR("%s", "typedef of untagged variant is not allowed");
1573 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1574 g_quark_to_string(qidentifier
), type_decl
);
1576 _PERROR("cannot register typedef \"%s\"",
1577 g_quark_to_string(qidentifier
));
1589 int visit_typealias(struct ctx
*ctx
, struct ctf_node
*target
,
1590 struct ctf_node
*alias
)
1594 struct ctf_node
*node
;
1595 GQuark qdummy_field_name
;
1596 _BT_CTF_FIELD_TYPE_INIT(type_decl
);
1598 /* Create target type declaration */
1599 if (bt_list_empty(&target
->u
.typealias_target
.type_declarators
)) {
1602 node
= _BT_LIST_FIRST_ENTRY(
1603 &target
->u
.typealias_target
.type_declarators
,
1604 struct ctf_node
, siblings
);
1607 ret
= visit_type_declarator(ctx
,
1608 target
->u
.typealias_target
.type_specifier_list
,
1609 &qdummy_field_name
, node
, &type_decl
, NULL
);
1612 _PERROR("%s", "problem creating type declaration");
1616 /* Do not allow typedef and typealias of untagged variants */
1617 if (bt_ctf_field_type_is_variant(type_decl
)) {
1618 if (bt_ctf_field_type_variant_get_tag_name(type_decl
)) {
1620 "typealias of untagged variant is not allowed");
1627 * The semantic validator does not check whether the target is
1628 * abstract or not (if it has an identifier). Check it here.
1630 if (qdummy_field_name
!= 0) {
1631 _PERROR("%s", "expecting empty identifier");
1636 /* Create alias identifier */
1637 node
= _BT_LIST_FIRST_ENTRY(&alias
->u
.typealias_alias
.type_declarators
,
1638 struct ctf_node
, siblings
);
1639 qalias
= create_typealias_identifier(ctx
,
1640 alias
->u
.typealias_alias
.type_specifier_list
, node
);
1641 ret
= ctx_decl_scope_register_alias(ctx
->current_scope
,
1642 g_quark_to_string(qalias
), type_decl
);
1644 _PERROR("cannot register typealias \"%s\"",
1645 g_quark_to_string(qalias
));
1656 int visit_struct_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1657 struct bt_ctf_field_type
*struct_decl
)
1661 switch (entry_node
->type
) {
1663 ret
= visit_typedef(ctx
,
1664 entry_node
->u
._typedef
.type_specifier_list
,
1665 &entry_node
->u
._typedef
.type_declarators
);
1668 "cannot add typedef in \"struct\" declaration");
1672 case NODE_TYPEALIAS
:
1673 ret
= visit_typealias(ctx
, entry_node
->u
.typealias
.target
,
1674 entry_node
->u
.typealias
.alias
);
1677 "cannot add typealias in \"struct\" declaration");
1681 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1683 ret
= visit_struct_decl_field(ctx
, struct_decl
,
1684 entry_node
->u
.struct_or_variant_declaration
.
1685 type_specifier_list
,
1686 &entry_node
->u
.struct_or_variant_declaration
.
1693 _PERROR("unexpected node type: %d", (int) entry_node
->type
);
1703 int visit_variant_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
1704 struct bt_ctf_field_type
*variant_decl
)
1708 switch (entry_node
->type
) {
1710 ret
= visit_typedef(ctx
,
1711 entry_node
->u
._typedef
.type_specifier_list
,
1712 &entry_node
->u
._typedef
.type_declarators
);
1715 "cannot add typedef in \"variant\" declaration");
1719 case NODE_TYPEALIAS
:
1720 ret
= visit_typealias(ctx
, entry_node
->u
.typealias
.target
,
1721 entry_node
->u
.typealias
.alias
);
1724 "cannot add typealias in \"variant\" declaration");
1728 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
1730 ret
= visit_variant_decl_field(ctx
, variant_decl
,
1731 entry_node
->u
.struct_or_variant_declaration
.
1732 type_specifier_list
,
1733 &entry_node
->u
.struct_or_variant_declaration
.
1740 _PERROR("unexpected node type: %d", (int) entry_node
->type
);
1750 int visit_struct_decl(struct ctx
*ctx
, const char *name
,
1751 struct bt_list_head
*decl_list
, int has_body
,
1752 struct bt_list_head
*min_align
,
1753 struct bt_ctf_field_type
**struct_decl
)
1757 *struct_decl
= NULL
;
1759 /* For named struct (without body), lookup in declaration scope */
1761 _BT_CTF_FIELD_TYPE_INIT(struct_decl_copy
);
1768 *struct_decl
= ctx_decl_scope_lookup_struct(ctx
->current_scope
,
1770 if (!*struct_decl
) {
1771 _PERROR("cannot find \"struct %s\"", name
);
1776 /* Make a copy of it */
1777 struct_decl_copy
= bt_ctf_field_type_copy(*struct_decl
);
1778 if (!struct_decl_copy
) {
1780 "cannot create copy of structure declaration");
1785 BT_MOVE(*struct_decl
, struct_decl_copy
);
1787 struct ctf_node
*entry_node
;
1788 uint64_t min_align_value
= 0;
1791 _BT_CTF_FIELD_TYPE_INIT(estruct_decl
);
1793 estruct_decl
= ctx_decl_scope_lookup_struct(
1794 ctx
->current_scope
, name
, 1);
1796 BT_PUT(estruct_decl
);
1797 _PERROR("\"struct %s\" already declared in local scope",
1804 if (!bt_list_empty(min_align
)) {
1805 ret
= get_unary_unsigned(min_align
, &min_align_value
);
1807 _PERROR("%s", "unexpected unary expression for structure declaration's \"align\" attribute");
1812 *struct_decl
= bt_ctf_field_type_structure_create();
1813 if (!*struct_decl
) {
1814 _PERROR("%s", "cannot create structure declaration");
1819 if (min_align_value
!= 0) {
1820 ret
= bt_ctf_field_type_set_alignment(*struct_decl
,
1823 _PERROR("%s", "failed to set structure's minimal alignment");
1828 ret
= ctx_push_scope(ctx
);
1830 _PERROR("%s", "cannot push scope");
1834 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1835 ret
= visit_struct_decl_entry(ctx
, entry_node
,
1846 ret
= ctx_decl_scope_register_struct(ctx
->current_scope
,
1847 name
, *struct_decl
);
1849 _PERROR("cannot register \"struct %s\" in declaration scope",
1859 BT_PUT(*struct_decl
);
1865 int visit_variant_decl(struct ctx
*ctx
, const char *name
,
1866 const char *tag
, struct bt_list_head
*decl_list
,
1867 int has_body
, struct bt_ctf_field_type
**variant_decl
)
1870 _BT_CTF_FIELD_TYPE_INIT(untagged_variant_decl
);
1872 *variant_decl
= NULL
;
1874 /* For named variant (without body), lookup in declaration scope */
1876 _BT_CTF_FIELD_TYPE_INIT(variant_decl_copy
);
1883 untagged_variant_decl
=
1884 ctx_decl_scope_lookup_variant(ctx
->current_scope
,
1886 if (!untagged_variant_decl
) {
1887 _PERROR("cannot find \"variant %s\"", name
);
1892 /* Make a copy of it */
1893 variant_decl_copy
= bt_ctf_field_type_copy(
1894 untagged_variant_decl
);
1895 if (!variant_decl_copy
) {
1897 "cannot create copy of structure declaration");
1902 BT_MOVE(untagged_variant_decl
, variant_decl_copy
);
1904 struct ctf_node
*entry_node
;
1907 struct bt_ctf_field_type
*evariant_decl
=
1908 ctx_decl_scope_lookup_struct(ctx
->current_scope
,
1911 if (evariant_decl
) {
1912 BT_PUT(evariant_decl
);
1913 _PERROR("\"variant %s\" already declared in local scope",
1920 untagged_variant_decl
= bt_ctf_field_type_variant_create(NULL
,
1922 if (!untagged_variant_decl
) {
1923 _PERROR("%s", "cannot create variant declaration");
1928 ret
= ctx_push_scope(ctx
);
1930 _PERROR("%s", "cannot push scope");
1934 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
1935 ret
= visit_variant_decl_entry(ctx
, entry_node
,
1936 untagged_variant_decl
);
1946 ret
= ctx_decl_scope_register_variant(
1947 ctx
->current_scope
, name
,
1948 untagged_variant_decl
);
1950 _PERROR("cannot register \"variant %s\" in declaration scope",
1958 * If tagged, create tagged variant and return; otherwise
1959 * return untagged variant.
1962 BT_MOVE(*variant_decl
, untagged_variant_decl
);
1965 * At this point, we have a fresh untagged variant; nobody
1966 * else owns it. Set its tag now.
1968 ret
= bt_ctf_field_type_variant_set_tag_name(
1969 untagged_variant_decl
, tag
);
1974 BT_MOVE(*variant_decl
, untagged_variant_decl
);
1977 assert(!untagged_variant_decl
);
1978 assert(*variant_decl
);
1983 BT_PUT(untagged_variant_decl
);
1984 BT_PUT(*variant_decl
);
1990 int visit_enum_decl_entry(struct ctx
*ctx
, struct ctf_node
*enumerator
,
1991 struct bt_ctf_field_type
*enum_decl
, int64_t *last
, int is_signed
)
1995 struct ctf_node
*iter
;
1996 int64_t start
= 0, end
= 0;
1997 const char *label
= enumerator
->u
.enumerator
.id
;
1998 struct bt_list_head
*values
= &enumerator
->u
.enumerator
.values
;
2000 bt_list_for_each_entry(iter
, values
, siblings
) {
2003 if (iter
->type
!= NODE_UNARY_EXPRESSION
) {
2004 _PERROR("wrong unary expression for enumeration label \"%s\"",
2016 switch (iter
->u
.unary_expression
.type
) {
2017 case UNARY_SIGNED_CONSTANT
:
2018 *target
= iter
->u
.unary_expression
.u
.signed_constant
;
2020 case UNARY_UNSIGNED_CONSTANT
:
2022 iter
->u
.unary_expression
.u
.unsigned_constant
;
2025 _PERROR("invalid enumeration entry: \"%s\"",
2032 _PERROR("invalid enumeration entry: \"%s\"",
2052 ret
= bt_ctf_field_type_enumeration_add_mapping(enum_decl
, label
,
2055 ret
= bt_ctf_field_type_enumeration_add_mapping_unsigned(enum_decl
,
2056 label
, (uint64_t) start
, (uint64_t) end
);
2059 _PERROR("cannot add mapping to enumeration for label \"%s\"",
2071 int visit_enum_decl(struct ctx
*ctx
, const char *name
,
2072 struct ctf_node
*container_type
,
2073 struct bt_list_head
*enumerator_list
,
2075 struct bt_ctf_field_type
**enum_decl
)
2079 _BT_CTF_FIELD_TYPE_INIT(integer_decl
);
2083 /* For named enum (without body), lookup in declaration scope */
2085 _BT_CTF_FIELD_TYPE_INIT(enum_decl_copy
);
2092 *enum_decl
= ctx_decl_scope_lookup_enum(ctx
->current_scope
,
2095 _PERROR("cannot find \"enum %s\"", name
);
2100 /* Make a copy of it */
2101 enum_decl_copy
= bt_ctf_field_type_copy(*enum_decl
);
2102 if (!enum_decl_copy
) {
2104 "cannot create copy of enumeration declaration");
2110 BT_MOVE(*enum_decl
, enum_decl_copy
);
2112 struct ctf_node
*iter
;
2113 int64_t last_value
= 0;
2116 _BT_CTF_FIELD_TYPE_INIT(eenum_decl
);
2118 eenum_decl
= ctx_decl_scope_lookup_enum(
2119 ctx
->current_scope
, name
, 1);
2122 _PERROR("\"enum %s\" already declared in local scope",
2129 if (!container_type
) {
2130 integer_decl
= ctx_decl_scope_lookup_alias(
2131 ctx
->current_scope
, "int", -1);
2132 if (!integer_decl
) {
2133 _PERROR("%s", "cannot find \"int\" type for enumeration");
2138 ret
= visit_type_declarator(ctx
, container_type
,
2139 &qdummy_id
, NULL
, &integer_decl
, NULL
);
2141 assert(!integer_decl
);
2147 assert(integer_decl
);
2149 if (!bt_ctf_field_type_is_integer(integer_decl
)) {
2150 _PERROR("%s", "container type for enumeration is not an integer");
2155 *enum_decl
= bt_ctf_field_type_enumeration_create(integer_decl
);
2157 _PERROR("%s", "cannot create enumeration declaration");
2162 bt_list_for_each_entry(iter
, enumerator_list
, siblings
) {
2163 ret
= visit_enum_decl_entry(ctx
, iter
, *enum_decl
,
2165 bt_ctf_field_type_integer_get_signed(integer_decl
));
2172 ret
= ctx_decl_scope_register_enum(ctx
->current_scope
,
2180 BT_PUT(integer_decl
);
2185 BT_PUT(integer_decl
);
2192 int visit_type_specifier(struct ctx
*ctx
,
2193 struct ctf_node
*type_specifier_list
,
2194 struct bt_ctf_field_type
**decl
)
2197 GString
*str
= NULL
;
2198 _BT_CTF_FIELD_TYPE_INIT(decl_copy
);
2201 str
= g_string_new("");
2202 ret
= get_type_specifier_list_name(ctx
, type_specifier_list
, str
);
2207 *decl
= ctx_decl_scope_lookup_alias(ctx
->current_scope
, str
->str
, -1);
2209 _PERROR("cannot find type alias \"%s\"", str
->str
);
2214 /* Make a copy of the type declaration */
2215 decl_copy
= bt_ctf_field_type_copy(*decl
);
2217 _PERROR("%s", "cannot create copy of type declaration");
2222 BT_MOVE(*decl
, decl_copy
);
2223 (void) g_string_free(str
, TRUE
);
2230 (void) g_string_free(str
, TRUE
);
2239 int visit_integer_decl(struct ctx
*ctx
,
2240 struct bt_list_head
*expressions
,
2241 struct bt_ctf_field_type
**integer_decl
)
2246 struct ctf_node
*expression
;
2247 uint64_t alignment
= 0, size
= 0;
2248 struct bt_ctf_clock_class
*mapped_clock
= NULL
;
2249 enum bt_ctf_string_encoding encoding
= BT_CTF_STRING_ENCODING_NONE
;
2250 enum bt_ctf_integer_base base
= BT_CTF_INTEGER_BASE_DECIMAL
;
2251 enum bt_ctf_byte_order byte_order
=
2252 bt_ctf_trace_get_byte_order(ctx
->trace
);
2254 *integer_decl
= NULL
;
2256 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2257 struct ctf_node
*left
, *right
;
2259 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2260 struct ctf_node
, siblings
);
2261 right
= _BT_LIST_FIRST_ENTRY(
2262 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2265 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2270 if (!strcmp(left
->u
.unary_expression
.u
.string
, "signed")) {
2271 if (_IS_SET(&set
, _INTEGER_SIGNED_SET
)) {
2272 _PERROR_DUP_ATTR("signed",
2273 "integer declaration");
2278 signedness
= get_boolean(ctx
->efd
, right
);
2279 if (signedness
< 0) {
2284 _SET(&set
, _INTEGER_SIGNED_SET
);
2285 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2287 if (_IS_SET(&set
, _INTEGER_BYTE_ORDER_SET
)) {
2288 _PERROR_DUP_ATTR("byte_order",
2289 "integer declaration");
2294 byte_order
= get_real_byte_order(ctx
, right
);
2295 if (byte_order
== BT_CTF_BYTE_ORDER_UNKNOWN
) {
2296 _PERROR("%s", "invalid \"byte_order\" attribute in integer declaration");
2301 _SET(&set
, _INTEGER_BYTE_ORDER_SET
);
2302 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "size")) {
2303 if (_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2304 _PERROR_DUP_ATTR("size",
2305 "integer declaration");
2310 if (right
->u
.unary_expression
.type
!=
2311 UNARY_UNSIGNED_CONSTANT
) {
2312 _PERROR("%s", "invalid \"size\" attribute in integer declaration: expecting unsigned constant");
2317 size
= right
->u
.unary_expression
.u
.unsigned_constant
;
2319 _PERROR("%s", "invalid \"size\" attribute in integer declaration: expecting positive constant");
2322 } else if (size
> 64) {
2323 _PERROR("%s", "invalid \"size\" attribute in integer declaration: integers over 64-bit are not supported as of this version");
2328 _SET(&set
, _INTEGER_SIZE_SET
);
2329 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2331 if (_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2332 _PERROR_DUP_ATTR("align",
2333 "integer declaration");
2338 if (right
->u
.unary_expression
.type
!=
2339 UNARY_UNSIGNED_CONSTANT
) {
2340 _PERROR("%s", "invalid \"align\" attribute in integer declaration: expecting unsigned constant");
2346 right
->u
.unary_expression
.u
.unsigned_constant
;
2347 if (!is_align_valid(alignment
)) {
2348 _PERROR("%s", "invalid \"align\" attribute in integer declaration: expecting power of two");
2353 _SET(&set
, _INTEGER_ALIGN_SET
);
2354 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "base")) {
2355 if (_IS_SET(&set
, _INTEGER_BASE_SET
)) {
2356 _PERROR_DUP_ATTR("base", "integer declaration");
2361 switch (right
->u
.unary_expression
.type
) {
2362 case UNARY_UNSIGNED_CONSTANT
:
2364 uint64_t constant
= right
->u
.unary_expression
.
2365 u
.unsigned_constant
;
2369 base
= BT_CTF_INTEGER_BASE_BINARY
;
2372 base
= BT_CTF_INTEGER_BASE_OCTAL
;
2375 base
= BT_CTF_INTEGER_BASE_DECIMAL
;
2378 base
= BT_CTF_INTEGER_BASE_HEXADECIMAL
;
2381 _PERROR("invalid \"base\" attribute in integer declaration: %" PRIu64
,
2382 right
->u
.unary_expression
.u
.unsigned_constant
);
2390 char *s_right
= concatenate_unary_strings(
2391 &expression
->u
.ctf_expression
.right
);
2393 _PERROR("%s", "unexpected unary expression for integer declaration's \"base\" attribute");
2398 if (!strcmp(s_right
, "decimal") ||
2399 !strcmp(s_right
, "dec") ||
2400 !strcmp(s_right
, "d") ||
2401 !strcmp(s_right
, "i") ||
2402 !strcmp(s_right
, "u")) {
2403 base
= BT_CTF_INTEGER_BASE_DECIMAL
;
2404 } else if (!strcmp(s_right
, "hexadecimal") ||
2405 !strcmp(s_right
, "hex") ||
2406 !strcmp(s_right
, "x") ||
2407 !strcmp(s_right
, "X") ||
2408 !strcmp(s_right
, "p")) {
2409 base
= BT_CTF_INTEGER_BASE_HEXADECIMAL
;
2410 } else if (!strcmp(s_right
, "octal") ||
2411 !strcmp(s_right
, "oct") ||
2412 !strcmp(s_right
, "o")) {
2413 base
= BT_CTF_INTEGER_BASE_OCTAL
;
2414 } else if (!strcmp(s_right
, "binary") ||
2415 !strcmp(s_right
, "b")) {
2416 base
= BT_CTF_INTEGER_BASE_BINARY
;
2418 _PERROR("unexpected unary expression for integer declaration's \"base\" attribute: \"%s\"",
2429 _PERROR("%s", "invalid \"base\" attribute in integer declaration: expecting unsigned constant or unary string");
2434 _SET(&set
, _INTEGER_BASE_SET
);
2435 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2439 if (_IS_SET(&set
, _INTEGER_ENCODING_SET
)) {
2440 _PERROR_DUP_ATTR("encoding",
2441 "integer declaration");
2446 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2447 _PERROR("%s", "invalid \"encoding\" attribute in integer declaration: expecting unary string");
2452 s_right
= concatenate_unary_strings(
2453 &expression
->u
.ctf_expression
.right
);
2455 _PERROR("%s", "unexpected unary expression for integer declaration's \"encoding\" attribute");
2460 if (!strcmp(s_right
, "UTF8") ||
2461 !strcmp(s_right
, "utf8") ||
2462 !strcmp(s_right
, "utf-8") ||
2463 !strcmp(s_right
, "UTF-8")) {
2464 encoding
= BT_CTF_STRING_ENCODING_UTF8
;
2465 } else if (!strcmp(s_right
, "ASCII") ||
2466 !strcmp(s_right
, "ascii")) {
2467 encoding
= BT_CTF_STRING_ENCODING_ASCII
;
2468 } else if (!strcmp(s_right
, "none")) {
2469 encoding
= BT_CTF_STRING_ENCODING_NONE
;
2471 _PERROR("invalid \"encoding\" attribute in integer declaration: unknown encoding \"%s\"",
2479 _SET(&set
, _INTEGER_ENCODING_SET
);
2480 } else if (!strcmp(left
->u
.unary_expression
.u
.string
, "map")) {
2481 const char *clock_name
;
2483 if (_IS_SET(&set
, _INTEGER_MAP_SET
)) {
2484 _PERROR_DUP_ATTR("map", "integer declaration");
2489 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2490 _PERROR("%s", "invalid \"map\" attribute in integer declaration: expecting unary string");
2496 get_map_clock_name_value(
2497 &expression
->u
.ctf_expression
.right
);
2499 char *s_right
= concatenate_unary_strings(
2500 &expression
->u
.ctf_expression
.right
);
2503 _PERROR("%s", "unexpected unary expression for integer declaration's \"map\" attribute");
2508 _PWARNING("invalid \"map\" attribute in integer declaration: unknown clock: \"%s\"",
2510 _SET(&set
, _INTEGER_MAP_SET
);
2515 mapped_clock
= bt_ctf_trace_get_clock_class_by_name(
2516 ctx
->trace
, clock_name
);
2517 if (!mapped_clock
) {
2518 _PERROR("invalid \"map\" attribute in integer declaration: cannot find clock \"%s\"",
2524 _SET(&set
, _INTEGER_MAP_SET
);
2526 _PWARNING("unknown attribute \"%s\" in integer declaration",
2527 left
->u
.unary_expression
.u
.string
);
2531 if (!_IS_SET(&set
, _INTEGER_SIZE_SET
)) {
2533 "missing \"size\" attribute in integer declaration");
2538 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2539 if (size
% CHAR_BIT
) {
2540 /* Bit-packed alignment */
2543 /* Byte-packed alignment */
2544 alignment
= CHAR_BIT
;
2548 *integer_decl
= bt_ctf_field_type_integer_create((unsigned int) size
);
2549 if (!*integer_decl
) {
2550 _PERROR("%s", "cannot create integer declaration");
2555 ret
= bt_ctf_field_type_integer_set_signed(*integer_decl
, signedness
);
2556 ret
|= bt_ctf_field_type_integer_set_base(*integer_decl
, base
);
2557 ret
|= bt_ctf_field_type_integer_set_encoding(*integer_decl
, encoding
);
2558 ret
|= bt_ctf_field_type_set_alignment(*integer_decl
,
2559 (unsigned int) alignment
);
2560 ret
|= bt_ctf_field_type_set_byte_order(*integer_decl
, byte_order
);
2564 ret
|= bt_ctf_field_type_integer_set_mapped_clock_class(
2565 *integer_decl
, mapped_clock
);
2566 bt_put(mapped_clock
);
2567 mapped_clock
= NULL
;
2571 _PERROR("%s", "cannot configure integer declaration");
2580 bt_put(mapped_clock
);
2583 BT_PUT(*integer_decl
);
2589 int visit_floating_point_number_decl(struct ctx
*ctx
,
2590 struct bt_list_head
*expressions
,
2591 struct bt_ctf_field_type
**float_decl
)
2595 struct ctf_node
*expression
;
2596 uint64_t alignment
= 1, exp_dig
= 0, mant_dig
= 0;
2597 enum bt_ctf_byte_order byte_order
=
2598 bt_ctf_trace_get_byte_order(ctx
->trace
);
2602 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2603 struct ctf_node
*left
, *right
;
2605 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2606 struct ctf_node
, siblings
);
2607 right
= _BT_LIST_FIRST_ENTRY(
2608 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2611 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2616 if (!strcmp(left
->u
.unary_expression
.u
.string
, "byte_order")) {
2617 if (_IS_SET(&set
, _FLOAT_BYTE_ORDER_SET
)) {
2618 _PERROR_DUP_ATTR("byte_order",
2619 "floating point number declaration");
2624 byte_order
= get_real_byte_order(ctx
, right
);
2625 if (byte_order
== BT_CTF_BYTE_ORDER_UNKNOWN
) {
2626 _PERROR("%s", "invalid \"byte_order\" attribute in floating point number declaration");
2631 _SET(&set
, _FLOAT_BYTE_ORDER_SET
);
2632 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2634 if (_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2635 _PERROR_DUP_ATTR("exp_dig",
2636 "floating point number declaration");
2641 if (right
->u
.unary_expression
.type
!=
2642 UNARY_UNSIGNED_CONSTANT
) {
2643 _PERROR("%s", "invalid \"exp_dig\" attribute in floating point number declaration: expecting unsigned constant");
2648 exp_dig
= right
->u
.unary_expression
.u
.unsigned_constant
;
2649 _SET(&set
, _FLOAT_EXP_DIG_SET
);
2650 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2652 if (_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2653 _PERROR_DUP_ATTR("mant_dig",
2654 "floating point number declaration");
2659 if (right
->u
.unary_expression
.type
!=
2660 UNARY_UNSIGNED_CONSTANT
) {
2661 _PERROR("%s", "invalid \"mant_dig\" attribute in floating point number declaration: expecting unsigned constant");
2666 mant_dig
= right
->u
.unary_expression
.u
.
2668 _SET(&set
, _FLOAT_MANT_DIG_SET
);
2669 } else if (!strcmp(left
->u
.unary_expression
.u
.string
,
2671 if (_IS_SET(&set
, _FLOAT_ALIGN_SET
)) {
2672 _PERROR_DUP_ATTR("align",
2673 "floating point number declaration");
2678 if (right
->u
.unary_expression
.type
!=
2679 UNARY_UNSIGNED_CONSTANT
) {
2680 _PERROR("%s", "invalid \"align\" attribute in floating point number declaration: expecting unsigned constant");
2685 alignment
= right
->u
.unary_expression
.u
.
2688 if (!is_align_valid(alignment
)) {
2689 _PERROR("%s", "invalid \"align\" attribute in floating point number declaration: expecting power of two");
2694 _SET(&set
, _FLOAT_ALIGN_SET
);
2696 _PWARNING("unknown attribute \"%s\" in floating point number declaration",
2697 left
->u
.unary_expression
.u
.string
);
2701 if (!_IS_SET(&set
, _FLOAT_MANT_DIG_SET
)) {
2702 _PERROR("%s", "missing \"mant_dig\" attribute in floating point number declaration");
2707 if (!_IS_SET(&set
, _FLOAT_EXP_DIG_SET
)) {
2708 _PERROR("%s", "missing \"exp_dig\" attribute in floating point number declaration");
2713 if (!_IS_SET(&set
, _INTEGER_ALIGN_SET
)) {
2714 if ((mant_dig
+ exp_dig
) % CHAR_BIT
) {
2715 /* Bit-packed alignment */
2718 /* Byte-packed alignment */
2719 alignment
= CHAR_BIT
;
2723 *float_decl
= bt_ctf_field_type_floating_point_create();
2726 "cannot create floating point number declaration");
2731 ret
= bt_ctf_field_type_floating_point_set_exponent_digits(
2732 *float_decl
, exp_dig
);
2733 ret
|= bt_ctf_field_type_floating_point_set_mantissa_digits(
2734 *float_decl
, mant_dig
);
2735 ret
|= bt_ctf_field_type_set_byte_order(*float_decl
, byte_order
);
2736 ret
|= bt_ctf_field_type_set_alignment(*float_decl
, alignment
);
2739 "cannot configure floating point number declaration");
2747 BT_PUT(*float_decl
);
2753 int visit_string_decl(struct ctx
*ctx
,
2754 struct bt_list_head
*expressions
,
2755 struct bt_ctf_field_type
**string_decl
)
2759 struct ctf_node
*expression
;
2760 enum bt_ctf_string_encoding encoding
= BT_CTF_STRING_ENCODING_UTF8
;
2762 *string_decl
= NULL
;
2764 bt_list_for_each_entry(expression
, expressions
, siblings
) {
2765 struct ctf_node
*left
, *right
;
2767 left
= _BT_LIST_FIRST_ENTRY(&expression
->u
.ctf_expression
.left
,
2768 struct ctf_node
, siblings
);
2769 right
= _BT_LIST_FIRST_ENTRY(
2770 &expression
->u
.ctf_expression
.right
, struct ctf_node
,
2773 if (left
->u
.unary_expression
.type
!= UNARY_STRING
) {
2778 if (!strcmp(left
->u
.unary_expression
.u
.string
, "encoding")) {
2781 if (_IS_SET(&set
, _STRING_ENCODING_SET
)) {
2782 _PERROR_DUP_ATTR("encoding",
2783 "string declaration");
2788 if (right
->u
.unary_expression
.type
!= UNARY_STRING
) {
2789 _PERROR("%s", "invalid \"encoding\" attribute in string declaration: expecting unary string");
2794 s_right
= concatenate_unary_strings(
2795 &expression
->u
.ctf_expression
.right
);
2797 _PERROR("%s", "unexpected unary expression for string declaration's \"encoding\" attribute");
2802 if (!strcmp(s_right
, "UTF8") ||
2803 !strcmp(s_right
, "utf8") ||
2804 !strcmp(s_right
, "utf-8") ||
2805 !strcmp(s_right
, "UTF-8")) {
2806 encoding
= BT_CTF_STRING_ENCODING_UTF8
;
2807 } else if (!strcmp(s_right
, "ASCII") ||
2808 !strcmp(s_right
, "ascii")) {
2809 encoding
= BT_CTF_STRING_ENCODING_ASCII
;
2810 } else if (!strcmp(s_right
, "none")) {
2811 encoding
= BT_CTF_STRING_ENCODING_NONE
;
2813 _PERROR("invalid \"encoding\" attribute in string declaration: unknown encoding \"%s\"",
2821 _SET(&set
, _STRING_ENCODING_SET
);
2823 _PWARNING("unknown attribute \"%s\" in string declaration",
2824 left
->u
.unary_expression
.u
.string
);
2828 *string_decl
= bt_ctf_field_type_string_create();
2829 if (!*string_decl
) {
2830 _PERROR("%s", "cannot create string declaration");
2835 ret
= bt_ctf_field_type_string_set_encoding(*string_decl
, encoding
);
2837 _PERROR("%s", "cannot configure string declaration");
2845 BT_PUT(*string_decl
);
2851 int visit_type_specifier_list(struct ctx
*ctx
,
2852 struct ctf_node
*ts_list
,
2853 struct bt_ctf_field_type
**decl
)
2856 struct ctf_node
*first
, *node
;
2860 if (ts_list
->type
!= NODE_TYPE_SPECIFIER_LIST
) {
2865 first
= _BT_LIST_FIRST_ENTRY(&ts_list
->u
.type_specifier_list
.head
,
2866 struct ctf_node
, siblings
);
2867 if (first
->type
!= NODE_TYPE_SPECIFIER
) {
2872 node
= first
->u
.type_specifier
.node
;
2874 switch (first
->u
.type_specifier
.type
) {
2875 case TYPESPEC_INTEGER
:
2876 ret
= visit_integer_decl(ctx
, &node
->u
.integer
.expressions
,
2883 case TYPESPEC_FLOATING_POINT
:
2884 ret
= visit_floating_point_number_decl(ctx
,
2885 &node
->u
.floating_point
.expressions
, decl
);
2891 case TYPESPEC_STRING
:
2892 ret
= visit_string_decl(ctx
,
2893 &node
->u
.string
.expressions
, decl
);
2899 case TYPESPEC_STRUCT
:
2900 ret
= visit_struct_decl(ctx
, node
->u
._struct
.name
,
2901 &node
->u
._struct
.declaration_list
,
2902 node
->u
._struct
.has_body
,
2903 &node
->u
._struct
.min_align
, decl
);
2909 case TYPESPEC_VARIANT
:
2910 ret
= visit_variant_decl(ctx
, node
->u
.variant
.name
,
2911 node
->u
.variant
.choice
,
2912 &node
->u
.variant
.declaration_list
,
2913 node
->u
.variant
.has_body
, decl
);
2920 ret
= visit_enum_decl(ctx
, node
->u
._enum
.enum_id
,
2921 node
->u
._enum
.container_type
,
2922 &node
->u
._enum
.enumerator_list
,
2923 node
->u
._enum
.has_body
, decl
);
2931 case TYPESPEC_SHORT
:
2934 case TYPESPEC_FLOAT
:
2935 case TYPESPEC_DOUBLE
:
2936 case TYPESPEC_SIGNED
:
2937 case TYPESPEC_UNSIGNED
:
2939 case TYPESPEC_COMPLEX
:
2940 case TYPESPEC_IMAGINARY
:
2941 case TYPESPEC_CONST
:
2942 case TYPESPEC_ID_TYPE
:
2943 ret
= visit_type_specifier(ctx
, ts_list
, decl
);
2950 _PERROR("unexpected node type: %d",
2951 (int) first
->u
.type_specifier
.type
);
2967 int visit_event_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
2968 struct bt_ctf_event_class
*event_class
, int64_t *stream_id
,
2973 _BT_CTF_FIELD_TYPE_INIT(decl
);
2975 switch (node
->type
) {
2977 ret
= visit_typedef(ctx
, node
->u
._typedef
.type_specifier_list
,
2978 &node
->u
._typedef
.type_declarators
);
2981 "cannot add typedef in \"event\" declaration");
2985 case NODE_TYPEALIAS
:
2986 ret
= visit_typealias(ctx
, node
->u
.typealias
.target
,
2987 node
->u
.typealias
.alias
);
2989 _PERROR("%s", "cannot add typealias in \"event\" declaration");
2993 case NODE_CTF_EXPRESSION
:
2995 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3001 if (!strcmp(left
, "name")) {
3002 /* This is already known at this stage */
3003 if (_IS_SET(set
, _EVENT_NAME_SET
)) {
3004 _PERROR_DUP_ATTR("name", "event declaration");
3009 _SET(set
, _EVENT_NAME_SET
);
3010 } else if (!strcmp(left
, "id")) {
3013 if (_IS_SET(set
, _EVENT_ID_SET
)) {
3014 _PERROR_DUP_ATTR("id", "event declaration");
3019 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3021 if (ret
|| id
< 0) {
3022 _PERROR("%s", "unexpected unary expression for event declaration's \"id\" attribute");
3027 ret
= bt_ctf_event_class_set_id(event_class
, id
);
3030 "cannot set event declaration's ID");
3034 _SET(set
, _EVENT_ID_SET
);
3035 } else if (!strcmp(left
, "stream_id")) {
3036 if (_IS_SET(set
, _EVENT_STREAM_ID_SET
)) {
3037 _PERROR_DUP_ATTR("stream_id",
3038 "event declaration");
3043 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3044 (uint64_t *) stream_id
);
3045 if (ret
|| *stream_id
< 0) {
3046 _PERROR("%s", "unexpected unary expression for event declaration's \"stream_id\" attribute");
3051 _SET(set
, _EVENT_STREAM_ID_SET
);
3052 } else if (!strcmp(left
, "context")) {
3053 if (_IS_SET(set
, _EVENT_CONTEXT_SET
)) {
3054 _PERROR("%s", "duplicate \"context\" entry in event declaration");
3059 ret
= visit_type_specifier_list(ctx
,
3060 _BT_LIST_FIRST_ENTRY(
3061 &node
->u
.ctf_expression
.right
,
3062 struct ctf_node
, siblings
),
3065 _PERROR("%s", "cannot create event context declaration");
3070 ret
= bt_ctf_event_class_set_context_type(
3074 _PERROR("%s", "cannot set event's context declaration");
3078 _SET(set
, _EVENT_CONTEXT_SET
);
3079 } else if (!strcmp(left
, "fields")) {
3080 if (_IS_SET(set
, _EVENT_FIELDS_SET
)) {
3081 _PERROR("%s", "duplicate \"fields\" entry in event declaration");
3086 ret
= visit_type_specifier_list(ctx
,
3087 _BT_LIST_FIRST_ENTRY(
3088 &node
->u
.ctf_expression
.right
,
3089 struct ctf_node
, siblings
),
3092 _PERROR("%s", "cannot create event payload declaration");
3097 ret
= bt_ctf_event_class_set_payload_type(
3101 _PERROR("%s", "cannot set event's payload declaration");
3105 _SET(set
, _EVENT_FIELDS_SET
);
3106 } else if (!strcmp(left
, "loglevel")) {
3107 uint64_t loglevel_value
;
3108 const char *loglevel_str
;
3109 struct bt_value
*value_obj
, *str_obj
;
3111 if (_IS_SET(set
, _EVENT_LOGLEVEL_SET
)) {
3112 _PERROR_DUP_ATTR("loglevel",
3113 "event declaration");
3118 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3121 _PERROR("%s", "unexpected unary expression for event declaration's \"loglevel\" attribute");
3125 value_obj
= bt_value_integer_create_init(loglevel_value
);
3127 _PERROR("%s", "cannot allocate memory for loglevel value object");
3131 if (bt_ctf_event_class_set_attribute(event_class
,
3132 "loglevel", value_obj
) != BT_VALUE_STATUS_OK
) {
3133 _PERROR("%s", "cannot set loglevel value");
3138 loglevel_str
= print_loglevel(loglevel_value
);
3140 str_obj
= bt_value_string_create_init(loglevel_str
);
3141 if (bt_ctf_event_class_set_attribute(event_class
,
3142 "loglevel_string", str_obj
) != BT_VALUE_STATUS_OK
) {
3143 _PERROR("%s", "cannot set loglevel string");
3151 _SET(set
, _EVENT_LOGLEVEL_SET
);
3152 } else if (!strcmp(left
, "model.emf.uri")) {
3155 if (_IS_SET(set
, _EVENT_MODEL_EMF_URI_SET
)) {
3156 _PERROR_DUP_ATTR("model.emf.uri",
3157 "event declaration");
3162 right
= concatenate_unary_strings(
3163 &node
->u
.ctf_expression
.right
);
3165 _PERROR("%s", "unexpected unary expression for event declaration's \"model.emf.uri\" attribute");
3170 // TODO: FIXME: set model EMF URI here
3173 _SET(set
, _EVENT_MODEL_EMF_URI_SET
);
3175 _PWARNING("unknown attribute \"%s\" in event declaration",
3201 char *get_event_decl_name(struct ctx
*ctx
, struct ctf_node
*node
)
3205 struct ctf_node
*iter
;
3206 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3208 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3209 if (iter
->type
!= NODE_CTF_EXPRESSION
) {
3213 left
= concatenate_unary_strings(&iter
->u
.ctf_expression
.left
);
3218 if (!strcmp(left
, "name")) {
3219 name
= concatenate_unary_strings(
3220 &iter
->u
.ctf_expression
.right
);
3222 _PERROR("%s", "unexpected unary expression for event declaration's \"name\" attribute");
3244 int reset_event_decl_types(struct ctx
*ctx
,
3245 struct bt_ctf_event_class
*event_class
)
3250 ret
= bt_ctf_event_class_set_context_type(event_class
, NULL
);
3252 _PERROR("%s", "cannot set initial NULL event context");
3256 /* Event payload. */
3257 ret
= bt_ctf_event_class_set_payload_type(event_class
, NULL
);
3259 _PERROR("%s", "cannot set initial NULL event payload");
3267 int reset_stream_decl_types(struct ctx
*ctx
,
3268 struct bt_ctf_stream_class
*stream_class
)
3272 /* Packet context. */
3273 ret
= bt_ctf_stream_class_set_packet_context_type(stream_class
, NULL
);
3275 _PERROR("%s", "cannot set initial empty packet context");
3280 ret
= bt_ctf_stream_class_set_event_header_type(stream_class
, NULL
);
3282 _PERROR("%s", "cannot set initial empty event header");
3286 /* Event context. */
3287 ret
= bt_ctf_stream_class_set_event_context_type(stream_class
, NULL
);
3289 _PERROR("%s", "cannot set initial empty stream event context");
3297 struct bt_ctf_stream_class
*create_reset_stream_class(struct ctx
*ctx
)
3300 struct bt_ctf_stream_class
*stream_class
;
3302 stream_class
= bt_ctf_stream_class_create(NULL
);
3303 if (!stream_class
) {
3304 _PERROR("%s", "cannot create stream class");
3309 * Set packet context, event header, and event context to NULL to
3310 * override the default ones.
3312 ret
= reset_stream_decl_types(ctx
, stream_class
);
3317 return stream_class
;
3320 BT_PUT(stream_class
);
3326 int visit_event_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3331 struct ctf_node
*iter
;
3332 int64_t stream_id
= -1;
3333 char *event_name
= NULL
;
3334 struct bt_ctf_event_class
*event_class
= NULL
;
3335 struct bt_ctf_event_class
*eevent_class
;
3336 struct bt_ctf_stream_class
*stream_class
;
3337 struct bt_list_head
*decl_list
= &node
->u
.event
.declaration_list
;
3339 if (node
->visited
) {
3343 node
->visited
= TRUE
;
3344 event_name
= get_event_decl_name(ctx
, node
);
3347 "missing \"name\" attribute in event declaration");
3352 event_class
= bt_ctf_event_class_create(event_name
);
3355 * Unset context and fields to override the default ones.
3357 ret
= reset_event_decl_types(ctx
, event_class
);
3363 ret
= ctx_push_scope(ctx
);
3365 _PERROR("%s", "cannot push scope");
3369 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3370 ret
= visit_event_decl_entry(ctx
, iter
, event_class
,
3377 if (!_IS_SET(&set
, _EVENT_STREAM_ID_SET
)) {
3379 struct bt_ctf_stream_class
*new_stream_class
;
3381 /* Allow missing stream_id if there is only a single stream */
3382 switch (g_hash_table_size(ctx
->stream_classes
)) {
3384 /* Create stream if there's none */
3385 new_stream_class
= create_reset_stream_class(ctx
);
3386 if (!new_stream_class
) {
3391 ret
= bt_ctf_stream_class_set_id(new_stream_class
, 0);
3393 _PERROR("%s", "cannot set stream's ID");
3394 BT_PUT(new_stream_class
);
3400 /* Move reference to visitor's context */
3401 g_hash_table_insert(ctx
->stream_classes
,
3402 (gpointer
) stream_id
, new_stream_class
);
3403 new_stream_class
= NULL
;
3407 /* Single stream: get its ID */
3408 keys
= g_hash_table_get_keys(ctx
->stream_classes
);
3409 stream_id
= (int64_t) keys
->data
;
3414 _PERROR("%s", "missing \"stream_id\" attribute in event declaration");
3422 assert(stream_id
>= 0);
3424 /* We have the stream ID now; borrow the stream class if found */
3425 stream_class
= g_hash_table_lookup(ctx
->stream_classes
,
3426 (gpointer
) stream_id
);
3427 if (!stream_class
) {
3428 _PERROR("cannot find stream class with ID %" PRId64
,
3434 if (!_IS_SET(&set
, _EVENT_ID_SET
)) {
3435 /* Allow only one event without ID per stream */
3436 if (bt_ctf_stream_class_get_event_class_count(stream_class
) !=
3439 "missing \"id\" field in event declaration");
3445 ret
= bt_ctf_event_class_set_id(event_class
, 0);
3447 _PERROR("%s", "cannot set event's ID");
3452 event_id
= bt_ctf_event_class_get_id(event_class
);
3454 _PERROR("%s", "cannot get event's ID");
3459 eevent_class
= bt_ctf_stream_class_get_event_class_by_id(stream_class
,
3462 BT_PUT(eevent_class
);
3463 _PERROR("%s", "duplicate event with ID %" PRId64
" in same stream");
3468 eevent_class
= bt_ctf_stream_class_get_event_class_by_name(stream_class
,
3471 BT_PUT(eevent_class
);
3472 eevent_class
= NULL
;
3474 "duplicate event with name \"%s\" in same stream");
3480 ret
= bt_ctf_stream_class_add_event_class(stream_class
, event_class
);
3481 BT_PUT(event_class
);
3485 _PERROR("%s", "cannot add event class to stream class");
3494 BT_PUT(event_class
);
3496 /* stream_class is borrowed; it still belongs to the hash table */
3502 int visit_stream_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
,
3503 struct bt_ctf_stream_class
*stream_class
, int *set
)
3507 _BT_CTF_FIELD_TYPE_INIT(decl
);
3509 switch (node
->type
) {
3511 ret
= visit_typedef(ctx
, node
->u
._typedef
.type_specifier_list
,
3512 &node
->u
._typedef
.type_declarators
);
3515 "cannot add typedef in \"stream\" declaration");
3519 case NODE_TYPEALIAS
:
3520 ret
= visit_typealias(ctx
, node
->u
.typealias
.target
,
3521 node
->u
.typealias
.alias
);
3523 _PERROR("%s", "cannot add typealias in \"stream\" declaration");
3527 case NODE_CTF_EXPRESSION
:
3529 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3535 if (!strcmp(left
, "id")) {
3539 if (_IS_SET(set
, _STREAM_ID_SET
)) {
3540 _PERROR_DUP_ATTR("id", "stream declaration");
3545 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3547 if (ret
|| id
< 0) {
3548 _PERROR("%s", "unexpected unary expression for stream declaration's \"id\" attribute");
3553 ptr
= g_hash_table_lookup(ctx
->stream_classes
,
3556 _PERROR("duplicate stream with ID %" PRId64
,
3562 ret
= bt_ctf_stream_class_set_id(stream_class
, id
);
3565 "cannot set stream declaration's ID");
3569 _SET(set
, _STREAM_ID_SET
);
3570 } else if (!strcmp(left
, "event.header")) {
3571 if (_IS_SET(set
, _STREAM_EVENT_HEADER_SET
)) {
3572 _PERROR("%s", "duplicate \"event.header\" entry in stream declaration");
3577 ret
= visit_type_specifier_list(ctx
,
3578 _BT_LIST_FIRST_ENTRY(
3579 &node
->u
.ctf_expression
.right
,
3580 struct ctf_node
, siblings
),
3583 _PERROR("%s", "cannot create event header declaration");
3589 ret
= bt_ctf_stream_class_set_event_header_type(
3590 stream_class
, decl
);
3593 _PERROR("%s", "cannot set stream's event header declaration");
3597 _SET(set
, _STREAM_EVENT_HEADER_SET
);
3598 } else if (!strcmp(left
, "event.context")) {
3599 if (_IS_SET(set
, _STREAM_EVENT_CONTEXT_SET
)) {
3600 _PERROR("%s", "duplicate \"event.context\" entry in stream declaration");
3605 ret
= visit_type_specifier_list(ctx
,
3606 _BT_LIST_FIRST_ENTRY(
3607 &node
->u
.ctf_expression
.right
,
3608 struct ctf_node
, siblings
),
3611 _PERROR("%s", "cannot create stream event context declaration");
3617 ret
= bt_ctf_stream_class_set_event_context_type(
3618 stream_class
, decl
);
3621 _PERROR("%s", "cannot set stream's event context declaration");
3625 _SET(set
, _STREAM_EVENT_CONTEXT_SET
);
3626 } else if (!strcmp(left
, "packet.context")) {
3627 if (_IS_SET(set
, _STREAM_PACKET_CONTEXT_SET
)) {
3628 _PERROR("%s", "duplicate \"packet.context\" entry in stream declaration");
3633 ret
= visit_type_specifier_list(ctx
,
3634 _BT_LIST_FIRST_ENTRY(
3635 &node
->u
.ctf_expression
.right
,
3636 struct ctf_node
, siblings
),
3639 _PERROR("%s", "cannot create packet context declaration");
3645 ret
= bt_ctf_stream_class_set_packet_context_type(
3646 stream_class
, decl
);
3649 _PERROR("%s", "cannot set stream's packet context declaration");
3653 _SET(set
, _STREAM_PACKET_CONTEXT_SET
);
3655 _PWARNING("unknown attribute \"%s\" in stream declaration",
3679 int visit_stream_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3684 struct ctf_node
*iter
;
3685 struct bt_ctf_stream_class
*stream_class
= NULL
;
3686 struct bt_list_head
*decl_list
= &node
->u
.stream
.declaration_list
;
3688 if (node
->visited
) {
3692 node
->visited
= TRUE
;
3693 stream_class
= create_reset_stream_class(ctx
);
3694 if (!stream_class
) {
3699 ret
= ctx_push_scope(ctx
);
3701 _PERROR("%s", "cannot push scope");
3705 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3706 ret
= visit_stream_decl_entry(ctx
, iter
, stream_class
, &set
);
3715 if (_IS_SET(&set
, _STREAM_ID_SET
)) {
3716 /* Check that packet header has stream_id field */
3717 _BT_CTF_FIELD_TYPE_INIT(stream_id_decl
);
3718 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl
);
3720 packet_header_decl
=
3721 bt_ctf_trace_get_packet_header_type(ctx
->trace
);
3722 if (!packet_header_decl
) {
3724 "cannot get trace packet header declaration");
3729 bt_ctf_field_type_structure_get_field_type_by_name(
3730 packet_header_decl
, "stream_id");
3731 BT_PUT(packet_header_decl
);
3732 if (!stream_id_decl
) {
3733 _PERROR("%s", "missing \"stream_id\" field in packet header declaration, but \"id\" attribute is declared for stream");
3737 if (!bt_ctf_field_type_is_integer(stream_id_decl
)) {
3738 BT_PUT(stream_id_decl
);
3739 _PERROR("%s", "\"stream_id\" field in packet header declaration is not an integer");
3743 BT_PUT(stream_id_decl
);
3745 /* Allow only _one_ ID-less stream */
3746 if (g_hash_table_size(ctx
->stream_classes
) != 0) {
3748 "missing \"id\" field in stream declaration");
3753 /* Automatic ID: 0 */
3754 ret
= bt_ctf_stream_class_set_id(stream_class
, 0);
3757 id
= bt_ctf_stream_class_get_id(stream_class
);
3759 _PERROR("wrong stream ID: %" PRId64
, id
);
3764 /* Move reference to visitor's context */
3765 g_hash_table_insert(ctx
->stream_classes
, (gpointer
) (int64_t) id
,
3767 stream_class
= NULL
;
3773 BT_PUT(stream_class
);
3779 int visit_trace_decl_entry(struct ctx
*ctx
, struct ctf_node
*node
, int *set
)
3783 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl
);
3785 switch (node
->type
) {
3787 ret
= visit_typedef(ctx
, node
->u
._typedef
.type_specifier_list
,
3788 &node
->u
._typedef
.type_declarators
);
3791 "cannot add typedef in \"trace\" declaration");
3795 case NODE_TYPEALIAS
:
3796 ret
= visit_typealias(ctx
, node
->u
.typealias
.target
,
3797 node
->u
.typealias
.alias
);
3800 "cannot add typealias in \"trace\" declaration");
3804 case NODE_CTF_EXPRESSION
:
3806 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
3812 if (!strcmp(left
, "major")) {
3813 if (_IS_SET(set
, _TRACE_MAJOR_SET
)) {
3814 _PERROR_DUP_ATTR("major", "trace declaration");
3819 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3822 _PERROR("%s", "unexpected unary expression for trace's \"major\" attribute");
3827 _SET(set
, _TRACE_MAJOR_SET
);
3828 } else if (!strcmp(left
, "minor")) {
3829 if (_IS_SET(set
, _TRACE_MINOR_SET
)) {
3830 _PERROR_DUP_ATTR("minor", "trace declaration");
3835 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
,
3838 _PERROR("%s", "unexpected unary expression for trace's \"minor\" attribute");
3843 _SET(set
, _TRACE_MINOR_SET
);
3844 } else if (!strcmp(left
, "uuid")) {
3845 if (_IS_SET(set
, _TRACE_UUID_SET
)) {
3846 _PERROR_DUP_ATTR("uuid", "trace declaration");
3851 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
,
3855 "invalid trace declaration's UUID");
3859 _SET(set
, _TRACE_UUID_SET
);
3860 } else if (!strcmp(left
, "byte_order")) {
3861 /* Native byte order is already known at this stage */
3862 if (_IS_SET(set
, _TRACE_BYTE_ORDER_SET
)) {
3863 _PERROR_DUP_ATTR("byte_order",
3864 "trace declaration");
3869 _SET(set
, _TRACE_BYTE_ORDER_SET
);
3870 } else if (!strcmp(left
, "packet.header")) {
3871 if (_IS_SET(set
, _TRACE_PACKET_HEADER_SET
)) {
3872 _PERROR("%s", "duplicate \"packet.header\" entry in trace declaration");
3877 ret
= visit_type_specifier_list(ctx
,
3878 _BT_LIST_FIRST_ENTRY(
3879 &node
->u
.ctf_expression
.right
,
3880 struct ctf_node
, siblings
),
3881 &packet_header_decl
);
3883 _PERROR("%s", "cannot create packet header declaration");
3887 assert(packet_header_decl
);
3888 ret
= bt_ctf_trace_set_packet_header_type(ctx
->trace
,
3889 packet_header_decl
);
3890 BT_PUT(packet_header_decl
);
3892 _PERROR("%s", "cannot set trace declaration's packet header declaration");
3896 _SET(set
, _TRACE_PACKET_HEADER_SET
);
3898 _PWARNING("%s", "unknown attribute \"%s\" in trace declaration");
3906 _PERROR("%s", "unknown expression in trace declaration");
3915 BT_PUT(packet_header_decl
);
3921 int visit_trace_decl(struct ctx
*ctx
, struct ctf_node
*node
)
3925 struct ctf_node
*iter
;
3926 struct bt_list_head
*decl_list
= &node
->u
.trace
.declaration_list
;
3928 if (node
->visited
) {
3932 node
->visited
= TRUE
;
3934 if (ctx
->is_trace_visited
) {
3935 _PERROR("%s", "duplicate \"trace\" block");
3940 ret
= ctx_push_scope(ctx
);
3942 _PERROR("%s", "cannot push scope");
3946 bt_list_for_each_entry(iter
, decl_list
, siblings
) {
3947 ret
= visit_trace_decl_entry(ctx
, iter
, &set
);
3956 if (!_IS_SET(&set
, _TRACE_MAJOR_SET
)) {
3958 "missing \"major\" attribute in trace declaration");
3963 if (!_IS_SET(&set
, _TRACE_MINOR_SET
)) {
3965 "missing \"minor\" attribute in trace declaration");
3970 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
3971 _PERROR("%s", "missing \"byte_order\" attribute in trace declaration");
3976 ctx
->is_trace_visited
= TRUE
;
3986 int visit_env(struct ctx
*ctx
, struct ctf_node
*node
)
3990 struct ctf_node
*entry_node
;
3991 struct bt_list_head
*decl_list
= &node
->u
.env
.declaration_list
;
3993 if (node
->visited
) {
3997 node
->visited
= TRUE
;
3999 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4000 struct bt_list_head
*right_head
=
4001 &entry_node
->u
.ctf_expression
.right
;
4003 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4004 _PERROR("%s", "wrong expression in environment entry");
4009 left
= concatenate_unary_strings(
4010 &entry_node
->u
.ctf_expression
.left
);
4012 _PERROR("%s", "cannot get environment entry name");
4017 if (is_unary_string(right_head
)) {
4018 char *right
= concatenate_unary_strings(right_head
);
4021 _PERROR("unexpected unary expression for environment entry's value (\"%s\")",
4027 printf_verbose("env.%s = \"%s\"\n", left
, right
);
4028 ret
= bt_ctf_trace_set_environment_field_string(
4029 ctx
->trace
, left
, right
);
4033 _PERROR("environment: cannot add entry \"%s\" to trace",
4037 } else if (is_unary_unsigned(right_head
) ||
4038 is_unary_signed(right_head
)) {
4041 if (is_unary_unsigned(right_head
)) {
4042 ret
= get_unary_unsigned(right_head
,
4045 ret
= get_unary_signed(right_head
, &v
);
4048 _PERROR("unexpected unary expression for environment entry's value (\"%s\")",
4054 printf_verbose("env.%s = %" PRId64
"\n", left
, v
);
4055 ret
= bt_ctf_trace_set_environment_field_integer(
4056 ctx
->trace
, left
, v
);
4058 _PERROR("environment: cannot add entry \"%s\" to trace",
4063 printf_verbose("%s: environment entry \"%s\" has unknown type\n",
4081 int set_trace_byte_order(struct ctx
*ctx
, struct ctf_node
*trace_node
)
4086 struct ctf_node
*node
;
4087 struct bt_list_head
*decl_list
= &trace_node
->u
.trace
.declaration_list
;
4089 bt_list_for_each_entry(node
, decl_list
, siblings
) {
4090 if (node
->type
== NODE_CTF_EXPRESSION
) {
4091 struct ctf_node
*right_node
;
4093 left
= concatenate_unary_strings(
4094 &node
->u
.ctf_expression
.left
);
4100 if (!strcmp(left
, "byte_order")) {
4101 enum bt_ctf_byte_order bo
;
4103 if (_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4104 _PERROR_DUP_ATTR("byte_order",
4105 "trace declaration");
4110 _SET(&set
, _TRACE_BYTE_ORDER_SET
);
4111 right_node
= _BT_LIST_FIRST_ENTRY(
4112 &node
->u
.ctf_expression
.right
,
4113 struct ctf_node
, siblings
);
4114 bo
= byte_order_from_unary_expr(ctx
->efd
,
4116 if (bo
== BT_CTF_BYTE_ORDER_UNKNOWN
) {
4117 _PERROR("%s", "unknown \"byte_order\" attribute in trace declaration");
4120 } else if (bo
== BT_CTF_BYTE_ORDER_NATIVE
) {
4121 _PERROR("%s", "\"byte_order\" attribute cannot be set to \"native\" in trace declaration");
4126 ret
= bt_ctf_trace_set_native_byte_order(
4129 _PERROR("cannot set trace's byte order (%d)",
4140 if (!_IS_SET(&set
, _TRACE_BYTE_ORDER_SET
)) {
4141 _PERROR("%s", "missing \"byte_order\" attribute in trace declaration");
4155 int visit_clock_decl_entry(struct ctx
*ctx
, struct ctf_node
*entry_node
,
4156 struct bt_ctf_clock_class
*clock
, int *set
)
4161 if (entry_node
->type
!= NODE_CTF_EXPRESSION
) {
4166 left
= concatenate_unary_strings(&entry_node
->u
.ctf_expression
.left
);
4172 if (!strcmp(left
, "name")) {
4175 if (_IS_SET(set
, _CLOCK_NAME_SET
)) {
4176 _PERROR_DUP_ATTR("name", "clock declaration");
4181 right
= concatenate_unary_strings(
4182 &entry_node
->u
.ctf_expression
.right
);
4184 _PERROR("%s", "unexpected unary expression for clock declaration's \"name\" attribute");
4189 ret
= bt_ctf_clock_class_set_name(clock
, right
);
4191 _PERROR("%s", "cannot set clock's name");
4197 _SET(set
, _CLOCK_NAME_SET
);
4198 } else if (!strcmp(left
, "uuid")) {
4199 unsigned char uuid
[BABELTRACE_UUID_LEN
];
4201 if (_IS_SET(set
, _CLOCK_UUID_SET
)) {
4202 _PERROR_DUP_ATTR("uuid", "clock declaration");
4207 ret
= get_unary_uuid(&entry_node
->u
.ctf_expression
.right
, uuid
);
4209 _PERROR("%s", "invalid clock UUID");
4213 ret
= bt_ctf_clock_class_set_uuid(clock
, uuid
);
4215 _PERROR("%s", "cannot set clock's UUID");
4219 _SET(set
, _CLOCK_UUID_SET
);
4220 } else if (!strcmp(left
, "description")) {
4223 if (_IS_SET(set
, _CLOCK_DESCRIPTION_SET
)) {
4224 _PERROR_DUP_ATTR("description", "clock declaration");
4229 right
= concatenate_unary_strings(
4230 &entry_node
->u
.ctf_expression
.right
);
4232 _PERROR("%s", "unexpected unary expression for clock's \"description\" attribute");
4237 ret
= bt_ctf_clock_class_set_description(clock
, right
);
4239 _PERROR("%s", "cannot set clock's description");
4245 _SET(set
, _CLOCK_DESCRIPTION_SET
);
4246 } else if (!strcmp(left
, "freq")) {
4249 if (_IS_SET(set
, _CLOCK_FREQ_SET
)) {
4250 _PERROR_DUP_ATTR("freq", "clock declaration");
4255 ret
= get_unary_unsigned(
4256 &entry_node
->u
.ctf_expression
.right
, &freq
);
4258 _PERROR("%s", "unexpected unary expression for clock declaration's \"freq\" attribute");
4263 ret
= bt_ctf_clock_class_set_frequency(clock
, freq
);
4265 _PERROR("%s", "cannot set clock's frequency");
4269 _SET(set
, _CLOCK_FREQ_SET
);
4270 } else if (!strcmp(left
, "precision")) {
4273 if (_IS_SET(set
, _CLOCK_PRECISION_SET
)) {
4274 _PERROR_DUP_ATTR("precision", "clock declaration");
4279 ret
= get_unary_unsigned(
4280 &entry_node
->u
.ctf_expression
.right
, &precision
);
4282 _PERROR("%s", "unexpected unary expression for clock declaration's \"precision\" attribute");
4287 ret
= bt_ctf_clock_class_set_precision(clock
, precision
);
4289 _PERROR("%s", "cannot set clock's precision");
4293 _SET(set
, _CLOCK_PRECISION_SET
);
4294 } else if (!strcmp(left
, "offset_s")) {
4297 if (_IS_SET(set
, _CLOCK_OFFSET_S_SET
)) {
4298 _PERROR_DUP_ATTR("offset_s", "clock declaration");
4303 ret
= get_unary_unsigned(
4304 &entry_node
->u
.ctf_expression
.right
, &offset_s
);
4306 _PERROR("%s", "unexpected unary expression for clock declaration's \"offset_s\" attribute");
4311 ret
= bt_ctf_clock_class_set_offset_s(clock
, offset_s
);
4313 _PERROR("%s", "cannot set clock's offset in seconds");
4317 _SET(set
, _CLOCK_OFFSET_S_SET
);
4318 } else if (!strcmp(left
, "offset")) {
4321 if (_IS_SET(set
, _CLOCK_OFFSET_SET
)) {
4322 _PERROR_DUP_ATTR("offset", "clock declaration");
4327 ret
= get_unary_unsigned(
4328 &entry_node
->u
.ctf_expression
.right
, &offset
);
4330 _PERROR("%s", "unexpected unary expression for clock declaration's \"offset\" attribute");
4335 ret
= bt_ctf_clock_class_set_offset_cycles(clock
, offset
);
4337 _PERROR("%s", "cannot set clock's offset in cycles");
4341 _SET(set
, _CLOCK_OFFSET_SET
);
4342 } else if (!strcmp(left
, "absolute")) {
4343 struct ctf_node
*right
;
4345 if (_IS_SET(set
, _CLOCK_ABSOLUTE_SET
)) {
4346 _PERROR_DUP_ATTR("absolute", "clock declaration");
4351 right
= _BT_LIST_FIRST_ENTRY(
4352 &entry_node
->u
.ctf_expression
.right
,
4353 struct ctf_node
, siblings
);
4354 ret
= get_boolean(ctx
->efd
, right
);
4356 _PERROR("%s", "unexpected unary expression for clock declaration's \"absolute\" attribute");
4361 ret
= bt_ctf_clock_class_set_is_absolute(clock
, ret
);
4363 _PERROR("%s", "cannot set clock's absolute option");
4367 _SET(set
, _CLOCK_ABSOLUTE_SET
);
4369 _PWARNING("unknown attribute \"%s\" in clock declaration",
4385 uint64_t cycles_from_ns(uint64_t frequency
, uint64_t ns
)
4390 if (frequency
== 1000000000ULL) {
4393 cycles
= (uint64_t) (((double) ns
* (double) frequency
) / 1e9
);
4400 int apply_clock_offset(struct ctx
*ctx
, struct bt_ctf_clock_class
*clock
,
4401 uint64_t clock_offset_ns
)
4405 int64_t offset_cycles
;
4407 freq
= bt_ctf_clock_class_get_frequency(clock
);
4408 if (freq
== -1ULL) {
4409 _PERROR("%s", "No clock frequency");
4414 ret
= bt_ctf_clock_class_get_offset_cycles(clock
, &offset_cycles
);
4416 _PERROR("%s", "Getting offset cycles");
4421 offset_cycles
+= cycles_from_ns(freq
, clock_offset_ns
);
4423 ret
= bt_ctf_clock_class_set_offset_cycles(clock
, offset_cycles
);
4430 int visit_clock_decl(struct ctx
*ctx
, struct ctf_node
*clock_node
,
4431 uint64_t clock_offset_ns
)
4435 struct bt_ctf_clock_class
*clock
;
4436 struct ctf_node
*entry_node
;
4437 struct bt_list_head
*decl_list
= &clock_node
->u
.clock
.declaration_list
;
4439 if (clock_node
->visited
) {
4443 clock_node
->visited
= TRUE
;
4444 clock
= bt_ctf_clock_class_create(NULL
);
4446 _PERROR("%s", "cannot create clock");
4451 bt_list_for_each_entry(entry_node
, decl_list
, siblings
) {
4452 ret
= visit_clock_decl_entry(ctx
, entry_node
, clock
, &set
);
4458 if (!_IS_SET(&set
, _CLOCK_NAME_SET
)) {
4460 "missing \"name\" attribute in clock declaration");
4465 if (bt_ctf_trace_get_clock_class_count(ctx
->trace
) != 0) {
4466 _PERROR("%s", "only CTF traces with a single clock declaration are supported as of this version");
4471 ret
= apply_clock_offset(ctx
, clock
, clock_offset_ns
);
4473 _PERROR("%s", "cannot apply clock offset ");
4477 ret
= bt_ctf_trace_add_clock_class(ctx
->trace
, clock
);
4479 _PERROR("%s", "cannot add clock to trace");
4490 int visit_root_decl(struct ctx
*ctx
, struct ctf_node
*root_decl_node
)
4494 if (root_decl_node
->visited
) {
4498 root_decl_node
->visited
= TRUE
;
4500 switch (root_decl_node
->type
) {
4502 ret
= visit_typedef(ctx
,
4503 root_decl_node
->u
._typedef
.type_specifier_list
,
4504 &root_decl_node
->u
._typedef
.type_declarators
);
4506 _PERROR("%s", "cannot add typedef in root scope");
4510 case NODE_TYPEALIAS
:
4511 ret
= visit_typealias(ctx
, root_decl_node
->u
.typealias
.target
,
4512 root_decl_node
->u
.typealias
.alias
);
4514 _PERROR("%s", "cannot add typealias in root scope");
4518 case NODE_TYPE_SPECIFIER_LIST
:
4520 _BT_CTF_FIELD_TYPE_INIT(decl
);
4523 * Just add the type specifier to the root
4524 * declaration scope. Put local reference.
4526 ret
= visit_type_specifier_list(ctx
, root_decl_node
, &decl
);
4545 int add_stream_classes_to_trace(struct ctx
*ctx
)
4548 GHashTableIter iter
;
4549 gpointer key
, stream_class
;
4551 g_hash_table_iter_init(&iter
, ctx
->stream_classes
);
4553 while (g_hash_table_iter_next(&iter
, &key
, &stream_class
)) {
4554 ret
= bt_ctf_trace_add_stream_class(ctx
->trace
,
4557 int64_t id
= bt_ctf_stream_class_get_id(stream_class
);
4558 _PERROR("cannot add stream class %" PRId64
" to trace",
4568 int ctf_visitor_generate_ir(FILE *efd
, struct ctf_node
*node
,
4569 struct bt_ctf_trace
**trace
, uint64_t clock_offset_ns
)
4572 struct ctx
*ctx
= NULL
;
4574 printf_verbose("CTF visitor: AST -> CTF IR...\n");
4576 *trace
= bt_ctf_trace_create();
4578 _FPERROR(efd
, "%s", "cannot create trace");
4583 /* Set packet header to NULL to override the default one */
4584 ret
= bt_ctf_trace_set_packet_header_type(*trace
, NULL
);
4588 "cannot set initial, empty packet header structure");
4592 ctx
= ctx_create(*trace
, efd
);
4594 _FPERROR(efd
, "%s", "cannot create visitor context");
4599 switch (node
->type
) {
4602 struct ctf_node
*iter
;
4603 int got_trace_decl
= FALSE
;
4604 int found_callsite
= FALSE
;
4607 * Find trace declaration's byte order first (for early
4610 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4611 if (got_trace_decl
) {
4612 _PERROR("%s", "duplicate trace declaration");
4616 ret
= set_trace_byte_order(ctx
, iter
);
4618 _PERROR("cannot set trace's byte order (%d)",
4623 got_trace_decl
= TRUE
;
4626 if (!got_trace_decl
) {
4627 _PERROR("no trace declaration found (%d)", ret
);
4633 * Visit clocks first since any early integer can be mapped
4636 bt_list_for_each_entry(iter
, &node
->u
.root
.clock
, siblings
) {
4637 ret
= visit_clock_decl(ctx
, iter
, clock_offset_ns
);
4639 _PERROR("error while visiting clock declaration (%d)",
4646 * Visit root declarations next, as they can be used by any
4649 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
4651 ret
= visit_root_decl(ctx
, iter
);
4653 _PERROR("error while visiting root declaration (%d)",
4659 /* Callsite are not supported */
4660 bt_list_for_each_entry(iter
, &node
->u
.root
.callsite
, siblings
) {
4661 found_callsite
= TRUE
;
4665 if (found_callsite
) {
4666 _PWARNING("%s", "\"callsite\" blocks are not supported as of this version");
4670 bt_list_for_each_entry(iter
, &node
->u
.root
.env
, siblings
) {
4671 ret
= visit_env(ctx
, iter
);
4673 _PERROR("error while visiting environment block (%d)",
4680 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
4681 ret
= visit_trace_decl(ctx
, iter
);
4683 _PERROR("%s", "error while visiting trace declaration");
4689 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
4690 ret
= visit_stream_decl(ctx
, iter
);
4692 _PERROR("%s", "error while visiting stream declaration");
4698 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
4699 ret
= visit_event_decl(ctx
, iter
);
4701 _PERROR("%s", "error while visiting event declaration");
4709 _PERROR("unknown node type: %d", (int) node
->type
);
4714 /* Add stream classes to trace now */
4715 ret
= add_stream_classes_to_trace(ctx
);
4717 _PERROR("%s", "cannot add stream classes to trace");
4721 printf_verbose("done!\n");