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