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