19a67896bfe936b850d7b41d75c66cf2f71c6cc0
[babeltrace.git] / plugins / ctf / common / metadata / visitor-generate-ir.c
1 /*
2 * ctf-visitor-generate-ir.c
3 *
4 * Common Trace Format metadata visitor (generates CTF IR objects).
5 *
6 * Based on older ctf-visitor-generate-io-struct.c.
7 *
8 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Copyright 2015-2016 - Philippe Proulx <philippe.proulx@efficios.com>
10 *
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:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
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
27 * SOFTWARE.
28 */
29
30 #define BT_LOG_TAG "PLUGIN-CTF-METADATA-IR-VISITOR"
31 #include "logging.h"
32
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <stdbool.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39 #include <assert.h>
40 #include <glib.h>
41 #include <inttypes.h>
42 #include <errno.h>
43 #include <babeltrace/compat/uuid-internal.h>
44 #include <babeltrace/endian-internal.h>
45 #include <babeltrace/ref.h>
46 #include <babeltrace/ctf-ir/trace.h>
47 #include <babeltrace/ctf-ir/stream-class.h>
48 #include <babeltrace/ctf-ir/event.h>
49 #include <babeltrace/ctf-ir/event-class.h>
50 #include <babeltrace/ctf-ir/field-types.h>
51 #include <babeltrace/ctf-ir/field-types-internal.h>
52 #include <babeltrace/ctf-ir/clock-class.h>
53
54 #include "scanner.h"
55 #include "parser.h"
56 #include "ast.h"
57
58 /* Bit value (left shift) */
59 #define _BV(_val) (1 << (_val))
60
61 /* Bit is set in a set of bits */
62 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
63
64 /* Set bit in a set of bits */
65 #define _SET(_set, _mask) (*(_set) |= (_mask))
66
67 /* Bits for verifying existing attributes in various declarations */
68 enum {
69 _CLOCK_NAME_SET = _BV(0),
70 _CLOCK_UUID_SET = _BV(1),
71 _CLOCK_FREQ_SET = _BV(2),
72 _CLOCK_PRECISION_SET = _BV(3),
73 _CLOCK_OFFSET_S_SET = _BV(4),
74 _CLOCK_OFFSET_SET = _BV(5),
75 _CLOCK_ABSOLUTE_SET = _BV(6),
76 _CLOCK_DESCRIPTION_SET = _BV(7),
77 };
78
79 enum {
80 _INTEGER_ALIGN_SET = _BV(0),
81 _INTEGER_SIZE_SET = _BV(1),
82 _INTEGER_BASE_SET = _BV(2),
83 _INTEGER_ENCODING_SET = _BV(3),
84 _INTEGER_BYTE_ORDER_SET = _BV(4),
85 _INTEGER_SIGNED_SET = _BV(5),
86 _INTEGER_MAP_SET = _BV(6),
87 };
88
89 enum {
90 _FLOAT_ALIGN_SET = _BV(0),
91 _FLOAT_MANT_DIG_SET = _BV(1),
92 _FLOAT_EXP_DIG_SET = _BV(2),
93 _FLOAT_BYTE_ORDER_SET = _BV(3),
94 };
95
96 enum {
97 _STRING_ENCODING_SET = _BV(0),
98 };
99
100 enum {
101 _TRACE_MINOR_SET = _BV(0),
102 _TRACE_MAJOR_SET = _BV(1),
103 _TRACE_BYTE_ORDER_SET = _BV(2),
104 _TRACE_UUID_SET = _BV(3),
105 _TRACE_PACKET_HEADER_SET = _BV(4),
106 };
107
108 enum {
109 _STREAM_ID_SET = _BV(0),
110 _STREAM_PACKET_CONTEXT_SET = _BV(1),
111 _STREAM_EVENT_HEADER_SET = _BV(2),
112 _STREAM_EVENT_CONTEXT_SET = _BV(3),
113 };
114
115 enum {
116 _EVENT_NAME_SET = _BV(0),
117 _EVENT_ID_SET = _BV(1),
118 _EVENT_MODEL_EMF_URI_SET = _BV(2),
119 _EVENT_STREAM_ID_SET = _BV(3),
120 _EVENT_LOGLEVEL_SET = _BV(4),
121 _EVENT_CONTEXT_SET = _BV(5),
122 _EVENT_FIELDS_SET = _BV(6),
123 };
124
125 enum loglevel {
126 LOGLEVEL_EMERG = 0,
127 LOGLEVEL_ALERT = 1,
128 LOGLEVEL_CRIT = 2,
129 LOGLEVEL_ERR = 3,
130 LOGLEVEL_WARNING = 4,
131 LOGLEVEL_NOTICE = 5,
132 LOGLEVEL_INFO = 6,
133 LOGLEVEL_DEBUG_SYSTEM = 7,
134 LOGLEVEL_DEBUG_PROGRAM = 8,
135 LOGLEVEL_DEBUG_PROCESS = 9,
136 LOGLEVEL_DEBUG_MODULE = 10,
137 LOGLEVEL_DEBUG_UNIT = 11,
138 LOGLEVEL_DEBUG_FUNCTION = 12,
139 LOGLEVEL_DEBUG_LINE = 13,
140 LOGLEVEL_DEBUG = 14,
141 _NR_LOGLEVELS = 15,
142 };
143
144 /* Prefixes of type aliases */
145 #define _PREFIX_ALIAS 'a'
146 #define _PREFIX_ENUM 'e'
147 #define _PREFIX_STRUCT 's'
148 #define _PREFIX_VARIANT 'v'
149
150 /* First entry in a BT list */
151 #define _BT_LIST_FIRST_ENTRY(_ptr, _type, _member) \
152 bt_list_entry((_ptr)->next, _type, _member)
153
154 #define _BT_CTF_FIELD_TYPE_INIT(_name) struct bt_ctf_field_type *_name = NULL;
155
156 #define _BT_LOGE_DUP_ATTR(_node, _attr, _entity) \
157 _BT_LOGE_LINENO((_node)->lineno, \
158 "Duplicate attribute in %s: attr-name=\"%s\"", \
159 _entity, _attr)
160
161 #define _BT_LOGE_NODE(_node, _msg, args...) \
162 _BT_LOGE_LINENO((_node)->lineno, _msg, ## args)
163
164 #define _BT_LOGW_NODE(_node, _msg, args...) \
165 _BT_LOGW_LINENO((_node)->lineno, _msg, ## args)
166
167 #define _BT_LOGV_NODE(_node, _msg, args...) \
168 _BT_LOGV_LINENO((_node)->lineno, _msg, ## args)
169
170 /*
171 * Declaration scope of a visitor context. This represents a TSDL
172 * lexical scope, so that aliases and named structures, variants,
173 * and enumerations may be registered and looked up hierarchically.
174 */
175 struct ctx_decl_scope {
176 /*
177 * Alias name to field type.
178 *
179 * GQuark -> struct bt_ctf_field_type *
180 */
181 GHashTable *decl_map;
182
183 /* Parent scope; NULL if this is the root declaration scope */
184 struct ctx_decl_scope *parent_scope;
185 };
186
187 /*
188 * Visitor context (private).
189 */
190 struct ctx {
191 /* Trace being filled (owned by this) */
192 struct bt_ctf_trace *trace;
193
194 /* Current declaration scope (top of the stack) */
195 struct ctx_decl_scope *current_scope;
196
197 /* 1 if trace declaration is visited */
198 int is_trace_visited;
199
200 /* 1 if this is an LTTng trace */
201 bool is_lttng;
202
203 /* Offset (ns) to apply to clock classes on creation */
204 int64_t clock_class_offset_ns;
205
206 /* Eventual name suffix of the trace to set */
207 char *trace_name_suffix;
208
209 /* Trace attributes */
210 enum bt_ctf_byte_order trace_bo;
211 uint64_t trace_major;
212 uint64_t trace_minor;
213 unsigned char trace_uuid[BABELTRACE_UUID_LEN];
214
215 /*
216 * Stream IDs to stream classes.
217 *
218 * int64_t -> struct bt_ctf_stream_class *
219 */
220 GHashTable *stream_classes;
221 };
222
223 /*
224 * Visitor (public).
225 */
226 struct ctf_visitor_generate_ir { };
227
228 static
229 const char *loglevel_str [] = {
230 [ LOGLEVEL_EMERG ] = "TRACE_EMERG",
231 [ LOGLEVEL_ALERT ] = "TRACE_ALERT",
232 [ LOGLEVEL_CRIT ] = "TRACE_CRIT",
233 [ LOGLEVEL_ERR ] = "TRACE_ERR",
234 [ LOGLEVEL_WARNING ] = "TRACE_WARNING",
235 [ LOGLEVEL_NOTICE ] = "TRACE_NOTICE",
236 [ LOGLEVEL_INFO ] = "TRACE_INFO",
237 [ LOGLEVEL_DEBUG_SYSTEM ] = "TRACE_DEBUG_SYSTEM",
238 [ LOGLEVEL_DEBUG_PROGRAM ] = "TRACE_DEBUG_PROGRAM",
239 [ LOGLEVEL_DEBUG_PROCESS ] = "TRACE_DEBUG_PROCESS",
240 [ LOGLEVEL_DEBUG_MODULE ] = "TRACE_DEBUG_MODULE",
241 [ LOGLEVEL_DEBUG_UNIT ] = "TRACE_DEBUG_UNIT",
242 [ LOGLEVEL_DEBUG_FUNCTION ] = "TRACE_DEBUG_FUNCTION",
243 [ LOGLEVEL_DEBUG_LINE ] = "TRACE_DEBUG_LINE",
244 [ LOGLEVEL_DEBUG ] = "TRACE_DEBUG",
245 };
246
247 static
248 const char *print_loglevel(int64_t value)
249 {
250 if (value < 0) {
251 return NULL;
252 }
253 if (value >= _NR_LOGLEVELS) {
254 return "<<UNKNOWN>>";
255 }
256 return loglevel_str[value];
257 }
258
259 /**
260 * Creates a new declaration scope.
261 *
262 * @param par_scope Parent scope (NULL if creating a root scope)
263 * @returns New declaration scope, or NULL on error
264 */
265 static
266 struct ctx_decl_scope *ctx_decl_scope_create(struct ctx_decl_scope *par_scope)
267 {
268 struct ctx_decl_scope *scope;
269
270 scope = g_new(struct ctx_decl_scope, 1);
271 if (!scope) {
272 BT_LOGE_STR("Failed to allocate one declaration scope.");
273 goto end;
274 }
275
276 scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal,
277 NULL, (GDestroyNotify) bt_ctf_field_type_put);
278 scope->parent_scope = par_scope;
279
280 end:
281 return scope;
282 }
283
284 /**
285 * Destroys a declaration scope.
286 *
287 * This function does not destroy the parent scope.
288 *
289 * @param scope Scope to destroy
290 */
291 static
292 void ctx_decl_scope_destroy(struct ctx_decl_scope *scope)
293 {
294 if (!scope) {
295 goto end;
296 }
297
298 g_hash_table_destroy(scope->decl_map);
299 g_free(scope);
300
301 end:
302 return;
303 }
304
305 /**
306 * Returns the GQuark of a prefixed alias.
307 *
308 * @param prefix Prefix character
309 * @param name Name
310 * @returns Associated GQuark, or 0 on error
311 */
312 static
313 GQuark get_prefixed_named_quark(char prefix, const char *name)
314 {
315 GQuark qname = 0;
316
317 assert(name);
318
319 /* Prefix character + original string + '\0' */
320 char *prname = g_new(char, strlen(name) + 2);
321 if (!prname) {
322 BT_LOGE_STR("Failed to allocate a string.");
323 goto end;
324 }
325
326 sprintf(prname, "%c%s", prefix, name);
327 qname = g_quark_from_string(prname);
328 g_free(prname);
329
330 end:
331 return qname;
332 }
333
334 /**
335 * Looks up a prefixed type alias within a declaration scope.
336 *
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
342 */
343 static
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)
347 {
348 GQuark qname = 0;
349 int cur_levels = 0;
350 _BT_CTF_FIELD_TYPE_INIT(decl);
351 struct ctx_decl_scope *cur_scope = scope;
352
353 assert(scope);
354 assert(name);
355 qname = get_prefixed_named_quark(prefix, name);
356 if (!qname) {
357 goto error;
358 }
359
360 if (levels < 0) {
361 levels = INT_MAX;
362 }
363
364 while (cur_scope && cur_levels < levels) {
365 decl = g_hash_table_lookup(cur_scope->decl_map,
366 (gconstpointer) GUINT_TO_POINTER(qname));
367 if (decl) {
368 /* Caller's reference */
369 bt_get(decl);
370 break;
371 }
372
373 cur_scope = cur_scope->parent_scope;
374 cur_levels++;
375 }
376
377 return decl;
378
379 error:
380 return NULL;
381 }
382
383 /**
384 * Looks up a type alias within a declaration scope.
385 *
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
390 */
391 static
392 struct bt_ctf_field_type *ctx_decl_scope_lookup_alias(
393 struct ctx_decl_scope *scope, const char *name, int levels)
394 {
395 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ALIAS,
396 name, levels);
397 }
398
399 /**
400 * Looks up an enumeration within a declaration scope.
401 *
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
406 */
407 static
408 struct bt_ctf_field_type *ctx_decl_scope_lookup_enum(
409 struct ctx_decl_scope *scope, const char *name, int levels)
410 {
411 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ENUM,
412 name, levels);
413 }
414
415 /**
416 * Looks up a structure within a declaration scope.
417 *
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
422 */
423 static
424 struct bt_ctf_field_type *ctx_decl_scope_lookup_struct(
425 struct ctx_decl_scope *scope, const char *name, int levels)
426 {
427 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_STRUCT,
428 name, levels);
429 }
430
431 /**
432 * Looks up a variant within a declaration scope.
433 *
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
438 */
439 static
440 struct bt_ctf_field_type *ctx_decl_scope_lookup_variant(
441 struct ctx_decl_scope *scope, const char *name, int levels)
442 {
443 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_VARIANT,
444 name, levels);
445 }
446
447 /**
448 * Registers a prefixed type alias within a declaration scope.
449 *
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
455 */
456 static
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)
459 {
460 int ret = 0;
461 GQuark qname = 0;
462 _BT_CTF_FIELD_TYPE_INIT(edecl);
463
464 assert(scope);
465 assert(name);
466 assert(decl);
467 qname = get_prefixed_named_quark(prefix, name);
468 if (!qname) {
469 ret = -ENOMEM;
470 goto error;
471 }
472
473 /* Make sure alias does not exist in local scope */
474 edecl = ctx_decl_scope_lookup_prefix_alias(scope, prefix, name, 1);
475 if (edecl) {
476 BT_PUT(edecl);
477 ret = -EEXIST;
478 goto error;
479 }
480
481 g_hash_table_insert(scope->decl_map,
482 GUINT_TO_POINTER(qname), decl);
483
484 /* Hash table's reference */
485 bt_get(decl);
486
487 return 0;
488
489 error:
490 return ret;
491 }
492
493 /**
494 * Registers a type alias within a declaration scope.
495 *
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
500 */
501 static
502 int ctx_decl_scope_register_alias(struct ctx_decl_scope *scope,
503 const char *name, struct bt_ctf_field_type *decl)
504 {
505 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ALIAS,
506 name, decl);
507 }
508
509 /**
510 * Registers an enumeration declaration within a declaration scope.
511 *
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
516 */
517 static
518 int ctx_decl_scope_register_enum(struct ctx_decl_scope *scope,
519 const char *name, struct bt_ctf_field_type *decl)
520 {
521 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ENUM,
522 name, decl);
523 }
524
525 /**
526 * Registers a structure declaration within a declaration scope.
527 *
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
532 */
533 static
534 int ctx_decl_scope_register_struct(struct ctx_decl_scope *scope,
535 const char *name, struct bt_ctf_field_type *decl)
536 {
537 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_STRUCT,
538 name, decl);
539 }
540
541 /**
542 * Registers a variant declaration within a declaration scope.
543 *
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
548 */
549 static
550 int ctx_decl_scope_register_variant(struct ctx_decl_scope *scope,
551 const char *name, struct bt_ctf_field_type *decl)
552 {
553 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_VARIANT,
554 name, decl);
555 }
556
557 /**
558 * Destroys a visitor context.
559 *
560 * @param ctx Visitor context to destroy
561 */
562 static
563 void ctx_destroy(struct ctx *ctx)
564 {
565 struct ctx_decl_scope *scope;
566 /*
567 * Destroy all scopes, from current one to the root scope.
568 */
569
570 if (!ctx) {
571 goto end;
572 }
573
574 scope = ctx->current_scope;
575
576 while (scope) {
577 struct ctx_decl_scope *parent_scope = scope->parent_scope;
578
579 ctx_decl_scope_destroy(scope);
580 scope = parent_scope;
581 }
582
583 bt_put(ctx->trace);
584
585 if (ctx->stream_classes) {
586 g_hash_table_destroy(ctx->stream_classes);
587 }
588
589 free(ctx->trace_name_suffix);
590 g_free(ctx);
591
592 end:
593 return;
594 }
595
596 /**
597 * Creates a new visitor context.
598 *
599 * @param trace Associated trace
600 * @returns New visitor context, or NULL on error
601 */
602 static
603 struct ctx *ctx_create(struct bt_ctf_trace *trace,
604 int64_t clock_class_offset_ns, const char *trace_name_suffix)
605 {
606 struct ctx *ctx = NULL;
607 struct ctx_decl_scope *scope = NULL;
608
609 ctx = g_new0(struct ctx, 1);
610 if (!ctx) {
611 BT_LOGE_STR("Failed to allocate one visitor context.");
612 goto error;
613 }
614
615 /* Root declaration scope */
616 scope = ctx_decl_scope_create(NULL);
617 if (!scope) {
618 BT_LOGE_STR("Cannot create declaration scope.");
619 goto error;
620 }
621
622 ctx->stream_classes = g_hash_table_new_full(g_direct_hash,
623 g_direct_equal, NULL, (GDestroyNotify) bt_put);
624 if (!ctx->stream_classes) {
625 BT_LOGE_STR("Failed to allocate a GHashTable.");
626 goto error;
627 }
628
629 if (trace_name_suffix) {
630 ctx->trace_name_suffix = strdup(trace_name_suffix);
631 if (!ctx->trace_name_suffix) {
632 BT_LOGE_STR("Failed to copy string.");
633 goto error;
634 }
635 }
636
637 ctx->trace = trace;
638 ctx->current_scope = scope;
639 scope = NULL;
640 ctx->trace_bo = BT_CTF_BYTE_ORDER_NATIVE;
641 ctx->clock_class_offset_ns = clock_class_offset_ns;
642 return ctx;
643
644 error:
645 ctx_destroy(ctx);
646 ctx_decl_scope_destroy(scope);
647 return NULL;
648 }
649
650 /**
651 * Pushes a new declaration scope on top of a visitor context's
652 * declaration scope stack.
653 *
654 * @param ctx Visitor context
655 * @returns 0 on success, or a negative value on error
656 */
657 static
658 int ctx_push_scope(struct ctx *ctx)
659 {
660 int ret = 0;
661 struct ctx_decl_scope *new_scope;
662
663 assert(ctx);
664 new_scope = ctx_decl_scope_create(ctx->current_scope);
665 if (!new_scope) {
666 BT_LOGE_STR("Cannot create declaration scope.");
667 ret = -ENOMEM;
668 goto end;
669 }
670
671 ctx->current_scope = new_scope;
672
673 end:
674 return ret;
675 }
676
677 static
678 void ctx_pop_scope(struct ctx *ctx)
679 {
680 struct ctx_decl_scope *parent_scope = NULL;
681
682 assert(ctx);
683
684 if (!ctx->current_scope) {
685 goto end;
686 }
687
688 parent_scope = ctx->current_scope->parent_scope;
689 ctx_decl_scope_destroy(ctx->current_scope);
690 ctx->current_scope = parent_scope;
691
692 end:
693 return;
694 }
695
696 static
697 int visit_type_specifier_list(struct ctx *ctx, struct ctf_node *ts_list,
698 struct bt_ctf_field_type **decl);
699
700 static
701 int is_unary_string(struct bt_list_head *head)
702 {
703 int ret = TRUE;
704 struct ctf_node *node;
705
706 bt_list_for_each_entry(node, head, siblings) {
707 if (node->type != NODE_UNARY_EXPRESSION) {
708 ret = FALSE;
709 }
710
711 if (node->u.unary_expression.type != UNARY_STRING) {
712 ret = FALSE;
713 }
714 }
715
716 return ret;
717 }
718
719 static
720 char *concatenate_unary_strings(struct bt_list_head *head)
721 {
722 int i = 0;
723 GString *str;
724 struct ctf_node *node;
725
726 str = g_string_new(NULL);
727 assert(str);
728
729 bt_list_for_each_entry(node, head, siblings) {
730 char *src_string;
731
732 if (
733 node->type != NODE_UNARY_EXPRESSION ||
734 node->u.unary_expression.type != UNARY_STRING ||
735 !(
736 (
737 node->u.unary_expression.link !=
738 UNARY_LINK_UNKNOWN
739 ) ^ (i == 0)
740 )
741 ) {
742 goto error;
743 }
744
745 switch (node->u.unary_expression.link) {
746 case UNARY_DOTLINK:
747 g_string_append(str, ".");
748 break;
749 case UNARY_ARROWLINK:
750 g_string_append(str, "->");
751 break;
752 case UNARY_DOTDOTDOT:
753 g_string_append(str, "...");
754 break;
755 default:
756 break;
757 }
758
759 src_string = node->u.unary_expression.u.string;
760 g_string_append(str, src_string);
761 i++;
762 }
763
764 /* Destroys the container, returns the underlying string */
765 return g_string_free(str, FALSE);
766
767 error:
768 /* This always returns NULL */
769 return g_string_free(str, TRUE);
770 }
771
772 static
773 const char *get_map_clock_name_value(struct bt_list_head *head)
774 {
775 int i = 0;
776 struct ctf_node *node;
777 const char *name = NULL;
778
779 bt_list_for_each_entry(node, head, siblings) {
780 char *src_string;
781 int uexpr_type = node->u.unary_expression.type;
782 int uexpr_link = node->u.unary_expression.link;
783 int cond = node->type != NODE_UNARY_EXPRESSION ||
784 uexpr_type != UNARY_STRING ||
785 !((uexpr_link != UNARY_LINK_UNKNOWN) ^ (i == 0));
786 if (cond) {
787 goto error;
788 }
789
790 /* Needs to be chained with . */
791 switch (node->u.unary_expression.link) {
792 case UNARY_DOTLINK:
793 break;
794 case UNARY_ARROWLINK:
795 case UNARY_DOTDOTDOT:
796 goto error;
797 default:
798 break;
799 }
800
801 src_string = node->u.unary_expression.u.string;
802
803 switch (i) {
804 case 0:
805 if (strcmp("clock", src_string)) {
806 goto error;
807 }
808 break;
809 case 1:
810 name = src_string;
811 break;
812 case 2:
813 if (strcmp("value", src_string)) {
814 goto error;
815 }
816 break;
817 default:
818 /* Extra identifier, unknown */
819 goto error;
820 }
821
822 i++;
823 }
824
825 return name;
826
827 error:
828 return NULL;
829 }
830
831 static
832 int is_unary_unsigned(struct bt_list_head *head)
833 {
834 int ret = TRUE;
835 struct ctf_node *node;
836
837 bt_list_for_each_entry(node, head, siblings) {
838 if (node->type != NODE_UNARY_EXPRESSION) {
839 ret = FALSE;
840 }
841
842 if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
843 ret = FALSE;
844 }
845 }
846
847 return ret;
848 }
849
850 static
851 int get_unary_unsigned(struct bt_list_head *head, uint64_t *value)
852 {
853 int i = 0;
854 int ret = 0;
855 struct ctf_node *node;
856
857 if (bt_list_empty(head)) {
858 ret = -1;
859 goto end;
860 }
861
862 bt_list_for_each_entry(node, head, siblings) {
863 int uexpr_type = node->u.unary_expression.type;
864 int uexpr_link = node->u.unary_expression.link;
865 int cond = node->type != NODE_UNARY_EXPRESSION ||
866 uexpr_type != UNARY_UNSIGNED_CONSTANT ||
867 uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
868 if (cond) {
869 _BT_LOGE_NODE(node, "Invalid constant unsigned integer.");
870 ret = -EINVAL;
871 goto end;
872 }
873
874 *value = node->u.unary_expression.u.unsigned_constant;
875 i++;
876 }
877
878 end:
879 return ret;
880 }
881
882 static
883 int is_unary_signed(struct bt_list_head *head)
884 {
885 int ret = TRUE;
886 struct ctf_node *node;
887
888 bt_list_for_each_entry(node, head, siblings) {
889 if (node->type != NODE_UNARY_EXPRESSION) {
890 ret = FALSE;
891 }
892
893 if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) {
894 ret = FALSE;
895 }
896 }
897
898 return ret;
899 }
900
901 static
902 int get_unary_signed(struct bt_list_head *head, int64_t *value)
903 {
904 int i = 0;
905 int ret = 0;
906 struct ctf_node *node;
907
908 bt_list_for_each_entry(node, head, siblings) {
909 int uexpr_type = node->u.unary_expression.type;
910 int uexpr_link = node->u.unary_expression.link;
911 int cond = node->type != NODE_UNARY_EXPRESSION ||
912 (uexpr_type != UNARY_UNSIGNED_CONSTANT) ||
913 (uexpr_type != UNARY_UNSIGNED_CONSTANT &&
914 uexpr_type != UNARY_SIGNED_CONSTANT) ||
915 uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
916 if (cond) {
917 ret = -EINVAL;
918 goto end;
919 }
920
921 switch (node->u.unary_expression.type) {
922 case UNARY_UNSIGNED_CONSTANT:
923 *value = (int64_t)
924 node->u.unary_expression.u.unsigned_constant;
925 break;
926 case UNARY_SIGNED_CONSTANT:
927 *value = node->u.unary_expression.u.signed_constant;
928 break;
929 default:
930 ret = -EINVAL;
931 goto end;
932 }
933
934 i++;
935 }
936
937 end:
938 return ret;
939 }
940
941 static
942 int get_unary_uuid(struct bt_list_head *head, unsigned char *uuid)
943 {
944 int i = 0;
945 int ret = 0;
946 struct ctf_node *node;
947
948 bt_list_for_each_entry(node, head, siblings) {
949 int uexpr_type = node->u.unary_expression.type;
950 int uexpr_link = node->u.unary_expression.link;
951 const char *src_string;
952
953 if (node->type != NODE_UNARY_EXPRESSION ||
954 uexpr_type != UNARY_STRING ||
955 uexpr_link != UNARY_LINK_UNKNOWN ||
956 i != 0) {
957 ret = -EINVAL;
958 goto end;
959 }
960
961 src_string = node->u.unary_expression.u.string;
962 ret = bt_uuid_parse(src_string, uuid);
963 if (ret) {
964 _BT_LOGE_NODE(node,
965 "Cannot parse UUID: uuid=\"%s\"", src_string);
966 goto end;
967 }
968 }
969
970 end:
971 return ret;
972 }
973
974 static
975 int get_boolean(struct ctf_node *unary_expr)
976 {
977 int ret = 0;
978
979 if (unary_expr->type != NODE_UNARY_EXPRESSION) {
980 _BT_LOGE_NODE(unary_expr,
981 "Expecting unary expression: node-type=%d",
982 unary_expr->type);
983 ret = -EINVAL;
984 goto end;
985 }
986
987 switch (unary_expr->u.unary_expression.type) {
988 case UNARY_UNSIGNED_CONSTANT:
989 ret = (unary_expr->u.unary_expression.u.unsigned_constant != 0);
990 break;
991 case UNARY_SIGNED_CONSTANT:
992 ret = (unary_expr->u.unary_expression.u.signed_constant != 0);
993 break;
994 case UNARY_STRING:
995 {
996 const char *str = unary_expr->u.unary_expression.u.string;
997
998 if (!strcmp(str, "true") || !strcmp(str, "TRUE")) {
999 ret = TRUE;
1000 } else if (!strcmp(str, "false") || !strcmp(str, "FALSE")) {
1001 ret = FALSE;
1002 } else {
1003 _BT_LOGE_NODE(unary_expr,
1004 "Unexpected boolean value: value=\"%s\"", str);
1005 ret = -EINVAL;
1006 goto end;
1007 }
1008 break;
1009 }
1010 default:
1011 _BT_LOGE_NODE(unary_expr,
1012 "Unexpected unary expression type: node-type=%d",
1013 unary_expr->u.unary_expression.type);
1014 ret = -EINVAL;
1015 goto end;
1016 }
1017
1018 end:
1019 return ret;
1020 }
1021
1022 static
1023 enum bt_ctf_byte_order byte_order_from_unary_expr(struct ctf_node *unary_expr)
1024 {
1025 const char *str;
1026 enum bt_ctf_byte_order bo = BT_CTF_BYTE_ORDER_UNKNOWN;
1027
1028 if (unary_expr->u.unary_expression.type != UNARY_STRING) {
1029 _BT_LOGE_NODE(unary_expr,
1030 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
1031 goto end;
1032 }
1033
1034 str = unary_expr->u.unary_expression.u.string;
1035
1036 if (!strcmp(str, "be") || !strcmp(str, "network")) {
1037 bo = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
1038 } else if (!strcmp(str, "le")) {
1039 bo = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
1040 } else if (!strcmp(str, "native")) {
1041 bo = BT_CTF_BYTE_ORDER_NATIVE;
1042 } else {
1043 _BT_LOGE_NODE(unary_expr,
1044 "Unexpected \"byte_order\" attribute value: "
1045 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
1046 str);
1047 goto end;
1048 }
1049
1050 end:
1051 return bo;
1052 }
1053
1054 static
1055 enum bt_ctf_byte_order get_real_byte_order(struct ctx *ctx,
1056 struct ctf_node *uexpr)
1057 {
1058 enum bt_ctf_byte_order bo = byte_order_from_unary_expr(uexpr);
1059
1060 if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
1061 bo = bt_ctf_trace_get_native_byte_order(ctx->trace);
1062 }
1063
1064 return bo;
1065 }
1066
1067 static
1068 int is_align_valid(uint64_t align)
1069 {
1070 return (align != 0) && !(align & (align - 1));
1071 }
1072
1073 static
1074 int get_type_specifier_name(struct ctx *ctx, struct ctf_node *type_specifier,
1075 GString *str)
1076 {
1077 int ret = 0;
1078
1079 if (type_specifier->type != NODE_TYPE_SPECIFIER) {
1080 _BT_LOGE_NODE(type_specifier,
1081 "Unexpected node type: node-type=%d",
1082 type_specifier->type);
1083 ret = -EINVAL;
1084 goto end;
1085 }
1086
1087 switch (type_specifier->u.type_specifier.type) {
1088 case TYPESPEC_VOID:
1089 g_string_append(str, "void");
1090 break;
1091 case TYPESPEC_CHAR:
1092 g_string_append(str, "char");
1093 break;
1094 case TYPESPEC_SHORT:
1095 g_string_append(str, "short");
1096 break;
1097 case TYPESPEC_INT:
1098 g_string_append(str, "int");
1099 break;
1100 case TYPESPEC_LONG:
1101 g_string_append(str, "long");
1102 break;
1103 case TYPESPEC_FLOAT:
1104 g_string_append(str, "float");
1105 break;
1106 case TYPESPEC_DOUBLE:
1107 g_string_append(str, "double");
1108 break;
1109 case TYPESPEC_SIGNED:
1110 g_string_append(str, "signed");
1111 break;
1112 case TYPESPEC_UNSIGNED:
1113 g_string_append(str, "unsigned");
1114 break;
1115 case TYPESPEC_BOOL:
1116 g_string_append(str, "bool");
1117 break;
1118 case TYPESPEC_COMPLEX:
1119 g_string_append(str, "_Complex");
1120 break;
1121 case TYPESPEC_IMAGINARY:
1122 g_string_append(str, "_Imaginary");
1123 break;
1124 case TYPESPEC_CONST:
1125 g_string_append(str, "const");
1126 break;
1127 case TYPESPEC_ID_TYPE:
1128 if (type_specifier->u.type_specifier.id_type) {
1129 g_string_append(str,
1130 type_specifier->u.type_specifier.id_type);
1131 }
1132 break;
1133 case TYPESPEC_STRUCT:
1134 {
1135 struct ctf_node *node = type_specifier->u.type_specifier.node;
1136
1137 if (!node->u._struct.name) {
1138 _BT_LOGE_NODE(node, "Unexpected empty structure field type name.");
1139 ret = -EINVAL;
1140 goto end;
1141 }
1142
1143 g_string_append(str, "struct ");
1144 g_string_append(str, node->u._struct.name);
1145 break;
1146 }
1147 case TYPESPEC_VARIANT:
1148 {
1149 struct ctf_node *node = type_specifier->u.type_specifier.node;
1150
1151 if (!node->u.variant.name) {
1152 _BT_LOGE_NODE(node, "Unexpected empty variant field type name.");
1153 ret = -EINVAL;
1154 goto end;
1155 }
1156
1157 g_string_append(str, "variant ");
1158 g_string_append(str, node->u.variant.name);
1159 break;
1160 }
1161 case TYPESPEC_ENUM:
1162 {
1163 struct ctf_node *node = type_specifier->u.type_specifier.node;
1164
1165 if (!node->u._enum.enum_id) {
1166 _BT_LOGE_NODE(node,
1167 "Unexpected empty enumeration field type (`enum`) name.");
1168 ret = -EINVAL;
1169 goto end;
1170 }
1171
1172 g_string_append(str, "enum ");
1173 g_string_append(str, node->u._enum.enum_id);
1174 break;
1175 }
1176 case TYPESPEC_FLOATING_POINT:
1177 case TYPESPEC_INTEGER:
1178 case TYPESPEC_STRING:
1179 default:
1180 _BT_LOGE_NODE(type_specifier->u.type_specifier.node,
1181 "Unexpected type specifier type: %d",
1182 type_specifier->u.type_specifier.type);
1183 ret = -EINVAL;
1184 goto end;
1185 }
1186
1187 end:
1188 return ret;
1189 }
1190
1191 static
1192 int get_type_specifier_list_name(struct ctx *ctx,
1193 struct ctf_node *type_specifier_list, GString *str)
1194 {
1195 int ret = 0;
1196 struct ctf_node *iter;
1197 int alias_item_nr = 0;
1198 struct bt_list_head *head =
1199 &type_specifier_list->u.type_specifier_list.head;
1200
1201 bt_list_for_each_entry(iter, head, siblings) {
1202 if (alias_item_nr != 0) {
1203 g_string_append(str, " ");
1204 }
1205
1206 alias_item_nr++;
1207 ret = get_type_specifier_name(ctx, iter, str);
1208 if (ret) {
1209 goto end;
1210 }
1211 }
1212
1213 end:
1214 return ret;
1215 }
1216
1217 static
1218 GQuark create_typealias_identifier(struct ctx *ctx,
1219 struct ctf_node *type_specifier_list,
1220 struct ctf_node *node_type_declarator)
1221 {
1222 int ret;
1223 char *str_c;
1224 GString *str;
1225 GQuark qalias = 0;
1226 struct ctf_node *iter;
1227 struct bt_list_head *pointers =
1228 &node_type_declarator->u.type_declarator.pointers;
1229
1230 str = g_string_new("");
1231 ret = get_type_specifier_list_name(ctx, type_specifier_list, str);
1232 if (ret) {
1233 g_string_free(str, TRUE);
1234 goto end;
1235 }
1236
1237 bt_list_for_each_entry(iter, pointers, siblings) {
1238 g_string_append(str, " *");
1239
1240 if (iter->u.pointer.const_qualifier) {
1241 g_string_append(str, " const");
1242 }
1243 }
1244
1245 str_c = g_string_free(str, FALSE);
1246 qalias = g_quark_from_string(str_c);
1247 g_free(str_c);
1248
1249 end:
1250 return qalias;
1251 }
1252
1253 static
1254 int visit_type_declarator(struct ctx *ctx, struct ctf_node *type_specifier_list,
1255 GQuark *field_name, struct ctf_node *node_type_declarator,
1256 struct bt_ctf_field_type **field_decl,
1257 struct bt_ctf_field_type *nested_decl)
1258 {
1259 /*
1260 * During this whole function, nested_decl is always OURS,
1261 * whereas field_decl is an output which we create, but
1262 * belongs to the caller (it is moved).
1263 */
1264
1265 int ret = 0;
1266 *field_decl = NULL;
1267
1268 /* Validate type declarator node */
1269 if (node_type_declarator) {
1270 if (node_type_declarator->u.type_declarator.type ==
1271 TYPEDEC_UNKNOWN) {
1272 _BT_LOGE_NODE(node_type_declarator,
1273 "Unexpected type declarator type: type=%d",
1274 node_type_declarator->u.type_declarator.type);
1275 ret = -EINVAL;
1276 goto error;
1277 }
1278
1279 /* TODO: GCC bitfields not supported yet */
1280 if (node_type_declarator->u.type_declarator.bitfield_len !=
1281 NULL) {
1282 _BT_LOGE_NODE(node_type_declarator,
1283 "GCC bitfields are not supported as of this version.");
1284 ret = -EPERM;
1285 goto error;
1286 }
1287 }
1288
1289 /* Find the right nested declaration if not provided */
1290 if (!nested_decl) {
1291 struct bt_list_head *pointers =
1292 &node_type_declarator->u.type_declarator.pointers;
1293
1294 if (node_type_declarator && !bt_list_empty(pointers)) {
1295 GQuark qalias;
1296 _BT_CTF_FIELD_TYPE_INIT(nested_decl_copy);
1297
1298 /*
1299 * If we have a pointer declarator, it HAS to
1300 * be present in the typealiases (else fail).
1301 */
1302 qalias = create_typealias_identifier(ctx,
1303 type_specifier_list, node_type_declarator);
1304 nested_decl =
1305 ctx_decl_scope_lookup_alias(ctx->current_scope,
1306 g_quark_to_string(qalias), -1);
1307 if (!nested_decl) {
1308 _BT_LOGE_NODE(node_type_declarator,
1309 "Cannot find type alias: name=\"%s\"",
1310 g_quark_to_string(qalias));
1311 ret = -EINVAL;
1312 goto error;
1313 }
1314
1315 /* Make a copy of it */
1316 nested_decl_copy = bt_ctf_field_type_copy(nested_decl);
1317 BT_PUT(nested_decl);
1318 if (!nested_decl_copy) {
1319 _BT_LOGE_NODE(node_type_declarator,
1320 "Cannot copy nested field type.");
1321 ret = -EINVAL;
1322 goto error;
1323 }
1324
1325 BT_MOVE(nested_decl, nested_decl_copy);
1326
1327 /* Force integer's base to 16 since it's a pointer */
1328 if (bt_ctf_field_type_is_integer(nested_decl)) {
1329 ret = bt_ctf_field_type_integer_set_base(
1330 nested_decl,
1331 BT_CTF_INTEGER_BASE_HEXADECIMAL);
1332 assert(ret == 0);
1333 }
1334 } else {
1335 ret = visit_type_specifier_list(ctx,
1336 type_specifier_list, &nested_decl);
1337 if (ret) {
1338 assert(!nested_decl);
1339 goto error;
1340 }
1341 }
1342 }
1343
1344 assert(nested_decl);
1345
1346 if (!node_type_declarator) {
1347 BT_MOVE(*field_decl, nested_decl);
1348 goto end;
1349 }
1350
1351 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
1352 if (node_type_declarator->u.type_declarator.u.id) {
1353 const char *id =
1354 node_type_declarator->u.type_declarator.u.id;
1355
1356 *field_name = g_quark_from_string(id);
1357 } else {
1358 *field_name = 0;
1359 }
1360
1361 BT_MOVE(*field_decl, nested_decl);
1362 goto end;
1363 } else {
1364 struct ctf_node *first;
1365 _BT_CTF_FIELD_TYPE_INIT(decl);
1366 _BT_CTF_FIELD_TYPE_INIT(outer_field_decl);
1367 struct bt_list_head *length =
1368 &node_type_declarator->
1369 u.type_declarator.u.nested.length;
1370
1371 /* Create array/sequence, pass nested_decl as child */
1372 if (bt_list_empty(length)) {
1373 _BT_LOGE_NODE(node_type_declarator,
1374 "Expecting length field reference or value.");
1375 ret = -EINVAL;
1376 goto error;
1377 }
1378
1379 first = _BT_LIST_FIRST_ENTRY(length, struct ctf_node, siblings);
1380 if (first->type != NODE_UNARY_EXPRESSION) {
1381 _BT_LOGE_NODE(first,
1382 "Unexpected node type: node-type=%d",
1383 first->type);
1384 ret = -EINVAL;
1385 goto error;
1386 }
1387
1388 switch (first->u.unary_expression.type) {
1389 case UNARY_UNSIGNED_CONSTANT:
1390 {
1391 size_t len;
1392 _BT_CTF_FIELD_TYPE_INIT(array_decl);
1393
1394 len = first->u.unary_expression.u.unsigned_constant;
1395 array_decl = bt_ctf_field_type_array_create(nested_decl,
1396 len);
1397 BT_PUT(nested_decl);
1398 if (!array_decl) {
1399 _BT_LOGE_NODE(first,
1400 "Cannot create array field type.");
1401 ret = -ENOMEM;
1402 goto error;
1403 }
1404
1405 BT_MOVE(decl, array_decl);
1406 break;
1407 }
1408 case UNARY_STRING:
1409 {
1410 /* Lookup unsigned integer definition, create seq. */
1411 _BT_CTF_FIELD_TYPE_INIT(seq_decl);
1412 char *length_name = concatenate_unary_strings(length);
1413
1414 if (!length_name) {
1415 _BT_LOGE_NODE(node_type_declarator,
1416 "Cannot concatenate unary strings.");
1417 ret = -EINVAL;
1418 goto error;
1419 }
1420
1421 seq_decl = bt_ctf_field_type_sequence_create(
1422 nested_decl, length_name);
1423 g_free(length_name);
1424 BT_PUT(nested_decl);
1425 if (!seq_decl) {
1426 _BT_LOGE_NODE(node_type_declarator,
1427 "Cannot create sequence field type.");
1428 ret = -ENOMEM;
1429 goto error;
1430 }
1431
1432 BT_MOVE(decl, seq_decl);
1433 break;
1434 }
1435 default:
1436 ret = -EINVAL;
1437 goto error;
1438 }
1439
1440 assert(!nested_decl);
1441 assert(decl);
1442 assert(!*field_decl);
1443
1444 /*
1445 * At this point, we found the next nested declaration.
1446 * We currently own this (and lost the ownership of
1447 * nested_decl in the meantime). Pass this next
1448 * nested declaration as the content of the outer
1449 * container, MOVING its ownership.
1450 */
1451 ret = visit_type_declarator(ctx, type_specifier_list,
1452 field_name,
1453 node_type_declarator->
1454 u.type_declarator.u.nested.type_declarator,
1455 &outer_field_decl, decl);
1456 decl = NULL;
1457 if (ret) {
1458 assert(!outer_field_decl);
1459 ret = -EINVAL;
1460 goto error;
1461 }
1462
1463 assert(outer_field_decl);
1464 BT_MOVE(*field_decl, outer_field_decl);
1465 }
1466
1467 end:
1468 BT_PUT(nested_decl);
1469 assert(*field_decl);
1470
1471 return 0;
1472
1473 error:
1474 BT_PUT(nested_decl);
1475 BT_PUT(*field_decl);
1476
1477 return ret;
1478 }
1479
1480 static
1481 int visit_struct_decl_field(struct ctx *ctx,
1482 struct bt_ctf_field_type *struct_decl,
1483 struct ctf_node *type_specifier_list,
1484 struct bt_list_head *type_declarators)
1485 {
1486 int ret = 0;
1487 struct ctf_node *iter;
1488 _BT_CTF_FIELD_TYPE_INIT(field_decl);
1489
1490 bt_list_for_each_entry(iter, type_declarators, siblings) {
1491 field_decl = NULL;
1492 GQuark qfield_name;
1493 const char *field_name;
1494 _BT_CTF_FIELD_TYPE_INIT(efield_decl);
1495
1496 ret = visit_type_declarator(ctx, type_specifier_list,
1497 &qfield_name, iter, &field_decl, NULL);
1498 if (ret) {
1499 assert(!field_decl);
1500 _BT_LOGE_NODE(type_specifier_list,
1501 "Cannot visit type declarator: ret=%d", ret);
1502 goto error;
1503 }
1504
1505 assert(field_decl);
1506 field_name = g_quark_to_string(qfield_name);
1507
1508 /* Check if field with same name already exists */
1509 efield_decl =
1510 bt_ctf_field_type_structure_get_field_type_by_name(
1511 struct_decl, field_name);
1512 if (efield_decl) {
1513 BT_PUT(efield_decl);
1514 _BT_LOGE_NODE(type_specifier_list,
1515 "Duplicate field in structure field type: "
1516 "field-name=\"%s\"", field_name);
1517 ret = -EINVAL;
1518 goto error;
1519 }
1520
1521 /* Add field to structure */
1522 ret = bt_ctf_field_type_structure_add_field(struct_decl,
1523 field_decl, field_name);
1524 BT_PUT(field_decl);
1525 if (ret) {
1526 _BT_LOGE_NODE(type_specifier_list,
1527 "Cannot add field to structure field type: "
1528 "field-name=\"%s\", ret=%d",
1529 g_quark_to_string(qfield_name), ret);
1530 goto error;
1531 }
1532 }
1533
1534 return 0;
1535
1536 error:
1537 BT_PUT(field_decl);
1538
1539 return ret;
1540 }
1541
1542 static
1543 int visit_variant_decl_field(struct ctx *ctx,
1544 struct bt_ctf_field_type *variant_decl,
1545 struct ctf_node *type_specifier_list,
1546 struct bt_list_head *type_declarators)
1547 {
1548 int ret = 0;
1549 struct ctf_node *iter;
1550 _BT_CTF_FIELD_TYPE_INIT(field_decl);
1551
1552 bt_list_for_each_entry(iter, type_declarators, siblings) {
1553 field_decl = NULL;
1554 GQuark qfield_name;
1555 const char *field_name;
1556 _BT_CTF_FIELD_TYPE_INIT(efield_decl);
1557
1558 ret = visit_type_declarator(ctx, type_specifier_list,
1559 &qfield_name, iter, &field_decl, NULL);
1560 if (ret) {
1561 assert(!field_decl);
1562 _BT_LOGE_NODE(type_specifier_list,
1563 "Cannot visit type declarator: ret=%d", ret);
1564 goto error;
1565 }
1566
1567 assert(field_decl);
1568 field_name = g_quark_to_string(qfield_name);
1569
1570 /* Check if field with same name already exists */
1571 efield_decl =
1572 bt_ctf_field_type_variant_get_field_type_by_name(
1573 variant_decl, field_name);
1574 if (efield_decl) {
1575 BT_PUT(efield_decl);
1576 _BT_LOGE_NODE(type_specifier_list,
1577 "Duplicate field in variant field type: "
1578 "field-name=\"%s\"", field_name);
1579 ret = -EINVAL;
1580 goto error;
1581 }
1582
1583 /* Add field to structure */
1584 ret = bt_ctf_field_type_variant_add_field(variant_decl,
1585 field_decl, field_name);
1586 BT_PUT(field_decl);
1587 if (ret) {
1588 _BT_LOGE_NODE(type_specifier_list,
1589 "Cannot add field to variant field type: "
1590 "field-name=\"%s\", ret=%d",
1591 g_quark_to_string(qfield_name), ret);
1592 goto error;
1593 }
1594 }
1595
1596 return 0;
1597
1598 error:
1599 BT_PUT(field_decl);
1600
1601 return ret;
1602 }
1603
1604 static
1605 int visit_typedef(struct ctx *ctx, struct ctf_node *type_specifier_list,
1606 struct bt_list_head *type_declarators)
1607 {
1608 int ret = 0;
1609 GQuark qidentifier;
1610 struct ctf_node *iter;
1611 _BT_CTF_FIELD_TYPE_INIT(type_decl);
1612
1613 bt_list_for_each_entry(iter, type_declarators, siblings) {
1614 ret = visit_type_declarator(ctx, type_specifier_list,
1615 &qidentifier, iter, &type_decl, NULL);
1616 if (ret) {
1617 _BT_LOGE_NODE(iter,
1618 "Cannot visit type declarator: ret=%d", ret);
1619 ret = -EINVAL;
1620 goto end;
1621 }
1622
1623 /* Do not allow typedef and typealias of untagged variants */
1624 if (bt_ctf_field_type_is_variant(type_decl)) {
1625 if (bt_ctf_field_type_variant_get_tag_name(type_decl)) {
1626 _BT_LOGE_NODE(iter,
1627 "Type definition of untagged variant field type is not allowed.");
1628 ret = -EPERM;
1629 goto end;
1630 }
1631 }
1632
1633 ret = ctx_decl_scope_register_alias(ctx->current_scope,
1634 g_quark_to_string(qidentifier), type_decl);
1635 if (ret) {
1636 _BT_LOGE_NODE(iter,
1637 "Cannot register type definition: name=\"%s\"",
1638 g_quark_to_string(qidentifier));
1639 goto end;
1640 }
1641 }
1642
1643 end:
1644 BT_PUT(type_decl);
1645
1646 return ret;
1647 }
1648
1649 static
1650 int visit_typealias(struct ctx *ctx, struct ctf_node *target,
1651 struct ctf_node *alias)
1652 {
1653 int ret = 0;
1654 GQuark qalias;
1655 struct ctf_node *node;
1656 GQuark qdummy_field_name;
1657 _BT_CTF_FIELD_TYPE_INIT(type_decl);
1658
1659 /* Create target type declaration */
1660 if (bt_list_empty(&target->u.typealias_target.type_declarators)) {
1661 node = NULL;
1662 } else {
1663 node = _BT_LIST_FIRST_ENTRY(
1664 &target->u.typealias_target.type_declarators,
1665 struct ctf_node, siblings);
1666 }
1667
1668 ret = visit_type_declarator(ctx,
1669 target->u.typealias_target.type_specifier_list,
1670 &qdummy_field_name, node, &type_decl, NULL);
1671 if (ret) {
1672 assert(!type_decl);
1673 _BT_LOGE_NODE(node,
1674 "Cannot visit type declarator: ret=%d", ret);
1675 goto end;
1676 }
1677
1678 /* Do not allow typedef and typealias of untagged variants */
1679 if (bt_ctf_field_type_is_variant(type_decl)) {
1680 if (bt_ctf_field_type_variant_get_tag_name(type_decl)) {
1681 _BT_LOGE_NODE(node,
1682 "Type definition of untagged variant field type is not allowed.");
1683 ret = -EPERM;
1684 goto end;
1685 }
1686 }
1687
1688 /*
1689 * The semantic validator does not check whether the target is
1690 * abstract or not (if it has an identifier). Check it here.
1691 */
1692 if (qdummy_field_name != 0) {
1693 _BT_LOGE_NODE(node,
1694 "Expecting empty identifier: id=\"%s\"",
1695 g_quark_to_string(qdummy_field_name));
1696 ret = -EINVAL;
1697 goto end;
1698 }
1699
1700 /* Create alias identifier */
1701 node = _BT_LIST_FIRST_ENTRY(&alias->u.typealias_alias.type_declarators,
1702 struct ctf_node, siblings);
1703 qalias = create_typealias_identifier(ctx,
1704 alias->u.typealias_alias.type_specifier_list, node);
1705 ret = ctx_decl_scope_register_alias(ctx->current_scope,
1706 g_quark_to_string(qalias), type_decl);
1707 if (ret) {
1708 _BT_LOGE_NODE(node,
1709 "Cannot register type alias: name=\"%s\"",
1710 g_quark_to_string(qalias));
1711 goto end;
1712 }
1713
1714 end:
1715 BT_PUT(type_decl);
1716
1717 return ret;
1718 }
1719
1720 static
1721 int visit_struct_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
1722 struct bt_ctf_field_type *struct_decl)
1723 {
1724 int ret = 0;
1725
1726 switch (entry_node->type) {
1727 case NODE_TYPEDEF:
1728 ret = visit_typedef(ctx,
1729 entry_node->u._typedef.type_specifier_list,
1730 &entry_node->u._typedef.type_declarators);
1731 if (ret) {
1732 _BT_LOGE_NODE(entry_node,
1733 "Cannot add type definition found in structure field type: ret=%d",
1734 ret);
1735 goto end;
1736 }
1737 break;
1738 case NODE_TYPEALIAS:
1739 ret = visit_typealias(ctx, entry_node->u.typealias.target,
1740 entry_node->u.typealias.alias);
1741 if (ret) {
1742 _BT_LOGE_NODE(entry_node,
1743 "Cannot add type alias found in structure field type: ret=%d",
1744 ret);
1745 goto end;
1746 }
1747 break;
1748 case NODE_STRUCT_OR_VARIANT_DECLARATION:
1749 /* Field */
1750 ret = visit_struct_decl_field(ctx, struct_decl,
1751 entry_node->u.struct_or_variant_declaration.
1752 type_specifier_list,
1753 &entry_node->u.struct_or_variant_declaration.
1754 type_declarators);
1755 if (ret) {
1756 goto end;
1757 }
1758 break;
1759 default:
1760 _BT_LOGE_NODE(entry_node,
1761 "Unexpected node type: node-type=%d", entry_node->type);
1762 ret = -EINVAL;
1763 goto end;
1764 }
1765
1766 end:
1767 return ret;
1768 }
1769
1770 static
1771 int visit_variant_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
1772 struct bt_ctf_field_type *variant_decl)
1773 {
1774 int ret = 0;
1775
1776 switch (entry_node->type) {
1777 case NODE_TYPEDEF:
1778 ret = visit_typedef(ctx,
1779 entry_node->u._typedef.type_specifier_list,
1780 &entry_node->u._typedef.type_declarators);
1781 if (ret) {
1782 _BT_LOGE_NODE(entry_node,
1783 "Cannot add type definition found in variant field type: ret=%d",
1784 ret);
1785 goto end;
1786 }
1787 break;
1788 case NODE_TYPEALIAS:
1789 ret = visit_typealias(ctx, entry_node->u.typealias.target,
1790 entry_node->u.typealias.alias);
1791 if (ret) {
1792 _BT_LOGE_NODE(entry_node,
1793 "Cannot add type alias found in variant field type: ret=%d",
1794 ret);
1795 goto end;
1796 }
1797 break;
1798 case NODE_STRUCT_OR_VARIANT_DECLARATION:
1799 /* Field */
1800 ret = visit_variant_decl_field(ctx, variant_decl,
1801 entry_node->u.struct_or_variant_declaration.
1802 type_specifier_list,
1803 &entry_node->u.struct_or_variant_declaration.
1804 type_declarators);
1805 if (ret) {
1806 goto end;
1807 }
1808 break;
1809 default:
1810 _BT_LOGE_NODE(entry_node,
1811 "Unexpected node type: node-type=%d",
1812 entry_node->type);
1813 ret = -EINVAL;
1814 goto end;
1815 }
1816
1817 end:
1818 return ret;
1819 }
1820
1821 static
1822 int visit_struct_decl(struct ctx *ctx, const char *name,
1823 struct bt_list_head *decl_list, int has_body,
1824 struct bt_list_head *min_align,
1825 struct bt_ctf_field_type **struct_decl)
1826 {
1827 int ret = 0;
1828
1829 *struct_decl = NULL;
1830
1831 /* For named struct (without body), lookup in declaration scope */
1832 if (!has_body) {
1833 _BT_CTF_FIELD_TYPE_INIT(struct_decl_copy);
1834
1835 if (!name) {
1836 BT_LOGE_STR("Bodyless structure field type: missing name.");
1837 ret = -EPERM;
1838 goto error;
1839 }
1840
1841 *struct_decl = ctx_decl_scope_lookup_struct(ctx->current_scope,
1842 name, -1);
1843 if (!*struct_decl) {
1844 BT_LOGE("Cannot find structure field type: name=\"struct %s\"",
1845 name);
1846 ret = -EINVAL;
1847 goto error;
1848 }
1849
1850 /* Make a copy of it */
1851 struct_decl_copy = bt_ctf_field_type_copy(*struct_decl);
1852 if (!struct_decl_copy) {
1853 BT_LOGE_STR("Cannot create copy of structure field type.");
1854 ret = -EINVAL;
1855 goto error;
1856 }
1857
1858 BT_MOVE(*struct_decl, struct_decl_copy);
1859 } else {
1860 struct ctf_node *entry_node;
1861 uint64_t min_align_value = 0;
1862
1863 if (name) {
1864 _BT_CTF_FIELD_TYPE_INIT(estruct_decl);
1865
1866 estruct_decl = ctx_decl_scope_lookup_struct(
1867 ctx->current_scope, name, 1);
1868 if (estruct_decl) {
1869 BT_PUT(estruct_decl);
1870 BT_LOGE("Structure field type already declared in local scope: "
1871 "name=\"struct %s\"", name);
1872 ret = -EINVAL;
1873 goto error;
1874 }
1875 }
1876
1877 if (!bt_list_empty(min_align)) {
1878 ret = get_unary_unsigned(min_align, &min_align_value);
1879 if (ret) {
1880 BT_LOGE("Unexpected unary expression for structure field type's `align` attribute: "
1881 "ret=%d", ret);
1882 goto error;
1883 }
1884 }
1885
1886 *struct_decl = bt_ctf_field_type_structure_create();
1887 if (!*struct_decl) {
1888 BT_LOGE_STR("Cannot create empty structure field type.");
1889 ret = -ENOMEM;
1890 goto error;
1891 }
1892
1893 if (min_align_value != 0) {
1894 ret = bt_ctf_field_type_set_alignment(*struct_decl,
1895 min_align_value);
1896 if (ret) {
1897 BT_LOGE("Cannot set structure field type's alignment: "
1898 "ret=%d", ret);
1899 goto error;
1900 }
1901 }
1902
1903 ret = ctx_push_scope(ctx);
1904 if (ret) {
1905 BT_LOGE_STR("Cannot push scope.");
1906 goto error;
1907 }
1908
1909 bt_list_for_each_entry(entry_node, decl_list, siblings) {
1910 ret = visit_struct_decl_entry(ctx, entry_node,
1911 *struct_decl);
1912 if (ret) {
1913 _BT_LOGE_NODE(entry_node,
1914 "Cannot visit structure field type entry: "
1915 "ret=%d", ret);
1916 ctx_pop_scope(ctx);
1917 goto error;
1918 }
1919 }
1920
1921 ctx_pop_scope(ctx);
1922
1923 if (name) {
1924 ret = ctx_decl_scope_register_struct(ctx->current_scope,
1925 name, *struct_decl);
1926 if (ret) {
1927 BT_LOGE("Cannot register structure field type in declaration scope: "
1928 "name=\"struct %s\", ret=%d", name, ret);
1929 goto error;
1930 }
1931 }
1932 }
1933
1934 return 0;
1935
1936 error:
1937 BT_PUT(*struct_decl);
1938
1939 return ret;
1940 }
1941
1942 static
1943 int visit_variant_decl(struct ctx *ctx, const char *name,
1944 const char *tag, struct bt_list_head *decl_list,
1945 int has_body, struct bt_ctf_field_type **variant_decl)
1946 {
1947 int ret = 0;
1948 _BT_CTF_FIELD_TYPE_INIT(untagged_variant_decl);
1949
1950 *variant_decl = NULL;
1951
1952 /* For named variant (without body), lookup in declaration scope */
1953 if (!has_body) {
1954 _BT_CTF_FIELD_TYPE_INIT(variant_decl_copy);
1955
1956 if (!name) {
1957 BT_LOGE_STR("Bodyless variant field type: missing name.");
1958 ret = -EPERM;
1959 goto error;
1960 }
1961
1962 untagged_variant_decl =
1963 ctx_decl_scope_lookup_variant(ctx->current_scope,
1964 name, -1);
1965 if (!untagged_variant_decl) {
1966 BT_LOGE("Cannot find variant field type: name=\"variant %s\"",
1967 name);
1968 ret = -EINVAL;
1969 goto error;
1970 }
1971
1972 /* Make a copy of it */
1973 variant_decl_copy = bt_ctf_field_type_copy(
1974 untagged_variant_decl);
1975 if (!variant_decl_copy) {
1976 BT_LOGE_STR("Cannot create copy of variant field type.");
1977 ret = -EINVAL;
1978 goto error;
1979 }
1980
1981 BT_MOVE(untagged_variant_decl, variant_decl_copy);
1982 } else {
1983 struct ctf_node *entry_node;
1984
1985 if (name) {
1986 struct bt_ctf_field_type *evariant_decl =
1987 ctx_decl_scope_lookup_struct(ctx->current_scope,
1988 name, 1);
1989
1990 if (evariant_decl) {
1991 BT_PUT(evariant_decl);
1992 BT_LOGE("Variant field type already declared in local scope: "
1993 "name=\"variant %s\"", name);
1994 ret = -EINVAL;
1995 goto error;
1996 }
1997 }
1998
1999 untagged_variant_decl = bt_ctf_field_type_variant_create(NULL,
2000 NULL);
2001 if (!untagged_variant_decl) {
2002 BT_LOGE_STR("Cannot create empty variant field type.");
2003 ret = -ENOMEM;
2004 goto error;
2005 }
2006
2007 ret = ctx_push_scope(ctx);
2008 if (ret) {
2009 BT_LOGE_STR("Cannot push scope.");
2010 goto error;
2011 }
2012
2013 bt_list_for_each_entry(entry_node, decl_list, siblings) {
2014 ret = visit_variant_decl_entry(ctx, entry_node,
2015 untagged_variant_decl);
2016 if (ret) {
2017 _BT_LOGE_NODE(entry_node,
2018 "Cannot visit variant field type entry: "
2019 "ret=%d", ret);
2020 ctx_pop_scope(ctx);
2021 goto error;
2022 }
2023 }
2024
2025 ctx_pop_scope(ctx);
2026
2027 if (name) {
2028 ret = ctx_decl_scope_register_variant(
2029 ctx->current_scope, name,
2030 untagged_variant_decl);
2031 if (ret) {
2032 BT_LOGE("Cannot register variant field type in declaration scope: "
2033 "name=\"variant %s\", ret=%d", name, ret);
2034 goto error;
2035 }
2036 }
2037 }
2038
2039 /*
2040 * If tagged, create tagged variant and return; otherwise
2041 * return untagged variant.
2042 */
2043 if (!tag) {
2044 BT_MOVE(*variant_decl, untagged_variant_decl);
2045 } else {
2046 /*
2047 * At this point, we have a fresh untagged variant; nobody
2048 * else owns it. Set its tag now.
2049 */
2050 ret = bt_ctf_field_type_variant_set_tag_name(
2051 untagged_variant_decl, tag);
2052 if (ret) {
2053 BT_LOGE("Cannot set variant field type's tag name: "
2054 "tag-name=\"%s\"", tag);
2055 goto error;
2056 }
2057
2058 BT_MOVE(*variant_decl, untagged_variant_decl);
2059 }
2060
2061 assert(!untagged_variant_decl);
2062 assert(*variant_decl);
2063
2064 return 0;
2065
2066 error:
2067 BT_PUT(untagged_variant_decl);
2068 BT_PUT(*variant_decl);
2069
2070 return ret;
2071 }
2072
2073 static
2074 int visit_enum_decl_entry(struct ctx *ctx, struct ctf_node *enumerator,
2075 struct bt_ctf_field_type *enum_decl, int64_t *last, int is_signed)
2076 {
2077 int ret = 0;
2078 int nr_vals = 0;
2079 struct ctf_node *iter;
2080 int64_t start = 0, end = 0;
2081 const char *label = enumerator->u.enumerator.id;
2082 struct bt_list_head *values = &enumerator->u.enumerator.values;
2083
2084 bt_list_for_each_entry(iter, values, siblings) {
2085 int64_t *target;
2086
2087 if (iter->type != NODE_UNARY_EXPRESSION) {
2088 _BT_LOGE_NODE(iter,
2089 "Wrong expression for enumeration field type label: "
2090 "node-type=%d, label=\"%s\"", iter->type,
2091 label);
2092 ret = -EINVAL;
2093 goto error;
2094 }
2095
2096 if (nr_vals == 0) {
2097 target = &start;
2098 } else {
2099 target = &end;
2100 }
2101
2102 switch (iter->u.unary_expression.type) {
2103 case UNARY_SIGNED_CONSTANT:
2104 *target = iter->u.unary_expression.u.signed_constant;
2105 break;
2106 case UNARY_UNSIGNED_CONSTANT:
2107 *target = (int64_t)
2108 iter->u.unary_expression.u.unsigned_constant;
2109 break;
2110 default:
2111 _BT_LOGE_NODE(iter,
2112 "Invalid enumeration field type entry: "
2113 "expecting constant signed or unsigned integer: "
2114 "node-type=%d, label=\"%s\"",
2115 iter->u.unary_expression.type, label);
2116 ret = -EINVAL;
2117 goto error;
2118 }
2119
2120 if (nr_vals > 1) {
2121 _BT_LOGE_NODE(iter,
2122 "Invalid enumeration field type entry: label=\"%s\"",
2123 label);
2124 ret = -EINVAL;
2125 goto error;
2126 }
2127
2128 nr_vals++;
2129 }
2130
2131 if (nr_vals == 0) {
2132 start = *last;
2133 }
2134
2135 if (nr_vals <= 1) {
2136 end = start;
2137 }
2138
2139 *last = end + 1;
2140
2141 if (is_signed) {
2142 ret = bt_ctf_field_type_enumeration_add_mapping(enum_decl, label,
2143 start, end);
2144 } else {
2145 ret = bt_ctf_field_type_enumeration_add_mapping_unsigned(enum_decl,
2146 label, (uint64_t) start, (uint64_t) end);
2147 }
2148 if (ret) {
2149 _BT_LOGE_NODE(enumerator,
2150 "Cannot add mapping to enumeration field type: "
2151 "label=\"%s\", ret=%d, "
2152 "start-value-unsigned=%" PRIu64 ", "
2153 "end-value-unsigned=%" PRIu64, label, ret,
2154 (uint64_t) start, (uint64_t) end);
2155 goto error;
2156 }
2157
2158 return 0;
2159
2160 error:
2161 return ret;
2162 }
2163
2164 static
2165 int visit_enum_decl(struct ctx *ctx, const char *name,
2166 struct ctf_node *container_type,
2167 struct bt_list_head *enumerator_list,
2168 int has_body,
2169 struct bt_ctf_field_type **enum_decl)
2170 {
2171 int ret = 0;
2172 GQuark qdummy_id;
2173 _BT_CTF_FIELD_TYPE_INIT(integer_decl);
2174
2175 *enum_decl = NULL;
2176
2177 /* For named enum (without body), lookup in declaration scope */
2178 if (!has_body) {
2179 _BT_CTF_FIELD_TYPE_INIT(enum_decl_copy);
2180
2181 if (!name) {
2182 BT_LOGE_STR("Bodyless enumeration field type: missing name.");
2183 ret = -EPERM;
2184 goto error;
2185 }
2186
2187 *enum_decl = ctx_decl_scope_lookup_enum(ctx->current_scope,
2188 name, -1);
2189 if (!*enum_decl) {
2190 BT_LOGE("Cannot find enumeration field type: "
2191 "name=\"enum %s\"", name);
2192 ret = -EINVAL;
2193 goto error;
2194 }
2195
2196 /* Make a copy of it */
2197 enum_decl_copy = bt_ctf_field_type_copy(*enum_decl);
2198 if (!enum_decl_copy) {
2199 BT_LOGE_STR("Cannot create copy of enumeration field type.");
2200 ret = -EINVAL;
2201 goto error;
2202 }
2203
2204 BT_PUT(*enum_decl);
2205 BT_MOVE(*enum_decl, enum_decl_copy);
2206 } else {
2207 struct ctf_node *iter;
2208 int64_t last_value = 0;
2209
2210 if (name) {
2211 _BT_CTF_FIELD_TYPE_INIT(eenum_decl);
2212
2213 eenum_decl = ctx_decl_scope_lookup_enum(
2214 ctx->current_scope, name, 1);
2215 if (eenum_decl) {
2216 BT_PUT(eenum_decl);
2217 BT_LOGE("Enumeration field type already declared in local scope: "
2218 "name=\"enum %s\"", name);
2219 ret = -EINVAL;
2220 goto error;
2221 }
2222 }
2223
2224 if (!container_type) {
2225 integer_decl = ctx_decl_scope_lookup_alias(
2226 ctx->current_scope, "int", -1);
2227 if (!integer_decl) {
2228 BT_LOGE_STR("Cannot find implicit `int` field type alias for enumeration field type.");
2229 ret = -EINVAL;
2230 goto error;
2231 }
2232 } else {
2233 ret = visit_type_declarator(ctx, container_type,
2234 &qdummy_id, NULL, &integer_decl, NULL);
2235 if (ret) {
2236 assert(!integer_decl);
2237 ret = -EINVAL;
2238 goto error;
2239 }
2240 }
2241
2242 assert(integer_decl);
2243
2244 if (!bt_ctf_field_type_is_integer(integer_decl)) {
2245 BT_LOGE("Container field type for enumeration field type is not an integer field type: "
2246 "ft-id=%s",
2247 bt_ctf_field_type_id_string(
2248 bt_ctf_field_type_get_type_id(integer_decl)));
2249 ret = -EINVAL;
2250 goto error;
2251 }
2252
2253 *enum_decl = bt_ctf_field_type_enumeration_create(integer_decl);
2254 if (!*enum_decl) {
2255 BT_LOGE_STR("Cannot create enumeration field type.");
2256 ret = -ENOMEM;
2257 goto error;
2258 }
2259
2260 bt_list_for_each_entry(iter, enumerator_list, siblings) {
2261 ret = visit_enum_decl_entry(ctx, iter, *enum_decl,
2262 &last_value,
2263 bt_ctf_field_type_integer_get_signed(integer_decl));
2264 if (ret) {
2265 _BT_LOGE_NODE(iter,
2266 "Cannot visit enumeration field type entry: "
2267 "ret=%d", ret);
2268 goto error;
2269 }
2270 }
2271
2272 if (name) {
2273 ret = ctx_decl_scope_register_enum(ctx->current_scope,
2274 name, *enum_decl);
2275 if (ret) {
2276 BT_LOGE("Cannot register enumeration field type in declaration scope: "
2277 "ret=%d", ret);
2278 goto error;
2279 }
2280 }
2281 }
2282
2283 BT_PUT(integer_decl);
2284
2285 return 0;
2286
2287 error:
2288 BT_PUT(integer_decl);
2289 BT_PUT(*enum_decl);
2290
2291 return ret;
2292 }
2293
2294 static
2295 int visit_type_specifier(struct ctx *ctx,
2296 struct ctf_node *type_specifier_list,
2297 struct bt_ctf_field_type **decl)
2298 {
2299 int ret = 0;
2300 GString *str = NULL;
2301 _BT_CTF_FIELD_TYPE_INIT(decl_copy);
2302
2303 *decl = NULL;
2304 str = g_string_new("");
2305 ret = get_type_specifier_list_name(ctx, type_specifier_list, str);
2306 if (ret) {
2307 _BT_LOGE_NODE(type_specifier_list,
2308 "Cannot get type specifier list's name: ret=%d", ret);
2309 goto error;
2310 }
2311
2312 *decl = ctx_decl_scope_lookup_alias(ctx->current_scope, str->str, -1);
2313 if (!*decl) {
2314 _BT_LOGE_NODE(type_specifier_list,
2315 "Cannot find type alias: name=\"%s\"", str->str);
2316 ret = -EINVAL;
2317 goto error;
2318 }
2319
2320 /* Make a copy of the type declaration */
2321 decl_copy = bt_ctf_field_type_copy(*decl);
2322 if (!decl_copy) {
2323 _BT_LOGE_NODE(type_specifier_list,
2324 "Cannot create field type copy.");
2325 ret = -EINVAL;
2326 goto error;
2327 }
2328
2329 BT_MOVE(*decl, decl_copy);
2330 (void) g_string_free(str, TRUE);
2331 str = NULL;
2332
2333 return 0;
2334
2335 error:
2336 if (str) {
2337 (void) g_string_free(str, TRUE);
2338 }
2339
2340 BT_PUT(*decl);
2341
2342 return ret;
2343 }
2344
2345 static
2346 int visit_integer_decl(struct ctx *ctx,
2347 struct bt_list_head *expressions,
2348 struct bt_ctf_field_type **integer_decl)
2349 {
2350 int set = 0;
2351 int ret = 0;
2352 int signedness = 0;
2353 struct ctf_node *expression;
2354 uint64_t alignment = 0, size = 0;
2355 struct bt_ctf_clock_class *mapped_clock = NULL;
2356 enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_NONE;
2357 enum bt_ctf_integer_base base = BT_CTF_INTEGER_BASE_DECIMAL;
2358 enum bt_ctf_byte_order byte_order =
2359 bt_ctf_trace_get_native_byte_order(ctx->trace);
2360
2361 *integer_decl = NULL;
2362
2363 bt_list_for_each_entry(expression, expressions, siblings) {
2364 struct ctf_node *left, *right;
2365
2366 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2367 struct ctf_node, siblings);
2368 right = _BT_LIST_FIRST_ENTRY(
2369 &expression->u.ctf_expression.right, struct ctf_node,
2370 siblings);
2371
2372 if (left->u.unary_expression.type != UNARY_STRING) {
2373 _BT_LOGE_NODE(left,
2374 "Unexpected unary expression type: type=%d",
2375 left->u.unary_expression.type);
2376 ret = -EINVAL;
2377 goto error;
2378 }
2379
2380 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
2381 if (_IS_SET(&set, _INTEGER_SIGNED_SET)) {
2382 _BT_LOGE_DUP_ATTR(left, "signed",
2383 "integer field type");
2384 ret = -EPERM;
2385 goto error;
2386 }
2387
2388 signedness = get_boolean(right);
2389 if (signedness < 0) {
2390 _BT_LOGE_NODE(right,
2391 "Invalid boolean value for integer field type's `signed` attribute: "
2392 "ret=%d", ret);
2393 ret = -EINVAL;
2394 goto error;
2395 }
2396
2397 _SET(&set, _INTEGER_SIGNED_SET);
2398 } else if (!strcmp(left->u.unary_expression.u.string,
2399 "byte_order")) {
2400 if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) {
2401 _BT_LOGE_DUP_ATTR(left, "byte_order",
2402 "integer field type");
2403 ret = -EPERM;
2404 goto error;
2405 }
2406
2407 byte_order = get_real_byte_order(ctx, right);
2408 if (byte_order == BT_CTF_BYTE_ORDER_UNKNOWN) {
2409 _BT_LOGE_NODE(right,
2410 "Invalid `byte_order` attribute in integer field type: "
2411 "ret=%d", ret);
2412 ret = -EINVAL;
2413 goto error;
2414 }
2415
2416 _SET(&set, _INTEGER_BYTE_ORDER_SET);
2417 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
2418 if (_IS_SET(&set, _INTEGER_SIZE_SET)) {
2419 _BT_LOGE_DUP_ATTR(left, "size",
2420 "integer field type");
2421 ret = -EPERM;
2422 goto error;
2423 }
2424
2425 if (right->u.unary_expression.type !=
2426 UNARY_UNSIGNED_CONSTANT) {
2427 _BT_LOGE_NODE(right,
2428 "Invalid `size` attribute in integer field type: "
2429 "expecting unsigned constant integer: "
2430 "node-type=%d",
2431 right->u.unary_expression.type);
2432 ret = -EINVAL;
2433 goto error;
2434 }
2435
2436 size = right->u.unary_expression.u.unsigned_constant;
2437 if (size == 0) {
2438 _BT_LOGE_NODE(right,
2439 "Invalid `size` attribute in integer field type: "
2440 "expecting positive constant integer: "
2441 "size=%" PRIu64, size);
2442 ret = -EINVAL;
2443 goto error;
2444 } else if (size > 64) {
2445 _BT_LOGE_NODE(right,
2446 "Invalid `size` attribute in integer field type: "
2447 "integer fields over 64 bits are not supported as of this version: "
2448 "size=%" PRIu64, size);
2449 ret = -EINVAL;
2450 goto error;
2451 }
2452
2453 _SET(&set, _INTEGER_SIZE_SET);
2454 } else if (!strcmp(left->u.unary_expression.u.string,
2455 "align")) {
2456 if (_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2457 _BT_LOGE_DUP_ATTR(left, "align",
2458 "integer field type");
2459 ret = -EPERM;
2460 goto error;
2461 }
2462
2463 if (right->u.unary_expression.type !=
2464 UNARY_UNSIGNED_CONSTANT) {
2465 _BT_LOGE_NODE(right,
2466 "Invalid `align` attribute in integer field type: "
2467 "expecting unsigned constant integer: "
2468 "node-type=%d",
2469 right->u.unary_expression.type);
2470 ret = -EINVAL;
2471 goto error;
2472 }
2473
2474 alignment =
2475 right->u.unary_expression.u.unsigned_constant;
2476 if (!is_align_valid(alignment)) {
2477 _BT_LOGE_NODE(right,
2478 "Invalid `align` attribute in integer field type: "
2479 "expecting power of two: "
2480 "align=%" PRIu64, alignment);
2481 ret = -EINVAL;
2482 goto error;
2483 }
2484
2485 _SET(&set, _INTEGER_ALIGN_SET);
2486 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
2487 if (_IS_SET(&set, _INTEGER_BASE_SET)) {
2488 _BT_LOGE_DUP_ATTR(left, "base",
2489 "integer field type");
2490 ret = -EPERM;
2491 goto error;
2492 }
2493
2494 switch (right->u.unary_expression.type) {
2495 case UNARY_UNSIGNED_CONSTANT:
2496 {
2497 uint64_t constant = right->u.unary_expression.
2498 u.unsigned_constant;
2499
2500 switch (constant) {
2501 case 2:
2502 base = BT_CTF_INTEGER_BASE_BINARY;
2503 break;
2504 case 8:
2505 base = BT_CTF_INTEGER_BASE_OCTAL;
2506 break;
2507 case 10:
2508 base = BT_CTF_INTEGER_BASE_DECIMAL;
2509 break;
2510 case 16:
2511 base = BT_CTF_INTEGER_BASE_HEXADECIMAL;
2512 break;
2513 default:
2514 _BT_LOGE_NODE(right,
2515 "Invalid `base` attribute in integer field type: "
2516 "base=%" PRIu64,
2517 right->u.unary_expression.u.unsigned_constant);
2518 ret = -EINVAL;
2519 goto error;
2520 }
2521 break;
2522 }
2523 case UNARY_STRING:
2524 {
2525 char *s_right = concatenate_unary_strings(
2526 &expression->u.ctf_expression.right);
2527 if (!s_right) {
2528 _BT_LOGE_NODE(right,
2529 "Unexpected unary expression for integer field type's `base` attribute.");
2530 ret = -EINVAL;
2531 goto error;
2532 }
2533
2534 if (!strcmp(s_right, "decimal") ||
2535 !strcmp(s_right, "dec") ||
2536 !strcmp(s_right, "d") ||
2537 !strcmp(s_right, "i") ||
2538 !strcmp(s_right, "u")) {
2539 base = BT_CTF_INTEGER_BASE_DECIMAL;
2540 } else if (!strcmp(s_right, "hexadecimal") ||
2541 !strcmp(s_right, "hex") ||
2542 !strcmp(s_right, "x") ||
2543 !strcmp(s_right, "X") ||
2544 !strcmp(s_right, "p")) {
2545 base = BT_CTF_INTEGER_BASE_HEXADECIMAL;
2546 } else if (!strcmp(s_right, "octal") ||
2547 !strcmp(s_right, "oct") ||
2548 !strcmp(s_right, "o")) {
2549 base = BT_CTF_INTEGER_BASE_OCTAL;
2550 } else if (!strcmp(s_right, "binary") ||
2551 !strcmp(s_right, "b")) {
2552 base = BT_CTF_INTEGER_BASE_BINARY;
2553 } else {
2554 _BT_LOGE_NODE(right,
2555 "Unexpected unary expression for integer field type's `base` attribute: "
2556 "base=\"%s\"", s_right);
2557 g_free(s_right);
2558 ret = -EINVAL;
2559 goto error;
2560 }
2561
2562 g_free(s_right);
2563 break;
2564 }
2565 default:
2566 _BT_LOGE_NODE(right,
2567 "Invalid `base` attribute in integer field type: "
2568 "expecting unsigned constant integer or unary string.");
2569 ret = -EINVAL;
2570 goto error;
2571 }
2572
2573 _SET(&set, _INTEGER_BASE_SET);
2574 } else if (!strcmp(left->u.unary_expression.u.string,
2575 "encoding")) {
2576 char *s_right;
2577
2578 if (_IS_SET(&set, _INTEGER_ENCODING_SET)) {
2579 _BT_LOGE_DUP_ATTR(left, "encoding",
2580 "integer field type");
2581 ret = -EPERM;
2582 goto error;
2583 }
2584
2585 if (right->u.unary_expression.type != UNARY_STRING) {
2586 _BT_LOGE_NODE(right,
2587 "Invalid `encoding` attribute in integer field type: "
2588 "expecting unary string.");
2589 ret = -EINVAL;
2590 goto error;
2591 }
2592
2593 s_right = concatenate_unary_strings(
2594 &expression->u.ctf_expression.right);
2595 if (!s_right) {
2596 _BT_LOGE_NODE(right,
2597 "Unexpected unary expression for integer field type's `encoding` attribute.");
2598 ret = -EINVAL;
2599 goto error;
2600 }
2601
2602 if (!strcmp(s_right, "UTF8") ||
2603 !strcmp(s_right, "utf8") ||
2604 !strcmp(s_right, "utf-8") ||
2605 !strcmp(s_right, "UTF-8")) {
2606 encoding = BT_CTF_STRING_ENCODING_UTF8;
2607 } else if (!strcmp(s_right, "ASCII") ||
2608 !strcmp(s_right, "ascii")) {
2609 encoding = BT_CTF_STRING_ENCODING_ASCII;
2610 } else if (!strcmp(s_right, "none")) {
2611 encoding = BT_CTF_STRING_ENCODING_NONE;
2612 } else {
2613 _BT_LOGE_NODE(right,
2614 "Invalid `encoding` attribute in integer field type: "
2615 "unknown encoding: encoding=\"%s\"",
2616 s_right);
2617 g_free(s_right);
2618 ret = -EINVAL;
2619 goto error;
2620 }
2621
2622 g_free(s_right);
2623 _SET(&set, _INTEGER_ENCODING_SET);
2624 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
2625 const char *clock_name;
2626
2627 if (_IS_SET(&set, _INTEGER_MAP_SET)) {
2628 _BT_LOGE_DUP_ATTR(left, "map",
2629 "integer field type");
2630 ret = -EPERM;
2631 goto error;
2632 }
2633
2634 if (right->u.unary_expression.type != UNARY_STRING) {
2635 _BT_LOGE_NODE(right,
2636 "Invalid `map` attribute in integer field type: "
2637 "expecting unary string.");
2638 ret = -EINVAL;
2639 goto error;
2640 }
2641
2642 clock_name =
2643 get_map_clock_name_value(
2644 &expression->u.ctf_expression.right);
2645 if (!clock_name) {
2646 char *s_right = concatenate_unary_strings(
2647 &expression->u.ctf_expression.right);
2648
2649 if (!s_right) {
2650 _BT_LOGE_NODE(right,
2651 "Unexpected unary expression for integer field type's `map` attribute.");
2652 ret = -EINVAL;
2653 goto error;
2654 }
2655
2656 _BT_LOGE_NODE(right,
2657 "Invalid `map` attribute in integer field type: "
2658 "cannot find clock class at this point: name=\"%s\"",
2659 s_right);
2660 _SET(&set, _INTEGER_MAP_SET);
2661 g_free(s_right);
2662 continue;
2663 }
2664
2665 mapped_clock = bt_ctf_trace_get_clock_class_by_name(
2666 ctx->trace, clock_name);
2667 if (!mapped_clock) {
2668 _BT_LOGE_NODE(right,
2669 "Invalid `map` attribute in integer field type: "
2670 "cannot find clock class at this point: name=\"%s\"",
2671 clock_name);
2672 ret = -EINVAL;
2673 goto error;
2674 }
2675
2676 _SET(&set, _INTEGER_MAP_SET);
2677 } else {
2678 _BT_LOGW_NODE(left,
2679 "Unknown attribute in integer field type: "
2680 "attr-name=\"%s\"",
2681 left->u.unary_expression.u.string);
2682 }
2683 }
2684
2685 if (!_IS_SET(&set, _INTEGER_SIZE_SET)) {
2686 BT_LOGE_STR("Missing `size` attribute in integer field type.");
2687 ret = -EPERM;
2688 goto error;
2689 }
2690
2691 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2692 if (size % CHAR_BIT) {
2693 /* Bit-packed alignment */
2694 alignment = 1;
2695 } else {
2696 /* Byte-packed alignment */
2697 alignment = CHAR_BIT;
2698 }
2699 }
2700
2701 *integer_decl = bt_ctf_field_type_integer_create((unsigned int) size);
2702 if (!*integer_decl) {
2703 BT_LOGE_STR("Cannot create integer field type.");
2704 ret = -ENOMEM;
2705 goto error;
2706 }
2707
2708 ret = bt_ctf_field_type_integer_set_signed(*integer_decl, signedness);
2709 ret |= bt_ctf_field_type_integer_set_base(*integer_decl, base);
2710 ret |= bt_ctf_field_type_integer_set_encoding(*integer_decl, encoding);
2711 ret |= bt_ctf_field_type_set_alignment(*integer_decl,
2712 (unsigned int) alignment);
2713 ret |= bt_ctf_field_type_set_byte_order(*integer_decl, byte_order);
2714
2715 if (mapped_clock) {
2716 /* Move clock */
2717 ret |= bt_ctf_field_type_integer_set_mapped_clock_class(
2718 *integer_decl, mapped_clock);
2719 bt_put(mapped_clock);
2720 mapped_clock = NULL;
2721 }
2722
2723 if (ret) {
2724 BT_LOGE_STR("Cannot configure integer field type.");
2725 ret = -EINVAL;
2726 goto error;
2727 }
2728
2729 return 0;
2730
2731 error:
2732 if (mapped_clock) {
2733 bt_put(mapped_clock);
2734 }
2735
2736 BT_PUT(*integer_decl);
2737
2738 return ret;
2739 }
2740
2741 static
2742 int visit_floating_point_number_decl(struct ctx *ctx,
2743 struct bt_list_head *expressions,
2744 struct bt_ctf_field_type **float_decl)
2745 {
2746 int set = 0;
2747 int ret = 0;
2748 struct ctf_node *expression;
2749 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
2750 enum bt_ctf_byte_order byte_order =
2751 bt_ctf_trace_get_native_byte_order(ctx->trace);
2752
2753 *float_decl = NULL;
2754
2755 bt_list_for_each_entry(expression, expressions, siblings) {
2756 struct ctf_node *left, *right;
2757
2758 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2759 struct ctf_node, siblings);
2760 right = _BT_LIST_FIRST_ENTRY(
2761 &expression->u.ctf_expression.right, struct ctf_node,
2762 siblings);
2763
2764 if (left->u.unary_expression.type != UNARY_STRING) {
2765 _BT_LOGE_NODE(left,
2766 "Unexpected unary expression type: type=%d",
2767 left->u.unary_expression.type);
2768 ret = -EINVAL;
2769 goto error;
2770 }
2771
2772 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
2773 if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) {
2774 _BT_LOGE_DUP_ATTR(left, "byte_order",
2775 "floating point number field type");
2776 ret = -EPERM;
2777 goto error;
2778 }
2779
2780 byte_order = get_real_byte_order(ctx, right);
2781 if (byte_order == BT_CTF_BYTE_ORDER_UNKNOWN) {
2782 _BT_LOGE_NODE(right,
2783 "Invalid `byte_order` attribute in floating point number field type: "
2784 "ret=%d", ret);
2785 ret = -EINVAL;
2786 goto error;
2787 }
2788
2789 _SET(&set, _FLOAT_BYTE_ORDER_SET);
2790 } else if (!strcmp(left->u.unary_expression.u.string,
2791 "exp_dig")) {
2792 if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
2793 _BT_LOGE_DUP_ATTR(left, "exp_dig",
2794 "floating point number field type");
2795 ret = -EPERM;
2796 goto error;
2797 }
2798
2799 if (right->u.unary_expression.type !=
2800 UNARY_UNSIGNED_CONSTANT) {
2801 _BT_LOGE_NODE(right,
2802 "Invalid `exp_dig` attribute in floating point number field type: "
2803 "expecting unsigned constant integer: "
2804 "node-type=%d",
2805 right->u.unary_expression.type);
2806 ret = -EINVAL;
2807 goto error;
2808 }
2809
2810 exp_dig = right->u.unary_expression.u.unsigned_constant;
2811 _SET(&set, _FLOAT_EXP_DIG_SET);
2812 } else if (!strcmp(left->u.unary_expression.u.string,
2813 "mant_dig")) {
2814 if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
2815 _BT_LOGE_DUP_ATTR(left, "mant_dig",
2816 "floating point number field type");
2817 ret = -EPERM;
2818 goto error;
2819 }
2820
2821 if (right->u.unary_expression.type !=
2822 UNARY_UNSIGNED_CONSTANT) {
2823 _BT_LOGE_NODE(right,
2824 "Invalid `mant_dig` attribute in floating point number field type: "
2825 "expecting unsigned constant integer: "
2826 "node-type=%d",
2827 right->u.unary_expression.type);
2828 ret = -EINVAL;
2829 goto error;
2830 }
2831
2832 mant_dig = right->u.unary_expression.u.
2833 unsigned_constant;
2834 _SET(&set, _FLOAT_MANT_DIG_SET);
2835 } else if (!strcmp(left->u.unary_expression.u.string,
2836 "align")) {
2837 if (_IS_SET(&set, _FLOAT_ALIGN_SET)) {
2838 _BT_LOGE_DUP_ATTR(left, "align",
2839 "floating point number field type");
2840 ret = -EPERM;
2841 goto error;
2842 }
2843
2844 if (right->u.unary_expression.type !=
2845 UNARY_UNSIGNED_CONSTANT) {
2846 _BT_LOGE_NODE(right,
2847 "Invalid `align` attribute in floating point number field type: "
2848 "expecting unsigned constant integer: "
2849 "node-type=%d",
2850 right->u.unary_expression.type);
2851 ret = -EINVAL;
2852 goto error;
2853 }
2854
2855 alignment = right->u.unary_expression.u.
2856 unsigned_constant;
2857
2858 if (!is_align_valid(alignment)) {
2859 _BT_LOGE_NODE(right,
2860 "Invalid `align` attribute in floating point number field type: "
2861 "expecting power of two: "
2862 "align=%" PRIu64, alignment);
2863 ret = -EINVAL;
2864 goto error;
2865 }
2866
2867 _SET(&set, _FLOAT_ALIGN_SET);
2868 } else {
2869 _BT_LOGW_NODE(left,
2870 "Unknown attribute in floating point number field type: "
2871 "attr-name=\"%s\"",
2872 left->u.unary_expression.u.string);
2873 }
2874 }
2875
2876 if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
2877 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field type.");
2878 ret = -EPERM;
2879 goto error;
2880 }
2881
2882 if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
2883 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field type.");
2884 ret = -EPERM;
2885 goto error;
2886 }
2887
2888 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2889 if ((mant_dig + exp_dig) % CHAR_BIT) {
2890 /* Bit-packed alignment */
2891 alignment = 1;
2892 } else {
2893 /* Byte-packed alignment */
2894 alignment = CHAR_BIT;
2895 }
2896 }
2897
2898 *float_decl = bt_ctf_field_type_floating_point_create();
2899 if (!*float_decl) {
2900 BT_LOGE_STR("Cannot create floating point number field type.");
2901 ret = -ENOMEM;
2902 goto error;
2903 }
2904
2905 ret = bt_ctf_field_type_floating_point_set_exponent_digits(
2906 *float_decl, exp_dig);
2907 ret |= bt_ctf_field_type_floating_point_set_mantissa_digits(
2908 *float_decl, mant_dig);
2909 ret |= bt_ctf_field_type_set_byte_order(*float_decl, byte_order);
2910 ret |= bt_ctf_field_type_set_alignment(*float_decl, alignment);
2911 if (ret) {
2912 BT_LOGE_STR("Cannot configure floating point number field type.");
2913 ret = -EINVAL;
2914 goto error;
2915 }
2916
2917 return 0;
2918
2919 error:
2920 BT_PUT(*float_decl);
2921
2922 return ret;
2923 }
2924
2925 static
2926 int visit_string_decl(struct ctx *ctx,
2927 struct bt_list_head *expressions,
2928 struct bt_ctf_field_type **string_decl)
2929 {
2930 int set = 0;
2931 int ret = 0;
2932 struct ctf_node *expression;
2933 enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_UTF8;
2934
2935 *string_decl = NULL;
2936
2937 bt_list_for_each_entry(expression, expressions, siblings) {
2938 struct ctf_node *left, *right;
2939
2940 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2941 struct ctf_node, siblings);
2942 right = _BT_LIST_FIRST_ENTRY(
2943 &expression->u.ctf_expression.right, struct ctf_node,
2944 siblings);
2945
2946 if (left->u.unary_expression.type != UNARY_STRING) {
2947 _BT_LOGE_NODE(left,
2948 "Unexpected unary expression type: type=%d",
2949 left->u.unary_expression.type);
2950 ret = -EINVAL;
2951 goto error;
2952 }
2953
2954 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
2955 char *s_right;
2956
2957 if (_IS_SET(&set, _STRING_ENCODING_SET)) {
2958 _BT_LOGE_DUP_ATTR(left, "encoding",
2959 "string field type");
2960 ret = -EPERM;
2961 goto error;
2962 }
2963
2964 if (right->u.unary_expression.type != UNARY_STRING) {
2965 _BT_LOGE_NODE(right,
2966 "Invalid `encoding` attribute in string field type: "
2967 "expecting unary string.");
2968 ret = -EINVAL;
2969 goto error;
2970 }
2971
2972 s_right = concatenate_unary_strings(
2973 &expression->u.ctf_expression.right);
2974 if (!s_right) {
2975 _BT_LOGE_NODE(right,
2976 "Unexpected unary expression for string field type's `encoding` attribute.");
2977 ret = -EINVAL;
2978 goto error;
2979 }
2980
2981 if (!strcmp(s_right, "UTF8") ||
2982 !strcmp(s_right, "utf8") ||
2983 !strcmp(s_right, "utf-8") ||
2984 !strcmp(s_right, "UTF-8")) {
2985 encoding = BT_CTF_STRING_ENCODING_UTF8;
2986 } else if (!strcmp(s_right, "ASCII") ||
2987 !strcmp(s_right, "ascii")) {
2988 encoding = BT_CTF_STRING_ENCODING_ASCII;
2989 } else if (!strcmp(s_right, "none")) {
2990 encoding = BT_CTF_STRING_ENCODING_NONE;
2991 } else {
2992 _BT_LOGE_NODE(right,
2993 "Invalid `encoding` attribute in string field type: "
2994 "unknown encoding: encoding=\"%s\"",
2995 s_right);
2996 g_free(s_right);
2997 ret = -EINVAL;
2998 goto error;
2999 }
3000
3001 g_free(s_right);
3002 _SET(&set, _STRING_ENCODING_SET);
3003 } else {
3004 _BT_LOGW_NODE(left,
3005 "Unknown attribute in string field type: "
3006 "attr-name=\"%s\"",
3007 left->u.unary_expression.u.string);
3008 }
3009 }
3010
3011 *string_decl = bt_ctf_field_type_string_create();
3012 if (!*string_decl) {
3013 BT_LOGE_STR("Cannot create string field type.");
3014 ret = -ENOMEM;
3015 goto error;
3016 }
3017
3018 ret = bt_ctf_field_type_string_set_encoding(*string_decl, encoding);
3019 if (ret) {
3020 BT_LOGE_STR("Cannot configure string field type.");
3021 ret = -EINVAL;
3022 goto error;
3023 }
3024
3025 return 0;
3026
3027 error:
3028 BT_PUT(*string_decl);
3029
3030 return ret;
3031 }
3032
3033 static
3034 int visit_type_specifier_list(struct ctx *ctx,
3035 struct ctf_node *ts_list,
3036 struct bt_ctf_field_type **decl)
3037 {
3038 int ret = 0;
3039 struct ctf_node *first, *node;
3040
3041 *decl = NULL;
3042
3043 if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) {
3044 _BT_LOGE_NODE(ts_list,
3045 "Unexpected node type: node-type=%d", ts_list->type);
3046 ret = -EINVAL;
3047 goto error;
3048 }
3049
3050 first = _BT_LIST_FIRST_ENTRY(&ts_list->u.type_specifier_list.head,
3051 struct ctf_node, siblings);
3052 if (first->type != NODE_TYPE_SPECIFIER) {
3053 _BT_LOGE_NODE(first,
3054 "Unexpected node type: node-type=%d", first->type);
3055 ret = -EINVAL;
3056 goto error;
3057 }
3058
3059 node = first->u.type_specifier.node;
3060
3061 switch (first->u.type_specifier.type) {
3062 case TYPESPEC_INTEGER:
3063 ret = visit_integer_decl(ctx, &node->u.integer.expressions,
3064 decl);
3065 if (ret) {
3066 assert(!*decl);
3067 goto error;
3068 }
3069 break;
3070 case TYPESPEC_FLOATING_POINT:
3071 ret = visit_floating_point_number_decl(ctx,
3072 &node->u.floating_point.expressions, decl);
3073 if (ret) {
3074 assert(!*decl);
3075 goto error;
3076 }
3077 break;
3078 case TYPESPEC_STRING:
3079 ret = visit_string_decl(ctx,
3080 &node->u.string.expressions, decl);
3081 if (ret) {
3082 assert(!*decl);
3083 goto error;
3084 }
3085 break;
3086 case TYPESPEC_STRUCT:
3087 ret = visit_struct_decl(ctx, node->u._struct.name,
3088 &node->u._struct.declaration_list,
3089 node->u._struct.has_body,
3090 &node->u._struct.min_align, decl);
3091 if (ret) {
3092 assert(!*decl);
3093 goto error;
3094 }
3095 break;
3096 case TYPESPEC_VARIANT:
3097 ret = visit_variant_decl(ctx, node->u.variant.name,
3098 node->u.variant.choice,
3099 &node->u.variant.declaration_list,
3100 node->u.variant.has_body, decl);
3101 if (ret) {
3102 assert(!*decl);
3103 goto error;
3104 }
3105 break;
3106 case TYPESPEC_ENUM:
3107 ret = visit_enum_decl(ctx, node->u._enum.enum_id,
3108 node->u._enum.container_type,
3109 &node->u._enum.enumerator_list,
3110 node->u._enum.has_body, decl);
3111 if (ret) {
3112 assert(!*decl);
3113 goto error;
3114 }
3115 break;
3116 case TYPESPEC_VOID:
3117 case TYPESPEC_CHAR:
3118 case TYPESPEC_SHORT:
3119 case TYPESPEC_INT:
3120 case TYPESPEC_LONG:
3121 case TYPESPEC_FLOAT:
3122 case TYPESPEC_DOUBLE:
3123 case TYPESPEC_SIGNED:
3124 case TYPESPEC_UNSIGNED:
3125 case TYPESPEC_BOOL:
3126 case TYPESPEC_COMPLEX:
3127 case TYPESPEC_IMAGINARY:
3128 case TYPESPEC_CONST:
3129 case TYPESPEC_ID_TYPE:
3130 ret = visit_type_specifier(ctx, ts_list, decl);
3131 if (ret) {
3132 _BT_LOGE_NODE(first,
3133 "Cannot visit type specifier: ret=%d",
3134 ret);
3135 assert(!*decl);
3136 goto error;
3137 }
3138 break;
3139 default:
3140 _BT_LOGE_NODE(first,
3141 "Unexpected type specifier type: node-type=%d",
3142 first->u.type_specifier.type);
3143 ret = -EINVAL;
3144 goto error;
3145 }
3146
3147 assert(*decl);
3148
3149 return 0;
3150
3151 error:
3152 BT_PUT(*decl);
3153
3154 return ret;
3155 }
3156
3157 static
3158 int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
3159 struct bt_ctf_event_class *event_class, int64_t *stream_id,
3160 int *set)
3161 {
3162 int ret = 0;
3163 char *left = NULL;
3164 _BT_CTF_FIELD_TYPE_INIT(decl);
3165
3166 switch (node->type) {
3167 case NODE_TYPEDEF:
3168 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
3169 &node->u._typedef.type_declarators);
3170 if (ret) {
3171 _BT_LOGE_NODE(node,
3172 "Cannot add type definition found in event class.");
3173 goto error;
3174 }
3175 break;
3176 case NODE_TYPEALIAS:
3177 ret = visit_typealias(ctx, node->u.typealias.target,
3178 node->u.typealias.alias);
3179 if (ret) {
3180 _BT_LOGE_NODE(node,
3181 "Cannot add type alias found in event class.");
3182 goto error;
3183 }
3184 break;
3185 case NODE_CTF_EXPRESSION:
3186 {
3187 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3188 if (!left) {
3189 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
3190 ret = -EINVAL;
3191 goto error;
3192 }
3193
3194 if (!strcmp(left, "name")) {
3195 /* This is already known at this stage */
3196 if (_IS_SET(set, _EVENT_NAME_SET)) {
3197 _BT_LOGE_DUP_ATTR(node, "name",
3198 "event class");
3199 ret = -EPERM;
3200 goto error;
3201 }
3202
3203 _SET(set, _EVENT_NAME_SET);
3204 } else if (!strcmp(left, "id")) {
3205 int64_t id;
3206
3207 if (_IS_SET(set, _EVENT_ID_SET)) {
3208 _BT_LOGE_DUP_ATTR(node, "id",
3209 "event class");
3210 ret = -EPERM;
3211 goto error;
3212 }
3213
3214 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3215 (uint64_t *) &id);
3216 /* Only read "id" if get_unary_unsigned() succeeded. */
3217 if (ret || (!ret && id < 0)) {
3218 _BT_LOGE_NODE(node,
3219 "Unexpected unary expression for event class's `id` attribute.");
3220 ret = -EINVAL;
3221 goto error;
3222 }
3223
3224 ret = bt_ctf_event_class_set_id(event_class, id);
3225 if (ret) {
3226 _BT_LOGE_NODE(node,
3227 "Cannot set event class's ID: "
3228 "id=%" PRId64, id);
3229 goto error;
3230 }
3231
3232 _SET(set, _EVENT_ID_SET);
3233 } else if (!strcmp(left, "stream_id")) {
3234 if (_IS_SET(set, _EVENT_STREAM_ID_SET)) {
3235 _BT_LOGE_DUP_ATTR(node, "stream_id",
3236 "event class");
3237 ret = -EPERM;
3238 goto error;
3239 }
3240
3241 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3242 (uint64_t *) stream_id);
3243 /*
3244 * Only read "stream_id" if get_unary_unsigned()
3245 * succeeded.
3246 */
3247 if (ret || (!ret && *stream_id < 0)) {
3248 _BT_LOGE_NODE(node,
3249 "Unexpected unary expression for event class's `stream_id` attribute.");
3250 ret = -EINVAL;
3251 goto error;
3252 }
3253
3254 _SET(set, _EVENT_STREAM_ID_SET);
3255 } else if (!strcmp(left, "context")) {
3256 if (_IS_SET(set, _EVENT_CONTEXT_SET)) {
3257 _BT_LOGE_NODE(node,
3258 "Duplicate `context` entry in event class.");
3259 ret = -EPERM;
3260 goto error;
3261 }
3262
3263 ret = visit_type_specifier_list(ctx,
3264 _BT_LIST_FIRST_ENTRY(
3265 &node->u.ctf_expression.right,
3266 struct ctf_node, siblings),
3267 &decl);
3268 if (ret) {
3269 _BT_LOGE_NODE(node,
3270 "Cannot create event class's context field type.");
3271 goto error;
3272 }
3273
3274 assert(decl);
3275 ret = bt_ctf_event_class_set_context_type(
3276 event_class, decl);
3277 BT_PUT(decl);
3278 if (ret) {
3279 _BT_LOGE_NODE(node,
3280 "Cannot set event class's context field type.");
3281 goto error;
3282 }
3283
3284 _SET(set, _EVENT_CONTEXT_SET);
3285 } else if (!strcmp(left, "fields")) {
3286 if (_IS_SET(set, _EVENT_FIELDS_SET)) {
3287 _BT_LOGE_NODE(node,
3288 "Duplicate `fields` entry in event class.");
3289 ret = -EPERM;
3290 goto error;
3291 }
3292
3293 ret = visit_type_specifier_list(ctx,
3294 _BT_LIST_FIRST_ENTRY(
3295 &node->u.ctf_expression.right,
3296 struct ctf_node, siblings),
3297 &decl);
3298 if (ret) {
3299 _BT_LOGE_NODE(node,
3300 "Cannot create event class's payload field type.");
3301 goto error;
3302 }
3303
3304 assert(decl);
3305 ret = bt_ctf_event_class_set_payload_type(
3306 event_class, decl);
3307 BT_PUT(decl);
3308 if (ret) {
3309 _BT_LOGE_NODE(node,
3310 "Cannot set event class's payload field type.");
3311 goto error;
3312 }
3313
3314 _SET(set, _EVENT_FIELDS_SET);
3315 } else if (!strcmp(left, "loglevel")) {
3316 uint64_t loglevel_value;
3317 const char *loglevel_str;
3318 struct bt_value *value_obj, *str_obj;
3319
3320 if (_IS_SET(set, _EVENT_LOGLEVEL_SET)) {
3321 _BT_LOGE_DUP_ATTR(node, "loglevel",
3322 "event class");
3323 ret = -EPERM;
3324 goto error;
3325 }
3326
3327 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3328 &loglevel_value);
3329 if (ret) {
3330 _BT_LOGE_NODE(node,
3331 "Unexpected unary expression for event class's `loglevel` attribute.");
3332 ret = -EINVAL;
3333 goto error;
3334 }
3335 value_obj = bt_value_integer_create_init(loglevel_value);
3336 if (!value_obj) {
3337 _BT_LOGE_NODE(node,
3338 "Cannot create integer value object.");
3339 ret = -ENOMEM;
3340 goto error;
3341 }
3342 if (bt_ctf_event_class_set_attribute(event_class,
3343 "loglevel", value_obj) != BT_VALUE_STATUS_OK) {
3344 _BT_LOGE_NODE(node,
3345 "Cannot set event class's `loglevel` attribute.");
3346 ret = -EINVAL;
3347 bt_put(value_obj);
3348 goto error;
3349 }
3350 loglevel_str = print_loglevel(loglevel_value);
3351 if (loglevel_str) {
3352 str_obj = bt_value_string_create_init(loglevel_str);
3353 if (bt_ctf_event_class_set_attribute(event_class,
3354 "loglevel_string", str_obj) != BT_VALUE_STATUS_OK) {
3355 _BT_LOGE_NODE(node,
3356 "Cannot set event class's `loglevel_string` attribute.");
3357 ret = -EINVAL;
3358 bt_put(str_obj);
3359 goto error;
3360 }
3361 bt_put(str_obj);
3362 }
3363 bt_put(value_obj);
3364 _SET(set, _EVENT_LOGLEVEL_SET);
3365 } else if (!strcmp(left, "model.emf.uri")) {
3366 char *right;
3367 struct bt_value *str_obj;
3368
3369 if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) {
3370 _BT_LOGE_DUP_ATTR(node, "model.emf.uri",
3371 "event class");
3372 ret = -EPERM;
3373 goto error;
3374 }
3375
3376 right = concatenate_unary_strings(
3377 &node->u.ctf_expression.right);
3378 if (!right) {
3379 _BT_LOGE_NODE(node,
3380 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3381 ret = -EINVAL;
3382 goto error;
3383 }
3384
3385 str_obj = bt_value_string_create_init(right);
3386 if (bt_ctf_event_class_set_attribute(event_class,
3387 "model.emf.uri", str_obj) != BT_VALUE_STATUS_OK) {
3388 _BT_LOGE_NODE(node,
3389 "Cannot set event class's `model.emf.uri` attribute.");
3390 ret = -EINVAL;
3391 bt_put(str_obj);
3392 goto error;
3393 }
3394 bt_put(str_obj);
3395 g_free(right);
3396 _SET(set, _EVENT_MODEL_EMF_URI_SET);
3397 } else {
3398 _BT_LOGW_NODE(node,
3399 "Unknown attribute in event class: "
3400 "attr-name=\"%s\"", left);
3401 }
3402
3403 g_free(left);
3404 left = NULL;
3405 break;
3406 }
3407 default:
3408 ret = -EPERM;
3409 goto error;
3410 }
3411
3412 return 0;
3413
3414 error:
3415 if (left) {
3416 g_free(left);
3417 }
3418
3419 BT_PUT(decl);
3420
3421 return ret;
3422 }
3423
3424 static
3425 char *get_event_decl_name(struct ctx *ctx, struct ctf_node *node)
3426 {
3427 char *left = NULL;
3428 char *name = NULL;
3429 struct ctf_node *iter;
3430 struct bt_list_head *decl_list = &node->u.event.declaration_list;
3431
3432 bt_list_for_each_entry(iter, decl_list, siblings) {
3433 if (iter->type != NODE_CTF_EXPRESSION) {
3434 continue;
3435 }
3436
3437 left = concatenate_unary_strings(&iter->u.ctf_expression.left);
3438 if (!left) {
3439 _BT_LOGE_NODE(iter,
3440 "Cannot concatenate unary strings.");
3441 goto error;
3442 }
3443
3444 if (!strcmp(left, "name")) {
3445 name = concatenate_unary_strings(
3446 &iter->u.ctf_expression.right);
3447 if (!name) {
3448 _BT_LOGE_NODE(iter,
3449 "Unexpected unary expression for event class's `name` attribute.");
3450 goto error;
3451 }
3452 }
3453
3454 g_free(left);
3455 left = NULL;
3456
3457 if (name) {
3458 break;
3459 }
3460 }
3461
3462 return name;
3463
3464 error:
3465 g_free(left);
3466
3467 return NULL;
3468 }
3469
3470 static
3471 int reset_event_decl_types(struct ctx *ctx,
3472 struct bt_ctf_event_class *event_class)
3473 {
3474 int ret = 0;
3475
3476 /* Context type. */
3477 ret = bt_ctf_event_class_set_context_type(event_class, NULL);
3478 if (ret) {
3479 BT_LOGE("Cannot reset initial event class's context field type: "
3480 "event-name=\"%s\"",
3481 bt_ctf_event_class_get_name(event_class));
3482 goto end;
3483 }
3484
3485 /* Event payload. */
3486 ret = bt_ctf_event_class_set_payload_type(event_class, NULL);
3487 if (ret) {
3488 BT_LOGE("Cannot reset initial event class's payload field type: "
3489 "event-name=\"%s\"",
3490 bt_ctf_event_class_get_name(event_class));
3491 goto end;
3492 }
3493 end:
3494 return ret;
3495 }
3496
3497 static
3498 int reset_stream_decl_types(struct ctx *ctx,
3499 struct bt_ctf_stream_class *stream_class)
3500 {
3501 int ret = 0;
3502
3503 /* Packet context. */
3504 ret = bt_ctf_stream_class_set_packet_context_type(stream_class, NULL);
3505 if (ret) {
3506 BT_LOGE_STR("Cannot reset initial stream class's packet context field type.");
3507 goto end;
3508 }
3509
3510 /* Event header. */
3511 ret = bt_ctf_stream_class_set_event_header_type(stream_class, NULL);
3512 if (ret) {
3513 BT_LOGE_STR("Cannot reset initial stream class's event header field type.");
3514 goto end;
3515 }
3516
3517 /* Event context. */
3518 ret = bt_ctf_stream_class_set_event_context_type(stream_class, NULL);
3519 if (ret) {
3520 BT_LOGE_STR("Cannot reset initial stream class's event context field type.");
3521 goto end;
3522 }
3523 end:
3524 return ret;
3525 }
3526
3527 static
3528 struct bt_ctf_stream_class *create_reset_stream_class(struct ctx *ctx)
3529 {
3530 int ret;
3531 struct bt_ctf_stream_class *stream_class;
3532
3533 stream_class = bt_ctf_stream_class_create_empty(NULL);
3534 if (!stream_class) {
3535 BT_LOGE_STR("Cannot create empty stream class.");
3536 goto error;
3537 }
3538
3539 /*
3540 * Set packet context, event header, and event context to NULL to
3541 * override the default ones.
3542 */
3543 ret = reset_stream_decl_types(ctx, stream_class);
3544 if (ret) {
3545 goto error;
3546 }
3547
3548 return stream_class;
3549
3550 error:
3551 BT_PUT(stream_class);
3552
3553 return NULL;
3554 }
3555
3556 static
3557 int visit_event_decl(struct ctx *ctx, struct ctf_node *node)
3558 {
3559 int ret = 0;
3560 int set = 0;
3561 int64_t event_id;
3562 struct ctf_node *iter;
3563 int64_t stream_id = -1;
3564 char *event_name = NULL;
3565 struct bt_ctf_event_class *event_class = NULL;
3566 struct bt_ctf_event_class *eevent_class;
3567 struct bt_ctf_stream_class *stream_class = NULL;
3568 struct bt_list_head *decl_list = &node->u.event.declaration_list;
3569 bool pop_scope = false;
3570
3571 if (node->visited) {
3572 goto end;
3573 }
3574
3575 node->visited = TRUE;
3576 event_name = get_event_decl_name(ctx, node);
3577 if (!event_name) {
3578 _BT_LOGE_NODE(node,
3579 "Missing `name` attribute in event class.");
3580 ret = -EPERM;
3581 goto error;
3582 }
3583
3584 event_class = bt_ctf_event_class_create(event_name);
3585
3586 /*
3587 * Unset context and fields to override the default ones.
3588 */
3589 ret = reset_event_decl_types(ctx, event_class);
3590 if (ret) {
3591 _BT_LOGE_NODE(node,
3592 "Cannot reset event class's field types: "
3593 "ret=%d", ret);
3594 goto error;
3595 }
3596
3597 ret = ctx_push_scope(ctx);
3598 if (ret) {
3599 BT_LOGE_STR("Cannot push scope.");
3600 goto error;
3601 }
3602
3603 pop_scope = true;
3604
3605 bt_list_for_each_entry(iter, decl_list, siblings) {
3606 ret = visit_event_decl_entry(ctx, iter, event_class,
3607 &stream_id, &set);
3608 if (ret) {
3609 _BT_LOGE_NODE(iter, "Cannot visit event class's entry: "
3610 "ret=%d", ret);
3611 goto error;
3612 }
3613 }
3614
3615 if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
3616 GList *keys = NULL;
3617 struct bt_ctf_stream_class *new_stream_class;
3618 size_t stream_class_count =
3619 g_hash_table_size(ctx->stream_classes) +
3620 bt_ctf_trace_get_stream_class_count(ctx->trace);
3621
3622 /*
3623 * Allow missing stream_id if there is only a single
3624 * stream class.
3625 */
3626 switch (stream_class_count) {
3627 case 0:
3628 /* Create implicit stream class if there's none */
3629 new_stream_class = create_reset_stream_class(ctx);
3630 if (!new_stream_class) {
3631 _BT_LOGE_NODE(node,
3632 "Cannot create empty stream class.");
3633 ret = -EINVAL;
3634 goto error;
3635 }
3636
3637 ret = bt_ctf_stream_class_set_id(new_stream_class, 0);
3638 if (ret) {
3639 _BT_LOGE_NODE(node,
3640 "Cannot set stream class's ID: "
3641 "id=0, ret=%d", ret);
3642 BT_PUT(new_stream_class);
3643 goto error;
3644 }
3645
3646 stream_id = 0;
3647
3648 /* Move reference to visitor's context */
3649 g_hash_table_insert(ctx->stream_classes,
3650 (gpointer) stream_id, new_stream_class);
3651 new_stream_class = NULL;
3652 break;
3653 case 1:
3654 /* Single stream class: get its ID */
3655 if (g_hash_table_size(ctx->stream_classes) == 1) {
3656 keys = g_hash_table_get_keys(ctx->stream_classes);
3657 stream_id = (int64_t) keys->data;
3658 g_list_free(keys);
3659 } else {
3660 assert(bt_ctf_trace_get_stream_class_count(
3661 ctx->trace) == 1);
3662 stream_class =
3663 bt_ctf_trace_get_stream_class_by_index(
3664 ctx->trace, 0);
3665 assert(stream_class);
3666 stream_id = bt_ctf_stream_class_get_id(
3667 stream_class);
3668 BT_PUT(stream_class);
3669 }
3670 break;
3671 default:
3672 _BT_LOGE_NODE(node,
3673 "Missing `stream_id` attribute in event class.");
3674 ret = -EPERM;
3675 goto error;
3676 }
3677 }
3678
3679 assert(stream_id >= 0);
3680
3681 /* We have the stream ID now; get the stream class if found */
3682 stream_class = g_hash_table_lookup(ctx->stream_classes,
3683 (gpointer) stream_id);
3684 bt_get(stream_class);
3685 if (!stream_class) {
3686 stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
3687 stream_id);
3688 if (!stream_class) {
3689 _BT_LOGE_NODE(node,
3690 "Cannot find stream class at this point: "
3691 "id=%" PRId64, stream_id);
3692 ret = -EINVAL;
3693 goto error;
3694 }
3695 }
3696
3697 assert(stream_class);
3698
3699 if (!_IS_SET(&set, _EVENT_ID_SET)) {
3700 /* Allow only one event without ID per stream */
3701 if (bt_ctf_stream_class_get_event_class_count(stream_class) !=
3702 0) {
3703 _BT_LOGE_NODE(node,
3704 "Missing `id` attribute in event class.");
3705 ret = -EPERM;
3706 goto error;
3707 }
3708
3709 /* Automatic ID */
3710 ret = bt_ctf_event_class_set_id(event_class, 0);
3711 if (ret) {
3712 _BT_LOGE_NODE(node,
3713 "Cannot set event class's ID: id=0, ret=%d",
3714 ret);
3715 goto error;
3716 }
3717 }
3718
3719 event_id = bt_ctf_event_class_get_id(event_class);
3720 if (event_id < 0) {
3721 _BT_LOGE_NODE(node, "Cannot get event class's ID.");
3722 ret = -EINVAL;
3723 goto error;
3724 }
3725
3726 eevent_class = bt_ctf_stream_class_get_event_class_by_id(stream_class,
3727 event_id);
3728 if (eevent_class) {
3729 BT_PUT(eevent_class);
3730 _BT_LOGE_NODE(node,
3731 "Duplicate event class (same ID) in the same stream class: "
3732 "id=%" PRId64, event_id);
3733 ret = -EEXIST;
3734 goto error;
3735 }
3736
3737 ret = bt_ctf_stream_class_add_event_class(stream_class, event_class);
3738 BT_PUT(event_class);
3739 if (ret) {
3740 _BT_LOGE_NODE(node,
3741 "Cannot add event class to stream class: ret=%d", ret);
3742 goto error;
3743 }
3744
3745 goto end;
3746
3747 error:
3748 bt_put(event_class);
3749
3750 end:
3751 if (pop_scope) {
3752 ctx_pop_scope(ctx);
3753 }
3754
3755 g_free(event_name);
3756 bt_put(stream_class);
3757 return ret;
3758 }
3759
3760 static
3761 int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
3762 struct bt_ctf_stream_class *stream_class, int *set)
3763 {
3764 int ret = 0;
3765 char *left = NULL;
3766 _BT_CTF_FIELD_TYPE_INIT(decl);
3767
3768 switch (node->type) {
3769 case NODE_TYPEDEF:
3770 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
3771 &node->u._typedef.type_declarators);
3772 if (ret) {
3773 _BT_LOGE_NODE(node,
3774 "Cannot add type definition found in stream class.");
3775 goto error;
3776 }
3777 break;
3778 case NODE_TYPEALIAS:
3779 ret = visit_typealias(ctx, node->u.typealias.target,
3780 node->u.typealias.alias);
3781 if (ret) {
3782 _BT_LOGE_NODE(node,
3783 "Cannot add type alias found in stream class.");
3784 goto error;
3785 }
3786 break;
3787 case NODE_CTF_EXPRESSION:
3788 {
3789 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3790 if (!left) {
3791 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
3792 ret = -EINVAL;
3793 goto error;
3794 }
3795
3796 if (!strcmp(left, "id")) {
3797 int64_t id;
3798 gpointer ptr;
3799
3800 if (_IS_SET(set, _STREAM_ID_SET)) {
3801 _BT_LOGE_DUP_ATTR(node, "id",
3802 "stream declaration");
3803 ret = -EPERM;
3804 goto error;
3805 }
3806
3807 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3808 (uint64_t *) &id);
3809 /* Only read "id" if get_unary_unsigned() succeeded. */
3810 if (ret || (!ret && id < 0)) {
3811 _BT_LOGE_NODE(node,
3812 "Unexpected unary expression for stream class's `id` attribute.");
3813 ret = -EINVAL;
3814 goto error;
3815 }
3816
3817 ptr = g_hash_table_lookup(ctx->stream_classes,
3818 (gpointer) id);
3819 if (ptr) {
3820 _BT_LOGE_NODE(node,
3821 "Duplicate stream class (same ID): id=%" PRId64,
3822 id);
3823 ret = -EEXIST;
3824 goto error;
3825 }
3826
3827 ret = bt_ctf_stream_class_set_id(stream_class, id);
3828 if (ret) {
3829 _BT_LOGE_NODE(node,
3830 "Cannot set stream class's ID: "
3831 "id=%" PRId64 ", ret=%d", id, ret);
3832 goto error;
3833 }
3834
3835 _SET(set, _STREAM_ID_SET);
3836 } else if (!strcmp(left, "event.header")) {
3837 if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
3838 _BT_LOGE_NODE(node,
3839 "Duplicate `event.header` entry in stream class.");
3840 ret = -EPERM;
3841 goto error;
3842 }
3843
3844 ret = visit_type_specifier_list(ctx,
3845 _BT_LIST_FIRST_ENTRY(
3846 &node->u.ctf_expression.right,
3847 struct ctf_node, siblings),
3848 &decl);
3849 if (ret) {
3850 _BT_LOGE_NODE(node,
3851 "Cannot create stream class's event header field type.");
3852 goto error;
3853 }
3854
3855 assert(decl);
3856
3857 ret = bt_ctf_stream_class_set_event_header_type(
3858 stream_class, decl);
3859 BT_PUT(decl);
3860 if (ret) {
3861 _BT_LOGE_NODE(node,
3862 "Cannot set stream class's event header field type.");
3863 goto error;
3864 }
3865
3866 _SET(set, _STREAM_EVENT_HEADER_SET);
3867 } else if (!strcmp(left, "event.context")) {
3868 if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
3869 _BT_LOGE_NODE(node,
3870 "Duplicate `event.context` entry in stream class.");
3871 ret = -EPERM;
3872 goto error;
3873 }
3874
3875 ret = visit_type_specifier_list(ctx,
3876 _BT_LIST_FIRST_ENTRY(
3877 &node->u.ctf_expression.right,
3878 struct ctf_node, siblings),
3879 &decl);
3880 if (ret) {
3881 _BT_LOGE_NODE(node,
3882 "Cannot create stream class's event context field type.");
3883 goto error;
3884 }
3885
3886 assert(decl);
3887
3888 ret = bt_ctf_stream_class_set_event_context_type(
3889 stream_class, decl);
3890 BT_PUT(decl);
3891 if (ret) {
3892 _BT_LOGE_NODE(node,
3893 "Cannot set stream class's event context field type.");
3894 goto error;
3895 }
3896
3897 _SET(set, _STREAM_EVENT_CONTEXT_SET);
3898 } else if (!strcmp(left, "packet.context")) {
3899 if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
3900 _BT_LOGE_NODE(node,
3901 "Duplicate `packet.context` entry in stream class.");
3902 ret = -EPERM;
3903 goto error;
3904 }
3905
3906 ret = visit_type_specifier_list(ctx,
3907 _BT_LIST_FIRST_ENTRY(
3908 &node->u.ctf_expression.right,
3909 struct ctf_node, siblings),
3910 &decl);
3911 if (ret) {
3912 _BT_LOGE_NODE(node,
3913 "Cannot create stream class's packet context field type.");
3914 goto error;
3915 }
3916
3917 assert(decl);
3918
3919 ret = bt_ctf_stream_class_set_packet_context_type(
3920 stream_class, decl);
3921 BT_PUT(decl);
3922 if (ret) {
3923 _BT_LOGE_NODE(node,
3924 "Cannot set stream class's packet context field type.");
3925 goto error;
3926 }
3927
3928 _SET(set, _STREAM_PACKET_CONTEXT_SET);
3929 } else {
3930 _BT_LOGW_NODE(node,
3931 "Unknown attribute in stream class: "
3932 "attr-name=\"%s\"", left);
3933 }
3934
3935 g_free(left);
3936 left = NULL;
3937 break;
3938 }
3939
3940 default:
3941 ret = -EPERM;
3942 goto error;
3943 }
3944
3945 return 0;
3946
3947 error:
3948 g_free(left);
3949 BT_PUT(decl);
3950
3951 return ret;
3952 }
3953
3954 static
3955 int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
3956 {
3957 int64_t id;
3958 int set = 0;
3959 int ret = 0;
3960 struct ctf_node *iter;
3961 struct bt_ctf_stream_class *stream_class = NULL;
3962 struct bt_ctf_stream_class *existing_stream_class = NULL;
3963 struct bt_list_head *decl_list = &node->u.stream.declaration_list;
3964
3965 if (node->visited) {
3966 goto end;
3967 }
3968
3969 node->visited = TRUE;
3970 stream_class = create_reset_stream_class(ctx);
3971 if (!stream_class) {
3972 _BT_LOGE_NODE(node, "Cannot create empty stream class.");
3973 ret = -EINVAL;
3974 goto error;
3975 }
3976
3977 ret = ctx_push_scope(ctx);
3978 if (ret) {
3979 BT_LOGE_STR("Cannot push scope.");
3980 goto error;
3981 }
3982
3983 bt_list_for_each_entry(iter, decl_list, siblings) {
3984 ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
3985 if (ret) {
3986 _BT_LOGE_NODE(iter,
3987 "Cannot visit stream class's entry: "
3988 "ret=%d", ret);
3989 ctx_pop_scope(ctx);
3990 goto error;
3991 }
3992 }
3993
3994 ctx_pop_scope(ctx);
3995
3996 if (_IS_SET(&set, _STREAM_ID_SET)) {
3997 /* Check that packet header has stream_id field */
3998 _BT_CTF_FIELD_TYPE_INIT(stream_id_decl);
3999 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
4000
4001 packet_header_decl =
4002 bt_ctf_trace_get_packet_header_type(ctx->trace);
4003 if (!packet_header_decl) {
4004 _BT_LOGE_NODE(node,
4005 "Stream class has a `id` attribute, "
4006 "but trace has no packet header field type.");
4007 goto error;
4008 }
4009
4010 stream_id_decl =
4011 bt_ctf_field_type_structure_get_field_type_by_name(
4012 packet_header_decl, "stream_id");
4013 BT_PUT(packet_header_decl);
4014 if (!stream_id_decl) {
4015 _BT_LOGE_NODE(node,
4016 "Stream class has a `id` attribute, "
4017 "but trace's packet header field type has no `stream_id` field.");
4018 goto error;
4019 }
4020
4021 if (!bt_ctf_field_type_is_integer(stream_id_decl)) {
4022 BT_PUT(stream_id_decl);
4023 _BT_LOGE_NODE(node,
4024 "Stream class has a `id` attribute, "
4025 "but trace's packet header field type's `stream_id` field is not an integer field type.");
4026 goto error;
4027 }
4028
4029 BT_PUT(stream_id_decl);
4030 } else {
4031 /* Allow only _one_ ID-less stream */
4032 if (g_hash_table_size(ctx->stream_classes) != 0) {
4033 _BT_LOGE_NODE(node,
4034 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
4035 ret = -EPERM;
4036 goto error;
4037 }
4038
4039 /* Automatic ID: 0 */
4040 ret = bt_ctf_stream_class_set_id(stream_class, 0);
4041 assert(ret == 0);
4042 }
4043
4044 id = bt_ctf_stream_class_get_id(stream_class);
4045 if (id < 0) {
4046 _BT_LOGE_NODE(node,
4047 "Cannot get stream class's ID.");
4048 ret = -EINVAL;
4049 goto error;
4050 }
4051
4052 /*
4053 * Make sure that this stream class's ID is currently unique in
4054 * the trace.
4055 */
4056 existing_stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
4057 id);
4058 if (g_hash_table_lookup(ctx->stream_classes, (gpointer) id) ||
4059 existing_stream_class) {
4060 _BT_LOGE_NODE(node,
4061 "Duplicate stream class (same ID): id=%" PRId64,
4062 id);
4063 ret = -EINVAL;
4064 goto error;
4065 }
4066
4067 /* Move reference to visitor's context */
4068 g_hash_table_insert(ctx->stream_classes, (gpointer) (int64_t) id,
4069 stream_class);
4070 stream_class = NULL;
4071 goto end;
4072
4073 error:
4074 bt_put(stream_class);
4075
4076 end:
4077 bt_put(existing_stream_class);
4078 return ret;
4079 }
4080
4081 static
4082 int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
4083 {
4084 int ret = 0;
4085 char *left = NULL;
4086 _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
4087
4088 switch (node->type) {
4089 case NODE_TYPEDEF:
4090 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
4091 &node->u._typedef.type_declarators);
4092 if (ret) {
4093 _BT_LOGE_NODE(node,
4094 "Cannot add type definition found in trace (`trace` block).");
4095 goto error;
4096 }
4097 break;
4098 case NODE_TYPEALIAS:
4099 ret = visit_typealias(ctx, node->u.typealias.target,
4100 node->u.typealias.alias);
4101 if (ret) {
4102 _BT_LOGE_NODE(node,
4103 "Cannot add type alias found in trace (`trace` block).");
4104 goto error;
4105 }
4106 break;
4107 case NODE_CTF_EXPRESSION:
4108 {
4109 left = concatenate_unary_strings(&node->u.ctf_expression.left);
4110 if (!left) {
4111 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
4112 ret = -EINVAL;
4113 goto error;
4114 }
4115
4116 if (!strcmp(left, "major")) {
4117 if (_IS_SET(set, _TRACE_MAJOR_SET)) {
4118 _BT_LOGE_DUP_ATTR(node, "major", "trace");
4119 ret = -EPERM;
4120 goto error;
4121 }
4122
4123 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4124 &ctx->trace_major);
4125 if (ret) {
4126 _BT_LOGE_NODE(node,
4127 "Unexpected unary expression for trace's `major` attribute.");
4128 ret = -EINVAL;
4129 goto error;
4130 }
4131
4132 _SET(set, _TRACE_MAJOR_SET);
4133 } else if (!strcmp(left, "minor")) {
4134 if (_IS_SET(set, _TRACE_MINOR_SET)) {
4135 _BT_LOGE_DUP_ATTR(node, "minor", "trace");
4136 ret = -EPERM;
4137 goto error;
4138 }
4139
4140 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4141 &ctx->trace_minor);
4142 if (ret) {
4143 _BT_LOGE_NODE(node,
4144 "Unexpected unary expression for trace's `minor` attribute.");
4145 ret = -EINVAL;
4146 goto error;
4147 }
4148
4149 _SET(set, _TRACE_MINOR_SET);
4150 } else if (!strcmp(left, "uuid")) {
4151 if (_IS_SET(set, _TRACE_UUID_SET)) {
4152 _BT_LOGE_DUP_ATTR(node, "uuid", "trace");
4153 ret = -EPERM;
4154 goto error;
4155 }
4156
4157 ret = get_unary_uuid(&node->u.ctf_expression.right,
4158 ctx->trace_uuid);
4159 if (ret) {
4160 _BT_LOGE_NODE(node,
4161 "Invalid trace's `uuid` attribute.");
4162 goto error;
4163 }
4164
4165 ret = bt_ctf_trace_set_uuid(ctx->trace, ctx->trace_uuid);
4166 if (ret) {
4167 _BT_LOGE_NODE(node, "Cannot set trace's UUID.");
4168 goto error;
4169 }
4170
4171 _SET(set, _TRACE_UUID_SET);
4172 } else if (!strcmp(left, "byte_order")) {
4173 /* Native byte order is already known at this stage */
4174 if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
4175 _BT_LOGE_DUP_ATTR(node, "byte_order",
4176 "trace");
4177 ret = -EPERM;
4178 goto error;
4179 }
4180
4181 _SET(set, _TRACE_BYTE_ORDER_SET);
4182 } else if (!strcmp(left, "packet.header")) {
4183 if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
4184 _BT_LOGE_NODE(node,
4185 "Duplicate `packet.header` entry in trace.");
4186 ret = -EPERM;
4187 goto error;
4188 }
4189
4190 ret = visit_type_specifier_list(ctx,
4191 _BT_LIST_FIRST_ENTRY(
4192 &node->u.ctf_expression.right,
4193 struct ctf_node, siblings),
4194 &packet_header_decl);
4195 if (ret) {
4196 _BT_LOGE_NODE(node,
4197 "Cannot create trace's packet header field type.");
4198 goto error;
4199 }
4200
4201 assert(packet_header_decl);
4202 ret = bt_ctf_trace_set_packet_header_type(ctx->trace,
4203 packet_header_decl);
4204 BT_PUT(packet_header_decl);
4205 if (ret) {
4206 _BT_LOGE_NODE(node,
4207 "Cannot set trace's packet header field type.");
4208 goto error;
4209 }
4210
4211 _SET(set, _TRACE_PACKET_HEADER_SET);
4212 } else {
4213 _BT_LOGW_NODE(node,
4214 "Unknown attribute in stream class: "
4215 "attr-name=\"%s\"", left);
4216 }
4217
4218 g_free(left);
4219 left = NULL;
4220 break;
4221 }
4222 default:
4223 _BT_LOGE_NODE(node, "Unknown expression in trace.");
4224 ret = -EINVAL;
4225 goto error;
4226 }
4227
4228 return 0;
4229
4230 error:
4231 g_free(left);
4232 BT_PUT(packet_header_decl);
4233
4234 return ret;
4235 }
4236
4237 static
4238 int visit_trace_decl(struct ctx *ctx, struct ctf_node *node)
4239 {
4240 int ret = 0;
4241 int set = 0;
4242 struct ctf_node *iter;
4243 struct bt_list_head *decl_list = &node->u.trace.declaration_list;
4244
4245 if (node->visited) {
4246 goto end;
4247 }
4248
4249 node->visited = TRUE;
4250
4251 if (ctx->is_trace_visited) {
4252 _BT_LOGE_NODE(node, "Duplicate trace (`trace` block).");
4253 ret = -EEXIST;
4254 goto error;
4255 }
4256
4257 ret = ctx_push_scope(ctx);
4258 if (ret) {
4259 BT_LOGE_STR("Cannot push scope.");
4260 goto error;
4261 }
4262
4263 bt_list_for_each_entry(iter, decl_list, siblings) {
4264 ret = visit_trace_decl_entry(ctx, iter, &set);
4265 if (ret) {
4266 _BT_LOGE_NODE(iter, "Cannot visit trace's entry (`trace` block): "
4267 "ret=%d", ret);
4268 ctx_pop_scope(ctx);
4269 goto error;
4270 }
4271 }
4272
4273 ctx_pop_scope(ctx);
4274
4275 if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
4276 _BT_LOGE_NODE(node,
4277 "Missing `major` attribute in trace (`trace` block).");
4278 ret = -EPERM;
4279 goto error;
4280 }
4281
4282 if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
4283 _BT_LOGE_NODE(node,
4284 "Missing `minor` attribute in trace (`trace` block).");
4285 ret = -EPERM;
4286 goto error;
4287 }
4288
4289 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4290 _BT_LOGE_NODE(node,
4291 "Missing `byte_order` attribute in trace (`trace` block).");
4292 ret = -EPERM;
4293 goto error;
4294 }
4295
4296 ctx->is_trace_visited = TRUE;
4297
4298 end:
4299 return 0;
4300
4301 error:
4302 return ret;
4303 }
4304
4305 static
4306 int visit_env(struct ctx *ctx, struct ctf_node *node)
4307 {
4308 int ret = 0;
4309 char *left = NULL;
4310 struct ctf_node *entry_node;
4311 struct bt_list_head *decl_list = &node->u.env.declaration_list;
4312
4313 if (node->visited) {
4314 goto end;
4315 }
4316
4317 node->visited = TRUE;
4318
4319 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4320 struct bt_list_head *right_head =
4321 &entry_node->u.ctf_expression.right;
4322
4323 if (entry_node->type != NODE_CTF_EXPRESSION) {
4324 _BT_LOGE_NODE(entry_node,
4325 "Wrong expression in environment entry: "
4326 "node-type=%d", entry_node->type);
4327 ret = -EPERM;
4328 goto error;
4329 }
4330
4331 left = concatenate_unary_strings(
4332 &entry_node->u.ctf_expression.left);
4333 if (!left) {
4334 _BT_LOGE_NODE(entry_node,
4335 "Cannot get environment entry's name.");
4336 ret = -EINVAL;
4337 goto error;
4338 }
4339
4340 if (is_unary_string(right_head)) {
4341 char *right = concatenate_unary_strings(right_head);
4342
4343 if (!right) {
4344 _BT_LOGE_NODE(entry_node,
4345 "Unexpected unary expression for environment entry's value: "
4346 "name=\"%s\"", left);
4347 ret = -EINVAL;
4348 goto error;
4349 }
4350
4351 if (strcmp(left, "tracer_name") == 0) {
4352 if (strncmp(right, "lttng", 5) == 0) {
4353 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4354 "tracer-name=\"%s\"",
4355 left, right);
4356 ctx->is_lttng = 1;
4357 }
4358 }
4359
4360 ret = bt_ctf_trace_set_environment_field_string(
4361 ctx->trace, left, right);
4362 g_free(right);
4363
4364 if (ret) {
4365 _BT_LOGE_NODE(entry_node,
4366 "Cannot add string environment entry to trace: "
4367 "name=\"%s\", ret=%d", left, ret);
4368 goto error;
4369 }
4370 } else if (is_unary_unsigned(right_head) ||
4371 is_unary_signed(right_head)) {
4372 int64_t v;
4373
4374 if (is_unary_unsigned(right_head)) {
4375 ret = get_unary_unsigned(right_head,
4376 (uint64_t *) &v);
4377 } else {
4378 ret = get_unary_signed(right_head, &v);
4379 }
4380 if (ret) {
4381 _BT_LOGE_NODE(entry_node,
4382 "Unexpected unary expression for environment entry's value: "
4383 "name=\"%s\"", left);
4384 ret = -EINVAL;
4385 goto error;
4386 }
4387
4388 ret = bt_ctf_trace_set_environment_field_integer(
4389 ctx->trace, left, v);
4390 if (ret) {
4391 _BT_LOGE_NODE(entry_node,
4392 "Cannot add integer environment entry to trace: "
4393 "name=\"%s\", ret=%d", left, ret);
4394 goto error;
4395 }
4396 } else {
4397 _BT_LOGW_NODE(entry_node,
4398 "Environment entry has unknown type: "
4399 "name=\"%s\"", left);
4400 }
4401
4402 g_free(left);
4403 left = NULL;
4404 }
4405
4406 end:
4407 return 0;
4408
4409 error:
4410 g_free(left);
4411
4412 return ret;
4413 }
4414
4415 static
4416 int set_trace_byte_order(struct ctx *ctx, struct ctf_node *trace_node)
4417 {
4418 int ret = 0;
4419 int set = 0;
4420 char *left = NULL;
4421 struct ctf_node *node;
4422 struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
4423
4424 bt_list_for_each_entry(node, decl_list, siblings) {
4425 if (node->type == NODE_CTF_EXPRESSION) {
4426 struct ctf_node *right_node;
4427
4428 left = concatenate_unary_strings(
4429 &node->u.ctf_expression.left);
4430 if (!left) {
4431 _BT_LOGE_NODE(node,
4432 "Cannot concatenate unary strings.");
4433 ret = -EINVAL;
4434 goto error;
4435 }
4436
4437 if (!strcmp(left, "byte_order")) {
4438 enum bt_ctf_byte_order bo;
4439
4440 if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4441 _BT_LOGE_DUP_ATTR(node, "byte_order",
4442 "trace");
4443 ret = -EPERM;
4444 goto error;
4445 }
4446
4447 _SET(&set, _TRACE_BYTE_ORDER_SET);
4448 right_node = _BT_LIST_FIRST_ENTRY(
4449 &node->u.ctf_expression.right,
4450 struct ctf_node, siblings);
4451 bo = byte_order_from_unary_expr(right_node);
4452 if (bo == BT_CTF_BYTE_ORDER_UNKNOWN) {
4453 _BT_LOGE_NODE(node,
4454 "Invalid `byte_order` attribute in trace (`trace` block): "
4455 "expecting `le`, `be`, or `network`.");
4456 ret = -EINVAL;
4457 goto error;
4458 } else if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
4459 _BT_LOGE_NODE(node,
4460 "Invalid `byte_order` attribute in trace (`trace` block): "
4461 "cannot be set to `native` here.");
4462 ret = -EPERM;
4463 goto error;
4464 }
4465
4466 ctx->trace_bo = bo;
4467 ret = bt_ctf_trace_set_native_byte_order(
4468 ctx->trace, bo);
4469 if (ret) {
4470 _BT_LOGE_NODE(node,
4471 "Cannot set trace's byte order: "
4472 "ret=%d", ret);
4473 goto error;
4474 }
4475 }
4476
4477 g_free(left);
4478 left = NULL;
4479 }
4480 }
4481
4482 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4483 _BT_LOGE_NODE(trace_node,
4484 "Missing `byte_order` attribute in trace (`trace` block).");
4485 ret = -EINVAL;
4486 goto error;
4487 }
4488
4489 return 0;
4490
4491 error:
4492 g_free(left);
4493
4494 return ret;
4495 }
4496
4497 static
4498 int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
4499 struct bt_ctf_clock_class *clock, int *set)
4500 {
4501 int ret = 0;
4502 char *left = NULL;
4503
4504 if (entry_node->type != NODE_CTF_EXPRESSION) {
4505 _BT_LOGE_NODE(entry_node,
4506 "Unexpected node type: node-type=%d",
4507 entry_node->type);
4508 ret = -EPERM;
4509 goto error;
4510 }
4511
4512 left = concatenate_unary_strings(&entry_node->u.ctf_expression.left);
4513 if (!left) {
4514 _BT_LOGE_NODE(entry_node, "Cannot concatenate unary strings.");
4515 ret = -EINVAL;
4516 goto error;
4517 }
4518
4519 if (!strcmp(left, "name")) {
4520 char *right;
4521
4522 if (_IS_SET(set, _CLOCK_NAME_SET)) {
4523 _BT_LOGE_DUP_ATTR(entry_node, "name", "clock class");
4524 ret = -EPERM;
4525 goto error;
4526 }
4527
4528 right = concatenate_unary_strings(
4529 &entry_node->u.ctf_expression.right);
4530 if (!right) {
4531 _BT_LOGE_NODE(entry_node,
4532 "Unexpected unary expression for clock class's `name` attribute.");
4533 ret = -EINVAL;
4534 goto error;
4535 }
4536
4537 ret = bt_ctf_clock_class_set_name(clock, right);
4538 if (ret) {
4539 _BT_LOGE_NODE(entry_node,
4540 "cannot set clock class's name");
4541 g_free(right);
4542 goto error;
4543 }
4544
4545 g_free(right);
4546 _SET(set, _CLOCK_NAME_SET);
4547 } else if (!strcmp(left, "uuid")) {
4548 unsigned char uuid[BABELTRACE_UUID_LEN];
4549
4550 if (_IS_SET(set, _CLOCK_UUID_SET)) {
4551 _BT_LOGE_DUP_ATTR(entry_node, "uuid", "clock class");
4552 ret = -EPERM;
4553 goto error;
4554 }
4555
4556 ret = get_unary_uuid(&entry_node->u.ctf_expression.right, uuid);
4557 if (ret) {
4558 _BT_LOGE_NODE(entry_node,
4559 "Invalid clock class's `uuid` attribute.");
4560 goto error;
4561 }
4562
4563 ret = bt_ctf_clock_class_set_uuid(clock, uuid);
4564 if (ret) {
4565 _BT_LOGE_NODE(entry_node,
4566 "Cannot set clock class's UUID.");
4567 goto error;
4568 }
4569
4570 _SET(set, _CLOCK_UUID_SET);
4571 } else if (!strcmp(left, "description")) {
4572 char *right;
4573
4574 if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
4575 _BT_LOGE_DUP_ATTR(entry_node, "description",
4576 "clock class");
4577 ret = -EPERM;
4578 goto error;
4579 }
4580
4581 right = concatenate_unary_strings(
4582 &entry_node->u.ctf_expression.right);
4583 if (!right) {
4584 _BT_LOGE_NODE(entry_node,
4585 "Unexpected unary expression for clock class's `description` attribute.");
4586 ret = -EINVAL;
4587 goto error;
4588 }
4589
4590 ret = bt_ctf_clock_class_set_description(clock, right);
4591 if (ret) {
4592 _BT_LOGE_NODE(entry_node,
4593 "Cannot set clock class's description.");
4594 g_free(right);
4595 goto error;
4596 }
4597
4598 g_free(right);
4599 _SET(set, _CLOCK_DESCRIPTION_SET);
4600 } else if (!strcmp(left, "freq")) {
4601 uint64_t freq;
4602
4603 if (_IS_SET(set, _CLOCK_FREQ_SET)) {
4604 _BT_LOGE_DUP_ATTR(entry_node, "freq", "clock class");
4605 ret = -EPERM;
4606 goto error;
4607 }
4608
4609 ret = get_unary_unsigned(
4610 &entry_node->u.ctf_expression.right, &freq);
4611 if (ret) {
4612 _BT_LOGE_NODE(entry_node,
4613 "Unexpected unary expression for clock class's `freq` attribute.");
4614 ret = -EINVAL;
4615 goto error;
4616 }
4617
4618 ret = bt_ctf_clock_class_set_frequency(clock, freq);
4619 if (ret) {
4620 _BT_LOGE_NODE(entry_node,
4621 "Cannot set clock class's frequency.");
4622 goto error;
4623 }
4624
4625 _SET(set, _CLOCK_FREQ_SET);
4626 } else if (!strcmp(left, "precision")) {
4627 uint64_t precision;
4628
4629 if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
4630 _BT_LOGE_DUP_ATTR(entry_node, "precision",
4631 "clock class");
4632 ret = -EPERM;
4633 goto error;
4634 }
4635
4636 ret = get_unary_unsigned(
4637 &entry_node->u.ctf_expression.right, &precision);
4638 if (ret) {
4639 _BT_LOGE_NODE(entry_node,
4640 "Unexpected unary expression for clock class's `precision` attribute.");
4641 ret = -EINVAL;
4642 goto error;
4643 }
4644
4645 ret = bt_ctf_clock_class_set_precision(clock, precision);
4646 if (ret) {
4647 _BT_LOGE_NODE(entry_node,
4648 "Cannot set clock class's precision.");
4649 goto error;
4650 }
4651
4652 _SET(set, _CLOCK_PRECISION_SET);
4653 } else if (!strcmp(left, "offset_s")) {
4654 uint64_t offset_s;
4655
4656 if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
4657 _BT_LOGE_DUP_ATTR(entry_node, "offset_s",
4658 "clock class");
4659 ret = -EPERM;
4660 goto error;
4661 }
4662
4663 ret = get_unary_unsigned(
4664 &entry_node->u.ctf_expression.right, &offset_s);
4665 if (ret) {
4666 _BT_LOGE_NODE(entry_node,
4667 "Unexpected unary expression for clock class's `offset_s` attribute.");
4668 ret = -EINVAL;
4669 goto error;
4670 }
4671
4672 ret = bt_ctf_clock_class_set_offset_s(clock, offset_s);
4673 if (ret) {
4674 _BT_LOGE_NODE(entry_node,
4675 "Cannot set clock class's offset in seconds.");
4676 goto error;
4677 }
4678
4679 _SET(set, _CLOCK_OFFSET_S_SET);
4680 } else if (!strcmp(left, "offset")) {
4681 uint64_t offset;
4682
4683 if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
4684 _BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
4685 ret = -EPERM;
4686 goto error;
4687 }
4688
4689 ret = get_unary_unsigned(
4690 &entry_node->u.ctf_expression.right, &offset);
4691 if (ret) {
4692 _BT_LOGE_NODE(entry_node,
4693 "Unexpected unary expression for clock class's `offset` attribute.");
4694 ret = -EINVAL;
4695 goto error;
4696 }
4697
4698 ret = bt_ctf_clock_class_set_offset_cycles(clock, offset);
4699 if (ret) {
4700 _BT_LOGE_NODE(entry_node,
4701 "Cannot set clock class's offset in cycles.");
4702 goto error;
4703 }
4704
4705 _SET(set, _CLOCK_OFFSET_SET);
4706 } else if (!strcmp(left, "absolute")) {
4707 struct ctf_node *right;
4708
4709 if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
4710 _BT_LOGE_DUP_ATTR(entry_node, "absolute",
4711 "clock class");
4712 ret = -EPERM;
4713 goto error;
4714 }
4715
4716 right = _BT_LIST_FIRST_ENTRY(
4717 &entry_node->u.ctf_expression.right,
4718 struct ctf_node, siblings);
4719 ret = get_boolean(right);
4720 if (ret < 0) {
4721 _BT_LOGE_NODE(entry_node,
4722 "Unexpected unary expression for clock class's `absolute` attribute.");
4723 ret = -EINVAL;
4724 goto error;
4725 }
4726
4727 ret = bt_ctf_clock_class_set_is_absolute(clock, ret);
4728 if (ret) {
4729 _BT_LOGE_NODE(entry_node,
4730 "Cannot set clock class's absolute flag.");
4731 goto error;
4732 }
4733
4734 _SET(set, _CLOCK_ABSOLUTE_SET);
4735 } else {
4736 _BT_LOGW_NODE(entry_node,
4737 "Unknown attribute in clock class: attr-name=\"%s\"",
4738 left);
4739 }
4740
4741 g_free(left);
4742 left = NULL;
4743
4744 return 0;
4745
4746 error:
4747 g_free(left);
4748
4749 return ret;
4750 }
4751
4752 static
4753 int64_t cycles_from_ns(uint64_t frequency, int64_t ns)
4754 {
4755 int64_t cycles;
4756
4757 /* 1GHz */
4758 if (frequency == 1000000000ULL) {
4759 cycles = ns;
4760 } else {
4761 cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
4762 }
4763
4764 return cycles;
4765 }
4766
4767 static
4768 int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock)
4769 {
4770 int ret;
4771 uint64_t freq;
4772 int64_t offset_cycles;
4773
4774 freq = bt_ctf_clock_class_get_frequency(clock);
4775 if (freq == -1ULL) {
4776 BT_LOGE_STR("Cannot get clock class's frequency.");
4777 ret = -1;
4778 goto end;
4779 }
4780
4781 ret = bt_ctf_clock_class_get_offset_cycles(clock, &offset_cycles);
4782 if (ret) {
4783 BT_LOGE_STR("Cannot get clock class's offset in cycles.");
4784 ret = -1;
4785 goto end;
4786 }
4787
4788 offset_cycles += cycles_from_ns(freq, ctx->clock_class_offset_ns);
4789 ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles);
4790
4791 end:
4792 return ret;
4793 }
4794
4795 static
4796 int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
4797 {
4798 int ret = 0;
4799 int set = 0;
4800 struct bt_ctf_clock_class *clock;
4801 struct ctf_node *entry_node;
4802 struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
4803 const char *clock_class_name;
4804
4805 if (clock_node->visited) {
4806 return 0;
4807 }
4808
4809 clock_node->visited = TRUE;
4810 clock = bt_ctf_clock_class_create(NULL);
4811 if (!clock) {
4812 _BT_LOGE_NODE(clock_node,
4813 "Cannot create default clock class.");
4814 ret = -ENOMEM;
4815 goto error;
4816 }
4817
4818 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4819 ret = visit_clock_decl_entry(ctx, entry_node, clock, &set);
4820 if (ret) {
4821 _BT_LOGE_NODE(entry_node,
4822 "Cannot visit clock class's entry: ret=%d",
4823 ret);
4824 goto error;
4825 }
4826 }
4827
4828 if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
4829 _BT_LOGE_NODE(clock_node,
4830 "Missing `name` attribute in clock class.");
4831 ret = -EPERM;
4832 goto error;
4833 }
4834
4835 clock_class_name = bt_ctf_clock_class_get_name(clock);
4836 assert(clock_class_name);
4837 if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
4838 /*
4839 * Old versions of LTTng forgot to set its clock class
4840 * as absolute, even if it is. This is important because
4841 * it's a condition to be able to sort notifications
4842 * from different sources.
4843 */
4844 ret = bt_ctf_clock_class_set_is_absolute(clock, 1);
4845 if (ret) {
4846 _BT_LOGE_NODE(clock_node,
4847 "Cannot set clock class's absolute flag.");
4848 goto error;
4849 }
4850 }
4851
4852 ret = apply_clock_class_offset(ctx, clock);
4853 if (ret) {
4854 _BT_LOGE_NODE(clock_node,
4855 "Cannot apply clock class's custom offset.");
4856 goto error;
4857 }
4858
4859 ret = bt_ctf_trace_add_clock_class(ctx->trace, clock);
4860 if (ret) {
4861 _BT_LOGE_NODE(clock_node,
4862 "Cannot add clock class to trace.");
4863 goto error;
4864 }
4865
4866 error:
4867 BT_PUT(clock);
4868
4869 return ret;
4870 }
4871
4872 static
4873 int visit_root_decl(struct ctx *ctx, struct ctf_node *root_decl_node)
4874 {
4875 int ret = 0;
4876
4877 if (root_decl_node->visited) {
4878 goto end;
4879 }
4880
4881 root_decl_node->visited = TRUE;
4882
4883 switch (root_decl_node->type) {
4884 case NODE_TYPEDEF:
4885 ret = visit_typedef(ctx,
4886 root_decl_node->u._typedef.type_specifier_list,
4887 &root_decl_node->u._typedef.type_declarators);
4888 if (ret) {
4889 _BT_LOGE_NODE(root_decl_node,
4890 "Cannot add type definition found in root scope.");
4891 goto end;
4892 }
4893 break;
4894 case NODE_TYPEALIAS:
4895 ret = visit_typealias(ctx, root_decl_node->u.typealias.target,
4896 root_decl_node->u.typealias.alias);
4897 if (ret) {
4898 _BT_LOGE_NODE(root_decl_node,
4899 "Cannot add type alias found in root scope.");
4900 goto end;
4901 }
4902 break;
4903 case NODE_TYPE_SPECIFIER_LIST:
4904 {
4905 _BT_CTF_FIELD_TYPE_INIT(decl);
4906
4907 /*
4908 * Just add the type specifier to the root
4909 * declaration scope. Put local reference.
4910 */
4911 ret = visit_type_specifier_list(ctx, root_decl_node, &decl);
4912 if (ret) {
4913 _BT_LOGE_NODE(root_decl_node,
4914 "Cannot visit root scope's field type: "
4915 "ret=%d", ret);
4916 assert(!decl);
4917 goto end;
4918 }
4919
4920 BT_PUT(decl);
4921 break;
4922 }
4923 default:
4924 _BT_LOGE_NODE(root_decl_node,
4925 "Unexpected node type: node-type=%d",
4926 root_decl_node->type);
4927 ret = -EPERM;
4928 goto end;
4929 }
4930
4931 end:
4932 return ret;
4933 }
4934
4935 static
4936 int set_trace_name(struct ctx *ctx)
4937 {
4938 GString *name;
4939 int ret = 0;
4940 struct bt_value *value = NULL;
4941
4942 assert(bt_ctf_trace_get_stream_class_count(ctx->trace) == 0);
4943 name = g_string_new(NULL);
4944 if (!name) {
4945 BT_LOGE_STR("Failed to allocate a GString.");
4946 ret = -1;
4947 goto end;
4948 }
4949
4950 /*
4951 * Check if we have a trace environment string value named `hostname`.
4952 * If so, use it as the trace name's prefix.
4953 */
4954 value = bt_ctf_trace_get_environment_field_value_by_name(ctx->trace,
4955 "hostname");
4956 if (bt_value_is_string(value)) {
4957 const char *hostname;
4958
4959 ret = bt_value_string_get(value, &hostname);
4960 assert(ret == 0);
4961 g_string_append(name, hostname);
4962
4963 if (ctx->trace_name_suffix) {
4964 g_string_append_c(name, G_DIR_SEPARATOR);
4965 }
4966 }
4967
4968 if (ctx->trace_name_suffix) {
4969 g_string_append(name, ctx->trace_name_suffix);
4970 }
4971
4972 ret = bt_ctf_trace_set_name(ctx->trace, name->str);
4973 if (ret) {
4974 BT_LOGE("Cannot set trace's name: name=\"%s\"", name->str);
4975 goto error;
4976 }
4977
4978 goto end;
4979
4980 error:
4981 ret = -1;
4982
4983 end:
4984 bt_put(value);
4985
4986 if (name) {
4987 g_string_free(name, TRUE);
4988 }
4989
4990 return ret;
4991 }
4992
4993 static
4994 int move_ctx_stream_classes_to_trace(struct ctx *ctx)
4995 {
4996 int ret = 0;
4997 GHashTableIter iter;
4998 gpointer key, stream_class;
4999
5000 if (g_hash_table_size(ctx->stream_classes) > 0 &&
5001 bt_ctf_trace_get_stream_class_count(ctx->trace) == 0) {
5002 /*
5003 * We're about to add the first stream class to the
5004 * trace. This will freeze the trace, and after this
5005 * we cannot set the name anymore. At this point,
5006 * set the trace name.
5007 */
5008 ret = set_trace_name(ctx);
5009 if (ret) {
5010 BT_LOGE_STR("Cannot set trace's name.");
5011 goto end;
5012 }
5013 }
5014
5015 g_hash_table_iter_init(&iter, ctx->stream_classes);
5016
5017 while (g_hash_table_iter_next(&iter, &key, &stream_class)) {
5018 ret = bt_ctf_trace_add_stream_class(ctx->trace,
5019 stream_class);
5020 if (ret) {
5021 int64_t id = bt_ctf_stream_class_get_id(stream_class);
5022 BT_LOGE("Cannot add stream class to trace: id=%" PRId64,
5023 id);
5024 goto end;
5025 }
5026 }
5027
5028 g_hash_table_remove_all(ctx->stream_classes);
5029
5030 end:
5031 return ret;
5032 }
5033
5034 BT_HIDDEN
5035 struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
5036 int64_t clock_class_offset_ns, const char *name)
5037 {
5038 int ret;
5039 struct ctx *ctx = NULL;
5040 struct bt_ctf_trace *trace;
5041
5042 trace = bt_ctf_trace_create();
5043 if (!trace) {
5044 BT_LOGE_STR("Cannot create empty trace.");
5045 goto error;
5046 }
5047
5048 /* Set packet header to NULL to override the default one */
5049 ret = bt_ctf_trace_set_packet_header_type(trace, NULL);
5050 if (ret) {
5051 BT_LOGE_STR("Cannot reset initial trace's packet header field type.");
5052 goto error;
5053 }
5054
5055 /* Create visitor's context */
5056 ctx = ctx_create(trace, clock_class_offset_ns, name);
5057 if (!ctx) {
5058 BT_LOGE_STR("Cannot create visitor's context.");
5059 goto error;
5060 }
5061
5062 trace = NULL;
5063 goto end;
5064
5065 error:
5066 ctx_destroy(ctx);
5067 ctx = NULL;
5068
5069 end:
5070 bt_put(trace);
5071 return (void *) ctx;
5072 }
5073
5074 BT_HIDDEN
5075 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor)
5076 {
5077 ctx_destroy((void *) visitor);
5078 }
5079
5080 BT_HIDDEN
5081 struct bt_ctf_trace *ctf_visitor_generate_ir_get_trace(
5082 struct ctf_visitor_generate_ir *visitor)
5083 {
5084 struct ctx *ctx = (void *) visitor;
5085
5086 assert(ctx);
5087 assert(ctx->trace);
5088 return bt_get(ctx->trace);
5089 }
5090
5091 BT_HIDDEN
5092 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
5093 struct ctf_node *node)
5094 {
5095 int ret = 0;
5096 struct ctx *ctx = (void *) visitor;
5097
5098 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
5099
5100 switch (node->type) {
5101 case NODE_ROOT:
5102 {
5103 struct ctf_node *iter;
5104 int got_trace_decl = FALSE;
5105
5106 /*
5107 * The first thing we need is the native byte order of
5108 * the trace block, because early type aliases can have
5109 * a `byte_order` attribute set to `native`. If we don't
5110 * have the native byte order yet, and we don't have any
5111 * trace block yet, then fail with EINCOMPLETE.
5112 */
5113 if (ctx->trace_bo == BT_CTF_BYTE_ORDER_NATIVE) {
5114 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5115 if (got_trace_decl) {
5116 _BT_LOGE_NODE(node,
5117 "Duplicate trace (`trace` block).");
5118 ret = -1;
5119 goto end;
5120 }
5121
5122 ret = set_trace_byte_order(ctx, iter);
5123 if (ret) {
5124 _BT_LOGE_NODE(node,
5125 "Cannot set trace's native byte order: "
5126 "ret=%d", ret);
5127 goto end;
5128 }
5129
5130 got_trace_decl = TRUE;
5131 }
5132
5133 if (!got_trace_decl) {
5134 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
5135 ret = -EINCOMPLETE;
5136 goto end;
5137 }
5138 }
5139
5140 assert(ctx->trace_bo == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
5141 ctx->trace_bo == BT_CTF_BYTE_ORDER_BIG_ENDIAN);
5142 assert(ctx->current_scope &&
5143 ctx->current_scope->parent_scope == NULL);
5144
5145 /* Environment */
5146 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
5147 ret = visit_env(ctx, iter);
5148 if (ret) {
5149 _BT_LOGE_NODE(iter,
5150 "Cannot visit trace's environment (`env` block) entry: "
5151 "ret=%d", ret);
5152 goto end;
5153 }
5154 }
5155
5156 assert(ctx->current_scope &&
5157 ctx->current_scope->parent_scope == NULL);
5158
5159 /*
5160 * Visit clock blocks.
5161 */
5162 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
5163 ret = visit_clock_decl(ctx, iter);
5164 if (ret) {
5165 _BT_LOGE_NODE(iter,
5166 "Cannot visit clock class: ret=%d",
5167 ret);
5168 goto end;
5169 }
5170 }
5171
5172 assert(ctx->current_scope &&
5173 ctx->current_scope->parent_scope == NULL);
5174
5175 /*
5176 * Visit root declarations next, as they can be used by any
5177 * following entity.
5178 */
5179 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
5180 siblings) {
5181 ret = visit_root_decl(ctx, iter);
5182 if (ret) {
5183 _BT_LOGE_NODE(iter,
5184 "Cannot visit root entry: ret=%d",
5185 ret);
5186 goto end;
5187 }
5188 }
5189
5190 assert(ctx->current_scope &&
5191 ctx->current_scope->parent_scope == NULL);
5192
5193 /* Callsite blocks are not supported */
5194 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
5195 _BT_LOGW_NODE(iter,
5196 "\"callsite\" blocks are not supported as of this version.");
5197 }
5198
5199 assert(ctx->current_scope &&
5200 ctx->current_scope->parent_scope == NULL);
5201
5202 /* Trace */
5203 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5204 ret = visit_trace_decl(ctx, iter);
5205 if (ret) {
5206 _BT_LOGE_NODE(iter,
5207 "Cannot visit trace (`trace` block): "
5208 "ret=%d", ret);
5209 goto end;
5210 }
5211 }
5212
5213 assert(ctx->current_scope &&
5214 ctx->current_scope->parent_scope == NULL);
5215
5216 /* Streams */
5217 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
5218 ret = visit_stream_decl(ctx, iter);
5219 if (ret) {
5220 _BT_LOGE_NODE(iter,
5221 "Cannot visit stream class: ret=%d",
5222 ret);
5223 goto end;
5224 }
5225 }
5226
5227 assert(ctx->current_scope &&
5228 ctx->current_scope->parent_scope == NULL);
5229
5230 /* Events */
5231 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
5232 ret = visit_event_decl(ctx, iter);
5233 if (ret) {
5234 _BT_LOGE_NODE(iter,
5235 "Cannot visit event class: ret=%d",
5236 ret);
5237 goto end;
5238 }
5239 }
5240
5241 assert(ctx->current_scope &&
5242 ctx->current_scope->parent_scope == NULL);
5243 break;
5244 }
5245 default:
5246 _BT_LOGE_NODE(node,
5247 "Unexpected node type: node-type=%d",
5248 node->type);
5249 ret = -EINVAL;
5250 goto end;
5251 }
5252
5253 /* Move decoded stream classes to trace, if any */
5254 ret = move_ctx_stream_classes_to_trace(ctx);
5255 if (ret) {
5256 BT_LOGE("Cannot move stream classes to trace: ret=%d", ret);
5257 }
5258
5259 end:
5260 return ret;
5261 }
This page took 0.170883 seconds and 3 git commands to generate.