gen io struct visitor: update enum
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
1 /*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <glib.h>
25 #include <inttypes.h>
26 #include <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
39 static
40 struct 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 */
48 static
49 char *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
81 static
82 int 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
98 static
99 int 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
118 static
119 struct 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
126 static
127 void 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;
224 error:
225 return err;
226 }
227
228 static
229 GQuark 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
255 static
256 struct 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
337 static
338 int 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
362 static
363 int 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
387 static
388 int 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
412 static
413 int 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
458 error:
459 type_declaration->declaration_free(type_declaration);
460 return ret;
461 }
462
463 static
464 int 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
505 static
506 int 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
547 static
548 struct 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 }
592 error:
593 struct_declaration->p.declaration_free(&struct_declaration->p);
594 return NULL;
595 }
596
597 static
598 struct 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 }
642 error:
643 variant_declaration->p.declaration_free(&variant_declaration->p);
644 return NULL;
645 }
646
647 static
648 int 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
730 static
731 struct 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 }
803 error:
804 enum_declaration->p.declaration_free(&enum_declaration->p);
805 return NULL;
806 }
807
808 static
809 struct 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 */
831 static
832 int 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
873 static
874 int 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
899 static
900 struct 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
965 static
966 struct 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
1037 static
1038 struct 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 */
1076 static
1077 struct 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
1125 static
1126 int 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
1225 static
1226 int 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
1282 error:
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
1292 static
1293 int 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
1372 static
1373 int 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
1433 error:
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
1445 static
1446 int 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
1519 static
1520 int 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
1553 error:
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
1560 int 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.103028 seconds and 4 git commands to generate.