API : list of events in the trace
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
1 /*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <glib.h>
25 #include <inttypes.h>
26 #include <errno.h>
27 #include <babeltrace/babeltrace-internal.h>
28 #include <babeltrace/list.h>
29 #include <babeltrace/types.h>
30 #include <babeltrace/ctf/metadata.h>
31 #include <babeltrace/uuid.h>
32 #include <babeltrace/endian.h>
33 #include <babeltrace/ctf/events-internal.h>
34 #include "ctf-scanner.h"
35 #include "ctf-parser.h"
36 #include "ctf-ast.h"
37
38 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
39
40 #define _bt_list_first_entry(ptr, type, member) \
41 bt_list_entry((ptr)->next, type, member)
42
43 int opt_clock_force_correlate;
44
45 static
46 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
47 int depth, struct ctf_node *type_specifier_list,
48 struct declaration_scope *declaration_scope,
49 struct ctf_trace *trace);
50
51 static
52 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
53 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
54
55 static
56 int is_unary_string(struct bt_list_head *head)
57 {
58 struct ctf_node *node;
59
60 bt_list_for_each_entry(node, head, siblings) {
61 if (node->type != NODE_UNARY_EXPRESSION)
62 return 0;
63 if (node->u.unary_expression.type != UNARY_STRING)
64 return 0;
65 }
66 return 1;
67 }
68
69 /*
70 * String returned must be freed by the caller using g_free.
71 */
72 static
73 char *concatenate_unary_strings(struct bt_list_head *head)
74 {
75 struct ctf_node *node;
76 GString *str;
77 int i = 0;
78
79 str = g_string_new("");
80 bt_list_for_each_entry(node, head, siblings) {
81 char *src_string;
82
83 assert(node->type == NODE_UNARY_EXPRESSION);
84 assert(node->u.unary_expression.type == UNARY_STRING);
85 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
86 ^ (i != 0));
87 switch (node->u.unary_expression.link) {
88 case UNARY_DOTLINK:
89 g_string_append(str, ".");
90 break;
91 case UNARY_ARROWLINK:
92 g_string_append(str, "->");
93 break;
94 case UNARY_DOTDOTDOT:
95 g_string_append(str, "...");
96 break;
97 default:
98 break;
99 }
100 src_string = node->u.unary_expression.u.string;
101 g_string_append(str, src_string);
102 i++;
103 }
104 return g_string_free(str, FALSE);
105 }
106
107 static
108 GQuark get_map_clock_name_value(struct bt_list_head *head)
109 {
110 struct ctf_node *node;
111 const char *name = NULL;
112 int i = 0;
113
114 bt_list_for_each_entry(node, head, siblings) {
115 char *src_string;
116
117 assert(node->type == NODE_UNARY_EXPRESSION);
118 assert(node->u.unary_expression.type == UNARY_STRING);
119 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
120 ^ (i != 0));
121 /* needs to be chained with . */
122 switch (node->u.unary_expression.link) {
123 case UNARY_DOTLINK:
124 break;
125 case UNARY_ARROWLINK:
126 case UNARY_DOTDOTDOT:
127 return 0;
128 default:
129 break;
130 }
131 src_string = node->u.unary_expression.u.string;
132 switch (i) {
133 case 0: if (strcmp("clock", src_string) != 0) {
134 return 0;
135 }
136 break;
137 case 1: name = src_string;
138 break;
139 case 2: if (strcmp("value", src_string) != 0) {
140 return 0;
141 }
142 break;
143 default:
144 return 0; /* extra identifier, unknown */
145 }
146 i++;
147 }
148 return g_quark_from_string(name);
149 }
150
151 static
152 int is_unary_unsigned(struct bt_list_head *head)
153 {
154 struct ctf_node *node;
155
156 bt_list_for_each_entry(node, head, siblings) {
157 if (node->type != NODE_UNARY_EXPRESSION)
158 return 0;
159 if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
160 return 0;
161 }
162 return 1;
163 }
164
165 static
166 int get_unary_unsigned(struct bt_list_head *head, uint64_t *value)
167 {
168 struct ctf_node *node;
169 int i = 0;
170
171 bt_list_for_each_entry(node, head, siblings) {
172 assert(node->type == NODE_UNARY_EXPRESSION);
173 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
174 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
175 assert(i == 0);
176 *value = node->u.unary_expression.u.unsigned_constant;
177 i++;
178 }
179 return 0;
180 }
181
182 static
183 int is_unary_signed(struct bt_list_head *head)
184 {
185 struct ctf_node *node;
186
187 bt_list_for_each_entry(node, head, siblings) {
188 if (node->type != NODE_UNARY_EXPRESSION)
189 return 0;
190 if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT)
191 return 0;
192 }
193 return 1;
194 }
195
196 static
197 int get_unary_signed(struct bt_list_head *head, int64_t *value)
198 {
199 struct ctf_node *node;
200 int i = 0;
201
202 bt_list_for_each_entry(node, head, siblings) {
203 assert(node->type == NODE_UNARY_EXPRESSION);
204 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT
205 || node->u.unary_expression.type == UNARY_SIGNED_CONSTANT);
206 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
207 assert(i == 0);
208 switch (node->u.unary_expression.type) {
209 case UNARY_UNSIGNED_CONSTANT:
210 *value = (int64_t) node->u.unary_expression.u.unsigned_constant;
211 break;
212 case UNARY_SIGNED_CONSTANT:
213 *value = node->u.unary_expression.u.signed_constant;
214 break;
215 default:
216 assert(0);
217 }
218 i++;
219 }
220 return 0;
221 }
222
223 static
224 int get_unary_uuid(struct bt_list_head *head, unsigned char *uuid)
225 {
226 struct ctf_node *node;
227 int i = 0;
228 int ret = -1;
229
230 bt_list_for_each_entry(node, head, siblings) {
231 const char *src_string;
232
233 assert(node->type == NODE_UNARY_EXPRESSION);
234 assert(node->u.unary_expression.type == UNARY_STRING);
235 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
236 assert(i == 0);
237 src_string = node->u.unary_expression.u.string;
238 ret = babeltrace_uuid_parse(src_string, uuid);
239 }
240 return ret;
241 }
242
243 static
244 struct ctf_stream_declaration *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
245 {
246 if (trace->streams->len <= stream_id)
247 return NULL;
248 return g_ptr_array_index(trace->streams, stream_id);
249 }
250
251 static
252 struct ctf_clock *trace_clock_lookup(struct ctf_trace *trace, GQuark clock_name)
253 {
254 return g_hash_table_lookup(trace->clocks, (gpointer) (unsigned long) clock_name);
255 }
256
257 static
258 int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
259 {
260 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
261
262 switch (type_specifier->u.type_specifier.type) {
263 case TYPESPEC_VOID:
264 g_string_append(str, "void");
265 break;
266 case TYPESPEC_CHAR:
267 g_string_append(str, "char");
268 break;
269 case TYPESPEC_SHORT:
270 g_string_append(str, "short");
271 break;
272 case TYPESPEC_INT:
273 g_string_append(str, "int");
274 break;
275 case TYPESPEC_LONG:
276 g_string_append(str, "long");
277 break;
278 case TYPESPEC_FLOAT:
279 g_string_append(str, "float");
280 break;
281 case TYPESPEC_DOUBLE:
282 g_string_append(str, "double");
283 break;
284 case TYPESPEC_SIGNED:
285 g_string_append(str, "signed");
286 break;
287 case TYPESPEC_UNSIGNED:
288 g_string_append(str, "unsigned");
289 break;
290 case TYPESPEC_BOOL:
291 g_string_append(str, "bool");
292 break;
293 case TYPESPEC_COMPLEX:
294 g_string_append(str, "_Complex");
295 break;
296 case TYPESPEC_IMAGINARY:
297 g_string_append(str, "_Imaginary");
298 break;
299 case TYPESPEC_CONST:
300 g_string_append(str, "const");
301 break;
302 case TYPESPEC_ID_TYPE:
303 if (type_specifier->u.type_specifier.id_type)
304 g_string_append(str, type_specifier->u.type_specifier.id_type);
305 break;
306 case TYPESPEC_STRUCT:
307 {
308 struct ctf_node *node = type_specifier->u.type_specifier.node;
309
310 if (!node->u._struct.name) {
311 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
312 return -EINVAL;
313 }
314 g_string_append(str, "struct ");
315 g_string_append(str, node->u._struct.name);
316 break;
317 }
318 case TYPESPEC_VARIANT:
319 {
320 struct ctf_node *node = type_specifier->u.type_specifier.node;
321
322 if (!node->u.variant.name) {
323 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
324 return -EINVAL;
325 }
326 g_string_append(str, "variant ");
327 g_string_append(str, node->u.variant.name);
328 break;
329 }
330 case TYPESPEC_ENUM:
331 {
332 struct ctf_node *node = type_specifier->u.type_specifier.node;
333
334 if (!node->u._enum.enum_id) {
335 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
336 return -EINVAL;
337 }
338 g_string_append(str, "enum ");
339 g_string_append(str, node->u._enum.enum_id);
340 break;
341 }
342 case TYPESPEC_FLOATING_POINT:
343 case TYPESPEC_INTEGER:
344 case TYPESPEC_STRING:
345 default:
346 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
347 return -EINVAL;
348 }
349 return 0;
350 }
351
352 static
353 int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
354 {
355 struct ctf_node *iter;
356 int alias_item_nr = 0;
357 int ret;
358
359 bt_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
360 if (alias_item_nr != 0)
361 g_string_append(str, " ");
362 alias_item_nr++;
363 ret = visit_type_specifier(fd, iter, str);
364 if (ret)
365 return ret;
366 }
367 return 0;
368 }
369
370 static
371 GQuark create_typealias_identifier(FILE *fd, int depth,
372 struct ctf_node *type_specifier_list,
373 struct ctf_node *node_type_declarator)
374 {
375 struct ctf_node *iter;
376 GString *str;
377 char *str_c;
378 GQuark alias_q;
379 int ret;
380
381 str = g_string_new("");
382 ret = visit_type_specifier_list(fd, type_specifier_list, str);
383 if (ret) {
384 g_string_free(str, TRUE);
385 return 0;
386 }
387 bt_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
388 g_string_append(str, " *");
389 if (iter->u.pointer.const_qualifier)
390 g_string_append(str, " const");
391 }
392 str_c = g_string_free(str, FALSE);
393 alias_q = g_quark_from_string(str_c);
394 g_free(str_c);
395 return alias_q;
396 }
397
398 static
399 struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
400 struct ctf_node *type_specifier_list,
401 GQuark *field_name,
402 struct ctf_node *node_type_declarator,
403 struct declaration_scope *declaration_scope,
404 struct declaration *nested_declaration,
405 struct ctf_trace *trace)
406 {
407 /*
408 * Visit type declarator by first taking care of sequence/array
409 * (recursively). Then, when we get to the identifier, take care
410 * of pointers.
411 */
412
413 if (node_type_declarator) {
414 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
415
416 /* TODO: gcc bitfields not supported yet. */
417 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
418 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
419 return NULL;
420 }
421 }
422
423 if (!nested_declaration) {
424 if (node_type_declarator && !bt_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
425 GQuark alias_q;
426
427 /*
428 * If we have a pointer declarator, it _has_ to be present in
429 * the typealiases (else fail).
430 */
431 alias_q = create_typealias_identifier(fd, depth,
432 type_specifier_list, node_type_declarator);
433 nested_declaration = lookup_declaration(alias_q, declaration_scope);
434 if (!nested_declaration) {
435 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
436 return NULL;
437 }
438 if (nested_declaration->id == CTF_TYPE_INTEGER) {
439 struct declaration_integer *integer_declaration =
440 container_of(nested_declaration, struct declaration_integer, p);
441 /* For base to 16 for pointers (expected pretty-print) */
442 if (!integer_declaration->base) {
443 /*
444 * We need to do a copy of the
445 * integer declaration to modify it. There could be other references to
446 * it.
447 */
448 integer_declaration = integer_declaration_new(integer_declaration->len,
449 integer_declaration->byte_order, integer_declaration->signedness,
450 integer_declaration->p.alignment, 16, integer_declaration->encoding,
451 integer_declaration->clock);
452 nested_declaration = &integer_declaration->p;
453 }
454 }
455 } else {
456 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
457 type_specifier_list, declaration_scope, trace);
458 }
459 }
460
461 if (!node_type_declarator)
462 return nested_declaration;
463
464 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
465 if (node_type_declarator->u.type_declarator.u.id)
466 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
467 else
468 *field_name = 0;
469 return nested_declaration;
470 } else {
471 struct declaration *declaration;
472 struct ctf_node *first;
473
474 /* TYPEDEC_NESTED */
475
476 if (!nested_declaration) {
477 fprintf(fd, "[error] %s: nested type is unknown.\n", __func__);
478 return NULL;
479 }
480
481 /* create array/sequence, pass nested_declaration as child. */
482 if (bt_list_empty(&node_type_declarator->u.type_declarator.u.nested.length)) {
483 fprintf(fd, "[error] %s: expecting length field reference or value.\n", __func__);
484 return NULL;
485 }
486 first = _bt_list_first_entry(&node_type_declarator->u.type_declarator.u.nested.length,
487 struct ctf_node, siblings);
488 assert(first->type == NODE_UNARY_EXPRESSION);
489
490 switch (first->u.unary_expression.type) {
491 case UNARY_UNSIGNED_CONSTANT:
492 {
493 struct declaration_array *array_declaration;
494 size_t len;
495
496 len = first->u.unary_expression.u.unsigned_constant;
497 array_declaration = array_declaration_new(len, nested_declaration,
498 declaration_scope);
499
500 if (!array_declaration) {
501 fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__);
502 return NULL;
503 }
504 declaration = &array_declaration->p;
505 break;
506 }
507 case UNARY_STRING:
508 {
509 /* Lookup unsigned integer definition, create sequence */
510 char *length_name = concatenate_unary_strings(&node_type_declarator->u.type_declarator.u.nested.length);
511 struct declaration_sequence *sequence_declaration;
512
513 sequence_declaration = sequence_declaration_new(length_name, nested_declaration, declaration_scope);
514 if (!sequence_declaration) {
515 fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__);
516 return NULL;
517 }
518 declaration = &sequence_declaration->p;
519 break;
520 }
521 default:
522 assert(0);
523 }
524
525 /* Pass it as content of outer container */
526 declaration = ctf_type_declarator_visit(fd, depth,
527 type_specifier_list, field_name,
528 node_type_declarator->u.type_declarator.u.nested.type_declarator,
529 declaration_scope, declaration, trace);
530 return declaration;
531 }
532 }
533
534 static
535 int ctf_struct_type_declarators_visit(FILE *fd, int depth,
536 struct declaration_struct *struct_declaration,
537 struct ctf_node *type_specifier_list,
538 struct bt_list_head *type_declarators,
539 struct declaration_scope *declaration_scope,
540 struct ctf_trace *trace)
541 {
542 struct ctf_node *iter;
543 GQuark field_name;
544
545 bt_list_for_each_entry(iter, type_declarators, siblings) {
546 struct declaration *field_declaration;
547
548 field_declaration = ctf_type_declarator_visit(fd, depth,
549 type_specifier_list,
550 &field_name, iter,
551 struct_declaration->scope,
552 NULL, trace);
553 if (!field_declaration) {
554 fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
555 return -EINVAL;
556 }
557
558 /* Check if field with same name already exists */
559 if (struct_declaration_lookup_field_index(struct_declaration, field_name) >= 0) {
560 fprintf(fd, "[error] %s: duplicate field %s in struct\n", __func__, g_quark_to_string(field_name));
561 return -EINVAL;
562 }
563
564 struct_declaration_add_field(struct_declaration,
565 g_quark_to_string(field_name),
566 field_declaration);
567 }
568 return 0;
569 }
570
571 static
572 int ctf_variant_type_declarators_visit(FILE *fd, int depth,
573 struct declaration_untagged_variant *untagged_variant_declaration,
574 struct ctf_node *type_specifier_list,
575 struct bt_list_head *type_declarators,
576 struct declaration_scope *declaration_scope,
577 struct ctf_trace *trace)
578 {
579 struct ctf_node *iter;
580 GQuark field_name;
581
582 bt_list_for_each_entry(iter, type_declarators, siblings) {
583 struct declaration *field_declaration;
584
585 field_declaration = ctf_type_declarator_visit(fd, depth,
586 type_specifier_list,
587 &field_name, iter,
588 untagged_variant_declaration->scope,
589 NULL, trace);
590 if (!field_declaration) {
591 fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
592 return -EINVAL;
593 }
594
595 if (untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration, field_name) != NULL) {
596 fprintf(fd, "[error] %s: duplicate field %s in variant\n", __func__, g_quark_to_string(field_name));
597 return -EINVAL;
598 }
599
600
601 untagged_variant_declaration_add_field(untagged_variant_declaration,
602 g_quark_to_string(field_name),
603 field_declaration);
604 }
605 return 0;
606 }
607
608 static
609 int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
610 struct ctf_node *type_specifier_list,
611 struct bt_list_head *type_declarators,
612 struct ctf_trace *trace)
613 {
614 struct ctf_node *iter;
615 GQuark identifier;
616
617 bt_list_for_each_entry(iter, type_declarators, siblings) {
618 struct declaration *type_declaration;
619 int ret;
620
621 type_declaration = ctf_type_declarator_visit(fd, depth,
622 type_specifier_list,
623 &identifier, iter,
624 scope, NULL, trace);
625 if (!type_declaration) {
626 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
627 return -EINVAL;
628 }
629 /*
630 * Don't allow typedef and typealias of untagged
631 * variants.
632 */
633 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
634 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
635 declaration_unref(type_declaration);
636 return -EPERM;
637 }
638 ret = register_declaration(identifier, type_declaration, scope);
639 if (ret) {
640 type_declaration->declaration_free(type_declaration);
641 return ret;
642 }
643 }
644 return 0;
645 }
646
647 static
648 int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
649 struct ctf_node *target, struct ctf_node *alias,
650 struct ctf_trace *trace)
651 {
652 struct declaration *type_declaration;
653 struct ctf_node *node;
654 GQuark dummy_id;
655 GQuark alias_q;
656 int err;
657
658 /* See ctf_visitor_type_declarator() in the semantic validator. */
659
660 /*
661 * Create target type declaration.
662 */
663
664 if (bt_list_empty(&target->u.typealias_target.type_declarators))
665 node = NULL;
666 else
667 node = _bt_list_first_entry(&target->u.typealias_target.type_declarators,
668 struct ctf_node, siblings);
669 type_declaration = ctf_type_declarator_visit(fd, depth,
670 target->u.typealias_target.type_specifier_list,
671 &dummy_id, node,
672 scope, NULL, trace);
673 if (!type_declaration) {
674 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
675 err = -EINVAL;
676 goto error;
677 }
678 /*
679 * Don't allow typedef and typealias of untagged
680 * variants.
681 */
682 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
683 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
684 declaration_unref(type_declaration);
685 return -EPERM;
686 }
687 /*
688 * The semantic validator does not check whether the target is
689 * abstract or not (if it has an identifier). Check it here.
690 */
691 if (dummy_id != 0) {
692 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
693 err = -EINVAL;
694 goto error;
695 }
696 /*
697 * Create alias identifier.
698 */
699
700 node = _bt_list_first_entry(&alias->u.typealias_alias.type_declarators,
701 struct ctf_node, siblings);
702 alias_q = create_typealias_identifier(fd, depth,
703 alias->u.typealias_alias.type_specifier_list, node);
704 err = register_declaration(alias_q, type_declaration, scope);
705 if (err)
706 goto error;
707 return 0;
708
709 error:
710 if (type_declaration) {
711 type_declaration->declaration_free(type_declaration);
712 }
713 return err;
714 }
715
716 static
717 int ctf_struct_declaration_list_visit(FILE *fd, int depth,
718 struct ctf_node *iter, struct declaration_struct *struct_declaration,
719 struct ctf_trace *trace)
720 {
721 int ret;
722
723 switch (iter->type) {
724 case NODE_TYPEDEF:
725 /* For each declarator, declare type and add type to struct declaration scope */
726 ret = ctf_typedef_visit(fd, depth,
727 struct_declaration->scope,
728 iter->u._typedef.type_specifier_list,
729 &iter->u._typedef.type_declarators, trace);
730 if (ret)
731 return ret;
732 break;
733 case NODE_TYPEALIAS:
734 /* Declare type with declarator and add type to struct declaration scope */
735 ret = ctf_typealias_visit(fd, depth,
736 struct_declaration->scope,
737 iter->u.typealias.target,
738 iter->u.typealias.alias, trace);
739 if (ret)
740 return ret;
741 break;
742 case NODE_STRUCT_OR_VARIANT_DECLARATION:
743 /* Add field to structure declaration */
744 ret = ctf_struct_type_declarators_visit(fd, depth,
745 struct_declaration,
746 iter->u.struct_or_variant_declaration.type_specifier_list,
747 &iter->u.struct_or_variant_declaration.type_declarators,
748 struct_declaration->scope, trace);
749 if (ret)
750 return ret;
751 break;
752 default:
753 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
754 assert(0);
755 }
756 return 0;
757 }
758
759 static
760 int ctf_variant_declaration_list_visit(FILE *fd, int depth,
761 struct ctf_node *iter,
762 struct declaration_untagged_variant *untagged_variant_declaration,
763 struct ctf_trace *trace)
764 {
765 int ret;
766
767 switch (iter->type) {
768 case NODE_TYPEDEF:
769 /* For each declarator, declare type and add type to variant declaration scope */
770 ret = ctf_typedef_visit(fd, depth,
771 untagged_variant_declaration->scope,
772 iter->u._typedef.type_specifier_list,
773 &iter->u._typedef.type_declarators, trace);
774 if (ret)
775 return ret;
776 break;
777 case NODE_TYPEALIAS:
778 /* Declare type with declarator and add type to variant declaration scope */
779 ret = ctf_typealias_visit(fd, depth,
780 untagged_variant_declaration->scope,
781 iter->u.typealias.target,
782 iter->u.typealias.alias, trace);
783 if (ret)
784 return ret;
785 break;
786 case NODE_STRUCT_OR_VARIANT_DECLARATION:
787 /* Add field to structure declaration */
788 ret = ctf_variant_type_declarators_visit(fd, depth,
789 untagged_variant_declaration,
790 iter->u.struct_or_variant_declaration.type_specifier_list,
791 &iter->u.struct_or_variant_declaration.type_declarators,
792 untagged_variant_declaration->scope, trace);
793 if (ret)
794 return ret;
795 break;
796 default:
797 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
798 assert(0);
799 }
800 return 0;
801 }
802
803 static
804 struct declaration *ctf_declaration_struct_visit(FILE *fd,
805 int depth, const char *name, struct bt_list_head *declaration_list,
806 int has_body, struct bt_list_head *min_align,
807 struct declaration_scope *declaration_scope,
808 struct ctf_trace *trace)
809 {
810 struct declaration_struct *struct_declaration;
811 struct ctf_node *iter;
812 int ret;
813
814 /*
815 * For named struct (without body), lookup in
816 * declaration scope. Don't take reference on struct
817 * declaration: ref is only taken upon definition.
818 */
819 if (!has_body) {
820 assert(name);
821 struct_declaration =
822 lookup_struct_declaration(g_quark_from_string(name),
823 declaration_scope);
824 return &struct_declaration->p;
825 } else {
826 uint64_t min_align_value = 0;
827
828 /* For unnamed struct, create type */
829 /* For named struct (with body), create type and add to declaration scope */
830 if (name) {
831 if (lookup_struct_declaration(g_quark_from_string(name),
832 declaration_scope)) {
833
834 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
835 return NULL;
836 }
837 }
838 if (!bt_list_empty(min_align)) {
839 ret = get_unary_unsigned(min_align, &min_align_value);
840 if (ret) {
841 fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
842 ret = -EINVAL;
843 goto error;
844 }
845 }
846 struct_declaration = struct_declaration_new(declaration_scope,
847 min_align_value);
848 bt_list_for_each_entry(iter, declaration_list, siblings) {
849 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
850 struct_declaration, trace);
851 if (ret)
852 goto error_free_declaration;
853 }
854 if (name) {
855 ret = register_struct_declaration(g_quark_from_string(name),
856 struct_declaration,
857 declaration_scope);
858 assert(!ret);
859 }
860 return &struct_declaration->p;
861 }
862 error_free_declaration:
863 struct_declaration->p.declaration_free(&struct_declaration->p);
864 error:
865 return NULL;
866 }
867
868 static
869 struct declaration *ctf_declaration_variant_visit(FILE *fd,
870 int depth, const char *name, const char *choice,
871 struct bt_list_head *declaration_list,
872 int has_body, struct declaration_scope *declaration_scope,
873 struct ctf_trace *trace)
874 {
875 struct declaration_untagged_variant *untagged_variant_declaration;
876 struct declaration_variant *variant_declaration;
877 struct ctf_node *iter;
878 int ret;
879
880 /*
881 * For named variant (without body), lookup in
882 * declaration scope. Don't take reference on variant
883 * declaration: ref is only taken upon definition.
884 */
885 if (!has_body) {
886 assert(name);
887 untagged_variant_declaration =
888 lookup_variant_declaration(g_quark_from_string(name),
889 declaration_scope);
890 } else {
891 /* For unnamed variant, create type */
892 /* For named variant (with body), create type and add to declaration scope */
893 if (name) {
894 if (lookup_variant_declaration(g_quark_from_string(name),
895 declaration_scope)) {
896
897 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
898 return NULL;
899 }
900 }
901 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
902 bt_list_for_each_entry(iter, declaration_list, siblings) {
903 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
904 untagged_variant_declaration, trace);
905 if (ret)
906 goto error;
907 }
908 if (name) {
909 ret = register_variant_declaration(g_quark_from_string(name),
910 untagged_variant_declaration,
911 declaration_scope);
912 assert(!ret);
913 }
914 }
915 /*
916 * if tagged, create tagged variant and return. else return
917 * untagged variant.
918 */
919 if (!choice) {
920 return &untagged_variant_declaration->p;
921 } else {
922 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
923 if (!variant_declaration)
924 goto error;
925 declaration_unref(&untagged_variant_declaration->p);
926 return &variant_declaration->p;
927 }
928 error:
929 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
930 return NULL;
931 }
932
933 static
934 int ctf_enumerator_list_visit(FILE *fd, int depth,
935 struct ctf_node *enumerator,
936 struct declaration_enum *enum_declaration)
937 {
938 GQuark q;
939 struct ctf_node *iter;
940
941 q = g_quark_from_string(enumerator->u.enumerator.id);
942 if (enum_declaration->integer_declaration->signedness) {
943 int64_t start, end;
944 int nr_vals = 0;
945
946 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
947 int64_t *target;
948
949 assert(iter->type == NODE_UNARY_EXPRESSION);
950 if (nr_vals == 0)
951 target = &start;
952 else
953 target = &end;
954
955 switch (iter->u.unary_expression.type) {
956 case UNARY_SIGNED_CONSTANT:
957 *target = iter->u.unary_expression.u.signed_constant;
958 break;
959 case UNARY_UNSIGNED_CONSTANT:
960 *target = iter->u.unary_expression.u.unsigned_constant;
961 break;
962 default:
963 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
964 return -EINVAL;
965 }
966 if (nr_vals > 1) {
967 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
968 return -EINVAL;
969 }
970 nr_vals++;
971 }
972 if (nr_vals == 1)
973 end = start;
974 enum_signed_insert(enum_declaration, start, end, q);
975 } else {
976 uint64_t start, end;
977 int nr_vals = 0;
978
979 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
980 uint64_t *target;
981
982 assert(iter->type == NODE_UNARY_EXPRESSION);
983 if (nr_vals == 0)
984 target = &start;
985 else
986 target = &end;
987
988 switch (iter->u.unary_expression.type) {
989 case UNARY_UNSIGNED_CONSTANT:
990 *target = iter->u.unary_expression.u.unsigned_constant;
991 break;
992 case UNARY_SIGNED_CONSTANT:
993 /*
994 * We don't accept signed constants for enums with unsigned
995 * container type.
996 */
997 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
998 return -EINVAL;
999 default:
1000 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1001 return -EINVAL;
1002 }
1003 if (nr_vals > 1) {
1004 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1005 return -EINVAL;
1006 }
1007 nr_vals++;
1008 }
1009 if (nr_vals == 1)
1010 end = start;
1011 enum_unsigned_insert(enum_declaration, start, end, q);
1012 }
1013 return 0;
1014 }
1015
1016 static
1017 struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
1018 const char *name,
1019 struct ctf_node *container_type,
1020 struct bt_list_head *enumerator_list,
1021 int has_body,
1022 struct declaration_scope *declaration_scope,
1023 struct ctf_trace *trace)
1024 {
1025 struct declaration *declaration;
1026 struct declaration_enum *enum_declaration;
1027 struct declaration_integer *integer_declaration;
1028 struct ctf_node *iter;
1029 GQuark dummy_id;
1030 int ret;
1031
1032 /*
1033 * For named enum (without body), lookup in
1034 * declaration scope. Don't take reference on enum
1035 * declaration: ref is only taken upon definition.
1036 */
1037 if (!has_body) {
1038 assert(name);
1039 enum_declaration =
1040 lookup_enum_declaration(g_quark_from_string(name),
1041 declaration_scope);
1042 return &enum_declaration->p;
1043 } else {
1044 /* For unnamed enum, create type */
1045 /* For named enum (with body), create type and add to declaration scope */
1046 if (name) {
1047 if (lookup_enum_declaration(g_quark_from_string(name),
1048 declaration_scope)) {
1049
1050 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
1051 return NULL;
1052 }
1053 }
1054 if (!container_type) {
1055 declaration = lookup_declaration(g_quark_from_static_string("int"),
1056 declaration_scope);
1057 if (!declaration) {
1058 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
1059 return NULL;
1060 }
1061 } else {
1062 declaration = ctf_type_declarator_visit(fd, depth,
1063 container_type,
1064 &dummy_id, NULL,
1065 declaration_scope,
1066 NULL, trace);
1067 }
1068 if (!declaration) {
1069 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
1070 return NULL;
1071 }
1072 if (declaration->id != CTF_TYPE_INTEGER) {
1073 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
1074 return NULL;
1075 }
1076 integer_declaration = container_of(declaration, struct declaration_integer, p);
1077 enum_declaration = enum_declaration_new(integer_declaration);
1078 declaration_unref(&integer_declaration->p); /* leave ref to enum */
1079 bt_list_for_each_entry(iter, enumerator_list, siblings) {
1080 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
1081 if (ret)
1082 goto error;
1083 }
1084 if (name) {
1085 ret = register_enum_declaration(g_quark_from_string(name),
1086 enum_declaration,
1087 declaration_scope);
1088 assert(!ret);
1089 }
1090 return &enum_declaration->p;
1091 }
1092 error:
1093 enum_declaration->p.declaration_free(&enum_declaration->p);
1094 return NULL;
1095 }
1096
1097 static
1098 struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
1099 struct ctf_node *type_specifier_list,
1100 struct declaration_scope *declaration_scope)
1101 {
1102 GString *str;
1103 struct declaration *declaration;
1104 char *str_c;
1105 int ret;
1106 GQuark id_q;
1107
1108 str = g_string_new("");
1109 ret = visit_type_specifier_list(fd, type_specifier_list, str);
1110 if (ret)
1111 return NULL;
1112 str_c = g_string_free(str, FALSE);
1113 id_q = g_quark_from_string(str_c);
1114 g_free(str_c);
1115 declaration = lookup_declaration(id_q, declaration_scope);
1116 return declaration;
1117 }
1118
1119 /*
1120 * Returns 0/1 boolean, or < 0 on error.
1121 */
1122 static
1123 int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
1124 {
1125 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
1126 fprintf(fd, "[error] %s: expecting unary expression\n",
1127 __func__);
1128 return -EINVAL;
1129 }
1130 switch (unary_expression->u.unary_expression.type) {
1131 case UNARY_UNSIGNED_CONSTANT:
1132 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
1133 return 0;
1134 else
1135 return 1;
1136 case UNARY_SIGNED_CONSTANT:
1137 if (unary_expression->u.unary_expression.u.signed_constant == 0)
1138 return 0;
1139 else
1140 return 1;
1141 case UNARY_STRING:
1142 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
1143 return 1;
1144 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
1145 return 1;
1146 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
1147 return 0;
1148 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
1149 return 0;
1150 else {
1151 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
1152 __func__, unary_expression->u.unary_expression.u.string);
1153 return -EINVAL;
1154 }
1155 break;
1156 default:
1157 fprintf(fd, "[error] %s: unexpected unary expression type\n",
1158 __func__);
1159 return -EINVAL;
1160 }
1161
1162 }
1163
1164 static
1165 int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1166 {
1167 int byte_order;
1168
1169 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1170 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1171 __func__);
1172 return -EINVAL;
1173 }
1174 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1175 byte_order = BIG_ENDIAN;
1176 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1177 byte_order = LITTLE_ENDIAN;
1178 else {
1179 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1180 __func__, unary_expression->u.unary_expression.u.string);
1181 return -EINVAL;
1182 }
1183 return byte_order;
1184 }
1185
1186 static
1187 int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1188 struct ctf_trace *trace)
1189 {
1190 int byte_order;
1191
1192 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1193 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1194 __func__);
1195 return -EINVAL;
1196 }
1197 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1198 byte_order = trace->byte_order;
1199 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1200 byte_order = BIG_ENDIAN;
1201 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1202 byte_order = BIG_ENDIAN;
1203 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1204 byte_order = LITTLE_ENDIAN;
1205 else {
1206 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1207 __func__, unary_expression->u.unary_expression.u.string);
1208 return -EINVAL;
1209 }
1210 return byte_order;
1211 }
1212
1213 static
1214 struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
1215 struct bt_list_head *expressions,
1216 struct ctf_trace *trace)
1217 {
1218 struct ctf_node *expression;
1219 uint64_t alignment = 1, size = 0;
1220 int byte_order = trace->byte_order;
1221 int signedness = 0;
1222 int has_alignment = 0, has_size = 0;
1223 int base = 0;
1224 enum ctf_string_encoding encoding = CTF_STRING_NONE;
1225 struct ctf_clock *clock = NULL;
1226 struct declaration_integer *integer_declaration;
1227
1228 bt_list_for_each_entry(expression, expressions, siblings) {
1229 struct ctf_node *left, *right;
1230
1231 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1232 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1233 assert(left->u.unary_expression.type == UNARY_STRING);
1234 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
1235 signedness = get_boolean(fd, depth, right);
1236 if (signedness < 0)
1237 return NULL;
1238 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1239 byte_order = get_byte_order(fd, depth, right, trace);
1240 if (byte_order < 0)
1241 return NULL;
1242 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
1243 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1244 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
1245 __func__);
1246 return NULL;
1247 }
1248 size = right->u.unary_expression.u.unsigned_constant;
1249 has_size = 1;
1250 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1251 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1252 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1253 __func__);
1254 return NULL;
1255 }
1256 alignment = right->u.unary_expression.u.unsigned_constant;
1257 /* Make sure alignment is a power of two */
1258 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1259 fprintf(fd, "[error] %s: align: expecting power of two\n",
1260 __func__);
1261 return NULL;
1262 }
1263 has_alignment = 1;
1264 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
1265 switch (right->u.unary_expression.type) {
1266 case UNARY_UNSIGNED_CONSTANT:
1267 switch (right->u.unary_expression.u.unsigned_constant) {
1268 case 2:
1269 case 8:
1270 case 10:
1271 case 16:
1272 base = right->u.unary_expression.u.unsigned_constant;
1273 break;
1274 default:
1275 fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
1276 __func__, right->u.unary_expression.u.unsigned_constant);
1277 return NULL;
1278 }
1279 break;
1280 case UNARY_STRING:
1281 {
1282 char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1283 if (!s_right) {
1284 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1285 g_free(s_right);
1286 return NULL;
1287 }
1288 if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
1289 || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
1290 base = 10;
1291 } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
1292 || !strcmp(s_right, "x") || !strcmp(s_right, "X")
1293 || !strcmp(s_right, "p")) {
1294 base = 16;
1295 } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
1296 || !strcmp(s_right, "o")) {
1297 base = 8;
1298 } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
1299 base = 2;
1300 } else {
1301 fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
1302 g_free(s_right);
1303 return NULL;
1304 }
1305
1306 g_free(s_right);
1307 break;
1308 }
1309 default:
1310 fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
1311 __func__);
1312 return NULL;
1313 }
1314 } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1315 char *s_right;
1316
1317 if (right->u.unary_expression.type != UNARY_STRING) {
1318 fprintf(fd, "[error] %s: encoding: expecting unary string\n",
1319 __func__);
1320 return NULL;
1321 }
1322 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1323 if (!s_right) {
1324 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1325 g_free(s_right);
1326 return NULL;
1327 }
1328 if (!strcmp(s_right, "UTF8")
1329 || !strcmp(s_right, "utf8")
1330 || !strcmp(s_right, "utf-8")
1331 || !strcmp(s_right, "UTF-8"))
1332 encoding = CTF_STRING_UTF8;
1333 else if (!strcmp(s_right, "ASCII")
1334 || !strcmp(s_right, "ascii"))
1335 encoding = CTF_STRING_ASCII;
1336 else if (!strcmp(s_right, "none"))
1337 encoding = CTF_STRING_NONE;
1338 else {
1339 fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
1340 g_free(s_right);
1341 return NULL;
1342 }
1343 g_free(s_right);
1344 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
1345 GQuark clock_name;
1346
1347 if (right->u.unary_expression.type != UNARY_STRING) {
1348 fprintf(fd, "[error] %s: map: expecting identifier\n",
1349 __func__);
1350 return NULL;
1351 }
1352 /* currently only support clock.name.value */
1353 clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
1354 if (!clock_name) {
1355 char *s_right;
1356
1357 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1358 if (!s_right) {
1359 fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
1360 g_free(s_right);
1361 return NULL;
1362 }
1363 fprintf(fd, "[warning] %s: unknown map %s in integer declaration\n", __func__,
1364 s_right);
1365 g_free(s_right);
1366 continue;
1367 }
1368 clock = trace_clock_lookup(trace, clock_name);
1369 if (!clock) {
1370 fprintf(fd, "[error] %s: map: unable to find clock %s declaration\n",
1371 __func__, g_quark_to_string(clock_name));
1372 return NULL;
1373 }
1374 } else {
1375 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1376 __func__, left->u.unary_expression.u.string);
1377 /* Fall-through after warning */
1378 }
1379 }
1380 if (!has_size) {
1381 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
1382 return NULL;
1383 }
1384 if (!has_alignment) {
1385 if (size % CHAR_BIT) {
1386 /* bit-packed alignment */
1387 alignment = 1;
1388 } else {
1389 /* byte-packed alignment */
1390 alignment = CHAR_BIT;
1391 }
1392 }
1393 integer_declaration = integer_declaration_new(size,
1394 byte_order, signedness, alignment,
1395 base, encoding, clock);
1396 return &integer_declaration->p;
1397 }
1398
1399 static
1400 struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
1401 struct bt_list_head *expressions,
1402 struct ctf_trace *trace)
1403 {
1404 struct ctf_node *expression;
1405 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0,
1406 byte_order = trace->byte_order;
1407 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1408 struct declaration_float *float_declaration;
1409
1410 bt_list_for_each_entry(expression, expressions, siblings) {
1411 struct ctf_node *left, *right;
1412
1413 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1414 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1415 assert(left->u.unary_expression.type == UNARY_STRING);
1416 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1417 byte_order = get_byte_order(fd, depth, right, trace);
1418 if (byte_order < 0)
1419 return NULL;
1420 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1421 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1422 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
1423 __func__);
1424 return NULL;
1425 }
1426 exp_dig = right->u.unary_expression.u.unsigned_constant;
1427 has_exp_dig = 1;
1428 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1429 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1430 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
1431 __func__);
1432 return NULL;
1433 }
1434 mant_dig = right->u.unary_expression.u.unsigned_constant;
1435 has_mant_dig = 1;
1436 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1437 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1438 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1439 __func__);
1440 return NULL;
1441 }
1442 alignment = right->u.unary_expression.u.unsigned_constant;
1443 /* Make sure alignment is a power of two */
1444 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1445 fprintf(fd, "[error] %s: align: expecting power of two\n",
1446 __func__);
1447 return NULL;
1448 }
1449 has_alignment = 1;
1450 } else {
1451 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1452 __func__, left->u.unary_expression.u.string);
1453 /* Fall-through after warning */
1454 }
1455 }
1456 if (!has_mant_dig) {
1457 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
1458 return NULL;
1459 }
1460 if (!has_exp_dig) {
1461 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
1462 return NULL;
1463 }
1464 if (!has_alignment) {
1465 if ((mant_dig + exp_dig) % CHAR_BIT) {
1466 /* bit-packed alignment */
1467 alignment = 1;
1468 } else {
1469 /* byte-packed alignment */
1470 alignment = CHAR_BIT;
1471 }
1472 }
1473 float_declaration = float_declaration_new(mant_dig, exp_dig,
1474 byte_order, alignment);
1475 return &float_declaration->p;
1476 }
1477
1478 static
1479 struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
1480 struct bt_list_head *expressions,
1481 struct ctf_trace *trace)
1482 {
1483 struct ctf_node *expression;
1484 const char *encoding_c = NULL;
1485 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1486 struct declaration_string *string_declaration;
1487
1488 bt_list_for_each_entry(expression, expressions, siblings) {
1489 struct ctf_node *left, *right;
1490
1491 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1492 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1493 assert(left->u.unary_expression.type == UNARY_STRING);
1494 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1495 if (right->u.unary_expression.type != UNARY_STRING) {
1496 fprintf(fd, "[error] %s: encoding: expecting string\n",
1497 __func__);
1498 return NULL;
1499 }
1500 encoding_c = right->u.unary_expression.u.string;
1501 } else {
1502 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1503 __func__, left->u.unary_expression.u.string);
1504 /* Fall-through after warning */
1505 }
1506 }
1507 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1508 encoding = CTF_STRING_ASCII;
1509 string_declaration = string_declaration_new(encoding);
1510 return &string_declaration->p;
1511 }
1512
1513
1514 static
1515 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1516 int depth, struct ctf_node *type_specifier_list,
1517 struct declaration_scope *declaration_scope,
1518 struct ctf_trace *trace)
1519 {
1520 struct ctf_node *first;
1521 struct ctf_node *node;
1522
1523 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1524
1525 first = _bt_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
1526
1527 assert(first->type == NODE_TYPE_SPECIFIER);
1528
1529 node = first->u.type_specifier.node;
1530
1531 switch (first->u.type_specifier.type) {
1532 case TYPESPEC_FLOATING_POINT:
1533 return ctf_declaration_floating_point_visit(fd, depth,
1534 &node->u.floating_point.expressions, trace);
1535 case TYPESPEC_INTEGER:
1536 return ctf_declaration_integer_visit(fd, depth,
1537 &node->u.integer.expressions, trace);
1538 case TYPESPEC_STRING:
1539 return ctf_declaration_string_visit(fd, depth,
1540 &node->u.string.expressions, trace);
1541 case TYPESPEC_STRUCT:
1542 return ctf_declaration_struct_visit(fd, depth,
1543 node->u._struct.name,
1544 &node->u._struct.declaration_list,
1545 node->u._struct.has_body,
1546 &node->u._struct.min_align,
1547 declaration_scope,
1548 trace);
1549 case TYPESPEC_VARIANT:
1550 return ctf_declaration_variant_visit(fd, depth,
1551 node->u.variant.name,
1552 node->u.variant.choice,
1553 &node->u.variant.declaration_list,
1554 node->u.variant.has_body,
1555 declaration_scope,
1556 trace);
1557 case TYPESPEC_ENUM:
1558 return ctf_declaration_enum_visit(fd, depth,
1559 node->u._enum.enum_id,
1560 node->u._enum.container_type,
1561 &node->u._enum.enumerator_list,
1562 node->u._enum.has_body,
1563 declaration_scope,
1564 trace);
1565
1566 case TYPESPEC_VOID:
1567 case TYPESPEC_CHAR:
1568 case TYPESPEC_SHORT:
1569 case TYPESPEC_INT:
1570 case TYPESPEC_LONG:
1571 case TYPESPEC_FLOAT:
1572 case TYPESPEC_DOUBLE:
1573 case TYPESPEC_SIGNED:
1574 case TYPESPEC_UNSIGNED:
1575 case TYPESPEC_BOOL:
1576 case TYPESPEC_COMPLEX:
1577 case TYPESPEC_IMAGINARY:
1578 case TYPESPEC_CONST:
1579 case TYPESPEC_ID_TYPE:
1580 return ctf_declaration_type_specifier_visit(fd, depth,
1581 type_specifier_list, declaration_scope);
1582 default:
1583 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
1584 return NULL;
1585 }
1586 }
1587
1588 static
1589 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event_declaration *event, struct ctf_trace *trace)
1590 {
1591 int ret = 0;
1592
1593 switch (node->type) {
1594 case NODE_TYPEDEF:
1595 ret = ctf_typedef_visit(fd, depth + 1,
1596 event->declaration_scope,
1597 node->u._typedef.type_specifier_list,
1598 &node->u._typedef.type_declarators,
1599 trace);
1600 if (ret)
1601 return ret;
1602 break;
1603 case NODE_TYPEALIAS:
1604 ret = ctf_typealias_visit(fd, depth + 1,
1605 event->declaration_scope,
1606 node->u.typealias.target, node->u.typealias.alias,
1607 trace);
1608 if (ret)
1609 return ret;
1610 break;
1611 case NODE_CTF_EXPRESSION:
1612 {
1613 char *left;
1614
1615 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1616 if (!strcmp(left, "name")) {
1617 char *right;
1618
1619 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1620 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
1621 ret = -EPERM;
1622 goto error;
1623 }
1624 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1625 if (!right) {
1626 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
1627 ret = -EINVAL;
1628 goto error;
1629 }
1630 event->name = g_quark_from_string(right);
1631 g_free(right);
1632 CTF_EVENT_SET_FIELD(event, name);
1633 } else if (!strcmp(left, "id")) {
1634 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1635 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
1636 ret = -EPERM;
1637 goto error;
1638 }
1639 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1640 if (ret) {
1641 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
1642 ret = -EINVAL;
1643 goto error;
1644 }
1645 CTF_EVENT_SET_FIELD(event, id);
1646 } else if (!strcmp(left, "stream_id")) {
1647 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1648 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
1649 ret = -EPERM;
1650 goto error;
1651 }
1652 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1653 if (ret) {
1654 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1655 ret = -EINVAL;
1656 goto error;
1657 }
1658 event->stream = trace_stream_lookup(trace, event->stream_id);
1659 if (!event->stream) {
1660 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1661 ret = -EINVAL;
1662 goto error;
1663 }
1664 CTF_EVENT_SET_FIELD(event, stream_id);
1665 } else if (!strcmp(left, "context")) {
1666 struct declaration *declaration;
1667
1668 if (event->context_decl) {
1669 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
1670 ret = -EINVAL;
1671 goto error;
1672 }
1673 declaration = ctf_type_specifier_list_visit(fd, depth,
1674 _bt_list_first_entry(&node->u.ctf_expression.right,
1675 struct ctf_node, siblings),
1676 event->declaration_scope, trace);
1677 if (!declaration) {
1678 ret = -EPERM;
1679 goto error;
1680 }
1681 if (declaration->id != CTF_TYPE_STRUCT) {
1682 ret = -EPERM;
1683 goto error;
1684 }
1685 event->context_decl = container_of(declaration, struct declaration_struct, p);
1686 } else if (!strcmp(left, "fields")) {
1687 struct declaration *declaration;
1688
1689 if (event->fields_decl) {
1690 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
1691 ret = -EINVAL;
1692 goto error;
1693 }
1694 declaration = ctf_type_specifier_list_visit(fd, depth,
1695 _bt_list_first_entry(&node->u.ctf_expression.right,
1696 struct ctf_node, siblings),
1697 event->declaration_scope, trace);
1698 if (!declaration) {
1699 ret = -EPERM;
1700 goto error;
1701 }
1702 if (declaration->id != CTF_TYPE_STRUCT) {
1703 ret = -EPERM;
1704 goto error;
1705 }
1706 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1707 } else if (!strcmp(left, "loglevel")) {
1708 int64_t loglevel = -1;
1709
1710 if (CTF_EVENT_FIELD_IS_SET(event, loglevel)) {
1711 fprintf(fd, "[error] %s: loglevel already declared in event declaration\n", __func__);
1712 ret = -EPERM;
1713 goto error;
1714 }
1715 ret = get_unary_signed(&node->u.ctf_expression.right, &loglevel);
1716 if (ret) {
1717 fprintf(fd, "[error] %s: unexpected unary expression for event loglevel\n", __func__);
1718 ret = -EINVAL;
1719 goto error;
1720 }
1721 event->loglevel = (int) loglevel;
1722 CTF_EVENT_SET_FIELD(event, loglevel);
1723 } else {
1724 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
1725 /* Fall-through after warning */
1726 }
1727 error:
1728 g_free(left);
1729 break;
1730 }
1731 default:
1732 return -EPERM;
1733 /* TODO: declaration specifier should be added. */
1734 }
1735
1736 return ret;
1737 }
1738
1739 static
1740 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1741 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1742 {
1743 int ret = 0;
1744 struct ctf_node *iter;
1745 struct ctf_event_declaration *event;
1746 struct bt_ctf_event_decl *event_decl;
1747
1748 event_decl = g_new0(struct bt_ctf_event_decl, 1);
1749 event = &event_decl->parent;
1750 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1751 event->loglevel = -1;
1752 bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1753 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1754 if (ret)
1755 goto error;
1756 }
1757 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1758 ret = -EPERM;
1759 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
1760 goto error;
1761 }
1762 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1763 /* Allow missing stream_id if there is only a single stream */
1764 switch (trace->streams->len) {
1765 case 0: /* Create stream if there was none. */
1766 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1767 if (ret)
1768 goto error;
1769 /* Fall-through */
1770 case 1:
1771 event->stream_id = 0;
1772 event->stream = trace_stream_lookup(trace, event->stream_id);
1773 break;
1774 default:
1775 ret = -EPERM;
1776 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1777 goto error;
1778 }
1779 }
1780 /* Allow only one event without id per stream */
1781 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1782 && event->stream->events_by_id->len != 0) {
1783 ret = -EPERM;
1784 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1785 goto error;
1786 }
1787 if (event->stream->events_by_id->len <= event->id)
1788 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1789 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1790 g_hash_table_insert(event->stream->event_quark_to_id,
1791 (gpointer) (unsigned long) event->name,
1792 &event->id);
1793 g_ptr_array_add(trace->event_declarations, event_decl);
1794 return 0;
1795
1796 error:
1797 if (event->fields_decl)
1798 declaration_unref(&event->fields_decl->p);
1799 if (event->context_decl)
1800 declaration_unref(&event->context_decl->p);
1801 free_declaration_scope(event->declaration_scope);
1802 g_free(event_decl);
1803 return ret;
1804 }
1805
1806
1807 static
1808 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_declaration *stream, struct ctf_trace *trace)
1809 {
1810 int ret = 0;
1811
1812 switch (node->type) {
1813 case NODE_TYPEDEF:
1814 ret = ctf_typedef_visit(fd, depth + 1,
1815 stream->declaration_scope,
1816 node->u._typedef.type_specifier_list,
1817 &node->u._typedef.type_declarators,
1818 trace);
1819 if (ret)
1820 return ret;
1821 break;
1822 case NODE_TYPEALIAS:
1823 ret = ctf_typealias_visit(fd, depth + 1,
1824 stream->declaration_scope,
1825 node->u.typealias.target, node->u.typealias.alias,
1826 trace);
1827 if (ret)
1828 return ret;
1829 break;
1830 case NODE_CTF_EXPRESSION:
1831 {
1832 char *left;
1833
1834 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1835 if (!strcmp(left, "id")) {
1836 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1837 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
1838 ret = -EPERM;
1839 goto error;
1840 }
1841 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
1842 if (ret) {
1843 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
1844 ret = -EINVAL;
1845 goto error;
1846 }
1847 CTF_STREAM_SET_FIELD(stream, stream_id);
1848 } else if (!strcmp(left, "event.header")) {
1849 struct declaration *declaration;
1850
1851 if (stream->event_header_decl) {
1852 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
1853 ret = -EINVAL;
1854 goto error;
1855 }
1856 declaration = ctf_type_specifier_list_visit(fd, depth,
1857 _bt_list_first_entry(&node->u.ctf_expression.right,
1858 struct ctf_node, siblings),
1859 stream->declaration_scope, trace);
1860 if (!declaration) {
1861 ret = -EPERM;
1862 goto error;
1863 }
1864 if (declaration->id != CTF_TYPE_STRUCT) {
1865 ret = -EPERM;
1866 goto error;
1867 }
1868 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1869 } else if (!strcmp(left, "event.context")) {
1870 struct declaration *declaration;
1871
1872 if (stream->event_context_decl) {
1873 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
1874 ret = -EINVAL;
1875 goto error;
1876 }
1877 declaration = ctf_type_specifier_list_visit(fd, depth,
1878 _bt_list_first_entry(&node->u.ctf_expression.right,
1879 struct ctf_node, siblings),
1880 stream->declaration_scope, trace);
1881 if (!declaration) {
1882 ret = -EPERM;
1883 goto error;
1884 }
1885 if (declaration->id != CTF_TYPE_STRUCT) {
1886 ret = -EPERM;
1887 goto error;
1888 }
1889 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1890 } else if (!strcmp(left, "packet.context")) {
1891 struct declaration *declaration;
1892
1893 if (stream->packet_context_decl) {
1894 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
1895 ret = -EINVAL;
1896 goto error;
1897 }
1898 declaration = ctf_type_specifier_list_visit(fd, depth,
1899 _bt_list_first_entry(&node->u.ctf_expression.right,
1900 struct ctf_node, siblings),
1901 stream->declaration_scope, trace);
1902 if (!declaration) {
1903 ret = -EPERM;
1904 goto error;
1905 }
1906 if (declaration->id != CTF_TYPE_STRUCT) {
1907 ret = -EPERM;
1908 goto error;
1909 }
1910 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1911 } else {
1912 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
1913 /* Fall-through after warning */
1914 }
1915
1916 error:
1917 g_free(left);
1918 break;
1919 }
1920 default:
1921 return -EPERM;
1922 /* TODO: declaration specifier should be added. */
1923 }
1924
1925 return ret;
1926 }
1927
1928 static
1929 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1930 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1931 {
1932 int ret = 0;
1933 struct ctf_node *iter;
1934 struct ctf_stream_declaration *stream;
1935
1936 stream = g_new0(struct ctf_stream_declaration, 1);
1937 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1938 stream->events_by_id = g_ptr_array_new();
1939 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1940 stream->streams = g_ptr_array_new();
1941 if (node) {
1942 bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1943 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1944 if (ret)
1945 goto error;
1946 }
1947 }
1948 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1949 /* check that packet header has stream_id field. */
1950 if (!trace->packet_header_decl
1951 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
1952 ret = -EPERM;
1953 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
1954 goto error;
1955 }
1956 } else {
1957 /* Allow only one id-less stream */
1958 if (trace->streams->len != 0) {
1959 ret = -EPERM;
1960 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
1961 goto error;
1962 }
1963 stream->stream_id = 0;
1964 }
1965 if (trace->streams->len <= stream->stream_id)
1966 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1967 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
1968 stream->trace = trace;
1969
1970 return 0;
1971
1972 error:
1973 if (stream->event_header_decl)
1974 declaration_unref(&stream->event_header_decl->p);
1975 if (stream->event_context_decl)
1976 declaration_unref(&stream->event_context_decl->p);
1977 if (stream->packet_context_decl)
1978 declaration_unref(&stream->packet_context_decl->p);
1979 g_ptr_array_free(stream->streams, TRUE);
1980 g_ptr_array_free(stream->events_by_id, TRUE);
1981 g_hash_table_destroy(stream->event_quark_to_id);
1982 free_declaration_scope(stream->declaration_scope);
1983 g_free(stream);
1984 return ret;
1985 }
1986
1987 static
1988 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1989 {
1990 int ret = 0;
1991
1992 switch (node->type) {
1993 case NODE_TYPEDEF:
1994 ret = ctf_typedef_visit(fd, depth + 1,
1995 trace->declaration_scope,
1996 node->u._typedef.type_specifier_list,
1997 &node->u._typedef.type_declarators,
1998 trace);
1999 if (ret)
2000 return ret;
2001 break;
2002 case NODE_TYPEALIAS:
2003 ret = ctf_typealias_visit(fd, depth + 1,
2004 trace->declaration_scope,
2005 node->u.typealias.target, node->u.typealias.alias,
2006 trace);
2007 if (ret)
2008 return ret;
2009 break;
2010 case NODE_CTF_EXPRESSION:
2011 {
2012 char *left;
2013
2014 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2015 if (!strcmp(left, "major")) {
2016 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
2017 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
2018 ret = -EPERM;
2019 goto error;
2020 }
2021 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
2022 if (ret) {
2023 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
2024 ret = -EINVAL;
2025 goto error;
2026 }
2027 CTF_TRACE_SET_FIELD(trace, major);
2028 } else if (!strcmp(left, "minor")) {
2029 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2030 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
2031 ret = -EPERM;
2032 goto error;
2033 }
2034 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
2035 if (ret) {
2036 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
2037 ret = -EINVAL;
2038 goto error;
2039 }
2040 CTF_TRACE_SET_FIELD(trace, minor);
2041 } else if (!strcmp(left, "uuid")) {
2042 unsigned char uuid[BABELTRACE_UUID_LEN];
2043
2044 ret = get_unary_uuid(&node->u.ctf_expression.right, uuid);
2045 if (ret) {
2046 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
2047 ret = -EINVAL;
2048 goto error;
2049 }
2050 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
2051 && babeltrace_uuid_compare(uuid, trace->uuid)) {
2052 fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
2053 ret = -EPERM;
2054 goto error;
2055 } else {
2056 memcpy(trace->uuid, uuid, sizeof(uuid));
2057 }
2058 CTF_TRACE_SET_FIELD(trace, uuid);
2059 } else if (!strcmp(left, "byte_order")) {
2060 struct ctf_node *right;
2061 int byte_order;
2062
2063 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2064 byte_order = get_trace_byte_order(fd, depth, right);
2065 if (byte_order < 0)
2066 return -EINVAL;
2067
2068 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
2069 && byte_order != trace->byte_order) {
2070 fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
2071 ret = -EPERM;
2072 goto error;
2073 } else {
2074 if (byte_order != trace->byte_order) {
2075 trace->byte_order = byte_order;
2076 /*
2077 * We need to restart
2078 * construction of the
2079 * intermediate representation.
2080 */
2081 trace->field_mask = 0;
2082 CTF_TRACE_SET_FIELD(trace, byte_order);
2083 ret = -EINTR;
2084 goto error;
2085 }
2086 }
2087 CTF_TRACE_SET_FIELD(trace, byte_order);
2088 } else if (!strcmp(left, "packet.header")) {
2089 struct declaration *declaration;
2090
2091 if (trace->packet_header_decl) {
2092 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
2093 ret = -EINVAL;
2094 goto error;
2095 }
2096 declaration = ctf_type_specifier_list_visit(fd, depth,
2097 _bt_list_first_entry(&node->u.ctf_expression.right,
2098 struct ctf_node, siblings),
2099 trace->declaration_scope, trace);
2100 if (!declaration) {
2101 ret = -EPERM;
2102 goto error;
2103 }
2104 if (declaration->id != CTF_TYPE_STRUCT) {
2105 ret = -EPERM;
2106 goto error;
2107 }
2108 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
2109 } else {
2110 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
2111 }
2112
2113 error:
2114 g_free(left);
2115 break;
2116 }
2117 default:
2118 return -EPERM;
2119 /* TODO: declaration specifier should be added. */
2120 }
2121
2122 return ret;
2123 }
2124
2125 static
2126 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2127 {
2128 int ret = 0;
2129 struct ctf_node *iter;
2130
2131 if (trace->declaration_scope)
2132 return -EEXIST;
2133 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
2134 trace->streams = g_ptr_array_new();
2135 trace->event_declarations = g_ptr_array_new();
2136 bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
2137 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
2138 if (ret)
2139 goto error;
2140 }
2141 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
2142 ret = -EPERM;
2143 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
2144 goto error;
2145 }
2146 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2147 ret = -EPERM;
2148 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
2149 goto error;
2150 }
2151 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2152 ret = -EPERM;
2153 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
2154 goto error;
2155 }
2156
2157 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2158 /* check that the packet header contains a "magic" field */
2159 if (!trace->packet_header_decl
2160 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
2161 ret = -EPERM;
2162 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
2163 goto error;
2164 }
2165 }
2166 return 0;
2167
2168 error:
2169 if (trace->packet_header_decl) {
2170 declaration_unref(&trace->packet_header_decl->p);
2171 trace->packet_header_decl = NULL;
2172 }
2173 g_ptr_array_free(trace->streams, TRUE);
2174 g_ptr_array_free(trace->event_declarations, TRUE);
2175 free_declaration_scope(trace->declaration_scope);
2176 trace->declaration_scope = NULL;
2177 return ret;
2178 }
2179
2180 static
2181 int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2182 struct ctf_clock *clock, struct ctf_trace *trace)
2183 {
2184 int ret = 0;
2185
2186 switch (node->type) {
2187 case NODE_CTF_EXPRESSION:
2188 {
2189 char *left;
2190
2191 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2192 if (!strcmp(left, "name")) {
2193 char *right;
2194
2195 if (CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2196 fprintf(fd, "[error] %s: name already declared in clock declaration\n", __func__);
2197 ret = -EPERM;
2198 goto error;
2199 }
2200 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2201 if (!right) {
2202 fprintf(fd, "[error] %s: unexpected unary expression for clock name\n", __func__);
2203 ret = -EINVAL;
2204 goto error;
2205 }
2206 clock->name = g_quark_from_string(right);
2207 g_free(right);
2208 CTF_CLOCK_SET_FIELD(clock, name);
2209 } else if (!strcmp(left, "uuid")) {
2210 char *right;
2211
2212 if (clock->uuid) {
2213 fprintf(fd, "[error] %s: uuid already declared in clock declaration\n", __func__);
2214 ret = -EPERM;
2215 goto error;
2216 }
2217 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2218 if (!right) {
2219 fprintf(fd, "[error] %s: unexpected unary expression for clock uuid\n", __func__);
2220 ret = -EINVAL;
2221 goto error;
2222 }
2223 clock->uuid = g_quark_from_string(right);
2224 g_free(right);
2225 } else if (!strcmp(left, "description")) {
2226 char *right;
2227
2228 if (clock->description) {
2229 fprintf(fd, "[warning] %s: duplicated clock description\n", __func__);
2230 goto error; /* ret is 0, so not an actual error, just warn. */
2231 }
2232 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2233 if (!right) {
2234 fprintf(fd, "[warning] %s: unexpected unary expression for clock description\n", __func__);
2235 goto error; /* ret is 0, so not an actual error, just warn. */
2236 }
2237 clock->description = right;
2238 } else if (!strcmp(left, "freq")) {
2239 if (CTF_CLOCK_FIELD_IS_SET(clock, freq)) {
2240 fprintf(fd, "[error] %s: freq already declared in clock declaration\n", __func__);
2241 ret = -EPERM;
2242 goto error;
2243 }
2244 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->freq);
2245 if (ret) {
2246 fprintf(fd, "[error] %s: unexpected unary expression for clock freq\n", __func__);
2247 ret = -EINVAL;
2248 goto error;
2249 }
2250 CTF_CLOCK_SET_FIELD(clock, freq);
2251 } else if (!strcmp(left, "precision")) {
2252 if (clock->precision) {
2253 fprintf(fd, "[error] %s: precision already declared in clock declaration\n", __func__);
2254 ret = -EPERM;
2255 goto error;
2256 }
2257 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->precision);
2258 if (ret) {
2259 fprintf(fd, "[error] %s: unexpected unary expression for clock precision\n", __func__);
2260 ret = -EINVAL;
2261 goto error;
2262 }
2263 } else if (!strcmp(left, "offset_s")) {
2264 if (clock->offset_s) {
2265 fprintf(fd, "[error] %s: offset_s already declared in clock declaration\n", __func__);
2266 ret = -EPERM;
2267 goto error;
2268 }
2269 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset_s);
2270 if (ret) {
2271 fprintf(fd, "[error] %s: unexpected unary expression for clock offset_s\n", __func__);
2272 ret = -EINVAL;
2273 goto error;
2274 }
2275 } else if (!strcmp(left, "offset")) {
2276 if (clock->offset) {
2277 fprintf(fd, "[error] %s: offset already declared in clock declaration\n", __func__);
2278 ret = -EPERM;
2279 goto error;
2280 }
2281 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset);
2282 if (ret) {
2283 fprintf(fd, "[error] %s: unexpected unary expression for clock offset\n", __func__);
2284 ret = -EINVAL;
2285 goto error;
2286 }
2287 } else if (!strcmp(left, "absolute")) {
2288 struct ctf_node *right;
2289
2290 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2291 ret = get_boolean(fd, depth, right);
2292 if (ret < 0) {
2293 fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__);
2294 ret = -EINVAL;
2295 goto error;
2296 }
2297 clock->absolute = ret;
2298 } else {
2299 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left);
2300 }
2301
2302 error:
2303 g_free(left);
2304 break;
2305 }
2306 default:
2307 return -EPERM;
2308 /* TODO: declaration specifier should be added. */
2309 }
2310
2311 return ret;
2312 }
2313
2314 static
2315 int ctf_clock_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2316 {
2317 int ret = 0;
2318 struct ctf_node *iter;
2319 struct ctf_clock *clock;
2320
2321 clock = g_new0(struct ctf_clock, 1);
2322 /* Default clock frequency is set to 1000000000 */
2323 clock->freq = 1000000000ULL;
2324 bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
2325 ret = ctf_clock_declaration_visit(fd, depth + 1, iter, clock, trace);
2326 if (ret)
2327 goto error;
2328 }
2329 if (opt_clock_force_correlate) {
2330 /*
2331 * User requested to forcibly correlate the clock
2332 * sources, even if we have no correlatation
2333 * information.
2334 */
2335 if (!clock->absolute) {
2336 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2337 }
2338 clock->absolute = 1;
2339 }
2340 if (!CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2341 ret = -EPERM;
2342 fprintf(fd, "[error] %s: missing namefield in clock declaration\n", __func__);
2343 goto error;
2344 }
2345 if (g_hash_table_size(trace->clocks) > 0) {
2346 fprintf(fd, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
2347 ret = -EINVAL;
2348 goto error;
2349 }
2350 trace->single_clock = clock;
2351 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2352 return 0;
2353
2354 error:
2355 g_free(clock->description);
2356 g_free(clock);
2357 return ret;
2358 }
2359
2360 static
2361 void ctf_clock_default(FILE *fd, int depth, struct ctf_trace *trace)
2362 {
2363 struct ctf_clock *clock;
2364
2365 clock = g_new0(struct ctf_clock, 1);
2366 clock->name = g_quark_from_string("monotonic");
2367 clock->uuid = 0;
2368 clock->description = g_strdup("Default clock");
2369 /* Default clock frequency is set to 1000000000 */
2370 clock->freq = 1000000000ULL;
2371 if (opt_clock_force_correlate) {
2372 /*
2373 * User requested to forcibly correlate the clock
2374 * sources, even if we have no correlatation
2375 * information.
2376 */
2377 if (!clock->absolute) {
2378 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2379 }
2380 clock->absolute = 1;
2381 } else {
2382 clock->absolute = 0; /* Not an absolute reference across traces */
2383 }
2384
2385 trace->single_clock = clock;
2386 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2387 }
2388
2389 static
2390 void clock_free(gpointer data)
2391 {
2392 struct ctf_clock *clock = data;
2393
2394 g_free(clock->description);
2395 g_free(clock);
2396 }
2397
2398 static
2399 int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2400 struct ctf_trace *trace)
2401 {
2402 int ret = 0;
2403 struct ctf_tracer_env *env = &trace->env;
2404
2405 switch (node->type) {
2406 case NODE_CTF_EXPRESSION:
2407 {
2408 char *left;
2409
2410 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2411 if (!strcmp(left, "vpid")) {
2412 uint64_t v;
2413
2414 if (env->vpid != -1) {
2415 fprintf(fd, "[error] %s: vpid already declared in env declaration\n", __func__);
2416 goto error; /* ret is 0, so not an actual error, just warn. */
2417 }
2418 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2419 if (ret) {
2420 fprintf(fd, "[error] %s: unexpected unary expression for env vpid\n", __func__);
2421 goto error; /* ret is 0, so not an actual error, just warn. */
2422 }
2423 env->vpid = (int) v;
2424 printf_verbose("env.vpid = %d\n", env->vpid);
2425 } else if (!strcmp(left, "procname")) {
2426 char *right;
2427
2428 if (env->procname[0]) {
2429 fprintf(fd, "[warning] %s: duplicated env procname\n", __func__);
2430 goto error; /* ret is 0, so not an actual error, just warn. */
2431 }
2432 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2433 if (!right) {
2434 fprintf(fd, "[warning] %s: unexpected unary expression for env procname\n", __func__);
2435 goto error; /* ret is 0, so not an actual error, just warn. */
2436 }
2437 strncpy(env->procname, right, TRACER_ENV_LEN);
2438 env->procname[TRACER_ENV_LEN - 1] = '\0';
2439 printf_verbose("env.procname = \"%s\"\n", env->procname);
2440 } else if (!strcmp(left, "domain")) {
2441 char *right;
2442
2443 if (env->domain[0]) {
2444 fprintf(fd, "[warning] %s: duplicated env domain\n", __func__);
2445 goto error; /* ret is 0, so not an actual error, just warn. */
2446 }
2447 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2448 if (!right) {
2449 fprintf(fd, "[warning] %s: unexpected unary expression for env domain\n", __func__);
2450 goto error; /* ret is 0, so not an actual error, just warn. */
2451 }
2452 strncpy(env->domain, right, TRACER_ENV_LEN);
2453 env->domain[TRACER_ENV_LEN - 1] = '\0';
2454 printf_verbose("env.domain = \"%s\"\n", env->domain);
2455 } else if (!strcmp(left, "sysname")) {
2456 char *right;
2457
2458 if (env->sysname[0]) {
2459 fprintf(fd, "[warning] %s: duplicated env sysname\n", __func__);
2460 goto error; /* ret is 0, so not an actual error, just warn. */
2461 }
2462 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2463 if (!right) {
2464 fprintf(fd, "[warning] %s: unexpected unary expression for env sysname\n", __func__);
2465 goto error; /* ret is 0, so not an actual error, just warn. */
2466 }
2467 strncpy(env->sysname, right, TRACER_ENV_LEN);
2468 env->sysname[TRACER_ENV_LEN - 1] = '\0';
2469 printf_verbose("env.sysname = \"%s\"\n", env->sysname);
2470 } else if (!strcmp(left, "kernel_release")) {
2471 char *right;
2472
2473 if (env->release[0]) {
2474 fprintf(fd, "[warning] %s: duplicated env release\n", __func__);
2475 goto error; /* ret is 0, so not an actual error, just warn. */
2476 }
2477 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2478 if (!right) {
2479 fprintf(fd, "[warning] %s: unexpected unary expression for env release\n", __func__);
2480 goto error; /* ret is 0, so not an actual error, just warn. */
2481 }
2482 strncpy(env->release, right, TRACER_ENV_LEN);
2483 env->release[TRACER_ENV_LEN - 1] = '\0';
2484 printf_verbose("env.release = \"%s\"\n", env->release);
2485 } else if (!strcmp(left, "kernel_version")) {
2486 char *right;
2487
2488 if (env->version[0]) {
2489 fprintf(fd, "[warning] %s: duplicated env version\n", __func__);
2490 goto error; /* ret is 0, so not an actual error, just warn. */
2491 }
2492 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2493 if (!right) {
2494 fprintf(fd, "[warning] %s: unexpected unary expression for env version\n", __func__);
2495 goto error; /* ret is 0, so not an actual error, just warn. */
2496 }
2497 strncpy(env->version, right, TRACER_ENV_LEN);
2498 env->version[TRACER_ENV_LEN - 1] = '\0';
2499 printf_verbose("env.version = \"%s\"\n", env->version);
2500 } else {
2501 if (is_unary_string(&node->u.ctf_expression.right)) {
2502 char *right;
2503
2504 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2505 printf_verbose("env.%s = \"%s\"\n", left, right);
2506 } else if (is_unary_unsigned(&node->u.ctf_expression.right)) {
2507 uint64_t v;
2508 int ret;
2509
2510 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2511 assert(ret == 0);
2512 printf_verbose("env.%s = %" PRIu64 "\n", left, v);
2513 } else if (is_unary_signed(&node->u.ctf_expression.right)) {
2514 int64_t v;
2515 int ret;
2516
2517 ret = get_unary_signed(&node->u.ctf_expression.right, &v);
2518 assert(ret == 0);
2519 printf_verbose("env.%s = %" PRId64 "\n", left, v);
2520 } else {
2521 printf_verbose("%s: attribute \"%s\" has unknown type.\n", __func__, left);
2522 }
2523 }
2524
2525 error:
2526 g_free(left);
2527 break;
2528 }
2529 default:
2530 return -EPERM;
2531 }
2532
2533 return ret;
2534 }
2535
2536 static
2537 int ctf_env_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2538 {
2539 int ret = 0;
2540 struct ctf_node *iter;
2541
2542 trace->env.vpid = -1;
2543 trace->env.procname[0] = '\0';
2544 trace->env.domain[0] = '\0';
2545 trace->env.sysname[0] = '\0';
2546 trace->env.release[0] = '\0';
2547 trace->env.version[0] = '\0';
2548 bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
2549 ret = ctf_env_declaration_visit(fd, depth + 1, iter, trace);
2550 if (ret)
2551 goto error;
2552 }
2553 error:
2554 return 0;
2555 }
2556
2557 static
2558 int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2559 {
2560 int ret = 0;
2561
2562 switch (node->type) {
2563 case NODE_TYPEDEF:
2564 ret = ctf_typedef_visit(fd, depth + 1,
2565 trace->root_declaration_scope,
2566 node->u._typedef.type_specifier_list,
2567 &node->u._typedef.type_declarators,
2568 trace);
2569 if (ret)
2570 return ret;
2571 break;
2572 case NODE_TYPEALIAS:
2573 ret = ctf_typealias_visit(fd, depth + 1,
2574 trace->root_declaration_scope,
2575 node->u.typealias.target, node->u.typealias.alias,
2576 trace);
2577 if (ret)
2578 return ret;
2579 break;
2580 case NODE_TYPE_SPECIFIER_LIST:
2581 {
2582 struct declaration *declaration;
2583
2584 /*
2585 * Just add the type specifier to the root scope
2586 * declaration scope. Release local reference.
2587 */
2588 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2589 node, trace->root_declaration_scope, trace);
2590 if (!declaration)
2591 return -ENOMEM;
2592 declaration_unref(declaration);
2593 break;
2594 }
2595 default:
2596 return -EPERM;
2597 }
2598
2599 return 0;
2600 }
2601
2602 /* TODO: missing metadata "destroy" (memory leak) */
2603 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2604 struct ctf_trace *trace, int byte_order)
2605 {
2606 int ret = 0;
2607 struct ctf_node *iter;
2608 int env_clock_done = 0;
2609
2610 printf_verbose("CTF visitor: metadata construction... ");
2611 trace->byte_order = byte_order;
2612 trace->clocks = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2613 NULL, clock_free);
2614
2615 retry:
2616 trace->root_declaration_scope = new_declaration_scope(NULL);
2617
2618 switch (node->type) {
2619 case NODE_ROOT:
2620 if (!env_clock_done) {
2621 /*
2622 * declarations need to query clock hash table,
2623 * so clock need to be treated first.
2624 */
2625 if (bt_list_empty(&node->u.root.clock)) {
2626 ctf_clock_default(fd, depth + 1, trace);
2627 } else {
2628 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
2629 ret = ctf_clock_visit(fd, depth + 1, iter,
2630 trace);
2631 if (ret) {
2632 fprintf(fd, "[error] %s: clock declaration error\n", __func__);
2633 goto error;
2634 }
2635 }
2636 }
2637 env_clock_done = 1;
2638 }
2639 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
2640 siblings) {
2641 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
2642 if (ret) {
2643 fprintf(fd, "[error] %s: root declaration error\n", __func__);
2644 goto error;
2645 }
2646 }
2647 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
2648 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
2649 if (ret == -EINTR) {
2650 free_declaration_scope(trace->root_declaration_scope);
2651 /*
2652 * Need to restart creation of type
2653 * definitions, aliases and
2654 * trace header declarations.
2655 */
2656 goto retry;
2657 }
2658 if (ret) {
2659 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
2660 goto error;
2661 }
2662 }
2663 if (!trace->streams) {
2664 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
2665 ret = -EINVAL;
2666 goto error;
2667 }
2668 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
2669 ret = ctf_env_visit(fd, depth + 1, iter, trace);
2670 if (ret) {
2671 fprintf(fd, "[error] %s: env declaration error\n", __func__);
2672 goto error;
2673 }
2674 }
2675 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
2676 ret = ctf_stream_visit(fd, depth + 1, iter,
2677 trace->root_declaration_scope, trace);
2678 if (ret) {
2679 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
2680 goto error;
2681 }
2682 }
2683 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
2684 ret = ctf_event_visit(fd, depth + 1, iter,
2685 trace->root_declaration_scope, trace);
2686 if (ret) {
2687 fprintf(fd, "[error] %s: event declaration error\n", __func__);
2688 goto error;
2689 }
2690 }
2691 break;
2692 case NODE_UNKNOWN:
2693 default:
2694 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
2695 (int) node->type);
2696 ret = -EINVAL;
2697 goto error;
2698 }
2699 printf_verbose("done.\n");
2700 return ret;
2701
2702 error:
2703 free_declaration_scope(trace->root_declaration_scope);
2704 g_hash_table_destroy(trace->clocks);
2705 return ret;
2706 }
This page took 0.156516 seconds and 4 git commands to generate.