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