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