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_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 /* TODO: definition */
406 event
->context
= container_of(declaration
, struct declaration_struct
, p
);
407 } else if (!strcmp(left
, "fields")) {
408 struct declaration
*declaration
;
410 if (!event
->definition_scope
)
412 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
413 &node
->u
.ctf_expression
.right
,
414 event
->declaration_scope
);
417 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
419 /* TODO: definition */
420 event
->fields
= container_of(declaration
, struct declaration_struct
, p
);
427 /* TODO: declaration specifier should be added. */
434 int ctf_event_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
435 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
438 struct ctf_node
*iter
;
439 struct ctf_event
*event
;
441 event
= g_new0(struct ctf_event
, 1);
442 event
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
443 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
444 ret
= ctf_event_declaration_visit(fd
, depth
+ 1, iter
, event
, trace
);
448 if (!CTF_EVENT_FIELD_IS_SET(event
, name
)) {
452 if (!CTF_EVENT_FIELD_IS_SET(event
, id
)) {
456 if (!CTF_EVENT_FIELD_IS_SET(event
, stream_id
)) {
460 if (event
->stream
->events_by_id
->len
<= event
->id
)
461 g_ptr_array_set_size(event
->stream
->events_by_id
, event
->id
+ 1);
462 g_ptr_array_index(event
->stream
->events_by_id
, event
->id
) = event
;
463 g_hash_table_insert(event
->stream
->event_quark_to_id
,
464 (gpointer
)(unsigned long) event
->name
,
469 declaration_unref(event
->fields
);
470 declaration_unref(event
->context
);
471 free_definition_scope(event
->definition_scope
);
472 free_declaration_scope(event
->declaration_scope
);
479 int ctf_stream_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_stream
*stream
, struct ctf_trace
*trace
)
483 switch (node
->type
) {
485 ret
= ctf_typedef_visit(fd
, depth
+ 1,
486 &node
->u
._typedef
.declaration_specifier
,
487 &node
->u
._typedef
.type_declarators
,
488 stream
->declaration_scope
);
493 ret
= ctf_typealias_visit(fd
, depth
+ 1,
494 &node
->u
.typealias
.target
, &node
->u
.typealias
.alias
495 stream
->declaration_scope
);
499 case NODE_CTF_EXPRESSION
:
503 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
504 if (!strcmp(left
, "stream_id")) {
505 if (CTF_EVENT_FIELD_IS_SET(event
, stream_id
))
507 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &event
->stream_id
);
509 fprintf(stderr
, "[error] %s: unexpected unary expression for event stream_id\n", __func__
);
512 CTF_EVENT_SET_FIELD(event
, stream_id
);
513 } else if (!strcmp(left
, "event_header")) {
514 struct declaration
*declaration
;
516 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
517 &node
->u
.ctf_expression
.right
,
518 stream
->declaration_scope
, stream
->definition_scope
);
521 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
523 /* TODO: definition */
524 stream
->event_header
= container_of(declaration
, struct declaration_struct
, p
);
525 } else if (!strcmp(left
, "event_context")) {
526 struct declaration
*declaration
;
528 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
529 &node
->u
.ctf_expression
.right
,
530 stream
->declaration_scope
);
533 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
535 /* TODO: definition */
536 stream
->event_context
= container_of(declaration
, struct declaration_struct
, p
);
537 } else if (!strcmp(left
, "packet_context")) {
538 struct declaration
*declaration
;
540 declaration
= ctf_declaration_specifier_visit(fd
, depth
,
541 &node
->u
.ctf_expression
.right
,
542 stream
->declaration_scope
);
545 if (declaration
->type
->id
!= CTF_TYPE_STRUCT
)
547 /* TODO: definition */
548 stream
->packet_context
= container_of(declaration
, struct declaration_struct
, p
);
555 /* TODO: declaration specifier should be added. */
562 int ctf_stream_visit(FILE *fd
, int depth
, struct ctf_node
*node
,
563 struct declaration_scope
*parent_declaration_scope
, struct ctf_trace
*trace
)
566 struct ctf_node
*iter
;
567 struct ctf_stream
*stream
;
569 stream
= g_new0(struct ctf_stream
, 1);
570 stream
->declaration_scope
= new_declaration_scope(parent_declaration_scope
);
571 stream
->definition_scope
= new_definition_scope(trace
->definition_scope
);
572 stream
->events_by_id
= g_ptr_array_new();
573 stream
->event_quark_to_id
= g_hash_table_new(g_int_hash
, g_int_equal
);
574 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
575 ret
= ctf_stream_declaration_visit(fd
, depth
+ 1, iter
, stream
, trace
);
579 if (!CTF_EVENT_FIELD_IS_SET(stream
, stream_id
)) {
583 if (trace
->streams
->len
<= stream
->stream_id
)
584 g_ptr_array_set_size(trace
->streams
, stream
->stream_id
+ 1);
585 g_ptr_array_index(trace
->streams
, stream
->stream_id
) = stream
;
589 declaration_unref(stream
->event_header
);
590 declaration_unref(stream
->event_context
);
591 declaration_unref(stream
->packet_context
);
592 g_ptr_array_free(stream
->events_by_id
, TRUE
);
593 g_hash_table_free(stream
->event_quark_to_id
);
594 free_definition_scope(stream
->definition_scope
);
595 free_declaration_scope(stream
->declaration_scope
);
601 int ctf_trace_declaration_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
605 switch (node
->type
) {
607 ret
= ctf_typedef_visit(fd
, depth
+ 1,
608 &node
->u
._typedef
.declaration_specifier
,
609 &node
->u
._typedef
.type_declarators
,
610 trace
->declaration_scope
);
615 ret
= ctf_typealias_visit(fd
, depth
+ 1,
616 &node
->u
.typealias
.target
, &node
->u
.typealias
.alias
617 trace
->declaration_scope
);
621 case NODE_CTF_EXPRESSION
:
625 left
= concatenate_unary_strings(&node
->u
.ctf_expression
.left
);
626 if (!strcmp(left
, "major")) {
627 if (CTF_EVENT_FIELD_IS_SET(trace
, major
))
629 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->major
);
631 fprintf(stderr
, "[error] %s: unexpected unary expression for trace major number\n", __func__
);
634 CTF_EVENT_SET_FIELD(trace
, major
);
635 } else if (!strcmp(left
, "minor")) {
636 if (CTF_EVENT_FIELD_IS_SET(trace
, minor
))
638 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->minor
);
640 fprintf(stderr
, "[error] %s: unexpected unary expression for trace minor number\n", __func__
);
643 CTF_EVENT_SET_FIELD(trace
, minor
);
644 } else if (!strcmp(left
, "word_size")) {
645 if (CTF_EVENT_FIELD_IS_SET(trace
, word_size
))
647 ret
= get_unary_unsigned(&node
->u
.ctf_expression
.right
, &trace
->word_size
);
649 fprintf(stderr
, "[error] %s: unexpected unary expression for trace word_size\n", __func__
);
652 CTF_EVENT_SET_FIELD(trace
, word_size
);
653 } else if (!strcmp(left
, "uuid")) {
654 if (CTF_EVENT_FIELD_IS_SET(trace
, uuid
))
656 ret
= get_unary_uuid(&node
->u
.ctf_expression
.right
, &trace
->uuid
);
658 fprintf(stderr
, "[error] %s: unexpected unary expression for trace uuid\n", __func__
);
661 CTF_EVENT_SET_FIELD(trace
, uuid
);
668 /* TODO: declaration specifier should be added. */
676 int ctf_trace_visit(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
679 struct ctf_node
*iter
;
681 if (trace
->declaration_scope
)
683 trace
->declaration_scope
= new_declaration_scope(trace
->root_declaration_scope
);
684 trace
->definition_scope
= new_definition_scope(trace
->root_definition_scope
);
685 trace
->streams
= g_ptr_array_new();
686 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
687 ret
= ctf_trace_declaration_visit(fd
, depth
+ 1, iter
, trace
);
691 if (!CTF_EVENT_FIELD_IS_SET(trace
, major
)) {
695 if (!CTF_EVENT_FIELD_IS_SET(trace
, minor
)) {
699 if (!CTF_EVENT_FIELD_IS_SET(trace
, uuid
)) {
703 if (!CTF_EVENT_FIELD_IS_SET(trace
, word_size
)) {
710 g_ptr_array_free(trace
->streams
, TRUE
);
711 free_definition_scope(stream
->definition_scope
);
712 free_declaration_scope(stream
->declaration_scope
);
716 int _ctf_visitor(FILE *fd
, int depth
, struct ctf_node
*node
, struct ctf_trace
*trace
)
719 struct ctf_node
*iter
;
721 switch (node
->type
) {
723 cds_list_for_each_entry(iter
, &node
->u
.root
._typedef
,
725 ret
= ctf_typedef_visit(fd
, depth
+ 1,
726 &iter
->u
._typedef
.declaration_specifier
,
727 &iter
->u
._typedef
.type_declarators
,
728 trace
->declaration_scope
);
732 cds_list_for_each_entry(iter
, &node
->u
.root
.typealias
,
734 ret
= ctf_typealias_visit(fd
, depth
+ 1,
735 &iter
->u
.typealias
.target
, &iter
->u
.typealias
.alias
736 trace
->declaration_scope
);
740 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_specifier
, siblings
) {
741 ret
= ctf_declaration_specifier_visit(fd
, depth
, iter
,
742 trace
->root_declaration_scope
);
746 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
747 ret
= ctf_trace_visit(fd
, depth
+ 1, iter
, trace
);
751 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
752 ret
= ctf_stream_visit(fd
, depth
+ 1, iter
,
753 trace
->declaration_scope
, trace
);
757 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
758 ret
= ctf_event_visit(fd
, depth
+ 1, iter
,
759 trace
->declaration_scope
, trace
);
765 case NODE_TYPEALIAS_TARGET
:
766 print_tabs(fd
, depth
);
767 fprintf(fd
, "<target>\n");
770 print_tabs(fd
, depth
);
771 fprintf(fd
, "<declaration_specifier>\n");
772 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.declaration_specifier
, siblings
) {
773 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
777 print_tabs(fd
, depth
);
778 fprintf(fd
, "</declaration_specifier>\n");
780 print_tabs(fd
, depth
);
781 fprintf(fd
, "<type_declarators>\n");
782 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
783 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
787 print_tabs(fd
, depth
);
788 fprintf(fd
, "</type_declarators>\n");
791 print_tabs(fd
, depth
);
792 fprintf(fd
, "</target>\n");
794 case NODE_TYPEALIAS_ALIAS
:
795 print_tabs(fd
, depth
);
796 fprintf(fd
, "<alias>\n");
799 print_tabs(fd
, depth
);
800 fprintf(fd
, "<declaration_specifier>\n");
801 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.declaration_specifier
, siblings
) {
802 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
806 print_tabs(fd
, depth
);
807 fprintf(fd
, "</declaration_specifier>\n");
809 print_tabs(fd
, depth
);
810 fprintf(fd
, "<type_declarators>\n");
811 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
812 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
816 print_tabs(fd
, depth
);
817 fprintf(fd
, "</type_declarators>\n");
820 print_tabs(fd
, depth
);
821 fprintf(fd
, "</alias>\n");
824 print_tabs(fd
, depth
);
825 fprintf(fd
, "<typealias>\n");
826 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.target
);
829 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.alias
);
832 print_tabs(fd
, depth
);
833 fprintf(fd
, "</typealias>\n");
836 case NODE_TYPE_SPECIFIER
:
837 ret
= ctf_visitor_print_type_specifier(fd
, depth
, node
);
842 print_tabs(fd
, depth
);
843 if (node
->u
.pointer
.const_qualifier
)
844 fprintf(fd
, "<const_pointer />\n");
846 fprintf(fd
, "<pointer />\n");
848 case NODE_TYPE_DECLARATOR
:
849 ret
= ctf_visitor_print_type_declarator(fd
, depth
, node
);
854 case NODE_FLOATING_POINT
:
855 print_tabs(fd
, depth
);
856 fprintf(fd
, "<floating_point>\n");
857 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
858 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
862 print_tabs(fd
, depth
);
863 fprintf(fd
, "</floating_point>\n");
866 print_tabs(fd
, depth
);
867 fprintf(fd
, "<integer>\n");
868 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
869 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
873 print_tabs(fd
, depth
);
874 fprintf(fd
, "</integer>\n");
877 print_tabs(fd
, depth
);
878 fprintf(fd
, "<string>\n");
879 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
880 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
884 print_tabs(fd
, depth
);
885 fprintf(fd
, "</string>\n");
887 case NODE_ENUMERATOR
:
888 print_tabs(fd
, depth
);
889 fprintf(fd
, "<enumerator");
890 if (node
->u
.enumerator
.id
)
891 fprintf(fd
, " id=\"%s\"", node
->u
.enumerator
.id
);
893 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
894 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
898 print_tabs(fd
, depth
);
899 fprintf(fd
, "</enumerator>\n");
902 print_tabs(fd
, depth
);
903 if (node
->u
._struct
.name
)
904 fprintf(fd
, "<enum name=\"%s\">\n",
905 node
->u
._enum
.enum_id
);
907 fprintf(fd
, "<enum >\n");
910 if (node
->u
._enum
.container_type
) {
911 print_tabs(fd
, depth
);
912 fprintf(fd
, "<container_type>\n");
913 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._enum
.container_type
);
916 print_tabs(fd
, depth
);
917 fprintf(fd
, "</container_type>\n");
920 print_tabs(fd
, depth
);
921 fprintf(fd
, "<enumerator_list>\n");
922 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
923 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
927 print_tabs(fd
, depth
);
928 fprintf(fd
, "</enumerator_list>\n");
931 print_tabs(fd
, depth
);
932 fprintf(fd
, "</enum>\n");
934 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
935 print_tabs(fd
, depth
);
936 fprintf(fd
, "<declaration_specifier>\n");
937 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.declaration_specifier
, siblings
) {
938 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
942 print_tabs(fd
, depth
);
943 fprintf(fd
, "</declaration_specifier>\n");
945 print_tabs(fd
, depth
);
946 fprintf(fd
, "<type_declarators>\n");
947 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
948 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
952 print_tabs(fd
, depth
);
953 fprintf(fd
, "</type_declarators>\n");
956 print_tabs(fd
, depth
);
957 fprintf(fd
, "<variant");
958 if (node
->u
.variant
.name
)
959 fprintf(fd
, " name=\"%s\"", node
->u
.variant
.name
);
960 if (node
->u
.variant
.choice
)
961 fprintf(fd
, " choice=\"%s\"", node
->u
.variant
.choice
);
963 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
964 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
968 print_tabs(fd
, depth
);
969 fprintf(fd
, "</variant>\n");
972 print_tabs(fd
, depth
);
973 if (node
->u
._struct
.name
)
974 fprintf(fd
, "<struct name=\"%s\">\n",
975 node
->u
._struct
.name
);
977 fprintf(fd
, "<struct>\n");
978 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
979 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
983 print_tabs(fd
, depth
);
984 fprintf(fd
, "</struct>\n");
989 fprintf(stderr
, "[error] %s: unknown node type %d\n", __func__
,