Add -t option
[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 <endian.h>
27 #include <errno.h>
28 #include <babeltrace/babeltrace.h>
29 #include <babeltrace/list.h>
30 #include <babeltrace/types.h>
31 #include <babeltrace/ctf/metadata.h>
32 #include <uuid/uuid.h>
33 #include "ctf-scanner.h"
34 #include "ctf-parser.h"
35 #include "ctf-ast.h"
36
37 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
38
39 #define _cds_list_first_entry(ptr, type, member) \
40 cds_list_entry((ptr)->next, type, member)
41
42 static
43 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
44 int depth, struct ctf_node *type_specifier_list,
45 struct declaration_scope *declaration_scope,
46 struct ctf_trace *trace);
47
48 static
49 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
50 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
51
52 /*
53 * String returned must be freed by the caller using g_free.
54 */
55 static
56 char *concatenate_unary_strings(struct cds_list_head *head)
57 {
58 struct ctf_node *node;
59 GString *str;
60 int i = 0;
61
62 str = g_string_new("");
63 cds_list_for_each_entry(node, head, siblings) {
64 char *src_string;
65
66 assert(node->type == NODE_UNARY_EXPRESSION);
67 assert(node->u.unary_expression.type == UNARY_STRING);
68 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
69 ^ (i != 0));
70 switch (node->u.unary_expression.link) {
71 case UNARY_DOTLINK:
72 g_string_append(str, ".");
73 break;
74 case UNARY_ARROWLINK:
75 g_string_append(str, "->");
76 break;
77 case UNARY_DOTDOTDOT:
78 g_string_append(str, "...");
79 break;
80 default:
81 break;
82 }
83 src_string = node->u.unary_expression.u.string;
84 g_string_append(str, src_string);
85 i++;
86 }
87 return g_string_free(str, FALSE);
88 }
89
90 static
91 int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
92 {
93 struct ctf_node *node;
94 int i = 0;
95
96 cds_list_for_each_entry(node, head, siblings) {
97 assert(node->type == NODE_UNARY_EXPRESSION);
98 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
99 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
100 assert(i == 0);
101 *value = node->u.unary_expression.u.unsigned_constant;
102 i++;
103 }
104 return 0;
105 }
106
107 static
108 int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
109 {
110 struct ctf_node *node;
111 int i = 0;
112 int ret = -1;
113
114 cds_list_for_each_entry(node, head, siblings) {
115 const 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 assert(i == 0);
121 src_string = node->u.unary_expression.u.string;
122 ret = uuid_parse(node->u.unary_expression.u.string, *uuid);
123 }
124 return ret;
125 }
126
127 static
128 struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
129 {
130 if (trace->streams->len <= stream_id)
131 return NULL;
132 return g_ptr_array_index(trace->streams, stream_id);
133 }
134
135 static
136 int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
137 {
138 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
139
140 switch (type_specifier->u.type_specifier.type) {
141 case TYPESPEC_VOID:
142 g_string_append(str, "void");
143 break;
144 case TYPESPEC_CHAR:
145 g_string_append(str, "char");
146 break;
147 case TYPESPEC_SHORT:
148 g_string_append(str, "short");
149 break;
150 case TYPESPEC_INT:
151 g_string_append(str, "int");
152 break;
153 case TYPESPEC_LONG:
154 g_string_append(str, "long");
155 break;
156 case TYPESPEC_FLOAT:
157 g_string_append(str, "float");
158 break;
159 case TYPESPEC_DOUBLE:
160 g_string_append(str, "double");
161 break;
162 case TYPESPEC_SIGNED:
163 g_string_append(str, "signed");
164 break;
165 case TYPESPEC_UNSIGNED:
166 g_string_append(str, "unsigned");
167 break;
168 case TYPESPEC_BOOL:
169 g_string_append(str, "bool");
170 break;
171 case TYPESPEC_COMPLEX:
172 g_string_append(str, "_Complex");
173 break;
174 case TYPESPEC_IMAGINARY:
175 g_string_append(str, "_Imaginary");
176 break;
177 case TYPESPEC_CONST:
178 g_string_append(str, "const");
179 break;
180 case TYPESPEC_ID_TYPE:
181 if (type_specifier->u.type_specifier.id_type)
182 g_string_append(str, type_specifier->u.type_specifier.id_type);
183 break;
184 case TYPESPEC_STRUCT:
185 {
186 struct ctf_node *node = type_specifier->u.type_specifier.node;
187
188 if (!node->u._struct.name) {
189 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
190 return -EINVAL;
191 }
192 g_string_append(str, "struct ");
193 g_string_append(str, node->u._struct.name);
194 break;
195 }
196 case TYPESPEC_VARIANT:
197 {
198 struct ctf_node *node = type_specifier->u.type_specifier.node;
199
200 if (!node->u.variant.name) {
201 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
202 return -EINVAL;
203 }
204 g_string_append(str, "variant ");
205 g_string_append(str, node->u.variant.name);
206 break;
207 }
208 case TYPESPEC_ENUM:
209 {
210 struct ctf_node *node = type_specifier->u.type_specifier.node;
211
212 if (!node->u._enum.enum_id) {
213 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
214 return -EINVAL;
215 }
216 g_string_append(str, "enum ");
217 g_string_append(str, node->u._enum.enum_id);
218 break;
219 }
220 case TYPESPEC_FLOATING_POINT:
221 case TYPESPEC_INTEGER:
222 case TYPESPEC_STRING:
223 default:
224 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
225 return -EINVAL;
226 }
227 return 0;
228 }
229
230 static
231 int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
232 {
233 struct ctf_node *iter;
234 int alias_item_nr = 0;
235 int ret;
236
237 cds_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
238 if (alias_item_nr != 0)
239 g_string_append(str, " ");
240 alias_item_nr++;
241 ret = visit_type_specifier(fd, iter, str);
242 if (ret)
243 return ret;
244 }
245 return 0;
246 }
247
248 static
249 GQuark create_typealias_identifier(FILE *fd, int depth,
250 struct ctf_node *type_specifier_list,
251 struct ctf_node *node_type_declarator)
252 {
253 struct ctf_node *iter;
254 GString *str;
255 char *str_c;
256 GQuark alias_q;
257 int ret;
258
259 str = g_string_new("");
260 ret = visit_type_specifier_list(fd, type_specifier_list, str);
261 if (ret) {
262 g_string_free(str, TRUE);
263 return 0;
264 }
265 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
266 g_string_append(str, " *");
267 if (iter->u.pointer.const_qualifier)
268 g_string_append(str, " const");
269 }
270 str_c = g_string_free(str, FALSE);
271 alias_q = g_quark_from_string(str_c);
272 g_free(str_c);
273 return alias_q;
274 }
275
276 static
277 struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
278 struct ctf_node *type_specifier_list,
279 GQuark *field_name,
280 struct ctf_node *node_type_declarator,
281 struct declaration_scope *declaration_scope,
282 struct declaration *nested_declaration,
283 struct ctf_trace *trace)
284 {
285 /*
286 * Visit type declarator by first taking care of sequence/array
287 * (recursively). Then, when we get to the identifier, take care
288 * of pointers.
289 */
290
291 if (node_type_declarator) {
292 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
293
294 /* TODO: gcc bitfields not supported yet. */
295 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
296 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
297 return NULL;
298 }
299 }
300
301 if (!nested_declaration) {
302 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
303 GQuark alias_q;
304
305 /*
306 * If we have a pointer declarator, it _has_ to be present in
307 * the typealiases (else fail).
308 */
309 alias_q = create_typealias_identifier(fd, depth,
310 type_specifier_list, node_type_declarator);
311 nested_declaration = lookup_declaration(alias_q, declaration_scope);
312 if (!nested_declaration) {
313 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
314 return NULL;
315 }
316 } else {
317 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
318 type_specifier_list, declaration_scope, trace);
319 }
320 }
321
322 if (!node_type_declarator)
323 return nested_declaration;
324
325 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
326 if (node_type_declarator->u.type_declarator.u.id)
327 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
328 else
329 *field_name = 0;
330 return nested_declaration;
331 } else {
332 struct declaration *declaration;
333 struct ctf_node *length;
334
335 /* TYPEDEC_NESTED */
336
337 /* create array/sequence, pass nested_declaration as child. */
338 length = node_type_declarator->u.type_declarator.u.nested.length;
339 if (!length) {
340 fprintf(fd, "[error] %s: expecting length type or value.\n", __func__);
341 return NULL;
342 }
343 switch (length->type) {
344 case NODE_UNARY_EXPRESSION:
345 {
346 struct declaration_array *array_declaration;
347 size_t len;
348
349 if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
350 fprintf(fd, "[error] %s: array: unexpected unary expression.\n", __func__);
351 return NULL;
352 }
353 len = length->u.unary_expression.u.unsigned_constant;
354 array_declaration = array_declaration_new(len, nested_declaration,
355 declaration_scope);
356 declaration = &array_declaration->p;
357 break;
358 }
359 case NODE_TYPE_SPECIFIER_LIST:
360 {
361 struct declaration_sequence *sequence_declaration;
362 struct declaration_integer *integer_declaration;
363
364 declaration = ctf_type_specifier_list_visit(fd, depth,
365 length, declaration_scope, trace);
366 if (!declaration) {
367 fprintf(fd, "[error] %s: unable to find declaration type for sequence length\n", __func__);
368 return NULL;
369 }
370 if (declaration->id != CTF_TYPE_INTEGER) {
371 fprintf(fd, "[error] %s: length type for sequence is expected to be an integer (unsigned).\n", __func__);
372 declaration_unref(declaration);
373 return NULL;
374 }
375 integer_declaration = container_of(declaration, struct declaration_integer, p);
376 if (integer_declaration->signedness != false) {
377 fprintf(fd, "[error] %s: length type for sequence should always be an unsigned integer.\n", __func__);
378 declaration_unref(declaration);
379 return NULL;
380 }
381
382 sequence_declaration = sequence_declaration_new(integer_declaration,
383 nested_declaration, declaration_scope);
384 declaration = &sequence_declaration->p;
385 break;
386 }
387 default:
388 assert(0);
389 }
390
391 /* Pass it as content of outer container */
392 declaration = ctf_type_declarator_visit(fd, depth,
393 type_specifier_list, field_name,
394 node_type_declarator->u.type_declarator.u.nested.type_declarator,
395 declaration_scope, declaration, trace);
396 return declaration;
397 }
398 }
399
400 static
401 int ctf_struct_type_declarators_visit(FILE *fd, int depth,
402 struct declaration_struct *struct_declaration,
403 struct ctf_node *type_specifier_list,
404 struct cds_list_head *type_declarators,
405 struct declaration_scope *declaration_scope,
406 struct ctf_trace *trace)
407 {
408 struct ctf_node *iter;
409 GQuark field_name;
410
411 cds_list_for_each_entry(iter, type_declarators, siblings) {
412 struct declaration *field_declaration;
413
414 field_declaration = ctf_type_declarator_visit(fd, depth,
415 type_specifier_list,
416 &field_name, iter,
417 struct_declaration->scope,
418 NULL, trace);
419 if (!field_declaration) {
420 fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
421 return -EINVAL;
422 }
423 struct_declaration_add_field(struct_declaration,
424 g_quark_to_string(field_name),
425 field_declaration);
426 }
427 return 0;
428 }
429
430 static
431 int ctf_variant_type_declarators_visit(FILE *fd, int depth,
432 struct declaration_untagged_variant *untagged_variant_declaration,
433 struct ctf_node *type_specifier_list,
434 struct cds_list_head *type_declarators,
435 struct declaration_scope *declaration_scope,
436 struct ctf_trace *trace)
437 {
438 struct ctf_node *iter;
439 GQuark field_name;
440
441 cds_list_for_each_entry(iter, type_declarators, siblings) {
442 struct declaration *field_declaration;
443
444 field_declaration = ctf_type_declarator_visit(fd, depth,
445 type_specifier_list,
446 &field_name, iter,
447 untagged_variant_declaration->scope,
448 NULL, trace);
449 if (!field_declaration) {
450 fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
451 return -EINVAL;
452 }
453 untagged_variant_declaration_add_field(untagged_variant_declaration,
454 g_quark_to_string(field_name),
455 field_declaration);
456 }
457 return 0;
458 }
459
460 static
461 int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
462 struct ctf_node *type_specifier_list,
463 struct cds_list_head *type_declarators,
464 struct ctf_trace *trace)
465 {
466 struct ctf_node *iter;
467 GQuark identifier;
468
469 cds_list_for_each_entry(iter, type_declarators, siblings) {
470 struct declaration *type_declaration;
471 int ret;
472
473 type_declaration = ctf_type_declarator_visit(fd, depth,
474 type_specifier_list,
475 &identifier, iter,
476 scope, NULL, trace);
477 if (!type_declaration) {
478 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
479 return -EINVAL;
480 }
481 /*
482 * Don't allow typedef and typealias of untagged
483 * variants.
484 */
485 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
486 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
487 declaration_unref(type_declaration);
488 return -EPERM;
489 }
490 ret = register_declaration(identifier, type_declaration, scope);
491 if (ret) {
492 type_declaration->declaration_free(type_declaration);
493 return ret;
494 }
495 }
496 return 0;
497 }
498
499 static
500 int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
501 struct ctf_node *target, struct ctf_node *alias,
502 struct ctf_trace *trace)
503 {
504 struct declaration *type_declaration;
505 struct ctf_node *node;
506 GQuark dummy_id;
507 GQuark alias_q;
508 int err;
509
510 /* See ctf_visitor_type_declarator() in the semantic validator. */
511
512 /*
513 * Create target type declaration.
514 */
515
516 if (cds_list_empty(&target->u.typealias_target.type_declarators))
517 node = NULL;
518 else
519 node = _cds_list_first_entry(&target->u.typealias_target.type_declarators,
520 struct ctf_node, siblings);
521 type_declaration = ctf_type_declarator_visit(fd, depth,
522 target->u.typealias_target.type_specifier_list,
523 &dummy_id, node,
524 scope, NULL, trace);
525 if (!type_declaration) {
526 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
527 err = -EINVAL;
528 goto error;
529 }
530 /*
531 * Don't allow typedef and typealias of untagged
532 * variants.
533 */
534 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
535 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
536 declaration_unref(type_declaration);
537 return -EPERM;
538 }
539 /*
540 * The semantic validator does not check whether the target is
541 * abstract or not (if it has an identifier). Check it here.
542 */
543 if (dummy_id != 0) {
544 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
545 err = -EINVAL;
546 goto error;
547 }
548 /*
549 * Create alias identifier.
550 */
551
552 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
553 struct ctf_node, siblings);
554 alias_q = create_typealias_identifier(fd, depth,
555 alias->u.typealias_alias.type_specifier_list, node);
556 err = register_declaration(alias_q, type_declaration, scope);
557 if (err)
558 goto error;
559 return 0;
560
561 error:
562 type_declaration->declaration_free(type_declaration);
563 return err;
564 }
565
566 static
567 int ctf_struct_declaration_list_visit(FILE *fd, int depth,
568 struct ctf_node *iter, struct declaration_struct *struct_declaration,
569 struct ctf_trace *trace)
570 {
571 int ret;
572
573 switch (iter->type) {
574 case NODE_TYPEDEF:
575 /* For each declarator, declare type and add type to struct declaration scope */
576 ret = ctf_typedef_visit(fd, depth,
577 struct_declaration->scope,
578 iter->u._typedef.type_specifier_list,
579 &iter->u._typedef.type_declarators, trace);
580 if (ret)
581 return ret;
582 break;
583 case NODE_TYPEALIAS:
584 /* Declare type with declarator and add type to struct declaration scope */
585 ret = ctf_typealias_visit(fd, depth,
586 struct_declaration->scope,
587 iter->u.typealias.target,
588 iter->u.typealias.alias, trace);
589 if (ret)
590 return ret;
591 break;
592 case NODE_STRUCT_OR_VARIANT_DECLARATION:
593 /* Add field to structure declaration */
594 ret = ctf_struct_type_declarators_visit(fd, depth,
595 struct_declaration,
596 iter->u.struct_or_variant_declaration.type_specifier_list,
597 &iter->u.struct_or_variant_declaration.type_declarators,
598 struct_declaration->scope, trace);
599 if (ret)
600 return ret;
601 break;
602 default:
603 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
604 assert(0);
605 }
606 return 0;
607 }
608
609 static
610 int ctf_variant_declaration_list_visit(FILE *fd, int depth,
611 struct ctf_node *iter,
612 struct declaration_untagged_variant *untagged_variant_declaration,
613 struct ctf_trace *trace)
614 {
615 int ret;
616
617 switch (iter->type) {
618 case NODE_TYPEDEF:
619 /* For each declarator, declare type and add type to variant declaration scope */
620 ret = ctf_typedef_visit(fd, depth,
621 untagged_variant_declaration->scope,
622 iter->u._typedef.type_specifier_list,
623 &iter->u._typedef.type_declarators, trace);
624 if (ret)
625 return ret;
626 break;
627 case NODE_TYPEALIAS:
628 /* Declare type with declarator and add type to variant declaration scope */
629 ret = ctf_typealias_visit(fd, depth,
630 untagged_variant_declaration->scope,
631 iter->u.typealias.target,
632 iter->u.typealias.alias, trace);
633 if (ret)
634 return ret;
635 break;
636 case NODE_STRUCT_OR_VARIANT_DECLARATION:
637 /* Add field to structure declaration */
638 ret = ctf_variant_type_declarators_visit(fd, depth,
639 untagged_variant_declaration,
640 iter->u.struct_or_variant_declaration.type_specifier_list,
641 &iter->u.struct_or_variant_declaration.type_declarators,
642 untagged_variant_declaration->scope, trace);
643 if (ret)
644 return ret;
645 break;
646 default:
647 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
648 assert(0);
649 }
650 return 0;
651 }
652
653 static
654 struct declaration *ctf_declaration_struct_visit(FILE *fd,
655 int depth, const char *name, struct cds_list_head *declaration_list,
656 int has_body, struct declaration_scope *declaration_scope,
657 struct ctf_trace *trace)
658 {
659 struct declaration_struct *struct_declaration;
660 struct ctf_node *iter;
661 int ret;
662
663 /*
664 * For named struct (without body), lookup in
665 * declaration scope. Don't take reference on struct
666 * declaration: ref is only taken upon definition.
667 */
668 if (!has_body) {
669 assert(name);
670 struct_declaration =
671 lookup_struct_declaration(g_quark_from_string(name),
672 declaration_scope);
673 return &struct_declaration->p;
674 } else {
675 /* For unnamed struct, create type */
676 /* For named struct (with body), create type and add to declaration scope */
677 if (name) {
678 if (lookup_struct_declaration(g_quark_from_string(name),
679 declaration_scope)) {
680
681 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
682 return NULL;
683 }
684 }
685 struct_declaration = struct_declaration_new(declaration_scope);
686 cds_list_for_each_entry(iter, declaration_list, siblings) {
687 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
688 struct_declaration, trace);
689 if (ret)
690 goto error;
691 }
692 if (name) {
693 ret = register_struct_declaration(g_quark_from_string(name),
694 struct_declaration,
695 declaration_scope);
696 assert(!ret);
697 }
698 return &struct_declaration->p;
699 }
700 error:
701 struct_declaration->p.declaration_free(&struct_declaration->p);
702 return NULL;
703 }
704
705 static
706 struct declaration *ctf_declaration_variant_visit(FILE *fd,
707 int depth, const char *name, const char *choice,
708 struct cds_list_head *declaration_list,
709 int has_body, struct declaration_scope *declaration_scope,
710 struct ctf_trace *trace)
711 {
712 struct declaration_untagged_variant *untagged_variant_declaration;
713 struct declaration_variant *variant_declaration;
714 struct ctf_node *iter;
715 int ret;
716
717 /*
718 * For named variant (without body), lookup in
719 * declaration scope. Don't take reference on variant
720 * declaration: ref is only taken upon definition.
721 */
722 if (!has_body) {
723 assert(name);
724 untagged_variant_declaration =
725 lookup_variant_declaration(g_quark_from_string(name),
726 declaration_scope);
727 } else {
728 /* For unnamed variant, create type */
729 /* For named variant (with body), create type and add to declaration scope */
730 if (name) {
731 if (lookup_variant_declaration(g_quark_from_string(name),
732 declaration_scope)) {
733
734 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
735 return NULL;
736 }
737 }
738 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
739 cds_list_for_each_entry(iter, declaration_list, siblings) {
740 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
741 untagged_variant_declaration, trace);
742 if (ret)
743 goto error;
744 }
745 if (name) {
746 ret = register_variant_declaration(g_quark_from_string(name),
747 untagged_variant_declaration,
748 declaration_scope);
749 assert(!ret);
750 }
751 }
752 /*
753 * if tagged, create tagged variant and return. else return
754 * untagged variant.
755 */
756 if (!choice) {
757 return &untagged_variant_declaration->p;
758 } else {
759 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
760 if (!variant_declaration)
761 goto error;
762 declaration_unref(&untagged_variant_declaration->p);
763 return &variant_declaration->p;
764 }
765 error:
766 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
767 return NULL;
768 }
769
770 static
771 int ctf_enumerator_list_visit(FILE *fd, int depth,
772 struct ctf_node *enumerator,
773 struct declaration_enum *enum_declaration)
774 {
775 GQuark q;
776 struct ctf_node *iter;
777
778 q = g_quark_from_string(enumerator->u.enumerator.id);
779 if (enum_declaration->integer_declaration->signedness) {
780 int64_t start, end;
781 int nr_vals = 0;
782
783 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
784 int64_t *target;
785
786 assert(iter->type == NODE_UNARY_EXPRESSION);
787 if (nr_vals == 0)
788 target = &start;
789 else
790 target = &end;
791
792 switch (iter->u.unary_expression.type) {
793 case UNARY_SIGNED_CONSTANT:
794 *target = iter->u.unary_expression.u.signed_constant;
795 break;
796 case UNARY_UNSIGNED_CONSTANT:
797 *target = iter->u.unary_expression.u.unsigned_constant;
798 break;
799 default:
800 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
801 return -EINVAL;
802 }
803 if (nr_vals > 1) {
804 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
805 return -EINVAL;
806 }
807 nr_vals++;
808 }
809 if (nr_vals == 1)
810 end = start;
811 enum_signed_insert(enum_declaration, start, end, q);
812 } else {
813 uint64_t start, end;
814 int nr_vals = 0;
815
816 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
817 uint64_t *target;
818
819 assert(iter->type == NODE_UNARY_EXPRESSION);
820 if (nr_vals == 0)
821 target = &start;
822 else
823 target = &end;
824
825 switch (iter->u.unary_expression.type) {
826 case UNARY_UNSIGNED_CONSTANT:
827 *target = iter->u.unary_expression.u.unsigned_constant;
828 break;
829 case UNARY_SIGNED_CONSTANT:
830 /*
831 * We don't accept signed constants for enums with unsigned
832 * container type.
833 */
834 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
835 return -EINVAL;
836 default:
837 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
838 return -EINVAL;
839 }
840 if (nr_vals > 1) {
841 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
842 return -EINVAL;
843 }
844 nr_vals++;
845 }
846 if (nr_vals == 1)
847 end = start;
848 enum_unsigned_insert(enum_declaration, start, end, q);
849 }
850 return 0;
851 }
852
853 static
854 struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
855 const char *name,
856 struct ctf_node *container_type,
857 struct cds_list_head *enumerator_list,
858 int has_body,
859 struct declaration_scope *declaration_scope,
860 struct ctf_trace *trace)
861 {
862 struct declaration *declaration;
863 struct declaration_enum *enum_declaration;
864 struct declaration_integer *integer_declaration;
865 struct ctf_node *iter;
866 GQuark dummy_id;
867 int ret;
868
869 /*
870 * For named enum (without body), lookup in
871 * declaration scope. Don't take reference on enum
872 * declaration: ref is only taken upon definition.
873 */
874 if (!has_body) {
875 assert(name);
876 enum_declaration =
877 lookup_enum_declaration(g_quark_from_string(name),
878 declaration_scope);
879 return &enum_declaration->p;
880 } else {
881 /* For unnamed enum, create type */
882 /* For named enum (with body), create type and add to declaration scope */
883 if (name) {
884 if (lookup_enum_declaration(g_quark_from_string(name),
885 declaration_scope)) {
886
887 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
888 return NULL;
889 }
890 }
891 if (!container_type) {
892 declaration = lookup_declaration(g_quark_from_static_string("int"),
893 declaration_scope);
894 if (!declaration) {
895 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
896 return NULL;
897 }
898 } else {
899 declaration = ctf_type_declarator_visit(fd, depth,
900 container_type,
901 &dummy_id, NULL,
902 declaration_scope,
903 NULL, trace);
904 }
905 if (!declaration) {
906 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
907 return NULL;
908 }
909 if (declaration->id != CTF_TYPE_INTEGER) {
910 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
911 return NULL;
912 }
913 integer_declaration = container_of(declaration, struct declaration_integer, p);
914 enum_declaration = enum_declaration_new(integer_declaration);
915 declaration_unref(&integer_declaration->p); /* leave ref to enum */
916 cds_list_for_each_entry(iter, enumerator_list, siblings) {
917 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
918 if (ret)
919 goto error;
920 }
921 if (name) {
922 ret = register_enum_declaration(g_quark_from_string(name),
923 enum_declaration,
924 declaration_scope);
925 assert(!ret);
926 }
927 return &enum_declaration->p;
928 }
929 error:
930 enum_declaration->p.declaration_free(&enum_declaration->p);
931 return NULL;
932 }
933
934 static
935 struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
936 struct ctf_node *type_specifier_list,
937 struct declaration_scope *declaration_scope)
938 {
939 GString *str;
940 struct declaration *declaration;
941 char *str_c;
942 int ret;
943 GQuark id_q;
944
945 str = g_string_new("");
946 ret = visit_type_specifier_list(fd, type_specifier_list, str);
947 if (ret)
948 return NULL;
949 str_c = g_string_free(str, FALSE);
950 id_q = g_quark_from_string(str_c);
951 g_free(str_c);
952 declaration = lookup_declaration(id_q, declaration_scope);
953 return declaration;
954 }
955
956 /*
957 * Returns 0/1 boolean, or < 0 on error.
958 */
959 static
960 int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
961 {
962 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
963 fprintf(fd, "[error] %s: expecting unary expression\n",
964 __func__);
965 return -EINVAL;
966 }
967 switch (unary_expression->u.unary_expression.type) {
968 case UNARY_UNSIGNED_CONSTANT:
969 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
970 return 0;
971 else
972 return 1;
973 case UNARY_SIGNED_CONSTANT:
974 if (unary_expression->u.unary_expression.u.signed_constant == 0)
975 return 0;
976 else
977 return 1;
978 case UNARY_STRING:
979 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
980 return 1;
981 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
982 return 1;
983 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
984 return 0;
985 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
986 return 0;
987 else {
988 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
989 __func__, unary_expression->u.unary_expression.u.string);
990 return -EINVAL;
991 }
992 break;
993 default:
994 fprintf(fd, "[error] %s: unexpected unary expression type\n",
995 __func__);
996 return -EINVAL;
997 }
998
999 }
1000
1001 static
1002 int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1003 {
1004 int byte_order;
1005
1006 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1007 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1008 __func__);
1009 return -EINVAL;
1010 }
1011 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1012 byte_order = BIG_ENDIAN;
1013 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1014 byte_order = LITTLE_ENDIAN;
1015 else {
1016 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1017 __func__, unary_expression->u.unary_expression.u.string);
1018 return -EINVAL;
1019 }
1020 return byte_order;
1021 }
1022
1023 static
1024 int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1025 struct ctf_trace *trace)
1026 {
1027 int byte_order;
1028
1029 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1030 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1031 __func__);
1032 return -EINVAL;
1033 }
1034 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1035 byte_order = trace->byte_order;
1036 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1037 byte_order = BIG_ENDIAN;
1038 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1039 byte_order = BIG_ENDIAN;
1040 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1041 byte_order = LITTLE_ENDIAN;
1042 else {
1043 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1044 __func__, unary_expression->u.unary_expression.u.string);
1045 return -EINVAL;
1046 }
1047 return byte_order;
1048 }
1049
1050 static
1051 struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
1052 struct cds_list_head *expressions,
1053 struct ctf_trace *trace)
1054 {
1055 struct ctf_node *expression;
1056 uint64_t alignment, size;
1057 int byte_order = trace->byte_order;
1058 int signedness = 0;
1059 int has_alignment = 0, has_size = 0;
1060 struct declaration_integer *integer_declaration;
1061
1062 cds_list_for_each_entry(expression, expressions, siblings) {
1063 struct ctf_node *left, *right;
1064
1065 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1066 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1067 assert(left->u.unary_expression.type == UNARY_STRING);
1068 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
1069 signedness = get_boolean(fd, depth, right);
1070 if (signedness < 0)
1071 return NULL;
1072 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1073 byte_order = get_byte_order(fd, depth, right, trace);
1074 if (byte_order < 0)
1075 return NULL;
1076 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
1077 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1078 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
1079 __func__);
1080 return NULL;
1081 }
1082 size = right->u.unary_expression.u.unsigned_constant;
1083 has_size = 1;
1084 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1085 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1086 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1087 __func__);
1088 return NULL;
1089 }
1090 alignment = right->u.unary_expression.u.unsigned_constant;
1091 has_alignment = 1;
1092 } else {
1093 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1094 __func__, left->u.unary_expression.u.string);
1095 return NULL;
1096 }
1097 }
1098 if (!has_size) {
1099 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
1100 return NULL;
1101 }
1102 if (!has_alignment) {
1103 if (size % CHAR_BIT) {
1104 /* bit-packed alignment */
1105 alignment = 1;
1106 } else {
1107 /* byte-packed alignment */
1108 alignment = CHAR_BIT;
1109 }
1110 }
1111 integer_declaration = integer_declaration_new(size,
1112 byte_order, signedness, alignment);
1113 return &integer_declaration->p;
1114 }
1115
1116 static
1117 struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
1118 struct cds_list_head *expressions,
1119 struct ctf_trace *trace)
1120 {
1121 struct ctf_node *expression;
1122 uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
1123 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1124 struct declaration_float *float_declaration;
1125
1126 cds_list_for_each_entry(expression, expressions, siblings) {
1127 struct ctf_node *left, *right;
1128
1129 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1130 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1131 assert(left->u.unary_expression.type == UNARY_STRING);
1132 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1133 byte_order = get_byte_order(fd, depth, right, trace);
1134 if (byte_order < 0)
1135 return NULL;
1136 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1137 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1138 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
1139 __func__);
1140 return NULL;
1141 }
1142 exp_dig = right->u.unary_expression.u.unsigned_constant;
1143 has_exp_dig = 1;
1144 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1145 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1146 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
1147 __func__);
1148 return NULL;
1149 }
1150 mant_dig = right->u.unary_expression.u.unsigned_constant;
1151 has_mant_dig = 1;
1152 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1153 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1154 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1155 __func__);
1156 return NULL;
1157 }
1158 alignment = right->u.unary_expression.u.unsigned_constant;
1159 has_alignment = 1;
1160 } else {
1161 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1162 __func__, left->u.unary_expression.u.string);
1163 return NULL;
1164 }
1165 }
1166 if (!has_mant_dig) {
1167 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
1168 return NULL;
1169 }
1170 if (!has_exp_dig) {
1171 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
1172 return NULL;
1173 }
1174 if (!has_alignment) {
1175 if ((mant_dig + exp_dig) % CHAR_BIT) {
1176 /* bit-packed alignment */
1177 alignment = 1;
1178 } else {
1179 /* byte-packed alignment */
1180 alignment = CHAR_BIT;
1181 }
1182 }
1183 float_declaration = float_declaration_new(mant_dig, exp_dig,
1184 byte_order, alignment);
1185 return &float_declaration->p;
1186 }
1187
1188 static
1189 struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
1190 struct cds_list_head *expressions,
1191 struct ctf_trace *trace)
1192 {
1193 struct ctf_node *expression;
1194 const char *encoding_c = NULL;
1195 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1196 struct declaration_string *string_declaration;
1197
1198 cds_list_for_each_entry(expression, expressions, siblings) {
1199 struct ctf_node *left, *right;
1200
1201 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1202 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1203 assert(left->u.unary_expression.type == UNARY_STRING);
1204 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1205 if (right->u.unary_expression.type != UNARY_STRING) {
1206 fprintf(fd, "[error] %s: encoding: expecting string\n",
1207 __func__);
1208 return NULL;
1209 }
1210 encoding_c = right->u.unary_expression.u.string;
1211 } else {
1212 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1213 __func__, left->u.unary_expression.u.string);
1214 return NULL;
1215 }
1216 }
1217 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1218 encoding = CTF_STRING_ASCII;
1219 string_declaration = string_declaration_new(encoding);
1220 return &string_declaration->p;
1221 }
1222
1223
1224 static
1225 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1226 int depth, struct ctf_node *type_specifier_list,
1227 struct declaration_scope *declaration_scope,
1228 struct ctf_trace *trace)
1229 {
1230 struct ctf_node *first;
1231 struct ctf_node *node;
1232
1233 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1234
1235 first = _cds_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
1236
1237 assert(first->type == NODE_TYPE_SPECIFIER);
1238
1239 node = first->u.type_specifier.node;
1240
1241 switch (first->u.type_specifier.type) {
1242 case TYPESPEC_FLOATING_POINT:
1243 return ctf_declaration_floating_point_visit(fd, depth,
1244 &node->u.floating_point.expressions, trace);
1245 case TYPESPEC_INTEGER:
1246 return ctf_declaration_integer_visit(fd, depth,
1247 &node->u.integer.expressions, trace);
1248 case TYPESPEC_STRING:
1249 return ctf_declaration_string_visit(fd, depth,
1250 &node->u.string.expressions, trace);
1251 case TYPESPEC_STRUCT:
1252 return ctf_declaration_struct_visit(fd, depth,
1253 node->u._struct.name,
1254 &node->u._struct.declaration_list,
1255 node->u._struct.has_body,
1256 declaration_scope,
1257 trace);
1258 case TYPESPEC_VARIANT:
1259 return ctf_declaration_variant_visit(fd, depth,
1260 node->u.variant.name,
1261 node->u.variant.choice,
1262 &node->u.variant.declaration_list,
1263 node->u.variant.has_body,
1264 declaration_scope,
1265 trace);
1266 case TYPESPEC_ENUM:
1267 return ctf_declaration_enum_visit(fd, depth,
1268 node->u._enum.enum_id,
1269 node->u._enum.container_type,
1270 &node->u._enum.enumerator_list,
1271 node->u._enum.has_body,
1272 declaration_scope,
1273 trace);
1274
1275 case TYPESPEC_VOID:
1276 case TYPESPEC_CHAR:
1277 case TYPESPEC_SHORT:
1278 case TYPESPEC_INT:
1279 case TYPESPEC_LONG:
1280 case TYPESPEC_FLOAT:
1281 case TYPESPEC_DOUBLE:
1282 case TYPESPEC_SIGNED:
1283 case TYPESPEC_UNSIGNED:
1284 case TYPESPEC_BOOL:
1285 case TYPESPEC_COMPLEX:
1286 case TYPESPEC_IMAGINARY:
1287 case TYPESPEC_CONST:
1288 case TYPESPEC_ID_TYPE:
1289 return ctf_declaration_type_specifier_visit(fd, depth,
1290 type_specifier_list, declaration_scope);
1291 default:
1292 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
1293 return NULL;
1294 }
1295 }
1296
1297 static
1298 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1299 {
1300 int ret = 0;
1301
1302 switch (node->type) {
1303 case NODE_TYPEDEF:
1304 ret = ctf_typedef_visit(fd, depth + 1,
1305 event->declaration_scope,
1306 node->u._typedef.type_specifier_list,
1307 &node->u._typedef.type_declarators,
1308 trace);
1309 if (ret)
1310 return ret;
1311 break;
1312 case NODE_TYPEALIAS:
1313 ret = ctf_typealias_visit(fd, depth + 1,
1314 event->declaration_scope,
1315 node->u.typealias.target, node->u.typealias.alias,
1316 trace);
1317 if (ret)
1318 return ret;
1319 break;
1320 case NODE_CTF_EXPRESSION:
1321 {
1322 char *left;
1323
1324 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1325 if (!strcmp(left, "name")) {
1326 char *right;
1327
1328 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1329 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
1330 ret = -EPERM;
1331 goto error;
1332 }
1333 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1334 if (!right) {
1335 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
1336 ret = -EINVAL;
1337 goto error;
1338 }
1339 event->name = g_quark_from_string(right);
1340 g_free(right);
1341 CTF_EVENT_SET_FIELD(event, name);
1342 } else if (!strcmp(left, "id")) {
1343 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1344 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
1345 ret = -EPERM;
1346 goto error;
1347 }
1348 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1349 if (ret) {
1350 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
1351 ret = -EINVAL;
1352 goto error;
1353 }
1354 CTF_EVENT_SET_FIELD(event, id);
1355 } else if (!strcmp(left, "stream_id")) {
1356 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1357 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
1358 ret = -EPERM;
1359 goto error;
1360 }
1361 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1362 if (ret) {
1363 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1364 ret = -EINVAL;
1365 goto error;
1366 }
1367 event->stream = trace_stream_lookup(trace, event->stream_id);
1368 if (!event->stream) {
1369 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1370 ret = -EINVAL;
1371 goto error;
1372 }
1373 CTF_EVENT_SET_FIELD(event, stream_id);
1374 } else if (!strcmp(left, "context")) {
1375 struct declaration *declaration;
1376
1377 if (event->context_decl) {
1378 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
1379 ret = -EINVAL;
1380 goto error;
1381 }
1382 declaration = ctf_type_specifier_list_visit(fd, depth,
1383 _cds_list_first_entry(&node->u.ctf_expression.right,
1384 struct ctf_node, siblings),
1385 event->declaration_scope, trace);
1386 if (!declaration) {
1387 ret = -EPERM;
1388 goto error;
1389 }
1390 if (declaration->id != CTF_TYPE_STRUCT) {
1391 ret = -EPERM;
1392 goto error;
1393 }
1394 event->context_decl = container_of(declaration, struct declaration_struct, p);
1395 } else if (!strcmp(left, "fields")) {
1396 struct declaration *declaration;
1397
1398 if (event->fields_decl) {
1399 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
1400 ret = -EINVAL;
1401 goto error;
1402 }
1403 declaration = ctf_type_specifier_list_visit(fd, depth,
1404 _cds_list_first_entry(&node->u.ctf_expression.right,
1405 struct ctf_node, siblings),
1406 event->declaration_scope, trace);
1407 if (!declaration) {
1408 ret = -EPERM;
1409 goto error;
1410 }
1411 if (declaration->id != CTF_TYPE_STRUCT) {
1412 ret = -EPERM;
1413 goto error;
1414 }
1415 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1416 }
1417 error:
1418 g_free(left);
1419 break;
1420 }
1421 default:
1422 return -EPERM;
1423 /* TODO: declaration specifier should be added. */
1424 }
1425
1426 return ret;
1427 }
1428
1429 static
1430 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1431 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1432 {
1433 int ret = 0;
1434 struct ctf_node *iter;
1435 struct ctf_event *event;
1436 struct definition_scope *parent_def_scope;
1437
1438 event = g_new0(struct ctf_event, 1);
1439 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1440 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1441 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1442 if (ret)
1443 goto error;
1444 }
1445 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1446 ret = -EPERM;
1447 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
1448 goto error;
1449 }
1450 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1451 /* Allow missing stream_id if there is only a single stream */
1452 switch (trace->streams->len) {
1453 case 0: /* Create stream if there was none. */
1454 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1455 if (ret)
1456 goto error;
1457 /* Fall-through */
1458 case 1:
1459 event->stream_id = 0;
1460 event->stream = trace_stream_lookup(trace, event->stream_id);
1461 break;
1462 default:
1463 ret = -EPERM;
1464 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1465 goto error;
1466 }
1467 }
1468 /* Allow only one event without id per stream */
1469 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1470 && event->stream->events_by_id->len != 0) {
1471 ret = -EPERM;
1472 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1473 goto error;
1474 }
1475 if (event->stream->events_by_id->len <= event->id)
1476 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1477 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1478 g_hash_table_insert(event->stream->event_quark_to_id,
1479 (gpointer)(unsigned long) event->name,
1480 &event->id);
1481 parent_def_scope = event->stream->definition_scope;
1482 if (event->context_decl) {
1483 event->context =
1484 container_of(
1485 event->context_decl->p.definition_new(&event->context_decl->p,
1486 parent_def_scope, 0, 0),
1487 struct definition_struct, p);
1488 set_dynamic_definition_scope(&event->context->p,
1489 event->context->scope,
1490 "event.context");
1491 parent_def_scope = event->context->scope;
1492 declaration_unref(&event->context_decl->p);
1493 }
1494 if (event->fields_decl) {
1495 event->fields =
1496 container_of(
1497 event->fields_decl->p.definition_new(&event->fields_decl->p,
1498 parent_def_scope, 0, 0),
1499 struct definition_struct, p);
1500 set_dynamic_definition_scope(&event->fields->p,
1501 event->fields->scope,
1502 "event.fields");
1503 parent_def_scope = event->fields->scope;
1504 declaration_unref(&event->fields_decl->p);
1505 }
1506 return 0;
1507
1508 error:
1509 declaration_unref(&event->fields_decl->p);
1510 declaration_unref(&event->context_decl->p);
1511 free_declaration_scope(event->declaration_scope);
1512 g_free(event);
1513 return ret;
1514 }
1515
1516
1517 static
1518 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
1519 {
1520 int ret = 0;
1521
1522 switch (node->type) {
1523 case NODE_TYPEDEF:
1524 ret = ctf_typedef_visit(fd, depth + 1,
1525 stream->declaration_scope,
1526 node->u._typedef.type_specifier_list,
1527 &node->u._typedef.type_declarators,
1528 trace);
1529 if (ret)
1530 return ret;
1531 break;
1532 case NODE_TYPEALIAS:
1533 ret = ctf_typealias_visit(fd, depth + 1,
1534 stream->declaration_scope,
1535 node->u.typealias.target, node->u.typealias.alias,
1536 trace);
1537 if (ret)
1538 return ret;
1539 break;
1540 case NODE_CTF_EXPRESSION:
1541 {
1542 char *left;
1543
1544 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1545 if (!strcmp(left, "id")) {
1546 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1547 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
1548 ret = -EPERM;
1549 goto error;
1550 }
1551 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
1552 if (ret) {
1553 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
1554 ret = -EINVAL;
1555 goto error;
1556 }
1557 CTF_STREAM_SET_FIELD(stream, stream_id);
1558 } else if (!strcmp(left, "event.header")) {
1559 struct declaration *declaration;
1560
1561 if (stream->event_header_decl) {
1562 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
1563 ret = -EINVAL;
1564 goto error;
1565 }
1566 declaration = ctf_type_specifier_list_visit(fd, depth,
1567 _cds_list_first_entry(&node->u.ctf_expression.right,
1568 struct ctf_node, siblings),
1569 stream->declaration_scope, trace);
1570 if (!declaration) {
1571 ret = -EPERM;
1572 goto error;
1573 }
1574 if (declaration->id != CTF_TYPE_STRUCT) {
1575 ret = -EPERM;
1576 goto error;
1577 }
1578 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1579 } else if (!strcmp(left, "event.context")) {
1580 struct declaration *declaration;
1581
1582 if (stream->event_context_decl) {
1583 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
1584 ret = -EINVAL;
1585 goto error;
1586 }
1587 declaration = ctf_type_specifier_list_visit(fd, depth,
1588 _cds_list_first_entry(&node->u.ctf_expression.right,
1589 struct ctf_node, siblings),
1590 stream->declaration_scope, trace);
1591 if (!declaration) {
1592 ret = -EPERM;
1593 goto error;
1594 }
1595 if (declaration->id != CTF_TYPE_STRUCT) {
1596 ret = -EPERM;
1597 goto error;
1598 }
1599 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1600 } else if (!strcmp(left, "packet.context")) {
1601 struct declaration *declaration;
1602
1603 if (stream->packet_context_decl) {
1604 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
1605 ret = -EINVAL;
1606 goto error;
1607 }
1608 declaration = ctf_type_specifier_list_visit(fd, depth,
1609 _cds_list_first_entry(&node->u.ctf_expression.right,
1610 struct ctf_node, siblings),
1611 stream->declaration_scope, trace);
1612 if (!declaration) {
1613 ret = -EPERM;
1614 goto error;
1615 }
1616 if (declaration->id != CTF_TYPE_STRUCT) {
1617 ret = -EPERM;
1618 goto error;
1619 }
1620 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1621 }
1622 error:
1623 g_free(left);
1624 break;
1625 }
1626 default:
1627 return -EPERM;
1628 /* TODO: declaration specifier should be added. */
1629 }
1630
1631 return ret;
1632 }
1633
1634 static
1635 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1636 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1637 {
1638 int ret = 0;
1639 struct ctf_node *iter;
1640 struct ctf_stream *stream;
1641 struct definition_scope *parent_def_scope;
1642
1643 stream = g_new0(struct ctf_stream, 1);
1644 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1645 stream->events_by_id = g_ptr_array_new();
1646 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1647 stream->files = g_ptr_array_new();
1648 if (node) {
1649 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1650 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1651 if (ret)
1652 goto error;
1653 }
1654 }
1655 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1656 /* check that packet header has stream_id field. */
1657 if (!trace->packet_header_decl
1658 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
1659 ret = -EPERM;
1660 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
1661 goto error;
1662 }
1663 } else {
1664 /* Allow only one id-less stream */
1665 if (trace->streams->len != 0) {
1666 ret = -EPERM;
1667 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
1668 goto error;
1669 }
1670 stream->stream_id = 0;
1671 }
1672 if (trace->streams->len <= stream->stream_id)
1673 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1674 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
1675
1676 parent_def_scope = trace->definition_scope;
1677 if (stream->packet_context_decl) {
1678 stream->packet_context =
1679 container_of(
1680 stream->packet_context_decl->p.definition_new(&stream->packet_context_decl->p,
1681 parent_def_scope, 0, 0),
1682 struct definition_struct, p);
1683 set_dynamic_definition_scope(&stream->packet_context->p,
1684 stream->packet_context->scope,
1685 "stream.packet.context");
1686 parent_def_scope = stream->packet_context->scope;
1687 declaration_unref(&stream->packet_context_decl->p);
1688 }
1689 if (stream->event_header_decl) {
1690 stream->event_header =
1691 container_of(
1692 stream->event_header_decl->p.definition_new(&stream->event_header_decl->p,
1693 parent_def_scope, 0, 0),
1694 struct definition_struct, p);
1695 set_dynamic_definition_scope(&stream->event_header->p,
1696 stream->event_header->scope,
1697 "stream.event.header");
1698 parent_def_scope = stream->event_header->scope;
1699 declaration_unref(&stream->event_header_decl->p);
1700 }
1701 if (stream->event_context_decl) {
1702 stream->event_context =
1703 container_of(
1704 stream->event_context_decl->p.definition_new(&stream->event_context_decl->p,
1705 parent_def_scope, 0, 0),
1706 struct definition_struct, p);
1707 set_dynamic_definition_scope(&stream->event_context->p,
1708 stream->event_context->scope,
1709 "stream.event.context");
1710 parent_def_scope = stream->event_context->scope;
1711 declaration_unref(&stream->event_context_decl->p);
1712 }
1713 stream->definition_scope = parent_def_scope;
1714
1715 return 0;
1716
1717 error:
1718 declaration_unref(&stream->event_header_decl->p);
1719 declaration_unref(&stream->event_context_decl->p);
1720 declaration_unref(&stream->packet_context_decl->p);
1721 g_ptr_array_free(stream->files, TRUE);
1722 g_ptr_array_free(stream->events_by_id, TRUE);
1723 g_hash_table_destroy(stream->event_quark_to_id);
1724 free_declaration_scope(stream->declaration_scope);
1725 g_free(stream);
1726 return ret;
1727 }
1728
1729 static
1730 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1731 {
1732 int ret = 0;
1733
1734 switch (node->type) {
1735 case NODE_TYPEDEF:
1736 ret = ctf_typedef_visit(fd, depth + 1,
1737 trace->declaration_scope,
1738 node->u._typedef.type_specifier_list,
1739 &node->u._typedef.type_declarators,
1740 trace);
1741 if (ret)
1742 return ret;
1743 break;
1744 case NODE_TYPEALIAS:
1745 ret = ctf_typealias_visit(fd, depth + 1,
1746 trace->declaration_scope,
1747 node->u.typealias.target, node->u.typealias.alias,
1748 trace);
1749 if (ret)
1750 return ret;
1751 break;
1752 case NODE_CTF_EXPRESSION:
1753 {
1754 char *left;
1755
1756 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1757 if (!strcmp(left, "major")) {
1758 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
1759 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
1760 ret = -EPERM;
1761 goto error;
1762 }
1763 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1764 if (ret) {
1765 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
1766 ret = -EINVAL;
1767 goto error;
1768 }
1769 CTF_TRACE_SET_FIELD(trace, major);
1770 } else if (!strcmp(left, "minor")) {
1771 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1772 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
1773 ret = -EPERM;
1774 goto error;
1775 }
1776 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1777 if (ret) {
1778 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
1779 ret = -EINVAL;
1780 goto error;
1781 }
1782 CTF_TRACE_SET_FIELD(trace, minor);
1783 } else if (!strcmp(left, "uuid")) {
1784 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
1785 fprintf(fd, "[error] %s: uuid already declared in trace declaration\n", __func__);
1786 ret = -EPERM;
1787 goto error;
1788 }
1789 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1790 if (ret) {
1791 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
1792 ret = -EINVAL;
1793 goto error;
1794 }
1795 CTF_TRACE_SET_FIELD(trace, uuid);
1796 } else if (!strcmp(left, "byte_order")) {
1797 struct ctf_node *right;
1798 int byte_order;
1799
1800 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1801 fprintf(fd, "[error] %s: endianness already declared in trace declaration\n", __func__);
1802 ret = -EPERM;
1803 goto error;
1804 }
1805 right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
1806 byte_order = get_trace_byte_order(fd, depth, right);
1807 if (byte_order < 0)
1808 return -EINVAL;
1809 trace->byte_order = byte_order;
1810 CTF_TRACE_SET_FIELD(trace, byte_order);
1811 } else if (!strcmp(left, "packet.header")) {
1812 struct declaration *declaration;
1813
1814 if (trace->packet_header_decl) {
1815 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
1816 ret = -EINVAL;
1817 goto error;
1818 }
1819 declaration = ctf_type_specifier_list_visit(fd, depth,
1820 _cds_list_first_entry(&node->u.ctf_expression.right,
1821 struct ctf_node, siblings),
1822 trace->declaration_scope, trace);
1823 if (!declaration) {
1824 ret = -EPERM;
1825 goto error;
1826 }
1827 if (declaration->id != CTF_TYPE_STRUCT) {
1828 ret = -EPERM;
1829 goto error;
1830 }
1831 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
1832 }
1833 error:
1834 g_free(left);
1835 break;
1836 }
1837 default:
1838 return -EPERM;
1839 /* TODO: declaration specifier should be added. */
1840 }
1841
1842 return ret;
1843 }
1844
1845 static
1846 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1847 {
1848 struct definition_scope *parent_def_scope;
1849 int ret = 0;
1850 struct ctf_node *iter;
1851
1852 if (trace->declaration_scope)
1853 return -EEXIST;
1854 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
1855 trace->streams = g_ptr_array_new();
1856 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1857 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1858 if (ret)
1859 goto error;
1860 }
1861 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
1862 ret = -EPERM;
1863 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
1864 goto error;
1865 }
1866 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1867 ret = -EPERM;
1868 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
1869 goto error;
1870 }
1871 if (!CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
1872 ret = -EPERM;
1873 fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
1874 goto error;
1875 }
1876 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1877 ret = -EPERM;
1878 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
1879 goto error;
1880 }
1881
1882 parent_def_scope = NULL;
1883 if (trace->packet_header_decl) {
1884 trace->packet_header =
1885 container_of(
1886 trace->packet_header_decl->p.definition_new(&trace->packet_header_decl->p,
1887 parent_def_scope, 0, 0),
1888 struct definition_struct, p);
1889 set_dynamic_definition_scope(&trace->packet_header->p,
1890 trace->packet_header->scope,
1891 "trace.packet.header");
1892 parent_def_scope = trace->packet_header->scope;
1893 declaration_unref(&trace->packet_header_decl->p);
1894 }
1895 trace->definition_scope = parent_def_scope;
1896
1897 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1898 /* check that the packet header contains a "magic" field */
1899 if (!trace->packet_header
1900 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
1901 ret = -EPERM;
1902 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
1903 goto error_free_def;
1904 }
1905 }
1906 return 0;
1907
1908 error_free_def:
1909 definition_unref(&trace->packet_header->p);
1910 error:
1911 g_ptr_array_free(trace->streams, TRUE);
1912 free_declaration_scope(trace->declaration_scope);
1913 return ret;
1914 }
1915
1916 static
1917 int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1918 {
1919 int ret = 0;
1920
1921 switch (node->type) {
1922 case NODE_TYPEDEF:
1923 ret = ctf_typedef_visit(fd, depth + 1,
1924 trace->root_declaration_scope,
1925 node->u._typedef.type_specifier_list,
1926 &node->u._typedef.type_declarators,
1927 trace);
1928 if (ret)
1929 return ret;
1930 break;
1931 case NODE_TYPEALIAS:
1932 ret = ctf_typealias_visit(fd, depth + 1,
1933 trace->root_declaration_scope,
1934 node->u.typealias.target, node->u.typealias.alias,
1935 trace);
1936 if (ret)
1937 return ret;
1938 break;
1939 case NODE_TYPE_SPECIFIER_LIST:
1940 {
1941 struct declaration *declaration;
1942
1943 /*
1944 * Just add the type specifier to the root scope
1945 * declaration scope. Release local reference.
1946 */
1947 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
1948 node, trace->root_declaration_scope, trace);
1949 if (!declaration)
1950 return -ENOMEM;
1951 declaration_unref(declaration);
1952 break;
1953 }
1954 default:
1955 return -EPERM;
1956 }
1957
1958 return 0;
1959 }
1960
1961 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
1962 struct ctf_trace *trace, int byte_order)
1963 {
1964 int ret = 0;
1965 struct ctf_node *iter;
1966
1967 printf_verbose("CTF visitor: metadata construction... ");
1968 trace->root_declaration_scope = new_declaration_scope(NULL);
1969 trace->byte_order = byte_order;
1970
1971 switch (node->type) {
1972 case NODE_ROOT:
1973 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
1974 siblings) {
1975 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
1976 if (ret) {
1977 fprintf(fd, "[error] %s: root declaration error\n", __func__);
1978 return ret;
1979 }
1980 }
1981 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
1982 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
1983 if (ret) {
1984 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
1985 return ret;
1986 }
1987 }
1988 if (!trace->streams) {
1989 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
1990 return -EINVAL;
1991 }
1992 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
1993 ret = ctf_stream_visit(fd, depth + 1, iter,
1994 trace->root_declaration_scope, trace);
1995 if (ret) {
1996 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
1997 return ret;
1998 }
1999 }
2000 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
2001 ret = ctf_event_visit(fd, depth + 1, iter,
2002 trace->root_declaration_scope, trace);
2003 if (ret) {
2004 fprintf(fd, "[error] %s: event declaration error\n", __func__);
2005 return ret;
2006 }
2007 }
2008 break;
2009 case NODE_UNKNOWN:
2010 default:
2011 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
2012 (int) node->type);
2013 return -EINVAL;
2014 }
2015 printf_verbose("done.\n");
2016 return ret;
2017 }
This page took 0.113049 seconds and 4 git commands to generate.