437748cab323f5cedaf9fc3a530e8bf2b4bd5772
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-xml.c
1 /*
2 * ctf-visitor-xml.c
3 *
4 * Common Trace Format Metadata Visitor (XML dump).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <glib.h>
25 #include <inttypes.h>
26 #include <errno.h>
27 #include <babeltrace/babeltrace-internal.h>
28 #include <babeltrace/list.h>
29 #include "ctf-scanner.h"
30 #include "ctf-parser.h"
31 #include "ctf-ast.h"
32
33 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
34
35 static
36 void print_tabs(FILE *fd, int depth)
37 {
38 int i;
39
40 for (i = 0; i < depth; i++)
41 fprintf(fd, "\t");
42 }
43
44 static
45 int ctf_visitor_print_unary_expression(FILE *fd, int depth, struct ctf_node *node)
46 {
47 int ret = 0;
48
49 switch (node->u.unary_expression.link) {
50 case UNARY_LINK_UNKNOWN:
51 break;
52 case UNARY_DOTLINK:
53 print_tabs(fd, depth);
54 fprintf(fd, "<dotlink/>\n");
55 break;
56 case UNARY_ARROWLINK:
57 print_tabs(fd, depth);
58 fprintf(fd, "<arrowlink/>\n");
59 break;
60 case UNARY_DOTDOTDOT:
61 print_tabs(fd, depth);
62 fprintf(fd, "<dotdotdot/>\n");
63 break;
64 default:
65 fprintf(stderr, "[error] %s: unknown expression link type %d\n", __func__,
66 (int) node->u.unary_expression.link);
67 return -EINVAL;
68 }
69
70 switch (node->u.unary_expression.type) {
71 case UNARY_STRING:
72 print_tabs(fd, depth);
73 fprintf(fd, "<unary_expression value=");
74 fprintf(fd, "\"%s\"", node->u.unary_expression.u.string);
75 fprintf(fd, " />\n");
76 break;
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");
82 break;
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");
88 break;
89 case UNARY_SBRAC:
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);
94 if (ret)
95 return ret;
96 print_tabs(fd, depth);
97 fprintf(fd, "</unary_expression_sbrac>\n");
98 break;
99 case UNARY_NESTED:
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);
104 if (ret)
105 return ret;
106 print_tabs(fd, depth);
107 fprintf(fd, "</unary_expression_nested>\n");
108 break;
109
110 case UNARY_UNKNOWN:
111 default:
112 fprintf(stderr, "[error] %s: unknown expression type %d\n", __func__,
113 (int) node->u.unary_expression.type);
114 return -EINVAL;
115 }
116 return 0;
117 }
118
119 static
120 int ctf_visitor_print_type_specifier_list(FILE *fd, int depth, struct ctf_node *node)
121 {
122 struct ctf_node *iter;
123 int ret;
124
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);
129 if (ret)
130 return ret;
131 }
132 print_tabs(fd, depth);
133 fprintf(fd, "</type_specifier_list>\n");
134 return 0;
135 }
136
137 static
138 int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
139 {
140 int ret;
141 print_tabs(fd, depth);
142
143 switch (node->u.type_specifier.type) {
144 case TYPESPEC_VOID:
145 case TYPESPEC_CHAR:
146 case TYPESPEC_SHORT:
147 case TYPESPEC_INT:
148 case TYPESPEC_LONG:
149 case TYPESPEC_FLOAT:
150 case TYPESPEC_DOUBLE:
151 case TYPESPEC_SIGNED:
152 case TYPESPEC_UNSIGNED:
153 case TYPESPEC_BOOL:
154 case TYPESPEC_COMPLEX:
155 case TYPESPEC_IMAGINARY:
156 case TYPESPEC_CONST:
157 case TYPESPEC_ID_TYPE:
158 fprintf(fd, "<type_specifier type=\"");
159 break;
160 case TYPESPEC_FLOATING_POINT:
161 case TYPESPEC_INTEGER:
162 case TYPESPEC_STRING:
163 case TYPESPEC_STRUCT:
164 case TYPESPEC_VARIANT:
165 case TYPESPEC_ENUM:
166 fprintf(fd, "<type_specifier>\n");
167 depth++;
168 break;
169 case TYPESPEC_UNKNOWN:
170 default:
171 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
172 (int) node->u.type_specifier.type);
173 return -EINVAL;
174 }
175
176 switch (node->u.type_specifier.type) {
177 case TYPESPEC_VOID:
178 fprintf(fd, "void");
179 break;
180 case TYPESPEC_CHAR:
181 fprintf(fd, "char");
182 break;
183 case TYPESPEC_SHORT:
184 fprintf(fd, "short");
185 break;
186 case TYPESPEC_INT:
187 fprintf(fd, "int");
188 break;
189 case TYPESPEC_LONG:
190 fprintf(fd, "long");
191 break;
192 case TYPESPEC_FLOAT:
193 fprintf(fd, "float");
194 break;
195 case TYPESPEC_DOUBLE:
196 fprintf(fd, "double");
197 break;
198 case TYPESPEC_SIGNED:
199 fprintf(fd, "signed");
200 break;
201 case TYPESPEC_UNSIGNED:
202 fprintf(fd, "unsigned");
203 break;
204 case TYPESPEC_BOOL:
205 fprintf(fd, "bool");
206 break;
207 case TYPESPEC_COMPLEX:
208 fprintf(fd, "_Complex");
209 break;
210 case TYPESPEC_IMAGINARY:
211 fprintf(fd, "_Imaginary");
212 break;
213 case TYPESPEC_CONST:
214 fprintf(fd, "const");
215 break;
216 case TYPESPEC_ID_TYPE:
217 fprintf(fd, "%s", node->u.type_specifier.id_type);
218 break;
219 case TYPESPEC_FLOATING_POINT:
220 case TYPESPEC_INTEGER:
221 case TYPESPEC_STRING:
222 case TYPESPEC_STRUCT:
223 case TYPESPEC_VARIANT:
224 case TYPESPEC_ENUM:
225 ret = ctf_visitor_print_xml(fd, depth, node->u.type_specifier.node);
226 if (ret)
227 return ret;
228 break;
229 case TYPESPEC_UNKNOWN:
230 default:
231 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
232 (int) node->u.type_specifier.type);
233 return -EINVAL;
234 }
235
236 switch (node->u.type_specifier.type) {
237 case TYPESPEC_VOID:
238 case TYPESPEC_CHAR:
239 case TYPESPEC_SHORT:
240 case TYPESPEC_INT:
241 case TYPESPEC_LONG:
242 case TYPESPEC_FLOAT:
243 case TYPESPEC_DOUBLE:
244 case TYPESPEC_SIGNED:
245 case TYPESPEC_UNSIGNED:
246 case TYPESPEC_BOOL:
247 case TYPESPEC_COMPLEX:
248 case TYPESPEC_IMAGINARY:
249 case TYPESPEC_CONST:
250 case TYPESPEC_ID_TYPE:
251 fprintf(fd, "\"/>\n");
252 break;
253 case TYPESPEC_FLOATING_POINT:
254 case TYPESPEC_INTEGER:
255 case TYPESPEC_STRING:
256 case TYPESPEC_STRUCT:
257 case TYPESPEC_VARIANT:
258 case TYPESPEC_ENUM:
259 depth--;
260 print_tabs(fd, depth);
261 fprintf(fd, "</type_specifier>\n");
262 break;
263 case TYPESPEC_UNKNOWN:
264 default:
265 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
266 (int) node->u.type_specifier.type);
267 return -EINVAL;
268 }
269
270 return 0;
271 }
272
273 static
274 int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
275 {
276 int ret = 0;
277 struct ctf_node *iter;
278
279 print_tabs(fd, depth);
280 fprintf(fd, "<type_declarator>\n");
281 depth++;
282
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,
287 siblings) {
288 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
289 if (ret)
290 return ret;
291 }
292 print_tabs(fd, depth);
293 fprintf(fd, "</pointers>\n");
294 }
295
296 switch (node->u.type_declarator.type) {
297 case TYPEDEC_ID:
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");
303 }
304 break;
305 case TYPEDEC_NESTED:
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);
311 if (ret)
312 return ret;
313 print_tabs(fd, depth);
314 fprintf(fd, "</type_declarator>\n");
315 }
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,
325 siblings) {
326 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
327 if (ret)
328 return ret;
329 }
330 print_tabs(fd, depth);
331 fprintf(fd, "</length>\n");
332 }
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);
338 if (ret)
339 return ret;
340 print_tabs(fd, depth);
341 fprintf(fd, "</bitfield_len>\n");
342 }
343 break;
344 case TYPEDEC_UNKNOWN:
345 default:
346 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
347 (int) node->u.type_declarator.type);
348 return -EINVAL;
349 }
350
351 depth--;
352 print_tabs(fd, depth);
353 fprintf(fd, "</type_declarator>\n");
354 return 0;
355 }
356
357 int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
358 {
359 int ret = 0;
360 struct ctf_node *iter;
361
362 switch (node->type) {
363 case NODE_ROOT:
364 print_tabs(fd, depth);
365 fprintf(fd, "<root>\n");
366 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
367 siblings) {
368 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
369 if (ret)
370 return ret;
371 }
372 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
373 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
374 if (ret)
375 return ret;
376 }
377 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
378 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
379 if (ret)
380 return ret;
381 }
382 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
383 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
384 if (ret)
385 return ret;
386 }
387 print_tabs(fd, depth);
388 fprintf(fd, "</root>\n");
389 break;
390
391 case NODE_EVENT:
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);
396 if (ret)
397 return ret;
398 }
399 print_tabs(fd, depth);
400 fprintf(fd, "</event>\n");
401 break;
402 case NODE_STREAM:
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);
407 if (ret)
408 return ret;
409 }
410 print_tabs(fd, depth);
411 fprintf(fd, "</stream>\n");
412 break;
413 case NODE_ENV:
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);
418 if (ret)
419 return ret;
420 }
421 print_tabs(fd, depth);
422 fprintf(fd, "</env>\n");
423 break;
424 case NODE_TRACE:
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);
429 if (ret)
430 return ret;
431 }
432 print_tabs(fd, depth);
433 fprintf(fd, "</trace>\n");
434 break;
435 case NODE_CLOCK:
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);
440 if (ret)
441 return ret;
442 }
443 print_tabs(fd, depth);
444 fprintf(fd, "</clock>\n");
445 break;
446 case NODE_CALLSITE:
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);
451 if (ret)
452 return ret;
453 }
454 print_tabs(fd, depth);
455 fprintf(fd, "</callsite>\n");
456 break;
457
458
459 case NODE_CTF_EXPRESSION:
460 print_tabs(fd, depth);
461 fprintf(fd, "<ctf_expression>\n");
462 depth++;
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);
467 if (ret)
468 return ret;
469 }
470
471 print_tabs(fd, depth);
472 fprintf(fd, "</left>\n");
473
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);
478 if (ret)
479 return ret;
480 }
481 print_tabs(fd, depth);
482 fprintf(fd, "</right>\n");
483 depth--;
484 print_tabs(fd, depth);
485 fprintf(fd, "</ctf_expression>\n");
486 break;
487 case NODE_UNARY_EXPRESSION:
488 return ctf_visitor_print_unary_expression(fd, depth, node);
489
490 case NODE_TYPEDEF:
491 print_tabs(fd, depth);
492 fprintf(fd, "<typedef>\n");
493 depth++;
494 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._typedef.type_specifier_list);
495 if (ret)
496 return ret;
497
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);
502 if (ret)
503 return ret;
504 }
505 print_tabs(fd, depth);
506 fprintf(fd, "</type_declarator_list>\n");
507 depth--;
508 print_tabs(fd, depth);
509 fprintf(fd, "</typedef>\n");
510 break;
511 case NODE_TYPEALIAS_TARGET:
512 print_tabs(fd, depth);
513 fprintf(fd, "<target>\n");
514 depth++;
515
516 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_target.type_specifier_list);
517 if (ret)
518 return ret;
519
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);
524 if (ret)
525 return ret;
526 }
527 print_tabs(fd, depth);
528 fprintf(fd, "</type_declarator_list>\n");
529
530 depth--;
531 print_tabs(fd, depth);
532 fprintf(fd, "</target>\n");
533 break;
534 case NODE_TYPEALIAS_ALIAS:
535 print_tabs(fd, depth);
536 fprintf(fd, "<alias>\n");
537 depth++;
538
539 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_alias.type_specifier_list);
540 if (ret)
541 return ret;
542
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);
547 if (ret)
548 return ret;
549 }
550 print_tabs(fd, depth);
551 fprintf(fd, "</type_declarator_list>\n");
552
553 depth--;
554 print_tabs(fd, depth);
555 fprintf(fd, "</alias>\n");
556 break;
557 case NODE_TYPEALIAS:
558 print_tabs(fd, depth);
559 fprintf(fd, "<typealias>\n");
560 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
561 if (ret)
562 return ret;
563 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
564 if (ret)
565 return ret;
566 print_tabs(fd, depth);
567 fprintf(fd, "</typealias>\n");
568 break;
569
570 case NODE_TYPE_SPECIFIER_LIST:
571 ret = ctf_visitor_print_type_specifier_list(fd, depth, node);
572 if (ret)
573 return ret;
574 break;
575
576 case NODE_TYPE_SPECIFIER:
577 ret = ctf_visitor_print_type_specifier(fd, depth, node);
578 if (ret)
579 return ret;
580 break;
581 case NODE_POINTER:
582 print_tabs(fd, depth);
583 if (node->u.pointer.const_qualifier)
584 fprintf(fd, "<const_pointer />\n");
585 else
586 fprintf(fd, "<pointer />\n");
587 break;
588 case NODE_TYPE_DECLARATOR:
589 ret = ctf_visitor_print_type_declarator(fd, depth, node);
590 if (ret)
591 return ret;
592 break;
593
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);
599 if (ret)
600 return ret;
601 }
602 print_tabs(fd, depth);
603 fprintf(fd, "</floating_point>\n");
604 break;
605 case NODE_INTEGER:
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);
610 if (ret)
611 return ret;
612 }
613 print_tabs(fd, depth);
614 fprintf(fd, "</integer>\n");
615 break;
616 case NODE_STRING:
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);
621 if (ret)
622 return ret;
623 }
624 print_tabs(fd, depth);
625 fprintf(fd, "</string>\n");
626 break;
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);
632 fprintf(fd, ">\n");
633 bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
634 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
635 if (ret)
636 return ret;
637 }
638 print_tabs(fd, depth);
639 fprintf(fd, "</enumerator>\n");
640 break;
641 case NODE_ENUM:
642 print_tabs(fd, depth);
643 if (node->u._struct.name)
644 fprintf(fd, "<enum name=\"%s\">\n",
645 node->u._enum.enum_id);
646 else
647 fprintf(fd, "<enum >\n");
648 depth++;
649
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);
654 if (ret)
655 return ret;
656 print_tabs(fd, depth);
657 fprintf(fd, "</container_type>\n");
658 }
659
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);
664 if (ret)
665 return ret;
666 }
667 print_tabs(fd, depth);
668 fprintf(fd, "</enumerator_list>\n");
669
670 depth--;
671 print_tabs(fd, depth);
672 fprintf(fd, "</enum>\n");
673 break;
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);
677 if (ret)
678 return ret;
679
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);
684 if (ret)
685 return ret;
686 }
687 print_tabs(fd, depth);
688 fprintf(fd, "</type_declarator_list>\n");
689 break;
690 case NODE_VARIANT:
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);
697 fprintf(fd, ">\n");
698 bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
699 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
700 if (ret)
701 return ret;
702 }
703 print_tabs(fd, depth);
704 fprintf(fd, "</variant>\n");
705 break;
706 case NODE_STRUCT:
707 print_tabs(fd, depth);
708 if (node->u._struct.name)
709 fprintf(fd, "<struct name=\"%s\">\n",
710 node->u._struct.name);
711 else
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);
715 if (ret)
716 return ret;
717 }
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);
725 if (ret)
726 return ret;
727 }
728 print_tabs(fd, depth);
729 fprintf(fd, "</align>\n");
730 }
731 break;
732
733 case NODE_UNKNOWN:
734 default:
735 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
736 (int) node->type);
737 return -EINVAL;
738 }
739 return ret;
740 }
This page took 0.072874 seconds and 3 git commands to generate.