ctf visitor generate I/O struct: visit typedef/typealias
[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/list.h>
28 #include <uuid/uuid.h>
29 #include "ctf-scanner.h"
30 #include "ctf-parser.h"
31 #include "ctf-ast.h"
32
33 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
34
35 #define _cds_list_first_entry(ptr, type, member) \
36 cds_list_entry((ptr)->next, type, member)
37
38 static
39 struct declaration *ctf_declaration_specifier_visit(FILE *fd,
40 int depth, struct list_head *head,
41 struct declaration_scope *declaration_scope);
42
43 static
44 int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
45 {
46 print_tabs(fd, depth);
47 fprintf(fd, "<type_specifier \"");
48
49 switch (node->u.type_specifier.type) {
50 case TYPESPEC_VOID:
51 fprintf(fd, "void");
52 break;
53 case TYPESPEC_CHAR:
54 fprintf(fd, "char");
55 break;
56 case TYPESPEC_SHORT:
57 fprintf(fd, "short");
58 break;
59 case TYPESPEC_INT:
60 fprintf(fd, "int");
61 break;
62 case TYPESPEC_LONG:
63 fprintf(fd, "long");
64 break;
65 case TYPESPEC_FLOAT:
66 fprintf(fd, "float");
67 break;
68 case TYPESPEC_DOUBLE:
69 fprintf(fd, "double");
70 break;
71 case TYPESPEC_SIGNED:
72 fprintf(fd, "signed");
73 break;
74 case TYPESPEC_UNSIGNED:
75 fprintf(fd, "unsigned");
76 break;
77 case TYPESPEC_BOOL:
78 fprintf(fd, "bool");
79 break;
80 case TYPESPEC_COMPLEX:
81 fprintf(fd, "_Complex");
82 break;
83 case TYPESPEC_IMAGINARY:
84 fprintf(fd, "_Imaginary");
85 break;
86 case TYPESPEC_CONST:
87 fprintf(fd, "const");
88 break;
89 case TYPESPEC_ID_TYPE:
90 fprintf(fd, "%s", node->u.type_specifier.id_type);
91 break;
92
93 case TYPESPEC_UNKNOWN:
94 default:
95 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
96 (int) node->u.type_specifier.type);
97 return -EINVAL;
98 }
99 fprintf(fd, "\"/>\n");
100 return 0;
101 }
102
103 static
104 int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
105 {
106 int ret = 0;
107 struct ctf_node *iter;
108
109 print_tabs(fd, depth);
110 fprintf(fd, "<type_declarator>\n");
111 depth++;
112
113 if (!cds_list_empty(&node->u.type_declarator.pointers)) {
114 print_tabs(fd, depth);
115 fprintf(fd, "<pointers>\n");
116 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
117 siblings) {
118 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
119 if (ret)
120 return ret;
121 }
122 print_tabs(fd, depth);
123 fprintf(fd, "</pointers>\n");
124 }
125
126 switch (node->u.type_declarator.type) {
127 case TYPEDEC_ID:
128 if (node->u.type_declarator.u.id) {
129 print_tabs(fd, depth);
130 fprintf(fd, "<id \"");
131 fprintf(fd, "%s", node->u.type_declarator.u.id);
132 fprintf(fd, "\" />\n");
133 }
134 break;
135 case TYPEDEC_NESTED:
136 if (node->u.type_declarator.u.nested.type_declarator) {
137 print_tabs(fd, depth);
138 fprintf(fd, "<type_declarator>\n");
139 ret = ctf_visitor_print_xml(fd, depth + 1,
140 node->u.type_declarator.u.nested.type_declarator);
141 if (ret)
142 return ret;
143 print_tabs(fd, depth);
144 fprintf(fd, "</type_declarator>\n");
145 }
146 if (node->u.type_declarator.u.nested.length) {
147 print_tabs(fd, depth);
148 fprintf(fd, "<length>\n");
149 ret = ctf_visitor_print_xml(fd, depth + 1,
150 node->u.type_declarator.u.nested.length);
151 if (ret)
152 return ret;
153 print_tabs(fd, depth);
154 fprintf(fd, "</length>\n");
155 }
156 if (node->u.type_declarator.u.nested.abstract_array) {
157 print_tabs(fd, depth);
158 fprintf(fd, "<length>\n");
159 print_tabs(fd, depth);
160 fprintf(fd, "</length>\n");
161 }
162 if (node->u.type_declarator.bitfield_len) {
163 print_tabs(fd, depth);
164 fprintf(fd, "<bitfield_len>\n");
165 ret = ctf_visitor_print_xml(fd, depth + 1,
166 node->u.type_declarator.bitfield_len);
167 if (ret)
168 return ret;
169 print_tabs(fd, depth);
170 fprintf(fd, "</bitfield_len>\n");
171 }
172 break;
173 case TYPEDEC_UNKNOWN:
174 default:
175 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
176 (int) node->u.type_declarator.type);
177 return -EINVAL;
178 }
179
180 depth--;
181 print_tabs(fd, depth);
182 fprintf(fd, "</type_declarator>\n");
183 return 0;
184 }
185
186 /*
187 * String returned must be freed by the caller using g_free.
188 */
189 static
190 char *concatenate_unary_strings(struct list_head *head)
191 {
192 struct ctf_node *node;
193 GString *str;
194 int i = 0;
195
196 str = g_string_new();
197 cds_list_for_each_entry(node, head, siblings) {
198 char *src_string;
199
200 assert(node->type == NODE_UNARY_EXPRESSION);
201 assert(node->u.unary_expression.type == UNARY_STRING);
202 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
203 ^ (i != 0))
204 switch (node->u.unary_expression.link) {
205 case UNARY_DOTLINK:
206 g_string_append(str, ".")
207 break;
208 case UNARY_ARROWLINK:
209 g_string_append(str, "->")
210 break;
211 case UNARY_DOTDOTDOT:
212 g_string_append(str, "...")
213 break;
214 }
215 src_string = u.unary_expression.u.string;
216 g_string_append(str, src_string);
217 i++;
218 }
219 return g_string_free(str, FALSE);
220 }
221
222 static
223 int get_unary_unsigned(struct list_head *head, uint64_t *value)
224 {
225 struct ctf_node *node;
226 int i = 0;
227
228 cds_list_for_each_entry(node, head, siblings) {
229 assert(node->type == NODE_UNARY_EXPRESSION);
230 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
231 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
232 assert(i == 0);
233 *value = node->u.unary_expression.unsigned_constant
234 i++;
235 }
236 return 0;
237 }
238
239 static
240 int get_unary_uuid(struct list_head *head, uuid_t *uuid)
241 {
242 struct ctf_node *node;
243 int i = 0;
244 int ret = -1;
245
246 cds_list_for_each_entry(node, head, siblings) {
247 const char *src_string;
248
249 assert(node->type == NODE_UNARY_EXPRESSION);
250 assert(node->u.unary_expression.type == UNARY_STRING);
251 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
252 assert(i == 0);
253 src_string = u.unary_expression.u.string;
254 ret = uuid_parse(u.unary_expression.u.string, *uuid);
255 }
256 return ret;
257 }
258
259 static
260 struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
261 {
262 if (trace->streams->len <= stream_id)
263 return NULL;
264 return g_ptr_array_index(trace->streams, stream_id);
265 }
266
267 static
268 struct declaration *ctf_type_declarator_visit(int fd, int depth,
269 struct cds_list_head *declaration_specifier,
270 GQuark *field_name,
271 struct ctf_node *node_type_declarator,
272 struct declaration_scope *declaration_scope
273 struct declaration *nested_declaration)
274 {
275 /*
276 * Visit type declarator by first taking care of sequence/array
277 * (recursively). Then, when we get to the identifier, take care
278 * of pointers.
279 */
280
281 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
282 /* TODO: gcc bitfields not supported yet. */
283 assert(node_type_declarator->u.type_declarator.bitfield_len == NULL);
284
285 if (!nested_declaration) {
286 if (!cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
287 /*
288 * If we have a pointer declarator, it _has_ to be present in
289 * the typealiases (else fail).
290 */
291 nested_declaration = ... ;
292 } else {
293 nested_declaration = /* parse declaration_specifier */;
294 }
295
296 }
297
298 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
299 if (node_type_declarator->u.type_declarator.u.id)
300 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
301 else
302 *field_name = 0;
303 return nested_declaration;
304 } else {
305 struct declaration *declaration;
306 struct node *length;
307
308 /* TYPEDEC_NESTED */
309
310 /* create array/sequence, pass nested_declaration as child. */
311 length = node_type_declarator->u.type_declarator.u.nested.length;
312 if (length) {
313 switch (length->type) {
314 case NODE_UNARY_EXPRESSION:
315 /* Array */
316 declaration = /* create array */;
317 break;
318 case NODE_TYPE_SPECIFIER:
319 /* Sequence */
320 declaration = /* create sequence */;
321 break;
322 default:
323 assert(0);
324 }
325 }
326
327 /* Pass it as content of outer container */
328 declaration = ctf_type_declarator_visit(fd, depth,
329 declaration_specifier, field_name,
330 node_type_declarator->u.type_declarator.u.nested.type_declarator,
331 declaration_scope, declaration);
332 return declaration;
333 }
334 }
335
336 static
337 int ctf_struct_type_declarators_visit(int fd, int depth,
338 struct declaration_struct *struct_declaration,
339 struct cds_list_head *declaration_specifier,
340 struct cds_list_head *type_declarators,
341 struct declaration_scope *declaration_scope)
342 {
343 struct ctf_node *iter;
344 GQuark field_name;
345
346 cds_list_for_each_entry(iter, type_declarators, siblings) {
347 struct declaration *field_declaration;
348
349 field_declaration = ctf_type_declarator_visit(fd, depth,
350 declaration_specifier,
351 &field_name, iter,
352 struct_declaration->scope,
353 NULL);
354 struct_declaration_add_field(struct_declaration,
355 g_quark_to_string(field_name),
356 field_declaration);
357 }
358
359 return 0;
360 }
361
362 static
363 int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope,
364 struct cds_list_head *declaration_specifier,
365 struct cds_list_head *type_declarators)
366 {
367 struct ctf_node *iter;
368 GQuark identifier;
369
370 cds_list_for_each_entry(iter, type_declarators, siblings) {
371 struct declaration *type_declaration;
372 int ret;
373
374 type_declaration = ctf_type_declarator_visit(fd, depth,
375 declaration_specifier,
376 &identifier, iter,
377 scope, NULL);
378 ret = register_declaration(identifier, type_declaration, scope);
379 if (ret) {
380 type_declaration->declaration_free(type_declaration);
381 return ret;
382 }
383 }
384 return 0;
385 }
386
387 static
388 int ctf_typealias_visit(int fd, int depth, struct declaration_scope *scope,
389 struct ctf_node *target, struct ctf_node *alias)
390 {
391 struct declaration *type_declaration;
392 struct ctf_node *iter, *node;
393 GQuark identifier, dummy_id;
394 GString *str;
395 const char *str_c;
396 GQuark alias_q;
397 int alias_item_nr = 0;
398
399 /* See ctf_visitor_type_declarator() in the semantic validator. */
400
401 /*
402 * Create target type declaration.
403 */
404
405 type_declaration = ctf_type_declarator_visit(fd, depth,
406 &target->u.typealias_target.declaration_specifier,
407 &dummy_id, &target->u.typealias_target.type_declarators,
408 scope, NULL);
409 if (!type_declaration) {
410 fprintf(stderr, "[error] %s: problem creating type declaration\n", __func__);
411 err = -EINVAL;
412 goto error;
413 }
414 /*
415 * The semantic validator does not check whether the target is
416 * abstract or not (if it has an identifier). Check it here.
417 */
418 if (dummy_id != 0) {
419 fprintf(stderr, "[error] %s: expecting empty identifier\n", __func__);
420 err = -EINVAL;
421 goto error;
422 }
423 /*
424 * Create alias identifier.
425 */
426 str = g_string_new();
427 cds_list_for_each_entry(iter, &alias->u.typealias_alias.declaration_specifier, siblings) {
428 if (alias_item_nr != 0)
429 g_string_append(str, " ");
430 alias_item_nr++;
431
432 switch (iter->type) {
433 case NODE_TYPE_SPECIFIER:
434 switch (iter->u.type_specifier.type) {
435 case TYPESPEC_VOID:
436 g_string_append(str, "void");
437 break;
438 case TYPESPEC_CHAR:
439 g_string_append(str, "char");
440 break;
441 case TYPESPEC_SHORT:
442 g_string_append(str, "short");
443 break;
444 case TYPESPEC_INT:
445 g_string_append(str, "int");
446 break;
447 case TYPESPEC_LONG:
448 g_string_append(str, "long");
449 break;
450 case TYPESPEC_FLOAT:
451 g_string_append(str, "float");
452 break;
453 case TYPESPEC_DOUBLE:
454 g_string_append(str, "double");
455 break;
456 case TYPESPEC_SIGNED:
457 g_string_append(str, "signed");
458 break;
459 case TYPESPEC_UNSIGNED:
460 g_string_append(str, "unsigned");
461 break;
462 case TYPESPEC_BOOL:
463 g_string_append(str, "bool");
464 break;
465 case TYPESPEC_COMPLEX:
466 g_string_append(str, "_Complex");
467 break;
468 case TYPESPEC_IMAGINARY:
469 g_string_append(str, "_Imaginary");
470 break;
471 case TYPESPEC_CONST:
472 g_string_append(str, "const");
473 break;
474 case TYPESPEC_ID_TYPE:
475 if (!iter->u.type_specifier.id_type) {
476 fprintf(stderr, "[error] %s: unexpected empty ID\n", __func__);
477 err = -EINVAL;
478 goto error;
479 }
480 g_string_append(str, iter->u.type_specifier.id_type);
481 break;
482 default:
483 fprintf(stderr, "[error] %s: unknown specifier\n", __func__);
484 err = -EINVAL;
485 goto error;
486 }
487 break;
488 case NODE_ENUM:
489 if (!iter->u._enum.enum_id) {
490 fprintf(stderr, "[error] %s: unexpected empty enum ID\n", __func__);
491 err = -EINVAL;
492 goto error;
493 }
494 g_string_append(str, "enum ");
495 g_string_append(str, iter->u._enum.enum_id);
496 break;
497 case NODE_VARIANT:
498 if (!iter->u.variant.name) {
499 fprintf(stderr, "[error] %s: unexpected empty variant name\n", __func__);
500 err = -EINVAL;
501 goto error;
502 }
503 g_string_append(str, "variant ");
504 g_string_append(str, iter->u.variant.name);
505 break;
506 case NODE_STRUCT:
507 if (!iter->u._struct.name) {
508 fprintf(stderr, "[error] %s: unexpected empty variant name\n", __func__);
509 err = -EINVAL;
510 goto error;
511 }
512 g_string_append(str, "struct ");
513 g_string_append(str, iter->u._struct.name);
514 break;
515 default:
516 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
517 err = -EINVAL;
518 goto error;
519 }
520 }
521
522 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
523 struct node, siblings) {
524 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers, siblings) {
525 g_string_append(str, " *");
526 if (iter->u.pointer.const_qualifier)
527 g_string_append(str, " const");
528 }
529
530 }
531 str_c = g_string_free(str, FALSE);
532 alias_q = g_quark_from_string(str_c);
533 g_free(str_c);
534 ret = register_declaration(alias_q, type_declaration, scope);
535 if (ret)
536 goto error;
537 return 0;
538
539 error:
540 type_declaration->declaration_free(type_declaration);
541 return ret;
542 }
543
544 static
545 int ctf_struct_declaration_list_visit(int fd, int depth,
546 struct ctf_node *iter, struct declaration_struct *struct_declaration)
547 {
548 struct declaration *declaration;
549 int ret;
550
551 switch (iter->type) {
552 case NODE_TYPEDEF:
553 /* For each declarator, declare type and add type to struct declaration scope */
554 ret = ctf_typedef_visit(fd, depth,
555 struct_declaration->scope,
556 &iter->u._typedef.declaration_specifier,
557 &iter->u._typedef.type_declarators);
558 if (ret)
559 return ret;
560 break;
561 case NODE_TYPEALIAS:
562 /* Declare type with declarator and add type to struct declaration scope */
563 ret = ctf_typealias_visit(fd, depth,
564 struct_declaration->scope,
565 iter->u.typealias.target,
566 iter->u.typealias.alias);
567 if (ret)
568 return ret;
569 break;
570 case NODE_STRUCT_OR_VARIANT_DECLARATION:
571 /* Add field to structure declaration */
572 ret = ctf_struct_type_declarators_visit(fd, depth,
573 struct_declaration,
574 &iter->u.struct_or_variant_declaration.declaration_specifier,
575 &iter->u.struct_or_variant_declaration.type_declarators);
576 if (ret)
577 return ret;
578 break;
579 default:
580 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
581 assert(0);
582 }
583 return 0;
584 }
585
586 static
587 struct declaration_struct *ctf_declaration_struct_visit(FILE *fd,
588 int depth, const char *name, struct cds_list_head *declaration_list,
589 int has_body, struct declaration_scope *declaration_scope)
590 {
591 struct declaration *declaration;
592 struct declaration_struct *struct_declaration;
593 struct ctf_node *iter;
594
595 /*
596 * For named struct (without body), lookup in
597 * declaration scope. Don't take reference on struct
598 * declaration: ref is only taken upon definition.
599 */
600 if (!has_body) {
601 assert(name);
602 struct_declaration =
603 lookup_struct_declaration(g_quark_from_string(name),
604 declaration_scope);
605 return struct_declaration;
606 } else {
607 /* For unnamed struct, create type */
608 /* For named struct (with body), create type and add to declaration scope */
609 if (name) {
610 if (lookup_struct_declaration(g_quark_from_string(name),
611 declaration_scope)) {
612
613 fprintf(stderr, "[error] %s: struct %s already declared in scope\n", name);
614 return NULL;
615 }
616 }
617 struct_declaration = struct_declaration_new(name, declaration_scope);
618 cds_list_for_each_entry(iter, declaration_list, siblings) {
619 ret = ctf_struct_declaration_list_visit(fd,
620 depth + 1, iter, struct_declaration);
621 if (ret)
622 goto error;
623 }
624 if (name) {
625 ret = register_struct_declaration(g_quark_from_string(name),
626 struct_declaration,
627 declaration_scope);
628 assert(!ret);
629 }
630 return struct_declaration;
631 }
632 error:
633 struct_declaration->p.declaration_free(&struct_declaration->p);
634 return NULL;
635 }
636
637 /*
638 * Also add named variant, struct or enum to the current declaration scope.
639 */
640 static
641 struct declaration *ctf_declaration_specifier_visit(FILE *fd,
642 int depth, struct list_head *head,
643 struct declaration_scope *declaration_scope)
644 {
645 struct declaration *declaration;
646 struct node *first;
647
648 first = _cds_list_first_entry(head, struct node, siblings);
649
650 switch (first->type) {
651 case NODE_STRUCT:
652 return ctf_declaration_struct_visit(fd, depth,
653 first->u._struct.name,
654 &first->u._struct.declaration_list,
655 first->u._struct.has_body,
656 declaration_scope);
657 break;
658 case NODE_VARIANT:
659 /*
660 * For named variant (without body), lookup in
661 * declaration scope and create declaration copy.
662 */
663 /* For named variant (with body), create type and add to declaration scope */
664 /* For unnamed variant, create type */
665 /* If variant has a tag field specifier, assign tag name. */
666 break;
667 case NODE_ENUM:
668 /*
669 * For named enum (without body), lookup in declaration
670 * scope and create declaration copy.
671 */
672 /* For named enum (with body), create type and add to declaration scope */
673 /* For unnamed enum, create type */
674 /* Enumerations need to have their size/type specifier (< >). */
675 break;
676 case NODE_INTEGER:
677 /*
678 * Create an integer declaration.
679 */
680 break;
681 case NODE_FLOATING_POINT:
682 /*
683 * Create a floating point declaration.
684 */
685 break;
686 case NODE_STRING:
687 /*
688 * Create a string declaration.
689 */
690 break;
691 case NODE_TYPE_SPECIFIER:
692 /*
693 * Lookup named type in typedef declarations (in
694 * declaration scope). Create a copy of the declaration.
695 */
696 break;
697
698 }
699 }
700
701 static
702 int ctf_typedef_declarator_visit(FILE *fd, int depth,
703 struct list_head *declaration_specifier,
704 struct node *type_declarator,
705 struct declaration_scope *declaration_scope)
706 {
707 /*
708 * Build the type using declaration specifier (creating
709 * declaration from type_specifier), then apply type declarator,
710 * add the resulting type to the current declaration scope.
711 */
712 cds_list_for_each_entry(iter, declaration_specifier, siblings) {
713
714
715 }
716 return 0;
717 }
718
719 static
720 int ctf_typedef_visit(FILE *fd, int depth,
721 struct list_head *declaration_specifier,
722 struct list_head *type_declarators,
723 struct declaration_scope *declaration_scope)
724 {
725 struct ctf_node *iter;
726
727 cds_list_for_each_entry(iter, type_declarators, siblings) {
728 ret = ctf_typedef_declarator_visit(fd, depth + 1,
729 &node->u._typedef.declaration_specifier, iter,
730 declaration_scope);
731 if (ret)
732 return ret;
733 }
734 return 0;
735 }
736
737 static
738 int ctf_typealias_visit(FILE *fd, int depth, struct ctf_node *target,
739 struct ctf_node *alias,
740 struct declaration_scope *declaration_scope)
741 {
742 /*
743 * Build target type, check that it is reachable in current
744 * declaration scope.
745 */
746
747 /* Only one type declarator is allowed */
748
749 /* Build alias type, add to current declaration scope. */
750 /* Only one type declarator is allowed */
751 }
752
753 static
754 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
755 {
756 int ret = 0;
757
758 switch (node->type) {
759 case NODE_TYPEDEF:
760 ret = ctf_typedef_visit(fd, depth + 1,
761 &node->u._typedef.declaration_specifier,
762 &node->u._typedef.type_declarators,
763 event->declaration_scope);
764 if (ret)
765 return ret;
766 break;
767 case NODE_TYPEALIAS:
768 ret = ctf_typealias_visit(fd, depth + 1,
769 &node->u.typealias.target, &node->u.typealias.alias
770 event->declaration_scope);
771 if (ret)
772 return ret;
773 break;
774 case NODE_CTF_EXPRESSION:
775 {
776 char *left;
777
778 left = concatenate_unary_strings(&node->u.ctf_expression.left);
779 if (!strcmp(left, "name")) {
780 char *right;
781
782 if (CTF_EVENT_FIELD_IS_SET(event, name))
783 return -EPERM;
784 right = concatenate_unary_strings(&node->u.ctf_expression.right);
785 if (!right) {
786 fprintf(stderr, "[error] %s: unexpected unary expression for event name\n", __func__);
787 return -EINVAL;
788 }
789 event->name = g_quark_from_string(right);
790 g_free(right);
791 CTF_EVENT_SET_FIELD(event, name);
792 } else if (!strcmp(left, "id")) {
793 if (CTF_EVENT_FIELD_IS_SET(event, id))
794 return -EPERM;
795 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
796 if (ret) {
797 fprintf(stderr, "[error] %s: unexpected unary expression for event id\n", __func__);
798 return -EINVAL;
799 }
800 CTF_EVENT_SET_FIELD(event, id);
801 } else if (!strcmp(left, "stream_id")) {
802 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
803 return -EPERM;
804 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
805 if (ret) {
806 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
807 return -EINVAL;
808 }
809 event->stream = trace_stream_lookup(trace, event->stream_id);
810 if (!event->stream) {
811 fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
812 return -EINVAL;
813 }
814 CTF_EVENT_SET_FIELD(event, stream_id);
815 } else if (!strcmp(left, "context")) {
816 struct declaration *declaration;
817
818 if (!event->definition_scope)
819 return -EPERM;
820 declaration = ctf_declaration_specifier_visit(fd, depth,
821 &node->u.ctf_expression.right,
822 event->declaration_scope);
823 if (!declaration)
824 return -EPERM;
825 if (declaration->type->id != CTF_TYPE_STRUCT)
826 return -EPERM;
827 event->context_decl = container_of(declaration, struct declaration_struct, p);
828 } else if (!strcmp(left, "fields")) {
829 struct declaration *declaration;
830
831 if (!event->definition_scope)
832 return -EPERM;
833 declaration = ctf_declaration_specifier_visit(fd, depth,
834 &node->u.ctf_expression.right,
835 event->declaration_scope);
836 if (!declaration)
837 return -EPERM;
838 if (declaration->type->id != CTF_TYPE_STRUCT)
839 return -EPERM;
840 event->fields_decl = container_of(declaration, struct declaration_struct, p);
841 }
842 g_free(left);
843 break;
844 }
845 default:
846 return -EPERM;
847 /* TODO: declaration specifier should be added. */
848 }
849
850 return 0;
851 }
852
853 static
854 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
855 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
856 {
857 int ret = 0;
858 struct ctf_node *iter;
859 struct ctf_event *event;
860 struct definition_scope *parent_def_scope;
861
862 event = g_new0(struct ctf_event, 1);
863 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
864 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
865 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
866 if (ret)
867 goto error;
868 }
869 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
870 ret = -EPERM;
871 goto error;
872 }
873 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
874 ret = -EPERM;
875 goto error;
876 }
877 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
878 ret = -EPERM;
879 goto error;
880 }
881 if (event->stream->events_by_id->len <= event->id)
882 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
883 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
884 g_hash_table_insert(event->stream->event_quark_to_id,
885 (gpointer)(unsigned long) event->name,
886 &event->id);
887 parent_def_scope = stream->definition_scope;
888 if (event->context_decl) {
889 event->context =
890 event->context_decl->definition_new(event->context_decl,
891 parent_def_scope, 0, 0);
892 set_dynamic_definition_scope(&event->context->p,
893 event->context->scope,
894 "event.context");
895 parent_def_scope = event->context->scope;
896 declaration_unref(event->context_decl);
897 }
898 if (event->fields_decl) {
899 event->fields =
900 event->fields_decl->definition_new(event->fields_decl,
901 parent_def_scope, 0, 0);
902 set_dynamic_definition_scope(&event->fields->p,
903 event->fields->scope,
904 "event.fields");
905 parent_def_scope = event->fields->scope;
906 declaration_unref(event->fields_decl);
907 }
908 return 0;
909
910 error:
911 declaration_unref(event->fields_decl);
912 declaration_unref(event->context_decl);
913 free_definition_scope(event->definition_scope);
914 free_declaration_scope(event->declaration_scope);
915 g_free(event);
916 return ret;
917 }
918
919
920 static
921 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
922 {
923 int ret = 0;
924
925 switch (node->type) {
926 case NODE_TYPEDEF:
927 ret = ctf_typedef_visit(fd, depth + 1,
928 &node->u._typedef.declaration_specifier,
929 &node->u._typedef.type_declarators,
930 stream->declaration_scope);
931 if (ret)
932 return ret;
933 break;
934 case NODE_TYPEALIAS:
935 ret = ctf_typealias_visit(fd, depth + 1,
936 &node->u.typealias.target, &node->u.typealias.alias
937 stream->declaration_scope);
938 if (ret)
939 return ret;
940 break;
941 case NODE_CTF_EXPRESSION:
942 {
943 char *left;
944
945 left = concatenate_unary_strings(&node->u.ctf_expression.left);
946 if (!strcmp(left, "stream_id")) {
947 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
948 return -EPERM;
949 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
950 if (ret) {
951 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
952 return -EINVAL;
953 }
954 CTF_EVENT_SET_FIELD(event, stream_id);
955 } else if (!strcmp(left, "event.header")) {
956 struct declaration *declaration;
957
958 declaration = ctf_declaration_specifier_visit(fd, depth,
959 &node->u.ctf_expression.right,
960 stream->declaration_scope, stream->definition_scope);
961 if (!declaration)
962 return -EPERM;
963 if (declaration->type->id != CTF_TYPE_STRUCT)
964 return -EPERM;
965 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
966 } else if (!strcmp(left, "event.context")) {
967 struct declaration *declaration;
968
969 declaration = ctf_declaration_specifier_visit(fd, depth,
970 &node->u.ctf_expression.right,
971 stream->declaration_scope);
972 if (!declaration)
973 return -EPERM;
974 if (declaration->type->id != CTF_TYPE_STRUCT)
975 return -EPERM;
976 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
977 } else if (!strcmp(left, "packet.context")) {
978 struct declaration *declaration;
979
980 declaration = ctf_declaration_specifier_visit(fd, depth,
981 &node->u.ctf_expression.right,
982 stream->declaration_scope);
983 if (!declaration)
984 return -EPERM;
985 if (declaration->type->id != CTF_TYPE_STRUCT)
986 return -EPERM;
987 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
988 }
989 g_free(left);
990 break;
991 }
992 default:
993 return -EPERM;
994 /* TODO: declaration specifier should be added. */
995 }
996
997 return 0;
998 }
999
1000 static
1001 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1002 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1003 {
1004 int ret = 0;
1005 struct ctf_node *iter;
1006 struct ctf_stream *stream;
1007 struct definition_scope *parent_def_scope;
1008
1009 stream = g_new0(struct ctf_stream, 1);
1010 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1011 stream->events_by_id = g_ptr_array_new();
1012 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
1013 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1014 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1015 if (ret)
1016 goto error;
1017 }
1018 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
1019 ret = -EPERM;
1020 goto error;
1021 }
1022 if (trace->streams->len <= stream->stream_id)
1023 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1024 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
1025
1026 parent_def_scope = NULL;
1027 if (stream->packet_context_decl) {
1028 stream->packet_context =
1029 stream->packet_context_decl->definition_new(stream->packet_context_decl,
1030 parent_def_scope, 0, 0);
1031 set_dynamic_definition_scope(&stream->packet_context->p,
1032 stream->packet_context->scope,
1033 "stream.packet.context");
1034 parent_def_scope = stream->packet_context->scope;
1035 declaration_unref(stream->packet_context_decl);
1036 }
1037 if (stream->event_header_decl) {
1038 stream->event_header =
1039 stream->event_header_decl->definition_new(stream->event_header_decl,
1040 parent_def_scope, 0, 0);
1041 set_dynamic_definition_scope(&stream->event_header->p,
1042 stream->event_header->scope,
1043 "stream.event.header");
1044 parent_def_scope = stream->event_header->scope;
1045 declaration_unref(stream->event_header_decl);
1046 }
1047 if (stream->event_context_decl) {
1048 stream->event_context =
1049 stream->event_context_decl->definition_new(stream->event_context_decl,
1050 parent_def_scope, 0, 0);
1051 set_dynamic_definition_scope(&stream->event_context->p,
1052 stream->event_context->scope,
1053 "stream.event.context");
1054 parent_def_scope = stream->event_context->scope;
1055 declaration_unref(stream->event_context_decl);
1056 }
1057 stream->definition_scope = parent_def_scope;
1058
1059 return 0;
1060
1061 error:
1062 declaration_unref(stream->event_header);
1063 declaration_unref(stream->event_context);
1064 declaration_unref(stream->packet_context);
1065 g_ptr_array_free(stream->events_by_id, TRUE);
1066 g_hash_table_free(stream->event_quark_to_id);
1067 free_definition_scope(stream->definition_scope);
1068 free_declaration_scope(stream->declaration_scope);
1069 g_free(stream);
1070 return ret;
1071 }
1072
1073 static
1074 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1075 {
1076 int ret = 0;
1077
1078 switch (node->type) {
1079 case NODE_TYPEDEF:
1080 ret = ctf_typedef_visit(fd, depth + 1,
1081 &node->u._typedef.declaration_specifier,
1082 &node->u._typedef.type_declarators,
1083 trace->declaration_scope);
1084 if (ret)
1085 return ret;
1086 break;
1087 case NODE_TYPEALIAS:
1088 ret = ctf_typealias_visit(fd, depth + 1,
1089 &node->u.typealias.target, &node->u.typealias.alias
1090 trace->declaration_scope);
1091 if (ret)
1092 return ret;
1093 break;
1094 case NODE_CTF_EXPRESSION:
1095 {
1096 char *left;
1097
1098 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1099 if (!strcmp(left, "major")) {
1100 if (CTF_EVENT_FIELD_IS_SET(trace, major))
1101 return -EPERM;
1102 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1103 if (ret) {
1104 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
1105 return -EINVAL;
1106 }
1107 CTF_EVENT_SET_FIELD(trace, major);
1108 } else if (!strcmp(left, "minor")) {
1109 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
1110 return -EPERM;
1111 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1112 if (ret) {
1113 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
1114 return -EINVAL;
1115 }
1116 CTF_EVENT_SET_FIELD(trace, minor);
1117 } else if (!strcmp(left, "word_size")) {
1118 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
1119 return -EPERM;
1120 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
1121 if (ret) {
1122 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
1123 return -EINVAL;
1124 }
1125 CTF_EVENT_SET_FIELD(trace, word_size);
1126 } else if (!strcmp(left, "uuid")) {
1127 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
1128 return -EPERM;
1129 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1130 if (ret) {
1131 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
1132 return -EINVAL;
1133 }
1134 CTF_EVENT_SET_FIELD(trace, uuid);
1135 }
1136 g_free(left);
1137 break;
1138 }
1139 default:
1140 return -EPERM;
1141 /* TODO: declaration specifier should be added. */
1142 }
1143
1144 return 0;
1145 }
1146
1147
1148 static
1149 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1150 {
1151 int ret = 0;
1152 struct ctf_node *iter;
1153
1154 if (trace->declaration_scope)
1155 return -EEXIST;
1156 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
1157 trace->definition_scope = new_dynamic_definition_scope(trace->root_definition_scope);
1158 trace->streams = g_ptr_array_new();
1159 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1160 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1161 if (ret)
1162 goto error;
1163 }
1164 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
1165 ret = -EPERM;
1166 goto error;
1167 }
1168 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
1169 ret = -EPERM;
1170 goto error;
1171 }
1172 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
1173 ret = -EPERM;
1174 goto error;
1175 }
1176 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
1177 ret = -EPERM;
1178 goto error;
1179 }
1180 return 0;
1181
1182 error:
1183 g_ptr_array_free(trace->streams, TRUE);
1184 free_definition_scope(stream->definition_scope);
1185 free_declaration_scope(stream->declaration_scope);
1186 return ret;
1187 }
1188
1189 int _ctf_visitor(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1190 {
1191 int ret = 0;
1192 struct ctf_node *iter;
1193
1194 switch (node->type) {
1195 case NODE_ROOT:
1196 cds_list_for_each_entry(iter, &node->u.root._typedef,
1197 siblings) {
1198 ret = ctf_typedef_visit(fd, depth + 1,
1199 &iter->u._typedef.declaration_specifier,
1200 &iter->u._typedef.type_declarators,
1201 trace->root_declaration_scope);
1202 if (ret)
1203 return ret;
1204 }
1205 cds_list_for_each_entry(iter, &node->u.root.typealias,
1206 siblings) {
1207 ret = ctf_typealias_visit(fd, depth + 1,
1208 &iter->u.typealias.target, &iter->u.typealias.alias
1209 trace->root_declaration_scope);
1210 if (ret)
1211 return ret;
1212 }
1213 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
1214 ret = ctf_declaration_specifier_visit(fd, depth, iter,
1215 trace->root_declaration_scope);
1216 if (ret)
1217 return ret;
1218 }
1219 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
1220 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
1221 if (ret)
1222 return ret;
1223 }
1224 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
1225 ret = ctf_stream_visit(fd, depth + 1, iter,
1226 trace->root_declaration_scope, trace);
1227 if (ret)
1228 return ret;
1229 }
1230 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
1231 ret = ctf_event_visit(fd, depth + 1, iter,
1232 trace->root_declaration_scope, trace);
1233 if (ret)
1234 return ret;
1235 }
1236 break;
1237
1238 case NODE_TYPEALIAS_TARGET:
1239 print_tabs(fd, depth);
1240 fprintf(fd, "<target>\n");
1241 depth++;
1242
1243 print_tabs(fd, depth);
1244 fprintf(fd, "<declaration_specifier>\n");
1245 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
1246 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1247 if (ret)
1248 return ret;
1249 }
1250 print_tabs(fd, depth);
1251 fprintf(fd, "</declaration_specifier>\n");
1252
1253 print_tabs(fd, depth);
1254 fprintf(fd, "<type_declarators>\n");
1255 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
1256 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1257 if (ret)
1258 return ret;
1259 }
1260 print_tabs(fd, depth);
1261 fprintf(fd, "</type_declarators>\n");
1262
1263 depth--;
1264 print_tabs(fd, depth);
1265 fprintf(fd, "</target>\n");
1266 break;
1267 case NODE_TYPEALIAS_ALIAS:
1268 print_tabs(fd, depth);
1269 fprintf(fd, "<alias>\n");
1270 depth++;
1271
1272 print_tabs(fd, depth);
1273 fprintf(fd, "<declaration_specifier>\n");
1274 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
1275 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1276 if (ret)
1277 return ret;
1278 }
1279 print_tabs(fd, depth);
1280 fprintf(fd, "</declaration_specifier>\n");
1281
1282 print_tabs(fd, depth);
1283 fprintf(fd, "<type_declarators>\n");
1284 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
1285 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1286 if (ret)
1287 return ret;
1288 }
1289 print_tabs(fd, depth);
1290 fprintf(fd, "</type_declarators>\n");
1291
1292 depth--;
1293 print_tabs(fd, depth);
1294 fprintf(fd, "</alias>\n");
1295 break;
1296 case NODE_TYPEALIAS:
1297 print_tabs(fd, depth);
1298 fprintf(fd, "<typealias>\n");
1299 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
1300 if (ret)
1301 return ret;
1302 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
1303 if (ret)
1304 return ret;
1305 print_tabs(fd, depth);
1306 fprintf(fd, "</typealias>\n");
1307 break;
1308
1309 case NODE_TYPE_SPECIFIER:
1310 ret = ctf_visitor_print_type_specifier(fd, depth, node);
1311 if (ret)
1312 return ret;
1313 break;
1314 case NODE_POINTER:
1315 print_tabs(fd, depth);
1316 if (node->u.pointer.const_qualifier)
1317 fprintf(fd, "<const_pointer />\n");
1318 else
1319 fprintf(fd, "<pointer />\n");
1320 break;
1321 case NODE_TYPE_DECLARATOR:
1322 ret = ctf_visitor_print_type_declarator(fd, depth, node);
1323 if (ret)
1324 return ret;
1325 break;
1326
1327 case NODE_FLOATING_POINT:
1328 print_tabs(fd, depth);
1329 fprintf(fd, "<floating_point>\n");
1330 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
1331 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1332 if (ret)
1333 return ret;
1334 }
1335 print_tabs(fd, depth);
1336 fprintf(fd, "</floating_point>\n");
1337 break;
1338 case NODE_INTEGER:
1339 print_tabs(fd, depth);
1340 fprintf(fd, "<integer>\n");
1341 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
1342 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1343 if (ret)
1344 return ret;
1345 }
1346 print_tabs(fd, depth);
1347 fprintf(fd, "</integer>\n");
1348 break;
1349 case NODE_STRING:
1350 print_tabs(fd, depth);
1351 fprintf(fd, "<string>\n");
1352 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
1353 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1354 if (ret)
1355 return ret;
1356 }
1357 print_tabs(fd, depth);
1358 fprintf(fd, "</string>\n");
1359 break;
1360 case NODE_ENUMERATOR:
1361 print_tabs(fd, depth);
1362 fprintf(fd, "<enumerator");
1363 if (node->u.enumerator.id)
1364 fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
1365 fprintf(fd, ">\n");
1366 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
1367 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1368 if (ret)
1369 return ret;
1370 }
1371 print_tabs(fd, depth);
1372 fprintf(fd, "</enumerator>\n");
1373 break;
1374 case NODE_ENUM:
1375 print_tabs(fd, depth);
1376 if (node->u._struct.name)
1377 fprintf(fd, "<enum name=\"%s\">\n",
1378 node->u._enum.enum_id);
1379 else
1380 fprintf(fd, "<enum >\n");
1381 depth++;
1382
1383 if (node->u._enum.container_type) {
1384 print_tabs(fd, depth);
1385 fprintf(fd, "<container_type>\n");
1386 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
1387 if (ret)
1388 return ret;
1389 print_tabs(fd, depth);
1390 fprintf(fd, "</container_type>\n");
1391 }
1392
1393 print_tabs(fd, depth);
1394 fprintf(fd, "<enumerator_list>\n");
1395 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
1396 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1397 if (ret)
1398 return ret;
1399 }
1400 print_tabs(fd, depth);
1401 fprintf(fd, "</enumerator_list>\n");
1402
1403 depth--;
1404 print_tabs(fd, depth);
1405 fprintf(fd, "</enum>\n");
1406 break;
1407 case NODE_STRUCT_OR_VARIANT_DECLARATION:
1408 print_tabs(fd, depth);
1409 fprintf(fd, "<declaration_specifier>\n");
1410 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
1411 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1412 if (ret)
1413 return ret;
1414 }
1415 print_tabs(fd, depth);
1416 fprintf(fd, "</declaration_specifier>\n");
1417
1418 print_tabs(fd, depth);
1419 fprintf(fd, "<type_declarators>\n");
1420 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
1421 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1422 if (ret)
1423 return ret;
1424 }
1425 print_tabs(fd, depth);
1426 fprintf(fd, "</type_declarators>\n");
1427 break;
1428 case NODE_VARIANT:
1429 print_tabs(fd, depth);
1430 fprintf(fd, "<variant");
1431 if (node->u.variant.name)
1432 fprintf(fd, " name=\"%s\"", node->u.variant.name);
1433 if (node->u.variant.choice)
1434 fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
1435 fprintf(fd, ">\n");
1436 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
1437 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1438 if (ret)
1439 return ret;
1440 }
1441 print_tabs(fd, depth);
1442 fprintf(fd, "</variant>\n");
1443 break;
1444 case NODE_STRUCT:
1445 print_tabs(fd, depth);
1446 if (node->u._struct.name)
1447 fprintf(fd, "<struct name=\"%s\">\n",
1448 node->u._struct.name);
1449 else
1450 fprintf(fd, "<struct>\n");
1451 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
1452 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1453 if (ret)
1454 return ret;
1455 }
1456 print_tabs(fd, depth);
1457 fprintf(fd, "</struct>\n");
1458 break;
1459
1460 case NODE_UNKNOWN:
1461 default:
1462 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
1463 (int) node->type);
1464 return -EINVAL;
1465 }
1466 return ret;
1467 }
This page took 0.067657 seconds and 5 git commands to generate.