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