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