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