Fix: uninitialized variable may be used warning
[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
50842bdc 149#define _BT_FIELD_TYPE_INIT(_name) struct bt_field_type *_name = NULL;
e98a2d6e 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 *
50842bdc 174 * GQuark -> struct bt_field_type *
e98a2d6e
PP
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) */
50842bdc 187 struct bt_trace *trace;
e98a2d6e 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 */
50842bdc 202 enum bt_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 *
50842bdc 210 * int64_t -> struct bt_stream_class *
e98a2d6e
PP
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,
50842bdc 241 NULL, (GDestroyNotify) bt_put);
e98a2d6e
PP
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
50842bdc 308struct bt_field_type *ctx_decl_scope_lookup_prefix_alias(
e98a2d6e
PP
309 struct ctx_decl_scope *scope, char prefix,
310 const char *name, int levels)
311{
312 GQuark qname = 0;
313 int cur_levels = 0;
50842bdc 314 _BT_FIELD_TYPE_INIT(decl);
e98a2d6e
PP
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
50842bdc 356struct bt_field_type *ctx_decl_scope_lookup_alias(
e98a2d6e
PP
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
50842bdc 372struct bt_field_type *ctx_decl_scope_lookup_enum(
e98a2d6e
PP
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
50842bdc 388struct bt_field_type *ctx_decl_scope_lookup_struct(
e98a2d6e
PP
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
50842bdc 404struct bt_field_type *ctx_decl_scope_lookup_variant(
e98a2d6e
PP
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,
50842bdc 422 char prefix, const char *name, struct bt_field_type *decl)
e98a2d6e
PP
423{
424 int ret = 0;
425 GQuark qname = 0;
50842bdc 426 _BT_FIELD_TYPE_INIT(edecl);
e98a2d6e
PP
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,
50842bdc 467 const char *name, struct bt_field_type *decl)
e98a2d6e
PP
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,
50842bdc 483 const char *name, struct bt_field_type *decl)
e98a2d6e
PP
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,
50842bdc 499 const char *name, struct bt_field_type *decl)
e98a2d6e
PP
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,
50842bdc 515 const char *name, struct bt_field_type *decl)
e98a2d6e
PP
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
50842bdc 567struct ctx *ctx_create(struct bt_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;
50842bdc 607 ctx->trace_bo = BT_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,
50842bdc 665 struct bt_field_type **decl);
e98a2d6e 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
50842bdc 1044enum bt_byte_order byte_order_from_unary_expr(struct ctf_node *unary_expr)
e98a2d6e
PP
1045{
1046 const char *str;
50842bdc 1047 enum bt_byte_order bo = BT_BYTE_ORDER_UNKNOWN;
e98a2d6e
PP
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")) {
50842bdc 1058 bo = BT_BYTE_ORDER_BIG_ENDIAN;
e98a2d6e 1059 } else if (!strcmp(str, "le")) {
50842bdc 1060 bo = BT_BYTE_ORDER_LITTLE_ENDIAN;
e98a2d6e 1061 } else if (!strcmp(str, "native")) {
50842bdc 1062 bo = BT_BYTE_ORDER_NATIVE;
e98a2d6e 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
50842bdc 1076enum bt_byte_order get_real_byte_order(struct ctx *ctx,
e98a2d6e
PP
1077 struct ctf_node *uexpr)
1078{
50842bdc 1079 enum bt_byte_order bo = byte_order_from_unary_expr(uexpr);
e98a2d6e 1080
50842bdc
PP
1081 if (bo == BT_BYTE_ORDER_NATIVE) {
1082 bo = bt_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,
50842bdc
PP
1277 struct bt_field_type **field_decl,
1278 struct bt_field_type *nested_decl)
e98a2d6e
PP
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;
50842bdc 1317 _BT_FIELD_TYPE_INIT(nested_decl_copy);
e98a2d6e
PP
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 */
50842bdc 1337 nested_decl_copy = bt_field_type_copy(nested_decl);
e98a2d6e
PP
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 */
50842bdc
PP
1349 if (bt_field_type_is_integer(nested_decl)) {
1350 ret = bt_field_type_integer_set_base(
28973adf 1351 nested_decl,
50842bdc 1352 BT_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;
50842bdc
PP
1390 _BT_FIELD_TYPE_INIT(decl);
1391 _BT_FIELD_TYPE_INIT(outer_field_decl);
e98a2d6e
PP
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;
50842bdc 1417 _BT_FIELD_TYPE_INIT(array_decl);
e98a2d6e
PP
1418
1419 len = first->u.unary_expression.u.unsigned_constant;
50842bdc 1420 array_decl = bt_field_type_array_create(nested_decl,
e98a2d6e
PP
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. */
50842bdc 1436 _BT_FIELD_TYPE_INIT(seq_decl);
e98a2d6e 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 }
50842bdc 1454 seq_decl = bt_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,
50842bdc 1516 struct bt_field_type *struct_decl,
e98a2d6e
PP
1517 struct ctf_node *type_specifier_list,
1518 struct bt_list_head *type_declarators)
1519{
1520 int ret = 0;
1521 struct ctf_node *iter;
50842bdc 1522 _BT_FIELD_TYPE_INIT(field_decl);
e98a2d6e
PP
1523
1524 bt_list_for_each_entry(iter, type_declarators, siblings) {
1525 field_decl = NULL;
1526 GQuark qfield_name;
1527 const char *field_name;
50842bdc 1528 _BT_FIELD_TYPE_INIT(efield_decl);
e98a2d6e
PP
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 =
50842bdc 1544 bt_field_type_structure_get_field_type_by_name(
e98a2d6e
PP
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 */
50842bdc 1556 ret = bt_field_type_structure_add_field(struct_decl,
e98a2d6e
PP
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,
50842bdc 1578 struct bt_field_type *variant_decl,
e98a2d6e
PP
1579 struct ctf_node *type_specifier_list,
1580 struct bt_list_head *type_declarators)
1581{
1582 int ret = 0;
1583 struct ctf_node *iter;
50842bdc 1584 _BT_FIELD_TYPE_INIT(field_decl);
e98a2d6e
PP
1585
1586 bt_list_for_each_entry(iter, type_declarators, siblings) {
1587 field_decl = NULL;
1588 GQuark qfield_name;
1589 const char *field_name;
50842bdc 1590 _BT_FIELD_TYPE_INIT(efield_decl);
e98a2d6e
PP
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 =
50842bdc 1606 bt_field_type_variant_get_field_type_by_name(
e98a2d6e
PP
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 */
50842bdc 1618 ret = bt_field_type_variant_add_field(variant_decl,
e98a2d6e
PP
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;
50842bdc 1645 _BT_FIELD_TYPE_INIT(type_decl);
e98a2d6e
PP
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 */
50842bdc
PP
1658 if (bt_field_type_is_variant(type_decl)) {
1659 if (bt_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;
50842bdc 1691 _BT_FIELD_TYPE_INIT(type_decl);
e98a2d6e
PP
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 */
50842bdc
PP
1713 if (bt_field_type_is_variant(type_decl)) {
1714 if (bt_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,
50842bdc 1756 struct bt_field_type *struct_decl)
e98a2d6e
PP
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,
50842bdc 1806 struct bt_field_type *variant_decl)
e98a2d6e
PP
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,
50842bdc 1859 struct bt_field_type **struct_decl)
e98a2d6e
PP
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) {
50842bdc 1867 _BT_FIELD_TYPE_INIT(struct_decl_copy);
e98a2d6e
PP
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 */
50842bdc 1885 struct_decl_copy = bt_field_type_copy(*struct_decl);
e98a2d6e 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) {
50842bdc 1898 _BT_FIELD_TYPE_INIT(estruct_decl);
e98a2d6e
PP
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
50842bdc 1920 *struct_decl = bt_field_type_structure_create();
e98a2d6e 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 1927 if (min_align_value != 0) {
50842bdc 1928 ret = bt_field_type_set_alignment(*struct_decl,
539fd01b
JG
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,
50842bdc 1979 int has_body, struct bt_field_type **variant_decl)
e98a2d6e
PP
1980{
1981 int ret = 0;
50842bdc 1982 _BT_FIELD_TYPE_INIT(untagged_variant_decl);
e98a2d6e
PP
1983
1984 *variant_decl = NULL;
1985
1986 /* For named variant (without body), lookup in declaration scope */
1987 if (!has_body) {
50842bdc 1988 _BT_FIELD_TYPE_INIT(variant_decl_copy);
e98a2d6e
PP
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 */
50842bdc 2007 variant_decl_copy = bt_field_type_copy(
e98a2d6e
PP
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) {
50842bdc 2020 struct bt_field_type *evariant_decl =
e98a2d6e
PP
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
50842bdc 2033 untagged_variant_decl = bt_field_type_variant_create(NULL,
e98a2d6e
PP
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
50842bdc 2092 ret = bt_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,
50842bdc 2118 struct bt_field_type *enum_decl, int64_t *last, bt_bool is_signed)
e98a2d6e
PP
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;
f4cc9a21 2125 const char *effective_label = label;
e98a2d6e
PP
2126 struct bt_list_head *values = &enumerator->u.enumerator.values;
2127
2128 bt_list_for_each_entry(iter, values, siblings) {
2129 int64_t *target;
2130
2131 if (iter->type != NODE_UNARY_EXPRESSION) {
28973adf
PP
2132 _BT_LOGE_NODE(iter,
2133 "Wrong expression for enumeration field type label: "
08da4f77 2134 "node-type=%d, label=\"%s\"", iter->type,
e98a2d6e
PP
2135 label);
2136 ret = -EINVAL;
2137 goto error;
2138 }
2139
2140 if (nr_vals == 0) {
2141 target = &start;
2142 } else {
2143 target = &end;
2144 }
2145
2146 switch (iter->u.unary_expression.type) {
2147 case UNARY_SIGNED_CONSTANT:
2148 *target = iter->u.unary_expression.u.signed_constant;
2149 break;
2150 case UNARY_UNSIGNED_CONSTANT:
2151 *target = (int64_t)
2152 iter->u.unary_expression.u.unsigned_constant;
2153 break;
2154 default:
28973adf
PP
2155 _BT_LOGE_NODE(iter,
2156 "Invalid enumeration field type entry: "
08da4f77
PP
2157 "expecting constant signed or unsigned integer: "
2158 "node-type=%d, label=\"%s\"",
2159 iter->u.unary_expression.type, label);
e98a2d6e
PP
2160 ret = -EINVAL;
2161 goto error;
2162 }
2163
2164 if (nr_vals > 1) {
28973adf
PP
2165 _BT_LOGE_NODE(iter,
2166 "Invalid enumeration field type entry: label=\"%s\"",
e98a2d6e
PP
2167 label);
2168 ret = -EINVAL;
2169 goto error;
2170 }
2171
2172 nr_vals++;
2173 }
2174
2175 if (nr_vals == 0) {
2176 start = *last;
2177 }
2178
2179 if (nr_vals <= 1) {
2180 end = start;
2181 }
2182
2183 *last = end + 1;
2184
f4cc9a21
PP
2185 if (label[0] == '_') {
2186 /*
2187 * Strip the first underscore of any enumeration field
2188 * type's label in case this enumeration FT is used as
2189 * a variant FT tag later. The variant FT choice names
2190 * could also start with `_`, in which case the prefix
2191 * is removed, and it the resulting choice name needs to
2192 * match tag labels.
2193 */
2194 effective_label = &label[1];
2195 }
2196
e98a2d6e 2197 if (is_signed) {
f4cc9a21
PP
2198 ret = bt_field_type_enumeration_add_mapping_signed(enum_decl,
2199 effective_label, start, end);
e98a2d6e 2200 } else {
50842bdc 2201 ret = bt_field_type_enumeration_add_mapping_unsigned(enum_decl,
f4cc9a21 2202 effective_label, (uint64_t) start, (uint64_t) end);
e98a2d6e
PP
2203 }
2204 if (ret) {
28973adf
PP
2205 _BT_LOGE_NODE(enumerator,
2206 "Cannot add mapping to enumeration field type: "
08da4f77
PP
2207 "label=\"%s\", ret=%d, "
2208 "start-value-unsigned=%" PRIu64 ", "
2209 "end-value-unsigned=%" PRIu64, label, ret,
2210 (uint64_t) start, (uint64_t) end);
e98a2d6e
PP
2211 goto error;
2212 }
2213
2214 return 0;
2215
2216error:
2217 return ret;
2218}
2219
2220static
2221int visit_enum_decl(struct ctx *ctx, const char *name,
2222 struct ctf_node *container_type,
2223 struct bt_list_head *enumerator_list,
2224 int has_body,
50842bdc 2225 struct bt_field_type **enum_decl)
e98a2d6e
PP
2226{
2227 int ret = 0;
2228 GQuark qdummy_id;
50842bdc 2229 _BT_FIELD_TYPE_INIT(integer_decl);
e98a2d6e
PP
2230
2231 *enum_decl = NULL;
2232
2233 /* For named enum (without body), lookup in declaration scope */
2234 if (!has_body) {
50842bdc 2235 _BT_FIELD_TYPE_INIT(enum_decl_copy);
e98a2d6e
PP
2236
2237 if (!name) {
28973adf 2238 BT_LOGE_STR("Bodyless enumeration field type: missing name.");
e98a2d6e
PP
2239 ret = -EPERM;
2240 goto error;
2241 }
2242
2243 *enum_decl = ctx_decl_scope_lookup_enum(ctx->current_scope,
2244 name, -1);
2245 if (!*enum_decl) {
08da4f77
PP
2246 BT_LOGE("Cannot find enumeration field type: "
2247 "name=\"enum %s\"", name);
e98a2d6e
PP
2248 ret = -EINVAL;
2249 goto error;
2250 }
2251
2252 /* Make a copy of it */
50842bdc 2253 enum_decl_copy = bt_field_type_copy(*enum_decl);
e98a2d6e 2254 if (!enum_decl_copy) {
08da4f77 2255 BT_LOGE_STR("Cannot create copy of enumeration field type.");
e98a2d6e
PP
2256 ret = -EINVAL;
2257 goto error;
2258 }
2259
2260 BT_PUT(*enum_decl);
2261 BT_MOVE(*enum_decl, enum_decl_copy);
2262 } else {
2263 struct ctf_node *iter;
2264 int64_t last_value = 0;
2265
2266 if (name) {
50842bdc 2267 _BT_FIELD_TYPE_INIT(eenum_decl);
e98a2d6e
PP
2268
2269 eenum_decl = ctx_decl_scope_lookup_enum(
2270 ctx->current_scope, name, 1);
2271 if (eenum_decl) {
2272 BT_PUT(eenum_decl);
08da4f77
PP
2273 BT_LOGE("Enumeration field type already declared in local scope: "
2274 "name=\"enum %s\"", name);
e98a2d6e
PP
2275 ret = -EINVAL;
2276 goto error;
2277 }
2278 }
2279
2280 if (!container_type) {
2281 integer_decl = ctx_decl_scope_lookup_alias(
2282 ctx->current_scope, "int", -1);
2283 if (!integer_decl) {
08da4f77 2284 BT_LOGE_STR("Cannot find implicit `int` field type alias for enumeration field type.");
e98a2d6e
PP
2285 ret = -EINVAL;
2286 goto error;
2287 }
2288 } else {
2289 ret = visit_type_declarator(ctx, container_type,
2290 &qdummy_id, NULL, &integer_decl, NULL);
2291 if (ret) {
2292 assert(!integer_decl);
2293 ret = -EINVAL;
2294 goto error;
2295 }
2296 }
2297
2298 assert(integer_decl);
2299
50842bdc 2300 if (!bt_field_type_is_integer(integer_decl)) {
08da4f77
PP
2301 BT_LOGE("Container field type for enumeration field type is not an integer field type: "
2302 "ft-id=%s",
50842bdc
PP
2303 bt_field_type_id_string(
2304 bt_field_type_get_type_id(integer_decl)));
e98a2d6e
PP
2305 ret = -EINVAL;
2306 goto error;
2307 }
2308
50842bdc 2309 *enum_decl = bt_field_type_enumeration_create(integer_decl);
e98a2d6e 2310 if (!*enum_decl) {
08da4f77 2311 BT_LOGE_STR("Cannot create enumeration field type.");
e98a2d6e
PP
2312 ret = -ENOMEM;
2313 goto error;
2314 }
2315
2316 bt_list_for_each_entry(iter, enumerator_list, siblings) {
2317 ret = visit_enum_decl_entry(ctx, iter, *enum_decl,
2318 &last_value,
50842bdc 2319 bt_field_type_integer_is_signed(integer_decl));
e98a2d6e 2320 if (ret) {
28973adf
PP
2321 _BT_LOGE_NODE(iter,
2322 "Cannot visit enumeration field type entry: "
2323 "ret=%d", ret);
e98a2d6e
PP
2324 goto error;
2325 }
2326 }
2327
2328 if (name) {
2329 ret = ctx_decl_scope_register_enum(ctx->current_scope,
2330 name, *enum_decl);
2331 if (ret) {
28973adf
PP
2332 BT_LOGE("Cannot register enumeration field type in declaration scope: "
2333 "ret=%d", ret);
e98a2d6e
PP
2334 goto error;
2335 }
2336 }
2337 }
2338
2339 BT_PUT(integer_decl);
2340
2341 return 0;
2342
2343error:
2344 BT_PUT(integer_decl);
2345 BT_PUT(*enum_decl);
2346
2347 return ret;
2348}
2349
2350static
2351int visit_type_specifier(struct ctx *ctx,
2352 struct ctf_node *type_specifier_list,
50842bdc 2353 struct bt_field_type **decl)
e98a2d6e
PP
2354{
2355 int ret = 0;
2356 GString *str = NULL;
50842bdc 2357 _BT_FIELD_TYPE_INIT(decl_copy);
e98a2d6e
PP
2358
2359 *decl = NULL;
2360 str = g_string_new("");
2361 ret = get_type_specifier_list_name(ctx, type_specifier_list, str);
2362 if (ret) {
28973adf
PP
2363 _BT_LOGE_NODE(type_specifier_list,
2364 "Cannot get type specifier list's name: ret=%d", ret);
e98a2d6e
PP
2365 goto error;
2366 }
2367
2368 *decl = ctx_decl_scope_lookup_alias(ctx->current_scope, str->str, -1);
2369 if (!*decl) {
28973adf
PP
2370 _BT_LOGE_NODE(type_specifier_list,
2371 "Cannot find type alias: name=\"%s\"", str->str);
e98a2d6e
PP
2372 ret = -EINVAL;
2373 goto error;
2374 }
2375
2376 /* Make a copy of the type declaration */
50842bdc 2377 decl_copy = bt_field_type_copy(*decl);
e98a2d6e 2378 if (!decl_copy) {
28973adf
PP
2379 _BT_LOGE_NODE(type_specifier_list,
2380 "Cannot create field type copy.");
e98a2d6e
PP
2381 ret = -EINVAL;
2382 goto error;
2383 }
2384
2385 BT_MOVE(*decl, decl_copy);
2386 (void) g_string_free(str, TRUE);
2387 str = NULL;
2388
2389 return 0;
2390
2391error:
2392 if (str) {
2393 (void) g_string_free(str, TRUE);
2394 }
2395
2396 BT_PUT(*decl);
2397
2398 return ret;
2399}
2400
2401static
2402int visit_integer_decl(struct ctx *ctx,
2403 struct bt_list_head *expressions,
50842bdc 2404 struct bt_field_type **integer_decl)
e98a2d6e
PP
2405{
2406 int set = 0;
2407 int ret = 0;
50842bdc 2408 bt_bool signedness = 0;
e98a2d6e
PP
2409 struct ctf_node *expression;
2410 uint64_t alignment = 0, size = 0;
50842bdc
PP
2411 struct bt_clock_class *mapped_clock = NULL;
2412 enum bt_string_encoding encoding = BT_STRING_ENCODING_NONE;
2413 enum bt_integer_base base = BT_INTEGER_BASE_DECIMAL;
2414 enum bt_byte_order byte_order =
2415 bt_trace_get_native_byte_order(ctx->trace);
e98a2d6e
PP
2416
2417 *integer_decl = NULL;
2418
2419 bt_list_for_each_entry(expression, expressions, siblings) {
2420 struct ctf_node *left, *right;
2421
2422 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2423 struct ctf_node, siblings);
2424 right = _BT_LIST_FIRST_ENTRY(
2425 &expression->u.ctf_expression.right, struct ctf_node,
2426 siblings);
2427
2428 if (left->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2429 _BT_LOGE_NODE(left,
2430 "Unexpected unary expression type: type=%d",
2431 left->u.unary_expression.type);
e98a2d6e
PP
2432 ret = -EINVAL;
2433 goto error;
2434 }
2435
2436 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
2437 if (_IS_SET(&set, _INTEGER_SIGNED_SET)) {
28973adf 2438 _BT_LOGE_DUP_ATTR(left, "signed",
08da4f77 2439 "integer field type");
e98a2d6e
PP
2440 ret = -EPERM;
2441 goto error;
2442 }
2443
55314f2a 2444 signedness = get_boolean(right);
e98a2d6e 2445 if (signedness < 0) {
28973adf
PP
2446 _BT_LOGE_NODE(right,
2447 "Invalid boolean value for integer field type's `signed` attribute: "
2448 "ret=%d", ret);
e98a2d6e
PP
2449 ret = -EINVAL;
2450 goto error;
2451 }
2452
2453 _SET(&set, _INTEGER_SIGNED_SET);
2454 } else if (!strcmp(left->u.unary_expression.u.string,
2455 "byte_order")) {
2456 if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) {
28973adf 2457 _BT_LOGE_DUP_ATTR(left, "byte_order",
08da4f77 2458 "integer field type");
e98a2d6e
PP
2459 ret = -EPERM;
2460 goto error;
2461 }
2462
2463 byte_order = get_real_byte_order(ctx, right);
50842bdc 2464 if (byte_order == BT_BYTE_ORDER_UNKNOWN) {
28973adf
PP
2465 _BT_LOGE_NODE(right,
2466 "Invalid `byte_order` attribute in integer field type: "
08da4f77 2467 "ret=%d", ret);
e98a2d6e
PP
2468 ret = -EINVAL;
2469 goto error;
2470 }
2471
2472 _SET(&set, _INTEGER_BYTE_ORDER_SET);
2473 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
2474 if (_IS_SET(&set, _INTEGER_SIZE_SET)) {
28973adf 2475 _BT_LOGE_DUP_ATTR(left, "size",
08da4f77 2476 "integer field type");
e98a2d6e
PP
2477 ret = -EPERM;
2478 goto error;
2479 }
2480
2481 if (right->u.unary_expression.type !=
2482 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2483 _BT_LOGE_NODE(right,
2484 "Invalid `size` attribute in integer field type: "
08da4f77
PP
2485 "expecting unsigned constant integer: "
2486 "node-type=%d",
2487 right->u.unary_expression.type);
e98a2d6e
PP
2488 ret = -EINVAL;
2489 goto error;
2490 }
2491
2492 size = right->u.unary_expression.u.unsigned_constant;
2493 if (size == 0) {
28973adf
PP
2494 _BT_LOGE_NODE(right,
2495 "Invalid `size` attribute in integer field type: "
08da4f77
PP
2496 "expecting positive constant integer: "
2497 "size=%" PRIu64, size);
e98a2d6e
PP
2498 ret = -EINVAL;
2499 goto error;
2500 } else if (size > 64) {
28973adf
PP
2501 _BT_LOGE_NODE(right,
2502 "Invalid `size` attribute in integer field type: "
08da4f77
PP
2503 "integer fields over 64 bits are not supported as of this version: "
2504 "size=%" PRIu64, size);
e98a2d6e
PP
2505 ret = -EINVAL;
2506 goto error;
2507 }
2508
2509 _SET(&set, _INTEGER_SIZE_SET);
2510 } else if (!strcmp(left->u.unary_expression.u.string,
2511 "align")) {
2512 if (_IS_SET(&set, _INTEGER_ALIGN_SET)) {
28973adf 2513 _BT_LOGE_DUP_ATTR(left, "align",
08da4f77 2514 "integer field type");
e98a2d6e
PP
2515 ret = -EPERM;
2516 goto error;
2517 }
2518
2519 if (right->u.unary_expression.type !=
2520 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2521 _BT_LOGE_NODE(right,
2522 "Invalid `align` attribute in integer field type: "
08da4f77
PP
2523 "expecting unsigned constant integer: "
2524 "node-type=%d",
2525 right->u.unary_expression.type);
e98a2d6e
PP
2526 ret = -EINVAL;
2527 goto error;
2528 }
2529
2530 alignment =
2531 right->u.unary_expression.u.unsigned_constant;
2532 if (!is_align_valid(alignment)) {
28973adf
PP
2533 _BT_LOGE_NODE(right,
2534 "Invalid `align` attribute in integer field type: "
08da4f77
PP
2535 "expecting power of two: "
2536 "align=%" PRIu64, alignment);
e98a2d6e
PP
2537 ret = -EINVAL;
2538 goto error;
2539 }
2540
2541 _SET(&set, _INTEGER_ALIGN_SET);
2542 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
2543 if (_IS_SET(&set, _INTEGER_BASE_SET)) {
28973adf
PP
2544 _BT_LOGE_DUP_ATTR(left, "base",
2545 "integer field type");
e98a2d6e
PP
2546 ret = -EPERM;
2547 goto error;
2548 }
2549
2550 switch (right->u.unary_expression.type) {
2551 case UNARY_UNSIGNED_CONSTANT:
2552 {
2553 uint64_t constant = right->u.unary_expression.
2554 u.unsigned_constant;
2555
2556 switch (constant) {
2557 case 2:
50842bdc 2558 base = BT_INTEGER_BASE_BINARY;
e98a2d6e
PP
2559 break;
2560 case 8:
50842bdc 2561 base = BT_INTEGER_BASE_OCTAL;
e98a2d6e
PP
2562 break;
2563 case 10:
50842bdc 2564 base = BT_INTEGER_BASE_DECIMAL;
e98a2d6e
PP
2565 break;
2566 case 16:
50842bdc 2567 base = BT_INTEGER_BASE_HEXADECIMAL;
e98a2d6e
PP
2568 break;
2569 default:
28973adf
PP
2570 _BT_LOGE_NODE(right,
2571 "Invalid `base` attribute in integer field type: "
08da4f77 2572 "base=%" PRIu64,
e98a2d6e
PP
2573 right->u.unary_expression.u.unsigned_constant);
2574 ret = -EINVAL;
2575 goto error;
2576 }
2577 break;
2578 }
2579 case UNARY_STRING:
2580 {
2581 char *s_right = concatenate_unary_strings(
2582 &expression->u.ctf_expression.right);
2583 if (!s_right) {
28973adf
PP
2584 _BT_LOGE_NODE(right,
2585 "Unexpected unary expression for integer field type's `base` attribute.");
e98a2d6e
PP
2586 ret = -EINVAL;
2587 goto error;
2588 }
2589
2590 if (!strcmp(s_right, "decimal") ||
2591 !strcmp(s_right, "dec") ||
2592 !strcmp(s_right, "d") ||
2593 !strcmp(s_right, "i") ||
2594 !strcmp(s_right, "u")) {
50842bdc 2595 base = BT_INTEGER_BASE_DECIMAL;
e98a2d6e
PP
2596 } else if (!strcmp(s_right, "hexadecimal") ||
2597 !strcmp(s_right, "hex") ||
2598 !strcmp(s_right, "x") ||
2599 !strcmp(s_right, "X") ||
2600 !strcmp(s_right, "p")) {
50842bdc 2601 base = BT_INTEGER_BASE_HEXADECIMAL;
e98a2d6e
PP
2602 } else if (!strcmp(s_right, "octal") ||
2603 !strcmp(s_right, "oct") ||
2604 !strcmp(s_right, "o")) {
50842bdc 2605 base = BT_INTEGER_BASE_OCTAL;
e98a2d6e
PP
2606 } else if (!strcmp(s_right, "binary") ||
2607 !strcmp(s_right, "b")) {
50842bdc 2608 base = BT_INTEGER_BASE_BINARY;
e98a2d6e 2609 } else {
28973adf
PP
2610 _BT_LOGE_NODE(right,
2611 "Unexpected unary expression for integer field type's `base` attribute: "
08da4f77 2612 "base=\"%s\"", s_right);
e98a2d6e
PP
2613 g_free(s_right);
2614 ret = -EINVAL;
2615 goto error;
2616 }
2617
2618 g_free(s_right);
2619 break;
2620 }
2621 default:
28973adf
PP
2622 _BT_LOGE_NODE(right,
2623 "Invalid `base` attribute in integer field type: "
08da4f77 2624 "expecting unsigned constant integer or unary string.");
e98a2d6e
PP
2625 ret = -EINVAL;
2626 goto error;
2627 }
2628
2629 _SET(&set, _INTEGER_BASE_SET);
2630 } else if (!strcmp(left->u.unary_expression.u.string,
2631 "encoding")) {
2632 char *s_right;
2633
2634 if (_IS_SET(&set, _INTEGER_ENCODING_SET)) {
28973adf 2635 _BT_LOGE_DUP_ATTR(left, "encoding",
08da4f77 2636 "integer field type");
e98a2d6e
PP
2637 ret = -EPERM;
2638 goto error;
2639 }
2640
2641 if (right->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2642 _BT_LOGE_NODE(right,
2643 "Invalid `encoding` attribute in integer field type: "
08da4f77 2644 "expecting unary string.");
e98a2d6e
PP
2645 ret = -EINVAL;
2646 goto error;
2647 }
2648
2649 s_right = concatenate_unary_strings(
2650 &expression->u.ctf_expression.right);
2651 if (!s_right) {
28973adf
PP
2652 _BT_LOGE_NODE(right,
2653 "Unexpected unary expression for integer field type's `encoding` attribute.");
e98a2d6e
PP
2654 ret = -EINVAL;
2655 goto error;
2656 }
2657
2658 if (!strcmp(s_right, "UTF8") ||
2659 !strcmp(s_right, "utf8") ||
2660 !strcmp(s_right, "utf-8") ||
2661 !strcmp(s_right, "UTF-8")) {
50842bdc 2662 encoding = BT_STRING_ENCODING_UTF8;
e98a2d6e
PP
2663 } else if (!strcmp(s_right, "ASCII") ||
2664 !strcmp(s_right, "ascii")) {
50842bdc 2665 encoding = BT_STRING_ENCODING_ASCII;
e98a2d6e 2666 } else if (!strcmp(s_right, "none")) {
50842bdc 2667 encoding = BT_STRING_ENCODING_NONE;
e98a2d6e 2668 } else {
28973adf
PP
2669 _BT_LOGE_NODE(right,
2670 "Invalid `encoding` attribute in integer field type: "
08da4f77 2671 "unknown encoding: encoding=\"%s\"",
e98a2d6e
PP
2672 s_right);
2673 g_free(s_right);
2674 ret = -EINVAL;
2675 goto error;
2676 }
2677
2678 g_free(s_right);
2679 _SET(&set, _INTEGER_ENCODING_SET);
2680 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
2681 const char *clock_name;
2682
2683 if (_IS_SET(&set, _INTEGER_MAP_SET)) {
28973adf
PP
2684 _BT_LOGE_DUP_ATTR(left, "map",
2685 "integer field type");
e98a2d6e
PP
2686 ret = -EPERM;
2687 goto error;
2688 }
2689
2690 if (right->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2691 _BT_LOGE_NODE(right,
2692 "Invalid `map` attribute in integer field type: "
08da4f77 2693 "expecting unary string.");
e98a2d6e
PP
2694 ret = -EINVAL;
2695 goto error;
2696 }
2697
2698 clock_name =
2699 get_map_clock_name_value(
2700 &expression->u.ctf_expression.right);
2701 if (!clock_name) {
2702 char *s_right = concatenate_unary_strings(
2703 &expression->u.ctf_expression.right);
2704
2705 if (!s_right) {
28973adf
PP
2706 _BT_LOGE_NODE(right,
2707 "Unexpected unary expression for integer field type's `map` attribute.");
e98a2d6e
PP
2708 ret = -EINVAL;
2709 goto error;
2710 }
2711
28973adf
PP
2712 _BT_LOGE_NODE(right,
2713 "Invalid `map` attribute in integer field type: "
08da4f77 2714 "cannot find clock class at this point: name=\"%s\"",
e98a2d6e
PP
2715 s_right);
2716 _SET(&set, _INTEGER_MAP_SET);
2717 g_free(s_right);
2718 continue;
2719 }
2720
50842bdc 2721 mapped_clock = bt_trace_get_clock_class_by_name(
e98a2d6e
PP
2722 ctx->trace, clock_name);
2723 if (!mapped_clock) {
28973adf
PP
2724 _BT_LOGE_NODE(right,
2725 "Invalid `map` attribute in integer field type: "
08da4f77 2726 "cannot find clock class at this point: name=\"%s\"",
e98a2d6e
PP
2727 clock_name);
2728 ret = -EINVAL;
2729 goto error;
2730 }
2731
2732 _SET(&set, _INTEGER_MAP_SET);
2733 } else {
28973adf
PP
2734 _BT_LOGW_NODE(left,
2735 "Unknown attribute in integer field type: "
08da4f77 2736 "attr-name=\"%s\"",
e98a2d6e
PP
2737 left->u.unary_expression.u.string);
2738 }
2739 }
2740
2741 if (!_IS_SET(&set, _INTEGER_SIZE_SET)) {
08da4f77 2742 BT_LOGE_STR("Missing `size` attribute in integer field type.");
e98a2d6e
PP
2743 ret = -EPERM;
2744 goto error;
2745 }
2746
2747 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2748 if (size % CHAR_BIT) {
2749 /* Bit-packed alignment */
2750 alignment = 1;
2751 } else {
2752 /* Byte-packed alignment */
2753 alignment = CHAR_BIT;
2754 }
2755 }
2756
50842bdc 2757 *integer_decl = bt_field_type_integer_create((unsigned int) size);
e98a2d6e 2758 if (!*integer_decl) {
08da4f77 2759 BT_LOGE_STR("Cannot create integer field type.");
e98a2d6e
PP
2760 ret = -ENOMEM;
2761 goto error;
2762 }
2763
50842bdc
PP
2764 ret = bt_field_type_integer_set_is_signed(*integer_decl, signedness);
2765 ret |= bt_field_type_integer_set_base(*integer_decl, base);
2766 ret |= bt_field_type_integer_set_encoding(*integer_decl, encoding);
2767 ret |= bt_field_type_set_alignment(*integer_decl,
e98a2d6e 2768 (unsigned int) alignment);
50842bdc 2769 ret |= bt_field_type_set_byte_order(*integer_decl, byte_order);
e98a2d6e
PP
2770
2771 if (mapped_clock) {
2772 /* Move clock */
50842bdc 2773 ret |= bt_field_type_integer_set_mapped_clock_class(
e98a2d6e
PP
2774 *integer_decl, mapped_clock);
2775 bt_put(mapped_clock);
2776 mapped_clock = NULL;
2777 }
2778
2779 if (ret) {
08da4f77 2780 BT_LOGE_STR("Cannot configure integer field type.");
e98a2d6e
PP
2781 ret = -EINVAL;
2782 goto error;
2783 }
2784
2785 return 0;
2786
2787error:
2788 if (mapped_clock) {
2789 bt_put(mapped_clock);
2790 }
2791
2792 BT_PUT(*integer_decl);
2793
2794 return ret;
2795}
2796
2797static
2798int visit_floating_point_number_decl(struct ctx *ctx,
2799 struct bt_list_head *expressions,
50842bdc 2800 struct bt_field_type **float_decl)
e98a2d6e
PP
2801{
2802 int set = 0;
2803 int ret = 0;
2804 struct ctf_node *expression;
2805 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
50842bdc
PP
2806 enum bt_byte_order byte_order =
2807 bt_trace_get_native_byte_order(ctx->trace);
e98a2d6e
PP
2808
2809 *float_decl = NULL;
2810
2811 bt_list_for_each_entry(expression, expressions, siblings) {
2812 struct ctf_node *left, *right;
2813
2814 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2815 struct ctf_node, siblings);
2816 right = _BT_LIST_FIRST_ENTRY(
2817 &expression->u.ctf_expression.right, struct ctf_node,
2818 siblings);
2819
2820 if (left->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
2821 _BT_LOGE_NODE(left,
2822 "Unexpected unary expression type: type=%d",
2823 left->u.unary_expression.type);
e98a2d6e
PP
2824 ret = -EINVAL;
2825 goto error;
2826 }
2827
2828 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
2829 if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) {
28973adf 2830 _BT_LOGE_DUP_ATTR(left, "byte_order",
08da4f77 2831 "floating point number field type");
e98a2d6e
PP
2832 ret = -EPERM;
2833 goto error;
2834 }
2835
2836 byte_order = get_real_byte_order(ctx, right);
50842bdc 2837 if (byte_order == BT_BYTE_ORDER_UNKNOWN) {
28973adf
PP
2838 _BT_LOGE_NODE(right,
2839 "Invalid `byte_order` attribute in floating point number field type: "
08da4f77 2840 "ret=%d", ret);
e98a2d6e
PP
2841 ret = -EINVAL;
2842 goto error;
2843 }
2844
2845 _SET(&set, _FLOAT_BYTE_ORDER_SET);
2846 } else if (!strcmp(left->u.unary_expression.u.string,
2847 "exp_dig")) {
2848 if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
28973adf 2849 _BT_LOGE_DUP_ATTR(left, "exp_dig",
08da4f77 2850 "floating point number field type");
e98a2d6e
PP
2851 ret = -EPERM;
2852 goto error;
2853 }
2854
2855 if (right->u.unary_expression.type !=
2856 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2857 _BT_LOGE_NODE(right,
2858 "Invalid `exp_dig` attribute in floating point number field type: "
08da4f77
PP
2859 "expecting unsigned constant integer: "
2860 "node-type=%d",
2861 right->u.unary_expression.type);
e98a2d6e
PP
2862 ret = -EINVAL;
2863 goto error;
2864 }
2865
2866 exp_dig = right->u.unary_expression.u.unsigned_constant;
2867 _SET(&set, _FLOAT_EXP_DIG_SET);
2868 } else if (!strcmp(left->u.unary_expression.u.string,
2869 "mant_dig")) {
2870 if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
28973adf 2871 _BT_LOGE_DUP_ATTR(left, "mant_dig",
08da4f77 2872 "floating point number field type");
e98a2d6e
PP
2873 ret = -EPERM;
2874 goto error;
2875 }
2876
2877 if (right->u.unary_expression.type !=
2878 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2879 _BT_LOGE_NODE(right,
2880 "Invalid `mant_dig` attribute in floating point number field type: "
08da4f77
PP
2881 "expecting unsigned constant integer: "
2882 "node-type=%d",
2883 right->u.unary_expression.type);
e98a2d6e
PP
2884 ret = -EINVAL;
2885 goto error;
2886 }
2887
2888 mant_dig = right->u.unary_expression.u.
2889 unsigned_constant;
2890 _SET(&set, _FLOAT_MANT_DIG_SET);
2891 } else if (!strcmp(left->u.unary_expression.u.string,
2892 "align")) {
2893 if (_IS_SET(&set, _FLOAT_ALIGN_SET)) {
28973adf 2894 _BT_LOGE_DUP_ATTR(left, "align",
08da4f77 2895 "floating point number field type");
e98a2d6e
PP
2896 ret = -EPERM;
2897 goto error;
2898 }
2899
2900 if (right->u.unary_expression.type !=
2901 UNARY_UNSIGNED_CONSTANT) {
28973adf
PP
2902 _BT_LOGE_NODE(right,
2903 "Invalid `align` attribute in floating point number field type: "
08da4f77
PP
2904 "expecting unsigned constant integer: "
2905 "node-type=%d",
2906 right->u.unary_expression.type);
e98a2d6e
PP
2907 ret = -EINVAL;
2908 goto error;
2909 }
2910
2911 alignment = right->u.unary_expression.u.
2912 unsigned_constant;
2913
2914 if (!is_align_valid(alignment)) {
28973adf
PP
2915 _BT_LOGE_NODE(right,
2916 "Invalid `align` attribute in floating point number field type: "
08da4f77
PP
2917 "expecting power of two: "
2918 "align=%" PRIu64, alignment);
e98a2d6e
PP
2919 ret = -EINVAL;
2920 goto error;
2921 }
2922
2923 _SET(&set, _FLOAT_ALIGN_SET);
2924 } else {
28973adf
PP
2925 _BT_LOGW_NODE(left,
2926 "Unknown attribute in floating point number field type: "
08da4f77 2927 "attr-name=\"%s\"",
e98a2d6e
PP
2928 left->u.unary_expression.u.string);
2929 }
2930 }
2931
2932 if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
08da4f77 2933 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field type.");
e98a2d6e
PP
2934 ret = -EPERM;
2935 goto error;
2936 }
2937
2938 if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
08da4f77 2939 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field type.");
e98a2d6e
PP
2940 ret = -EPERM;
2941 goto error;
2942 }
2943
2944 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2945 if ((mant_dig + exp_dig) % CHAR_BIT) {
2946 /* Bit-packed alignment */
2947 alignment = 1;
2948 } else {
2949 /* Byte-packed alignment */
2950 alignment = CHAR_BIT;
2951 }
2952 }
2953
50842bdc 2954 *float_decl = bt_field_type_floating_point_create();
e98a2d6e 2955 if (!*float_decl) {
08da4f77 2956 BT_LOGE_STR("Cannot create floating point number field type.");
e98a2d6e
PP
2957 ret = -ENOMEM;
2958 goto error;
2959 }
2960
50842bdc 2961 ret = bt_field_type_floating_point_set_exponent_digits(
e98a2d6e 2962 *float_decl, exp_dig);
50842bdc 2963 ret |= bt_field_type_floating_point_set_mantissa_digits(
e98a2d6e 2964 *float_decl, mant_dig);
50842bdc
PP
2965 ret |= bt_field_type_set_byte_order(*float_decl, byte_order);
2966 ret |= bt_field_type_set_alignment(*float_decl, alignment);
e98a2d6e 2967 if (ret) {
08da4f77 2968 BT_LOGE_STR("Cannot configure floating point number field type.");
e98a2d6e
PP
2969 ret = -EINVAL;
2970 goto error;
2971 }
2972
2973 return 0;
2974
2975error:
2976 BT_PUT(*float_decl);
2977
2978 return ret;
2979}
2980
2981static
2982int visit_string_decl(struct ctx *ctx,
2983 struct bt_list_head *expressions,
50842bdc 2984 struct bt_field_type **string_decl)
e98a2d6e
PP
2985{
2986 int set = 0;
2987 int ret = 0;
2988 struct ctf_node *expression;
50842bdc 2989 enum bt_string_encoding encoding = BT_STRING_ENCODING_UTF8;
e98a2d6e
PP
2990
2991 *string_decl = NULL;
2992
2993 bt_list_for_each_entry(expression, expressions, siblings) {
2994 struct ctf_node *left, *right;
2995
2996 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2997 struct ctf_node, siblings);
2998 right = _BT_LIST_FIRST_ENTRY(
2999 &expression->u.ctf_expression.right, struct ctf_node,
3000 siblings);
3001
3002 if (left->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
3003 _BT_LOGE_NODE(left,
3004 "Unexpected unary expression type: type=%d",
3005 left->u.unary_expression.type);
e98a2d6e
PP
3006 ret = -EINVAL;
3007 goto error;
3008 }
3009
3010 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
3011 char *s_right;
3012
3013 if (_IS_SET(&set, _STRING_ENCODING_SET)) {
28973adf 3014 _BT_LOGE_DUP_ATTR(left, "encoding",
08da4f77 3015 "string field type");
e98a2d6e
PP
3016 ret = -EPERM;
3017 goto error;
3018 }
3019
3020 if (right->u.unary_expression.type != UNARY_STRING) {
28973adf
PP
3021 _BT_LOGE_NODE(right,
3022 "Invalid `encoding` attribute in string field type: "
08da4f77 3023 "expecting unary string.");
e98a2d6e
PP
3024 ret = -EINVAL;
3025 goto error;
3026 }
3027
3028 s_right = concatenate_unary_strings(
3029 &expression->u.ctf_expression.right);
3030 if (!s_right) {
28973adf
PP
3031 _BT_LOGE_NODE(right,
3032 "Unexpected unary expression for string field type's `encoding` attribute.");
e98a2d6e
PP
3033 ret = -EINVAL;
3034 goto error;
3035 }
3036
3037 if (!strcmp(s_right, "UTF8") ||
3038 !strcmp(s_right, "utf8") ||
3039 !strcmp(s_right, "utf-8") ||
3040 !strcmp(s_right, "UTF-8")) {
50842bdc 3041 encoding = BT_STRING_ENCODING_UTF8;
e98a2d6e
PP
3042 } else if (!strcmp(s_right, "ASCII") ||
3043 !strcmp(s_right, "ascii")) {
50842bdc 3044 encoding = BT_STRING_ENCODING_ASCII;
e98a2d6e 3045 } else if (!strcmp(s_right, "none")) {
50842bdc 3046 encoding = BT_STRING_ENCODING_NONE;
e98a2d6e 3047 } else {
28973adf
PP
3048 _BT_LOGE_NODE(right,
3049 "Invalid `encoding` attribute in string field type: "
08da4f77 3050 "unknown encoding: encoding=\"%s\"",
e98a2d6e
PP
3051 s_right);
3052 g_free(s_right);
3053 ret = -EINVAL;
3054 goto error;
3055 }
3056
3057 g_free(s_right);
3058 _SET(&set, _STRING_ENCODING_SET);
3059 } else {
28973adf
PP
3060 _BT_LOGW_NODE(left,
3061 "Unknown attribute in string field type: "
08da4f77 3062 "attr-name=\"%s\"",
e98a2d6e
PP
3063 left->u.unary_expression.u.string);
3064 }
3065 }
3066
50842bdc 3067 *string_decl = bt_field_type_string_create();
e98a2d6e 3068 if (!*string_decl) {
08da4f77 3069 BT_LOGE_STR("Cannot create string field type.");
e98a2d6e
PP
3070 ret = -ENOMEM;
3071 goto error;
3072 }
3073
50842bdc 3074 ret = bt_field_type_string_set_encoding(*string_decl, encoding);
e98a2d6e 3075 if (ret) {
08da4f77 3076 BT_LOGE_STR("Cannot configure string field type.");
e98a2d6e
PP
3077 ret = -EINVAL;
3078 goto error;
3079 }
3080
3081 return 0;
3082
3083error:
3084 BT_PUT(*string_decl);
3085
3086 return ret;
3087}
3088
3089static
3090int visit_type_specifier_list(struct ctx *ctx,
3091 struct ctf_node *ts_list,
50842bdc 3092 struct bt_field_type **decl)
e98a2d6e
PP
3093{
3094 int ret = 0;
3095 struct ctf_node *first, *node;
3096
3097 *decl = NULL;
3098
3099 if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) {
28973adf
PP
3100 _BT_LOGE_NODE(ts_list,
3101 "Unexpected node type: node-type=%d", ts_list->type);
e98a2d6e
PP
3102 ret = -EINVAL;
3103 goto error;
3104 }
3105
3106 first = _BT_LIST_FIRST_ENTRY(&ts_list->u.type_specifier_list.head,
3107 struct ctf_node, siblings);
3108 if (first->type != NODE_TYPE_SPECIFIER) {
28973adf
PP
3109 _BT_LOGE_NODE(first,
3110 "Unexpected node type: node-type=%d", first->type);
e98a2d6e
PP
3111 ret = -EINVAL;
3112 goto error;
3113 }
3114
3115 node = first->u.type_specifier.node;
3116
3117 switch (first->u.type_specifier.type) {
3118 case TYPESPEC_INTEGER:
3119 ret = visit_integer_decl(ctx, &node->u.integer.expressions,
3120 decl);
3121 if (ret) {
3122 assert(!*decl);
3123 goto error;
3124 }
3125 break;
3126 case TYPESPEC_FLOATING_POINT:
3127 ret = visit_floating_point_number_decl(ctx,
3128 &node->u.floating_point.expressions, decl);
3129 if (ret) {
3130 assert(!*decl);
3131 goto error;
3132 }
3133 break;
3134 case TYPESPEC_STRING:
3135 ret = visit_string_decl(ctx,
3136 &node->u.string.expressions, decl);
3137 if (ret) {
3138 assert(!*decl);
3139 goto error;
3140 }
3141 break;
3142 case TYPESPEC_STRUCT:
3143 ret = visit_struct_decl(ctx, node->u._struct.name,
3144 &node->u._struct.declaration_list,
3145 node->u._struct.has_body,
3146 &node->u._struct.min_align, decl);
3147 if (ret) {
3148 assert(!*decl);
3149 goto error;
3150 }
3151 break;
3152 case TYPESPEC_VARIANT:
3153 ret = visit_variant_decl(ctx, node->u.variant.name,
3154 node->u.variant.choice,
3155 &node->u.variant.declaration_list,
3156 node->u.variant.has_body, decl);
3157 if (ret) {
3158 assert(!*decl);
3159 goto error;
3160 }
3161 break;
3162 case TYPESPEC_ENUM:
3163 ret = visit_enum_decl(ctx, node->u._enum.enum_id,
3164 node->u._enum.container_type,
3165 &node->u._enum.enumerator_list,
3166 node->u._enum.has_body, decl);
3167 if (ret) {
3168 assert(!*decl);
3169 goto error;
3170 }
3171 break;
3172 case TYPESPEC_VOID:
3173 case TYPESPEC_CHAR:
3174 case TYPESPEC_SHORT:
3175 case TYPESPEC_INT:
3176 case TYPESPEC_LONG:
3177 case TYPESPEC_FLOAT:
3178 case TYPESPEC_DOUBLE:
3179 case TYPESPEC_SIGNED:
3180 case TYPESPEC_UNSIGNED:
3181 case TYPESPEC_BOOL:
3182 case TYPESPEC_COMPLEX:
3183 case TYPESPEC_IMAGINARY:
3184 case TYPESPEC_CONST:
3185 case TYPESPEC_ID_TYPE:
3186 ret = visit_type_specifier(ctx, ts_list, decl);
3187 if (ret) {
28973adf
PP
3188 _BT_LOGE_NODE(first,
3189 "Cannot visit type specifier: ret=%d",
3190 ret);
e98a2d6e
PP
3191 assert(!*decl);
3192 goto error;
3193 }
3194 break;
3195 default:
28973adf
PP
3196 _BT_LOGE_NODE(first,
3197 "Unexpected type specifier type: node-type=%d",
08da4f77 3198 first->u.type_specifier.type);
e98a2d6e
PP
3199 ret = -EINVAL;
3200 goto error;
3201 }
3202
3203 assert(*decl);
3204
3205 return 0;
3206
3207error:
3208 BT_PUT(*decl);
3209
3210 return ret;
3211}
3212
3213static
3214int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
50842bdc 3215 struct bt_event_class *event_class, int64_t *stream_id,
e98a2d6e
PP
3216 int *set)
3217{
3218 int ret = 0;
3219 char *left = NULL;
50842bdc 3220 _BT_FIELD_TYPE_INIT(decl);
e98a2d6e
PP
3221
3222 switch (node->type) {
3223 case NODE_TYPEDEF:
3224 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
3225 &node->u._typedef.type_declarators);
3226 if (ret) {
28973adf
PP
3227 _BT_LOGE_NODE(node,
3228 "Cannot add type definition found in event class.");
e98a2d6e
PP
3229 goto error;
3230 }
3231 break;
3232 case NODE_TYPEALIAS:
3233 ret = visit_typealias(ctx, node->u.typealias.target,
3234 node->u.typealias.alias);
3235 if (ret) {
28973adf
PP
3236 _BT_LOGE_NODE(node,
3237 "Cannot add type alias found in event class.");
e98a2d6e
PP
3238 goto error;
3239 }
3240 break;
3241 case NODE_CTF_EXPRESSION:
3242 {
3243 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3244 if (!left) {
28973adf 3245 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
3246 ret = -EINVAL;
3247 goto error;
3248 }
3249
3250 if (!strcmp(left, "name")) {
3251 /* This is already known at this stage */
3252 if (_IS_SET(set, _EVENT_NAME_SET)) {
28973adf
PP
3253 _BT_LOGE_DUP_ATTR(node, "name",
3254 "event class");
e98a2d6e
PP
3255 ret = -EPERM;
3256 goto error;
3257 }
3258
3259 _SET(set, _EVENT_NAME_SET);
3260 } else if (!strcmp(left, "id")) {
bc85036f 3261 int64_t id = -1;
e98a2d6e
PP
3262
3263 if (_IS_SET(set, _EVENT_ID_SET)) {
28973adf
PP
3264 _BT_LOGE_DUP_ATTR(node, "id",
3265 "event class");
e98a2d6e
PP
3266 ret = -EPERM;
3267 goto error;
3268 }
3269
3270 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3271 (uint64_t *) &id);
5eae0c3c
JG
3272 /* Only read "id" if get_unary_unsigned() succeeded. */
3273 if (ret || (!ret && id < 0)) {
28973adf
PP
3274 _BT_LOGE_NODE(node,
3275 "Unexpected unary expression for event class's `id` attribute.");
e98a2d6e
PP
3276 ret = -EINVAL;
3277 goto error;
3278 }
3279
50842bdc 3280 ret = bt_event_class_set_id(event_class, id);
e98a2d6e 3281 if (ret) {
28973adf
PP
3282 _BT_LOGE_NODE(node,
3283 "Cannot set event class's ID: "
08da4f77 3284 "id=%" PRId64, id);
e98a2d6e
PP
3285 goto error;
3286 }
3287
3288 _SET(set, _EVENT_ID_SET);
3289 } else if (!strcmp(left, "stream_id")) {
3290 if (_IS_SET(set, _EVENT_STREAM_ID_SET)) {
28973adf 3291 _BT_LOGE_DUP_ATTR(node, "stream_id",
08da4f77 3292 "event class");
e98a2d6e
PP
3293 ret = -EPERM;
3294 goto error;
3295 }
3296
3297 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3298 (uint64_t *) stream_id);
5eae0c3c
JG
3299 /*
3300 * Only read "stream_id" if get_unary_unsigned()
3301 * succeeded.
3302 */
3303 if (ret || (!ret && *stream_id < 0)) {
28973adf
PP
3304 _BT_LOGE_NODE(node,
3305 "Unexpected unary expression for event class's `stream_id` attribute.");
e98a2d6e
PP
3306 ret = -EINVAL;
3307 goto error;
3308 }
3309
3310 _SET(set, _EVENT_STREAM_ID_SET);
3311 } else if (!strcmp(left, "context")) {
3312 if (_IS_SET(set, _EVENT_CONTEXT_SET)) {
28973adf
PP
3313 _BT_LOGE_NODE(node,
3314 "Duplicate `context` entry in event class.");
e98a2d6e
PP
3315 ret = -EPERM;
3316 goto error;
3317 }
3318
3319 ret = visit_type_specifier_list(ctx,
3320 _BT_LIST_FIRST_ENTRY(
3321 &node->u.ctf_expression.right,
3322 struct ctf_node, siblings),
3323 &decl);
3324 if (ret) {
28973adf
PP
3325 _BT_LOGE_NODE(node,
3326 "Cannot create event class's context field type.");
e98a2d6e
PP
3327 goto error;
3328 }
3329
3330 assert(decl);
50842bdc 3331 ret = bt_event_class_set_context_type(
e98a2d6e
PP
3332 event_class, decl);
3333 BT_PUT(decl);
3334 if (ret) {
28973adf
PP
3335 _BT_LOGE_NODE(node,
3336 "Cannot set event class's context field type.");
e98a2d6e
PP
3337 goto error;
3338 }
3339
3340 _SET(set, _EVENT_CONTEXT_SET);
3341 } else if (!strcmp(left, "fields")) {
3342 if (_IS_SET(set, _EVENT_FIELDS_SET)) {
28973adf
PP
3343 _BT_LOGE_NODE(node,
3344 "Duplicate `fields` entry in event class.");
e98a2d6e
PP
3345 ret = -EPERM;
3346 goto error;
3347 }
3348
3349 ret = visit_type_specifier_list(ctx,
3350 _BT_LIST_FIRST_ENTRY(
3351 &node->u.ctf_expression.right,
3352 struct ctf_node, siblings),
3353 &decl);
3354 if (ret) {
28973adf
PP
3355 _BT_LOGE_NODE(node,
3356 "Cannot create event class's payload field type.");
e98a2d6e
PP
3357 goto error;
3358 }
3359
3360 assert(decl);
50842bdc 3361 ret = bt_event_class_set_payload_type(
e98a2d6e
PP
3362 event_class, decl);
3363 BT_PUT(decl);
3364 if (ret) {
28973adf
PP
3365 _BT_LOGE_NODE(node,
3366 "Cannot set event class's payload field type.");
e98a2d6e
PP
3367 goto error;
3368 }
3369
3370 _SET(set, _EVENT_FIELDS_SET);
3371 } else if (!strcmp(left, "loglevel")) {
c3c30b08 3372 uint64_t loglevel_value;
50842bdc
PP
3373 enum bt_event_class_log_level log_level =
3374 BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED;
e98a2d6e
PP
3375
3376 if (_IS_SET(set, _EVENT_LOGLEVEL_SET)) {
28973adf 3377 _BT_LOGE_DUP_ATTR(node, "loglevel",
08da4f77 3378 "event class");
e98a2d6e
PP
3379 ret = -EPERM;
3380 goto error;
3381 }
3382
3383 ret = get_unary_unsigned(&node->u.ctf_expression.right,
c3c30b08 3384 &loglevel_value);
e98a2d6e 3385 if (ret) {
28973adf
PP
3386 _BT_LOGE_NODE(node,
3387 "Unexpected unary expression for event class's `loglevel` attribute.");
e98a2d6e
PP
3388 ret = -EINVAL;
3389 goto error;
3390 }
cf76ce92
PP
3391
3392 switch (loglevel_value) {
3393 case 0:
50842bdc 3394 log_level = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY;
cf76ce92
PP
3395 break;
3396 case 1:
50842bdc 3397 log_level = BT_EVENT_CLASS_LOG_LEVEL_ALERT;
cf76ce92
PP
3398 break;
3399 case 2:
50842bdc 3400 log_level = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL;
cf76ce92
PP
3401 break;
3402 case 3:
50842bdc 3403 log_level = BT_EVENT_CLASS_LOG_LEVEL_ERROR;
cf76ce92
PP
3404 break;
3405 case 4:
50842bdc 3406 log_level = BT_EVENT_CLASS_LOG_LEVEL_WARNING;
cf76ce92
PP
3407 break;
3408 case 5:
50842bdc 3409 log_level = BT_EVENT_CLASS_LOG_LEVEL_NOTICE;
cf76ce92
PP
3410 break;
3411 case 6:
50842bdc 3412 log_level = BT_EVENT_CLASS_LOG_LEVEL_INFO;
cf76ce92
PP
3413 break;
3414 case 7:
50842bdc 3415 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM;
cf76ce92
PP
3416 break;
3417 case 8:
50842bdc 3418 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM;
cf76ce92
PP
3419 break;
3420 case 9:
50842bdc 3421 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS;
cf76ce92
PP
3422 break;
3423 case 10:
50842bdc 3424 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE;
cf76ce92
PP
3425 break;
3426 case 11:
50842bdc 3427 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT;
cf76ce92
PP
3428 break;
3429 case 12:
50842bdc 3430 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION;
cf76ce92
PP
3431 break;
3432 case 13:
50842bdc 3433 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE;
cf76ce92
PP
3434 break;
3435 case 14:
50842bdc 3436 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG;
cf76ce92
PP
3437 break;
3438 default:
3439 _BT_LOGW_NODE(node, "Not setting event class's log level because its value is unknown: "
3440 "log-level=%" PRIu64, loglevel_value);
c3c30b08 3441 }
cf76ce92 3442
50842bdc
PP
3443 if (log_level != BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
3444 ret = bt_event_class_set_log_level(
cf76ce92
PP
3445 event_class, log_level);
3446 if (ret) {
28973adf 3447 _BT_LOGE_NODE(node,
cf76ce92 3448 "Cannot set event class's log level.");
c3c30b08
MD
3449 goto error;
3450 }
c3c30b08 3451 }
cf76ce92 3452
e98a2d6e
PP
3453 _SET(set, _EVENT_LOGLEVEL_SET);
3454 } else if (!strcmp(left, "model.emf.uri")) {
3455 char *right;
3456
3457 if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) {
28973adf
PP
3458 _BT_LOGE_DUP_ATTR(node, "model.emf.uri",
3459 "event class");
e98a2d6e
PP
3460 ret = -EPERM;
3461 goto error;
3462 }
3463
3464 right = concatenate_unary_strings(
3465 &node->u.ctf_expression.right);
3466 if (!right) {
28973adf
PP
3467 _BT_LOGE_NODE(node,
3468 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
e98a2d6e
PP
3469 ret = -EINVAL;
3470 goto error;
3471 }
3472
cf76ce92
PP
3473 if (strlen(right) == 0) {
3474 _BT_LOGW_NODE(node,
3475 "Not setting event class's EMF URI because it's empty.");
3476 } else {
50842bdc 3477 ret = bt_event_class_set_emf_uri(
cf76ce92
PP
3478 event_class, right);
3479 if (ret) {
3480 _BT_LOGE_NODE(node,
3481 "Cannot set event class's EMF URI.");
3482 goto error;
3483 }
28973adf 3484 }
cf76ce92 3485
e98a2d6e
PP
3486 g_free(right);
3487 _SET(set, _EVENT_MODEL_EMF_URI_SET);
3488 } else {
28973adf
PP
3489 _BT_LOGW_NODE(node,
3490 "Unknown attribute in event class: "
08da4f77 3491 "attr-name=\"%s\"", left);
e98a2d6e
PP
3492 }
3493
3494 g_free(left);
3495 left = NULL;
3496 break;
3497 }
3498 default:
3499 ret = -EPERM;
3500 goto error;
3501 }
3502
3503 return 0;
3504
3505error:
3506 if (left) {
3507 g_free(left);
3508 }
3509
3510 BT_PUT(decl);
3511
3512 return ret;
3513}
3514
3515static
3516char *get_event_decl_name(struct ctx *ctx, struct ctf_node *node)
3517{
3518 char *left = NULL;
3519 char *name = NULL;
3520 struct ctf_node *iter;
3521 struct bt_list_head *decl_list = &node->u.event.declaration_list;
3522
3523 bt_list_for_each_entry(iter, decl_list, siblings) {
3524 if (iter->type != NODE_CTF_EXPRESSION) {
3525 continue;
3526 }
3527
3528 left = concatenate_unary_strings(&iter->u.ctf_expression.left);
3529 if (!left) {
28973adf
PP
3530 _BT_LOGE_NODE(iter,
3531 "Cannot concatenate unary strings.");
e98a2d6e
PP
3532 goto error;
3533 }
3534
3535 if (!strcmp(left, "name")) {
3536 name = concatenate_unary_strings(
3537 &iter->u.ctf_expression.right);
3538 if (!name) {
28973adf
PP
3539 _BT_LOGE_NODE(iter,
3540 "Unexpected unary expression for event class's `name` attribute.");
e98a2d6e
PP
3541 goto error;
3542 }
3543 }
3544
3545 g_free(left);
3546 left = NULL;
3547
3548 if (name) {
3549 break;
3550 }
3551 }
3552
3553 return name;
3554
3555error:
3556 g_free(left);
3557
3558 return NULL;
3559}
3560
3561static
3562int reset_event_decl_types(struct ctx *ctx,
50842bdc 3563 struct bt_event_class *event_class)
e98a2d6e
PP
3564{
3565 int ret = 0;
e98a2d6e 3566
835b2d10 3567 /* Context type. */
50842bdc 3568 ret = bt_event_class_set_context_type(event_class, NULL);
e98a2d6e 3569 if (ret) {
28973adf
PP
3570 BT_LOGE("Cannot reset initial event class's context field type: "
3571 "event-name=\"%s\"",
50842bdc 3572 bt_event_class_get_name(event_class));
835b2d10 3573 goto end;
e98a2d6e
PP
3574 }
3575
835b2d10 3576 /* Event payload. */
50842bdc 3577 ret = bt_event_class_set_payload_type(event_class, NULL);
e98a2d6e 3578 if (ret) {
28973adf
PP
3579 BT_LOGE("Cannot reset initial event class's payload field type: "
3580 "event-name=\"%s\"",
50842bdc 3581 bt_event_class_get_name(event_class));
835b2d10 3582 goto end;
e98a2d6e 3583 }
835b2d10 3584end:
e98a2d6e
PP
3585 return ret;
3586}
3587
3588static
3589int reset_stream_decl_types(struct ctx *ctx,
50842bdc 3590 struct bt_stream_class *stream_class)
e98a2d6e
PP
3591{
3592 int ret = 0;
e98a2d6e 3593
835b2d10 3594 /* Packet context. */
50842bdc 3595 ret = bt_stream_class_set_packet_context_type(stream_class, NULL);
e98a2d6e 3596 if (ret) {
08da4f77 3597 BT_LOGE_STR("Cannot reset initial stream class's packet context field type.");
835b2d10 3598 goto end;
e98a2d6e
PP
3599 }
3600
835b2d10 3601 /* Event header. */
50842bdc 3602 ret = bt_stream_class_set_event_header_type(stream_class, NULL);
e98a2d6e 3603 if (ret) {
08da4f77 3604 BT_LOGE_STR("Cannot reset initial stream class's event header field type.");
835b2d10 3605 goto end;
e98a2d6e
PP
3606 }
3607
835b2d10 3608 /* Event context. */
50842bdc 3609 ret = bt_stream_class_set_event_context_type(stream_class, NULL);
e98a2d6e 3610 if (ret) {
08da4f77 3611 BT_LOGE_STR("Cannot reset initial stream class's event context field type.");
835b2d10 3612 goto end;
e98a2d6e 3613 }
835b2d10 3614end:
e98a2d6e
PP
3615 return ret;
3616}
3617
3618static
50842bdc 3619struct bt_stream_class *create_reset_stream_class(struct ctx *ctx)
e98a2d6e
PP
3620{
3621 int ret;
50842bdc 3622 struct bt_stream_class *stream_class;
e98a2d6e 3623
50842bdc 3624 stream_class = bt_stream_class_create_empty(NULL);
e98a2d6e 3625 if (!stream_class) {
08da4f77 3626 BT_LOGE_STR("Cannot create empty stream class.");
e98a2d6e
PP
3627 goto error;
3628 }
3629
3630 /*
835b2d10
JG
3631 * Set packet context, event header, and event context to NULL to
3632 * override the default ones.
e98a2d6e
PP
3633 */
3634 ret = reset_stream_decl_types(ctx, stream_class);
3635 if (ret) {
3636 goto error;
3637 }
3638
3639 return stream_class;
3640
3641error:
3642 BT_PUT(stream_class);
3643
3644 return NULL;
3645}
3646
3647static
3648int visit_event_decl(struct ctx *ctx, struct ctf_node *node)
3649{
3650 int ret = 0;
3651 int set = 0;
3652 int64_t event_id;
3653 struct ctf_node *iter;
3654 int64_t stream_id = -1;
3655 char *event_name = NULL;
50842bdc
PP
3656 struct bt_event_class *event_class = NULL;
3657 struct bt_event_class *eevent_class;
3658 struct bt_stream_class *stream_class = NULL;
e98a2d6e 3659 struct bt_list_head *decl_list = &node->u.event.declaration_list;
1e649dff 3660 bool pop_scope = false;
e98a2d6e
PP
3661
3662 if (node->visited) {
3663 goto end;
3664 }
3665
3666 node->visited = TRUE;
3667 event_name = get_event_decl_name(ctx, node);
3668 if (!event_name) {
28973adf
PP
3669 _BT_LOGE_NODE(node,
3670 "Missing `name` attribute in event class.");
e98a2d6e
PP
3671 ret = -EPERM;
3672 goto error;
3673 }
3674
50842bdc 3675 event_class = bt_event_class_create(event_name);
e98a2d6e
PP
3676
3677 /*
835b2d10 3678 * Unset context and fields to override the default ones.
e98a2d6e
PP
3679 */
3680 ret = reset_event_decl_types(ctx, event_class);
3681 if (ret) {
28973adf
PP
3682 _BT_LOGE_NODE(node,
3683 "Cannot reset event class's field types: "
3684 "ret=%d", ret);
e98a2d6e
PP
3685 goto error;
3686 }
3687
e98a2d6e
PP
3688 ret = ctx_push_scope(ctx);
3689 if (ret) {
08da4f77 3690 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
3691 goto error;
3692 }
3693
1e649dff
PP
3694 pop_scope = true;
3695
e98a2d6e
PP
3696 bt_list_for_each_entry(iter, decl_list, siblings) {
3697 ret = visit_event_decl_entry(ctx, iter, event_class,
3698 &stream_id, &set);
3699 if (ret) {
28973adf
PP
3700 _BT_LOGE_NODE(iter, "Cannot visit event class's entry: "
3701 "ret=%d", ret);
e98a2d6e
PP
3702 goto error;
3703 }
3704 }
3705
3706 if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
3707 GList *keys = NULL;
942c0e8f 3708 int64_t *new_stream_id;
50842bdc 3709 struct bt_stream_class *new_stream_class;
1e649dff
PP
3710 size_t stream_class_count =
3711 g_hash_table_size(ctx->stream_classes) +
50842bdc 3712 bt_trace_get_stream_class_count(ctx->trace);
e98a2d6e 3713
1e649dff
PP
3714 /*
3715 * Allow missing stream_id if there is only a single
3716 * stream class.
3717 */
3718 switch (stream_class_count) {
e98a2d6e 3719 case 0:
1e649dff 3720 /* Create implicit stream class if there's none */
7b4b1ba2 3721 stream_id = 0;
e98a2d6e
PP
3722 new_stream_class = create_reset_stream_class(ctx);
3723 if (!new_stream_class) {
28973adf
PP
3724 _BT_LOGE_NODE(node,
3725 "Cannot create empty stream class.");
e98a2d6e
PP
3726 ret = -EINVAL;
3727 goto error;
3728 }
3729
50842bdc 3730 ret = bt_stream_class_set_id(new_stream_class,
7b4b1ba2 3731 stream_id);
e98a2d6e 3732 if (ret) {
28973adf
PP
3733 _BT_LOGE_NODE(node,
3734 "Cannot set stream class's ID: "
08da4f77 3735 "id=0, ret=%d", ret);
e98a2d6e
PP
3736 BT_PUT(new_stream_class);
3737 goto error;
3738 }
3739
942c0e8f
MJ
3740 new_stream_id = g_new0(int64_t, 1);
3741 if (!new_stream_id) {
3742 BT_LOGE_STR("Failed to allocate a int64_t.");
3743 ret = -ENOMEM;
3744 goto error;
3745 }
e98a2d6e 3746
7b4b1ba2
PP
3747 *new_stream_id = stream_id;
3748
e98a2d6e
PP
3749 /* Move reference to visitor's context */
3750 g_hash_table_insert(ctx->stream_classes,
942c0e8f
MJ
3751 new_stream_id, new_stream_class);
3752 new_stream_id = NULL;
e98a2d6e 3753 new_stream_class = NULL;
e98a2d6e
PP
3754 break;
3755 case 1:
1e649dff
PP
3756 /* Single stream class: get its ID */
3757 if (g_hash_table_size(ctx->stream_classes) == 1) {
3758 keys = g_hash_table_get_keys(ctx->stream_classes);
942c0e8f 3759 stream_id = *((int64_t *) keys->data);
1e649dff
PP
3760 g_list_free(keys);
3761 } else {
50842bdc 3762 assert(bt_trace_get_stream_class_count(
1e649dff 3763 ctx->trace) == 1);
9ac68eb1 3764 stream_class =
50842bdc 3765 bt_trace_get_stream_class_by_index(
9ac68eb1 3766 ctx->trace, 0);
1e649dff 3767 assert(stream_class);
50842bdc 3768 stream_id = bt_stream_class_get_id(
1e649dff
PP
3769 stream_class);
3770 BT_PUT(stream_class);
3771 }
e98a2d6e
PP
3772 break;
3773 default:
28973adf
PP
3774 _BT_LOGE_NODE(node,
3775 "Missing `stream_id` attribute in event class.");
e98a2d6e
PP
3776 ret = -EPERM;
3777 goto error;
3778 }
3779 }
3780
e98a2d6e
PP
3781 assert(stream_id >= 0);
3782
1e649dff 3783 /* We have the stream ID now; get the stream class if found */
942c0e8f 3784 stream_class = g_hash_table_lookup(ctx->stream_classes, &stream_id);
1e649dff 3785 bt_get(stream_class);
e98a2d6e 3786 if (!stream_class) {
50842bdc 3787 stream_class = bt_trace_get_stream_class_by_id(ctx->trace,
e98a2d6e 3788 stream_id);
1e649dff 3789 if (!stream_class) {
28973adf
PP
3790 _BT_LOGE_NODE(node,
3791 "Cannot find stream class at this point: "
08da4f77 3792 "id=%" PRId64, stream_id);
1e649dff
PP
3793 ret = -EINVAL;
3794 goto error;
3795 }
e98a2d6e
PP
3796 }
3797
1e649dff
PP
3798 assert(stream_class);
3799
e98a2d6e
PP
3800 if (!_IS_SET(&set, _EVENT_ID_SET)) {
3801 /* Allow only one event without ID per stream */
50842bdc 3802 if (bt_stream_class_get_event_class_count(stream_class) !=
e98a2d6e 3803 0) {
28973adf
PP
3804 _BT_LOGE_NODE(node,
3805 "Missing `id` attribute in event class.");
e98a2d6e
PP
3806 ret = -EPERM;
3807 goto error;
3808 }
3809
3810 /* Automatic ID */
50842bdc 3811 ret = bt_event_class_set_id(event_class, 0);
e98a2d6e 3812 if (ret) {
28973adf
PP
3813 _BT_LOGE_NODE(node,
3814 "Cannot set event class's ID: id=0, ret=%d",
08da4f77 3815 ret);
e98a2d6e
PP
3816 goto error;
3817 }
3818 }
3819
50842bdc 3820 event_id = bt_event_class_get_id(event_class);
e98a2d6e 3821 if (event_id < 0) {
28973adf 3822 _BT_LOGE_NODE(node, "Cannot get event class's ID.");
e98a2d6e
PP
3823 ret = -EINVAL;
3824 goto error;
3825 }
3826
50842bdc 3827 eevent_class = bt_stream_class_get_event_class_by_id(stream_class,
e98a2d6e
PP
3828 event_id);
3829 if (eevent_class) {
3830 BT_PUT(eevent_class);
28973adf
PP
3831 _BT_LOGE_NODE(node,
3832 "Duplicate event class (same ID) in the same stream class: "
08da4f77 3833 "id=%" PRId64, event_id);
e98a2d6e
PP
3834 ret = -EEXIST;
3835 goto error;
3836 }
3837
50842bdc 3838 ret = bt_stream_class_add_event_class(stream_class, event_class);
e98a2d6e 3839 BT_PUT(event_class);
e98a2d6e 3840 if (ret) {
28973adf
PP
3841 _BT_LOGE_NODE(node,
3842 "Cannot add event class to stream class: ret=%d", ret);
e98a2d6e
PP
3843 goto error;
3844 }
3845
1e649dff 3846 goto end;
e98a2d6e
PP
3847
3848error:
1e649dff 3849 bt_put(event_class);
e98a2d6e 3850
1e649dff
PP
3851end:
3852 if (pop_scope) {
3853 ctx_pop_scope(ctx);
3854 }
e98a2d6e 3855
1e649dff
PP
3856 g_free(event_name);
3857 bt_put(stream_class);
e98a2d6e
PP
3858 return ret;
3859}
3860
56b43721 3861static
7bf5af54 3862int auto_map_field_to_trace_clock_class(struct ctx *ctx,
50842bdc 3863 struct bt_field_type *ft)
56b43721 3864{
50842bdc
PP
3865 struct bt_clock_class *clock_class_to_map_to = NULL;
3866 struct bt_clock_class *mapped_clock_class = NULL;
56b43721 3867 int ret = 0;
7bf5af54 3868 int64_t clock_class_count;
56b43721 3869
50842bdc 3870 if (!ft || !bt_field_type_is_integer(ft)) {
56b43721
PP
3871 goto end;
3872 }
3873
7bf5af54 3874 mapped_clock_class =
50842bdc 3875 bt_field_type_integer_get_mapped_clock_class(ft);
7bf5af54 3876 if (mapped_clock_class) {
56b43721
PP
3877 goto end;
3878 }
3879
50842bdc 3880 clock_class_count = bt_trace_get_clock_class_count(ctx->trace);
7bf5af54
PP
3881 assert(clock_class_count >= 0);
3882
3883 switch (clock_class_count) {
3884 case 0:
3885 /*
3886 * No clock class exists in the trace at this
3887 * point. Create an implicit one at 1 GHz,
3888 * named `default`, and use this clock class.
3889 */
50842bdc 3890 clock_class_to_map_to = bt_clock_class_create("default",
f3534905 3891 1000000000);
7bf5af54
PP
3892 if (!clock_class_to_map_to) {
3893 BT_LOGE_STR("Cannot create a clock class.");
3894 ret = -1;
3895 goto end;
3896 }
3897
50842bdc 3898 ret = bt_trace_add_clock_class(ctx->trace,
7bf5af54
PP
3899 clock_class_to_map_to);
3900 if (ret) {
3901 BT_LOGE_STR("Cannot add clock class to trace.");
3902 goto end;
3903 }
3904 break;
3905 case 1:
3906 /*
3907 * Only one clock class exists in the trace at
3908 * this point: use this one.
3909 */
3910 clock_class_to_map_to =
50842bdc 3911 bt_trace_get_clock_class_by_index(ctx->trace, 0);
7bf5af54
PP
3912 assert(clock_class_to_map_to);
3913 break;
3914 default:
3915 /*
3916 * Timestamp field not mapped to a clock class
3917 * and there's more than one clock class in the
3918 * trace: this is an error.
3919 */
3920 BT_LOGE_STR("Timestamp field found with no mapped clock class, "
3921 "but there's more than one clock class in the trace at this point.");
3922 ret = -1;
56b43721
PP
3923 goto end;
3924 }
3925
7bf5af54 3926 assert(clock_class_to_map_to);
50842bdc 3927 ret = bt_field_type_integer_set_mapped_clock_class(ft,
7bf5af54
PP
3928 clock_class_to_map_to);
3929 if (ret) {
3930 BT_LOGE("Cannot map field type's field to trace's clock class: "
3931 "clock-class-name=\"%s\", ret=%d",
50842bdc 3932 bt_clock_class_get_name(clock_class_to_map_to),
7bf5af54 3933 ret);
56b43721
PP
3934 goto end;
3935 }
3936
7bf5af54
PP
3937end:
3938 bt_put(clock_class_to_map_to);
3939 bt_put(mapped_clock_class);
3940 return ret;
3941}
56b43721 3942
7bf5af54
PP
3943static
3944int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
50842bdc 3945 struct bt_field_type *root_ft, const char *field_name)
7bf5af54
PP
3946{
3947 int ret = 0;
3948 int64_t i, count;
56b43721 3949
7bf5af54
PP
3950 if (!root_ft) {
3951 goto end;
3952 }
56b43721 3953
50842bdc
PP
3954 if (!bt_field_type_is_structure(root_ft) &&
3955 !bt_field_type_is_variant(root_ft)) {
7bf5af54
PP
3956 goto end;
3957 }
3958
50842bdc
PP
3959 if (bt_field_type_is_structure(root_ft)) {
3960 count = bt_field_type_structure_get_field_count(root_ft);
7bf5af54 3961 } else {
50842bdc 3962 count = bt_field_type_variant_get_field_count(root_ft);
7bf5af54
PP
3963 }
3964
3965 assert(count >= 0);
3966
3967 for (i = 0; i < count; i++) {
50842bdc 3968 _BT_FIELD_TYPE_INIT(ft);
7bf5af54
PP
3969 const char *name;
3970
50842bdc
PP
3971 if (bt_field_type_is_structure(root_ft)) {
3972 ret = bt_field_type_structure_get_field_by_index(
7bf5af54 3973 root_ft, &name, &ft, i);
50842bdc
PP
3974 } else if (bt_field_type_is_variant(root_ft)) {
3975 ret = bt_field_type_variant_get_field_by_index(
7bf5af54
PP
3976 root_ft, &name, &ft, i);
3977 }
3978
3979 assert(ret == 0);
3980
3981 if (strcmp(name, field_name) == 0) {
3982 ret = auto_map_field_to_trace_clock_class(ctx, ft);
3983 if (ret) {
3984 BT_LOGE("Cannot automatically map field to trace's clock class: "
3985 "field-name=\"%s\"", field_name);
3986 bt_put(ft);
3987 goto end;
56b43721
PP
3988 }
3989 }
3990
7bf5af54
PP
3991 ret = auto_map_fields_to_trace_clock_class(ctx, ft, field_name);
3992 bt_put(ft);
3993 if (ret) {
3994 BT_LOGE("Cannot automatically map structure or variant field type's fields to trace's clock class: "
3995 "field-name=\"%s\", root-field-name=\"%s\"",
3996 field_name, name);
3997 goto end;
3998 }
56b43721
PP
3999 }
4000
4001end:
56b43721
PP
4002 return ret;
4003}
4004
e98a2d6e
PP
4005static
4006int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
50842bdc 4007 struct bt_stream_class *stream_class, int *set)
e98a2d6e
PP
4008{
4009 int ret = 0;
4010 char *left = NULL;
50842bdc 4011 _BT_FIELD_TYPE_INIT(decl);
e98a2d6e
PP
4012
4013 switch (node->type) {
4014 case NODE_TYPEDEF:
4015 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
4016 &node->u._typedef.type_declarators);
4017 if (ret) {
28973adf
PP
4018 _BT_LOGE_NODE(node,
4019 "Cannot add type definition found in stream class.");
e98a2d6e
PP
4020 goto error;
4021 }
4022 break;
4023 case NODE_TYPEALIAS:
4024 ret = visit_typealias(ctx, node->u.typealias.target,
4025 node->u.typealias.alias);
4026 if (ret) {
28973adf
PP
4027 _BT_LOGE_NODE(node,
4028 "Cannot add type alias found in stream class.");
e98a2d6e
PP
4029 goto error;
4030 }
4031 break;
4032 case NODE_CTF_EXPRESSION:
4033 {
4034 left = concatenate_unary_strings(&node->u.ctf_expression.left);
4035 if (!left) {
28973adf 4036 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
4037 ret = -EINVAL;
4038 goto error;
4039 }
4040
4041 if (!strcmp(left, "id")) {
4042 int64_t id;
4043 gpointer ptr;
4044
4045 if (_IS_SET(set, _STREAM_ID_SET)) {
28973adf
PP
4046 _BT_LOGE_DUP_ATTR(node, "id",
4047 "stream declaration");
e98a2d6e
PP
4048 ret = -EPERM;
4049 goto error;
4050 }
4051
4052 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4053 (uint64_t *) &id);
5eae0c3c
JG
4054 /* Only read "id" if get_unary_unsigned() succeeded. */
4055 if (ret || (!ret && id < 0)) {
28973adf
PP
4056 _BT_LOGE_NODE(node,
4057 "Unexpected unary expression for stream class's `id` attribute.");
e98a2d6e
PP
4058 ret = -EINVAL;
4059 goto error;
4060 }
4061
942c0e8f 4062 ptr = g_hash_table_lookup(ctx->stream_classes, &id);
e98a2d6e 4063 if (ptr) {
28973adf
PP
4064 _BT_LOGE_NODE(node,
4065 "Duplicate stream class (same ID): id=%" PRId64,
e98a2d6e
PP
4066 id);
4067 ret = -EEXIST;
4068 goto error;
4069 }
4070
50842bdc 4071 ret = bt_stream_class_set_id(stream_class, id);
e98a2d6e 4072 if (ret) {
28973adf
PP
4073 _BT_LOGE_NODE(node,
4074 "Cannot set stream class's ID: "
08da4f77 4075 "id=%" PRId64 ", ret=%d", id, ret);
e98a2d6e
PP
4076 goto error;
4077 }
4078
4079 _SET(set, _STREAM_ID_SET);
4080 } else if (!strcmp(left, "event.header")) {
4081 if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
28973adf
PP
4082 _BT_LOGE_NODE(node,
4083 "Duplicate `event.header` entry in stream class.");
e98a2d6e
PP
4084 ret = -EPERM;
4085 goto error;
4086 }
4087
4088 ret = visit_type_specifier_list(ctx,
4089 _BT_LIST_FIRST_ENTRY(
4090 &node->u.ctf_expression.right,
4091 struct ctf_node, siblings),
4092 &decl);
4093 if (ret) {
28973adf
PP
4094 _BT_LOGE_NODE(node,
4095 "Cannot create stream class's event header field type.");
e98a2d6e
PP
4096 goto error;
4097 }
4098
4099 assert(decl);
56b43721 4100 ret = auto_map_fields_to_trace_clock_class(ctx,
7bf5af54 4101 decl, "timestamp");
56b43721
PP
4102 if (ret) {
4103 _BT_LOGE_NODE(node,
7bf5af54 4104 "Cannot automatically map specific event header field type fields named `timestamp` to trace's clock class.");
56b43721
PP
4105 goto error;
4106 }
e98a2d6e 4107
50842bdc 4108 ret = bt_stream_class_set_event_header_type(
e98a2d6e
PP
4109 stream_class, decl);
4110 BT_PUT(decl);
4111 if (ret) {
28973adf
PP
4112 _BT_LOGE_NODE(node,
4113 "Cannot set stream class's event header field type.");
e98a2d6e
PP
4114 goto error;
4115 }
4116
4117 _SET(set, _STREAM_EVENT_HEADER_SET);
4118 } else if (!strcmp(left, "event.context")) {
4119 if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
28973adf
PP
4120 _BT_LOGE_NODE(node,
4121 "Duplicate `event.context` entry in stream class.");
e98a2d6e
PP
4122 ret = -EPERM;
4123 goto error;
4124 }
4125
4126 ret = visit_type_specifier_list(ctx,
4127 _BT_LIST_FIRST_ENTRY(
4128 &node->u.ctf_expression.right,
4129 struct ctf_node, siblings),
4130 &decl);
4131 if (ret) {
28973adf
PP
4132 _BT_LOGE_NODE(node,
4133 "Cannot create stream class's event context field type.");
e98a2d6e
PP
4134 goto error;
4135 }
4136
4137 assert(decl);
4138
50842bdc 4139 ret = bt_stream_class_set_event_context_type(
e98a2d6e
PP
4140 stream_class, decl);
4141 BT_PUT(decl);
4142 if (ret) {
28973adf
PP
4143 _BT_LOGE_NODE(node,
4144 "Cannot set stream class's event context field type.");
e98a2d6e
PP
4145 goto error;
4146 }
4147
4148 _SET(set, _STREAM_EVENT_CONTEXT_SET);
4149 } else if (!strcmp(left, "packet.context")) {
4150 if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
28973adf
PP
4151 _BT_LOGE_NODE(node,
4152 "Duplicate `packet.context` entry in stream class.");
e98a2d6e
PP
4153 ret = -EPERM;
4154 goto error;
4155 }
4156
4157 ret = visit_type_specifier_list(ctx,
4158 _BT_LIST_FIRST_ENTRY(
4159 &node->u.ctf_expression.right,
4160 struct ctf_node, siblings),
4161 &decl);
4162 if (ret) {
28973adf
PP
4163 _BT_LOGE_NODE(node,
4164 "Cannot create stream class's packet context field type.");
e98a2d6e
PP
4165 goto error;
4166 }
4167
4168 assert(decl);
56b43721 4169 ret = auto_map_fields_to_trace_clock_class(ctx,
7bf5af54
PP
4170 decl, "timestamp_begin");
4171 if (ret) {
4172 _BT_LOGE_NODE(node,
4173 "Cannot automatically map specific packet context field type fields named `timestamp_begin` to trace's clock class.");
4174 goto error;
4175 }
4176
4177 ret = auto_map_fields_to_trace_clock_class(ctx,
4178 decl, "timestamp_end");
56b43721
PP
4179 if (ret) {
4180 _BT_LOGE_NODE(node,
7bf5af54 4181 "Cannot automatically map specific packet context field type fields named `timestamp_end` to trace's clock class.");
56b43721
PP
4182 goto error;
4183 }
e98a2d6e 4184
50842bdc 4185 ret = bt_stream_class_set_packet_context_type(
e98a2d6e
PP
4186 stream_class, decl);
4187 BT_PUT(decl);
4188 if (ret) {
28973adf
PP
4189 _BT_LOGE_NODE(node,
4190 "Cannot set stream class's packet context field type.");
e98a2d6e
PP
4191 goto error;
4192 }
4193
4194 _SET(set, _STREAM_PACKET_CONTEXT_SET);
4195 } else {
28973adf
PP
4196 _BT_LOGW_NODE(node,
4197 "Unknown attribute in stream class: "
08da4f77 4198 "attr-name=\"%s\"", left);
e98a2d6e
PP
4199 }
4200
4201 g_free(left);
4202 left = NULL;
4203 break;
4204 }
4205
4206 default:
4207 ret = -EPERM;
4208 goto error;
4209 }
4210
4211 return 0;
4212
4213error:
4214 g_free(left);
4215 BT_PUT(decl);
4216
4217 return ret;
4218}
4219
4220static
4221int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
4222{
4223 int64_t id;
942c0e8f 4224 int64_t *new_id;
e98a2d6e
PP
4225 int set = 0;
4226 int ret = 0;
4227 struct ctf_node *iter;
50842bdc
PP
4228 struct bt_stream_class *stream_class = NULL;
4229 struct bt_stream_class *existing_stream_class = NULL;
e98a2d6e
PP
4230 struct bt_list_head *decl_list = &node->u.stream.declaration_list;
4231
4232 if (node->visited) {
4233 goto end;
4234 }
4235
4236 node->visited = TRUE;
4237 stream_class = create_reset_stream_class(ctx);
4238 if (!stream_class) {
28973adf 4239 _BT_LOGE_NODE(node, "Cannot create empty stream class.");
e98a2d6e
PP
4240 ret = -EINVAL;
4241 goto error;
4242 }
4243
4244 ret = ctx_push_scope(ctx);
4245 if (ret) {
08da4f77 4246 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
4247 goto error;
4248 }
4249
4250 bt_list_for_each_entry(iter, decl_list, siblings) {
4251 ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
4252 if (ret) {
28973adf
PP
4253 _BT_LOGE_NODE(iter,
4254 "Cannot visit stream class's entry: "
4255 "ret=%d", ret);
e98a2d6e
PP
4256 ctx_pop_scope(ctx);
4257 goto error;
4258 }
4259 }
4260
4261 ctx_pop_scope(ctx);
4262
4263 if (_IS_SET(&set, _STREAM_ID_SET)) {
4264 /* Check that packet header has stream_id field */
50842bdc
PP
4265 _BT_FIELD_TYPE_INIT(stream_id_decl);
4266 _BT_FIELD_TYPE_INIT(packet_header_decl);
e98a2d6e
PP
4267
4268 packet_header_decl =
50842bdc 4269 bt_trace_get_packet_header_type(ctx->trace);
e98a2d6e 4270 if (!packet_header_decl) {
28973adf
PP
4271 _BT_LOGE_NODE(node,
4272 "Stream class has a `id` attribute, "
08da4f77 4273 "but trace has no packet header field type.");
e98a2d6e
PP
4274 goto error;
4275 }
4276
4277 stream_id_decl =
50842bdc 4278 bt_field_type_structure_get_field_type_by_name(
e98a2d6e
PP
4279 packet_header_decl, "stream_id");
4280 BT_PUT(packet_header_decl);
4281 if (!stream_id_decl) {
28973adf
PP
4282 _BT_LOGE_NODE(node,
4283 "Stream class has a `id` attribute, "
08da4f77 4284 "but trace's packet header field type has no `stream_id` field.");
e98a2d6e
PP
4285 goto error;
4286 }
4287
50842bdc 4288 if (!bt_field_type_is_integer(stream_id_decl)) {
e98a2d6e 4289 BT_PUT(stream_id_decl);
28973adf
PP
4290 _BT_LOGE_NODE(node,
4291 "Stream class has a `id` attribute, "
08da4f77 4292 "but trace's packet header field type's `stream_id` field is not an integer field type.");
e98a2d6e
PP
4293 goto error;
4294 }
4295
4296 BT_PUT(stream_id_decl);
4297 } else {
4298 /* Allow only _one_ ID-less stream */
4299 if (g_hash_table_size(ctx->stream_classes) != 0) {
28973adf
PP
4300 _BT_LOGE_NODE(node,
4301 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
e98a2d6e
PP
4302 ret = -EPERM;
4303 goto error;
4304 }
4305
4306 /* Automatic ID: 0 */
50842bdc 4307 ret = bt_stream_class_set_id(stream_class, 0);
08da4f77 4308 assert(ret == 0);
e98a2d6e
PP
4309 }
4310
50842bdc 4311 id = bt_stream_class_get_id(stream_class);
e98a2d6e 4312 if (id < 0) {
28973adf
PP
4313 _BT_LOGE_NODE(node,
4314 "Cannot get stream class's ID.");
e98a2d6e
PP
4315 ret = -EINVAL;
4316 goto error;
4317 }
4318
1e649dff
PP
4319 /*
4320 * Make sure that this stream class's ID is currently unique in
4321 * the trace.
4322 */
50842bdc 4323 existing_stream_class = bt_trace_get_stream_class_by_id(ctx->trace,
1e649dff 4324 id);
942c0e8f 4325 if (g_hash_table_lookup(ctx->stream_classes, &id) ||
08da4f77 4326 existing_stream_class) {
28973adf
PP
4327 _BT_LOGE_NODE(node,
4328 "Duplicate stream class (same ID): id=%" PRId64,
08da4f77 4329 id);
1e649dff
PP
4330 ret = -EINVAL;
4331 goto error;
4332 }
4333
942c0e8f
MJ
4334 new_id = g_new0(int64_t, 1);
4335 if (!new_id) {
4336 BT_LOGE_STR("Failed to allocate a int64_t.");
4337 ret = -ENOMEM;
4338 goto error;
4339 }
4340 *new_id = id;
4341
e98a2d6e 4342 /* Move reference to visitor's context */
942c0e8f 4343 g_hash_table_insert(ctx->stream_classes, new_id,
e98a2d6e
PP
4344 stream_class);
4345 stream_class = NULL;
1e649dff 4346 goto end;
e98a2d6e
PP
4347
4348error:
1e649dff 4349 bt_put(stream_class);
e98a2d6e 4350
1e649dff
PP
4351end:
4352 bt_put(existing_stream_class);
e98a2d6e
PP
4353 return ret;
4354}
4355
4356static
4357int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
4358{
4359 int ret = 0;
4360 char *left = NULL;
50842bdc 4361 _BT_FIELD_TYPE_INIT(packet_header_decl);
e98a2d6e
PP
4362
4363 switch (node->type) {
4364 case NODE_TYPEDEF:
4365 ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
4366 &node->u._typedef.type_declarators);
4367 if (ret) {
28973adf
PP
4368 _BT_LOGE_NODE(node,
4369 "Cannot add type definition found in trace (`trace` block).");
e98a2d6e
PP
4370 goto error;
4371 }
4372 break;
4373 case NODE_TYPEALIAS:
4374 ret = visit_typealias(ctx, node->u.typealias.target,
4375 node->u.typealias.alias);
4376 if (ret) {
28973adf
PP
4377 _BT_LOGE_NODE(node,
4378 "Cannot add type alias found in trace (`trace` block).");
e98a2d6e
PP
4379 goto error;
4380 }
4381 break;
4382 case NODE_CTF_EXPRESSION:
4383 {
4384 left = concatenate_unary_strings(&node->u.ctf_expression.left);
4385 if (!left) {
28973adf 4386 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
e98a2d6e
PP
4387 ret = -EINVAL;
4388 goto error;
4389 }
4390
4391 if (!strcmp(left, "major")) {
4392 if (_IS_SET(set, _TRACE_MAJOR_SET)) {
28973adf 4393 _BT_LOGE_DUP_ATTR(node, "major", "trace");
e98a2d6e
PP
4394 ret = -EPERM;
4395 goto error;
4396 }
4397
4398 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4399 &ctx->trace_major);
4400 if (ret) {
28973adf
PP
4401 _BT_LOGE_NODE(node,
4402 "Unexpected unary expression for trace's `major` attribute.");
e98a2d6e
PP
4403 ret = -EINVAL;
4404 goto error;
4405 }
4406
4407 _SET(set, _TRACE_MAJOR_SET);
4408 } else if (!strcmp(left, "minor")) {
4409 if (_IS_SET(set, _TRACE_MINOR_SET)) {
28973adf 4410 _BT_LOGE_DUP_ATTR(node, "minor", "trace");
e98a2d6e
PP
4411 ret = -EPERM;
4412 goto error;
4413 }
4414
4415 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4416 &ctx->trace_minor);
4417 if (ret) {
28973adf
PP
4418 _BT_LOGE_NODE(node,
4419 "Unexpected unary expression for trace's `minor` attribute.");
e98a2d6e
PP
4420 ret = -EINVAL;
4421 goto error;
4422 }
4423
4424 _SET(set, _TRACE_MINOR_SET);
4425 } else if (!strcmp(left, "uuid")) {
4426 if (_IS_SET(set, _TRACE_UUID_SET)) {
28973adf 4427 _BT_LOGE_DUP_ATTR(node, "uuid", "trace");
e98a2d6e
PP
4428 ret = -EPERM;
4429 goto error;
4430 }
4431
4432 ret = get_unary_uuid(&node->u.ctf_expression.right,
4433 ctx->trace_uuid);
4434 if (ret) {
28973adf
PP
4435 _BT_LOGE_NODE(node,
4436 "Invalid trace's `uuid` attribute.");
e98a2d6e
PP
4437 goto error;
4438 }
4439
50842bdc 4440 ret = bt_trace_set_uuid(ctx->trace, ctx->trace_uuid);
892a5b6c 4441 if (ret) {
28973adf 4442 _BT_LOGE_NODE(node, "Cannot set trace's UUID.");
892a5b6c
PP
4443 goto error;
4444 }
4445
e98a2d6e
PP
4446 _SET(set, _TRACE_UUID_SET);
4447 } else if (!strcmp(left, "byte_order")) {
4448 /* Native byte order is already known at this stage */
4449 if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
28973adf 4450 _BT_LOGE_DUP_ATTR(node, "byte_order",
08da4f77 4451 "trace");
e98a2d6e
PP
4452 ret = -EPERM;
4453 goto error;
4454 }
4455
4456 _SET(set, _TRACE_BYTE_ORDER_SET);
4457 } else if (!strcmp(left, "packet.header")) {
4458 if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
28973adf
PP
4459 _BT_LOGE_NODE(node,
4460 "Duplicate `packet.header` entry in trace.");
e98a2d6e
PP
4461 ret = -EPERM;
4462 goto error;
4463 }
4464
4465 ret = visit_type_specifier_list(ctx,
4466 _BT_LIST_FIRST_ENTRY(
4467 &node->u.ctf_expression.right,
4468 struct ctf_node, siblings),
4469 &packet_header_decl);
4470 if (ret) {
28973adf
PP
4471 _BT_LOGE_NODE(node,
4472 "Cannot create trace's packet header field type.");
e98a2d6e
PP
4473 goto error;
4474 }
4475
4476 assert(packet_header_decl);
50842bdc 4477 ret = bt_trace_set_packet_header_type(ctx->trace,
e98a2d6e
PP
4478 packet_header_decl);
4479 BT_PUT(packet_header_decl);
4480 if (ret) {
28973adf
PP
4481 _BT_LOGE_NODE(node,
4482 "Cannot set trace's packet header field type.");
e98a2d6e
PP
4483 goto error;
4484 }
4485
4486 _SET(set, _TRACE_PACKET_HEADER_SET);
4487 } else {
28973adf
PP
4488 _BT_LOGW_NODE(node,
4489 "Unknown attribute in stream class: "
08da4f77 4490 "attr-name=\"%s\"", left);
e98a2d6e
PP
4491 }
4492
4493 g_free(left);
4494 left = NULL;
4495 break;
4496 }
4497 default:
28973adf 4498 _BT_LOGE_NODE(node, "Unknown expression in trace.");
e98a2d6e
PP
4499 ret = -EINVAL;
4500 goto error;
4501 }
4502
4503 return 0;
4504
4505error:
4506 g_free(left);
4507 BT_PUT(packet_header_decl);
4508
4509 return ret;
4510}
4511
4512static
4513int visit_trace_decl(struct ctx *ctx, struct ctf_node *node)
4514{
4515 int ret = 0;
4516 int set = 0;
4517 struct ctf_node *iter;
4518 struct bt_list_head *decl_list = &node->u.trace.declaration_list;
4519
4520 if (node->visited) {
4521 goto end;
4522 }
4523
4524 node->visited = TRUE;
4525
4526 if (ctx->is_trace_visited) {
28973adf 4527 _BT_LOGE_NODE(node, "Duplicate trace (`trace` block).");
e98a2d6e
PP
4528 ret = -EEXIST;
4529 goto error;
4530 }
4531
4532 ret = ctx_push_scope(ctx);
4533 if (ret) {
08da4f77 4534 BT_LOGE_STR("Cannot push scope.");
e98a2d6e
PP
4535 goto error;
4536 }
4537
4538 bt_list_for_each_entry(iter, decl_list, siblings) {
4539 ret = visit_trace_decl_entry(ctx, iter, &set);
4540 if (ret) {
28973adf
PP
4541 _BT_LOGE_NODE(iter, "Cannot visit trace's entry (`trace` block): "
4542 "ret=%d", ret);
e98a2d6e
PP
4543 ctx_pop_scope(ctx);
4544 goto error;
4545 }
4546 }
4547
4548 ctx_pop_scope(ctx);
4549
4550 if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
28973adf
PP
4551 _BT_LOGE_NODE(node,
4552 "Missing `major` attribute in trace (`trace` block).");
e98a2d6e
PP
4553 ret = -EPERM;
4554 goto error;
4555 }
4556
4557 if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
28973adf
PP
4558 _BT_LOGE_NODE(node,
4559 "Missing `minor` attribute in trace (`trace` block).");
e98a2d6e
PP
4560 ret = -EPERM;
4561 goto error;
4562 }
4563
4564 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf
PP
4565 _BT_LOGE_NODE(node,
4566 "Missing `byte_order` attribute in trace (`trace` block).");
e98a2d6e
PP
4567 ret = -EPERM;
4568 goto error;
4569 }
4570
4571 ctx->is_trace_visited = TRUE;
4572
4573end:
4574 return 0;
4575
4576error:
4577 return ret;
4578}
4579
4580static
4581int visit_env(struct ctx *ctx, struct ctf_node *node)
4582{
4583 int ret = 0;
4584 char *left = NULL;
4585 struct ctf_node *entry_node;
4586 struct bt_list_head *decl_list = &node->u.env.declaration_list;
4587
4588 if (node->visited) {
4589 goto end;
4590 }
4591
4592 node->visited = TRUE;
4593
4594 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4595 struct bt_list_head *right_head =
4596 &entry_node->u.ctf_expression.right;
4597
4598 if (entry_node->type != NODE_CTF_EXPRESSION) {
28973adf
PP
4599 _BT_LOGE_NODE(entry_node,
4600 "Wrong expression in environment entry: "
08da4f77 4601 "node-type=%d", entry_node->type);
e98a2d6e
PP
4602 ret = -EPERM;
4603 goto error;
4604 }
4605
4606 left = concatenate_unary_strings(
4607 &entry_node->u.ctf_expression.left);
4608 if (!left) {
28973adf
PP
4609 _BT_LOGE_NODE(entry_node,
4610 "Cannot get environment entry's name.");
e98a2d6e
PP
4611 ret = -EINVAL;
4612 goto error;
4613 }
4614
4615 if (is_unary_string(right_head)) {
4616 char *right = concatenate_unary_strings(right_head);
4617
4618 if (!right) {
28973adf
PP
4619 _BT_LOGE_NODE(entry_node,
4620 "Unexpected unary expression for environment entry's value: "
08da4f77 4621 "name=\"%s\"", left);
e98a2d6e
PP
4622 ret = -EINVAL;
4623 goto error;
4624 }
4625
7bf5af54
PP
4626 if (strcmp(left, "tracer_name") == 0) {
4627 if (strncmp(right, "lttng", 5) == 0) {
4628 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4629 "tracer-name=\"%s\"",
4630 left, right);
4631 ctx->is_lttng = 1;
f4421ff3
PP
4632 }
4633 }
4634
50842bdc 4635 ret = bt_trace_set_environment_field_string(
e98a2d6e
PP
4636 ctx->trace, left, right);
4637 g_free(right);
4638
4639 if (ret) {
28973adf
PP
4640 _BT_LOGE_NODE(entry_node,
4641 "Cannot add string environment entry to trace: "
08da4f77 4642 "name=\"%s\", ret=%d", left, ret);
e98a2d6e
PP
4643 goto error;
4644 }
4645 } else if (is_unary_unsigned(right_head) ||
4646 is_unary_signed(right_head)) {
4647 int64_t v;
4648
4649 if (is_unary_unsigned(right_head)) {
4650 ret = get_unary_unsigned(right_head,
4651 (uint64_t *) &v);
4652 } else {
4653 ret = get_unary_signed(right_head, &v);
4654 }
4655 if (ret) {
28973adf
PP
4656 _BT_LOGE_NODE(entry_node,
4657 "Unexpected unary expression for environment entry's value: "
08da4f77 4658 "name=\"%s\"", left);
e98a2d6e
PP
4659 ret = -EINVAL;
4660 goto error;
4661 }
4662
50842bdc 4663 ret = bt_trace_set_environment_field_integer(
e98a2d6e
PP
4664 ctx->trace, left, v);
4665 if (ret) {
28973adf
PP
4666 _BT_LOGE_NODE(entry_node,
4667 "Cannot add integer environment entry to trace: "
08da4f77 4668 "name=\"%s\", ret=%d", left, ret);
e98a2d6e
PP
4669 goto error;
4670 }
4671 } else {
28973adf
PP
4672 _BT_LOGW_NODE(entry_node,
4673 "Environment entry has unknown type: "
08da4f77 4674 "name=\"%s\"", left);
e98a2d6e
PP
4675 }
4676
4677 g_free(left);
4678 left = NULL;
4679 }
4680
4681end:
4682 return 0;
4683
4684error:
4685 g_free(left);
4686
4687 return ret;
4688}
4689
4690static
4691int set_trace_byte_order(struct ctx *ctx, struct ctf_node *trace_node)
4692{
4693 int ret = 0;
4694 int set = 0;
4695 char *left = NULL;
4696 struct ctf_node *node;
4697 struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
4698
4699 bt_list_for_each_entry(node, decl_list, siblings) {
4700 if (node->type == NODE_CTF_EXPRESSION) {
4701 struct ctf_node *right_node;
4702
4703 left = concatenate_unary_strings(
4704 &node->u.ctf_expression.left);
4705 if (!left) {
28973adf
PP
4706 _BT_LOGE_NODE(node,
4707 "Cannot concatenate unary strings.");
e98a2d6e
PP
4708 ret = -EINVAL;
4709 goto error;
4710 }
4711
4712 if (!strcmp(left, "byte_order")) {
50842bdc 4713 enum bt_byte_order bo;
e98a2d6e
PP
4714
4715 if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf 4716 _BT_LOGE_DUP_ATTR(node, "byte_order",
08da4f77 4717 "trace");
e98a2d6e
PP
4718 ret = -EPERM;
4719 goto error;
4720 }
4721
4722 _SET(&set, _TRACE_BYTE_ORDER_SET);
4723 right_node = _BT_LIST_FIRST_ENTRY(
4724 &node->u.ctf_expression.right,
4725 struct ctf_node, siblings);
55314f2a 4726 bo = byte_order_from_unary_expr(right_node);
50842bdc 4727 if (bo == BT_BYTE_ORDER_UNKNOWN) {
28973adf
PP
4728 _BT_LOGE_NODE(node,
4729 "Invalid `byte_order` attribute in trace (`trace` block): "
4730 "expecting `le`, `be`, or `network`.");
e98a2d6e
PP
4731 ret = -EINVAL;
4732 goto error;
50842bdc 4733 } else if (bo == BT_BYTE_ORDER_NATIVE) {
28973adf
PP
4734 _BT_LOGE_NODE(node,
4735 "Invalid `byte_order` attribute in trace (`trace` block): "
08da4f77 4736 "cannot be set to `native` here.");
e98a2d6e
PP
4737 ret = -EPERM;
4738 goto error;
4739 }
4740
1e649dff 4741 ctx->trace_bo = bo;
50842bdc 4742 ret = bt_trace_set_native_byte_order(
e98a2d6e
PP
4743 ctx->trace, bo);
4744 if (ret) {
28973adf
PP
4745 _BT_LOGE_NODE(node,
4746 "Cannot set trace's byte order: "
08da4f77 4747 "ret=%d", ret);
e98a2d6e
PP
4748 goto error;
4749 }
4750 }
4751
4752 g_free(left);
4753 left = NULL;
4754 }
4755 }
4756
4757 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
28973adf
PP
4758 _BT_LOGE_NODE(trace_node,
4759 "Missing `byte_order` attribute in trace (`trace` block).");
e98a2d6e
PP
4760 ret = -EINVAL;
4761 goto error;
4762 }
4763
4764 return 0;
4765
4766error:
4767 g_free(left);
4768
4769 return ret;
4770}
4771
4772static
4773int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
50842bdc 4774 struct bt_clock_class *clock, int *set)
e98a2d6e
PP
4775{
4776 int ret = 0;
4777 char *left = NULL;
4778
4779 if (entry_node->type != NODE_CTF_EXPRESSION) {
28973adf
PP
4780 _BT_LOGE_NODE(entry_node,
4781 "Unexpected node type: node-type=%d",
4782 entry_node->type);
e98a2d6e
PP
4783 ret = -EPERM;
4784 goto error;
4785 }
4786
4787 left = concatenate_unary_strings(&entry_node->u.ctf_expression.left);
4788 if (!left) {
28973adf 4789 _BT_LOGE_NODE(entry_node, "Cannot concatenate unary strings.");
e98a2d6e
PP
4790 ret = -EINVAL;
4791 goto error;
4792 }
4793
4794 if (!strcmp(left, "name")) {
4795 char *right;
4796
4797 if (_IS_SET(set, _CLOCK_NAME_SET)) {
28973adf 4798 _BT_LOGE_DUP_ATTR(entry_node, "name", "clock class");
e98a2d6e
PP
4799 ret = -EPERM;
4800 goto error;
4801 }
4802
4803 right = concatenate_unary_strings(
4804 &entry_node->u.ctf_expression.right);
4805 if (!right) {
28973adf
PP
4806 _BT_LOGE_NODE(entry_node,
4807 "Unexpected unary expression for clock class's `name` attribute.");
e98a2d6e
PP
4808 ret = -EINVAL;
4809 goto error;
4810 }
4811
50842bdc 4812 ret = bt_clock_class_set_name(clock, right);
e98a2d6e 4813 if (ret) {
28973adf
PP
4814 _BT_LOGE_NODE(entry_node,
4815 "cannot set clock class's name");
e98a2d6e
PP
4816 g_free(right);
4817 goto error;
4818 }
4819
4820 g_free(right);
4821 _SET(set, _CLOCK_NAME_SET);
4822 } else if (!strcmp(left, "uuid")) {
4823 unsigned char uuid[BABELTRACE_UUID_LEN];
4824
4825 if (_IS_SET(set, _CLOCK_UUID_SET)) {
28973adf 4826 _BT_LOGE_DUP_ATTR(entry_node, "uuid", "clock class");
e98a2d6e
PP
4827 ret = -EPERM;
4828 goto error;
4829 }
4830
4831 ret = get_unary_uuid(&entry_node->u.ctf_expression.right, uuid);
4832 if (ret) {
28973adf
PP
4833 _BT_LOGE_NODE(entry_node,
4834 "Invalid clock class's `uuid` attribute.");
e98a2d6e
PP
4835 goto error;
4836 }
4837
50842bdc 4838 ret = bt_clock_class_set_uuid(clock, uuid);
e98a2d6e 4839 if (ret) {
28973adf
PP
4840 _BT_LOGE_NODE(entry_node,
4841 "Cannot set clock class's UUID.");
e98a2d6e
PP
4842 goto error;
4843 }
4844
4845 _SET(set, _CLOCK_UUID_SET);
4846 } else if (!strcmp(left, "description")) {
4847 char *right;
4848
4849 if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
28973adf
PP
4850 _BT_LOGE_DUP_ATTR(entry_node, "description",
4851 "clock class");
e98a2d6e
PP
4852 ret = -EPERM;
4853 goto error;
4854 }
4855
4856 right = concatenate_unary_strings(
4857 &entry_node->u.ctf_expression.right);
4858 if (!right) {
28973adf
PP
4859 _BT_LOGE_NODE(entry_node,
4860 "Unexpected unary expression for clock class's `description` attribute.");
e98a2d6e
PP
4861 ret = -EINVAL;
4862 goto error;
4863 }
4864
50842bdc 4865 ret = bt_clock_class_set_description(clock, right);
e98a2d6e 4866 if (ret) {
28973adf
PP
4867 _BT_LOGE_NODE(entry_node,
4868 "Cannot set clock class's description.");
e98a2d6e
PP
4869 g_free(right);
4870 goto error;
4871 }
4872
4873 g_free(right);
4874 _SET(set, _CLOCK_DESCRIPTION_SET);
4875 } else if (!strcmp(left, "freq")) {
bc85036f 4876 uint64_t freq = -1ULL;
e98a2d6e
PP
4877
4878 if (_IS_SET(set, _CLOCK_FREQ_SET)) {
28973adf 4879 _BT_LOGE_DUP_ATTR(entry_node, "freq", "clock class");
e98a2d6e
PP
4880 ret = -EPERM;
4881 goto error;
4882 }
4883
4884 ret = get_unary_unsigned(
4885 &entry_node->u.ctf_expression.right, &freq);
4886 if (ret) {
28973adf
PP
4887 _BT_LOGE_NODE(entry_node,
4888 "Unexpected unary expression for clock class's `freq` attribute.");
e98a2d6e
PP
4889 ret = -EINVAL;
4890 goto error;
4891 }
4892
239744fc
PP
4893 if (freq == -1ULL || freq == 0) {
4894 _BT_LOGE_NODE(entry_node,
4895 "Invalid clock class frequency: freq=%" PRIu64,
4896 freq);
4897 ret = -EINVAL;
4898 goto error;
4899 }
4900
50842bdc 4901 ret = bt_clock_class_set_frequency(clock, freq);
e98a2d6e 4902 if (ret) {
28973adf
PP
4903 _BT_LOGE_NODE(entry_node,
4904 "Cannot set clock class's frequency.");
e98a2d6e
PP
4905 goto error;
4906 }
4907
4908 _SET(set, _CLOCK_FREQ_SET);
4909 } else if (!strcmp(left, "precision")) {
4910 uint64_t precision;
4911
4912 if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
28973adf
PP
4913 _BT_LOGE_DUP_ATTR(entry_node, "precision",
4914 "clock class");
e98a2d6e
PP
4915 ret = -EPERM;
4916 goto error;
4917 }
4918
4919 ret = get_unary_unsigned(
4920 &entry_node->u.ctf_expression.right, &precision);
4921 if (ret) {
28973adf
PP
4922 _BT_LOGE_NODE(entry_node,
4923 "Unexpected unary expression for clock class's `precision` attribute.");
e98a2d6e
PP
4924 ret = -EINVAL;
4925 goto error;
4926 }
4927
50842bdc 4928 ret = bt_clock_class_set_precision(clock, precision);
e98a2d6e 4929 if (ret) {
28973adf
PP
4930 _BT_LOGE_NODE(entry_node,
4931 "Cannot set clock class's precision.");
e98a2d6e
PP
4932 goto error;
4933 }
4934
4935 _SET(set, _CLOCK_PRECISION_SET);
4936 } else if (!strcmp(left, "offset_s")) {
fb4ac437 4937 int64_t offset_s;
e98a2d6e
PP
4938
4939 if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
28973adf
PP
4940 _BT_LOGE_DUP_ATTR(entry_node, "offset_s",
4941 "clock class");
e98a2d6e
PP
4942 ret = -EPERM;
4943 goto error;
4944 }
4945
fb4ac437 4946 ret = get_unary_signed(
e98a2d6e
PP
4947 &entry_node->u.ctf_expression.right, &offset_s);
4948 if (ret) {
28973adf
PP
4949 _BT_LOGE_NODE(entry_node,
4950 "Unexpected unary expression for clock class's `offset_s` attribute.");
e98a2d6e
PP
4951 ret = -EINVAL;
4952 goto error;
4953 }
4954
50842bdc 4955 ret = bt_clock_class_set_offset_s(clock, offset_s);
e98a2d6e 4956 if (ret) {
28973adf
PP
4957 _BT_LOGE_NODE(entry_node,
4958 "Cannot set clock class's offset in seconds.");
e98a2d6e
PP
4959 goto error;
4960 }
4961
4962 _SET(set, _CLOCK_OFFSET_S_SET);
4963 } else if (!strcmp(left, "offset")) {
fb4ac437 4964 int64_t offset;
e98a2d6e
PP
4965
4966 if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
28973adf 4967 _BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
e98a2d6e
PP
4968 ret = -EPERM;
4969 goto error;
4970 }
4971
fb4ac437 4972 ret = get_unary_signed(
e98a2d6e
PP
4973 &entry_node->u.ctf_expression.right, &offset);
4974 if (ret) {
28973adf
PP
4975 _BT_LOGE_NODE(entry_node,
4976 "Unexpected unary expression for clock class's `offset` attribute.");
e98a2d6e
PP
4977 ret = -EINVAL;
4978 goto error;
4979 }
4980
50842bdc 4981 ret = bt_clock_class_set_offset_cycles(clock, offset);
e98a2d6e 4982 if (ret) {
28973adf
PP
4983 _BT_LOGE_NODE(entry_node,
4984 "Cannot set clock class's offset in cycles.");
e98a2d6e
PP
4985 goto error;
4986 }
4987
4988 _SET(set, _CLOCK_OFFSET_SET);
4989 } else if (!strcmp(left, "absolute")) {
4990 struct ctf_node *right;
4991
4992 if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
28973adf
PP
4993 _BT_LOGE_DUP_ATTR(entry_node, "absolute",
4994 "clock class");
e98a2d6e
PP
4995 ret = -EPERM;
4996 goto error;
4997 }
4998
4999 right = _BT_LIST_FIRST_ENTRY(
5000 &entry_node->u.ctf_expression.right,
5001 struct ctf_node, siblings);
55314f2a 5002 ret = get_boolean(right);
e98a2d6e 5003 if (ret < 0) {
28973adf
PP
5004 _BT_LOGE_NODE(entry_node,
5005 "Unexpected unary expression for clock class's `absolute` attribute.");
e98a2d6e
PP
5006 ret = -EINVAL;
5007 goto error;
5008 }
5009
50842bdc 5010 ret = bt_clock_class_set_is_absolute(clock, ret);
e98a2d6e 5011 if (ret) {
28973adf
PP
5012 _BT_LOGE_NODE(entry_node,
5013 "Cannot set clock class's absolute flag.");
e98a2d6e
PP
5014 goto error;
5015 }
5016
5017 _SET(set, _CLOCK_ABSOLUTE_SET);
5018 } else {
28973adf
PP
5019 _BT_LOGW_NODE(entry_node,
5020 "Unknown attribute in clock class: attr-name=\"%s\"",
e98a2d6e
PP
5021 left);
5022 }
5023
5024 g_free(left);
5025 left = NULL;
5026
5027 return 0;
5028
5029error:
5030 g_free(left);
5031
5032 return ret;
5033}
5034
5035static
55314f2a 5036int64_t cycles_from_ns(uint64_t frequency, int64_t ns)
92540773 5037{
55314f2a 5038 int64_t cycles;
92540773
JD
5039
5040 /* 1GHz */
5041 if (frequency == 1000000000ULL) {
5042 cycles = ns;
5043 } else {
5044 cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
5045 }
5046
5047 return cycles;
5048}
5049
5050static
50842bdc 5051int apply_clock_class_offset(struct ctx *ctx, struct bt_clock_class *clock)
92540773
JD
5052{
5053 int ret;
5054 uint64_t freq;
5055 int64_t offset_cycles;
a2a54545 5056 int64_t offset_to_apply;
92540773 5057
50842bdc 5058 freq = bt_clock_class_get_frequency(clock);
92540773 5059 if (freq == -1ULL) {
08da4f77 5060 BT_LOGE_STR("Cannot get clock class's frequency.");
92540773
JD
5061 ret = -1;
5062 goto end;
5063 }
5064
50842bdc 5065 ret = bt_clock_class_get_offset_cycles(clock, &offset_cycles);
92540773 5066 if (ret) {
08da4f77 5067 BT_LOGE_STR("Cannot get clock class's offset in cycles.");
92540773
JD
5068 ret = -1;
5069 goto end;
5070 }
5071
a2a54545
PP
5072 offset_to_apply =
5073 ctx->decoder_config.clock_class_offset_s * 1000000000LL +
5074 ctx->decoder_config.clock_class_offset_ns;
5075 offset_cycles += cycles_from_ns(freq, offset_to_apply);
50842bdc 5076 ret = bt_clock_class_set_offset_cycles(clock, offset_cycles);
92540773
JD
5077
5078end:
5079 return ret;
5080}
5081
5082static
1e649dff 5083int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
e98a2d6e
PP
5084{
5085 int ret = 0;
5086 int set = 0;
50842bdc 5087 struct bt_clock_class *clock;
e98a2d6e
PP
5088 struct ctf_node *entry_node;
5089 struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
f4421ff3 5090 const char *clock_class_name;
e98a2d6e
PP
5091
5092 if (clock_node->visited) {
5093 return 0;
5094 }
5095
5096 clock_node->visited = TRUE;
f3534905
PP
5097
5098 /* CTF 1.8's default frequency for a clock class is 1 GHz */
50842bdc 5099 clock = bt_clock_class_create(NULL, 1000000000);
e98a2d6e 5100 if (!clock) {
28973adf
PP
5101 _BT_LOGE_NODE(clock_node,
5102 "Cannot create default clock class.");
e98a2d6e
PP
5103 ret = -ENOMEM;
5104 goto error;
5105 }
5106
5107 bt_list_for_each_entry(entry_node, decl_list, siblings) {
5108 ret = visit_clock_decl_entry(ctx, entry_node, clock, &set);
5109 if (ret) {
28973adf
PP
5110 _BT_LOGE_NODE(entry_node,
5111 "Cannot visit clock class's entry: ret=%d",
5112 ret);
e98a2d6e
PP
5113 goto error;
5114 }
5115 }
5116
5117 if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
28973adf
PP
5118 _BT_LOGE_NODE(clock_node,
5119 "Missing `name` attribute in clock class.");
e98a2d6e
PP
5120 ret = -EPERM;
5121 goto error;
5122 }
5123
50842bdc 5124 clock_class_name = bt_clock_class_get_name(clock);
f4421ff3
PP
5125 assert(clock_class_name);
5126 if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
5127 /*
5128 * Old versions of LTTng forgot to set its clock class
5129 * as absolute, even if it is. This is important because
5130 * it's a condition to be able to sort notifications
5131 * from different sources.
5132 */
50842bdc 5133 ret = bt_clock_class_set_is_absolute(clock, 1);
f4421ff3 5134 if (ret) {
28973adf
PP
5135 _BT_LOGE_NODE(clock_node,
5136 "Cannot set clock class's absolute flag.");
f4421ff3
PP
5137 goto error;
5138 }
e98a2d6e
PP
5139 }
5140
1e649dff 5141 ret = apply_clock_class_offset(ctx, clock);
92540773 5142 if (ret) {
28973adf
PP
5143 _BT_LOGE_NODE(clock_node,
5144 "Cannot apply clock class's custom offset.");
92540773
JD
5145 goto error;
5146 }
5147
50842bdc 5148 ret = bt_trace_add_clock_class(ctx->trace, clock);
e98a2d6e 5149 if (ret) {
28973adf
PP
5150 _BT_LOGE_NODE(clock_node,
5151 "Cannot add clock class to trace.");
e98a2d6e
PP
5152 goto error;
5153 }
5154
5155error:
5156 BT_PUT(clock);
5157
5158 return ret;
5159}
5160
5161static
5162int visit_root_decl(struct ctx *ctx, struct ctf_node *root_decl_node)
5163{
5164 int ret = 0;
5165
5166 if (root_decl_node->visited) {
5167 goto end;
5168 }
5169
5170 root_decl_node->visited = TRUE;
5171
5172 switch (root_decl_node->type) {
5173 case NODE_TYPEDEF:
5174 ret = visit_typedef(ctx,
5175 root_decl_node->u._typedef.type_specifier_list,
5176 &root_decl_node->u._typedef.type_declarators);
5177 if (ret) {
28973adf
PP
5178 _BT_LOGE_NODE(root_decl_node,
5179 "Cannot add type definition found in root scope.");
e98a2d6e
PP
5180 goto end;
5181 }
5182 break;
5183 case NODE_TYPEALIAS:
5184 ret = visit_typealias(ctx, root_decl_node->u.typealias.target,
5185 root_decl_node->u.typealias.alias);
5186 if (ret) {
28973adf
PP
5187 _BT_LOGE_NODE(root_decl_node,
5188 "Cannot add type alias found in root scope.");
e98a2d6e
PP
5189 goto end;
5190 }
5191 break;
5192 case NODE_TYPE_SPECIFIER_LIST:
5193 {
50842bdc 5194 _BT_FIELD_TYPE_INIT(decl);
e98a2d6e
PP
5195
5196 /*
5197 * Just add the type specifier to the root
5198 * declaration scope. Put local reference.
5199 */
5200 ret = visit_type_specifier_list(ctx, root_decl_node, &decl);
5201 if (ret) {
28973adf
PP
5202 _BT_LOGE_NODE(root_decl_node,
5203 "Cannot visit root scope's field type: "
5204 "ret=%d", ret);
e98a2d6e
PP
5205 assert(!decl);
5206 goto end;
5207 }
5208
5209 BT_PUT(decl);
5210 break;
5211 }
5212 default:
28973adf
PP
5213 _BT_LOGE_NODE(root_decl_node,
5214 "Unexpected node type: node-type=%d",
5215 root_decl_node->type);
e98a2d6e
PP
5216 ret = -EPERM;
5217 goto end;
5218 }
5219
5220end:
5221 return ret;
5222}
5223
91fd6f6a
PP
5224static
5225int set_trace_name(struct ctx *ctx)
5226{
5227 GString *name;
5228 int ret = 0;
5229 struct bt_value *value = NULL;
5230
50842bdc 5231 assert(bt_trace_get_stream_class_count(ctx->trace) == 0);
91fd6f6a
PP
5232 name = g_string_new(NULL);
5233 if (!name) {
28973adf 5234 BT_LOGE_STR("Failed to allocate a GString.");
91fd6f6a
PP
5235 ret = -1;
5236 goto end;
5237 }
5238
5239 /*
5240 * Check if we have a trace environment string value named `hostname`.
5241 * If so, use it as the trace name's prefix.
5242 */
50842bdc 5243 value = bt_trace_get_environment_field_value_by_name(ctx->trace,
91fd6f6a
PP
5244 "hostname");
5245 if (bt_value_is_string(value)) {
5246 const char *hostname;
5247
5248 ret = bt_value_string_get(value, &hostname);
5249 assert(ret == 0);
5250 g_string_append(name, hostname);
5251
5252 if (ctx->trace_name_suffix) {
5253 g_string_append_c(name, G_DIR_SEPARATOR);
5254 }
5255 }
5256
5257 if (ctx->trace_name_suffix) {
5258 g_string_append(name, ctx->trace_name_suffix);
5259 }
5260
50842bdc 5261 ret = bt_trace_set_name(ctx->trace, name->str);
91fd6f6a 5262 if (ret) {
28973adf 5263 BT_LOGE("Cannot set trace's name: name=\"%s\"", name->str);
91fd6f6a
PP
5264 goto error;
5265 }
5266
5267 goto end;
5268
5269error:
5270 ret = -1;
5271
5272end:
5273 bt_put(value);
5274
5275 if (name) {
5276 g_string_free(name, TRUE);
5277 }
5278
5279 return ret;
5280}
5281
e98a2d6e 5282static
1e649dff 5283int move_ctx_stream_classes_to_trace(struct ctx *ctx)
e98a2d6e 5284{
fde61d26 5285 int ret = 0;
e98a2d6e
PP
5286 GHashTableIter iter;
5287 gpointer key, stream_class;
5288
91fd6f6a 5289 if (g_hash_table_size(ctx->stream_classes) > 0 &&
50842bdc 5290 bt_trace_get_stream_class_count(ctx->trace) == 0) {
91fd6f6a
PP
5291 /*
5292 * We're about to add the first stream class to the
5293 * trace. This will freeze the trace, and after this
5294 * we cannot set the name anymore. At this point,
5295 * set the trace name.
5296 */
5297 ret = set_trace_name(ctx);
5298 if (ret) {
28973adf 5299 BT_LOGE_STR("Cannot set trace's name.");
91fd6f6a
PP
5300 goto end;
5301 }
5302 }
5303
e98a2d6e
PP
5304 g_hash_table_iter_init(&iter, ctx->stream_classes);
5305
5306 while (g_hash_table_iter_next(&iter, &key, &stream_class)) {
50842bdc 5307 ret = bt_trace_add_stream_class(ctx->trace,
e98a2d6e
PP
5308 stream_class);
5309 if (ret) {
50842bdc 5310 int64_t id = bt_stream_class_get_id(stream_class);
08da4f77 5311 BT_LOGE("Cannot add stream class to trace: id=%" PRId64,
e98a2d6e
PP
5312 id);
5313 goto end;
5314 }
5315 }
5316
1e649dff
PP
5317 g_hash_table_remove_all(ctx->stream_classes);
5318
e98a2d6e
PP
5319end:
5320 return ret;
5321}
5322
1e649dff 5323BT_HIDDEN
55314f2a 5324struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
a2a54545
PP
5325 const struct ctf_metadata_decoder_config *decoder_config,
5326 const char *name)
e98a2d6e 5327{
1e649dff 5328 int ret;
e98a2d6e 5329 struct ctx *ctx = NULL;
50842bdc 5330 struct bt_trace *trace;
e98a2d6e 5331
50842bdc 5332 trace = bt_trace_create();
1e649dff 5333 if (!trace) {
08da4f77 5334 BT_LOGE_STR("Cannot create empty trace.");
e98a2d6e
PP
5335 goto error;
5336 }
5337
835b2d10 5338 /* Set packet header to NULL to override the default one */
50842bdc 5339 ret = bt_trace_set_packet_header_type(trace, NULL);
e98a2d6e 5340 if (ret) {
08da4f77 5341 BT_LOGE_STR("Cannot reset initial trace's packet header field type.");
e98a2d6e
PP
5342 goto error;
5343 }
5344
1e649dff 5345 /* Create visitor's context */
a2a54545 5346 ctx = ctx_create(trace, decoder_config, name);
e98a2d6e 5347 if (!ctx) {
08da4f77 5348 BT_LOGE_STR("Cannot create visitor's context.");
e98a2d6e
PP
5349 goto error;
5350 }
5351
1e649dff
PP
5352 trace = NULL;
5353 goto end;
5354
5355error:
5356 ctx_destroy(ctx);
5357 ctx = NULL;
5358
5359end:
5360 bt_put(trace);
5361 return (void *) ctx;
5362}
5363
5364BT_HIDDEN
5365void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor)
5366{
5367 ctx_destroy((void *) visitor);
5368}
5369
5370BT_HIDDEN
50842bdc 5371struct bt_trace *ctf_visitor_generate_ir_get_trace(
1e649dff
PP
5372 struct ctf_visitor_generate_ir *visitor)
5373{
5374 struct ctx *ctx = (void *) visitor;
5375
5376 assert(ctx);
5377 assert(ctx->trace);
5378 return bt_get(ctx->trace);
5379}
5380
5381BT_HIDDEN
5382int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
5383 struct ctf_node *node)
5384{
5385 int ret = 0;
5386 struct ctx *ctx = (void *) visitor;
5387
08da4f77 5388 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
1e649dff 5389
e98a2d6e
PP
5390 switch (node->type) {
5391 case NODE_ROOT:
5392 {
5393 struct ctf_node *iter;
5394 int got_trace_decl = FALSE;
e98a2d6e
PP
5395
5396 /*
1e649dff
PP
5397 * The first thing we need is the native byte order of
5398 * the trace block, because early type aliases can have
5399 * a `byte_order` attribute set to `native`. If we don't
5400 * have the native byte order yet, and we don't have any
5401 * trace block yet, then fail with EINCOMPLETE.
e98a2d6e 5402 */
50842bdc 5403 if (ctx->trace_bo == BT_BYTE_ORDER_NATIVE) {
1e649dff
PP
5404 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5405 if (got_trace_decl) {
28973adf
PP
5406 _BT_LOGE_NODE(node,
5407 "Duplicate trace (`trace` block).");
1e649dff
PP
5408 ret = -1;
5409 goto end;
5410 }
e98a2d6e 5411
1e649dff
PP
5412 ret = set_trace_byte_order(ctx, iter);
5413 if (ret) {
28973adf
PP
5414 _BT_LOGE_NODE(node,
5415 "Cannot set trace's native byte order: "
08da4f77 5416 "ret=%d", ret);
1e649dff
PP
5417 goto end;
5418 }
5419
5420 got_trace_decl = TRUE;
e98a2d6e
PP
5421 }
5422
1e649dff 5423 if (!got_trace_decl) {
28973adf 5424 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
1e649dff
PP
5425 ret = -EINCOMPLETE;
5426 goto end;
5427 }
e98a2d6e
PP
5428 }
5429
50842bdc
PP
5430 assert(ctx->trace_bo == BT_BYTE_ORDER_LITTLE_ENDIAN ||
5431 ctx->trace_bo == BT_BYTE_ORDER_BIG_ENDIAN);
1e649dff
PP
5432 assert(ctx->current_scope &&
5433 ctx->current_scope->parent_scope == NULL);
e98a2d6e 5434
f4421ff3
PP
5435 /* Environment */
5436 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
5437 ret = visit_env(ctx, iter);
5438 if (ret) {
28973adf
PP
5439 _BT_LOGE_NODE(iter,
5440 "Cannot visit trace's environment (`env` block) entry: "
08da4f77 5441 "ret=%d", ret);
f4421ff3
PP
5442 goto end;
5443 }
5444 }
5445
5446 assert(ctx->current_scope &&
5447 ctx->current_scope->parent_scope == NULL);
5448
e98a2d6e 5449 /*
f4421ff3 5450 * Visit clock blocks.
e98a2d6e
PP
5451 */
5452 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
1e649dff 5453 ret = visit_clock_decl(ctx, iter);
e98a2d6e 5454 if (ret) {
28973adf
PP
5455 _BT_LOGE_NODE(iter,
5456 "Cannot visit clock class: ret=%d",
e98a2d6e 5457 ret);
1e649dff 5458 goto end;
e98a2d6e
PP
5459 }
5460 }
5461
1e649dff
PP
5462 assert(ctx->current_scope &&
5463 ctx->current_scope->parent_scope == NULL);
5464
e98a2d6e
PP
5465 /*
5466 * Visit root declarations next, as they can be used by any
5467 * following entity.
5468 */
5469 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
5470 siblings) {
5471 ret = visit_root_decl(ctx, iter);
5472 if (ret) {
28973adf
PP
5473 _BT_LOGE_NODE(iter,
5474 "Cannot visit root entry: ret=%d",
e98a2d6e 5475 ret);
1e649dff 5476 goto end;
e98a2d6e
PP
5477 }
5478 }
5479
1e649dff
PP
5480 assert(ctx->current_scope &&
5481 ctx->current_scope->parent_scope == NULL);
5482
5483 /* Callsite blocks are not supported */
e98a2d6e 5484 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
28973adf
PP
5485 _BT_LOGW_NODE(iter,
5486 "\"callsite\" blocks are not supported as of this version.");
e98a2d6e
PP
5487 }
5488
1e649dff
PP
5489 assert(ctx->current_scope &&
5490 ctx->current_scope->parent_scope == NULL);
5491
e98a2d6e
PP
5492 /* Trace */
5493 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
5494 ret = visit_trace_decl(ctx, iter);
5495 if (ret) {
28973adf
PP
5496 _BT_LOGE_NODE(iter,
5497 "Cannot visit trace (`trace` block): "
08da4f77 5498 "ret=%d", ret);
1e649dff 5499 goto end;
e98a2d6e
PP
5500 }
5501 }
5502
1e649dff
PP
5503 assert(ctx->current_scope &&
5504 ctx->current_scope->parent_scope == NULL);
5505
e98a2d6e
PP
5506 /* Streams */
5507 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
5508 ret = visit_stream_decl(ctx, iter);
5509 if (ret) {
28973adf
PP
5510 _BT_LOGE_NODE(iter,
5511 "Cannot visit stream class: ret=%d",
08da4f77 5512 ret);
1e649dff 5513 goto end;
e98a2d6e
PP
5514 }
5515 }
5516
1e649dff
PP
5517 assert(ctx->current_scope &&
5518 ctx->current_scope->parent_scope == NULL);
5519
e98a2d6e
PP
5520 /* Events */
5521 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
5522 ret = visit_event_decl(ctx, iter);
5523 if (ret) {
28973adf
PP
5524 _BT_LOGE_NODE(iter,
5525 "Cannot visit event class: ret=%d",
08da4f77 5526 ret);
1e649dff 5527 goto end;
e98a2d6e
PP
5528 }
5529 }
1e649dff
PP
5530
5531 assert(ctx->current_scope &&
5532 ctx->current_scope->parent_scope == NULL);
e98a2d6e
PP
5533 break;
5534 }
e98a2d6e 5535 default:
28973adf
PP
5536 _BT_LOGE_NODE(node,
5537 "Unexpected node type: node-type=%d",
08da4f77 5538 node->type);
e98a2d6e 5539 ret = -EINVAL;
1e649dff 5540 goto end;
e98a2d6e
PP
5541 }
5542
1e649dff
PP
5543 /* Move decoded stream classes to trace, if any */
5544 ret = move_ctx_stream_classes_to_trace(ctx);
e98a2d6e 5545 if (ret) {
08da4f77 5546 BT_LOGE("Cannot move stream classes to trace: ret=%d", ret);
e98a2d6e
PP
5547 }
5548
1e649dff 5549end:
e98a2d6e
PP
5550 return ret;
5551}
This page took 0.360624 seconds and 4 git commands to generate.