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