4 * Common Trace Format Metadata Visitor (XML dump).
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/babeltrace-internal.h>
28 #include <babeltrace/list.h>
29 #include "ctf-scanner.h"
30 #include "ctf-parser.h"
33 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
36 void print_tabs(FILE *fd
, int depth
)
40 for (i
= 0; i
< depth
; i
++)
45 int ctf_visitor_print_unary_expression(FILE *fd
, int depth
, struct ctf_node
*node
)
49 switch (node
->u
.unary_expression
.link
) {
50 case UNARY_LINK_UNKNOWN
:
53 print_tabs(fd
, depth
);
54 fprintf(fd
, "<dotlink/>\n");
57 print_tabs(fd
, depth
);
58 fprintf(fd
, "<arrowlink/>\n");
61 print_tabs(fd
, depth
);
62 fprintf(fd
, "<dotdotdot/>\n");
65 fprintf(stderr
, "[error] %s: unknown expression link type %d\n", __func__
,
66 (int) node
->u
.unary_expression
.link
);
70 switch (node
->u
.unary_expression
.type
) {
72 print_tabs(fd
, depth
);
73 fprintf(fd
, "<unary_expression value=");
74 fprintf(fd
, "\"%s\"", node
->u
.unary_expression
.u
.string
);
77 case UNARY_SIGNED_CONSTANT
:
78 print_tabs(fd
, depth
);
79 fprintf(fd
, "<unary_expression value=\"");
80 fprintf(fd
, "%" PRId64
, node
->u
.unary_expression
.u
.signed_constant
);
81 fprintf(fd
, "\" />\n");
83 case UNARY_UNSIGNED_CONSTANT
:
84 print_tabs(fd
, depth
);
85 fprintf(fd
, "<unary_expression value=\"");
86 fprintf(fd
, "%" PRIu64
, node
->u
.unary_expression
.u
.signed_constant
);
87 fprintf(fd
, "\" />\n");
90 print_tabs(fd
, depth
);
91 fprintf(fd
, "<unary_expression_sbrac>\n");
92 ret
= ctf_visitor_print_unary_expression(fd
, depth
+ 1,
93 node
->u
.unary_expression
.u
.sbrac_exp
);
96 print_tabs(fd
, depth
);
97 fprintf(fd
, "</unary_expression_sbrac>\n");
100 print_tabs(fd
, depth
);
101 fprintf(fd
, "<unary_expression_nested>\n");
102 ret
= ctf_visitor_print_unary_expression(fd
, depth
+ 1,
103 node
->u
.unary_expression
.u
.nested_exp
);
106 print_tabs(fd
, depth
);
107 fprintf(fd
, "</unary_expression_nested>\n");
112 fprintf(stderr
, "[error] %s: unknown expression type %d\n", __func__
,
113 (int) node
->u
.unary_expression
.type
);
120 int ctf_visitor_print_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
122 struct ctf_node
*iter
;
125 print_tabs(fd
, depth
);
126 fprintf(fd
, "<type_specifier_list>\n");
127 bt_list_for_each_entry(iter
, &node
->u
.type_specifier_list
.head
, siblings
) {
128 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
132 print_tabs(fd
, depth
);
133 fprintf(fd
, "</type_specifier_list>\n");
138 int ctf_visitor_print_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
141 print_tabs(fd
, depth
);
143 switch (node
->u
.type_specifier
.type
) {
150 case TYPESPEC_DOUBLE
:
151 case TYPESPEC_SIGNED
:
152 case TYPESPEC_UNSIGNED
:
154 case TYPESPEC_COMPLEX
:
155 case TYPESPEC_IMAGINARY
:
157 case TYPESPEC_ID_TYPE
:
158 fprintf(fd
, "<type_specifier type=\"");
160 case TYPESPEC_FLOATING_POINT
:
161 case TYPESPEC_INTEGER
:
162 case TYPESPEC_STRING
:
163 case TYPESPEC_STRUCT
:
164 case TYPESPEC_VARIANT
:
166 fprintf(fd
, "<type_specifier>\n");
169 case TYPESPEC_UNKNOWN
:
171 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
172 (int) node
->u
.type_specifier
.type
);
176 switch (node
->u
.type_specifier
.type
) {
184 fprintf(fd
, "short");
193 fprintf(fd
, "float");
195 case TYPESPEC_DOUBLE
:
196 fprintf(fd
, "double");
198 case TYPESPEC_SIGNED
:
199 fprintf(fd
, "signed");
201 case TYPESPEC_UNSIGNED
:
202 fprintf(fd
, "unsigned");
207 case TYPESPEC_COMPLEX
:
208 fprintf(fd
, "_Complex");
210 case TYPESPEC_IMAGINARY
:
211 fprintf(fd
, "_Imaginary");
214 fprintf(fd
, "const");
216 case TYPESPEC_ID_TYPE
:
217 fprintf(fd
, "%s", node
->u
.type_specifier
.id_type
);
219 case TYPESPEC_FLOATING_POINT
:
220 case TYPESPEC_INTEGER
:
221 case TYPESPEC_STRING
:
222 case TYPESPEC_STRUCT
:
223 case TYPESPEC_VARIANT
:
225 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.type_specifier
.node
);
229 case TYPESPEC_UNKNOWN
:
231 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
232 (int) node
->u
.type_specifier
.type
);
236 switch (node
->u
.type_specifier
.type
) {
243 case TYPESPEC_DOUBLE
:
244 case TYPESPEC_SIGNED
:
245 case TYPESPEC_UNSIGNED
:
247 case TYPESPEC_COMPLEX
:
248 case TYPESPEC_IMAGINARY
:
250 case TYPESPEC_ID_TYPE
:
251 fprintf(fd
, "\"/>\n");
253 case TYPESPEC_FLOATING_POINT
:
254 case TYPESPEC_INTEGER
:
255 case TYPESPEC_STRING
:
256 case TYPESPEC_STRUCT
:
257 case TYPESPEC_VARIANT
:
260 print_tabs(fd
, depth
);
261 fprintf(fd
, "</type_specifier>\n");
263 case TYPESPEC_UNKNOWN
:
265 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
266 (int) node
->u
.type_specifier
.type
);
274 int ctf_visitor_print_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
277 struct ctf_node
*iter
;
279 print_tabs(fd
, depth
);
280 fprintf(fd
, "<type_declarator>\n");
283 if (!bt_list_empty(&node
->u
.type_declarator
.pointers
)) {
284 print_tabs(fd
, depth
);
285 fprintf(fd
, "<pointers>\n");
286 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
288 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
292 print_tabs(fd
, depth
);
293 fprintf(fd
, "</pointers>\n");
296 switch (node
->u
.type_declarator
.type
) {
298 if (node
->u
.type_declarator
.u
.id
) {
299 print_tabs(fd
, depth
);
300 fprintf(fd
, "<id name=\"");
301 fprintf(fd
, "%s", node
->u
.type_declarator
.u
.id
);
302 fprintf(fd
, "\" />\n");
306 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
307 print_tabs(fd
, depth
);
308 fprintf(fd
, "<type_declarator>\n");
309 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
310 node
->u
.type_declarator
.u
.nested
.type_declarator
);
313 print_tabs(fd
, depth
);
314 fprintf(fd
, "</type_declarator>\n");
316 if (node
->u
.type_declarator
.u
.nested
.abstract_array
) {
317 print_tabs(fd
, depth
);
318 fprintf(fd
, "<length>\n");
319 print_tabs(fd
, depth
);
320 fprintf(fd
, "</length>\n");
321 } else if (!bt_list_empty(&node
->u
.type_declarator
.u
.nested
.length
)) {
322 print_tabs(fd
, depth
);
323 fprintf(fd
, "<length>\n");
324 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
326 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
330 print_tabs(fd
, depth
);
331 fprintf(fd
, "</length>\n");
333 if (node
->u
.type_declarator
.bitfield_len
) {
334 print_tabs(fd
, depth
);
335 fprintf(fd
, "<bitfield_len>\n");
336 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
337 node
->u
.type_declarator
.bitfield_len
);
340 print_tabs(fd
, depth
);
341 fprintf(fd
, "</bitfield_len>\n");
344 case TYPEDEC_UNKNOWN
:
346 fprintf(stderr
, "[error] %s: unknown type declarator %d\n", __func__
,
347 (int) node
->u
.type_declarator
.type
);
352 print_tabs(fd
, depth
);
353 fprintf(fd
, "</type_declarator>\n");
357 int ctf_visitor_print_xml(FILE *fd
, int depth
, struct ctf_node
*node
)
360 struct ctf_node
*iter
;
362 switch (node
->type
) {
364 print_tabs(fd
, depth
);
365 fprintf(fd
, "<root>\n");
366 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
368 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
372 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
373 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
377 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
378 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
382 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
383 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
387 print_tabs(fd
, depth
);
388 fprintf(fd
, "</root>\n");
392 print_tabs(fd
, depth
);
393 fprintf(fd
, "<event>\n");
394 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
395 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
399 print_tabs(fd
, depth
);
400 fprintf(fd
, "</event>\n");
403 print_tabs(fd
, depth
);
404 fprintf(fd
, "<stream>\n");
405 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
406 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
410 print_tabs(fd
, depth
);
411 fprintf(fd
, "</stream>\n");
414 print_tabs(fd
, depth
);
415 fprintf(fd
, "<env>\n");
416 bt_list_for_each_entry(iter
, &node
->u
.env
.declaration_list
, siblings
) {
417 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
421 print_tabs(fd
, depth
);
422 fprintf(fd
, "</env>\n");
425 print_tabs(fd
, depth
);
426 fprintf(fd
, "<trace>\n");
427 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
428 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
432 print_tabs(fd
, depth
);
433 fprintf(fd
, "</trace>\n");
436 print_tabs(fd
, depth
);
437 fprintf(fd
, "<clock>\n");
438 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
439 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
443 print_tabs(fd
, depth
);
444 fprintf(fd
, "</clock>\n");
447 print_tabs(fd
, depth
);
448 fprintf(fd
, "<callsite>\n");
449 bt_list_for_each_entry(iter
, &node
->u
.callsite
.declaration_list
, siblings
) {
450 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
454 print_tabs(fd
, depth
);
455 fprintf(fd
, "</callsite>\n");
459 case NODE_CTF_EXPRESSION
:
460 print_tabs(fd
, depth
);
461 fprintf(fd
, "<ctf_expression>\n");
463 print_tabs(fd
, depth
);
464 fprintf(fd
, "<left>\n");
465 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
466 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
471 print_tabs(fd
, depth
);
472 fprintf(fd
, "</left>\n");
474 print_tabs(fd
, depth
);
475 fprintf(fd
, "<right>\n");
476 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
477 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
481 print_tabs(fd
, depth
);
482 fprintf(fd
, "</right>\n");
484 print_tabs(fd
, depth
);
485 fprintf(fd
, "</ctf_expression>\n");
487 case NODE_UNARY_EXPRESSION
:
488 return ctf_visitor_print_unary_expression(fd
, depth
, node
);
491 print_tabs(fd
, depth
);
492 fprintf(fd
, "<typedef>\n");
494 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._typedef
.type_specifier_list
);
498 print_tabs(fd
, depth
);
499 fprintf(fd
, "<type_declarator_list>\n");
500 bt_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
501 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
505 print_tabs(fd
, depth
);
506 fprintf(fd
, "</type_declarator_list>\n");
508 print_tabs(fd
, depth
);
509 fprintf(fd
, "</typedef>\n");
511 case NODE_TYPEALIAS_TARGET
:
512 print_tabs(fd
, depth
);
513 fprintf(fd
, "<target>\n");
516 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_target
.type_specifier_list
);
520 print_tabs(fd
, depth
);
521 fprintf(fd
, "<type_declarator_list>\n");
522 bt_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
523 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
527 print_tabs(fd
, depth
);
528 fprintf(fd
, "</type_declarator_list>\n");
531 print_tabs(fd
, depth
);
532 fprintf(fd
, "</target>\n");
534 case NODE_TYPEALIAS_ALIAS
:
535 print_tabs(fd
, depth
);
536 fprintf(fd
, "<alias>\n");
539 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_alias
.type_specifier_list
);
543 print_tabs(fd
, depth
);
544 fprintf(fd
, "<type_declarator_list>\n");
545 bt_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
546 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
550 print_tabs(fd
, depth
);
551 fprintf(fd
, "</type_declarator_list>\n");
554 print_tabs(fd
, depth
);
555 fprintf(fd
, "</alias>\n");
558 print_tabs(fd
, depth
);
559 fprintf(fd
, "<typealias>\n");
560 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.target
);
563 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.alias
);
566 print_tabs(fd
, depth
);
567 fprintf(fd
, "</typealias>\n");
570 case NODE_TYPE_SPECIFIER_LIST
:
571 ret
= ctf_visitor_print_type_specifier_list(fd
, depth
, node
);
576 case NODE_TYPE_SPECIFIER
:
577 ret
= ctf_visitor_print_type_specifier(fd
, depth
, node
);
582 print_tabs(fd
, depth
);
583 if (node
->u
.pointer
.const_qualifier
)
584 fprintf(fd
, "<const_pointer />\n");
586 fprintf(fd
, "<pointer />\n");
588 case NODE_TYPE_DECLARATOR
:
589 ret
= ctf_visitor_print_type_declarator(fd
, depth
, node
);
594 case NODE_FLOATING_POINT
:
595 print_tabs(fd
, depth
);
596 fprintf(fd
, "<floating_point>\n");
597 bt_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
598 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
602 print_tabs(fd
, depth
);
603 fprintf(fd
, "</floating_point>\n");
606 print_tabs(fd
, depth
);
607 fprintf(fd
, "<integer>\n");
608 bt_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
609 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
613 print_tabs(fd
, depth
);
614 fprintf(fd
, "</integer>\n");
617 print_tabs(fd
, depth
);
618 fprintf(fd
, "<string>\n");
619 bt_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
620 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
624 print_tabs(fd
, depth
);
625 fprintf(fd
, "</string>\n");
627 case NODE_ENUMERATOR
:
628 print_tabs(fd
, depth
);
629 fprintf(fd
, "<enumerator");
630 if (node
->u
.enumerator
.id
)
631 fprintf(fd
, " id=\"%s\"", node
->u
.enumerator
.id
);
633 bt_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
634 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
638 print_tabs(fd
, depth
);
639 fprintf(fd
, "</enumerator>\n");
642 print_tabs(fd
, depth
);
643 if (node
->u
._struct
.name
)
644 fprintf(fd
, "<enum name=\"%s\">\n",
645 node
->u
._enum
.enum_id
);
647 fprintf(fd
, "<enum >\n");
650 if (node
->u
._enum
.container_type
) {
651 print_tabs(fd
, depth
);
652 fprintf(fd
, "<container_type>\n");
653 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._enum
.container_type
);
656 print_tabs(fd
, depth
);
657 fprintf(fd
, "</container_type>\n");
660 print_tabs(fd
, depth
);
661 fprintf(fd
, "<enumerator_list>\n");
662 bt_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
663 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
667 print_tabs(fd
, depth
);
668 fprintf(fd
, "</enumerator_list>\n");
671 print_tabs(fd
, depth
);
672 fprintf(fd
, "</enum>\n");
674 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
675 ret
= ctf_visitor_print_xml(fd
, depth
,
676 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
680 print_tabs(fd
, depth
);
681 fprintf(fd
, "<type_declarator_list>\n");
682 bt_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
683 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
687 print_tabs(fd
, depth
);
688 fprintf(fd
, "</type_declarator_list>\n");
691 print_tabs(fd
, depth
);
692 fprintf(fd
, "<variant");
693 if (node
->u
.variant
.name
)
694 fprintf(fd
, " name=\"%s\"", node
->u
.variant
.name
);
695 if (node
->u
.variant
.choice
)
696 fprintf(fd
, " choice=\"%s\"", node
->u
.variant
.choice
);
698 bt_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
699 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
703 print_tabs(fd
, depth
);
704 fprintf(fd
, "</variant>\n");
707 print_tabs(fd
, depth
);
708 if (node
->u
._struct
.name
)
709 fprintf(fd
, "<struct name=\"%s\">\n",
710 node
->u
._struct
.name
);
712 fprintf(fd
, "<struct>\n");
713 bt_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
714 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
718 print_tabs(fd
, depth
);
719 fprintf(fd
, "</struct>\n");
720 if (!bt_list_empty(&node
->u
._struct
.min_align
)) {
721 print_tabs(fd
, depth
);
722 fprintf(fd
, "<align>\n");
723 bt_list_for_each_entry(iter
, &node
->u
._struct
.min_align
, siblings
) {
724 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
728 print_tabs(fd
, depth
);
729 fprintf(fd
, "</align>\n");
735 fprintf(stderr
, "[error] %s: unknown node type %d\n", __func__
,