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.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
);
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
);
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 cds_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
)
140 print_tabs(fd
, depth
);
142 switch (node
->u
.type_specifier
.type
) {
149 case TYPESPEC_DOUBLE
:
150 case TYPESPEC_SIGNED
:
151 case TYPESPEC_UNSIGNED
:
153 case TYPESPEC_COMPLEX
:
154 case TYPESPEC_IMAGINARY
:
156 case TYPESPEC_ID_TYPE
:
157 fprintf(fd
, "<type_specifier \"");
159 case TYPESPEC_FLOATING_POINT
:
160 case TYPESPEC_INTEGER
:
161 case TYPESPEC_STRING
:
162 case TYPESPEC_STRUCT
:
163 case TYPESPEC_VARIANT
:
165 fprintf(fd
, "<type_specifier>\n");
168 case TYPESPEC_UNKNOWN
:
170 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
171 (int) node
->u
.type_specifier
.type
);
175 switch (node
->u
.type_specifier
.type
) {
183 fprintf(fd
, "short");
192 fprintf(fd
, "float");
194 case TYPESPEC_DOUBLE
:
195 fprintf(fd
, "double");
197 case TYPESPEC_SIGNED
:
198 fprintf(fd
, "signed");
200 case TYPESPEC_UNSIGNED
:
201 fprintf(fd
, "unsigned");
206 case TYPESPEC_COMPLEX
:
207 fprintf(fd
, "_Complex");
209 case TYPESPEC_IMAGINARY
:
210 fprintf(fd
, "_Imaginary");
213 fprintf(fd
, "const");
215 case TYPESPEC_ID_TYPE
:
216 fprintf(fd
, "%s", node
->u
.type_specifier
.id_type
);
218 case TYPESPEC_FLOATING_POINT
:
219 case TYPESPEC_INTEGER
:
220 case TYPESPEC_STRING
:
221 case TYPESPEC_STRUCT
:
222 case TYPESPEC_VARIANT
:
224 return ctf_visitor_print_xml(fd
, depth
, node
->u
.type_specifier
.node
);
225 case TYPESPEC_UNKNOWN
:
227 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
228 (int) node
->u
.type_specifier
.type
);
232 switch (node
->u
.type_specifier
.type
) {
239 case TYPESPEC_DOUBLE
:
240 case TYPESPEC_SIGNED
:
241 case TYPESPEC_UNSIGNED
:
243 case TYPESPEC_COMPLEX
:
244 case TYPESPEC_IMAGINARY
:
246 case TYPESPEC_ID_TYPE
:
247 fprintf(fd
, "\"/>\n");
249 case TYPESPEC_FLOATING_POINT
:
250 case TYPESPEC_INTEGER
:
251 case TYPESPEC_STRING
:
252 case TYPESPEC_STRUCT
:
253 case TYPESPEC_VARIANT
:
255 print_tabs(fd
, depth
);
256 fprintf(fd
, "</type_specifier>\n");
259 case TYPESPEC_UNKNOWN
:
261 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
262 (int) node
->u
.type_specifier
.type
);
270 int ctf_visitor_print_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
273 struct ctf_node
*iter
;
275 print_tabs(fd
, depth
);
276 fprintf(fd
, "<type_declarator>\n");
279 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
280 print_tabs(fd
, depth
);
281 fprintf(fd
, "<pointers>\n");
282 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
284 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
288 print_tabs(fd
, depth
);
289 fprintf(fd
, "</pointers>\n");
292 switch (node
->u
.type_declarator
.type
) {
294 if (node
->u
.type_declarator
.u
.id
) {
295 print_tabs(fd
, depth
);
296 fprintf(fd
, "<id \"");
297 fprintf(fd
, "%s", node
->u
.type_declarator
.u
.id
);
298 fprintf(fd
, "\" />\n");
302 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
303 print_tabs(fd
, depth
);
304 fprintf(fd
, "<type_declarator>\n");
305 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
306 node
->u
.type_declarator
.u
.nested
.type_declarator
);
309 print_tabs(fd
, depth
);
310 fprintf(fd
, "</type_declarator>\n");
312 if (!cds_list_empty(&node
->u
.type_declarator
.u
.nested
.length
)) {
313 print_tabs(fd
, depth
);
314 fprintf(fd
, "<length>\n");
315 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
317 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
321 print_tabs(fd
, depth
);
322 fprintf(fd
, "</length>\n");
324 if (node
->u
.type_declarator
.u
.nested
.abstract_array
) {
325 print_tabs(fd
, depth
);
326 fprintf(fd
, "<length>\n");
327 print_tabs(fd
, depth
);
328 fprintf(fd
, "</length>\n");
330 if (node
->u
.type_declarator
.bitfield_len
) {
331 print_tabs(fd
, depth
);
332 fprintf(fd
, "<bitfield_len>\n");
333 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
334 node
->u
.type_declarator
.bitfield_len
);
337 print_tabs(fd
, depth
);
338 fprintf(fd
, "</bitfield_len>\n");
341 case TYPEDEC_UNKNOWN
:
343 fprintf(stderr
, "[error] %s: unknown type declarator %d\n", __func__
,
344 (int) node
->u
.type_declarator
.type
);
349 print_tabs(fd
, depth
);
350 fprintf(fd
, "</type_declarator>\n");
354 int ctf_visitor_print_xml(FILE *fd
, int depth
, struct ctf_node
*node
)
357 struct ctf_node
*iter
;
359 switch (node
->type
) {
361 print_tabs(fd
, depth
);
362 fprintf(fd
, "<root>\n");
363 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
365 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
369 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
370 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
374 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
375 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
379 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
380 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
384 print_tabs(fd
, depth
);
385 fprintf(fd
, "</root>\n");
389 print_tabs(fd
, depth
);
390 fprintf(fd
, "<event>\n");
391 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
392 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
396 print_tabs(fd
, depth
);
397 fprintf(fd
, "</event>\n");
400 print_tabs(fd
, depth
);
401 fprintf(fd
, "<stream>\n");
402 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
403 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
407 print_tabs(fd
, depth
);
408 fprintf(fd
, "</stream>\n");
411 print_tabs(fd
, depth
);
412 fprintf(fd
, "<trace>\n");
413 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
414 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
418 print_tabs(fd
, depth
);
419 fprintf(fd
, "</trace>\n");
422 case NODE_CTF_EXPRESSION
:
423 print_tabs(fd
, depth
);
424 fprintf(fd
, "<ctf_expression>\n");
426 print_tabs(fd
, depth
);
427 fprintf(fd
, "<left>\n");
428 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
429 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
434 print_tabs(fd
, depth
);
435 fprintf(fd
, "</left>\n");
437 print_tabs(fd
, depth
);
438 fprintf(fd
, "<right>\n");
439 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
440 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
444 print_tabs(fd
, depth
);
445 fprintf(fd
, "</right>\n");
447 print_tabs(fd
, depth
);
448 fprintf(fd
, "</ctf_expression>\n");
450 case NODE_UNARY_EXPRESSION
:
451 return ctf_visitor_print_unary_expression(fd
, depth
, node
);
454 print_tabs(fd
, depth
);
455 fprintf(fd
, "<typedef>\n");
457 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._typedef
.type_specifier_list
);
461 print_tabs(fd
, depth
);
462 fprintf(fd
, "<type_declarator_list>\n");
463 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
464 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
468 print_tabs(fd
, depth
);
469 fprintf(fd
, "</type_declarator_list>\n");
471 print_tabs(fd
, depth
);
472 fprintf(fd
, "</typedef>\n");
474 case NODE_TYPEALIAS_TARGET
:
475 print_tabs(fd
, depth
);
476 fprintf(fd
, "<target>\n");
479 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_target
.type_specifier_list
);
483 print_tabs(fd
, depth
);
484 fprintf(fd
, "<type_declarator_list>\n");
485 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
486 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
490 print_tabs(fd
, depth
);
491 fprintf(fd
, "</type_declarator_list>\n");
494 print_tabs(fd
, depth
);
495 fprintf(fd
, "</target>\n");
497 case NODE_TYPEALIAS_ALIAS
:
498 print_tabs(fd
, depth
);
499 fprintf(fd
, "<alias>\n");
502 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_alias
.type_specifier_list
);
506 print_tabs(fd
, depth
);
507 fprintf(fd
, "<type_declarator_list>\n");
508 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
509 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
513 print_tabs(fd
, depth
);
514 fprintf(fd
, "</type_declarator_list>\n");
517 print_tabs(fd
, depth
);
518 fprintf(fd
, "</alias>\n");
521 print_tabs(fd
, depth
);
522 fprintf(fd
, "<typealias>\n");
523 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.target
);
526 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.alias
);
529 print_tabs(fd
, depth
);
530 fprintf(fd
, "</typealias>\n");
533 case NODE_TYPE_SPECIFIER_LIST
:
534 ret
= ctf_visitor_print_type_specifier_list(fd
, depth
, node
);
539 case NODE_TYPE_SPECIFIER
:
540 ret
= ctf_visitor_print_type_specifier(fd
, depth
, node
);
545 print_tabs(fd
, depth
);
546 if (node
->u
.pointer
.const_qualifier
)
547 fprintf(fd
, "<const_pointer />\n");
549 fprintf(fd
, "<pointer />\n");
551 case NODE_TYPE_DECLARATOR
:
552 ret
= ctf_visitor_print_type_declarator(fd
, depth
, node
);
557 case NODE_FLOATING_POINT
:
558 print_tabs(fd
, depth
);
559 fprintf(fd
, "<floating_point>\n");
560 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
561 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
565 print_tabs(fd
, depth
);
566 fprintf(fd
, "</floating_point>\n");
569 print_tabs(fd
, depth
);
570 fprintf(fd
, "<integer>\n");
571 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
572 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
576 print_tabs(fd
, depth
);
577 fprintf(fd
, "</integer>\n");
580 print_tabs(fd
, depth
);
581 fprintf(fd
, "<string>\n");
582 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
583 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
587 print_tabs(fd
, depth
);
588 fprintf(fd
, "</string>\n");
590 case NODE_ENUMERATOR
:
591 print_tabs(fd
, depth
);
592 fprintf(fd
, "<enumerator");
593 if (node
->u
.enumerator
.id
)
594 fprintf(fd
, " id=\"%s\"", node
->u
.enumerator
.id
);
596 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
597 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
601 print_tabs(fd
, depth
);
602 fprintf(fd
, "</enumerator>\n");
605 print_tabs(fd
, depth
);
606 if (node
->u
._struct
.name
)
607 fprintf(fd
, "<enum name=\"%s\">\n",
608 node
->u
._enum
.enum_id
);
610 fprintf(fd
, "<enum >\n");
613 if (node
->u
._enum
.container_type
) {
614 print_tabs(fd
, depth
);
615 fprintf(fd
, "<container_type>\n");
616 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._enum
.container_type
);
619 print_tabs(fd
, depth
);
620 fprintf(fd
, "</container_type>\n");
623 print_tabs(fd
, depth
);
624 fprintf(fd
, "<enumerator_list>\n");
625 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
626 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
630 print_tabs(fd
, depth
);
631 fprintf(fd
, "</enumerator_list>\n");
634 print_tabs(fd
, depth
);
635 fprintf(fd
, "</enum>\n");
637 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
638 ret
= ctf_visitor_print_xml(fd
, depth
,
639 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
643 print_tabs(fd
, depth
);
644 fprintf(fd
, "<type_declarator_list>\n");
645 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
646 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
650 print_tabs(fd
, depth
);
651 fprintf(fd
, "</type_declarator_list>\n");
654 print_tabs(fd
, depth
);
655 fprintf(fd
, "<variant");
656 if (node
->u
.variant
.name
)
657 fprintf(fd
, " name=\"%s\"", node
->u
.variant
.name
);
658 if (node
->u
.variant
.choice
)
659 fprintf(fd
, " choice=\"%s\"", node
->u
.variant
.choice
);
661 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
662 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
666 print_tabs(fd
, depth
);
667 fprintf(fd
, "</variant>\n");
670 print_tabs(fd
, depth
);
671 if (node
->u
._struct
.name
)
672 fprintf(fd
, "<struct name=\"%s\">\n",
673 node
->u
._struct
.name
);
675 fprintf(fd
, "<struct>\n");
676 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
677 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
681 print_tabs(fd
, depth
);
682 fprintf(fd
, "</struct>\n");
683 if (!cds_list_empty(&node
->u
._struct
.min_align
)) {
684 print_tabs(fd
, depth
);
685 fprintf(fd
, "<align>\n");
686 cds_list_for_each_entry(iter
, &node
->u
._struct
.min_align
, siblings
) {
687 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
691 print_tabs(fd
, depth
);
692 fprintf(fd
, "</align>\n");
698 fprintf(stderr
, "[error] %s: unknown node type %d\n", __func__
,