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