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