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