prettify output
[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 (node->u.type_declarator.u.nested.length) {
313 print_tabs(fd, depth);
314 fprintf(fd, "<length>\n");
315 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.type_declarator.u.nested.length);
316 if (ret)
317 return ret;
318 print_tabs(fd, depth);
319 fprintf(fd, "</length>\n");
320 }
321 if (node->u.type_declarator.u.nested.abstract_array) {
322 print_tabs(fd, depth);
323 fprintf(fd, "<length>\n");
324 print_tabs(fd, depth);
325 fprintf(fd, "</length>\n");
326 }
327 if (node->u.type_declarator.bitfield_len) {
328 print_tabs(fd, depth);
329 fprintf(fd, "<bitfield_len>\n");
330 ret = ctf_visitor_print_xml(fd, depth + 1,
331 node->u.type_declarator.bitfield_len);
332 if (ret)
333 return ret;
334 print_tabs(fd, depth);
335 fprintf(fd, "</bitfield_len>\n");
336 }
337 break;
338 case TYPEDEC_UNKNOWN:
339 default:
340 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
341 (int) node->u.type_declarator.type);
342 return -EINVAL;
343 }
344
345 depth--;
346 print_tabs(fd, depth);
347 fprintf(fd, "</type_declarator>\n");
348 return 0;
349 }
350
351 int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
352 {
353 int ret = 0;
354 struct ctf_node *iter;
355
356 switch (node->type) {
357 case NODE_ROOT:
358 print_tabs(fd, depth);
359 fprintf(fd, "<root>\n");
360 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
361 siblings) {
362 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
363 if (ret)
364 return ret;
365 }
366 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
367 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
368 if (ret)
369 return ret;
370 }
371 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
372 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
373 if (ret)
374 return ret;
375 }
376 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
377 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
378 if (ret)
379 return ret;
380 }
381 print_tabs(fd, depth);
382 fprintf(fd, "</root>\n");
383 break;
384
385 case NODE_EVENT:
386 print_tabs(fd, depth);
387 fprintf(fd, "<event>\n");
388 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
389 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
390 if (ret)
391 return ret;
392 }
393 print_tabs(fd, depth);
394 fprintf(fd, "</event>\n");
395 break;
396 case NODE_STREAM:
397 print_tabs(fd, depth);
398 fprintf(fd, "<stream>\n");
399 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
400 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
401 if (ret)
402 return ret;
403 }
404 print_tabs(fd, depth);
405 fprintf(fd, "</stream>\n");
406 break;
407 case NODE_TRACE:
408 print_tabs(fd, depth);
409 fprintf(fd, "<trace>\n");
410 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
411 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
412 if (ret)
413 return ret;
414 }
415 print_tabs(fd, depth);
416 fprintf(fd, "</trace>\n");
417 break;
418
419 case NODE_CTF_EXPRESSION:
420 print_tabs(fd, depth);
421 fprintf(fd, "<ctf_expression>\n");
422 depth++;
423 print_tabs(fd, depth);
424 fprintf(fd, "<left>\n");
425 cds_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
426 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
427 if (ret)
428 return ret;
429 }
430
431 print_tabs(fd, depth);
432 fprintf(fd, "</left>\n");
433
434 print_tabs(fd, depth);
435 fprintf(fd, "<right>\n");
436 cds_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
437 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
438 if (ret)
439 return ret;
440 }
441 print_tabs(fd, depth);
442 fprintf(fd, "</right>\n");
443 depth--;
444 print_tabs(fd, depth);
445 fprintf(fd, "</ctf_expression>\n");
446 break;
447 case NODE_UNARY_EXPRESSION:
448 return ctf_visitor_print_unary_expression(fd, depth, node);
449
450 case NODE_TYPEDEF:
451 print_tabs(fd, depth);
452 fprintf(fd, "<typedef>\n");
453 depth++;
454 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._typedef.type_specifier_list);
455 if (ret)
456 return ret;
457
458 print_tabs(fd, depth);
459 fprintf(fd, "<type_declarator_list>\n");
460 cds_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
461 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
462 if (ret)
463 return ret;
464 }
465 print_tabs(fd, depth);
466 fprintf(fd, "</type_declarator_list>\n");
467 depth--;
468 print_tabs(fd, depth);
469 fprintf(fd, "</typedef>\n");
470 break;
471 case NODE_TYPEALIAS_TARGET:
472 print_tabs(fd, depth);
473 fprintf(fd, "<target>\n");
474 depth++;
475
476 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_target.type_specifier_list);
477 if (ret)
478 return ret;
479
480 print_tabs(fd, depth);
481 fprintf(fd, "<type_declarator_list>\n");
482 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
483 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
484 if (ret)
485 return ret;
486 }
487 print_tabs(fd, depth);
488 fprintf(fd, "</type_declarator_list>\n");
489
490 depth--;
491 print_tabs(fd, depth);
492 fprintf(fd, "</target>\n");
493 break;
494 case NODE_TYPEALIAS_ALIAS:
495 print_tabs(fd, depth);
496 fprintf(fd, "<alias>\n");
497 depth++;
498
499 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_alias.type_specifier_list);
500 if (ret)
501 return ret;
502
503 print_tabs(fd, depth);
504 fprintf(fd, "<type_declarator_list>\n");
505 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
506 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
507 if (ret)
508 return ret;
509 }
510 print_tabs(fd, depth);
511 fprintf(fd, "</type_declarator_list>\n");
512
513 depth--;
514 print_tabs(fd, depth);
515 fprintf(fd, "</alias>\n");
516 break;
517 case NODE_TYPEALIAS:
518 print_tabs(fd, depth);
519 fprintf(fd, "<typealias>\n");
520 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
521 if (ret)
522 return ret;
523 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
524 if (ret)
525 return ret;
526 print_tabs(fd, depth);
527 fprintf(fd, "</typealias>\n");
528 break;
529
530 case NODE_TYPE_SPECIFIER_LIST:
531 ret = ctf_visitor_print_type_specifier_list(fd, depth, node);
532 if (ret)
533 return ret;
534 break;
535
536 case NODE_TYPE_SPECIFIER:
537 ret = ctf_visitor_print_type_specifier(fd, depth, node);
538 if (ret)
539 return ret;
540 break;
541 case NODE_POINTER:
542 print_tabs(fd, depth);
543 if (node->u.pointer.const_qualifier)
544 fprintf(fd, "<const_pointer />\n");
545 else
546 fprintf(fd, "<pointer />\n");
547 break;
548 case NODE_TYPE_DECLARATOR:
549 ret = ctf_visitor_print_type_declarator(fd, depth, node);
550 if (ret)
551 return ret;
552 break;
553
554 case NODE_FLOATING_POINT:
555 print_tabs(fd, depth);
556 fprintf(fd, "<floating_point>\n");
557 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
558 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
559 if (ret)
560 return ret;
561 }
562 print_tabs(fd, depth);
563 fprintf(fd, "</floating_point>\n");
564 break;
565 case NODE_INTEGER:
566 print_tabs(fd, depth);
567 fprintf(fd, "<integer>\n");
568 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
569 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
570 if (ret)
571 return ret;
572 }
573 print_tabs(fd, depth);
574 fprintf(fd, "</integer>\n");
575 break;
576 case NODE_STRING:
577 print_tabs(fd, depth);
578 fprintf(fd, "<string>\n");
579 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
580 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
581 if (ret)
582 return ret;
583 }
584 print_tabs(fd, depth);
585 fprintf(fd, "</string>\n");
586 break;
587 case NODE_ENUMERATOR:
588 print_tabs(fd, depth);
589 fprintf(fd, "<enumerator");
590 if (node->u.enumerator.id)
591 fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
592 fprintf(fd, ">\n");
593 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
594 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
595 if (ret)
596 return ret;
597 }
598 print_tabs(fd, depth);
599 fprintf(fd, "</enumerator>\n");
600 break;
601 case NODE_ENUM:
602 print_tabs(fd, depth);
603 if (node->u._struct.name)
604 fprintf(fd, "<enum name=\"%s\">\n",
605 node->u._enum.enum_id);
606 else
607 fprintf(fd, "<enum >\n");
608 depth++;
609
610 if (node->u._enum.container_type) {
611 print_tabs(fd, depth);
612 fprintf(fd, "<container_type>\n");
613 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
614 if (ret)
615 return ret;
616 print_tabs(fd, depth);
617 fprintf(fd, "</container_type>\n");
618 }
619
620 print_tabs(fd, depth);
621 fprintf(fd, "<enumerator_list>\n");
622 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
623 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
624 if (ret)
625 return ret;
626 }
627 print_tabs(fd, depth);
628 fprintf(fd, "</enumerator_list>\n");
629
630 depth--;
631 print_tabs(fd, depth);
632 fprintf(fd, "</enum>\n");
633 break;
634 case NODE_STRUCT_OR_VARIANT_DECLARATION:
635 ret = ctf_visitor_print_xml(fd, depth,
636 node->u.struct_or_variant_declaration.type_specifier_list);
637 if (ret)
638 return ret;
639
640 print_tabs(fd, depth);
641 fprintf(fd, "<type_declarator_list>\n");
642 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
643 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
644 if (ret)
645 return ret;
646 }
647 print_tabs(fd, depth);
648 fprintf(fd, "</type_declarator_list>\n");
649 break;
650 case NODE_VARIANT:
651 print_tabs(fd, depth);
652 fprintf(fd, "<variant");
653 if (node->u.variant.name)
654 fprintf(fd, " name=\"%s\"", node->u.variant.name);
655 if (node->u.variant.choice)
656 fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
657 fprintf(fd, ">\n");
658 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
659 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
660 if (ret)
661 return ret;
662 }
663 print_tabs(fd, depth);
664 fprintf(fd, "</variant>\n");
665 break;
666 case NODE_STRUCT:
667 print_tabs(fd, depth);
668 if (node->u._struct.name)
669 fprintf(fd, "<struct name=\"%s\">\n",
670 node->u._struct.name);
671 else
672 fprintf(fd, "<struct>\n");
673 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
674 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
675 if (ret)
676 return ret;
677 }
678 print_tabs(fd, depth);
679 fprintf(fd, "</struct>\n");
680 break;
681
682 case NODE_UNKNOWN:
683 default:
684 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
685 (int) node->type);
686 return -EINVAL;
687 }
688 return ret;
689 }
This page took 0.069152 seconds and 4 git commands to generate.