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