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