Generate IO struct visitor adapt to def/declaration
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
1 /*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
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/list.h>
28 #include "ctf-scanner.h"
29 #include "ctf-parser.h"
30 #include "ctf-ast.h"
31
32 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
33
34 #define _cds_list_first_entry(ptr, type, member) \
35 cds_list_entry((ptr)->next, type, member)
36
37 static
38 int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
39 {
40 print_tabs(fd, depth);
41 fprintf(fd, "<type_specifier \"");
42
43 switch (node->u.type_specifier.type) {
44 case TYPESPEC_VOID:
45 fprintf(fd, "void");
46 break;
47 case TYPESPEC_CHAR:
48 fprintf(fd, "char");
49 break;
50 case TYPESPEC_SHORT:
51 fprintf(fd, "short");
52 break;
53 case TYPESPEC_INT:
54 fprintf(fd, "int");
55 break;
56 case TYPESPEC_LONG:
57 fprintf(fd, "long");
58 break;
59 case TYPESPEC_FLOAT:
60 fprintf(fd, "float");
61 break;
62 case TYPESPEC_DOUBLE:
63 fprintf(fd, "double");
64 break;
65 case TYPESPEC_SIGNED:
66 fprintf(fd, "signed");
67 break;
68 case TYPESPEC_UNSIGNED:
69 fprintf(fd, "unsigned");
70 break;
71 case TYPESPEC_BOOL:
72 fprintf(fd, "bool");
73 break;
74 case TYPESPEC_COMPLEX:
75 fprintf(fd, "complex");
76 break;
77 case TYPESPEC_CONST:
78 fprintf(fd, "const");
79 break;
80 case TYPESPEC_ID_TYPE:
81 fprintf(fd, "%s", node->u.type_specifier.id_type);
82 break;
83
84 case TYPESPEC_UNKNOWN:
85 default:
86 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
87 (int) node->u.type_specifier.type);
88 return -EINVAL;
89 }
90 fprintf(fd, "\"/>\n");
91 return 0;
92 }
93
94 static
95 int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
96 {
97 int ret = 0;
98 struct ctf_node *iter;
99
100 print_tabs(fd, depth);
101 fprintf(fd, "<type_declarator>\n");
102 depth++;
103
104 if (!cds_list_empty(&node->u.type_declarator.pointers)) {
105 print_tabs(fd, depth);
106 fprintf(fd, "<pointers>\n");
107 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
108 siblings) {
109 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
110 if (ret)
111 return ret;
112 }
113 print_tabs(fd, depth);
114 fprintf(fd, "</pointers>\n");
115 }
116
117 switch (node->u.type_declarator.type) {
118 case TYPEDEC_ID:
119 if (node->u.type_declarator.u.id) {
120 print_tabs(fd, depth);
121 fprintf(fd, "<id \"");
122 fprintf(fd, "%s", node->u.type_declarator.u.id);
123 fprintf(fd, "\" />\n");
124 }
125 break;
126 case TYPEDEC_NESTED:
127 if (node->u.type_declarator.u.nested.type_declarator) {
128 print_tabs(fd, depth);
129 fprintf(fd, "<type_declarator>\n");
130 ret = ctf_visitor_print_xml(fd, depth + 1,
131 node->u.type_declarator.u.nested.type_declarator);
132 if (ret)
133 return ret;
134 print_tabs(fd, depth);
135 fprintf(fd, "</type_declarator>\n");
136 }
137 if (node->u.type_declarator.u.nested.length) {
138 print_tabs(fd, depth);
139 fprintf(fd, "<length>\n");
140 ret = ctf_visitor_print_xml(fd, depth + 1,
141 node->u.type_declarator.u.nested.length);
142 if (ret)
143 return ret;
144 print_tabs(fd, depth);
145 fprintf(fd, "</length>\n");
146 }
147 if (node->u.type_declarator.u.nested.abstract_array) {
148 print_tabs(fd, depth);
149 fprintf(fd, "<length>\n");
150 print_tabs(fd, depth);
151 fprintf(fd, "</length>\n");
152 }
153 if (node->u.type_declarator.bitfield_len) {
154 print_tabs(fd, depth);
155 fprintf(fd, "<bitfield_len>\n");
156 ret = ctf_visitor_print_xml(fd, depth + 1,
157 node->u.type_declarator.bitfield_len);
158 if (ret)
159 return ret;
160 print_tabs(fd, depth);
161 fprintf(fd, "</bitfield_len>\n");
162 }
163 break;
164 case TYPEDEC_UNKNOWN:
165 default:
166 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
167 (int) node->u.type_declarator.type);
168 return -EINVAL;
169 }
170
171 depth--;
172 print_tabs(fd, depth);
173 fprintf(fd, "</type_declarator>\n");
174 return 0;
175 }
176
177 /*
178 * String returned must be freed by the caller.
179 */
180 static
181 char *concatenate_unary_strings(struct list_head *head)
182 {
183
184 }
185
186 static
187 int get_unary_unsigned(struct list_head *head, uint64_t *value)
188 {
189
190 }
191
192 static
193 int get_unary_uuid(struct list_head *head, uuid_t *uuid)
194 {
195
196 }
197
198 static
199 struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
200 {
201 if (trace->streams->len <= stream_id)
202 return NULL;
203 return g_ptr_array_index(trace->streams, stream_id);
204 }
205
206 /*
207 * Also add named variant, struct or enum to the current declaration scope.
208 */
209 static
210 struct ctf_declaration *ctf_declaration_specifier_visit(FILE *fd,
211 int depth, struct list_head *head,
212 struct declaration_scope *declaration_scope)
213 {
214 struct ctf_declaration *declaration;
215 struct node *first;
216
217 first = _cds_list_first_entry(head, struct node, siblings);
218
219 switch (first->type) {
220 case NODE_STRUCT:
221 /*
222 * For named struct (without body), lookup in
223 * declaration scope and create declaration copy.
224 */
225 /* For named struct (with body), create type and add to declaration scope */
226 /* For unnamed struct, create type */
227 break;
228 case NODE_VARIANT:
229 /*
230 * For named variant (without body), lookup in
231 * declaration scope and create declaration copy.
232 */
233 /* For named variant (with body), create type and add to declaration scope */
234 /* For unnamed variant, create type */
235 /* If variant has a tag field specifier, assign tag name. */
236 break;
237 case NODE_ENUM:
238 /*
239 * For named enum (without body), lookup in declaration
240 * scope and create declaration copy.
241 */
242 /* For named enum (with body), create type and add to declaration scope */
243 /* For unnamed enum, create type */
244 /* Enumerations need to have their size/type specifier (< >). */
245 break;
246 case NODE_INTEGER:
247 /*
248 * Create an integer declaration.
249 */
250 break;
251 case NODE_FLOATING_POINT:
252 /*
253 * Create a floating point declaration.
254 */
255 break;
256 case NODE_STRING:
257 /*
258 * Create a string declaration.
259 */
260 break;
261 case NODE_TYPE_SPECIFIER:
262 /*
263 * Lookup named type in typedef declarations (in
264 * declaration scope). Create a copy of the declaration.
265 */
266 break;
267
268 }
269 }
270
271 static
272 int ctf_typedef_declarator_visit(FILE *fd, int depth,
273 struct list_head *declaration_specifier,
274 struct node *type_declarator,
275 struct declaration_scope *declaration_scope)
276 {
277 /*
278 * Build the type using declaration specifier (creating
279 * declaration from type_specifier), then apply type declarator,
280 * add the resulting type to the current declaration scope.
281 */
282 cds_list_for_each_entry(iter, declaration_specifier, siblings) {
283
284
285 }
286 return 0;
287 }
288
289 static
290 int ctf_typedef_visit(FILE *fd, int depth,
291 struct list_head *declaration_specifier,
292 struct list_head *type_declarators,
293 struct declaration_scope *declaration_scope)
294 {
295 struct ctf_node *iter;
296
297 cds_list_for_each_entry(iter, type_declarators, siblings) {
298 ret = ctf_typedef_declarator_visit(fd, depth + 1,
299 &node->u._typedef.declaration_specifier, iter,
300 declaration_scope);
301 if (ret)
302 return ret;
303 }
304 return 0;
305 }
306
307 static
308 int ctf_typealias_visit(FILE *fd, int depth, struct ctf_node *target,
309 struct ctf_node *alias,
310 struct declaration_scope *declaration_scope)
311 {
312 /*
313 * Build target type, check that it is reachable in current
314 * declaration scope.
315 */
316
317 /* Only one type declarator is allowed */
318
319 /* Build alias type, add to current declaration scope. */
320 /* Only one type declarator is allowed */
321 }
322
323 static
324 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
325 {
326 int ret = 0;
327
328 switch (node->type) {
329 case NODE_TYPEDEF:
330 ret = ctf_typedef_visit(fd, depth + 1,
331 &node->u._typedef.declaration_specifier,
332 &node->u._typedef.type_declarators,
333 event->declaration_scope);
334 if (ret)
335 return ret;
336 break;
337 case NODE_TYPEALIAS:
338 ret = ctf_typealias_visit(fd, depth + 1,
339 &node->u.typealias.target, &node->u.typealias.alias
340 event->declaration_scope);
341 if (ret)
342 return ret;
343 break;
344 case NODE_CTF_EXPRESSION:
345 {
346 char *left;
347
348 left = concatenate_unary_strings(&node->u.ctf_expression.left);
349 if (!strcmp(left, "name")) {
350 char *right;
351
352 if (CTF_EVENT_FIELD_IS_SET(event, name))
353 return -EPERM;
354 right = concatenate_unary_strings(&node->u.ctf_expression.right);
355 if (!right) {
356 fprintf(stderr, "[error] %s: unexpected unary expression for event name\n", __func__);
357 return -EINVAL;
358 }
359 event->name = g_quark_from_string(right);
360 free(right);
361 CTF_EVENT_SET_FIELD(event, name);
362 } else if (!strcmp(left, "id")) {
363 if (CTF_EVENT_FIELD_IS_SET(event, id))
364 return -EPERM;
365 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
366 if (ret) {
367 fprintf(stderr, "[error] %s: unexpected unary expression for event id\n", __func__);
368 return -EINVAL;
369 }
370 CTF_EVENT_SET_FIELD(event, id);
371 } else if (!strcmp(left, "stream_id")) {
372 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
373 return -EPERM;
374 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
375 if (ret) {
376 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
377 return -EINVAL;
378 }
379 event->stream = trace_stream_lookup(trace, event->stream_id);
380 if (!event->stream) {
381 fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
382 return -EINVAL;
383 }
384 event->definition_scope = new_definition_scope(stream->definition_scope);
385 if (!event->definition_scope) {
386 fprintf(stderr, "[error] %s: Error allocating declaration scope\n", __func__);
387 return -EPERM;
388 }
389 CTF_EVENT_SET_FIELD(event, stream_id);
390 } else if (!strcmp(left, "context")) {
391 struct declaration *declaration;
392
393 if (!event->definition_scope)
394 return -EPERM;
395 declaration = ctf_declaration_specifier_visit(fd, depth,
396 &node->u.ctf_expression.right,
397 event->declaration_scope);
398 if (!declaration)
399 return -EPERM;
400 if (declaration->type->id != CTF_TYPE_STRUCT)
401 return -EPERM;
402 /* TODO: definition */
403 event->context = container_of(declaration, struct declaration_struct, p);
404 } else if (!strcmp(left, "fields")) {
405 struct declaration *declaration;
406
407 if (!event->definition_scope)
408 return -EPERM;
409 declaration = ctf_declaration_specifier_visit(fd, depth,
410 &node->u.ctf_expression.right,
411 event->declaration_scope);
412 if (!declaration)
413 return -EPERM;
414 if (declaration->type->id != CTF_TYPE_STRUCT)
415 return -EPERM;
416 /* TODO: definition */
417 event->fields = container_of(declaration, struct declaration_struct, p);
418 }
419 free(left);
420 break;
421 }
422 default:
423 return -EPERM;
424 /* TODO: declaration specifier should be added. */
425 }
426
427 return 0;
428 }
429
430 static
431 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
432 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
433 {
434 int ret = 0;
435 struct ctf_node *iter;
436 struct ctf_event *event;
437
438 event = g_new0(struct ctf_event, 1);
439 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
440 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
441 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
442 if (ret)
443 goto error;
444 }
445 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
446 ret = -EPERM;
447 goto error;
448 }
449 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
450 ret = -EPERM;
451 goto error;
452 }
453 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
454 ret = -EPERM;
455 goto error;
456 }
457 if (event->stream->events_by_id->len <= event->id)
458 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
459 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
460 g_hash_table_insert(event->stream->event_quark_to_id,
461 (gpointer)(unsigned long) event->name,
462 &event->id);
463 return 0;
464
465 error:
466 declaration_unref(event->fields);
467 declaration_unref(event->context);
468 free_definition_scope(event->definition_scope);
469 free_declaration_scope(event->declaration_scope);
470 g_free(event);
471 return ret;
472 }
473
474
475 static
476 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
477 {
478 int ret = 0;
479
480 switch (node->type) {
481 case NODE_TYPEDEF:
482 ret = ctf_typedef_visit(fd, depth + 1,
483 &node->u._typedef.declaration_specifier,
484 &node->u._typedef.type_declarators,
485 stream->declaration_scope);
486 if (ret)
487 return ret;
488 break;
489 case NODE_TYPEALIAS:
490 ret = ctf_typealias_visit(fd, depth + 1,
491 &node->u.typealias.target, &node->u.typealias.alias
492 stream->declaration_scope);
493 if (ret)
494 return ret;
495 break;
496 case NODE_CTF_EXPRESSION:
497 {
498 char *left;
499
500 left = concatenate_unary_strings(&node->u.ctf_expression.left);
501 if (!strcmp(left, "stream_id")) {
502 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
503 return -EPERM;
504 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
505 if (ret) {
506 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
507 return -EINVAL;
508 }
509 CTF_EVENT_SET_FIELD(event, stream_id);
510 } else if (!strcmp(left, "event_header")) {
511 struct declaration *declaration;
512
513 declaration = ctf_declaration_specifier_visit(fd, depth,
514 &node->u.ctf_expression.right,
515 stream->declaration_scope, stream->definition_scope);
516 if (!declaration)
517 return -EPERM;
518 if (declaration->type->id != CTF_TYPE_STRUCT)
519 return -EPERM;
520 /* TODO: definition */
521 stream->event_header = container_of(declaration, struct declaration_struct, p);
522 } else if (!strcmp(left, "event_context")) {
523 struct declaration *declaration;
524
525 declaration = ctf_declaration_specifier_visit(fd, depth,
526 &node->u.ctf_expression.right,
527 stream->declaration_scope);
528 if (!declaration)
529 return -EPERM;
530 if (declaration->type->id != CTF_TYPE_STRUCT)
531 return -EPERM;
532 /* TODO: definition */
533 stream->event_context = container_of(declaration, struct declaration_struct, p);
534 } else if (!strcmp(left, "packet_context")) {
535 struct declaration *declaration;
536
537 declaration = ctf_declaration_specifier_visit(fd, depth,
538 &node->u.ctf_expression.right,
539 stream->declaration_scope);
540 if (!declaration)
541 return -EPERM;
542 if (declaration->type->id != CTF_TYPE_STRUCT)
543 return -EPERM;
544 /* TODO: definition */
545 stream->packet_context = container_of(declaration, struct declaration_struct, p);
546 }
547 free(left);
548 break;
549 }
550 default:
551 return -EPERM;
552 /* TODO: declaration specifier should be added. */
553 }
554
555 return 0;
556 }
557
558 static
559 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
560 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
561 {
562 int ret = 0;
563 struct ctf_node *iter;
564 struct ctf_stream *stream;
565
566 stream = g_new0(struct ctf_stream, 1);
567 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
568 stream->definition_scope = new_definition_scope(trace->definition_scope);
569 stream->events_by_id = g_ptr_array_new();
570 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
571 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
572 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
573 if (ret)
574 goto error;
575 }
576 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
577 ret = -EPERM;
578 goto error;
579 }
580 if (trace->streams->len <= stream->stream_id)
581 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
582 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
583 return 0;
584
585 error:
586 declaration_unref(stream->event_header);
587 declaration_unref(stream->event_context);
588 declaration_unref(stream->packet_context);
589 g_ptr_array_free(stream->events_by_id, TRUE);
590 g_hash_table_free(stream->event_quark_to_id);
591 free_definition_scope(stream->definition_scope);
592 free_declaration_scope(stream->declaration_scope);
593 g_free(stream);
594 return ret;
595 }
596
597 static
598 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
599 {
600 int ret = 0;
601
602 switch (node->type) {
603 case NODE_TYPEDEF:
604 ret = ctf_typedef_visit(fd, depth + 1,
605 &node->u._typedef.declaration_specifier,
606 &node->u._typedef.type_declarators,
607 trace->declaration_scope);
608 if (ret)
609 return ret;
610 break;
611 case NODE_TYPEALIAS:
612 ret = ctf_typealias_visit(fd, depth + 1,
613 &node->u.typealias.target, &node->u.typealias.alias
614 trace->declaration_scope);
615 if (ret)
616 return ret;
617 break;
618 case NODE_CTF_EXPRESSION:
619 {
620 char *left;
621
622 left = concatenate_unary_strings(&node->u.ctf_expression.left);
623 if (!strcmp(left, "major")) {
624 if (CTF_EVENT_FIELD_IS_SET(trace, major))
625 return -EPERM;
626 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
627 if (ret) {
628 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
629 return -EINVAL;
630 }
631 CTF_EVENT_SET_FIELD(trace, major);
632 } else if (!strcmp(left, "minor")) {
633 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
634 return -EPERM;
635 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
636 if (ret) {
637 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
638 return -EINVAL;
639 }
640 CTF_EVENT_SET_FIELD(trace, minor);
641 } else if (!strcmp(left, "word_size")) {
642 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
643 return -EPERM;
644 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
645 if (ret) {
646 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
647 return -EINVAL;
648 }
649 CTF_EVENT_SET_FIELD(trace, word_size);
650 } else if (!strcmp(left, "uuid")) {
651 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
652 return -EPERM;
653 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
654 if (ret) {
655 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
656 return -EINVAL;
657 }
658 CTF_EVENT_SET_FIELD(trace, uuid);
659 }
660 free(left);
661 break;
662 }
663 default:
664 return -EPERM;
665 /* TODO: declaration specifier should be added. */
666 }
667
668 return 0;
669 }
670
671
672 static
673 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
674 {
675 int ret = 0;
676 struct ctf_node *iter;
677
678 if (trace->declaration_scope)
679 return -EEXIST;
680 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
681 trace->definition_scope = new_definition_scope(trace->root_definition_scope);
682 trace->streams = g_ptr_array_new();
683 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
684 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
685 if (ret)
686 goto error;
687 }
688 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
689 ret = -EPERM;
690 goto error;
691 }
692 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
693 ret = -EPERM;
694 goto error;
695 }
696 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
697 ret = -EPERM;
698 goto error;
699 }
700 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
701 ret = -EPERM;
702 goto error;
703 }
704 return 0;
705
706 error:
707 g_ptr_array_free(trace->streams, TRUE);
708 free_definition_scope(stream->definition_scope);
709 free_declaration_scope(stream->declaration_scope);
710 return ret;
711 }
712
713 int _ctf_visitor(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
714 {
715 int ret = 0;
716 struct ctf_node *iter;
717
718 switch (node->type) {
719 case NODE_ROOT:
720 cds_list_for_each_entry(iter, &node->u.root._typedef,
721 siblings) {
722 ret = ctf_typedef_visit(fd, depth + 1,
723 &iter->u._typedef.declaration_specifier,
724 &iter->u._typedef.type_declarators,
725 trace->declaration_scope);
726 if (ret)
727 return ret;
728 }
729 cds_list_for_each_entry(iter, &node->u.root.typealias,
730 siblings) {
731 ret = ctf_typealias_visit(fd, depth + 1,
732 &iter->u.typealias.target, &iter->u.typealias.alias
733 trace->declaration_scope);
734 if (ret)
735 return ret;
736 }
737 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
738 ret = ctf_declaration_specifier_visit(fd, depth, iter,
739 trace->root_declaration_scope);
740 if (ret)
741 return ret;
742 }
743 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
744 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
745 if (ret)
746 return ret;
747 }
748 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
749 ret = ctf_stream_visit(fd, depth + 1, iter,
750 trace->declaration_scope, trace);
751 if (ret)
752 return ret;
753 }
754 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
755 ret = ctf_event_visit(fd, depth + 1, iter,
756 trace->declaration_scope, trace);
757 if (ret)
758 return ret;
759 }
760 break;
761
762 case NODE_TYPEALIAS_TARGET:
763 print_tabs(fd, depth);
764 fprintf(fd, "<target>\n");
765 depth++;
766
767 print_tabs(fd, depth);
768 fprintf(fd, "<declaration_specifier>\n");
769 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
770 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
771 if (ret)
772 return ret;
773 }
774 print_tabs(fd, depth);
775 fprintf(fd, "</declaration_specifier>\n");
776
777 print_tabs(fd, depth);
778 fprintf(fd, "<type_declarators>\n");
779 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
780 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
781 if (ret)
782 return ret;
783 }
784 print_tabs(fd, depth);
785 fprintf(fd, "</type_declarators>\n");
786
787 depth--;
788 print_tabs(fd, depth);
789 fprintf(fd, "</target>\n");
790 break;
791 case NODE_TYPEALIAS_ALIAS:
792 print_tabs(fd, depth);
793 fprintf(fd, "<alias>\n");
794 depth++;
795
796 print_tabs(fd, depth);
797 fprintf(fd, "<declaration_specifier>\n");
798 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
799 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
800 if (ret)
801 return ret;
802 }
803 print_tabs(fd, depth);
804 fprintf(fd, "</declaration_specifier>\n");
805
806 print_tabs(fd, depth);
807 fprintf(fd, "<type_declarators>\n");
808 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
809 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
810 if (ret)
811 return ret;
812 }
813 print_tabs(fd, depth);
814 fprintf(fd, "</type_declarators>\n");
815
816 depth--;
817 print_tabs(fd, depth);
818 fprintf(fd, "</alias>\n");
819 break;
820 case NODE_TYPEALIAS:
821 print_tabs(fd, depth);
822 fprintf(fd, "<typealias>\n");
823 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
824 if (ret)
825 return ret;
826 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
827 if (ret)
828 return ret;
829 print_tabs(fd, depth);
830 fprintf(fd, "</typealias>\n");
831 break;
832
833 case NODE_TYPE_SPECIFIER:
834 ret = ctf_visitor_print_type_specifier(fd, depth, node);
835 if (ret)
836 return ret;
837 break;
838 case NODE_POINTER:
839 print_tabs(fd, depth);
840 if (node->u.pointer.const_qualifier)
841 fprintf(fd, "<const_pointer />\n");
842 else
843 fprintf(fd, "<pointer />\n");
844 break;
845 case NODE_TYPE_DECLARATOR:
846 ret = ctf_visitor_print_type_declarator(fd, depth, node);
847 if (ret)
848 return ret;
849 break;
850
851 case NODE_FLOATING_POINT:
852 print_tabs(fd, depth);
853 fprintf(fd, "<floating_point>\n");
854 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
855 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
856 if (ret)
857 return ret;
858 }
859 print_tabs(fd, depth);
860 fprintf(fd, "</floating_point>\n");
861 break;
862 case NODE_INTEGER:
863 print_tabs(fd, depth);
864 fprintf(fd, "<integer>\n");
865 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
866 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
867 if (ret)
868 return ret;
869 }
870 print_tabs(fd, depth);
871 fprintf(fd, "</integer>\n");
872 break;
873 case NODE_STRING:
874 print_tabs(fd, depth);
875 fprintf(fd, "<string>\n");
876 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
877 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
878 if (ret)
879 return ret;
880 }
881 print_tabs(fd, depth);
882 fprintf(fd, "</string>\n");
883 break;
884 case NODE_ENUMERATOR:
885 print_tabs(fd, depth);
886 fprintf(fd, "<enumerator");
887 if (node->u.enumerator.id)
888 fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
889 fprintf(fd, ">\n");
890 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
891 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
892 if (ret)
893 return ret;
894 }
895 print_tabs(fd, depth);
896 fprintf(fd, "</enumerator>\n");
897 break;
898 case NODE_ENUM:
899 print_tabs(fd, depth);
900 if (node->u._struct.name)
901 fprintf(fd, "<enum name=\"%s\">\n",
902 node->u._enum.enum_id);
903 else
904 fprintf(fd, "<enum >\n");
905 depth++;
906
907 if (node->u._enum.container_type) {
908 print_tabs(fd, depth);
909 fprintf(fd, "<container_type>\n");
910 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
911 if (ret)
912 return ret;
913 print_tabs(fd, depth);
914 fprintf(fd, "</container_type>\n");
915 }
916
917 print_tabs(fd, depth);
918 fprintf(fd, "<enumerator_list>\n");
919 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
920 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
921 if (ret)
922 return ret;
923 }
924 print_tabs(fd, depth);
925 fprintf(fd, "</enumerator_list>\n");
926
927 depth--;
928 print_tabs(fd, depth);
929 fprintf(fd, "</enum>\n");
930 break;
931 case NODE_STRUCT_OR_VARIANT_DECLARATION:
932 print_tabs(fd, depth);
933 fprintf(fd, "<declaration_specifier>\n");
934 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
935 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
936 if (ret)
937 return ret;
938 }
939 print_tabs(fd, depth);
940 fprintf(fd, "</declaration_specifier>\n");
941
942 print_tabs(fd, depth);
943 fprintf(fd, "<type_declarators>\n");
944 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
945 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
946 if (ret)
947 return ret;
948 }
949 print_tabs(fd, depth);
950 fprintf(fd, "</type_declarators>\n");
951 break;
952 case NODE_VARIANT:
953 print_tabs(fd, depth);
954 fprintf(fd, "<variant");
955 if (node->u.variant.name)
956 fprintf(fd, " name=\"%s\"", node->u.variant.name);
957 if (node->u.variant.choice)
958 fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
959 fprintf(fd, ">\n");
960 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
961 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
962 if (ret)
963 return ret;
964 }
965 print_tabs(fd, depth);
966 fprintf(fd, "</variant>\n");
967 break;
968 case NODE_STRUCT:
969 print_tabs(fd, depth);
970 if (node->u._struct.name)
971 fprintf(fd, "<struct name=\"%s\">\n",
972 node->u._struct.name);
973 else
974 fprintf(fd, "<struct>\n");
975 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
976 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
977 if (ret)
978 return ret;
979 }
980 print_tabs(fd, depth);
981 fprintf(fd, "</struct>\n");
982 break;
983
984 case NODE_UNKNOWN:
985 default:
986 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
987 (int) node->type);
988 return -EINVAL;
989 }
990 return ret;
991 }
This page took 0.086861 seconds and 5 git commands to generate.