gen io structs: int fd -> FILE *fd
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
CommitLineData
05628561
MD
1/*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19#include <stdio.h>
20#include <unistd.h>
21#include <string.h>
22#include <stdlib.h>
23#include <assert.h>
24#include <glib.h>
25#include <inttypes.h>
add40b62 26#include <endian.h>
05628561
MD
27#include <errno.h>
28#include <babeltrace/list.h>
41253107 29#include <uuid/uuid.h>
05628561
MD
30#include "ctf-scanner.h"
31#include "ctf-parser.h"
32#include "ctf-ast.h"
33
34#define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
35
de47353a
MD
36#define _cds_list_first_entry(ptr, type, member) \
37 cds_list_entry((ptr)->next, type, member)
05628561 38
a3cca9e9
MD
39static
40struct declaration *ctf_declaration_specifier_visit(FILE *fd,
add40b62 41 int depth, struct cds_list_head *head,
ab4cf058
MD
42 struct declaration_scope *declaration_scope,
43 struct ctf_trace *trace);
a3cca9e9 44
05628561 45/*
41253107 46 * String returned must be freed by the caller using g_free.
05628561
MD
47 */
48static
add40b62 49char *concatenate_unary_strings(struct cds_list_head *head)
05628561 50{
41253107
MD
51 struct ctf_node *node;
52 GString *str;
53 int i = 0;
54
55 str = g_string_new();
56 cds_list_for_each_entry(node, head, siblings) {
57 char *src_string;
58
59 assert(node->type == NODE_UNARY_EXPRESSION);
60 assert(node->u.unary_expression.type == UNARY_STRING);
61 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
62 ^ (i != 0))
63 switch (node->u.unary_expression.link) {
64 case UNARY_DOTLINK:
65 g_string_append(str, ".")
66 break;
67 case UNARY_ARROWLINK:
68 g_string_append(str, "->")
69 break;
70 case UNARY_DOTDOTDOT:
71 g_string_append(str, "...")
72 break;
73 }
74 src_string = u.unary_expression.u.string;
75 g_string_append(str, src_string);
76 i++;
77 }
78 return g_string_free(str, FALSE);
05628561
MD
79}
80
81static
add40b62 82int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
05628561 83{
41253107
MD
84 struct ctf_node *node;
85 int i = 0;
86
87 cds_list_for_each_entry(node, head, siblings) {
88 assert(node->type == NODE_UNARY_EXPRESSION);
89 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
90 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
91 assert(i == 0);
92 *value = node->u.unary_expression.unsigned_constant
93 i++;
94 }
95 return 0;
05628561
MD
96}
97
98static
add40b62 99int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
05628561 100{
41253107
MD
101 struct ctf_node *node;
102 int i = 0;
103 int ret = -1;
104
105 cds_list_for_each_entry(node, head, siblings) {
106 const char *src_string;
107
108 assert(node->type == NODE_UNARY_EXPRESSION);
109 assert(node->u.unary_expression.type == UNARY_STRING);
110 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
111 assert(i == 0);
112 src_string = u.unary_expression.u.string;
113 ret = uuid_parse(u.unary_expression.u.string, *uuid);
114 }
115 return ret;
05628561
MD
116}
117
118static
119struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
120{
121 if (trace->streams->len <= stream_id)
122 return NULL;
123 return g_ptr_array_index(trace->streams, stream_id);
124}
125
add40b62
MD
126static
127void visit_declaration_specifier(struct cds_list_head *declaration_specifier, GString *str)
128{
129 struct ctf_node *iter;
130 int alias_item_nr = 0;
131 int err;
132
133 cds_list_for_each_entry(iter, declaration_specifier, siblings) {
134 if (alias_item_nr != 0)
135 g_string_append(str, " ");
136 alias_item_nr++;
137
138 switch (iter->type) {
139 case NODE_TYPE_SPECIFIER:
140 switch (iter->u.type_specifier.type) {
141 case TYPESPEC_VOID:
142 g_string_append(str, "void");
143 break;
144 case TYPESPEC_CHAR:
145 g_string_append(str, "char");
146 break;
147 case TYPESPEC_SHORT:
148 g_string_append(str, "short");
149 break;
150 case TYPESPEC_INT:
151 g_string_append(str, "int");
152 break;
153 case TYPESPEC_LONG:
154 g_string_append(str, "long");
155 break;
156 case TYPESPEC_FLOAT:
157 g_string_append(str, "float");
158 break;
159 case TYPESPEC_DOUBLE:
160 g_string_append(str, "double");
161 break;
162 case TYPESPEC_SIGNED:
163 g_string_append(str, "signed");
164 break;
165 case TYPESPEC_UNSIGNED:
166 g_string_append(str, "unsigned");
167 break;
168 case TYPESPEC_BOOL:
169 g_string_append(str, "bool");
170 break;
171 case TYPESPEC_COMPLEX:
172 g_string_append(str, "_Complex");
173 break;
174 case TYPESPEC_IMAGINARY:
175 g_string_append(str, "_Imaginary");
176 break;
177 case TYPESPEC_CONST:
178 g_string_append(str, "const");
179 break;
180 case TYPESPEC_ID_TYPE:
181 if (iter->u.type_specifier.id_type)
182 g_string_append(str, iter->u.type_specifier.id_type);
183 break;
184 default:
185 fprintf(stderr, "[error] %s: unknown specifier\n", __func__);
186 err = -EINVAL;
187 goto error;
188 }
189 break;
190 case NODE_ENUM:
191 if (!iter->u._enum.enum_id) {
192 fprintf(stderr, "[error] %s: unexpected empty enum ID\n", __func__);
193 err = -EINVAL;
194 goto error;
195 }
196 g_string_append(str, "enum ");
197 g_string_append(str, iter->u._enum.enum_id);
198 break;
199 case NODE_VARIANT:
200 if (!iter->u.variant.name) {
201 fprintf(stderr, "[error] %s: unexpected empty variant name\n", __func__);
202 err = -EINVAL;
203 goto error;
204 }
205 g_string_append(str, "variant ");
206 g_string_append(str, iter->u.variant.name);
207 break;
208 case NODE_STRUCT:
209 if (!iter->u._struct.name) {
210 fprintf(stderr, "[error] %s: unexpected empty variant name\n", __func__);
211 err = -EINVAL;
212 goto error;
213 }
214 g_string_append(str, "struct ");
215 g_string_append(str, iter->u._struct.name);
216 break;
217 default:
218 fprintf(stderr, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
219 err = -EINVAL;
220 goto error;
221 }
222 }
223 return 0;
224error:
225 return err;
226}
227
228static
8fdba45b 229GQuark create_typealias_identifier(FILE *fd, int depth,
add40b62
MD
230 struct cds_list_head *declaration_specifier,
231 struct ctf_node *node_type_declarator)
232{
233 GString *str;
234 const char *str_c;
235 GQuark alias_q;
236 int ret;
237
238 str = g_string_new();
239 ret = visit_declaration_specifier(declaration_specifier, str);
240 if (ret) {
241 g_string_free(str, TRUE);
242 return 0;
243 }
244 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
245 g_string_append(str, " *");
246 if (iter->u.pointer.const_qualifier)
247 g_string_append(str, " const");
248 }
249 str_c = g_string_free(str, FALSE);
250 alias_q = g_quark_from_string(str_c);
251 g_free(str_c);
252 return alias_q;
253}
254
a3cca9e9 255static
8fdba45b 256struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
a3cca9e9
MD
257 struct cds_list_head *declaration_specifier,
258 GQuark *field_name,
259 struct ctf_node *node_type_declarator,
add40b62 260 struct declaration_scope *declaration_scope,
e397791f
MD
261 struct declaration *nested_declaration,
262 struct ctf_trace *trace)
a3cca9e9
MD
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
e397791f
MD
270 if (node_type_declarator) {
271 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
add40b62 272
e397791f
MD
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 }
add40b62 278 }
a3cca9e9
MD
279
280 if (!nested_declaration) {
e397791f 281 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
add40b62
MD
282 GQuark alias_q;
283
a3cca9e9
MD
284 /*
285 * If we have a pointer declarator, it _has_ to be present in
286 * the typealiases (else fail).
287 */
add40b62
MD
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 }
a3cca9e9 295 } else {
e397791f
MD
296 nested_declaration = ctf_declaration_specifier_visit(fd, depth,
297 declaration_specifier, declaration_scope, trace);
a3cca9e9 298 }
a3cca9e9
MD
299 }
300
e397791f
MD
301 if (!node_type_declarator)
302 return nested_declaration;
303
a3cca9e9
MD
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:
e397791f
MD
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;
a3cca9e9 333 break;
e397791f
MD
334 }
335 case NODE_INTEGER:
a3cca9e9 336 case NODE_TYPE_SPECIFIER:
e397791f
MD
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;
a3cca9e9 352 break;
e397791f 353 }
a3cca9e9
MD
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,
e397791f 363 declaration_scope, declaration, trace);
a3cca9e9
MD
364 return declaration;
365 }
366}
367
368static
8fdba45b 369int ctf_struct_type_declarators_visit(FILE *fd, int depth,
a3cca9e9
MD
370 struct declaration_struct *struct_declaration,
371 struct cds_list_head *declaration_specifier,
372 struct cds_list_head *type_declarators,
e397791f
MD
373 struct declaration_scope *declaration_scope,
374 struct ctf_trace *trace)
a3cca9e9
MD
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,
e397791f 386 NULL, trace);
a3cca9e9
MD
387 struct_declaration_add_field(struct_declaration,
388 g_quark_to_string(field_name),
389 field_declaration);
390 }
add40b62
MD
391 return 0;
392}
a3cca9e9 393
add40b62 394static
8fdba45b 395int ctf_variant_type_declarators_visit(FILE *fd, int depth,
add40b62
MD
396 struct declaration_variant *variant_declaration,
397 struct cds_list_head *declaration_specifier,
398 struct cds_list_head *type_declarators,
e397791f
MD
399 struct declaration_scope *declaration_scope,
400 struct ctf_trace *trace)
add40b62
MD
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,
e397791f 412 NULL, trace);
add40b62
MD
413 variant_declaration_add_field(variant_declaration,
414 g_quark_to_string(field_name),
415 field_declaration);
416 }
a3cca9e9
MD
417 return 0;
418}
419
420static
8fdba45b 421int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
a3cca9e9 422 struct cds_list_head *declaration_specifier,
e397791f
MD
423 struct cds_list_head *type_declarators,
424 struct ctf_trace *trace)
a3cca9e9
MD
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,
e397791f 436 scope, NULL, trace);
a3cca9e9
MD
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
446static
8fdba45b 447int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
e397791f
MD
448 struct ctf_node *target, struct ctf_node *alias,
449 struct ctf_trace *trace)
a3cca9e9
MD
450{
451 struct declaration *type_declaration;
452 struct ctf_node *iter, *node;
add40b62 453 GQuark dummy_id;
a3cca9e9 454 GQuark alias_q;
a3cca9e9
MD
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,
e397791f 465 scope, NULL, trace);
a3cca9e9
MD
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 */
a3cca9e9
MD
483
484 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
add40b62
MD
485 struct node, siblings);
486 alias_q = create_typealias_identifier(fd, depth,
487 &alias->u.typealias_alias.declaration_specifier, node);
a3cca9e9
MD
488 ret = register_declaration(alias_q, type_declaration, scope);
489 if (ret)
490 goto error;
491 return 0;
492
493error:
494 type_declaration->declaration_free(type_declaration);
495 return ret;
496}
497
498static
8fdba45b 499int ctf_struct_declaration_list_visit(FILE *fd, int depth,
e397791f
MD
500 struct ctf_node *iter, struct declaration_struct *struct_declaration,
501 struct ctf_trace *trace)
a3cca9e9
MD
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,
e397791f 512 &iter->u._typedef.type_declarators, trace);
a3cca9e9
MD
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,
e397791f 521 iter->u.typealias.alias, trace);
a3cca9e9
MD
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,
e397791f 530 &iter->u.struct_or_variant_declaration.type_declarators, trace);
a3cca9e9
MD
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
add40b62 541static
8fdba45b 542int ctf_variant_declaration_list_visit(FILE *fd, int depth,
e397791f
MD
543 struct ctf_node *iter, struct declaration_variant *variant_declaration,
544 struct ctf_trace *trace)
add40b62
MD
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,
e397791f 555 &iter->u._typedef.type_declarators, trace);
add40b62
MD
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,
e397791f 564 iter->u.typealias.alias, trace);
add40b62
MD
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,
e397791f 573 &iter->u.struct_or_variant_declaration.type_declarators, trace);
add40b62
MD
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
a3cca9e9
MD
584static
585struct declaration_struct *ctf_declaration_struct_visit(FILE *fd,
586 int depth, const char *name, struct cds_list_head *declaration_list,
e397791f
MD
587 int has_body, struct declaration_scope *declaration_scope,
588 struct ctf_trace *trace)
a3cca9e9
MD
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
add40b62 612 fprintf(stderr, "[error] %s: struct %s already declared in scope\n", __func__, name);
a3cca9e9
MD
613 return NULL;
614 }
615 }
616 struct_declaration = struct_declaration_new(name, declaration_scope);
617 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f
MD
618 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
619 struct_declaration, trace);
a3cca9e9
MD
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 }
631error:
632 struct_declaration->p.declaration_free(&struct_declaration->p);
633 return NULL;
634}
635
05628561 636static
add40b62
MD
637struct declaration_variant *ctf_declaration_variant_visit(FILE *fd,
638 int depth, const char *name, struct cds_list_head *declaration_list,
e397791f
MD
639 int has_body, struct declaration_scope *declaration_scope,
640 struct ctf_trace *trace)
05628561 641{
a3cca9e9 642 struct declaration *declaration;
add40b62
MD
643 struct declaration_variant *variant_declaration;
644 struct ctf_node *iter;
de47353a 645
add40b62
MD
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 {
de47353a 658 /* For unnamed variant, create type */
add40b62
MD
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) {
e397791f
MD
670 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
671 variant_declaration, trace);
add40b62
MD
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;
de47353a 682 }
add40b62
MD
683error:
684 variant_declaration->p.declaration_free(&variant_declaration->p);
685 return NULL;
05628561
MD
686}
687
05628561 688static
8fdba45b 689int ctf_enumerator_list_visit(FILE *fd, int depth,
add40b62
MD
690 struct ctf_node *enumerator,
691 struct declaration_enum *enum_declaration)
692{
1cfda062
MD
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 }
add40b62
MD
768 return 0;
769}
770
771static
8fdba45b 772struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
add40b62 773 const char *name,
1cfda062 774 struct cds_list_head *container_type,
add40b62 775 struct cds_list_head *enumerator_list,
1cfda062
MD
776 int has_body,
777 struct declaration_scope *declaration_scope,
778 struct ctf_trace *trace)
05628561 779{
add40b62
MD
780 struct declaration *declaration;
781 struct declaration_enum *enum_declaration;
782 struct declaration_integer *integer_declaration;
1cfda062
MD
783 struct ctf_node *iter, *first;
784 GQuark dummy_id;
add40b62 785
05628561 786 /*
add40b62
MD
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.
05628561 790 */
add40b62
MD
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 }
1cfda062
MD
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,
e397791f 819 &dummy_id, NULL,
1cfda062 820 declaration_scope,
e397791f 821 NULL, trace);
1cfda062
MD
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 }
add40b62
MD
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;
05628561 843 }
add40b62
MD
844error:
845 enum_declaration->p.declaration_free(&enum_declaration->p);
846 return NULL;
05628561
MD
847}
848
849static
8fdba45b 850struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
add40b62 851 struct cds_list_head *declaration_specifier,
d20f5e59 852 struct declaration_scope *declaration_scope)
05628561 853{
add40b62
MD
854 GString *str;
855 struct declaration *declaration;
856 const char *str_c;
05628561 857
add40b62
MD
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
ab4cf058
MD
869/*
870 * Returns 0/1 boolean, or < 0 on error.
871 */
872static
8fdba45b 873int get_boolean(FILE *fd, int depth, struct node *unary_expression)
ab4cf058
MD
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
914static
8fdba45b 915int get_byte_order(FILE *fd, int depth, struct node *unary_expression)
ab4cf058
MD
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
add40b62 940static
8fdba45b 941struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
ab4cf058
MD
942 struct cds_list_head *expressions,
943 struct ctf_trace *trace)
add40b62
MD
944{
945 struct node *expression;
ab4cf058
MD
946 uint64_t alignment, size;
947 int byte_order = trace->byte_order;
948 int signedness = 0;
add40b62
MD
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")) {
ab4cf058
MD
959 signedness = get_boolean(fd, depth, right);
960 if (signedness < 0)
961 return NULL;
add40b62 962 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
ab4cf058
MD
963 byte_order = get_byte_order(fd, depth, right);
964 if (byte_order < 0)
965 return NULL;
add40b62 966 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
ab4cf058
MD
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;
add40b62
MD
973 has_size = 1;
974 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
ab4cf058
MD
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;
add40b62
MD
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 }
05628561 987 }
add40b62
MD
988 if (!has_size) {
989 fprintf(stderr, "[error] %s: missing size attribute\n", __func__);
990 return NULL;
991 }
ab4cf058
MD
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 }
add40b62
MD
1001 integer_declaration = integer_declaration_new(size,
1002 byte_order, signedness, alignment);
1003 return &integer_declaration->p;
05628561
MD
1004}
1005
ab4cf058 1006static
8fdba45b 1007struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
ab4cf058
MD
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
1078static
8fdba45b 1079struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
ab4cf058
MD
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
add40b62
MD
1114/*
1115 * Also add named variant, struct or enum to the current declaration scope.
1116 */
05628561 1117static
add40b62
MD
1118struct declaration *ctf_declaration_specifier_visit(FILE *fd,
1119 int depth, struct cds_list_head *head,
ab4cf058
MD
1120 struct declaration_scope *declaration_scope,
1121 struct ctf_trace *trace)
05628561 1122{
add40b62
MD
1123 struct declaration *declaration;
1124 struct node *first;
d20f5e59 1125
add40b62 1126 first = _cds_list_first_entry(head, struct node, siblings);
05628561 1127
add40b62
MD
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,
ab4cf058
MD
1134 declaration_scope,
1135 trace);
add40b62
MD
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,
ab4cf058
MD
1141 declaration_scope,
1142 trace);
add40b62
MD
1143 case NODE_ENUM:
1144 return ctf_declaration_enum_visit(fd, depth,
1145 first->u._enum.enum_id,
1cfda062 1146 &first->u._enum.container_type,
add40b62 1147 &first->u._enum.enumerator_list,
ab4cf058 1148 first->u._enum.has_body,
1cfda062 1149 declaration_scope,
ab4cf058 1150 trace);
add40b62
MD
1151 case NODE_INTEGER:
1152 return ctf_declaration_integer_visit(fd, depth,
ab4cf058
MD
1153 &first->u.integer.expressions, trace);
1154 case NODE_FLOATING_POINT:
add40b62 1155 return ctf_declaration_floating_point_visit(fd, depth,
ab4cf058
MD
1156 &first->u.floating_point.expressions, trace);
1157 case NODE_STRING:
add40b62 1158 return ctf_declaration_string_visit(fd, depth,
ab4cf058 1159 &first->u.string.expressions, trace);
add40b62
MD
1160 case NODE_TYPE_SPECIFIER:
1161 return ctf_declaration_type_specifier_visit(fd, depth,
ab4cf058 1162 head, declaration_scope, trace);
add40b62 1163 }
05628561
MD
1164}
1165
1166static
1167int 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,
d20f5e59 1176 event->declaration_scope);
05628561
MD
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
d20f5e59 1183 event->declaration_scope);
05628561
MD
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);
41253107 1203 g_free(right);
05628561
MD
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 }
05628561
MD
1227 CTF_EVENT_SET_FIELD(event, stream_id);
1228 } else if (!strcmp(left, "context")) {
1229 struct declaration *declaration;
1230
e1151715 1231 if (!event->definition_scope)
05628561
MD
1232 return -EPERM;
1233 declaration = ctf_declaration_specifier_visit(fd, depth,
1234 &node->u.ctf_expression.right,
ab4cf058 1235 event->declaration_scope, trace);
05628561
MD
1236 if (!declaration)
1237 return -EPERM;
1238 if (declaration->type->id != CTF_TYPE_STRUCT)
1239 return -EPERM;
9e29e16e 1240 event->context_decl = container_of(declaration, struct declaration_struct, p);
05628561
MD
1241 } else if (!strcmp(left, "fields")) {
1242 struct declaration *declaration;
1243
e1151715 1244 if (!event->definition_scope)
05628561
MD
1245 return -EPERM;
1246 declaration = ctf_declaration_specifier_visit(fd, depth,
1247 &node->u.ctf_expression.right,
ab4cf058 1248 event->declaration_scope, trace);
05628561
MD
1249 if (!declaration)
1250 return -EPERM;
1251 if (declaration->type->id != CTF_TYPE_STRUCT)
1252 return -EPERM;
9e29e16e 1253 event->fields_decl = container_of(declaration, struct declaration_struct, p);
05628561 1254 }
41253107 1255 g_free(left);
05628561
MD
1256 break;
1257 }
1258 default:
1259 return -EPERM;
1260 /* TODO: declaration specifier should be added. */
1261 }
1262
1263 return 0;
1264}
1265
1266static
1267int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1268 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1269{
1270 int ret = 0;
1271 struct ctf_node *iter;
1272 struct ctf_event *event;
9e29e16e 1273 struct definition_scope *parent_def_scope;
05628561
MD
1274
1275 event = g_new0(struct ctf_event, 1);
d20f5e59 1276 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
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);
41253107 1300 parent_def_scope = stream->definition_scope;
9e29e16e
MD
1301 if (event->context_decl) {
1302 event->context =
1303 event->context_decl->definition_new(event->context_decl,
41253107 1304 parent_def_scope, 0, 0);
6a36ddca
MD
1305 set_dynamic_definition_scope(&event->context->p,
1306 event->context->scope,
d00d17d1 1307 "event.context");
9e29e16e
MD
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,
41253107 1314 parent_def_scope, 0, 0);
6a36ddca
MD
1315 set_dynamic_definition_scope(&event->fields->p,
1316 event->fields->scope,
d00d17d1 1317 "event.fields");
9e29e16e
MD
1318 parent_def_scope = event->fields->scope;
1319 declaration_unref(event->fields_decl);
1320 }
05628561
MD
1321 return 0;
1322
1323error:
9e29e16e
MD
1324 declaration_unref(event->fields_decl);
1325 declaration_unref(event->context_decl);
e1151715 1326 free_definition_scope(event->definition_scope);
d20f5e59 1327 free_declaration_scope(event->declaration_scope);
05628561
MD
1328 g_free(event);
1329 return ret;
1330}
1331
1332
1333static
1334int 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,
d20f5e59 1343 stream->declaration_scope);
05628561
MD
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
d20f5e59 1350 stream->declaration_scope);
05628561
MD
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);
9e29e16e 1368 } else if (!strcmp(left, "event.header")) {
05628561
MD
1369 struct declaration *declaration;
1370
1371 declaration = ctf_declaration_specifier_visit(fd, depth,
1372 &node->u.ctf_expression.right,
ab4cf058 1373 stream->declaration_scope, stream->definition_scope, trace);
05628561
MD
1374 if (!declaration)
1375 return -EPERM;
1376 if (declaration->type->id != CTF_TYPE_STRUCT)
1377 return -EPERM;
9e29e16e
MD
1378 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1379 } else if (!strcmp(left, "event.context")) {
05628561
MD
1380 struct declaration *declaration;
1381
1382 declaration = ctf_declaration_specifier_visit(fd, depth,
1383 &node->u.ctf_expression.right,
ab4cf058 1384 stream->declaration_scope, trace);
05628561
MD
1385 if (!declaration)
1386 return -EPERM;
1387 if (declaration->type->id != CTF_TYPE_STRUCT)
1388 return -EPERM;
9e29e16e
MD
1389 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1390 } else if (!strcmp(left, "packet.context")) {
05628561
MD
1391 struct declaration *declaration;
1392
1393 declaration = ctf_declaration_specifier_visit(fd, depth,
1394 &node->u.ctf_expression.right,
ab4cf058 1395 stream->declaration_scope, trace);
05628561
MD
1396 if (!declaration)
1397 return -EPERM;
1398 if (declaration->type->id != CTF_TYPE_STRUCT)
1399 return -EPERM;
9e29e16e 1400 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
05628561 1401 }
41253107 1402 g_free(left);
05628561
MD
1403 break;
1404 }
1405 default:
1406 return -EPERM;
1407 /* TODO: declaration specifier should be added. */
1408 }
1409
1410 return 0;
1411}
1412
1413static
1414int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1415 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1416{
1417 int ret = 0;
1418 struct ctf_node *iter;
1419 struct ctf_stream *stream;
9e29e16e 1420 struct definition_scope *parent_def_scope;
05628561
MD
1421
1422 stream = g_new0(struct ctf_stream, 1);
d20f5e59 1423 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
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;
9e29e16e 1438
41253107 1439 parent_def_scope = NULL;
9e29e16e
MD
1440 if (stream->packet_context_decl) {
1441 stream->packet_context =
1442 stream->packet_context_decl->definition_new(stream->packet_context_decl,
41253107 1443 parent_def_scope, 0, 0);
6a36ddca
MD
1444 set_dynamic_definition_scope(&stream->packet_context->p,
1445 stream->packet_context->scope,
d00d17d1 1446 "stream.packet.context");
9e29e16e
MD
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,
41253107 1453 parent_def_scope, 0, 0);
6a36ddca
MD
1454 set_dynamic_definition_scope(&stream->event_header->p,
1455 stream->event_header->scope,
d00d17d1 1456 "stream.event.header");
9e29e16e
MD
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,
41253107 1463 parent_def_scope, 0, 0);
6a36ddca
MD
1464 set_dynamic_definition_scope(&stream->event_context->p,
1465 stream->event_context->scope,
d00d17d1 1466 "stream.event.context");
9e29e16e
MD
1467 parent_def_scope = stream->event_context->scope;
1468 declaration_unref(stream->event_context_decl);
1469 }
41253107 1470 stream->definition_scope = parent_def_scope;
9e29e16e 1471
05628561
MD
1472 return 0;
1473
1474error:
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);
e1151715 1480 free_definition_scope(stream->definition_scope);
d20f5e59 1481 free_declaration_scope(stream->declaration_scope);
05628561
MD
1482 g_free(stream);
1483 return ret;
1484}
1485
1486static
1487int 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,
d20f5e59 1496 trace->declaration_scope);
05628561
MD
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
d20f5e59 1503 trace->declaration_scope);
05628561
MD
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 }
41253107 1549 g_free(left);
05628561
MD
1550 break;
1551 }
1552 default:
1553 return -EPERM;
1554 /* TODO: declaration specifier should be added. */
1555 }
1556
1557 return 0;
1558}
1559
05628561
MD
1560static
1561int 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
d20f5e59 1566 if (trace->declaration_scope)
05628561 1567 return -EEXIST;
d20f5e59 1568 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
9e29e16e 1569 trace->definition_scope = new_dynamic_definition_scope(trace->root_definition_scope);
05628561
MD
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
1594error:
1595 g_ptr_array_free(trace->streams, TRUE);
e1151715 1596 free_definition_scope(stream->definition_scope);
d20f5e59 1597 free_declaration_scope(stream->declaration_scope);
05628561
MD
1598 return ret;
1599}
1600
ab4cf058
MD
1601int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
1602 struct ctf_trace *trace, int byte_order)
05628561
MD
1603{
1604 int ret = 0;
1605 struct ctf_node *iter;
1606
ab4cf058
MD
1607 trace->byte_order = byte_order;
1608
05628561
MD
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,
d60cb676 1616 trace->root_declaration_scope);
05628561
MD
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
d60cb676 1624 trace->root_declaration_scope);
05628561
MD
1625 if (ret)
1626 return ret;
1627 }
1628 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
de47353a 1629 ret = ctf_declaration_specifier_visit(fd, depth, iter,
ab4cf058 1630 trace->root_declaration_scope, trace);
05628561
MD
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,
41253107 1641 trace->root_declaration_scope, trace);
05628561
MD
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,
41253107 1647 trace->root_declaration_scope, trace);
05628561
MD
1648 if (ret)
1649 return ret;
1650 }
1651 break;
05628561
MD
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.162198 seconds and 4 git commands to generate.