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