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