Remove unneeded declaration "name", work in progress for gen io struct
[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>
add40b62 26#include <endian.h>
05628561
MD
27#include <errno.h>
28#include <babeltrace/list.h>
41253107 29#include <uuid/uuid.h>
05628561
MD
30#include "ctf-scanner.h"
31#include "ctf-parser.h"
32#include "ctf-ast.h"
33
34#define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
35
de47353a
MD
36#define _cds_list_first_entry(ptr, type, member) \
37 cds_list_entry((ptr)->next, type, member)
05628561 38
a3cca9e9
MD
39static
40struct declaration *ctf_declaration_specifier_visit(FILE *fd,
add40b62 41 int depth, struct cds_list_head *head,
ab4cf058
MD
42 struct declaration_scope *declaration_scope,
43 struct ctf_trace *trace);
a3cca9e9 44
05628561 45/*
41253107 46 * String returned must be freed by the caller using g_free.
05628561
MD
47 */
48static
add40b62 49char *concatenate_unary_strings(struct cds_list_head *head)
05628561 50{
41253107
MD
51 struct ctf_node *node;
52 GString *str;
53 int i = 0;
54
55 str = g_string_new();
56 cds_list_for_each_entry(node, head, siblings) {
57 char *src_string;
58
59 assert(node->type == NODE_UNARY_EXPRESSION);
60 assert(node->u.unary_expression.type == UNARY_STRING);
61 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
62 ^ (i != 0))
63 switch (node->u.unary_expression.link) {
64 case UNARY_DOTLINK:
65 g_string_append(str, ".")
66 break;
67 case UNARY_ARROWLINK:
68 g_string_append(str, "->")
69 break;
70 case UNARY_DOTDOTDOT:
71 g_string_append(str, "...")
72 break;
73 }
74 src_string = u.unary_expression.u.string;
75 g_string_append(str, src_string);
76 i++;
77 }
78 return g_string_free(str, FALSE);
05628561
MD
79}
80
81static
add40b62 82int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
05628561 83{
41253107
MD
84 struct ctf_node *node;
85 int i = 0;
86
87 cds_list_for_each_entry(node, head, siblings) {
88 assert(node->type == NODE_UNARY_EXPRESSION);
89 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
90 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
91 assert(i == 0);
92 *value = node->u.unary_expression.unsigned_constant
93 i++;
94 }
95 return 0;
05628561
MD
96}
97
98static
add40b62 99int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
05628561 100{
41253107
MD
101 struct ctf_node *node;
102 int i = 0;
103 int ret = -1;
104
105 cds_list_for_each_entry(node, head, siblings) {
106 const char *src_string;
107
108 assert(node->type == NODE_UNARY_EXPRESSION);
109 assert(node->u.unary_expression.type == UNARY_STRING);
110 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
111 assert(i == 0);
112 src_string = u.unary_expression.u.string;
113 ret = uuid_parse(u.unary_expression.u.string, *uuid);
114 }
115 return ret;
05628561
MD
116}
117
118static
119struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
120{
121 if (trace->streams->len <= stream_id)
122 return NULL;
123 return g_ptr_array_index(trace->streams, stream_id);
124}
125
add40b62
MD
126static
127void visit_declaration_specifier(struct cds_list_head *declaration_specifier, GString *str)
128{
129 struct ctf_node *iter;
130 int alias_item_nr = 0;
131 int err;
132
133 cds_list_for_each_entry(iter, declaration_specifier, siblings) {
134 if (alias_item_nr != 0)
135 g_string_append(str, " ");
136 alias_item_nr++;
137
138 switch (iter->type) {
139 case NODE_TYPE_SPECIFIER:
140 switch (iter->u.type_specifier.type) {
141 case TYPESPEC_VOID:
142 g_string_append(str, "void");
143 break;
144 case TYPESPEC_CHAR:
145 g_string_append(str, "char");
146 break;
147 case TYPESPEC_SHORT:
148 g_string_append(str, "short");
149 break;
150 case TYPESPEC_INT:
151 g_string_append(str, "int");
152 break;
153 case TYPESPEC_LONG:
154 g_string_append(str, "long");
155 break;
156 case TYPESPEC_FLOAT:
157 g_string_append(str, "float");
158 break;
159 case TYPESPEC_DOUBLE:
160 g_string_append(str, "double");
161 break;
162 case TYPESPEC_SIGNED:
163 g_string_append(str, "signed");
164 break;
165 case TYPESPEC_UNSIGNED:
166 g_string_append(str, "unsigned");
167 break;
168 case TYPESPEC_BOOL:
169 g_string_append(str, "bool");
170 break;
171 case TYPESPEC_COMPLEX:
172 g_string_append(str, "_Complex");
173 break;
174 case TYPESPEC_IMAGINARY:
175 g_string_append(str, "_Imaginary");
176 break;
177 case TYPESPEC_CONST:
178 g_string_append(str, "const");
179 break;
180 case TYPESPEC_ID_TYPE:
181 if (iter->u.type_specifier.id_type)
182 g_string_append(str, iter->u.type_specifier.id_type);
183 break;
184 default:
185 fprintf(stderr, "[error] %s: unknown specifier\n", __func__);
186 err = -EINVAL;
187 goto error;
188 }
189 break;
190 case NODE_ENUM:
191 if (!iter->u._enum.enum_id) {
192 fprintf(stderr, "[error] %s: unexpected empty enum ID\n", __func__);
193 err = -EINVAL;
194 goto error;
195 }
196 g_string_append(str, "enum ");
197 g_string_append(str, iter->u._enum.enum_id);
198 break;
199 case NODE_VARIANT:
200 if (!iter->u.variant.name) {
201 fprintf(stderr, "[error] %s: unexpected empty variant name\n", __func__);
202 err = -EINVAL;
203 goto error;
204 }
205 g_string_append(str, "variant ");
206 g_string_append(str, iter->u.variant.name);
207 break;
208 case NODE_STRUCT:
209 if (!iter->u._struct.name) {
210 fprintf(stderr, "[error] %s: unexpected empty variant name\n", __func__);
211 err = -EINVAL;
212 goto error;
213 }
214 g_string_append(str, "struct ");
215 g_string_append(str, iter->u._struct.name);
216 break;
217 default:
218 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
219 err = -EINVAL;
220 goto error;
221 }
222 }
223 return 0;
224error:
225 return err;
226}
227
228static
229GQuark create_typealias_identifier(int fd, int depth,
230 struct cds_list_head *declaration_specifier,
231 struct ctf_node *node_type_declarator)
232{
233 GString *str;
234 const char *str_c;
235 GQuark alias_q;
236 int ret;
237
238 str = g_string_new();
239 ret = visit_declaration_specifier(declaration_specifier, str);
240 if (ret) {
241 g_string_free(str, TRUE);
242 return 0;
243 }
244 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
245 g_string_append(str, " *");
246 if (iter->u.pointer.const_qualifier)
247 g_string_append(str, " const");
248 }
249 str_c = g_string_free(str, FALSE);
250 alias_q = g_quark_from_string(str_c);
251 g_free(str_c);
252 return alias_q;
253}
254
a3cca9e9
MD
255static
256struct declaration *ctf_type_declarator_visit(int fd, int depth,
257 struct cds_list_head *declaration_specifier,
258 GQuark *field_name,
259 struct ctf_node *node_type_declarator,
add40b62 260 struct declaration_scope *declaration_scope,
a3cca9e9
MD
261 struct declaration *nested_declaration)
262{
263 /*
264 * Visit type declarator by first taking care of sequence/array
265 * (recursively). Then, when we get to the identifier, take care
266 * of pointers.
267 */
268
269 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
add40b62 270
a3cca9e9 271 /* TODO: gcc bitfields not supported yet. */
add40b62
MD
272 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
273 fprintf(stderr, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
274 return NULL;
275 }
a3cca9e9
MD
276
277 if (!nested_declaration) {
278 if (!cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
add40b62
MD
279 GQuark alias_q;
280
a3cca9e9
MD
281 /*
282 * If we have a pointer declarator, it _has_ to be present in
283 * the typealiases (else fail).
284 */
add40b62
MD
285 alias_q = create_typealias_identifier(fd, depth,
286 declaration_specifier, node_type_declarator);
287 nested_declaration = lookup_declaration(alias_q, declaration_scope);
288 if (!nested_declaration) {
289 fprintf(stderr, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
290 return NULL;
291 }
a3cca9e9
MD
292 } else {
293 nested_declaration = /* parse declaration_specifier */;
294 }
a3cca9e9
MD
295 }
296
297 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
298 if (node_type_declarator->u.type_declarator.u.id)
299 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
300 else
301 *field_name = 0;
302 return nested_declaration;
303 } else {
304 struct declaration *declaration;
305 struct node *length;
306
307 /* TYPEDEC_NESTED */
308
309 /* create array/sequence, pass nested_declaration as child. */
310 length = node_type_declarator->u.type_declarator.u.nested.length;
311 if (length) {
312 switch (length->type) {
313 case NODE_UNARY_EXPRESSION:
314 /* Array */
add40b62
MD
315 /* TODO */
316 .............
a3cca9e9
MD
317 declaration = /* create array */;
318 break;
319 case NODE_TYPE_SPECIFIER:
320 /* Sequence */
321 declaration = /* create sequence */;
322 break;
323 default:
324 assert(0);
325 }
326 }
327
328 /* Pass it as content of outer container */
329 declaration = ctf_type_declarator_visit(fd, depth,
330 declaration_specifier, field_name,
331 node_type_declarator->u.type_declarator.u.nested.type_declarator,
332 declaration_scope, declaration);
333 return declaration;
334 }
335}
336
337static
338int ctf_struct_type_declarators_visit(int fd, int depth,
339 struct declaration_struct *struct_declaration,
340 struct cds_list_head *declaration_specifier,
341 struct cds_list_head *type_declarators,
342 struct declaration_scope *declaration_scope)
343{
344 struct ctf_node *iter;
345 GQuark field_name;
346
347 cds_list_for_each_entry(iter, type_declarators, siblings) {
348 struct declaration *field_declaration;
349
350 field_declaration = ctf_type_declarator_visit(fd, depth,
351 declaration_specifier,
352 &field_name, iter,
353 struct_declaration->scope,
354 NULL);
355 struct_declaration_add_field(struct_declaration,
356 g_quark_to_string(field_name),
357 field_declaration);
358 }
add40b62
MD
359 return 0;
360}
a3cca9e9 361
add40b62
MD
362static
363int ctf_variant_type_declarators_visit(int fd, int depth,
364 struct declaration_variant *variant_declaration,
365 struct cds_list_head *declaration_specifier,
366 struct cds_list_head *type_declarators,
367 struct declaration_scope *declaration_scope)
368{
369 struct ctf_node *iter;
370 GQuark field_name;
371
372 cds_list_for_each_entry(iter, type_declarators, siblings) {
373 struct declaration *field_declaration;
374
375 field_declaration = ctf_type_declarator_visit(fd, depth,
376 declaration_specifier,
377 &field_name, iter,
378 variant_declaration->scope,
379 NULL);
380 variant_declaration_add_field(variant_declaration,
381 g_quark_to_string(field_name),
382 field_declaration);
383 }
a3cca9e9
MD
384 return 0;
385}
386
387static
388int ctf_typedef_visit(int fd, int depth, struct declaration_scope *scope,
389 struct cds_list_head *declaration_specifier,
390 struct cds_list_head *type_declarators)
391{
392 struct ctf_node *iter;
393 GQuark identifier;
394
395 cds_list_for_each_entry(iter, type_declarators, siblings) {
396 struct declaration *type_declaration;
397 int ret;
398
399 type_declaration = ctf_type_declarator_visit(fd, depth,
400 declaration_specifier,
401 &identifier, iter,
402 scope, NULL);
403 ret = register_declaration(identifier, type_declaration, scope);
404 if (ret) {
405 type_declaration->declaration_free(type_declaration);
406 return ret;
407 }
408 }
409 return 0;
410}
411
412static
413int ctf_typealias_visit(int fd, int depth, struct declaration_scope *scope,
414 struct ctf_node *target, struct ctf_node *alias)
415{
416 struct declaration *type_declaration;
417 struct ctf_node *iter, *node;
add40b62 418 GQuark dummy_id;
a3cca9e9 419 GQuark alias_q;
a3cca9e9
MD
420
421 /* See ctf_visitor_type_declarator() in the semantic validator. */
422
423 /*
424 * Create target type declaration.
425 */
426
427 type_declaration = ctf_type_declarator_visit(fd, depth,
428 &target->u.typealias_target.declaration_specifier,
429 &dummy_id, &target->u.typealias_target.type_declarators,
430 scope, NULL);
431 if (!type_declaration) {
432 fprintf(stderr, "[error] %s: problem creating type declaration\n", __func__);
433 err = -EINVAL;
434 goto error;
435 }
436 /*
437 * The semantic validator does not check whether the target is
438 * abstract or not (if it has an identifier). Check it here.
439 */
440 if (dummy_id != 0) {
441 fprintf(stderr, "[error] %s: expecting empty identifier\n", __func__);
442 err = -EINVAL;
443 goto error;
444 }
445 /*
446 * Create alias identifier.
447 */
a3cca9e9
MD
448
449 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
add40b62
MD
450 struct node, siblings);
451 alias_q = create_typealias_identifier(fd, depth,
452 &alias->u.typealias_alias.declaration_specifier, node);
a3cca9e9
MD
453 ret = register_declaration(alias_q, type_declaration, scope);
454 if (ret)
455 goto error;
456 return 0;
457
458error:
459 type_declaration->declaration_free(type_declaration);
460 return ret;
461}
462
463static
464int ctf_struct_declaration_list_visit(int fd, int depth,
465 struct ctf_node *iter, struct declaration_struct *struct_declaration)
466{
467 struct declaration *declaration;
468 int ret;
469
470 switch (iter->type) {
471 case NODE_TYPEDEF:
472 /* For each declarator, declare type and add type to struct declaration scope */
473 ret = ctf_typedef_visit(fd, depth,
474 struct_declaration->scope,
475 &iter->u._typedef.declaration_specifier,
476 &iter->u._typedef.type_declarators);
477 if (ret)
478 return ret;
479 break;
480 case NODE_TYPEALIAS:
481 /* Declare type with declarator and add type to struct declaration scope */
482 ret = ctf_typealias_visit(fd, depth,
483 struct_declaration->scope,
484 iter->u.typealias.target,
485 iter->u.typealias.alias);
486 if (ret)
487 return ret;
488 break;
489 case NODE_STRUCT_OR_VARIANT_DECLARATION:
490 /* Add field to structure declaration */
491 ret = ctf_struct_type_declarators_visit(fd, depth,
492 struct_declaration,
493 &iter->u.struct_or_variant_declaration.declaration_specifier,
494 &iter->u.struct_or_variant_declaration.type_declarators);
495 if (ret)
496 return ret;
497 break;
498 default:
499 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
500 assert(0);
501 }
502 return 0;
503}
504
add40b62
MD
505static
506int ctf_variant_declaration_list_visit(int fd, int depth,
507 struct ctf_node *iter, struct declaration_variant *variant_declaration)
508{
509 struct declaration *declaration;
510 int ret;
511
512 switch (iter->type) {
513 case NODE_TYPEDEF:
514 /* For each declarator, declare type and add type to variant declaration scope */
515 ret = ctf_typedef_visit(fd, depth,
516 variant_declaration->scope,
517 &iter->u._typedef.declaration_specifier,
518 &iter->u._typedef.type_declarators);
519 if (ret)
520 return ret;
521 break;
522 case NODE_TYPEALIAS:
523 /* Declare type with declarator and add type to variant declaration scope */
524 ret = ctf_typealias_visit(fd, depth,
525 variant_declaration->scope,
526 iter->u.typealias.target,
527 iter->u.typealias.alias);
528 if (ret)
529 return ret;
530 break;
531 case NODE_STRUCT_OR_VARIANT_DECLARATION:
532 /* Add field to structure declaration */
533 ret = ctf_variant_type_declarators_visit(fd, depth,
534 variant_declaration,
535 &iter->u.struct_or_variant_declaration.declaration_specifier,
536 &iter->u.struct_or_variant_declaration.type_declarators);
537 if (ret)
538 return ret;
539 break;
540 default:
541 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
542 assert(0);
543 }
544 return 0;
545}
546
a3cca9e9
MD
547static
548struct declaration_struct *ctf_declaration_struct_visit(FILE *fd,
549 int depth, const char *name, struct cds_list_head *declaration_list,
550 int has_body, struct declaration_scope *declaration_scope)
551{
552 struct declaration *declaration;
553 struct declaration_struct *struct_declaration;
554 struct ctf_node *iter;
555
556 /*
557 * For named struct (without body), lookup in
558 * declaration scope. Don't take reference on struct
559 * declaration: ref is only taken upon definition.
560 */
561 if (!has_body) {
562 assert(name);
563 struct_declaration =
564 lookup_struct_declaration(g_quark_from_string(name),
565 declaration_scope);
566 return struct_declaration;
567 } else {
568 /* For unnamed struct, create type */
569 /* For named struct (with body), create type and add to declaration scope */
570 if (name) {
571 if (lookup_struct_declaration(g_quark_from_string(name),
572 declaration_scope)) {
573
add40b62 574 fprintf(stderr, "[error] %s: struct %s already declared in scope\n", __func__, name);
a3cca9e9
MD
575 return NULL;
576 }
577 }
578 struct_declaration = struct_declaration_new(name, declaration_scope);
579 cds_list_for_each_entry(iter, declaration_list, siblings) {
add40b62 580 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter, struct_declaration);
a3cca9e9
MD
581 if (ret)
582 goto error;
583 }
584 if (name) {
585 ret = register_struct_declaration(g_quark_from_string(name),
586 struct_declaration,
587 declaration_scope);
588 assert(!ret);
589 }
590 return struct_declaration;
591 }
592error:
593 struct_declaration->p.declaration_free(&struct_declaration->p);
594 return NULL;
595}
596
05628561 597static
add40b62
MD
598struct declaration_variant *ctf_declaration_variant_visit(FILE *fd,
599 int depth, const char *name, struct cds_list_head *declaration_list,
600 int has_body, struct declaration_scope *declaration_scope)
05628561 601{
a3cca9e9 602 struct declaration *declaration;
add40b62
MD
603 struct declaration_variant *variant_declaration;
604 struct ctf_node *iter;
de47353a 605
add40b62
MD
606 /*
607 * For named variant (without body), lookup in
608 * declaration scope. Don't take reference on variant
609 * declaration: ref is only taken upon definition.
610 */
611 if (!has_body) {
612 assert(name);
613 variant_declaration =
614 lookup_variant_declaration(g_quark_from_string(name),
615 declaration_scope);
616 return variant_declaration;
617 } else {
de47353a 618 /* For unnamed variant, create type */
add40b62
MD
619 /* For named variant (with body), create type and add to declaration scope */
620 if (name) {
621 if (lookup_variant_declaration(g_quark_from_string(name),
622 declaration_scope)) {
623
624 fprintf(stderr, "[error] %s: variant %s already declared in scope\n", __func__, name);
625 return NULL;
626 }
627 }
628 variant_declaration = variant_declaration_new(name, declaration_scope);
629 cds_list_for_each_entry(iter, declaration_list, siblings) {
630 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter, variant_declaration);
631 if (ret)
632 goto error;
633 }
634 if (name) {
635 ret = register_variant_declaration(g_quark_from_string(name),
636 variant_declaration,
637 declaration_scope);
638 assert(!ret);
639 }
640 return variant_declaration;
de47353a 641 }
add40b62
MD
642error:
643 variant_declaration->p.declaration_free(&variant_declaration->p);
644 return NULL;
05628561
MD
645}
646
05628561 647static
add40b62
MD
648int ctf_enumerator_list_visit(int fd, int depth,
649 struct ctf_node *enumerator,
650 struct declaration_enum *enum_declaration)
651{
652 /* TODO */
653........
654 return 0;
655}
656
657static
658struct declaration *ctf_declaration_enum_visit(int fd, int depth,
659 const char *name,
660 struct ctf_node *container_type,
661 struct cds_list_head *enumerator_list,
662 int has_body)
05628561 663{
add40b62
MD
664 struct declaration *declaration;
665 struct declaration_enum *enum_declaration;
666 struct declaration_integer *integer_declaration;
667 struct ctf_node *iter;
668
05628561 669 /*
add40b62
MD
670 * For named enum (without body), lookup in
671 * declaration scope. Don't take reference on enum
672 * declaration: ref is only taken upon definition.
05628561 673 */
add40b62
MD
674 if (!has_body) {
675 assert(name);
676 enum_declaration =
677 lookup_enum_declaration(g_quark_from_string(name),
678 declaration_scope);
679 return enum_declaration;
680 } else {
681 /* For unnamed enum, create type */
682 /* For named enum (with body), create type and add to declaration scope */
683 if (name) {
684 if (lookup_enum_declaration(g_quark_from_string(name),
685 declaration_scope)) {
686
687 fprintf(stderr, "[error] %s: enum %s already declared in scope\n", __func__, name);
688 return NULL;
689 }
690 }
05628561 691
add40b62
MD
692 /* TODO CHECK Enumerations need to have their size/type specifier (< >). */
693 integer_declaration = integer_declaration_new(); /* TODO ... */
694 .....
695 enum_declaration = enum_declaration_new(name, integer_declaration);
696 declaration_unref(&integer_declaration->p); /* leave ref to enum */
697 cds_list_for_each_entry(iter, enumerator_list, siblings) {
698 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
699 if (ret)
700 goto error;
701 }
702 if (name) {
703 ret = register_enum_declaration(g_quark_from_string(name),
704 enum_declaration,
705 declaration_scope);
706 assert(!ret);
707 }
708 return enum_declaration;
05628561 709 }
add40b62
MD
710error:
711 enum_declaration->p.declaration_free(&enum_declaration->p);
712 return NULL;
05628561
MD
713}
714
715static
add40b62
MD
716struct declaration *ctf_declaration_type_specifier_visit(int fd, int depth,
717 struct cds_list_head *declaration_specifier,
d20f5e59 718 struct declaration_scope *declaration_scope)
05628561 719{
add40b62
MD
720 GString *str;
721 struct declaration *declaration;
722 const char *str_c;
05628561 723
add40b62
MD
724 str = g_string_new();
725 ret = visit_declaration_specifier(declaration_specifier, str);
726 if (ret)
727 return NULL;
728 str_c = g_string_free(str, FALSE);
729 id_q = g_quark_from_string(str_c);
730 g_free(str_c);
731 declaration = lookup_declaration(id_q, declaration_scope);
732 return declaration;
733}
734
ab4cf058
MD
735/*
736 * Returns 0/1 boolean, or < 0 on error.
737 */
738static
739int get_boolean(int fd, int depth, struct node *unary_expression)
740{
741 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
742 fprintf(stderr, "[error] %s: expecting unary expression\n",
743 __func__);
744 return -EINVAL;
745 }
746 switch (unary_expression->u.unary_expression.type) {
747 case UNARY_UNSIGNED_CONSTANT:
748 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
749 return 0;
750 else
751 return 1;
752 case UNARY_SIGNED_CONSTANT:
753 if (unary_expression->u.unary_expression.u.signed_constant == 0)
754 return 0;
755 else
756 return 1;
757 case UNARY_STRING:
758 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
759 return 1;
760 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
761 return 1;
762 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
763 return 0;
764 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
765 return 0;
766 else {
767 fprintf(stderr, "[error] %s: unexpected string \"%s\"\n",
768 __func__, unary_expression->u.unary_expression.u.string);
769 return -EINVAL;
770 }
771 break;
772 default:
773 fprintf(stderr, "[error] %s: unexpected unary expression type\n",
774 __func__);
775 return -EINVAL;
776 }
777
778}
779
780static
781int get_byte_order(int fd, int depth, struct node *unary_expression)
782{
783 int byte_order;
784
785 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
786 fprintf(stderr, "[error] %s: byte_order: expecting string\n",
787 __func__);
788 return -EINVAL;
789 }
790 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
791 byte_order = trace->byte_order;
792 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
793 byte_order = BIG_ENDIAN;
794 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
795 byte_order = BIG_ENDIAN;
796 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
797 byte_order = LITTLE_ENDIAN;
798 else {
799 fprintf(stderr, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
800 __func__, right->u.unary_expression.u.string);
801 return -EINVAL;
802 }
803 return byte_order;
804}
805
add40b62
MD
806static
807struct declaration *ctf_declaration_integer_visit(int fd, int depth,
ab4cf058
MD
808 struct cds_list_head *expressions,
809 struct ctf_trace *trace)
add40b62
MD
810{
811 struct node *expression;
ab4cf058
MD
812 uint64_t alignment, size;
813 int byte_order = trace->byte_order;
814 int signedness = 0;
add40b62
MD
815 int has_alignment = 0, has_size = 0;
816 struct declaration_integer *integer_declaration;
817
818 cds_list_for_each_entry(expression, expressions, siblings) {
819 struct node *left, *right;
820
821 left = expression->u.ctf_expression.left;
822 right = expression->u.ctf_expression.right;
823 assert(left->u.unary_expression.type == UNARY_STRING);
824 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
ab4cf058
MD
825 signedness = get_boolean(fd, depth, right);
826 if (signedness < 0)
827 return NULL;
add40b62 828 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
ab4cf058
MD
829 byte_order = get_byte_order(fd, depth, right);
830 if (byte_order < 0)
831 return NULL;
add40b62 832 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
ab4cf058
MD
833 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
834 fprintf(stderr, "[error] %s: size: expecting unsigned constant\n",
835 __func__);
836 return NULL;
837 }
838 size = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
839 has_size = 1;
840 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
ab4cf058
MD
841 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
842 fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
843 __func__);
844 return NULL;
845 }
846 alignment = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
847 has_alignment = 1;
848 } else {
849 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
850 __func__, left->u.unary_expression.u.string);
851 return NULL;
852 }
05628561 853 }
add40b62
MD
854 if (!has_size) {
855 fprintf(stderr, "[error] %s: missing size attribute\n", __func__);
856 return NULL;
857 }
ab4cf058
MD
858 if (!has_alignment) {
859 if (size % CHAR_BIT) {
860 /* bit-packed alignment */
861 alignment = 1;
862 } else {
863 /* byte-packed alignment */
864 alignment = CHAR_BIT;
865 }
866 }
add40b62
MD
867 integer_declaration = integer_declaration_new(size,
868 byte_order, signedness, alignment);
869 return &integer_declaration->p;
05628561
MD
870}
871
ab4cf058
MD
872static
873struct declaration *ctf_declaration_floating_point_visit(int fd, int depth,
874 struct cds_list_head *expressions,
875 struct ctf_trace *trace)
876{
877 struct node *expression;
878 uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
879 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
880 struct declaration_float *float_declaration;
881
882 cds_list_for_each_entry(expression, expressions, siblings) {
883 struct node *left, *right;
884
885 left = expression->u.ctf_expression.left;
886 right = expression->u.ctf_expression.right;
887 assert(left->u.unary_expression.type == UNARY_STRING);
888 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
889 byte_order = get_byte_order(fd, depth, right);
890 if (byte_order < 0)
891 return NULL;
892 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
893 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
894 fprintf(stderr, "[error] %s: exp_dig: expecting unsigned constant\n",
895 __func__);
896 return NULL;
897 }
898 exp_dig = right->u.unary_expression.u.unsigned_constant;
899 has_exp_dig = 1;
900 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
901 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
902 fprintf(stderr, "[error] %s: mant_dig: expecting unsigned constant\n",
903 __func__);
904 return NULL;
905 }
906 mant_dig = right->u.unary_expression.u.unsigned_constant;
907 has_mant_dig = 1;
908 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
909 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
910 fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
911 __func__);
912 return NULL;
913 }
914 alignment = right->u.unary_expression.u.unsigned_constant;
915 has_alignment = 1;
916 } else {
917 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
918 __func__, left->u.unary_expression.u.string);
919 return NULL;
920 }
921 }
922 if (!has_mant_dig) {
923 fprintf(stderr, "[error] %s: missing mant_dig attribute\n", __func__);
924 return NULL;
925 }
926 if (!has_exp_dig) {
927 fprintf(stderr, "[error] %s: missing exp_dig attribute\n", __func__);
928 return NULL;
929 }
930 if (!has_alignment) {
931 if ((mant_dig + exp_dig) % CHAR_BIT) {
932 /* bit-packed alignment */
933 alignment = 1;
934 } else {
935 /* byte-packed alignment */
936 alignment = CHAR_BIT;
937 }
938 }
939 float_declaration = float_declaration_new(mant_dig, exp_dig,
940 byte_order, alignment);
941 return &float_declaration->p;
942}
943
944static
945struct declaration *ctf_declaration_string_visit(int fd, int depth,
946 struct cds_list_head *expressions,
947 struct ctf_trace *trace)
948{
949 struct node *expression;
950 const char *encoding_c = NULL;
951 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
952 struct declaration_string *string_declaration;
953
954 cds_list_for_each_entry(expression, expressions, siblings) {
955 struct node *left, *right;
956
957 left = expression->u.ctf_expression.left;
958 right = expression->u.ctf_expression.right;
959 assert(left->u.unary_expression.type == UNARY_STRING);
960 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
961 if (right->u.unary_expression.type != UNARY_UNSIGNED_STRING) {
962 fprintf(stderr, "[error] %s: encoding: expecting string\n",
963 __func__);
964 return NULL;
965 }
966 encoding_c = right->u.unary_expression.u.string;
967 } else {
968 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
969 __func__, left->u.unary_expression.u.string);
970 return NULL;
971 }
972 }
973 if (encoding_c && !strcmp(encoding_c, "ASCII"))
974 encoding = CTF_STRING_ASCII;
975 string_declaration = string_declaration_new(encoding);
976 return &string_declaration->p;
977}
978
979
add40b62
MD
980/*
981 * Also add named variant, struct or enum to the current declaration scope.
982 */
05628561 983static
add40b62
MD
984struct declaration *ctf_declaration_specifier_visit(FILE *fd,
985 int depth, struct cds_list_head *head,
ab4cf058
MD
986 struct declaration_scope *declaration_scope,
987 struct ctf_trace *trace)
05628561 988{
add40b62
MD
989 struct declaration *declaration;
990 struct node *first;
d20f5e59 991
add40b62 992 first = _cds_list_first_entry(head, struct node, siblings);
05628561 993
add40b62
MD
994 switch (first->type) {
995 case NODE_STRUCT:
996 return ctf_declaration_struct_visit(fd, depth,
997 first->u._struct.name,
998 &first->u._struct.declaration_list,
999 first->u._struct.has_body,
ab4cf058
MD
1000 declaration_scope,
1001 trace);
add40b62
MD
1002 case NODE_VARIANT:
1003 return ctf_declaration_variant_visit(fd, depth,
1004 first->u.variant.name,
1005 &first->u.variant.declaration_list,
1006 first->u.variant.has_body,
ab4cf058
MD
1007 declaration_scope,
1008 trace);
add40b62
MD
1009 case NODE_ENUM:
1010 return ctf_declaration_enum_visit(fd, depth,
1011 first->u._enum.enum_id,
1012 first->u._enum.container_type,
1013 &first->u._enum.enumerator_list,
ab4cf058
MD
1014 first->u._enum.has_body,
1015 trace);
add40b62
MD
1016 case NODE_INTEGER:
1017 return ctf_declaration_integer_visit(fd, depth,
ab4cf058
MD
1018 &first->u.integer.expressions, trace);
1019 case NODE_FLOATING_POINT:
add40b62 1020 return ctf_declaration_floating_point_visit(fd, depth,
ab4cf058
MD
1021 &first->u.floating_point.expressions, trace);
1022 case NODE_STRING:
add40b62 1023 return ctf_declaration_string_visit(fd, depth,
ab4cf058 1024 &first->u.string.expressions, trace);
add40b62
MD
1025 case NODE_TYPE_SPECIFIER:
1026 return ctf_declaration_type_specifier_visit(fd, depth,
ab4cf058 1027 head, declaration_scope, trace);
add40b62 1028 }
05628561
MD
1029}
1030
1031static
1032int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1033{
1034 int ret = 0;
1035
1036 switch (node->type) {
1037 case NODE_TYPEDEF:
1038 ret = ctf_typedef_visit(fd, depth + 1,
1039 &node->u._typedef.declaration_specifier,
1040 &node->u._typedef.type_declarators,
d20f5e59 1041 event->declaration_scope);
05628561
MD
1042 if (ret)
1043 return ret;
1044 break;
1045 case NODE_TYPEALIAS:
1046 ret = ctf_typealias_visit(fd, depth + 1,
1047 &node->u.typealias.target, &node->u.typealias.alias
d20f5e59 1048 event->declaration_scope);
05628561
MD
1049 if (ret)
1050 return ret;
1051 break;
1052 case NODE_CTF_EXPRESSION:
1053 {
1054 char *left;
1055
1056 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1057 if (!strcmp(left, "name")) {
1058 char *right;
1059
1060 if (CTF_EVENT_FIELD_IS_SET(event, name))
1061 return -EPERM;
1062 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1063 if (!right) {
1064 fprintf(stderr, "[error] %s: unexpected unary expression for event name\n", __func__);
1065 return -EINVAL;
1066 }
1067 event->name = g_quark_from_string(right);
41253107 1068 g_free(right);
05628561
MD
1069 CTF_EVENT_SET_FIELD(event, name);
1070 } else if (!strcmp(left, "id")) {
1071 if (CTF_EVENT_FIELD_IS_SET(event, id))
1072 return -EPERM;
1073 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1074 if (ret) {
1075 fprintf(stderr, "[error] %s: unexpected unary expression for event id\n", __func__);
1076 return -EINVAL;
1077 }
1078 CTF_EVENT_SET_FIELD(event, id);
1079 } else if (!strcmp(left, "stream_id")) {
1080 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
1081 return -EPERM;
1082 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1083 if (ret) {
1084 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1085 return -EINVAL;
1086 }
1087 event->stream = trace_stream_lookup(trace, event->stream_id);
1088 if (!event->stream) {
1089 fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1090 return -EINVAL;
1091 }
05628561
MD
1092 CTF_EVENT_SET_FIELD(event, stream_id);
1093 } else if (!strcmp(left, "context")) {
1094 struct declaration *declaration;
1095
e1151715 1096 if (!event->definition_scope)
05628561
MD
1097 return -EPERM;
1098 declaration = ctf_declaration_specifier_visit(fd, depth,
1099 &node->u.ctf_expression.right,
ab4cf058 1100 event->declaration_scope, trace);
05628561
MD
1101 if (!declaration)
1102 return -EPERM;
1103 if (declaration->type->id != CTF_TYPE_STRUCT)
1104 return -EPERM;
9e29e16e 1105 event->context_decl = container_of(declaration, struct declaration_struct, p);
05628561
MD
1106 } else if (!strcmp(left, "fields")) {
1107 struct declaration *declaration;
1108
e1151715 1109 if (!event->definition_scope)
05628561
MD
1110 return -EPERM;
1111 declaration = ctf_declaration_specifier_visit(fd, depth,
1112 &node->u.ctf_expression.right,
ab4cf058 1113 event->declaration_scope, trace);
05628561
MD
1114 if (!declaration)
1115 return -EPERM;
1116 if (declaration->type->id != CTF_TYPE_STRUCT)
1117 return -EPERM;
9e29e16e 1118 event->fields_decl = container_of(declaration, struct declaration_struct, p);
05628561 1119 }
41253107 1120 g_free(left);
05628561
MD
1121 break;
1122 }
1123 default:
1124 return -EPERM;
1125 /* TODO: declaration specifier should be added. */
1126 }
1127
1128 return 0;
1129}
1130
1131static
1132int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1133 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1134{
1135 int ret = 0;
1136 struct ctf_node *iter;
1137 struct ctf_event *event;
9e29e16e 1138 struct definition_scope *parent_def_scope;
05628561
MD
1139
1140 event = g_new0(struct ctf_event, 1);
d20f5e59 1141 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
1142 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1143 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1144 if (ret)
1145 goto error;
1146 }
1147 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1148 ret = -EPERM;
1149 goto error;
1150 }
1151 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
1152 ret = -EPERM;
1153 goto error;
1154 }
1155 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1156 ret = -EPERM;
1157 goto error;
1158 }
1159 if (event->stream->events_by_id->len <= event->id)
1160 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1161 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1162 g_hash_table_insert(event->stream->event_quark_to_id,
1163 (gpointer)(unsigned long) event->name,
1164 &event->id);
41253107 1165 parent_def_scope = stream->definition_scope;
9e29e16e
MD
1166 if (event->context_decl) {
1167 event->context =
1168 event->context_decl->definition_new(event->context_decl,
41253107 1169 parent_def_scope, 0, 0);
6a36ddca
MD
1170 set_dynamic_definition_scope(&event->context->p,
1171 event->context->scope,
d00d17d1 1172 "event.context");
9e29e16e
MD
1173 parent_def_scope = event->context->scope;
1174 declaration_unref(event->context_decl);
1175 }
1176 if (event->fields_decl) {
1177 event->fields =
1178 event->fields_decl->definition_new(event->fields_decl,
41253107 1179 parent_def_scope, 0, 0);
6a36ddca
MD
1180 set_dynamic_definition_scope(&event->fields->p,
1181 event->fields->scope,
d00d17d1 1182 "event.fields");
9e29e16e
MD
1183 parent_def_scope = event->fields->scope;
1184 declaration_unref(event->fields_decl);
1185 }
05628561
MD
1186 return 0;
1187
1188error:
9e29e16e
MD
1189 declaration_unref(event->fields_decl);
1190 declaration_unref(event->context_decl);
e1151715 1191 free_definition_scope(event->definition_scope);
d20f5e59 1192 free_declaration_scope(event->declaration_scope);
05628561
MD
1193 g_free(event);
1194 return ret;
1195}
1196
1197
1198static
1199int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
1200{
1201 int ret = 0;
1202
1203 switch (node->type) {
1204 case NODE_TYPEDEF:
1205 ret = ctf_typedef_visit(fd, depth + 1,
1206 &node->u._typedef.declaration_specifier,
1207 &node->u._typedef.type_declarators,
d20f5e59 1208 stream->declaration_scope);
05628561
MD
1209 if (ret)
1210 return ret;
1211 break;
1212 case NODE_TYPEALIAS:
1213 ret = ctf_typealias_visit(fd, depth + 1,
1214 &node->u.typealias.target, &node->u.typealias.alias
d20f5e59 1215 stream->declaration_scope);
05628561
MD
1216 if (ret)
1217 return ret;
1218 break;
1219 case NODE_CTF_EXPRESSION:
1220 {
1221 char *left;
1222
1223 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1224 if (!strcmp(left, "stream_id")) {
1225 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
1226 return -EPERM;
1227 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1228 if (ret) {
1229 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1230 return -EINVAL;
1231 }
1232 CTF_EVENT_SET_FIELD(event, stream_id);
9e29e16e 1233 } else if (!strcmp(left, "event.header")) {
05628561
MD
1234 struct declaration *declaration;
1235
1236 declaration = ctf_declaration_specifier_visit(fd, depth,
1237 &node->u.ctf_expression.right,
ab4cf058 1238 stream->declaration_scope, stream->definition_scope, trace);
05628561
MD
1239 if (!declaration)
1240 return -EPERM;
1241 if (declaration->type->id != CTF_TYPE_STRUCT)
1242 return -EPERM;
9e29e16e
MD
1243 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1244 } else if (!strcmp(left, "event.context")) {
05628561
MD
1245 struct declaration *declaration;
1246
1247 declaration = ctf_declaration_specifier_visit(fd, depth,
1248 &node->u.ctf_expression.right,
ab4cf058 1249 stream->declaration_scope, trace);
05628561
MD
1250 if (!declaration)
1251 return -EPERM;
1252 if (declaration->type->id != CTF_TYPE_STRUCT)
1253 return -EPERM;
9e29e16e
MD
1254 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1255 } else if (!strcmp(left, "packet.context")) {
05628561
MD
1256 struct declaration *declaration;
1257
1258 declaration = ctf_declaration_specifier_visit(fd, depth,
1259 &node->u.ctf_expression.right,
ab4cf058 1260 stream->declaration_scope, trace);
05628561
MD
1261 if (!declaration)
1262 return -EPERM;
1263 if (declaration->type->id != CTF_TYPE_STRUCT)
1264 return -EPERM;
9e29e16e 1265 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
05628561 1266 }
41253107 1267 g_free(left);
05628561
MD
1268 break;
1269 }
1270 default:
1271 return -EPERM;
1272 /* TODO: declaration specifier should be added. */
1273 }
1274
1275 return 0;
1276}
1277
1278static
1279int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1280 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1281{
1282 int ret = 0;
1283 struct ctf_node *iter;
1284 struct ctf_stream *stream;
9e29e16e 1285 struct definition_scope *parent_def_scope;
05628561
MD
1286
1287 stream = g_new0(struct ctf_stream, 1);
d20f5e59 1288 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
1289 stream->events_by_id = g_ptr_array_new();
1290 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
1291 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1292 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1293 if (ret)
1294 goto error;
1295 }
1296 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
1297 ret = -EPERM;
1298 goto error;
1299 }
1300 if (trace->streams->len <= stream->stream_id)
1301 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1302 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
9e29e16e 1303
41253107 1304 parent_def_scope = NULL;
9e29e16e
MD
1305 if (stream->packet_context_decl) {
1306 stream->packet_context =
1307 stream->packet_context_decl->definition_new(stream->packet_context_decl,
41253107 1308 parent_def_scope, 0, 0);
6a36ddca
MD
1309 set_dynamic_definition_scope(&stream->packet_context->p,
1310 stream->packet_context->scope,
d00d17d1 1311 "stream.packet.context");
9e29e16e
MD
1312 parent_def_scope = stream->packet_context->scope;
1313 declaration_unref(stream->packet_context_decl);
1314 }
1315 if (stream->event_header_decl) {
1316 stream->event_header =
1317 stream->event_header_decl->definition_new(stream->event_header_decl,
41253107 1318 parent_def_scope, 0, 0);
6a36ddca
MD
1319 set_dynamic_definition_scope(&stream->event_header->p,
1320 stream->event_header->scope,
d00d17d1 1321 "stream.event.header");
9e29e16e
MD
1322 parent_def_scope = stream->event_header->scope;
1323 declaration_unref(stream->event_header_decl);
1324 }
1325 if (stream->event_context_decl) {
1326 stream->event_context =
1327 stream->event_context_decl->definition_new(stream->event_context_decl,
41253107 1328 parent_def_scope, 0, 0);
6a36ddca
MD
1329 set_dynamic_definition_scope(&stream->event_context->p,
1330 stream->event_context->scope,
d00d17d1 1331 "stream.event.context");
9e29e16e
MD
1332 parent_def_scope = stream->event_context->scope;
1333 declaration_unref(stream->event_context_decl);
1334 }
41253107 1335 stream->definition_scope = parent_def_scope;
9e29e16e 1336
05628561
MD
1337 return 0;
1338
1339error:
1340 declaration_unref(stream->event_header);
1341 declaration_unref(stream->event_context);
1342 declaration_unref(stream->packet_context);
1343 g_ptr_array_free(stream->events_by_id, TRUE);
1344 g_hash_table_free(stream->event_quark_to_id);
e1151715 1345 free_definition_scope(stream->definition_scope);
d20f5e59 1346 free_declaration_scope(stream->declaration_scope);
05628561
MD
1347 g_free(stream);
1348 return ret;
1349}
1350
1351static
1352int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1353{
1354 int ret = 0;
1355
1356 switch (node->type) {
1357 case NODE_TYPEDEF:
1358 ret = ctf_typedef_visit(fd, depth + 1,
1359 &node->u._typedef.declaration_specifier,
1360 &node->u._typedef.type_declarators,
d20f5e59 1361 trace->declaration_scope);
05628561
MD
1362 if (ret)
1363 return ret;
1364 break;
1365 case NODE_TYPEALIAS:
1366 ret = ctf_typealias_visit(fd, depth + 1,
1367 &node->u.typealias.target, &node->u.typealias.alias
d20f5e59 1368 trace->declaration_scope);
05628561
MD
1369 if (ret)
1370 return ret;
1371 break;
1372 case NODE_CTF_EXPRESSION:
1373 {
1374 char *left;
1375
1376 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1377 if (!strcmp(left, "major")) {
1378 if (CTF_EVENT_FIELD_IS_SET(trace, major))
1379 return -EPERM;
1380 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1381 if (ret) {
1382 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
1383 return -EINVAL;
1384 }
1385 CTF_EVENT_SET_FIELD(trace, major);
1386 } else if (!strcmp(left, "minor")) {
1387 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
1388 return -EPERM;
1389 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1390 if (ret) {
1391 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
1392 return -EINVAL;
1393 }
1394 CTF_EVENT_SET_FIELD(trace, minor);
1395 } else if (!strcmp(left, "word_size")) {
1396 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
1397 return -EPERM;
1398 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
1399 if (ret) {
1400 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
1401 return -EINVAL;
1402 }
1403 CTF_EVENT_SET_FIELD(trace, word_size);
1404 } else if (!strcmp(left, "uuid")) {
1405 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
1406 return -EPERM;
1407 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1408 if (ret) {
1409 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
1410 return -EINVAL;
1411 }
1412 CTF_EVENT_SET_FIELD(trace, uuid);
1413 }
41253107 1414 g_free(left);
05628561
MD
1415 break;
1416 }
1417 default:
1418 return -EPERM;
1419 /* TODO: declaration specifier should be added. */
1420 }
1421
1422 return 0;
1423}
1424
05628561
MD
1425static
1426int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1427{
1428 int ret = 0;
1429 struct ctf_node *iter;
1430
d20f5e59 1431 if (trace->declaration_scope)
05628561 1432 return -EEXIST;
d20f5e59 1433 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
9e29e16e 1434 trace->definition_scope = new_dynamic_definition_scope(trace->root_definition_scope);
05628561
MD
1435 trace->streams = g_ptr_array_new();
1436 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1437 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1438 if (ret)
1439 goto error;
1440 }
1441 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
1442 ret = -EPERM;
1443 goto error;
1444 }
1445 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
1446 ret = -EPERM;
1447 goto error;
1448 }
1449 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
1450 ret = -EPERM;
1451 goto error;
1452 }
1453 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
1454 ret = -EPERM;
1455 goto error;
1456 }
1457 return 0;
1458
1459error:
1460 g_ptr_array_free(trace->streams, TRUE);
e1151715 1461 free_definition_scope(stream->definition_scope);
d20f5e59 1462 free_declaration_scope(stream->declaration_scope);
05628561
MD
1463 return ret;
1464}
1465
ab4cf058
MD
1466int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
1467 struct ctf_trace *trace, int byte_order)
05628561
MD
1468{
1469 int ret = 0;
1470 struct ctf_node *iter;
1471
ab4cf058
MD
1472 trace->byte_order = byte_order;
1473
05628561
MD
1474 switch (node->type) {
1475 case NODE_ROOT:
1476 cds_list_for_each_entry(iter, &node->u.root._typedef,
1477 siblings) {
1478 ret = ctf_typedef_visit(fd, depth + 1,
1479 &iter->u._typedef.declaration_specifier,
1480 &iter->u._typedef.type_declarators,
d60cb676 1481 trace->root_declaration_scope);
05628561
MD
1482 if (ret)
1483 return ret;
1484 }
1485 cds_list_for_each_entry(iter, &node->u.root.typealias,
1486 siblings) {
1487 ret = ctf_typealias_visit(fd, depth + 1,
1488 &iter->u.typealias.target, &iter->u.typealias.alias
d60cb676 1489 trace->root_declaration_scope);
05628561
MD
1490 if (ret)
1491 return ret;
1492 }
1493 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
de47353a 1494 ret = ctf_declaration_specifier_visit(fd, depth, iter,
ab4cf058 1495 trace->root_declaration_scope, trace);
05628561
MD
1496 if (ret)
1497 return ret;
1498 }
1499 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
1500 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
1501 if (ret)
1502 return ret;
1503 }
1504 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
1505 ret = ctf_stream_visit(fd, depth + 1, iter,
41253107 1506 trace->root_declaration_scope, trace);
05628561
MD
1507 if (ret)
1508 return ret;
1509 }
1510 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
1511 ret = ctf_event_visit(fd, depth + 1, iter,
41253107 1512 trace->root_declaration_scope, trace);
05628561
MD
1513 if (ret)
1514 return ret;
1515 }
1516 break;
05628561
MD
1517 case NODE_UNKNOWN:
1518 default:
1519 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
1520 (int) node->type);
1521 return -EINVAL;
1522 }
1523 return ret;
1524}
This page took 0.089095 seconds and 4 git commands to generate.