Dynamic definition scope hierarchy
[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_dynamic_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 event->context_decl = container_of(declaration, struct declaration_struct, p);
406 } else if (!strcmp(left, "fields")) {
407 struct declaration *declaration;
408
409 if (!event->definition_scope)
410 return -EPERM;
411 declaration = ctf_declaration_specifier_visit(fd, depth,
412 &node->u.ctf_expression.right,
413 event->declaration_scope);
414 if (!declaration)
415 return -EPERM;
416 if (declaration->type->id != CTF_TYPE_STRUCT)
417 return -EPERM;
418 event->fields_decl = container_of(declaration, struct declaration_struct, p);
419 }
420 free(left);
421 break;
422 }
423 default:
424 return -EPERM;
425 /* TODO: declaration specifier should be added. */
426 }
427
428 return 0;
429 }
430
431 static
432 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
433 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
434 {
435 int ret = 0;
436 struct ctf_node *iter;
437 struct ctf_event *event;
438 struct definition_scope *parent_def_scope;
439
440 event = g_new0(struct ctf_event, 1);
441 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
442 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
443 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
444 if (ret)
445 goto error;
446 }
447 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
448 ret = -EPERM;
449 goto error;
450 }
451 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
452 ret = -EPERM;
453 goto error;
454 }
455 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
456 ret = -EPERM;
457 goto error;
458 }
459 if (event->stream->events_by_id->len <= event->id)
460 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
461 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
462 g_hash_table_insert(event->stream->event_quark_to_id,
463 (gpointer)(unsigned long) event->name,
464 &event->id);
465 parent_def_scope = event->definition_scope;
466 if (event->context_decl) {
467 event->context =
468 event->context_decl->definition_new(event->context_decl,
469 parent_def_scope,
470 g_quark_from_string("event.context"),
471 MAX_INT);
472 parent_def_scope = event->context->scope;
473 declaration_unref(event->context_decl);
474 }
475 if (event->fields_decl) {
476 event->fields =
477 event->fields_decl->definition_new(event->fields_decl,
478 parent_def_scope,
479 g_quark_from_string("event.fields"),
480 MAX_INT);
481 parent_def_scope = event->fields->scope;
482 declaration_unref(event->fields_decl);
483 }
484 return 0;
485
486 error:
487 declaration_unref(event->fields_decl);
488 declaration_unref(event->context_decl);
489 free_definition_scope(event->definition_scope);
490 free_declaration_scope(event->declaration_scope);
491 g_free(event);
492 return ret;
493 }
494
495
496 static
497 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
498 {
499 int ret = 0;
500
501 switch (node->type) {
502 case NODE_TYPEDEF:
503 ret = ctf_typedef_visit(fd, depth + 1,
504 &node->u._typedef.declaration_specifier,
505 &node->u._typedef.type_declarators,
506 stream->declaration_scope);
507 if (ret)
508 return ret;
509 break;
510 case NODE_TYPEALIAS:
511 ret = ctf_typealias_visit(fd, depth + 1,
512 &node->u.typealias.target, &node->u.typealias.alias
513 stream->declaration_scope);
514 if (ret)
515 return ret;
516 break;
517 case NODE_CTF_EXPRESSION:
518 {
519 char *left;
520
521 left = concatenate_unary_strings(&node->u.ctf_expression.left);
522 if (!strcmp(left, "stream_id")) {
523 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
524 return -EPERM;
525 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
526 if (ret) {
527 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
528 return -EINVAL;
529 }
530 CTF_EVENT_SET_FIELD(event, stream_id);
531 } else if (!strcmp(left, "event.header")) {
532 struct declaration *declaration;
533
534 declaration = ctf_declaration_specifier_visit(fd, depth,
535 &node->u.ctf_expression.right,
536 stream->declaration_scope, stream->definition_scope);
537 if (!declaration)
538 return -EPERM;
539 if (declaration->type->id != CTF_TYPE_STRUCT)
540 return -EPERM;
541 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
542 } else if (!strcmp(left, "event.context")) {
543 struct declaration *declaration;
544
545 declaration = ctf_declaration_specifier_visit(fd, depth,
546 &node->u.ctf_expression.right,
547 stream->declaration_scope);
548 if (!declaration)
549 return -EPERM;
550 if (declaration->type->id != CTF_TYPE_STRUCT)
551 return -EPERM;
552 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
553 } else if (!strcmp(left, "packet.context")) {
554 struct declaration *declaration;
555
556 declaration = ctf_declaration_specifier_visit(fd, depth,
557 &node->u.ctf_expression.right,
558 stream->declaration_scope);
559 if (!declaration)
560 return -EPERM;
561 if (declaration->type->id != CTF_TYPE_STRUCT)
562 return -EPERM;
563 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
564 }
565 free(left);
566 break;
567 }
568 default:
569 return -EPERM;
570 /* TODO: declaration specifier should be added. */
571 }
572
573 return 0;
574 }
575
576 static
577 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
578 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
579 {
580 int ret = 0;
581 struct ctf_node *iter;
582 struct ctf_stream *stream;
583 struct definition_scope *parent_def_scope;
584
585 stream = g_new0(struct ctf_stream, 1);
586 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
587 stream->definition_scope = new_dynamic_definition_scope(trace->definition_scope);
588 stream->events_by_id = g_ptr_array_new();
589 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
590 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
591 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
592 if (ret)
593 goto error;
594 }
595 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
596 ret = -EPERM;
597 goto error;
598 }
599 if (trace->streams->len <= stream->stream_id)
600 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
601 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
602
603 parent_def_scope = stream->definition_scope;
604 if (stream->packet_context_decl) {
605 stream->packet_context =
606 stream->packet_context_decl->definition_new(stream->packet_context_decl,
607 parent_def_scope,
608 g_quark_from_string("stream.packet.context"),
609 MAX_INT);
610 parent_def_scope = stream->packet_context->scope;
611 declaration_unref(stream->packet_context_decl);
612 }
613 if (stream->event_header_decl) {
614 stream->event_header =
615 stream->event_header_decl->definition_new(stream->event_header_decl,
616 parent_def_scope,
617 g_quark_from_string("stream.event.header"),
618 MAX_INT);
619 parent_def_scope = stream->event_header->scope;
620 declaration_unref(stream->event_header_decl);
621 }
622 if (stream->event_context_decl) {
623 stream->event_context =
624 stream->event_context_decl->definition_new(stream->event_context_decl,
625 parent_def_scope,
626 g_quark_from_string("stream.event.context"),
627 MAX_INT);
628 parent_def_scope = stream->event_context->scope;
629 declaration_unref(stream->event_context_decl);
630 }
631
632 return 0;
633
634 error:
635 declaration_unref(stream->event_header);
636 declaration_unref(stream->event_context);
637 declaration_unref(stream->packet_context);
638 g_ptr_array_free(stream->events_by_id, TRUE);
639 g_hash_table_free(stream->event_quark_to_id);
640 free_definition_scope(stream->definition_scope);
641 free_declaration_scope(stream->declaration_scope);
642 g_free(stream);
643 return ret;
644 }
645
646 static
647 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
648 {
649 int ret = 0;
650
651 switch (node->type) {
652 case NODE_TYPEDEF:
653 ret = ctf_typedef_visit(fd, depth + 1,
654 &node->u._typedef.declaration_specifier,
655 &node->u._typedef.type_declarators,
656 trace->declaration_scope);
657 if (ret)
658 return ret;
659 break;
660 case NODE_TYPEALIAS:
661 ret = ctf_typealias_visit(fd, depth + 1,
662 &node->u.typealias.target, &node->u.typealias.alias
663 trace->declaration_scope);
664 if (ret)
665 return ret;
666 break;
667 case NODE_CTF_EXPRESSION:
668 {
669 char *left;
670
671 left = concatenate_unary_strings(&node->u.ctf_expression.left);
672 if (!strcmp(left, "major")) {
673 if (CTF_EVENT_FIELD_IS_SET(trace, major))
674 return -EPERM;
675 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
676 if (ret) {
677 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
678 return -EINVAL;
679 }
680 CTF_EVENT_SET_FIELD(trace, major);
681 } else if (!strcmp(left, "minor")) {
682 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
683 return -EPERM;
684 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
685 if (ret) {
686 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
687 return -EINVAL;
688 }
689 CTF_EVENT_SET_FIELD(trace, minor);
690 } else if (!strcmp(left, "word_size")) {
691 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
692 return -EPERM;
693 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
694 if (ret) {
695 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
696 return -EINVAL;
697 }
698 CTF_EVENT_SET_FIELD(trace, word_size);
699 } else if (!strcmp(left, "uuid")) {
700 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
701 return -EPERM;
702 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
703 if (ret) {
704 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
705 return -EINVAL;
706 }
707 CTF_EVENT_SET_FIELD(trace, uuid);
708 }
709 free(left);
710 break;
711 }
712 default:
713 return -EPERM;
714 /* TODO: declaration specifier should be added. */
715 }
716
717 return 0;
718 }
719
720
721 static
722 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
723 {
724 int ret = 0;
725 struct ctf_node *iter;
726
727 if (trace->declaration_scope)
728 return -EEXIST;
729 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
730 trace->definition_scope = new_dynamic_definition_scope(trace->root_definition_scope);
731 trace->streams = g_ptr_array_new();
732 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
733 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
734 if (ret)
735 goto error;
736 }
737 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
738 ret = -EPERM;
739 goto error;
740 }
741 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
742 ret = -EPERM;
743 goto error;
744 }
745 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
746 ret = -EPERM;
747 goto error;
748 }
749 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
750 ret = -EPERM;
751 goto error;
752 }
753 return 0;
754
755 error:
756 g_ptr_array_free(trace->streams, TRUE);
757 free_definition_scope(stream->definition_scope);
758 free_declaration_scope(stream->declaration_scope);
759 return ret;
760 }
761
762 int _ctf_visitor(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
763 {
764 int ret = 0;
765 struct ctf_node *iter;
766
767 switch (node->type) {
768 case NODE_ROOT:
769 cds_list_for_each_entry(iter, &node->u.root._typedef,
770 siblings) {
771 ret = ctf_typedef_visit(fd, depth + 1,
772 &iter->u._typedef.declaration_specifier,
773 &iter->u._typedef.type_declarators,
774 trace->declaration_scope);
775 if (ret)
776 return ret;
777 }
778 cds_list_for_each_entry(iter, &node->u.root.typealias,
779 siblings) {
780 ret = ctf_typealias_visit(fd, depth + 1,
781 &iter->u.typealias.target, &iter->u.typealias.alias
782 trace->declaration_scope);
783 if (ret)
784 return ret;
785 }
786 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
787 ret = ctf_declaration_specifier_visit(fd, depth, iter,
788 trace->root_declaration_scope);
789 if (ret)
790 return ret;
791 }
792 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
793 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
794 if (ret)
795 return ret;
796 }
797 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
798 ret = ctf_stream_visit(fd, depth + 1, iter,
799 trace->declaration_scope, trace);
800 if (ret)
801 return ret;
802 }
803 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
804 ret = ctf_event_visit(fd, depth + 1, iter,
805 trace->declaration_scope, trace);
806 if (ret)
807 return ret;
808 }
809 break;
810
811 case NODE_TYPEALIAS_TARGET:
812 print_tabs(fd, depth);
813 fprintf(fd, "<target>\n");
814 depth++;
815
816 print_tabs(fd, depth);
817 fprintf(fd, "<declaration_specifier>\n");
818 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
819 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
820 if (ret)
821 return ret;
822 }
823 print_tabs(fd, depth);
824 fprintf(fd, "</declaration_specifier>\n");
825
826 print_tabs(fd, depth);
827 fprintf(fd, "<type_declarators>\n");
828 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
829 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
830 if (ret)
831 return ret;
832 }
833 print_tabs(fd, depth);
834 fprintf(fd, "</type_declarators>\n");
835
836 depth--;
837 print_tabs(fd, depth);
838 fprintf(fd, "</target>\n");
839 break;
840 case NODE_TYPEALIAS_ALIAS:
841 print_tabs(fd, depth);
842 fprintf(fd, "<alias>\n");
843 depth++;
844
845 print_tabs(fd, depth);
846 fprintf(fd, "<declaration_specifier>\n");
847 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
848 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
849 if (ret)
850 return ret;
851 }
852 print_tabs(fd, depth);
853 fprintf(fd, "</declaration_specifier>\n");
854
855 print_tabs(fd, depth);
856 fprintf(fd, "<type_declarators>\n");
857 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, 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, "</type_declarators>\n");
864
865 depth--;
866 print_tabs(fd, depth);
867 fprintf(fd, "</alias>\n");
868 break;
869 case NODE_TYPEALIAS:
870 print_tabs(fd, depth);
871 fprintf(fd, "<typealias>\n");
872 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
873 if (ret)
874 return ret;
875 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
876 if (ret)
877 return ret;
878 print_tabs(fd, depth);
879 fprintf(fd, "</typealias>\n");
880 break;
881
882 case NODE_TYPE_SPECIFIER:
883 ret = ctf_visitor_print_type_specifier(fd, depth, node);
884 if (ret)
885 return ret;
886 break;
887 case NODE_POINTER:
888 print_tabs(fd, depth);
889 if (node->u.pointer.const_qualifier)
890 fprintf(fd, "<const_pointer />\n");
891 else
892 fprintf(fd, "<pointer />\n");
893 break;
894 case NODE_TYPE_DECLARATOR:
895 ret = ctf_visitor_print_type_declarator(fd, depth, node);
896 if (ret)
897 return ret;
898 break;
899
900 case NODE_FLOATING_POINT:
901 print_tabs(fd, depth);
902 fprintf(fd, "<floating_point>\n");
903 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
904 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
905 if (ret)
906 return ret;
907 }
908 print_tabs(fd, depth);
909 fprintf(fd, "</floating_point>\n");
910 break;
911 case NODE_INTEGER:
912 print_tabs(fd, depth);
913 fprintf(fd, "<integer>\n");
914 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
915 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
916 if (ret)
917 return ret;
918 }
919 print_tabs(fd, depth);
920 fprintf(fd, "</integer>\n");
921 break;
922 case NODE_STRING:
923 print_tabs(fd, depth);
924 fprintf(fd, "<string>\n");
925 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
926 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
927 if (ret)
928 return ret;
929 }
930 print_tabs(fd, depth);
931 fprintf(fd, "</string>\n");
932 break;
933 case NODE_ENUMERATOR:
934 print_tabs(fd, depth);
935 fprintf(fd, "<enumerator");
936 if (node->u.enumerator.id)
937 fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
938 fprintf(fd, ">\n");
939 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
940 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
941 if (ret)
942 return ret;
943 }
944 print_tabs(fd, depth);
945 fprintf(fd, "</enumerator>\n");
946 break;
947 case NODE_ENUM:
948 print_tabs(fd, depth);
949 if (node->u._struct.name)
950 fprintf(fd, "<enum name=\"%s\">\n",
951 node->u._enum.enum_id);
952 else
953 fprintf(fd, "<enum >\n");
954 depth++;
955
956 if (node->u._enum.container_type) {
957 print_tabs(fd, depth);
958 fprintf(fd, "<container_type>\n");
959 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
960 if (ret)
961 return ret;
962 print_tabs(fd, depth);
963 fprintf(fd, "</container_type>\n");
964 }
965
966 print_tabs(fd, depth);
967 fprintf(fd, "<enumerator_list>\n");
968 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
969 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
970 if (ret)
971 return ret;
972 }
973 print_tabs(fd, depth);
974 fprintf(fd, "</enumerator_list>\n");
975
976 depth--;
977 print_tabs(fd, depth);
978 fprintf(fd, "</enum>\n");
979 break;
980 case NODE_STRUCT_OR_VARIANT_DECLARATION:
981 print_tabs(fd, depth);
982 fprintf(fd, "<declaration_specifier>\n");
983 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
984 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
985 if (ret)
986 return ret;
987 }
988 print_tabs(fd, depth);
989 fprintf(fd, "</declaration_specifier>\n");
990
991 print_tabs(fd, depth);
992 fprintf(fd, "<type_declarators>\n");
993 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
994 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
995 if (ret)
996 return ret;
997 }
998 print_tabs(fd, depth);
999 fprintf(fd, "</type_declarators>\n");
1000 break;
1001 case NODE_VARIANT:
1002 print_tabs(fd, depth);
1003 fprintf(fd, "<variant");
1004 if (node->u.variant.name)
1005 fprintf(fd, " name=\"%s\"", node->u.variant.name);
1006 if (node->u.variant.choice)
1007 fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
1008 fprintf(fd, ">\n");
1009 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
1010 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1011 if (ret)
1012 return ret;
1013 }
1014 print_tabs(fd, depth);
1015 fprintf(fd, "</variant>\n");
1016 break;
1017 case NODE_STRUCT:
1018 print_tabs(fd, depth);
1019 if (node->u._struct.name)
1020 fprintf(fd, "<struct name=\"%s\">\n",
1021 node->u._struct.name);
1022 else
1023 fprintf(fd, "<struct>\n");
1024 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
1025 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
1026 if (ret)
1027 return ret;
1028 }
1029 print_tabs(fd, depth);
1030 fprintf(fd, "</struct>\n");
1031 break;
1032
1033 case NODE_UNKNOWN:
1034 default:
1035 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
1036 (int) node->type);
1037 return -EINVAL;
1038 }
1039 return ret;
1040 }
This page took 0.088326 seconds and 4 git commands to generate.