gen io struct visitor: update enum
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
... / ...
CommitLineData
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 <endian.h>
27#include <errno.h>
28#include <babeltrace/list.h>
29#include <uuid/uuid.h>
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
36#define _cds_list_first_entry(ptr, type, member) \
37 cds_list_entry((ptr)->next, type, member)
38
39static
40struct declaration *ctf_declaration_specifier_visit(FILE *fd,
41 int depth, struct cds_list_head *head,
42 struct declaration_scope *declaration_scope,
43 struct ctf_trace *trace);
44
45/*
46 * String returned must be freed by the caller using g_free.
47 */
48static
49char *concatenate_unary_strings(struct cds_list_head *head)
50{
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);
79}
80
81static
82int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
83{
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;
96}
97
98static
99int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
100{
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;
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
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
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,
260 struct declaration_scope *declaration_scope,
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);
270
271 /* TODO: gcc bitfields not supported yet. */
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 }
276
277 if (!nested_declaration) {
278 if (!cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
279 GQuark alias_q;
280
281 /*
282 * If we have a pointer declarator, it _has_ to be present in
283 * the typealiases (else fail).
284 */
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 }
292 } else {
293 nested_declaration = /* parse declaration_specifier */;
294 }
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 */
315 /* TODO */
316 .............
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 }
359 return 0;
360}
361
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 }
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;
418 GQuark dummy_id;
419 GQuark alias_q;
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 */
448
449 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
450 struct node, siblings);
451 alias_q = create_typealias_identifier(fd, depth,
452 &alias->u.typealias_alias.declaration_specifier, node);
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
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
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
574 fprintf(stderr, "[error] %s: struct %s already declared in scope\n", __func__, name);
575 return NULL;
576 }
577 }
578 struct_declaration = struct_declaration_new(name, declaration_scope);
579 cds_list_for_each_entry(iter, declaration_list, siblings) {
580 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter, struct_declaration);
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
597static
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)
601{
602 struct declaration *declaration;
603 struct declaration_variant *variant_declaration;
604 struct ctf_node *iter;
605
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 {
618 /* For unnamed variant, create type */
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;
641 }
642error:
643 variant_declaration->p.declaration_free(&variant_declaration->p);
644 return NULL;
645}
646
647static
648int ctf_enumerator_list_visit(int fd, int depth,
649 struct ctf_node *enumerator,
650 struct declaration_enum *enum_declaration)
651{
652 GQuark q;
653 struct ctf_node *iter;
654
655 q = g_quark_from_string(enumerator->u.enumerator.id);
656 if (enum_declaration->integer->signedness) {
657 int64_t start, end;
658 int nr_vals = 0;
659
660 cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) {
661 int64_t *target;
662
663 assert(iter->type == NODE_UNARY_EXPRESSION);
664 if (nr_vals == 0)
665 target = &start;
666 else
667 target = &end;
668
669 switch (iter->u.unary_expression.type) {
670 case UNARY_SIGNED_CONSTANT:
671 *target = iter->u.unary_expression.u.signed_constant;
672 break;
673 case UNARY_UNSIGNED_CONSTANT:
674 *target = iter->u.unary_expression.u.unsigned_constant;
675 break;
676 default:
677 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
678 return -EINVAL;
679 }
680 if (nr_vals > 1) {
681 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
682 return -EINVAL;
683 }
684 nr_vals++;
685 }
686 if (nr_vals == 1)
687 end = start;
688 enum_signed_insert(enum_declaration, start, end, q);
689 } else
690 uint64_t start, end;
691 int nr_vals = 0;
692
693 cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) {
694 int64_t *target;
695
696 assert(iter->type == NODE_UNARY_EXPRESSION);
697 if (nr_vals == 0)
698 target = &start;
699 else
700 target = &end;
701
702 switch (iter->u.unary_expression.type) {
703 case UNARY_UNSIGNED_CONSTANT:
704 *target = iter->u.unary_expression.u.unsigned_constant;
705 break;
706 case UNARY_SIGNED_CONSTANT:
707 /*
708 * We don't accept signed constants for enums with unsigned
709 * container type.
710 */
711 fprintf(stderr, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
712 return -EINVAL;
713 default:
714 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
715 return -EINVAL;
716 }
717 if (nr_vals > 1) {
718 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
719 return -EINVAL;
720 }
721 nr_vals++;
722 }
723 if (nr_vals == 1)
724 end = start;
725 enum_unsigned_insert(enum_declaration, start, end, q);
726 }
727 return 0;
728}
729
730static
731struct declaration *ctf_declaration_enum_visit(int fd, int depth,
732 const char *name,
733 struct cds_list_head *container_type,
734 struct cds_list_head *enumerator_list,
735 int has_body,
736 struct declaration_scope *declaration_scope,
737 struct ctf_trace *trace)
738{
739 struct declaration *declaration;
740 struct declaration_enum *enum_declaration;
741 struct declaration_integer *integer_declaration;
742 struct ctf_node *iter, *first;
743 GQuark dummy_id;
744
745 /*
746 * For named enum (without body), lookup in
747 * declaration scope. Don't take reference on enum
748 * declaration: ref is only taken upon definition.
749 */
750 if (!has_body) {
751 assert(name);
752 enum_declaration =
753 lookup_enum_declaration(g_quark_from_string(name),
754 declaration_scope);
755 return enum_declaration;
756 } else {
757 /* For unnamed enum, create type */
758 /* For named enum (with body), create type and add to declaration scope */
759 if (name) {
760 if (lookup_enum_declaration(g_quark_from_string(name),
761 declaration_scope)) {
762
763 fprintf(stderr, "[error] %s: enum %s already declared in scope\n", __func__, name);
764 return NULL;
765 }
766 }
767 if (cds_list_empty(container_type)) {
768 fprintf(stderr, "[error] %s: missing container type for enumeration\n", __func__, name);
769 return NULL;
770
771 }
772 first = _cds_list_first_entry(container_type, struct node, siblings);
773 switch (first->type) {
774 case NODE_INTEGER:
775 case NODE_TYPE_SPECIFIER:
776 declaration = ctf_type_declarator_visit(fd, depth,
777 container_type,
778 &dummy_id, iter,
779 declaration_scope,
780 NULL);
781 assert(declaration->id == CTF_TYPE_INTEGER);
782 integer_declaration = container_of(declaration, struct declaration_integer, p);
783 break;
784 }
785 default:
786 assert(0);
787 }
788 enum_declaration = enum_declaration_new(name, integer_declaration);
789 declaration_unref(&integer_declaration->p); /* leave ref to enum */
790 cds_list_for_each_entry(iter, enumerator_list, siblings) {
791 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
792 if (ret)
793 goto error;
794 }
795 if (name) {
796 ret = register_enum_declaration(g_quark_from_string(name),
797 enum_declaration,
798 declaration_scope);
799 assert(!ret);
800 }
801 return enum_declaration;
802 }
803error:
804 enum_declaration->p.declaration_free(&enum_declaration->p);
805 return NULL;
806}
807
808static
809struct declaration *ctf_declaration_type_specifier_visit(int fd, int depth,
810 struct cds_list_head *declaration_specifier,
811 struct declaration_scope *declaration_scope)
812{
813 GString *str;
814 struct declaration *declaration;
815 const char *str_c;
816
817 str = g_string_new();
818 ret = visit_declaration_specifier(declaration_specifier, str);
819 if (ret)
820 return NULL;
821 str_c = g_string_free(str, FALSE);
822 id_q = g_quark_from_string(str_c);
823 g_free(str_c);
824 declaration = lookup_declaration(id_q, declaration_scope);
825 return declaration;
826}
827
828/*
829 * Returns 0/1 boolean, or < 0 on error.
830 */
831static
832int get_boolean(int fd, int depth, struct node *unary_expression)
833{
834 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
835 fprintf(stderr, "[error] %s: expecting unary expression\n",
836 __func__);
837 return -EINVAL;
838 }
839 switch (unary_expression->u.unary_expression.type) {
840 case UNARY_UNSIGNED_CONSTANT:
841 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
842 return 0;
843 else
844 return 1;
845 case UNARY_SIGNED_CONSTANT:
846 if (unary_expression->u.unary_expression.u.signed_constant == 0)
847 return 0;
848 else
849 return 1;
850 case UNARY_STRING:
851 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
852 return 1;
853 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
854 return 1;
855 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
856 return 0;
857 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
858 return 0;
859 else {
860 fprintf(stderr, "[error] %s: unexpected string \"%s\"\n",
861 __func__, unary_expression->u.unary_expression.u.string);
862 return -EINVAL;
863 }
864 break;
865 default:
866 fprintf(stderr, "[error] %s: unexpected unary expression type\n",
867 __func__);
868 return -EINVAL;
869 }
870
871}
872
873static
874int get_byte_order(int fd, int depth, struct node *unary_expression)
875{
876 int byte_order;
877
878 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
879 fprintf(stderr, "[error] %s: byte_order: expecting string\n",
880 __func__);
881 return -EINVAL;
882 }
883 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
884 byte_order = trace->byte_order;
885 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
886 byte_order = BIG_ENDIAN;
887 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
888 byte_order = BIG_ENDIAN;
889 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
890 byte_order = LITTLE_ENDIAN;
891 else {
892 fprintf(stderr, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
893 __func__, right->u.unary_expression.u.string);
894 return -EINVAL;
895 }
896 return byte_order;
897}
898
899static
900struct declaration *ctf_declaration_integer_visit(int fd, int depth,
901 struct cds_list_head *expressions,
902 struct ctf_trace *trace)
903{
904 struct node *expression;
905 uint64_t alignment, size;
906 int byte_order = trace->byte_order;
907 int signedness = 0;
908 int has_alignment = 0, has_size = 0;
909 struct declaration_integer *integer_declaration;
910
911 cds_list_for_each_entry(expression, expressions, siblings) {
912 struct node *left, *right;
913
914 left = expression->u.ctf_expression.left;
915 right = expression->u.ctf_expression.right;
916 assert(left->u.unary_expression.type == UNARY_STRING);
917 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
918 signedness = get_boolean(fd, depth, right);
919 if (signedness < 0)
920 return NULL;
921 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
922 byte_order = get_byte_order(fd, depth, right);
923 if (byte_order < 0)
924 return NULL;
925 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
926 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
927 fprintf(stderr, "[error] %s: size: expecting unsigned constant\n",
928 __func__);
929 return NULL;
930 }
931 size = right->u.unary_expression.u.unsigned_constant;
932 has_size = 1;
933 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
934 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
935 fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
936 __func__);
937 return NULL;
938 }
939 alignment = right->u.unary_expression.u.unsigned_constant;
940 has_alignment = 1;
941 } else {
942 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
943 __func__, left->u.unary_expression.u.string);
944 return NULL;
945 }
946 }
947 if (!has_size) {
948 fprintf(stderr, "[error] %s: missing size attribute\n", __func__);
949 return NULL;
950 }
951 if (!has_alignment) {
952 if (size % CHAR_BIT) {
953 /* bit-packed alignment */
954 alignment = 1;
955 } else {
956 /* byte-packed alignment */
957 alignment = CHAR_BIT;
958 }
959 }
960 integer_declaration = integer_declaration_new(size,
961 byte_order, signedness, alignment);
962 return &integer_declaration->p;
963}
964
965static
966struct declaration *ctf_declaration_floating_point_visit(int fd, int depth,
967 struct cds_list_head *expressions,
968 struct ctf_trace *trace)
969{
970 struct node *expression;
971 uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
972 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
973 struct declaration_float *float_declaration;
974
975 cds_list_for_each_entry(expression, expressions, siblings) {
976 struct node *left, *right;
977
978 left = expression->u.ctf_expression.left;
979 right = expression->u.ctf_expression.right;
980 assert(left->u.unary_expression.type == UNARY_STRING);
981 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
982 byte_order = get_byte_order(fd, depth, right);
983 if (byte_order < 0)
984 return NULL;
985 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
986 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
987 fprintf(stderr, "[error] %s: exp_dig: expecting unsigned constant\n",
988 __func__);
989 return NULL;
990 }
991 exp_dig = right->u.unary_expression.u.unsigned_constant;
992 has_exp_dig = 1;
993 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
994 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
995 fprintf(stderr, "[error] %s: mant_dig: expecting unsigned constant\n",
996 __func__);
997 return NULL;
998 }
999 mant_dig = right->u.unary_expression.u.unsigned_constant;
1000 has_mant_dig = 1;
1001 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1002 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1003 fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
1004 __func__);
1005 return NULL;
1006 }
1007 alignment = right->u.unary_expression.u.unsigned_constant;
1008 has_alignment = 1;
1009 } else {
1010 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
1011 __func__, left->u.unary_expression.u.string);
1012 return NULL;
1013 }
1014 }
1015 if (!has_mant_dig) {
1016 fprintf(stderr, "[error] %s: missing mant_dig attribute\n", __func__);
1017 return NULL;
1018 }
1019 if (!has_exp_dig) {
1020 fprintf(stderr, "[error] %s: missing exp_dig attribute\n", __func__);
1021 return NULL;
1022 }
1023 if (!has_alignment) {
1024 if ((mant_dig + exp_dig) % CHAR_BIT) {
1025 /* bit-packed alignment */
1026 alignment = 1;
1027 } else {
1028 /* byte-packed alignment */
1029 alignment = CHAR_BIT;
1030 }
1031 }
1032 float_declaration = float_declaration_new(mant_dig, exp_dig,
1033 byte_order, alignment);
1034 return &float_declaration->p;
1035}
1036
1037static
1038struct declaration *ctf_declaration_string_visit(int fd, int depth,
1039 struct cds_list_head *expressions,
1040 struct ctf_trace *trace)
1041{
1042 struct node *expression;
1043 const char *encoding_c = NULL;
1044 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1045 struct declaration_string *string_declaration;
1046
1047 cds_list_for_each_entry(expression, expressions, siblings) {
1048 struct node *left, *right;
1049
1050 left = expression->u.ctf_expression.left;
1051 right = expression->u.ctf_expression.right;
1052 assert(left->u.unary_expression.type == UNARY_STRING);
1053 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1054 if (right->u.unary_expression.type != UNARY_UNSIGNED_STRING) {
1055 fprintf(stderr, "[error] %s: encoding: expecting string\n",
1056 __func__);
1057 return NULL;
1058 }
1059 encoding_c = right->u.unary_expression.u.string;
1060 } else {
1061 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
1062 __func__, left->u.unary_expression.u.string);
1063 return NULL;
1064 }
1065 }
1066 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1067 encoding = CTF_STRING_ASCII;
1068 string_declaration = string_declaration_new(encoding);
1069 return &string_declaration->p;
1070}
1071
1072
1073/*
1074 * Also add named variant, struct or enum to the current declaration scope.
1075 */
1076static
1077struct declaration *ctf_declaration_specifier_visit(FILE *fd,
1078 int depth, struct cds_list_head *head,
1079 struct declaration_scope *declaration_scope,
1080 struct ctf_trace *trace)
1081{
1082 struct declaration *declaration;
1083 struct node *first;
1084
1085 first = _cds_list_first_entry(head, struct node, siblings);
1086
1087 switch (first->type) {
1088 case NODE_STRUCT:
1089 return ctf_declaration_struct_visit(fd, depth,
1090 first->u._struct.name,
1091 &first->u._struct.declaration_list,
1092 first->u._struct.has_body,
1093 declaration_scope,
1094 trace);
1095 case NODE_VARIANT:
1096 return ctf_declaration_variant_visit(fd, depth,
1097 first->u.variant.name,
1098 &first->u.variant.declaration_list,
1099 first->u.variant.has_body,
1100 declaration_scope,
1101 trace);
1102 case NODE_ENUM:
1103 return ctf_declaration_enum_visit(fd, depth,
1104 first->u._enum.enum_id,
1105 &first->u._enum.container_type,
1106 &first->u._enum.enumerator_list,
1107 first->u._enum.has_body,
1108 declaration_scope,
1109 trace);
1110 case NODE_INTEGER:
1111 return ctf_declaration_integer_visit(fd, depth,
1112 &first->u.integer.expressions, trace);
1113 case NODE_FLOATING_POINT:
1114 return ctf_declaration_floating_point_visit(fd, depth,
1115 &first->u.floating_point.expressions, trace);
1116 case NODE_STRING:
1117 return ctf_declaration_string_visit(fd, depth,
1118 &first->u.string.expressions, trace);
1119 case NODE_TYPE_SPECIFIER:
1120 return ctf_declaration_type_specifier_visit(fd, depth,
1121 head, declaration_scope, trace);
1122 }
1123}
1124
1125static
1126int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1127{
1128 int ret = 0;
1129
1130 switch (node->type) {
1131 case NODE_TYPEDEF:
1132 ret = ctf_typedef_visit(fd, depth + 1,
1133 &node->u._typedef.declaration_specifier,
1134 &node->u._typedef.type_declarators,
1135 event->declaration_scope);
1136 if (ret)
1137 return ret;
1138 break;
1139 case NODE_TYPEALIAS:
1140 ret = ctf_typealias_visit(fd, depth + 1,
1141 &node->u.typealias.target, &node->u.typealias.alias
1142 event->declaration_scope);
1143 if (ret)
1144 return ret;
1145 break;
1146 case NODE_CTF_EXPRESSION:
1147 {
1148 char *left;
1149
1150 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1151 if (!strcmp(left, "name")) {
1152 char *right;
1153
1154 if (CTF_EVENT_FIELD_IS_SET(event, name))
1155 return -EPERM;
1156 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1157 if (!right) {
1158 fprintf(stderr, "[error] %s: unexpected unary expression for event name\n", __func__);
1159 return -EINVAL;
1160 }
1161 event->name = g_quark_from_string(right);
1162 g_free(right);
1163 CTF_EVENT_SET_FIELD(event, name);
1164 } else if (!strcmp(left, "id")) {
1165 if (CTF_EVENT_FIELD_IS_SET(event, id))
1166 return -EPERM;
1167 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1168 if (ret) {
1169 fprintf(stderr, "[error] %s: unexpected unary expression for event id\n", __func__);
1170 return -EINVAL;
1171 }
1172 CTF_EVENT_SET_FIELD(event, id);
1173 } else if (!strcmp(left, "stream_id")) {
1174 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
1175 return -EPERM;
1176 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1177 if (ret) {
1178 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1179 return -EINVAL;
1180 }
1181 event->stream = trace_stream_lookup(trace, event->stream_id);
1182 if (!event->stream) {
1183 fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1184 return -EINVAL;
1185 }
1186 CTF_EVENT_SET_FIELD(event, stream_id);
1187 } else if (!strcmp(left, "context")) {
1188 struct declaration *declaration;
1189
1190 if (!event->definition_scope)
1191 return -EPERM;
1192 declaration = ctf_declaration_specifier_visit(fd, depth,
1193 &node->u.ctf_expression.right,
1194 event->declaration_scope, trace);
1195 if (!declaration)
1196 return -EPERM;
1197 if (declaration->type->id != CTF_TYPE_STRUCT)
1198 return -EPERM;
1199 event->context_decl = container_of(declaration, struct declaration_struct, p);
1200 } else if (!strcmp(left, "fields")) {
1201 struct declaration *declaration;
1202
1203 if (!event->definition_scope)
1204 return -EPERM;
1205 declaration = ctf_declaration_specifier_visit(fd, depth,
1206 &node->u.ctf_expression.right,
1207 event->declaration_scope, trace);
1208 if (!declaration)
1209 return -EPERM;
1210 if (declaration->type->id != CTF_TYPE_STRUCT)
1211 return -EPERM;
1212 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1213 }
1214 g_free(left);
1215 break;
1216 }
1217 default:
1218 return -EPERM;
1219 /* TODO: declaration specifier should be added. */
1220 }
1221
1222 return 0;
1223}
1224
1225static
1226int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1227 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1228{
1229 int ret = 0;
1230 struct ctf_node *iter;
1231 struct ctf_event *event;
1232 struct definition_scope *parent_def_scope;
1233
1234 event = g_new0(struct ctf_event, 1);
1235 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1236 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1237 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1238 if (ret)
1239 goto error;
1240 }
1241 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1242 ret = -EPERM;
1243 goto error;
1244 }
1245 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
1246 ret = -EPERM;
1247 goto error;
1248 }
1249 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1250 ret = -EPERM;
1251 goto error;
1252 }
1253 if (event->stream->events_by_id->len <= event->id)
1254 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1255 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1256 g_hash_table_insert(event->stream->event_quark_to_id,
1257 (gpointer)(unsigned long) event->name,
1258 &event->id);
1259 parent_def_scope = stream->definition_scope;
1260 if (event->context_decl) {
1261 event->context =
1262 event->context_decl->definition_new(event->context_decl,
1263 parent_def_scope, 0, 0);
1264 set_dynamic_definition_scope(&event->context->p,
1265 event->context->scope,
1266 "event.context");
1267 parent_def_scope = event->context->scope;
1268 declaration_unref(event->context_decl);
1269 }
1270 if (event->fields_decl) {
1271 event->fields =
1272 event->fields_decl->definition_new(event->fields_decl,
1273 parent_def_scope, 0, 0);
1274 set_dynamic_definition_scope(&event->fields->p,
1275 event->fields->scope,
1276 "event.fields");
1277 parent_def_scope = event->fields->scope;
1278 declaration_unref(event->fields_decl);
1279 }
1280 return 0;
1281
1282error:
1283 declaration_unref(event->fields_decl);
1284 declaration_unref(event->context_decl);
1285 free_definition_scope(event->definition_scope);
1286 free_declaration_scope(event->declaration_scope);
1287 g_free(event);
1288 return ret;
1289}
1290
1291
1292static
1293int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
1294{
1295 int ret = 0;
1296
1297 switch (node->type) {
1298 case NODE_TYPEDEF:
1299 ret = ctf_typedef_visit(fd, depth + 1,
1300 &node->u._typedef.declaration_specifier,
1301 &node->u._typedef.type_declarators,
1302 stream->declaration_scope);
1303 if (ret)
1304 return ret;
1305 break;
1306 case NODE_TYPEALIAS:
1307 ret = ctf_typealias_visit(fd, depth + 1,
1308 &node->u.typealias.target, &node->u.typealias.alias
1309 stream->declaration_scope);
1310 if (ret)
1311 return ret;
1312 break;
1313 case NODE_CTF_EXPRESSION:
1314 {
1315 char *left;
1316
1317 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1318 if (!strcmp(left, "stream_id")) {
1319 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
1320 return -EPERM;
1321 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1322 if (ret) {
1323 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1324 return -EINVAL;
1325 }
1326 CTF_EVENT_SET_FIELD(event, stream_id);
1327 } else if (!strcmp(left, "event.header")) {
1328 struct declaration *declaration;
1329
1330 declaration = ctf_declaration_specifier_visit(fd, depth,
1331 &node->u.ctf_expression.right,
1332 stream->declaration_scope, stream->definition_scope, trace);
1333 if (!declaration)
1334 return -EPERM;
1335 if (declaration->type->id != CTF_TYPE_STRUCT)
1336 return -EPERM;
1337 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1338 } else if (!strcmp(left, "event.context")) {
1339 struct declaration *declaration;
1340
1341 declaration = ctf_declaration_specifier_visit(fd, depth,
1342 &node->u.ctf_expression.right,
1343 stream->declaration_scope, trace);
1344 if (!declaration)
1345 return -EPERM;
1346 if (declaration->type->id != CTF_TYPE_STRUCT)
1347 return -EPERM;
1348 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1349 } else if (!strcmp(left, "packet.context")) {
1350 struct declaration *declaration;
1351
1352 declaration = ctf_declaration_specifier_visit(fd, depth,
1353 &node->u.ctf_expression.right,
1354 stream->declaration_scope, trace);
1355 if (!declaration)
1356 return -EPERM;
1357 if (declaration->type->id != CTF_TYPE_STRUCT)
1358 return -EPERM;
1359 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1360 }
1361 g_free(left);
1362 break;
1363 }
1364 default:
1365 return -EPERM;
1366 /* TODO: declaration specifier should be added. */
1367 }
1368
1369 return 0;
1370}
1371
1372static
1373int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1374 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1375{
1376 int ret = 0;
1377 struct ctf_node *iter;
1378 struct ctf_stream *stream;
1379 struct definition_scope *parent_def_scope;
1380
1381 stream = g_new0(struct ctf_stream, 1);
1382 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1383 stream->events_by_id = g_ptr_array_new();
1384 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
1385 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1386 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1387 if (ret)
1388 goto error;
1389 }
1390 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
1391 ret = -EPERM;
1392 goto error;
1393 }
1394 if (trace->streams->len <= stream->stream_id)
1395 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1396 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
1397
1398 parent_def_scope = NULL;
1399 if (stream->packet_context_decl) {
1400 stream->packet_context =
1401 stream->packet_context_decl->definition_new(stream->packet_context_decl,
1402 parent_def_scope, 0, 0);
1403 set_dynamic_definition_scope(&stream->packet_context->p,
1404 stream->packet_context->scope,
1405 "stream.packet.context");
1406 parent_def_scope = stream->packet_context->scope;
1407 declaration_unref(stream->packet_context_decl);
1408 }
1409 if (stream->event_header_decl) {
1410 stream->event_header =
1411 stream->event_header_decl->definition_new(stream->event_header_decl,
1412 parent_def_scope, 0, 0);
1413 set_dynamic_definition_scope(&stream->event_header->p,
1414 stream->event_header->scope,
1415 "stream.event.header");
1416 parent_def_scope = stream->event_header->scope;
1417 declaration_unref(stream->event_header_decl);
1418 }
1419 if (stream->event_context_decl) {
1420 stream->event_context =
1421 stream->event_context_decl->definition_new(stream->event_context_decl,
1422 parent_def_scope, 0, 0);
1423 set_dynamic_definition_scope(&stream->event_context->p,
1424 stream->event_context->scope,
1425 "stream.event.context");
1426 parent_def_scope = stream->event_context->scope;
1427 declaration_unref(stream->event_context_decl);
1428 }
1429 stream->definition_scope = parent_def_scope;
1430
1431 return 0;
1432
1433error:
1434 declaration_unref(stream->event_header);
1435 declaration_unref(stream->event_context);
1436 declaration_unref(stream->packet_context);
1437 g_ptr_array_free(stream->events_by_id, TRUE);
1438 g_hash_table_free(stream->event_quark_to_id);
1439 free_definition_scope(stream->definition_scope);
1440 free_declaration_scope(stream->declaration_scope);
1441 g_free(stream);
1442 return ret;
1443}
1444
1445static
1446int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1447{
1448 int ret = 0;
1449
1450 switch (node->type) {
1451 case NODE_TYPEDEF:
1452 ret = ctf_typedef_visit(fd, depth + 1,
1453 &node->u._typedef.declaration_specifier,
1454 &node->u._typedef.type_declarators,
1455 trace->declaration_scope);
1456 if (ret)
1457 return ret;
1458 break;
1459 case NODE_TYPEALIAS:
1460 ret = ctf_typealias_visit(fd, depth + 1,
1461 &node->u.typealias.target, &node->u.typealias.alias
1462 trace->declaration_scope);
1463 if (ret)
1464 return ret;
1465 break;
1466 case NODE_CTF_EXPRESSION:
1467 {
1468 char *left;
1469
1470 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1471 if (!strcmp(left, "major")) {
1472 if (CTF_EVENT_FIELD_IS_SET(trace, major))
1473 return -EPERM;
1474 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1475 if (ret) {
1476 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
1477 return -EINVAL;
1478 }
1479 CTF_EVENT_SET_FIELD(trace, major);
1480 } else if (!strcmp(left, "minor")) {
1481 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
1482 return -EPERM;
1483 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1484 if (ret) {
1485 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
1486 return -EINVAL;
1487 }
1488 CTF_EVENT_SET_FIELD(trace, minor);
1489 } else if (!strcmp(left, "word_size")) {
1490 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
1491 return -EPERM;
1492 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
1493 if (ret) {
1494 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
1495 return -EINVAL;
1496 }
1497 CTF_EVENT_SET_FIELD(trace, word_size);
1498 } else if (!strcmp(left, "uuid")) {
1499 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
1500 return -EPERM;
1501 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1502 if (ret) {
1503 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
1504 return -EINVAL;
1505 }
1506 CTF_EVENT_SET_FIELD(trace, uuid);
1507 }
1508 g_free(left);
1509 break;
1510 }
1511 default:
1512 return -EPERM;
1513 /* TODO: declaration specifier should be added. */
1514 }
1515
1516 return 0;
1517}
1518
1519static
1520int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1521{
1522 int ret = 0;
1523 struct ctf_node *iter;
1524
1525 if (trace->declaration_scope)
1526 return -EEXIST;
1527 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
1528 trace->definition_scope = new_dynamic_definition_scope(trace->root_definition_scope);
1529 trace->streams = g_ptr_array_new();
1530 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1531 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1532 if (ret)
1533 goto error;
1534 }
1535 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
1536 ret = -EPERM;
1537 goto error;
1538 }
1539 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
1540 ret = -EPERM;
1541 goto error;
1542 }
1543 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
1544 ret = -EPERM;
1545 goto error;
1546 }
1547 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
1548 ret = -EPERM;
1549 goto error;
1550 }
1551 return 0;
1552
1553error:
1554 g_ptr_array_free(trace->streams, TRUE);
1555 free_definition_scope(stream->definition_scope);
1556 free_declaration_scope(stream->declaration_scope);
1557 return ret;
1558}
1559
1560int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
1561 struct ctf_trace *trace, int byte_order)
1562{
1563 int ret = 0;
1564 struct ctf_node *iter;
1565
1566 trace->byte_order = byte_order;
1567
1568 switch (node->type) {
1569 case NODE_ROOT:
1570 cds_list_for_each_entry(iter, &node->u.root._typedef,
1571 siblings) {
1572 ret = ctf_typedef_visit(fd, depth + 1,
1573 &iter->u._typedef.declaration_specifier,
1574 &iter->u._typedef.type_declarators,
1575 trace->root_declaration_scope);
1576 if (ret)
1577 return ret;
1578 }
1579 cds_list_for_each_entry(iter, &node->u.root.typealias,
1580 siblings) {
1581 ret = ctf_typealias_visit(fd, depth + 1,
1582 &iter->u.typealias.target, &iter->u.typealias.alias
1583 trace->root_declaration_scope);
1584 if (ret)
1585 return ret;
1586 }
1587 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
1588 ret = ctf_declaration_specifier_visit(fd, depth, iter,
1589 trace->root_declaration_scope, trace);
1590 if (ret)
1591 return ret;
1592 }
1593 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
1594 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
1595 if (ret)
1596 return ret;
1597 }
1598 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
1599 ret = ctf_stream_visit(fd, depth + 1, iter,
1600 trace->root_declaration_scope, trace);
1601 if (ret)
1602 return ret;
1603 }
1604 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
1605 ret = ctf_event_visit(fd, depth + 1, iter,
1606 trace->root_declaration_scope, trace);
1607 if (ret)
1608 return ret;
1609 }
1610 break;
1611 case NODE_UNKNOWN:
1612 default:
1613 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
1614 (int) node->type);
1615 return -EINVAL;
1616 }
1617 return ret;
1618}
This page took 0.048038 seconds and 4 git commands to generate.