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