2eb522cfa35d152ab9e0aba00b1d8316eaeb9289
[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(FILE *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(FILE *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 struct ctf_trace *trace)
263 {
264 /*
265 * Visit type declarator by first taking care of sequence/array
266 * (recursively). Then, when we get to the identifier, take care
267 * of pointers.
268 */
269
270 if (node_type_declarator) {
271 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
272
273 /* TODO: gcc bitfields not supported yet. */
274 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
275 fprintf(stderr, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
276 return NULL;
277 }
278 }
279
280 if (!nested_declaration) {
281 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
282 GQuark alias_q;
283
284 /*
285 * If we have a pointer declarator, it _has_ to be present in
286 * the typealiases (else fail).
287 */
288 alias_q = create_typealias_identifier(fd, depth,
289 declaration_specifier, node_type_declarator);
290 nested_declaration = lookup_declaration(alias_q, declaration_scope);
291 if (!nested_declaration) {
292 fprintf(stderr, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
293 return NULL;
294 }
295 } else {
296 nested_declaration = ctf_declaration_specifier_visit(fd, depth,
297 declaration_specifier, declaration_scope, trace);
298 }
299 }
300
301 if (!node_type_declarator)
302 return nested_declaration;
303
304 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
305 if (node_type_declarator->u.type_declarator.u.id)
306 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
307 else
308 *field_name = 0;
309 return nested_declaration;
310 } else {
311 struct declaration *declaration;
312 struct node *length;
313
314 /* TYPEDEC_NESTED */
315
316 /* create array/sequence, pass nested_declaration as child. */
317 length = node_type_declarator->u.type_declarator.u.nested.length;
318 if (length) {
319 switch (length->type) {
320 case NODE_UNARY_EXPRESSION:
321 {
322 struct declaration_array *array_declaration;
323 size_t len;
324
325 if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
326 fprintf(stderr, "[error] %s: array: unexpected unary expression.\n", __func__);
327 return NULL;
328 }
329 len = length->u.unary_expression.u.unsigned_constant;
330 array_declaration = array_declaration_new(len, nested_declaration,
331 declaration_scope);
332 declaration = &array_declaration->p;
333 break;
334 }
335 case NODE_INTEGER:
336 case NODE_TYPE_SPECIFIER:
337 {
338 struct declaration_sequence *sequence_declaration;
339 struct declaration_integer *integer_declaration;
340 GQuark dummy_id;
341
342 declaration = ctf_type_declarator_visit(fd, depth,
343 length,
344 &dummy_id, NULL,
345 declaration_scope,
346 NULL, trace);
347 assert(declaration->id == CTF_TYPE_INTEGER);
348 integer_declaration = container_of(declaration, struct declaration_integer, p);
349 declaration_sequence = sequence_declaration_new(integer_declaration,
350 nested_declaration, declaration_scope);
351 declaration = &declaration_sequence->p;
352 break;
353 }
354 default:
355 assert(0);
356 }
357 }
358
359 /* Pass it as content of outer container */
360 declaration = ctf_type_declarator_visit(fd, depth,
361 declaration_specifier, field_name,
362 node_type_declarator->u.type_declarator.u.nested.type_declarator,
363 declaration_scope, declaration, trace);
364 return declaration;
365 }
366 }
367
368 static
369 int ctf_struct_type_declarators_visit(FILE *fd, int depth,
370 struct declaration_struct *struct_declaration,
371 struct cds_list_head *declaration_specifier,
372 struct cds_list_head *type_declarators,
373 struct declaration_scope *declaration_scope,
374 struct ctf_trace *trace)
375 {
376 struct ctf_node *iter;
377 GQuark field_name;
378
379 cds_list_for_each_entry(iter, type_declarators, siblings) {
380 struct declaration *field_declaration;
381
382 field_declaration = ctf_type_declarator_visit(fd, depth,
383 declaration_specifier,
384 &field_name, iter,
385 struct_declaration->scope,
386 NULL, trace);
387 struct_declaration_add_field(struct_declaration,
388 g_quark_to_string(field_name),
389 field_declaration);
390 }
391 return 0;
392 }
393
394 static
395 int ctf_variant_type_declarators_visit(FILE *fd, int depth,
396 struct declaration_variant *variant_declaration,
397 struct cds_list_head *declaration_specifier,
398 struct cds_list_head *type_declarators,
399 struct declaration_scope *declaration_scope,
400 struct ctf_trace *trace)
401 {
402 struct ctf_node *iter;
403 GQuark field_name;
404
405 cds_list_for_each_entry(iter, type_declarators, siblings) {
406 struct declaration *field_declaration;
407
408 field_declaration = ctf_type_declarator_visit(fd, depth,
409 declaration_specifier,
410 &field_name, iter,
411 variant_declaration->scope,
412 NULL, trace);
413 variant_declaration_add_field(variant_declaration,
414 g_quark_to_string(field_name),
415 field_declaration);
416 }
417 return 0;
418 }
419
420 static
421 int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
422 struct cds_list_head *declaration_specifier,
423 struct cds_list_head *type_declarators,
424 struct ctf_trace *trace)
425 {
426 struct ctf_node *iter;
427 GQuark identifier;
428
429 cds_list_for_each_entry(iter, type_declarators, siblings) {
430 struct declaration *type_declaration;
431 int ret;
432
433 type_declaration = ctf_type_declarator_visit(fd, depth,
434 declaration_specifier,
435 &identifier, iter,
436 scope, NULL, trace);
437 ret = register_declaration(identifier, type_declaration, scope);
438 if (ret) {
439 type_declaration->declaration_free(type_declaration);
440 return ret;
441 }
442 }
443 return 0;
444 }
445
446 static
447 int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
448 struct ctf_node *target, struct ctf_node *alias,
449 struct ctf_trace *trace)
450 {
451 struct declaration *type_declaration;
452 struct ctf_node *iter, *node;
453 GQuark dummy_id;
454 GQuark alias_q;
455
456 /* See ctf_visitor_type_declarator() in the semantic validator. */
457
458 /*
459 * Create target type declaration.
460 */
461
462 type_declaration = ctf_type_declarator_visit(fd, depth,
463 &target->u.typealias_target.declaration_specifier,
464 &dummy_id, &target->u.typealias_target.type_declarators,
465 scope, NULL, trace);
466 if (!type_declaration) {
467 fprintf(stderr, "[error] %s: problem creating type declaration\n", __func__);
468 err = -EINVAL;
469 goto error;
470 }
471 /*
472 * The semantic validator does not check whether the target is
473 * abstract or not (if it has an identifier). Check it here.
474 */
475 if (dummy_id != 0) {
476 fprintf(stderr, "[error] %s: expecting empty identifier\n", __func__);
477 err = -EINVAL;
478 goto error;
479 }
480 /*
481 * Create alias identifier.
482 */
483
484 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
485 struct node, siblings);
486 alias_q = create_typealias_identifier(fd, depth,
487 &alias->u.typealias_alias.declaration_specifier, node);
488 ret = register_declaration(alias_q, type_declaration, scope);
489 if (ret)
490 goto error;
491 return 0;
492
493 error:
494 type_declaration->declaration_free(type_declaration);
495 return ret;
496 }
497
498 static
499 int ctf_struct_declaration_list_visit(FILE *fd, int depth,
500 struct ctf_node *iter, struct declaration_struct *struct_declaration,
501 struct ctf_trace *trace)
502 {
503 struct declaration *declaration;
504 int ret;
505
506 switch (iter->type) {
507 case NODE_TYPEDEF:
508 /* For each declarator, declare type and add type to struct declaration scope */
509 ret = ctf_typedef_visit(fd, depth,
510 struct_declaration->scope,
511 &iter->u._typedef.declaration_specifier,
512 &iter->u._typedef.type_declarators, trace);
513 if (ret)
514 return ret;
515 break;
516 case NODE_TYPEALIAS:
517 /* Declare type with declarator and add type to struct declaration scope */
518 ret = ctf_typealias_visit(fd, depth,
519 struct_declaration->scope,
520 iter->u.typealias.target,
521 iter->u.typealias.alias, trace);
522 if (ret)
523 return ret;
524 break;
525 case NODE_STRUCT_OR_VARIANT_DECLARATION:
526 /* Add field to structure declaration */
527 ret = ctf_struct_type_declarators_visit(fd, depth,
528 struct_declaration,
529 &iter->u.struct_or_variant_declaration.declaration_specifier,
530 &iter->u.struct_or_variant_declaration.type_declarators, trace);
531 if (ret)
532 return ret;
533 break;
534 default:
535 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
536 assert(0);
537 }
538 return 0;
539 }
540
541 static
542 int ctf_variant_declaration_list_visit(FILE *fd, int depth,
543 struct ctf_node *iter, struct declaration_variant *variant_declaration,
544 struct ctf_trace *trace)
545 {
546 struct declaration *declaration;
547 int ret;
548
549 switch (iter->type) {
550 case NODE_TYPEDEF:
551 /* For each declarator, declare type and add type to variant declaration scope */
552 ret = ctf_typedef_visit(fd, depth,
553 variant_declaration->scope,
554 &iter->u._typedef.declaration_specifier,
555 &iter->u._typedef.type_declarators, trace);
556 if (ret)
557 return ret;
558 break;
559 case NODE_TYPEALIAS:
560 /* Declare type with declarator and add type to variant declaration scope */
561 ret = ctf_typealias_visit(fd, depth,
562 variant_declaration->scope,
563 iter->u.typealias.target,
564 iter->u.typealias.alias, trace);
565 if (ret)
566 return ret;
567 break;
568 case NODE_STRUCT_OR_VARIANT_DECLARATION:
569 /* Add field to structure declaration */
570 ret = ctf_variant_type_declarators_visit(fd, depth,
571 variant_declaration,
572 &iter->u.struct_or_variant_declaration.declaration_specifier,
573 &iter->u.struct_or_variant_declaration.type_declarators, trace);
574 if (ret)
575 return ret;
576 break;
577 default:
578 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
579 assert(0);
580 }
581 return 0;
582 }
583
584 static
585 struct declaration_struct *ctf_declaration_struct_visit(FILE *fd,
586 int depth, const char *name, struct cds_list_head *declaration_list,
587 int has_body, struct declaration_scope *declaration_scope,
588 struct ctf_trace *trace)
589 {
590 struct declaration *declaration;
591 struct declaration_struct *struct_declaration;
592 struct ctf_node *iter;
593
594 /*
595 * For named struct (without body), lookup in
596 * declaration scope. Don't take reference on struct
597 * declaration: ref is only taken upon definition.
598 */
599 if (!has_body) {
600 assert(name);
601 struct_declaration =
602 lookup_struct_declaration(g_quark_from_string(name),
603 declaration_scope);
604 return struct_declaration;
605 } else {
606 /* For unnamed struct, create type */
607 /* For named struct (with body), create type and add to declaration scope */
608 if (name) {
609 if (lookup_struct_declaration(g_quark_from_string(name),
610 declaration_scope)) {
611
612 fprintf(stderr, "[error] %s: struct %s already declared in scope\n", __func__, name);
613 return NULL;
614 }
615 }
616 struct_declaration = struct_declaration_new(name, declaration_scope);
617 cds_list_for_each_entry(iter, declaration_list, siblings) {
618 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
619 struct_declaration, trace);
620 if (ret)
621 goto error;
622 }
623 if (name) {
624 ret = register_struct_declaration(g_quark_from_string(name),
625 struct_declaration,
626 declaration_scope);
627 assert(!ret);
628 }
629 return struct_declaration;
630 }
631 error:
632 struct_declaration->p.declaration_free(&struct_declaration->p);
633 return NULL;
634 }
635
636 static
637 struct declaration_variant *ctf_declaration_variant_visit(FILE *fd,
638 int depth, const char *name, struct cds_list_head *declaration_list,
639 int has_body, struct declaration_scope *declaration_scope,
640 struct ctf_trace *trace)
641 {
642 struct declaration *declaration;
643 struct declaration_variant *variant_declaration;
644 struct ctf_node *iter;
645
646 /*
647 * For named variant (without body), lookup in
648 * declaration scope. Don't take reference on variant
649 * declaration: ref is only taken upon definition.
650 */
651 if (!has_body) {
652 assert(name);
653 variant_declaration =
654 lookup_variant_declaration(g_quark_from_string(name),
655 declaration_scope);
656 return variant_declaration;
657 } else {
658 /* For unnamed variant, create type */
659 /* For named variant (with body), create type and add to declaration scope */
660 if (name) {
661 if (lookup_variant_declaration(g_quark_from_string(name),
662 declaration_scope)) {
663
664 fprintf(stderr, "[error] %s: variant %s already declared in scope\n", __func__, name);
665 return NULL;
666 }
667 }
668 variant_declaration = variant_declaration_new(name, declaration_scope);
669 cds_list_for_each_entry(iter, declaration_list, siblings) {
670 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
671 variant_declaration, trace);
672 if (ret)
673 goto error;
674 }
675 if (name) {
676 ret = register_variant_declaration(g_quark_from_string(name),
677 variant_declaration,
678 declaration_scope);
679 assert(!ret);
680 }
681 return variant_declaration;
682 }
683 error:
684 variant_declaration->p.declaration_free(&variant_declaration->p);
685 return NULL;
686 }
687
688 static
689 int ctf_enumerator_list_visit(FILE *fd, int depth,
690 struct ctf_node *enumerator,
691 struct declaration_enum *enum_declaration)
692 {
693 GQuark q;
694 struct ctf_node *iter;
695
696 q = g_quark_from_string(enumerator->u.enumerator.id);
697 if (enum_declaration->integer->signedness) {
698 int64_t start, end;
699 int nr_vals = 0;
700
701 cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) {
702 int64_t *target;
703
704 assert(iter->type == NODE_UNARY_EXPRESSION);
705 if (nr_vals == 0)
706 target = &start;
707 else
708 target = &end;
709
710 switch (iter->u.unary_expression.type) {
711 case UNARY_SIGNED_CONSTANT:
712 *target = iter->u.unary_expression.u.signed_constant;
713 break;
714 case UNARY_UNSIGNED_CONSTANT:
715 *target = iter->u.unary_expression.u.unsigned_constant;
716 break;
717 default:
718 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
719 return -EINVAL;
720 }
721 if (nr_vals > 1) {
722 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
723 return -EINVAL;
724 }
725 nr_vals++;
726 }
727 if (nr_vals == 1)
728 end = start;
729 enum_signed_insert(enum_declaration, start, end, q);
730 } else
731 uint64_t start, end;
732 int nr_vals = 0;
733
734 cds_list_for_each_entry(iter, enumerator->u.enumerator.values, siblings) {
735 int64_t *target;
736
737 assert(iter->type == NODE_UNARY_EXPRESSION);
738 if (nr_vals == 0)
739 target = &start;
740 else
741 target = &end;
742
743 switch (iter->u.unary_expression.type) {
744 case UNARY_UNSIGNED_CONSTANT:
745 *target = iter->u.unary_expression.u.unsigned_constant;
746 break;
747 case UNARY_SIGNED_CONSTANT:
748 /*
749 * We don't accept signed constants for enums with unsigned
750 * container type.
751 */
752 fprintf(stderr, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
753 return -EINVAL;
754 default:
755 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
756 return -EINVAL;
757 }
758 if (nr_vals > 1) {
759 fprintf(stderr, "[error] %s: invalid enumerator\n", __func__);
760 return -EINVAL;
761 }
762 nr_vals++;
763 }
764 if (nr_vals == 1)
765 end = start;
766 enum_unsigned_insert(enum_declaration, start, end, q);
767 }
768 return 0;
769 }
770
771 static
772 struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
773 const char *name,
774 struct cds_list_head *container_type,
775 struct cds_list_head *enumerator_list,
776 int has_body,
777 struct declaration_scope *declaration_scope,
778 struct ctf_trace *trace)
779 {
780 struct declaration *declaration;
781 struct declaration_enum *enum_declaration;
782 struct declaration_integer *integer_declaration;
783 struct ctf_node *iter, *first;
784 GQuark dummy_id;
785
786 /*
787 * For named enum (without body), lookup in
788 * declaration scope. Don't take reference on enum
789 * declaration: ref is only taken upon definition.
790 */
791 if (!has_body) {
792 assert(name);
793 enum_declaration =
794 lookup_enum_declaration(g_quark_from_string(name),
795 declaration_scope);
796 return enum_declaration;
797 } else {
798 /* For unnamed enum, create type */
799 /* For named enum (with body), create type and add to declaration scope */
800 if (name) {
801 if (lookup_enum_declaration(g_quark_from_string(name),
802 declaration_scope)) {
803
804 fprintf(stderr, "[error] %s: enum %s already declared in scope\n", __func__, name);
805 return NULL;
806 }
807 }
808 if (cds_list_empty(container_type)) {
809 fprintf(stderr, "[error] %s: missing container type for enumeration\n", __func__, name);
810 return NULL;
811
812 }
813 first = _cds_list_first_entry(container_type, struct node, siblings);
814 switch (first->type) {
815 case NODE_INTEGER:
816 case NODE_TYPE_SPECIFIER:
817 declaration = ctf_type_declarator_visit(fd, depth,
818 container_type,
819 &dummy_id, NULL,
820 declaration_scope,
821 NULL, trace);
822 assert(declaration->id == CTF_TYPE_INTEGER);
823 integer_declaration = container_of(declaration, struct declaration_integer, p);
824 break;
825 }
826 default:
827 assert(0);
828 }
829 enum_declaration = enum_declaration_new(name, integer_declaration);
830 declaration_unref(&integer_declaration->p); /* leave ref to enum */
831 cds_list_for_each_entry(iter, enumerator_list, siblings) {
832 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
833 if (ret)
834 goto error;
835 }
836 if (name) {
837 ret = register_enum_declaration(g_quark_from_string(name),
838 enum_declaration,
839 declaration_scope);
840 assert(!ret);
841 }
842 return enum_declaration;
843 }
844 error:
845 enum_declaration->p.declaration_free(&enum_declaration->p);
846 return NULL;
847 }
848
849 static
850 struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
851 struct cds_list_head *declaration_specifier,
852 struct declaration_scope *declaration_scope)
853 {
854 GString *str;
855 struct declaration *declaration;
856 const char *str_c;
857
858 str = g_string_new();
859 ret = visit_declaration_specifier(declaration_specifier, str);
860 if (ret)
861 return NULL;
862 str_c = g_string_free(str, FALSE);
863 id_q = g_quark_from_string(str_c);
864 g_free(str_c);
865 declaration = lookup_declaration(id_q, declaration_scope);
866 return declaration;
867 }
868
869 /*
870 * Returns 0/1 boolean, or < 0 on error.
871 */
872 static
873 int get_boolean(FILE *fd, int depth, struct node *unary_expression)
874 {
875 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
876 fprintf(stderr, "[error] %s: expecting unary expression\n",
877 __func__);
878 return -EINVAL;
879 }
880 switch (unary_expression->u.unary_expression.type) {
881 case UNARY_UNSIGNED_CONSTANT:
882 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
883 return 0;
884 else
885 return 1;
886 case UNARY_SIGNED_CONSTANT:
887 if (unary_expression->u.unary_expression.u.signed_constant == 0)
888 return 0;
889 else
890 return 1;
891 case UNARY_STRING:
892 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
893 return 1;
894 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
895 return 1;
896 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
897 return 0;
898 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
899 return 0;
900 else {
901 fprintf(stderr, "[error] %s: unexpected string \"%s\"\n",
902 __func__, unary_expression->u.unary_expression.u.string);
903 return -EINVAL;
904 }
905 break;
906 default:
907 fprintf(stderr, "[error] %s: unexpected unary expression type\n",
908 __func__);
909 return -EINVAL;
910 }
911
912 }
913
914 static
915 int get_byte_order(FILE *fd, int depth, struct node *unary_expression)
916 {
917 int byte_order;
918
919 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
920 fprintf(stderr, "[error] %s: byte_order: expecting string\n",
921 __func__);
922 return -EINVAL;
923 }
924 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
925 byte_order = trace->byte_order;
926 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
927 byte_order = BIG_ENDIAN;
928 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
929 byte_order = BIG_ENDIAN;
930 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
931 byte_order = LITTLE_ENDIAN;
932 else {
933 fprintf(stderr, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
934 __func__, right->u.unary_expression.u.string);
935 return -EINVAL;
936 }
937 return byte_order;
938 }
939
940 static
941 struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
942 struct cds_list_head *expressions,
943 struct ctf_trace *trace)
944 {
945 struct node *expression;
946 uint64_t alignment, size;
947 int byte_order = trace->byte_order;
948 int signedness = 0;
949 int has_alignment = 0, has_size = 0;
950 struct declaration_integer *integer_declaration;
951
952 cds_list_for_each_entry(expression, expressions, siblings) {
953 struct node *left, *right;
954
955 left = expression->u.ctf_expression.left;
956 right = expression->u.ctf_expression.right;
957 assert(left->u.unary_expression.type == UNARY_STRING);
958 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
959 signedness = get_boolean(fd, depth, right);
960 if (signedness < 0)
961 return NULL;
962 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
963 byte_order = get_byte_order(fd, depth, right);
964 if (byte_order < 0)
965 return NULL;
966 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
967 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
968 fprintf(stderr, "[error] %s: size: expecting unsigned constant\n",
969 __func__);
970 return NULL;
971 }
972 size = right->u.unary_expression.u.unsigned_constant;
973 has_size = 1;
974 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
975 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
976 fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
977 __func__);
978 return NULL;
979 }
980 alignment = right->u.unary_expression.u.unsigned_constant;
981 has_alignment = 1;
982 } else {
983 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
984 __func__, left->u.unary_expression.u.string);
985 return NULL;
986 }
987 }
988 if (!has_size) {
989 fprintf(stderr, "[error] %s: missing size attribute\n", __func__);
990 return NULL;
991 }
992 if (!has_alignment) {
993 if (size % CHAR_BIT) {
994 /* bit-packed alignment */
995 alignment = 1;
996 } else {
997 /* byte-packed alignment */
998 alignment = CHAR_BIT;
999 }
1000 }
1001 integer_declaration = integer_declaration_new(size,
1002 byte_order, signedness, alignment);
1003 return &integer_declaration->p;
1004 }
1005
1006 static
1007 struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
1008 struct cds_list_head *expressions,
1009 struct ctf_trace *trace)
1010 {
1011 struct node *expression;
1012 uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
1013 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1014 struct declaration_float *float_declaration;
1015
1016 cds_list_for_each_entry(expression, expressions, siblings) {
1017 struct node *left, *right;
1018
1019 left = expression->u.ctf_expression.left;
1020 right = expression->u.ctf_expression.right;
1021 assert(left->u.unary_expression.type == UNARY_STRING);
1022 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1023 byte_order = get_byte_order(fd, depth, right);
1024 if (byte_order < 0)
1025 return NULL;
1026 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1027 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1028 fprintf(stderr, "[error] %s: exp_dig: expecting unsigned constant\n",
1029 __func__);
1030 return NULL;
1031 }
1032 exp_dig = right->u.unary_expression.u.unsigned_constant;
1033 has_exp_dig = 1;
1034 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1035 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1036 fprintf(stderr, "[error] %s: mant_dig: expecting unsigned constant\n",
1037 __func__);
1038 return NULL;
1039 }
1040 mant_dig = right->u.unary_expression.u.unsigned_constant;
1041 has_mant_dig = 1;
1042 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1043 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1044 fprintf(stderr, "[error] %s: align: expecting unsigned constant\n",
1045 __func__);
1046 return NULL;
1047 }
1048 alignment = right->u.unary_expression.u.unsigned_constant;
1049 has_alignment = 1;
1050 } else {
1051 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
1052 __func__, left->u.unary_expression.u.string);
1053 return NULL;
1054 }
1055 }
1056 if (!has_mant_dig) {
1057 fprintf(stderr, "[error] %s: missing mant_dig attribute\n", __func__);
1058 return NULL;
1059 }
1060 if (!has_exp_dig) {
1061 fprintf(stderr, "[error] %s: missing exp_dig attribute\n", __func__);
1062 return NULL;
1063 }
1064 if (!has_alignment) {
1065 if ((mant_dig + exp_dig) % CHAR_BIT) {
1066 /* bit-packed alignment */
1067 alignment = 1;
1068 } else {
1069 /* byte-packed alignment */
1070 alignment = CHAR_BIT;
1071 }
1072 }
1073 float_declaration = float_declaration_new(mant_dig, exp_dig,
1074 byte_order, alignment);
1075 return &float_declaration->p;
1076 }
1077
1078 static
1079 struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
1080 struct cds_list_head *expressions,
1081 struct ctf_trace *trace)
1082 {
1083 struct node *expression;
1084 const char *encoding_c = NULL;
1085 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1086 struct declaration_string *string_declaration;
1087
1088 cds_list_for_each_entry(expression, expressions, siblings) {
1089 struct node *left, *right;
1090
1091 left = expression->u.ctf_expression.left;
1092 right = expression->u.ctf_expression.right;
1093 assert(left->u.unary_expression.type == UNARY_STRING);
1094 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1095 if (right->u.unary_expression.type != UNARY_UNSIGNED_STRING) {
1096 fprintf(stderr, "[error] %s: encoding: expecting string\n",
1097 __func__);
1098 return NULL;
1099 }
1100 encoding_c = right->u.unary_expression.u.string;
1101 } else {
1102 fprintf(stderr, "[error] %s: unknown attribute name %s\n",
1103 __func__, left->u.unary_expression.u.string);
1104 return NULL;
1105 }
1106 }
1107 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1108 encoding = CTF_STRING_ASCII;
1109 string_declaration = string_declaration_new(encoding);
1110 return &string_declaration->p;
1111 }
1112
1113
1114 /*
1115 * Also add named variant, struct or enum to the current declaration scope.
1116 */
1117 static
1118 struct declaration *ctf_declaration_specifier_visit(FILE *fd,
1119 int depth, struct cds_list_head *head,
1120 struct declaration_scope *declaration_scope,
1121 struct ctf_trace *trace)
1122 {
1123 struct declaration *declaration;
1124 struct node *first;
1125
1126 first = _cds_list_first_entry(head, struct node, siblings);
1127
1128 switch (first->type) {
1129 case NODE_STRUCT:
1130 return ctf_declaration_struct_visit(fd, depth,
1131 first->u._struct.name,
1132 &first->u._struct.declaration_list,
1133 first->u._struct.has_body,
1134 declaration_scope,
1135 trace);
1136 case NODE_VARIANT:
1137 return ctf_declaration_variant_visit(fd, depth,
1138 first->u.variant.name,
1139 &first->u.variant.declaration_list,
1140 first->u.variant.has_body,
1141 declaration_scope,
1142 trace);
1143 case NODE_ENUM:
1144 return ctf_declaration_enum_visit(fd, depth,
1145 first->u._enum.enum_id,
1146 &first->u._enum.container_type,
1147 &first->u._enum.enumerator_list,
1148 first->u._enum.has_body,
1149 declaration_scope,
1150 trace);
1151 case NODE_INTEGER:
1152 return ctf_declaration_integer_visit(fd, depth,
1153 &first->u.integer.expressions, trace);
1154 case NODE_FLOATING_POINT:
1155 return ctf_declaration_floating_point_visit(fd, depth,
1156 &first->u.floating_point.expressions, trace);
1157 case NODE_STRING:
1158 return ctf_declaration_string_visit(fd, depth,
1159 &first->u.string.expressions, trace);
1160 case NODE_TYPE_SPECIFIER:
1161 return ctf_declaration_type_specifier_visit(fd, depth,
1162 head, declaration_scope, trace);
1163 }
1164 }
1165
1166 static
1167 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1168 {
1169 int ret = 0;
1170
1171 switch (node->type) {
1172 case NODE_TYPEDEF:
1173 ret = ctf_typedef_visit(fd, depth + 1,
1174 &node->u._typedef.declaration_specifier,
1175 &node->u._typedef.type_declarators,
1176 event->declaration_scope);
1177 if (ret)
1178 return ret;
1179 break;
1180 case NODE_TYPEALIAS:
1181 ret = ctf_typealias_visit(fd, depth + 1,
1182 &node->u.typealias.target, &node->u.typealias.alias
1183 event->declaration_scope);
1184 if (ret)
1185 return ret;
1186 break;
1187 case NODE_CTF_EXPRESSION:
1188 {
1189 char *left;
1190
1191 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1192 if (!strcmp(left, "name")) {
1193 char *right;
1194
1195 if (CTF_EVENT_FIELD_IS_SET(event, name))
1196 return -EPERM;
1197 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1198 if (!right) {
1199 fprintf(stderr, "[error] %s: unexpected unary expression for event name\n", __func__);
1200 return -EINVAL;
1201 }
1202 event->name = g_quark_from_string(right);
1203 g_free(right);
1204 CTF_EVENT_SET_FIELD(event, name);
1205 } else if (!strcmp(left, "id")) {
1206 if (CTF_EVENT_FIELD_IS_SET(event, id))
1207 return -EPERM;
1208 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1209 if (ret) {
1210 fprintf(stderr, "[error] %s: unexpected unary expression for event id\n", __func__);
1211 return -EINVAL;
1212 }
1213 CTF_EVENT_SET_FIELD(event, id);
1214 } else if (!strcmp(left, "stream_id")) {
1215 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
1216 return -EPERM;
1217 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1218 if (ret) {
1219 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1220 return -EINVAL;
1221 }
1222 event->stream = trace_stream_lookup(trace, event->stream_id);
1223 if (!event->stream) {
1224 fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1225 return -EINVAL;
1226 }
1227 CTF_EVENT_SET_FIELD(event, stream_id);
1228 } else if (!strcmp(left, "context")) {
1229 struct declaration *declaration;
1230
1231 if (!event->definition_scope)
1232 return -EPERM;
1233 declaration = ctf_declaration_specifier_visit(fd, depth,
1234 &node->u.ctf_expression.right,
1235 event->declaration_scope, trace);
1236 if (!declaration)
1237 return -EPERM;
1238 if (declaration->type->id != CTF_TYPE_STRUCT)
1239 return -EPERM;
1240 event->context_decl = container_of(declaration, struct declaration_struct, p);
1241 } else if (!strcmp(left, "fields")) {
1242 struct declaration *declaration;
1243
1244 if (!event->definition_scope)
1245 return -EPERM;
1246 declaration = ctf_declaration_specifier_visit(fd, depth,
1247 &node->u.ctf_expression.right,
1248 event->declaration_scope, trace);
1249 if (!declaration)
1250 return -EPERM;
1251 if (declaration->type->id != CTF_TYPE_STRUCT)
1252 return -EPERM;
1253 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1254 }
1255 g_free(left);
1256 break;
1257 }
1258 default:
1259 return -EPERM;
1260 /* TODO: declaration specifier should be added. */
1261 }
1262
1263 return 0;
1264 }
1265
1266 static
1267 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1268 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1269 {
1270 int ret = 0;
1271 struct ctf_node *iter;
1272 struct ctf_event *event;
1273 struct definition_scope *parent_def_scope;
1274
1275 event = g_new0(struct ctf_event, 1);
1276 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1277 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1278 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1279 if (ret)
1280 goto error;
1281 }
1282 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1283 ret = -EPERM;
1284 goto error;
1285 }
1286 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
1287 ret = -EPERM;
1288 goto error;
1289 }
1290 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1291 ret = -EPERM;
1292 goto error;
1293 }
1294 if (event->stream->events_by_id->len <= event->id)
1295 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1296 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1297 g_hash_table_insert(event->stream->event_quark_to_id,
1298 (gpointer)(unsigned long) event->name,
1299 &event->id);
1300 parent_def_scope = stream->definition_scope;
1301 if (event->context_decl) {
1302 event->context =
1303 event->context_decl->definition_new(event->context_decl,
1304 parent_def_scope, 0, 0);
1305 set_dynamic_definition_scope(&event->context->p,
1306 event->context->scope,
1307 "event.context");
1308 parent_def_scope = event->context->scope;
1309 declaration_unref(event->context_decl);
1310 }
1311 if (event->fields_decl) {
1312 event->fields =
1313 event->fields_decl->definition_new(event->fields_decl,
1314 parent_def_scope, 0, 0);
1315 set_dynamic_definition_scope(&event->fields->p,
1316 event->fields->scope,
1317 "event.fields");
1318 parent_def_scope = event->fields->scope;
1319 declaration_unref(event->fields_decl);
1320 }
1321 return 0;
1322
1323 error:
1324 declaration_unref(event->fields_decl);
1325 declaration_unref(event->context_decl);
1326 free_definition_scope(event->definition_scope);
1327 free_declaration_scope(event->declaration_scope);
1328 g_free(event);
1329 return ret;
1330 }
1331
1332
1333 static
1334 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
1335 {
1336 int ret = 0;
1337
1338 switch (node->type) {
1339 case NODE_TYPEDEF:
1340 ret = ctf_typedef_visit(fd, depth + 1,
1341 &node->u._typedef.declaration_specifier,
1342 &node->u._typedef.type_declarators,
1343 stream->declaration_scope);
1344 if (ret)
1345 return ret;
1346 break;
1347 case NODE_TYPEALIAS:
1348 ret = ctf_typealias_visit(fd, depth + 1,
1349 &node->u.typealias.target, &node->u.typealias.alias
1350 stream->declaration_scope);
1351 if (ret)
1352 return ret;
1353 break;
1354 case NODE_CTF_EXPRESSION:
1355 {
1356 char *left;
1357
1358 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1359 if (!strcmp(left, "stream_id")) {
1360 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
1361 return -EPERM;
1362 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1363 if (ret) {
1364 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1365 return -EINVAL;
1366 }
1367 CTF_EVENT_SET_FIELD(event, stream_id);
1368 } else if (!strcmp(left, "event.header")) {
1369 struct declaration *declaration;
1370
1371 declaration = ctf_declaration_specifier_visit(fd, depth,
1372 &node->u.ctf_expression.right,
1373 stream->declaration_scope, stream->definition_scope, trace);
1374 if (!declaration)
1375 return -EPERM;
1376 if (declaration->type->id != CTF_TYPE_STRUCT)
1377 return -EPERM;
1378 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1379 } else if (!strcmp(left, "event.context")) {
1380 struct declaration *declaration;
1381
1382 declaration = ctf_declaration_specifier_visit(fd, depth,
1383 &node->u.ctf_expression.right,
1384 stream->declaration_scope, trace);
1385 if (!declaration)
1386 return -EPERM;
1387 if (declaration->type->id != CTF_TYPE_STRUCT)
1388 return -EPERM;
1389 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1390 } else if (!strcmp(left, "packet.context")) {
1391 struct declaration *declaration;
1392
1393 declaration = ctf_declaration_specifier_visit(fd, depth,
1394 &node->u.ctf_expression.right,
1395 stream->declaration_scope, trace);
1396 if (!declaration)
1397 return -EPERM;
1398 if (declaration->type->id != CTF_TYPE_STRUCT)
1399 return -EPERM;
1400 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1401 }
1402 g_free(left);
1403 break;
1404 }
1405 default:
1406 return -EPERM;
1407 /* TODO: declaration specifier should be added. */
1408 }
1409
1410 return 0;
1411 }
1412
1413 static
1414 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1415 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1416 {
1417 int ret = 0;
1418 struct ctf_node *iter;
1419 struct ctf_stream *stream;
1420 struct definition_scope *parent_def_scope;
1421
1422 stream = g_new0(struct ctf_stream, 1);
1423 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1424 stream->events_by_id = g_ptr_array_new();
1425 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
1426 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1427 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1428 if (ret)
1429 goto error;
1430 }
1431 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
1432 ret = -EPERM;
1433 goto error;
1434 }
1435 if (trace->streams->len <= stream->stream_id)
1436 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1437 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
1438
1439 parent_def_scope = NULL;
1440 if (stream->packet_context_decl) {
1441 stream->packet_context =
1442 stream->packet_context_decl->definition_new(stream->packet_context_decl,
1443 parent_def_scope, 0, 0);
1444 set_dynamic_definition_scope(&stream->packet_context->p,
1445 stream->packet_context->scope,
1446 "stream.packet.context");
1447 parent_def_scope = stream->packet_context->scope;
1448 declaration_unref(stream->packet_context_decl);
1449 }
1450 if (stream->event_header_decl) {
1451 stream->event_header =
1452 stream->event_header_decl->definition_new(stream->event_header_decl,
1453 parent_def_scope, 0, 0);
1454 set_dynamic_definition_scope(&stream->event_header->p,
1455 stream->event_header->scope,
1456 "stream.event.header");
1457 parent_def_scope = stream->event_header->scope;
1458 declaration_unref(stream->event_header_decl);
1459 }
1460 if (stream->event_context_decl) {
1461 stream->event_context =
1462 stream->event_context_decl->definition_new(stream->event_context_decl,
1463 parent_def_scope, 0, 0);
1464 set_dynamic_definition_scope(&stream->event_context->p,
1465 stream->event_context->scope,
1466 "stream.event.context");
1467 parent_def_scope = stream->event_context->scope;
1468 declaration_unref(stream->event_context_decl);
1469 }
1470 stream->definition_scope = parent_def_scope;
1471
1472 return 0;
1473
1474 error:
1475 declaration_unref(stream->event_header);
1476 declaration_unref(stream->event_context);
1477 declaration_unref(stream->packet_context);
1478 g_ptr_array_free(stream->events_by_id, TRUE);
1479 g_hash_table_free(stream->event_quark_to_id);
1480 free_definition_scope(stream->definition_scope);
1481 free_declaration_scope(stream->declaration_scope);
1482 g_free(stream);
1483 return ret;
1484 }
1485
1486 static
1487 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1488 {
1489 int ret = 0;
1490
1491 switch (node->type) {
1492 case NODE_TYPEDEF:
1493 ret = ctf_typedef_visit(fd, depth + 1,
1494 &node->u._typedef.declaration_specifier,
1495 &node->u._typedef.type_declarators,
1496 trace->declaration_scope);
1497 if (ret)
1498 return ret;
1499 break;
1500 case NODE_TYPEALIAS:
1501 ret = ctf_typealias_visit(fd, depth + 1,
1502 &node->u.typealias.target, &node->u.typealias.alias
1503 trace->declaration_scope);
1504 if (ret)
1505 return ret;
1506 break;
1507 case NODE_CTF_EXPRESSION:
1508 {
1509 char *left;
1510
1511 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1512 if (!strcmp(left, "major")) {
1513 if (CTF_EVENT_FIELD_IS_SET(trace, major))
1514 return -EPERM;
1515 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1516 if (ret) {
1517 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
1518 return -EINVAL;
1519 }
1520 CTF_EVENT_SET_FIELD(trace, major);
1521 } else if (!strcmp(left, "minor")) {
1522 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
1523 return -EPERM;
1524 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1525 if (ret) {
1526 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
1527 return -EINVAL;
1528 }
1529 CTF_EVENT_SET_FIELD(trace, minor);
1530 } else if (!strcmp(left, "word_size")) {
1531 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
1532 return -EPERM;
1533 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
1534 if (ret) {
1535 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
1536 return -EINVAL;
1537 }
1538 CTF_EVENT_SET_FIELD(trace, word_size);
1539 } else if (!strcmp(left, "uuid")) {
1540 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
1541 return -EPERM;
1542 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1543 if (ret) {
1544 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
1545 return -EINVAL;
1546 }
1547 CTF_EVENT_SET_FIELD(trace, uuid);
1548 }
1549 g_free(left);
1550 break;
1551 }
1552 default:
1553 return -EPERM;
1554 /* TODO: declaration specifier should be added. */
1555 }
1556
1557 return 0;
1558 }
1559
1560 static
1561 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1562 {
1563 int ret = 0;
1564 struct ctf_node *iter;
1565
1566 if (trace->declaration_scope)
1567 return -EEXIST;
1568 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
1569 trace->definition_scope = new_dynamic_definition_scope(trace->root_definition_scope);
1570 trace->streams = g_ptr_array_new();
1571 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1572 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1573 if (ret)
1574 goto error;
1575 }
1576 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
1577 ret = -EPERM;
1578 goto error;
1579 }
1580 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
1581 ret = -EPERM;
1582 goto error;
1583 }
1584 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
1585 ret = -EPERM;
1586 goto error;
1587 }
1588 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
1589 ret = -EPERM;
1590 goto error;
1591 }
1592 return 0;
1593
1594 error:
1595 g_ptr_array_free(trace->streams, TRUE);
1596 free_definition_scope(stream->definition_scope);
1597 free_declaration_scope(stream->declaration_scope);
1598 return ret;
1599 }
1600
1601 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
1602 struct ctf_trace *trace, int byte_order)
1603 {
1604 int ret = 0;
1605 struct ctf_node *iter;
1606
1607 trace->byte_order = byte_order;
1608
1609 switch (node->type) {
1610 case NODE_ROOT:
1611 cds_list_for_each_entry(iter, &node->u.root._typedef,
1612 siblings) {
1613 ret = ctf_typedef_visit(fd, depth + 1,
1614 &iter->u._typedef.declaration_specifier,
1615 &iter->u._typedef.type_declarators,
1616 trace->root_declaration_scope);
1617 if (ret)
1618 return ret;
1619 }
1620 cds_list_for_each_entry(iter, &node->u.root.typealias,
1621 siblings) {
1622 ret = ctf_typealias_visit(fd, depth + 1,
1623 &iter->u.typealias.target, &iter->u.typealias.alias
1624 trace->root_declaration_scope);
1625 if (ret)
1626 return ret;
1627 }
1628 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
1629 ret = ctf_declaration_specifier_visit(fd, depth, iter,
1630 trace->root_declaration_scope, trace);
1631 if (ret)
1632 return ret;
1633 }
1634 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
1635 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
1636 if (ret)
1637 return ret;
1638 }
1639 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
1640 ret = ctf_stream_visit(fd, depth + 1, iter,
1641 trace->root_declaration_scope, trace);
1642 if (ret)
1643 return ret;
1644 }
1645 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
1646 ret = ctf_event_visit(fd, depth + 1, iter,
1647 trace->root_declaration_scope, trace);
1648 if (ret)
1649 return ret;
1650 }
1651 break;
1652 case NODE_UNKNOWN:
1653 default:
1654 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
1655 (int) node->type);
1656 return -EINVAL;
1657 }
1658 return ret;
1659 }
This page took 0.106956 seconds and 3 git commands to generate.