2 * ctf-visitor-generate-io-struct.c
4 * Common Trace Format Metadata Visitor (generate I/O structures).
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
27 #include <babeltrace/list.h>
28 #include "ctf-scanner.h"
29 #include "ctf-parser.h"
32 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
34 #define _cds_list_first_entry(ptr, type, member) \
35 cds_list_entry((ptr)->next, type, member)
38 int ctf_visitor_print_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
40 print_tabs(fd
, depth
);
41 fprintf(fd
, "<type_specifier \"");
43 switch (node
->u
.type_specifier
.type
) {
63 fprintf(fd
, "double");
66 fprintf(fd
, "signed");
68 case TYPESPEC_UNSIGNED
:
69 fprintf(fd
, "unsigned");
74 case TYPESPEC_COMPLEX
:
75 fprintf(fd
, "_Complex");
77 case TYPESPEC_IMAGINARY
:
78 fprintf(fd
, "_Imaginary");
83 case TYPESPEC_ID_TYPE
:
84 fprintf(fd
, "%s", node
->u
.type_specifier
.id_type
);
87 case TYPESPEC_UNKNOWN
:
89 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
90 (int) node
->u
.type_specifier
.type
);
93 fprintf(fd
, "\"/>\n");
98 int ctf_visitor_print_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
101 struct ctf_node
*iter
;
103 print_tabs(fd
, depth
);
104 fprintf(fd
, "<type_declarator>\n");
107 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
108 print_tabs(fd
, depth
);
109 fprintf(fd
, "<pointers>\n");
110 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
112 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
116 print_tabs(fd
, depth
);
117 fprintf(fd
, "</pointers>\n");
120 switch (node
->u
.type_declarator
.type
) {
122 if (node
->u
.type_declarator
.u
.id
) {
123 print_tabs(fd
, depth
);
124 fprintf(fd
, "<id \"");
125 fprintf(fd
, "%s", node
->u
.type_declarator
.u
.id
);
126 fprintf(fd
, "\" />\n");
130 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
131 print_tabs(fd
, depth
);
132 fprintf(fd
, "<type_declarator>\n");
133 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
134 node
->u
.type_declarator
.u
.nested
.type_declarator
);
137 print_tabs(fd
, depth
);
138 fprintf(fd
, "</type_declarator>\n");
140 if (node
->u
.type_declarator
.u
.nested
.length
) {
141 print_tabs(fd
, depth
);
142 fprintf(fd
, "<length>\n");
143 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
144 node
->u
.type_declarator
.u
.nested
.length
);
147 print_tabs(fd
, depth
);
148 fprintf(fd
, "</length>\n");
150 if (node
->u
.type_declarator
.u
.nested
.abstract_array
) {
151 print_tabs(fd
, depth
);
152 fprintf(fd
, "<length>\n");
153 print_tabs(fd
, depth
);
154 fprintf(fd
, "</length>\n");
156 if (node
->u
.type_declarator
.bitfield_len
) {
157 print_tabs(fd
, depth
);
158 fprintf(fd
, "<bitfield_len>\n");
159 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
160 node
->u
.type_declarator
.bitfield_len
);
163 print_tabs(fd
, depth
);
164 fprintf(fd
, "</bitfield_len>\n");
167 case TYPEDEC_UNKNOWN
:
169 fprintf(stderr
, "[error] %s: unknown type declarator %d\n", __func__
,
170 (int) node
->u
.type_declarator
.type
);
175 print_tabs(fd
, depth
);
176 fprintf(fd
, "</type_declarator>\n");
181 * String returned must be freed by the caller.
184 char *concatenate_unary_strings(struct list_head
*head
)
190 int get_unary_unsigned(struct list_head
*head
, uint64_t *value
)
196 int get_unary_uuid(struct list_head
*head
, uuid_t
*uuid
)
202 struct ctf_stream
*trace_stream_lookup(struct ctf_trace
*trace
, uint64_t stream_id
)
204 if (trace
->streams
->len
<= stream_id
)
206 return g_ptr_array_index(trace
->streams
, stream_id
);
210 * Also add named variant, struct or enum to the current declaration scope.
213 struct ctf_declaration
*ctf_declaration_specifier_visit(FILE *fd
,
214 int depth
, struct list_head
*head
,
215 struct declaration_scope
*declaration_scope
)
217 struct ctf_declaration
*declaration
;
220 first
= _cds_list_first_entry(head
, struct node
, siblings
);
222 switch (first
->type
) {
225 * For named struct (without body), lookup in
226 * declaration scope and create declaration copy.
228 /* For named struct (with body), create type and add to declaration scope */
229 /* For unnamed struct, create type */
233 * For named variant (without body), lookup in
234 * declaration scope and create declaration copy.
236 /* For named variant (with body), create type and add to declaration scope */
237 /* For unnamed variant, create type */
238 /* If variant has a tag field specifier, assign tag name. */
242 * For named enum (without body), lookup in declaration
243 * scope and create declaration copy.
245 /* For named enum (with body), create type and add to declaration scope */
246 /* For unnamed enum, create type */
247 /* Enumerations need to have their size/type specifier (< >). */
251 * Create an integer declaration.
254 case NODE_FLOATING_POINT
:
256 * Create a floating point declaration.
261 * Create a string declaration.
264 case NODE_TYPE_SPECIFIER
:
266 * Lookup named type in typedef declarations (in
267 * declaration scope). Create a copy of the declaration.
275 int ctf_typedef_declarator_visit(FILE *fd
, int depth
,
276 struct list_head
*declaration_specifier
,
277 struct node
*type_declarator
,
278 struct declaration_scope
*declaration_scope
)
281 * Build the type using declaration specifier (creating
282 * declaration from type_specifier), then apply type declarator,
283 * add the resulting type to the current declaration scope.
285 cds_list_for_each_entry(iter
, declaration_specifier
, siblings
) {
293 int ctf_typedef_visit(FILE *fd
, int depth
,
294 struct list_head
*declaration_specifier
,
295 struct list_head
*type_declarators
,
296 struct declaration_scope
*declaration_scope
)
298 struct ctf_node
*iter
;
300 cds_list_for_each_entry(iter
, type_declarators
, siblings
) {
301 ret
= ctf_typedef_declarator_visit(fd
, depth
+ 1,
302 &node
->u
._typedef
.declaration_specifier
, iter
,
311 int ctf_typealias_visit(FILE *fd
, int depth
, struct ctf_node
*target
,
312 struct ctf_node
*alias
,
313 struct declaration_scope
*declaration_scope
)
316 * Build target type, check that it is reachable in current
320 /* Only one type declarator is allowed */
322 /* Build alias type, add to current declaration scope. */
323 /* Only one type declarator is allowed */
327 int ctf_event_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_event
*event
, struct ctf_trace
*trace
)
331 switch (node
->type
) {
333 ret
= ctf_typedef_visit(fd
, depth
+ 1,
334 &node
->u
._typedef
.declaration_specifier
,
335 &node
->u
._typedef
.type_declarators
,
336 event
->declaration_scope
);
341 ret
= ctf_typealias_visit(fd
, depth
+ 1,
342 &node
->u
.typealias
.target
, &node
->u
.typealias
.alias
343 event
->declaration_scope
);
347 case NODE_CTF_EXPRESSION
:
351 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
352 if (!strcmp(left
, "name")) {
355 if (CTF_EVENT_FIELD_IS_SET(event
, name
))
357 right
= concatenate_unary_strings(&node
->u
.ctf_expression
.right
);
359 fprintf(stderr
, "[error] %s: unexpected unary expression for event name\n", __func__
);
362 event
->name
= g_quark_from_string(right
);
364 CTF_EVENT_SET_FIELD(event
, name
);
365 } else if (!strcmp(left
, "id")) {
366 if (CTF_EVENT_FIELD_IS_SET(event
, id
))
368 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->id
);
370 fprintf(stderr
, "[error] %s: unexpected unary expression for event id\n", __func__
);
373 CTF_EVENT_SET_FIELD(event
, id
);
374 } else if (!strcmp(left
, "stream_id")) {
375 if (CTF_EVENT_FIELD_IS_SET(event
, stream_id
))
377 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->stream_id
);
379 fprintf(stderr
, "[error] %s: unexpected unary expression for event stream_id\n", __func__
);
382 event
->stream
= trace_stream_lookup(trace
, event
->stream_id
);
383 if (!event
->stream
) {
384 fprintf(stderr
, "[error] %s: stream id %" PRIu64
" cannot be found\n", __func__
, event
->stream_id
);
387 event
->definition_scope
= new_dynamic_definition_scope(stream
->definition_scope
);
388 if (!event
->definition_scope
) {
389 fprintf(stderr
, "[error] %s: Error allocating declaration scope\n", __func__
);
392 CTF_EVENT_SET_FIELD(event
, stream_id
);
393 } else if (!strcmp(left
, "context")) {
394 struct declaration
*declaration
;
396 if (!event
->definition_scope
)
398 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
399 &node
->u
.ctf_expression
.right
,
400 event
->declaration_scope
);
403 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
405 event
->context_decl
= container_of(declaration
, struct declaration_struct
, p
);
406 } else if (!strcmp(left
, "fields")) {
407 struct declaration
*declaration
;
409 if (!event
->definition_scope
)
411 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
412 &node
->u
.ctf_expression
.right
,
413 event
->declaration_scope
);
416 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
418 event
->fields_decl
= container_of(declaration
, struct declaration_struct
, p
);
425 /* TODO: declaration specifier should be added. */
432 int ctf_event_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
433 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
436 struct ctf_node
*iter
;
437 struct ctf_event
*event
;
438 struct definition_scope
*parent_def_scope
;
440 event
= g_new0(struct ctf_event
, 1);
441 event
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
442 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
443 ret
= ctf_event_declaration_visit(fd
, depth
+ 1, iter
, event
, trace
);
447 if (!CTF_EVENT_FIELD_IS_SET(event
, name
)) {
451 if (!CTF_EVENT_FIELD_IS_SET(event
, id
)) {
455 if (!CTF_EVENT_FIELD_IS_SET(event
, stream_id
)) {
459 if (event
->stream
->events_by_id
->len
<= event
->id
)
460 g_ptr_array_set_size(event
->stream
->events_by_id
, event
->id
+ 1);
461 g_ptr_array_index(event
->stream
->events_by_id
, event
->id
) = event
;
462 g_hash_table_insert(event
->stream
->event_quark_to_id
,
463 (gpointer
)(unsigned long) event
->name
,
465 parent_def_scope
= event
->definition_scope
;
466 if (event
->context_decl
) {
468 event
->context_decl
->definition_new(event
->context_decl
,
470 g_quark_from_string("event.context"),
472 parent_def_scope
= event
->context
->scope
;
473 declaration_unref(event
->context_decl
);
475 if (event
->fields_decl
) {
477 event
->fields_decl
->definition_new(event
->fields_decl
,
479 g_quark_from_string("event.fields"),
481 parent_def_scope
= event
->fields
->scope
;
482 declaration_unref(event
->fields_decl
);
487 declaration_unref(event
->fields_decl
);
488 declaration_unref(event
->context_decl
);
489 free_definition_scope(event
->definition_scope
);
490 free_declaration_scope(event
->declaration_scope
);
497 int ctf_stream_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_stream
*stream
, struct ctf_trace
*trace
)
501 switch (node
->type
) {
503 ret
= ctf_typedef_visit(fd
, depth
+ 1,
504 &node
->u
._typedef
.declaration_specifier
,
505 &node
->u
._typedef
.type_declarators
,
506 stream
->declaration_scope
);
511 ret
= ctf_typealias_visit(fd
, depth
+ 1,
512 &node
->u
.typealias
.target
, &node
->u
.typealias
.alias
513 stream
->declaration_scope
);
517 case NODE_CTF_EXPRESSION
:
521 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
522 if (!strcmp(left
, "stream_id")) {
523 if (CTF_EVENT_FIELD_IS_SET(event
, stream_id
))
525 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->stream_id
);
527 fprintf(stderr
, "[error] %s: unexpected unary expression for event stream_id\n", __func__
);
530 CTF_EVENT_SET_FIELD(event
, stream_id
);
531 } else if (!strcmp(left
, "event.header")) {
532 struct declaration
*declaration
;
534 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
535 &node
->u
.ctf_expression
.right
,
536 stream
->declaration_scope
, stream
->definition_scope
);
539 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
541 stream
->event_header_decl
= container_of(declaration
, struct declaration_struct
, p
);
542 } else if (!strcmp(left
, "event.context")) {
543 struct declaration
*declaration
;
545 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
546 &node
->u
.ctf_expression
.right
,
547 stream
->declaration_scope
);
550 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
552 stream
->event_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
553 } else if (!strcmp(left
, "packet.context")) {
554 struct declaration
*declaration
;
556 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
557 &node
->u
.ctf_expression
.right
,
558 stream
->declaration_scope
);
561 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
563 stream
->packet_context_decl
= container_of(declaration
, struct declaration_struct
, p
);
570 /* TODO: declaration specifier should be added. */
577 int ctf_stream_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
578 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
581 struct ctf_node
*iter
;
582 struct ctf_stream
*stream
;
583 struct definition_scope
*parent_def_scope
;
585 stream
= g_new0(struct ctf_stream
, 1);
586 stream
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
587 stream
->definition_scope
= new_dynamic_definition_scope(trace
->definition_scope
);
588 stream
->events_by_id
= g_ptr_array_new();
589 stream
->event_quark_to_id
= g_hash_table_new(g_int_hash
, g_int_equal
);
590 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
591 ret
= ctf_stream_declaration_visit(fd
, depth
+ 1, iter
, stream
, trace
);
595 if (!CTF_EVENT_FIELD_IS_SET(stream
, stream_id
)) {
599 if (trace
->streams
->len
<= stream
->stream_id
)
600 g_ptr_array_set_size(trace
->streams
, stream
->stream_id
+ 1);
601 g_ptr_array_index(trace
->streams
, stream
->stream_id
) = stream
;
603 parent_def_scope
= stream
->definition_scope
;
604 if (stream
->packet_context_decl
) {
605 stream
->packet_context
=
606 stream
->packet_context_decl
->definition_new(stream
->packet_context_decl
,
608 g_quark_from_string("stream.packet.context"),
610 parent_def_scope
= stream
->packet_context
->scope
;
611 declaration_unref(stream
->packet_context_decl
);
613 if (stream
->event_header_decl
) {
614 stream
->event_header
=
615 stream
->event_header_decl
->definition_new(stream
->event_header_decl
,
617 g_quark_from_string("stream.event.header"),
619 parent_def_scope
= stream
->event_header
->scope
;
620 declaration_unref(stream
->event_header_decl
);
622 if (stream
->event_context_decl
) {
623 stream
->event_context
=
624 stream
->event_context_decl
->definition_new(stream
->event_context_decl
,
626 g_quark_from_string("stream.event.context"),
628 parent_def_scope
= stream
->event_context
->scope
;
629 declaration_unref(stream
->event_context_decl
);
635 declaration_unref(stream
->event_header
);
636 declaration_unref(stream
->event_context
);
637 declaration_unref(stream
->packet_context
);
638 g_ptr_array_free(stream
->events_by_id
, TRUE
);
639 g_hash_table_free(stream
->event_quark_to_id
);
640 free_definition_scope(stream
->definition_scope
);
641 free_declaration_scope(stream
->declaration_scope
);
647 int ctf_trace_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
651 switch (node
->type
) {
653 ret
= ctf_typedef_visit(fd
, depth
+ 1,
654 &node
->u
._typedef
.declaration_specifier
,
655 &node
->u
._typedef
.type_declarators
,
656 trace
->declaration_scope
);
661 ret
= ctf_typealias_visit(fd
, depth
+ 1,
662 &node
->u
.typealias
.target
, &node
->u
.typealias
.alias
663 trace
->declaration_scope
);
667 case NODE_CTF_EXPRESSION
:
671 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
672 if (!strcmp(left
, "major")) {
673 if (CTF_EVENT_FIELD_IS_SET(trace
, major
))
675 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->major
);
677 fprintf(stderr
, "[error] %s: unexpected unary expression for trace major number\n", __func__
);
680 CTF_EVENT_SET_FIELD(trace
, major
);
681 } else if (!strcmp(left
, "minor")) {
682 if (CTF_EVENT_FIELD_IS_SET(trace
, minor
))
684 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->minor
);
686 fprintf(stderr
, "[error] %s: unexpected unary expression for trace minor number\n", __func__
);
689 CTF_EVENT_SET_FIELD(trace
, minor
);
690 } else if (!strcmp(left
, "word_size")) {
691 if (CTF_EVENT_FIELD_IS_SET(trace
, word_size
))
693 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->word_size
);
695 fprintf(stderr
, "[error] %s: unexpected unary expression for trace word_size\n", __func__
);
698 CTF_EVENT_SET_FIELD(trace
, word_size
);
699 } else if (!strcmp(left
, "uuid")) {
700 if (CTF_EVENT_FIELD_IS_SET(trace
, uuid
))
702 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
, &trace
->uuid
);
704 fprintf(stderr
, "[error] %s: unexpected unary expression for trace uuid\n", __func__
);
707 CTF_EVENT_SET_FIELD(trace
, uuid
);
714 /* TODO: declaration specifier should be added. */
722 int ctf_trace_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
725 struct ctf_node
*iter
;
727 if (trace
->declaration_scope
)
729 trace
->declaration_scope
= new_declaration_scope(trace
->root_declaration_scope
);
730 trace
->definition_scope
= new_dynamic_definition_scope(trace
->root_definition_scope
);
731 trace
->streams
= g_ptr_array_new();
732 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
733 ret
= ctf_trace_declaration_visit(fd
, depth
+ 1, iter
, trace
);
737 if (!CTF_EVENT_FIELD_IS_SET(trace
, major
)) {
741 if (!CTF_EVENT_FIELD_IS_SET(trace
, minor
)) {
745 if (!CTF_EVENT_FIELD_IS_SET(trace
, uuid
)) {
749 if (!CTF_EVENT_FIELD_IS_SET(trace
, word_size
)) {
756 g_ptr_array_free(trace
->streams
, TRUE
);
757 free_definition_scope(stream
->definition_scope
);
758 free_declaration_scope(stream
->declaration_scope
);
762 int _ctf_visitor(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
765 struct ctf_node
*iter
;
767 switch (node
->type
) {
769 cds_list_for_each_entry(iter
, &node
->u
.root
._typedef
,
771 ret
= ctf_typedef_visit(fd
, depth
+ 1,
772 &iter
->u
._typedef
.declaration_specifier
,
773 &iter
->u
._typedef
.type_declarators
,
774 trace
->declaration_scope
);
778 cds_list_for_each_entry(iter
, &node
->u
.root
.typealias
,
780 ret
= ctf_typealias_visit(fd
, depth
+ 1,
781 &iter
->u
.typealias
.target
, &iter
->u
.typealias
.alias
782 trace
->declaration_scope
);
786 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_specifier
, siblings
) {
787 ret
= ctf_declaration_specifier_visit(fd
, depth
, iter
,
788 trace
->root_declaration_scope
);
792 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
793 ret
= ctf_trace_visit(fd
, depth
+ 1, iter
, trace
);
797 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
798 ret
= ctf_stream_visit(fd
, depth
+ 1, iter
,
799 trace
->declaration_scope
, trace
);
803 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
804 ret
= ctf_event_visit(fd
, depth
+ 1, iter
,
805 trace
->declaration_scope
, trace
);
811 case NODE_TYPEALIAS_TARGET
:
812 print_tabs(fd
, depth
);
813 fprintf(fd
, "<target>\n");
816 print_tabs(fd
, depth
);
817 fprintf(fd
, "<declaration_specifier>\n");
818 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.declaration_specifier
, siblings
) {
819 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
823 print_tabs(fd
, depth
);
824 fprintf(fd
, "</declaration_specifier>\n");
826 print_tabs(fd
, depth
);
827 fprintf(fd
, "<type_declarators>\n");
828 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
829 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
833 print_tabs(fd
, depth
);
834 fprintf(fd
, "</type_declarators>\n");
837 print_tabs(fd
, depth
);
838 fprintf(fd
, "</target>\n");
840 case NODE_TYPEALIAS_ALIAS
:
841 print_tabs(fd
, depth
);
842 fprintf(fd
, "<alias>\n");
845 print_tabs(fd
, depth
);
846 fprintf(fd
, "<declaration_specifier>\n");
847 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.declaration_specifier
, siblings
) {
848 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
852 print_tabs(fd
, depth
);
853 fprintf(fd
, "</declaration_specifier>\n");
855 print_tabs(fd
, depth
);
856 fprintf(fd
, "<type_declarators>\n");
857 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
858 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
862 print_tabs(fd
, depth
);
863 fprintf(fd
, "</type_declarators>\n");
866 print_tabs(fd
, depth
);
867 fprintf(fd
, "</alias>\n");
870 print_tabs(fd
, depth
);
871 fprintf(fd
, "<typealias>\n");
872 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.target
);
875 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.alias
);
878 print_tabs(fd
, depth
);
879 fprintf(fd
, "</typealias>\n");
882 case NODE_TYPE_SPECIFIER
:
883 ret
= ctf_visitor_print_type_specifier(fd
, depth
, node
);
888 print_tabs(fd
, depth
);
889 if (node
->u
.pointer
.const_qualifier
)
890 fprintf(fd
, "<const_pointer />\n");
892 fprintf(fd
, "<pointer />\n");
894 case NODE_TYPE_DECLARATOR
:
895 ret
= ctf_visitor_print_type_declarator(fd
, depth
, node
);
900 case NODE_FLOATING_POINT
:
901 print_tabs(fd
, depth
);
902 fprintf(fd
, "<floating_point>\n");
903 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
904 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
908 print_tabs(fd
, depth
);
909 fprintf(fd
, "</floating_point>\n");
912 print_tabs(fd
, depth
);
913 fprintf(fd
, "<integer>\n");
914 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
915 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
919 print_tabs(fd
, depth
);
920 fprintf(fd
, "</integer>\n");
923 print_tabs(fd
, depth
);
924 fprintf(fd
, "<string>\n");
925 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
926 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
930 print_tabs(fd
, depth
);
931 fprintf(fd
, "</string>\n");
933 case NODE_ENUMERATOR
:
934 print_tabs(fd
, depth
);
935 fprintf(fd
, "<enumerator");
936 if (node
->u
.enumerator
.id
)
937 fprintf(fd
, " id=\"%s\"", node
->u
.enumerator
.id
);
939 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
940 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
944 print_tabs(fd
, depth
);
945 fprintf(fd
, "</enumerator>\n");
948 print_tabs(fd
, depth
);
949 if (node
->u
._struct
.name
)
950 fprintf(fd
, "<enum name=\"%s\">\n",
951 node
->u
._enum
.enum_id
);
953 fprintf(fd
, "<enum >\n");
956 if (node
->u
._enum
.container_type
) {
957 print_tabs(fd
, depth
);
958 fprintf(fd
, "<container_type>\n");
959 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._enum
.container_type
);
962 print_tabs(fd
, depth
);
963 fprintf(fd
, "</container_type>\n");
966 print_tabs(fd
, depth
);
967 fprintf(fd
, "<enumerator_list>\n");
968 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
969 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
973 print_tabs(fd
, depth
);
974 fprintf(fd
, "</enumerator_list>\n");
977 print_tabs(fd
, depth
);
978 fprintf(fd
, "</enum>\n");
980 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
981 print_tabs(fd
, depth
);
982 fprintf(fd
, "<declaration_specifier>\n");
983 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.declaration_specifier
, siblings
) {
984 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
988 print_tabs(fd
, depth
);
989 fprintf(fd
, "</declaration_specifier>\n");
991 print_tabs(fd
, depth
);
992 fprintf(fd
, "<type_declarators>\n");
993 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
994 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
998 print_tabs(fd
, depth
);
999 fprintf(fd
, "</type_declarators>\n");
1002 print_tabs(fd
, depth
);
1003 fprintf(fd
, "<variant");
1004 if (node
->u
.variant
.name
)
1005 fprintf(fd
, " name=\"%s\"", node
->u
.variant
.name
);
1006 if (node
->u
.variant
.choice
)
1007 fprintf(fd
, " choice=\"%s\"", node
->u
.variant
.choice
);
1009 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
1010 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
1014 print_tabs(fd
, depth
);
1015 fprintf(fd
, "</variant>\n");
1018 print_tabs(fd
, depth
);
1019 if (node
->u
._struct
.name
)
1020 fprintf(fd
, "<struct name=\"%s\">\n",
1021 node
->u
._struct
.name
);
1023 fprintf(fd
, "<struct>\n");
1024 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
1025 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
1029 print_tabs(fd
, depth
);
1030 fprintf(fd
, "</struct>\n");
1035 fprintf(stderr
, "[error] %s: unknown node type %d\n", __func__
,