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