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