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