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.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <babeltrace/babeltrace-internal.h>
36 #include <babeltrace/list.h>
37 #include "ctf-scanner.h"
38 #include "ctf-parser.h"
41 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
44 void print_tabs(FILE *fd
, int depth
)
48 for (i
= 0; i
< depth
; i
++)
53 int ctf_visitor_print_unary_expression(FILE *fd
, int depth
, struct ctf_node
*node
)
57 switch (node
->u
.unary_expression
.link
) {
58 case UNARY_LINK_UNKNOWN
:
61 print_tabs(fd
, depth
);
62 fprintf(fd
, "<dotlink/>\n");
65 print_tabs(fd
, depth
);
66 fprintf(fd
, "<arrowlink/>\n");
69 print_tabs(fd
, depth
);
70 fprintf(fd
, "<dotdotdot/>\n");
73 fprintf(stderr
, "[error] %s: unknown expression link type %d\n", __func__
,
74 (int) node
->u
.unary_expression
.link
);
78 switch (node
->u
.unary_expression
.type
) {
80 print_tabs(fd
, depth
);
81 fprintf(fd
, "<unary_expression value=");
82 fprintf(fd
, "\"%s\"", node
->u
.unary_expression
.u
.string
);
85 case UNARY_SIGNED_CONSTANT
:
86 print_tabs(fd
, depth
);
87 fprintf(fd
, "<unary_expression value=\"");
88 fprintf(fd
, "%" PRId64
, node
->u
.unary_expression
.u
.signed_constant
);
89 fprintf(fd
, "\" />\n");
91 case UNARY_UNSIGNED_CONSTANT
:
92 print_tabs(fd
, depth
);
93 fprintf(fd
, "<unary_expression value=\"");
94 fprintf(fd
, "%" PRIu64
, node
->u
.unary_expression
.u
.signed_constant
);
95 fprintf(fd
, "\" />\n");
98 print_tabs(fd
, depth
);
99 fprintf(fd
, "<unary_expression_sbrac>\n");
100 ret
= ctf_visitor_print_unary_expression(fd
, depth
+ 1,
101 node
->u
.unary_expression
.u
.sbrac_exp
);
104 print_tabs(fd
, depth
);
105 fprintf(fd
, "</unary_expression_sbrac>\n");
108 print_tabs(fd
, depth
);
109 fprintf(fd
, "<unary_expression_nested>\n");
110 ret
= ctf_visitor_print_unary_expression(fd
, depth
+ 1,
111 node
->u
.unary_expression
.u
.nested_exp
);
114 print_tabs(fd
, depth
);
115 fprintf(fd
, "</unary_expression_nested>\n");
120 fprintf(stderr
, "[error] %s: unknown expression type %d\n", __func__
,
121 (int) node
->u
.unary_expression
.type
);
128 int ctf_visitor_print_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
130 struct ctf_node
*iter
;
133 print_tabs(fd
, depth
);
134 fprintf(fd
, "<type_specifier_list>\n");
135 bt_list_for_each_entry(iter
, &node
->u
.type_specifier_list
.head
, siblings
) {
136 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
140 print_tabs(fd
, depth
);
141 fprintf(fd
, "</type_specifier_list>\n");
146 int ctf_visitor_print_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
149 print_tabs(fd
, depth
);
151 switch (node
->u
.type_specifier
.type
) {
158 case TYPESPEC_DOUBLE
:
159 case TYPESPEC_SIGNED
:
160 case TYPESPEC_UNSIGNED
:
162 case TYPESPEC_COMPLEX
:
163 case TYPESPEC_IMAGINARY
:
165 case TYPESPEC_ID_TYPE
:
166 fprintf(fd
, "<type_specifier type=\"");
168 case TYPESPEC_FLOATING_POINT
:
169 case TYPESPEC_INTEGER
:
170 case TYPESPEC_STRING
:
171 case TYPESPEC_STRUCT
:
172 case TYPESPEC_VARIANT
:
174 fprintf(fd
, "<type_specifier>\n");
177 case TYPESPEC_UNKNOWN
:
179 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
180 (int) node
->u
.type_specifier
.type
);
184 switch (node
->u
.type_specifier
.type
) {
192 fprintf(fd
, "short");
201 fprintf(fd
, "float");
203 case TYPESPEC_DOUBLE
:
204 fprintf(fd
, "double");
206 case TYPESPEC_SIGNED
:
207 fprintf(fd
, "signed");
209 case TYPESPEC_UNSIGNED
:
210 fprintf(fd
, "unsigned");
215 case TYPESPEC_COMPLEX
:
216 fprintf(fd
, "_Complex");
218 case TYPESPEC_IMAGINARY
:
219 fprintf(fd
, "_Imaginary");
222 fprintf(fd
, "const");
224 case TYPESPEC_ID_TYPE
:
225 fprintf(fd
, "%s", node
->u
.type_specifier
.id_type
);
227 case TYPESPEC_FLOATING_POINT
:
228 case TYPESPEC_INTEGER
:
229 case TYPESPEC_STRING
:
230 case TYPESPEC_STRUCT
:
231 case TYPESPEC_VARIANT
:
233 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.type_specifier
.node
);
237 case TYPESPEC_UNKNOWN
:
239 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
240 (int) node
->u
.type_specifier
.type
);
244 switch (node
->u
.type_specifier
.type
) {
251 case TYPESPEC_DOUBLE
:
252 case TYPESPEC_SIGNED
:
253 case TYPESPEC_UNSIGNED
:
255 case TYPESPEC_COMPLEX
:
256 case TYPESPEC_IMAGINARY
:
258 case TYPESPEC_ID_TYPE
:
259 fprintf(fd
, "\"/>\n");
261 case TYPESPEC_FLOATING_POINT
:
262 case TYPESPEC_INTEGER
:
263 case TYPESPEC_STRING
:
264 case TYPESPEC_STRUCT
:
265 case TYPESPEC_VARIANT
:
268 print_tabs(fd
, depth
);
269 fprintf(fd
, "</type_specifier>\n");
271 case TYPESPEC_UNKNOWN
:
273 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
274 (int) node
->u
.type_specifier
.type
);
282 int ctf_visitor_print_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
285 struct ctf_node
*iter
;
287 print_tabs(fd
, depth
);
288 fprintf(fd
, "<type_declarator>\n");
291 if (!bt_list_empty(&node
->u
.type_declarator
.pointers
)) {
292 print_tabs(fd
, depth
);
293 fprintf(fd
, "<pointers>\n");
294 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
296 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
300 print_tabs(fd
, depth
);
301 fprintf(fd
, "</pointers>\n");
304 switch (node
->u
.type_declarator
.type
) {
306 if (node
->u
.type_declarator
.u
.id
) {
307 print_tabs(fd
, depth
);
308 fprintf(fd
, "<id name=\"");
309 fprintf(fd
, "%s", node
->u
.type_declarator
.u
.id
);
310 fprintf(fd
, "\" />\n");
314 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
315 print_tabs(fd
, depth
);
316 fprintf(fd
, "<type_declarator>\n");
317 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
318 node
->u
.type_declarator
.u
.nested
.type_declarator
);
321 print_tabs(fd
, depth
);
322 fprintf(fd
, "</type_declarator>\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");
329 } else if (!bt_list_empty(&node
->u
.type_declarator
.u
.nested
.length
)) {
330 print_tabs(fd
, depth
);
331 fprintf(fd
, "<length>\n");
332 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
334 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
338 print_tabs(fd
, depth
);
339 fprintf(fd
, "</length>\n");
341 if (node
->u
.type_declarator
.bitfield_len
) {
342 print_tabs(fd
, depth
);
343 fprintf(fd
, "<bitfield_len>\n");
344 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
345 node
->u
.type_declarator
.bitfield_len
);
348 print_tabs(fd
, depth
);
349 fprintf(fd
, "</bitfield_len>\n");
352 case TYPEDEC_UNKNOWN
:
354 fprintf(stderr
, "[error] %s: unknown type declarator %d\n", __func__
,
355 (int) node
->u
.type_declarator
.type
);
360 print_tabs(fd
, depth
);
361 fprintf(fd
, "</type_declarator>\n");
365 int ctf_visitor_print_xml(FILE *fd
, int depth
, struct ctf_node
*node
)
368 struct ctf_node
*iter
;
370 switch (node
->type
) {
372 print_tabs(fd
, depth
);
373 fprintf(fd
, "<root>\n");
374 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
376 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
380 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
381 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
385 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
386 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
390 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
391 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
395 print_tabs(fd
, depth
);
396 fprintf(fd
, "</root>\n");
400 print_tabs(fd
, depth
);
401 fprintf(fd
, "<event>\n");
402 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
403 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
407 print_tabs(fd
, depth
);
408 fprintf(fd
, "</event>\n");
411 print_tabs(fd
, depth
);
412 fprintf(fd
, "<stream>\n");
413 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
414 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
418 print_tabs(fd
, depth
);
419 fprintf(fd
, "</stream>\n");
422 print_tabs(fd
, depth
);
423 fprintf(fd
, "<env>\n");
424 bt_list_for_each_entry(iter
, &node
->u
.env
.declaration_list
, siblings
) {
425 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
429 print_tabs(fd
, depth
);
430 fprintf(fd
, "</env>\n");
433 print_tabs(fd
, depth
);
434 fprintf(fd
, "<trace>\n");
435 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
436 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
440 print_tabs(fd
, depth
);
441 fprintf(fd
, "</trace>\n");
444 print_tabs(fd
, depth
);
445 fprintf(fd
, "<clock>\n");
446 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
447 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
451 print_tabs(fd
, depth
);
452 fprintf(fd
, "</clock>\n");
455 print_tabs(fd
, depth
);
456 fprintf(fd
, "<callsite>\n");
457 bt_list_for_each_entry(iter
, &node
->u
.callsite
.declaration_list
, siblings
) {
458 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
462 print_tabs(fd
, depth
);
463 fprintf(fd
, "</callsite>\n");
467 case NODE_CTF_EXPRESSION
:
468 print_tabs(fd
, depth
);
469 fprintf(fd
, "<ctf_expression>\n");
471 print_tabs(fd
, depth
);
472 fprintf(fd
, "<left>\n");
473 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
474 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
479 print_tabs(fd
, depth
);
480 fprintf(fd
, "</left>\n");
482 print_tabs(fd
, depth
);
483 fprintf(fd
, "<right>\n");
484 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
485 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
489 print_tabs(fd
, depth
);
490 fprintf(fd
, "</right>\n");
492 print_tabs(fd
, depth
);
493 fprintf(fd
, "</ctf_expression>\n");
495 case NODE_UNARY_EXPRESSION
:
496 return ctf_visitor_print_unary_expression(fd
, depth
, node
);
499 print_tabs(fd
, depth
);
500 fprintf(fd
, "<typedef>\n");
502 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._typedef
.type_specifier_list
);
506 print_tabs(fd
, depth
);
507 fprintf(fd
, "<type_declarator_list>\n");
508 bt_list_for_each_entry(iter
, &node
->u
._typedef
.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");
516 print_tabs(fd
, depth
);
517 fprintf(fd
, "</typedef>\n");
519 case NODE_TYPEALIAS_TARGET
:
520 print_tabs(fd
, depth
);
521 fprintf(fd
, "<target>\n");
524 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_target
.type_specifier_list
);
528 print_tabs(fd
, depth
);
529 fprintf(fd
, "<type_declarator_list>\n");
530 bt_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
531 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
535 print_tabs(fd
, depth
);
536 fprintf(fd
, "</type_declarator_list>\n");
539 print_tabs(fd
, depth
);
540 fprintf(fd
, "</target>\n");
542 case NODE_TYPEALIAS_ALIAS
:
543 print_tabs(fd
, depth
);
544 fprintf(fd
, "<alias>\n");
547 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_alias
.type_specifier_list
);
551 print_tabs(fd
, depth
);
552 fprintf(fd
, "<type_declarator_list>\n");
553 bt_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
554 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
558 print_tabs(fd
, depth
);
559 fprintf(fd
, "</type_declarator_list>\n");
562 print_tabs(fd
, depth
);
563 fprintf(fd
, "</alias>\n");
566 print_tabs(fd
, depth
);
567 fprintf(fd
, "<typealias>\n");
568 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.target
);
571 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.alias
);
574 print_tabs(fd
, depth
);
575 fprintf(fd
, "</typealias>\n");
578 case NODE_TYPE_SPECIFIER_LIST
:
579 ret
= ctf_visitor_print_type_specifier_list(fd
, depth
, node
);
584 case NODE_TYPE_SPECIFIER
:
585 ret
= ctf_visitor_print_type_specifier(fd
, depth
, node
);
590 print_tabs(fd
, depth
);
591 if (node
->u
.pointer
.const_qualifier
)
592 fprintf(fd
, "<const_pointer />\n");
594 fprintf(fd
, "<pointer />\n");
596 case NODE_TYPE_DECLARATOR
:
597 ret
= ctf_visitor_print_type_declarator(fd
, depth
, node
);
602 case NODE_FLOATING_POINT
:
603 print_tabs(fd
, depth
);
604 fprintf(fd
, "<floating_point>\n");
605 bt_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
606 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
610 print_tabs(fd
, depth
);
611 fprintf(fd
, "</floating_point>\n");
614 print_tabs(fd
, depth
);
615 fprintf(fd
, "<integer>\n");
616 bt_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
617 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
621 print_tabs(fd
, depth
);
622 fprintf(fd
, "</integer>\n");
625 print_tabs(fd
, depth
);
626 fprintf(fd
, "<string>\n");
627 bt_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
628 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
632 print_tabs(fd
, depth
);
633 fprintf(fd
, "</string>\n");
635 case NODE_ENUMERATOR
:
636 print_tabs(fd
, depth
);
637 fprintf(fd
, "<enumerator");
638 if (node
->u
.enumerator
.id
)
639 fprintf(fd
, " id=\"%s\"", node
->u
.enumerator
.id
);
641 bt_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
642 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
646 print_tabs(fd
, depth
);
647 fprintf(fd
, "</enumerator>\n");
650 print_tabs(fd
, depth
);
651 if (node
->u
._struct
.name
)
652 fprintf(fd
, "<enum name=\"%s\">\n",
653 node
->u
._enum
.enum_id
);
655 fprintf(fd
, "<enum >\n");
658 if (node
->u
._enum
.container_type
) {
659 print_tabs(fd
, depth
);
660 fprintf(fd
, "<container_type>\n");
661 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._enum
.container_type
);
664 print_tabs(fd
, depth
);
665 fprintf(fd
, "</container_type>\n");
668 print_tabs(fd
, depth
);
669 fprintf(fd
, "<enumerator_list>\n");
670 bt_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
671 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
675 print_tabs(fd
, depth
);
676 fprintf(fd
, "</enumerator_list>\n");
679 print_tabs(fd
, depth
);
680 fprintf(fd
, "</enum>\n");
682 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
683 ret
= ctf_visitor_print_xml(fd
, depth
,
684 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
688 print_tabs(fd
, depth
);
689 fprintf(fd
, "<type_declarator_list>\n");
690 bt_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
691 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
695 print_tabs(fd
, depth
);
696 fprintf(fd
, "</type_declarator_list>\n");
699 print_tabs(fd
, depth
);
700 fprintf(fd
, "<variant");
701 if (node
->u
.variant
.name
)
702 fprintf(fd
, " name=\"%s\"", node
->u
.variant
.name
);
703 if (node
->u
.variant
.choice
)
704 fprintf(fd
, " choice=\"%s\"", node
->u
.variant
.choice
);
706 bt_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
707 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
711 print_tabs(fd
, depth
);
712 fprintf(fd
, "</variant>\n");
715 print_tabs(fd
, depth
);
716 if (node
->u
._struct
.name
)
717 fprintf(fd
, "<struct name=\"%s\">\n",
718 node
->u
._struct
.name
);
720 fprintf(fd
, "<struct>\n");
721 bt_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
722 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
726 print_tabs(fd
, depth
);
727 fprintf(fd
, "</struct>\n");
728 if (!bt_list_empty(&node
->u
._struct
.min_align
)) {
729 print_tabs(fd
, depth
);
730 fprintf(fd
, "<align>\n");
731 bt_list_for_each_entry(iter
, &node
->u
._struct
.min_align
, siblings
) {
732 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
736 print_tabs(fd
, depth
);
737 fprintf(fd
, "</align>\n");
743 fprintf(stderr
, "[error] %s: unknown node type %d\n", __func__
,