Update sequence (type specifier -> field ref), fix definition lookup
[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.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 cds_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 print_tabs(fd, depth);
141
142 switch (node->u.type_specifier.type) {
143 case TYPESPEC_VOID:
144 case TYPESPEC_CHAR:
145 case TYPESPEC_SHORT:
146 case TYPESPEC_INT:
147 case TYPESPEC_LONG:
148 case TYPESPEC_FLOAT:
149 case TYPESPEC_DOUBLE:
150 case TYPESPEC_SIGNED:
151 case TYPESPEC_UNSIGNED:
152 case TYPESPEC_BOOL:
153 case TYPESPEC_COMPLEX:
154 case TYPESPEC_IMAGINARY:
155 case TYPESPEC_CONST:
156 case TYPESPEC_ID_TYPE:
157 fprintf(fd, "<type_specifier \"");
158 break;
159 case TYPESPEC_FLOATING_POINT:
160 case TYPESPEC_INTEGER:
161 case TYPESPEC_STRING:
162 case TYPESPEC_STRUCT:
163 case TYPESPEC_VARIANT:
164 case TYPESPEC_ENUM:
165 fprintf(fd, "<type_specifier>\n");
166 depth++;
167 break;
168 case TYPESPEC_UNKNOWN:
169 default:
170 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
171 (int) node->u.type_specifier.type);
172 return -EINVAL;
173 }
174
175 switch (node->u.type_specifier.type) {
176 case TYPESPEC_VOID:
177 fprintf(fd, "void");
178 break;
179 case TYPESPEC_CHAR:
180 fprintf(fd, "char");
181 break;
182 case TYPESPEC_SHORT:
183 fprintf(fd, "short");
184 break;
185 case TYPESPEC_INT:
186 fprintf(fd, "int");
187 break;
188 case TYPESPEC_LONG:
189 fprintf(fd, "long");
190 break;
191 case TYPESPEC_FLOAT:
192 fprintf(fd, "float");
193 break;
194 case TYPESPEC_DOUBLE:
195 fprintf(fd, "double");
196 break;
197 case TYPESPEC_SIGNED:
198 fprintf(fd, "signed");
199 break;
200 case TYPESPEC_UNSIGNED:
201 fprintf(fd, "unsigned");
202 break;
203 case TYPESPEC_BOOL:
204 fprintf(fd, "bool");
205 break;
206 case TYPESPEC_COMPLEX:
207 fprintf(fd, "_Complex");
208 break;
209 case TYPESPEC_IMAGINARY:
210 fprintf(fd, "_Imaginary");
211 break;
212 case TYPESPEC_CONST:
213 fprintf(fd, "const");
214 break;
215 case TYPESPEC_ID_TYPE:
216 fprintf(fd, "%s", node->u.type_specifier.id_type);
217 break;
218 case TYPESPEC_FLOATING_POINT:
219 case TYPESPEC_INTEGER:
220 case TYPESPEC_STRING:
221 case TYPESPEC_STRUCT:
222 case TYPESPEC_VARIANT:
223 case TYPESPEC_ENUM:
224 return ctf_visitor_print_xml(fd, depth, node->u.type_specifier.node);
225 case TYPESPEC_UNKNOWN:
226 default:
227 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
228 (int) node->u.type_specifier.type);
229 return -EINVAL;
230 }
231
232 switch (node->u.type_specifier.type) {
233 case TYPESPEC_VOID:
234 case TYPESPEC_CHAR:
235 case TYPESPEC_SHORT:
236 case TYPESPEC_INT:
237 case TYPESPEC_LONG:
238 case TYPESPEC_FLOAT:
239 case TYPESPEC_DOUBLE:
240 case TYPESPEC_SIGNED:
241 case TYPESPEC_UNSIGNED:
242 case TYPESPEC_BOOL:
243 case TYPESPEC_COMPLEX:
244 case TYPESPEC_IMAGINARY:
245 case TYPESPEC_CONST:
246 case TYPESPEC_ID_TYPE:
247 fprintf(fd, "\"/>\n");
248 break;
249 case TYPESPEC_FLOATING_POINT:
250 case TYPESPEC_INTEGER:
251 case TYPESPEC_STRING:
252 case TYPESPEC_STRUCT:
253 case TYPESPEC_VARIANT:
254 case TYPESPEC_ENUM:
255 print_tabs(fd, depth);
256 fprintf(fd, "</type_specifier>\n");
257 depth--;
258 break;
259 case TYPESPEC_UNKNOWN:
260 default:
261 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
262 (int) node->u.type_specifier.type);
263 return -EINVAL;
264 }
265
266 return 0;
267 }
268
269 static
270 int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
271 {
272 int ret = 0;
273 struct ctf_node *iter;
274
275 print_tabs(fd, depth);
276 fprintf(fd, "<type_declarator>\n");
277 depth++;
278
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,
283 siblings) {
284 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
285 if (ret)
286 return ret;
287 }
288 print_tabs(fd, depth);
289 fprintf(fd, "</pointers>\n");
290 }
291
292 switch (node->u.type_declarator.type) {
293 case TYPEDEC_ID:
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");
299 }
300 break;
301 case TYPEDEC_NESTED:
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);
307 if (ret)
308 return ret;
309 print_tabs(fd, depth);
310 fprintf(fd, "</type_declarator>\n");
311 }
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,
316 siblings) {
317 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
318 if (ret)
319 return ret;
320 }
321 print_tabs(fd, depth);
322 fprintf(fd, "</length>\n");
323 }
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 }
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);
335 if (ret)
336 return ret;
337 print_tabs(fd, depth);
338 fprintf(fd, "</bitfield_len>\n");
339 }
340 break;
341 case TYPEDEC_UNKNOWN:
342 default:
343 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
344 (int) node->u.type_declarator.type);
345 return -EINVAL;
346 }
347
348 depth--;
349 print_tabs(fd, depth);
350 fprintf(fd, "</type_declarator>\n");
351 return 0;
352 }
353
354 int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
355 {
356 int ret = 0;
357 struct ctf_node *iter;
358
359 switch (node->type) {
360 case NODE_ROOT:
361 print_tabs(fd, depth);
362 fprintf(fd, "<root>\n");
363 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
364 siblings) {
365 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
366 if (ret)
367 return ret;
368 }
369 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
370 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
371 if (ret)
372 return ret;
373 }
374 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
375 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
376 if (ret)
377 return ret;
378 }
379 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
380 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
381 if (ret)
382 return ret;
383 }
384 print_tabs(fd, depth);
385 fprintf(fd, "</root>\n");
386 break;
387
388 case NODE_EVENT:
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);
393 if (ret)
394 return ret;
395 }
396 print_tabs(fd, depth);
397 fprintf(fd, "</event>\n");
398 break;
399 case NODE_STREAM:
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);
404 if (ret)
405 return ret;
406 }
407 print_tabs(fd, depth);
408 fprintf(fd, "</stream>\n");
409 break;
410 case NODE_TRACE:
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);
415 if (ret)
416 return ret;
417 }
418 print_tabs(fd, depth);
419 fprintf(fd, "</trace>\n");
420 break;
421
422 case NODE_CTF_EXPRESSION:
423 print_tabs(fd, depth);
424 fprintf(fd, "<ctf_expression>\n");
425 depth++;
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);
430 if (ret)
431 return ret;
432 }
433
434 print_tabs(fd, depth);
435 fprintf(fd, "</left>\n");
436
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);
441 if (ret)
442 return ret;
443 }
444 print_tabs(fd, depth);
445 fprintf(fd, "</right>\n");
446 depth--;
447 print_tabs(fd, depth);
448 fprintf(fd, "</ctf_expression>\n");
449 break;
450 case NODE_UNARY_EXPRESSION:
451 return ctf_visitor_print_unary_expression(fd, depth, node);
452
453 case NODE_TYPEDEF:
454 print_tabs(fd, depth);
455 fprintf(fd, "<typedef>\n");
456 depth++;
457 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._typedef.type_specifier_list);
458 if (ret)
459 return ret;
460
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);
465 if (ret)
466 return ret;
467 }
468 print_tabs(fd, depth);
469 fprintf(fd, "</type_declarator_list>\n");
470 depth--;
471 print_tabs(fd, depth);
472 fprintf(fd, "</typedef>\n");
473 break;
474 case NODE_TYPEALIAS_TARGET:
475 print_tabs(fd, depth);
476 fprintf(fd, "<target>\n");
477 depth++;
478
479 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_target.type_specifier_list);
480 if (ret)
481 return ret;
482
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);
487 if (ret)
488 return ret;
489 }
490 print_tabs(fd, depth);
491 fprintf(fd, "</type_declarator_list>\n");
492
493 depth--;
494 print_tabs(fd, depth);
495 fprintf(fd, "</target>\n");
496 break;
497 case NODE_TYPEALIAS_ALIAS:
498 print_tabs(fd, depth);
499 fprintf(fd, "<alias>\n");
500 depth++;
501
502 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_alias.type_specifier_list);
503 if (ret)
504 return ret;
505
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);
510 if (ret)
511 return ret;
512 }
513 print_tabs(fd, depth);
514 fprintf(fd, "</type_declarator_list>\n");
515
516 depth--;
517 print_tabs(fd, depth);
518 fprintf(fd, "</alias>\n");
519 break;
520 case NODE_TYPEALIAS:
521 print_tabs(fd, depth);
522 fprintf(fd, "<typealias>\n");
523 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
524 if (ret)
525 return ret;
526 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
527 if (ret)
528 return ret;
529 print_tabs(fd, depth);
530 fprintf(fd, "</typealias>\n");
531 break;
532
533 case NODE_TYPE_SPECIFIER_LIST:
534 ret = ctf_visitor_print_type_specifier_list(fd, depth, node);
535 if (ret)
536 return ret;
537 break;
538
539 case NODE_TYPE_SPECIFIER:
540 ret = ctf_visitor_print_type_specifier(fd, depth, node);
541 if (ret)
542 return ret;
543 break;
544 case NODE_POINTER:
545 print_tabs(fd, depth);
546 if (node->u.pointer.const_qualifier)
547 fprintf(fd, "<const_pointer />\n");
548 else
549 fprintf(fd, "<pointer />\n");
550 break;
551 case NODE_TYPE_DECLARATOR:
552 ret = ctf_visitor_print_type_declarator(fd, depth, node);
553 if (ret)
554 return ret;
555 break;
556
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);
562 if (ret)
563 return ret;
564 }
565 print_tabs(fd, depth);
566 fprintf(fd, "</floating_point>\n");
567 break;
568 case NODE_INTEGER:
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);
573 if (ret)
574 return ret;
575 }
576 print_tabs(fd, depth);
577 fprintf(fd, "</integer>\n");
578 break;
579 case NODE_STRING:
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);
584 if (ret)
585 return ret;
586 }
587 print_tabs(fd, depth);
588 fprintf(fd, "</string>\n");
589 break;
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);
595 fprintf(fd, ">\n");
596 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
597 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
598 if (ret)
599 return ret;
600 }
601 print_tabs(fd, depth);
602 fprintf(fd, "</enumerator>\n");
603 break;
604 case NODE_ENUM:
605 print_tabs(fd, depth);
606 if (node->u._struct.name)
607 fprintf(fd, "<enum name=\"%s\">\n",
608 node->u._enum.enum_id);
609 else
610 fprintf(fd, "<enum >\n");
611 depth++;
612
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);
617 if (ret)
618 return ret;
619 print_tabs(fd, depth);
620 fprintf(fd, "</container_type>\n");
621 }
622
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);
627 if (ret)
628 return ret;
629 }
630 print_tabs(fd, depth);
631 fprintf(fd, "</enumerator_list>\n");
632
633 depth--;
634 print_tabs(fd, depth);
635 fprintf(fd, "</enum>\n");
636 break;
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);
640 if (ret)
641 return ret;
642
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);
647 if (ret)
648 return ret;
649 }
650 print_tabs(fd, depth);
651 fprintf(fd, "</type_declarator_list>\n");
652 break;
653 case NODE_VARIANT:
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);
660 fprintf(fd, ">\n");
661 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
662 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
663 if (ret)
664 return ret;
665 }
666 print_tabs(fd, depth);
667 fprintf(fd, "</variant>\n");
668 break;
669 case NODE_STRUCT:
670 print_tabs(fd, depth);
671 if (node->u._struct.name)
672 fprintf(fd, "<struct name=\"%s\">\n",
673 node->u._struct.name);
674 else
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);
678 if (ret)
679 return ret;
680 }
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);
688 if (ret)
689 return ret;
690 }
691 print_tabs(fd, depth);
692 fprintf(fd, "</align>\n");
693 }
694 break;
695
696 case NODE_UNKNOWN:
697 default:
698 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
699 (int) node->type);
700 return -EINVAL;
701 }
702 return ret;
703 }
This page took 0.044649 seconds and 4 git commands to generate.