Clear field mask before retry.
[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 27#include <errno.h>
c8b219a3 28#include <babeltrace/babeltrace.h>
05628561 29#include <babeltrace/list.h>
a0720417
MD
30#include <babeltrace/types.h>
31#include <babeltrace/ctf/metadata.h>
41253107 32#include <uuid/uuid.h>
05628561
MD
33#include "ctf-scanner.h"
34#include "ctf-parser.h"
35#include "ctf-ast.h"
36
37#define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
38
de47353a
MD
39#define _cds_list_first_entry(ptr, type, member) \
40 cds_list_entry((ptr)->next, type, member)
05628561 41
a3cca9e9 42static
78af2bcd
MD
43struct declaration *ctf_type_specifier_list_visit(FILE *fd,
44 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
45 struct declaration_scope *declaration_scope,
46 struct ctf_trace *trace);
a3cca9e9 47
33105c61
MD
48static
49int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
50 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
51
05628561 52/*
41253107 53 * String returned must be freed by the caller using g_free.
05628561
MD
54 */
55static
add40b62 56char *concatenate_unary_strings(struct cds_list_head *head)
05628561 57{
41253107
MD
58 struct ctf_node *node;
59 GString *str;
60 int i = 0;
61
a0720417 62 str = g_string_new("");
41253107
MD
63 cds_list_for_each_entry(node, head, siblings) {
64 char *src_string;
65
66 assert(node->type == NODE_UNARY_EXPRESSION);
67 assert(node->u.unary_expression.type == UNARY_STRING);
68 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
a0720417 69 ^ (i != 0));
41253107
MD
70 switch (node->u.unary_expression.link) {
71 case UNARY_DOTLINK:
a0720417 72 g_string_append(str, ".");
41253107
MD
73 break;
74 case UNARY_ARROWLINK:
a0720417 75 g_string_append(str, "->");
41253107
MD
76 break;
77 case UNARY_DOTDOTDOT:
a0720417
MD
78 g_string_append(str, "...");
79 break;
80 default:
41253107
MD
81 break;
82 }
a0720417 83 src_string = node->u.unary_expression.u.string;
41253107
MD
84 g_string_append(str, src_string);
85 i++;
86 }
87 return g_string_free(str, FALSE);
05628561
MD
88}
89
90static
add40b62 91int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
05628561 92{
41253107
MD
93 struct ctf_node *node;
94 int i = 0;
95
96 cds_list_for_each_entry(node, head, siblings) {
97 assert(node->type == NODE_UNARY_EXPRESSION);
98 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
99 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
100 assert(i == 0);
a0720417 101 *value = node->u.unary_expression.u.unsigned_constant;
41253107
MD
102 i++;
103 }
104 return 0;
05628561
MD
105}
106
107static
add40b62 108int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
05628561 109{
41253107
MD
110 struct ctf_node *node;
111 int i = 0;
112 int ret = -1;
113
114 cds_list_for_each_entry(node, head, siblings) {
115 const char *src_string;
116
117 assert(node->type == NODE_UNARY_EXPRESSION);
118 assert(node->u.unary_expression.type == UNARY_STRING);
119 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
120 assert(i == 0);
a0720417 121 src_string = node->u.unary_expression.u.string;
5c551b40 122 ret = uuid_parse(src_string, *uuid);
41253107
MD
123 }
124 return ret;
05628561
MD
125}
126
127static
aa6bffae 128struct ctf_stream_class *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
05628561
MD
129{
130 if (trace->streams->len <= stream_id)
131 return NULL;
132 return g_ptr_array_index(trace->streams, stream_id);
133}
134
add40b62 135static
78af2bcd
MD
136int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
137{
138 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
139
140 switch (type_specifier->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 (type_specifier->u.type_specifier.id_type)
182 g_string_append(str, type_specifier->u.type_specifier.id_type);
183 break;
184 case TYPESPEC_STRUCT:
185 {
186 struct ctf_node *node = type_specifier->u.type_specifier.node;
187
188 if (!node->u._struct.name) {
189 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
190 return -EINVAL;
191 }
192 g_string_append(str, "struct ");
193 g_string_append(str, node->u._struct.name);
194 break;
195 }
196 case TYPESPEC_VARIANT:
197 {
198 struct ctf_node *node = type_specifier->u.type_specifier.node;
199
200 if (!node->u.variant.name) {
201 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
202 return -EINVAL;
203 }
204 g_string_append(str, "variant ");
205 g_string_append(str, node->u.variant.name);
206 break;
207 }
208 case TYPESPEC_ENUM:
209 {
210 struct ctf_node *node = type_specifier->u.type_specifier.node;
211
212 if (!node->u._enum.enum_id) {
213 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
214 return -EINVAL;
215 }
216 g_string_append(str, "enum ");
217 g_string_append(str, node->u._enum.enum_id);
218 break;
219 }
220 case TYPESPEC_FLOATING_POINT:
221 case TYPESPEC_INTEGER:
222 case TYPESPEC_STRING:
223 default:
224 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
225 return -EINVAL;
226 }
227 return 0;
228}
229
230static
231int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
add40b62
MD
232{
233 struct ctf_node *iter;
234 int alias_item_nr = 0;
78af2bcd 235 int ret;
add40b62 236
78af2bcd 237 cds_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
add40b62
MD
238 if (alias_item_nr != 0)
239 g_string_append(str, " ");
240 alias_item_nr++;
78af2bcd
MD
241 ret = visit_type_specifier(fd, iter, str);
242 if (ret)
243 return ret;
add40b62
MD
244 }
245 return 0;
add40b62
MD
246}
247
248static
8fdba45b 249GQuark create_typealias_identifier(FILE *fd, int depth,
78af2bcd 250 struct ctf_node *type_specifier_list,
add40b62
MD
251 struct ctf_node *node_type_declarator)
252{
a0720417 253 struct ctf_node *iter;
add40b62 254 GString *str;
a0720417 255 char *str_c;
add40b62
MD
256 GQuark alias_q;
257 int ret;
258
a0720417 259 str = g_string_new("");
78af2bcd 260 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
261 if (ret) {
262 g_string_free(str, TRUE);
263 return 0;
264 }
265 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
266 g_string_append(str, " *");
267 if (iter->u.pointer.const_qualifier)
268 g_string_append(str, " const");
269 }
270 str_c = g_string_free(str, FALSE);
271 alias_q = g_quark_from_string(str_c);
272 g_free(str_c);
273 return alias_q;
274}
275
a3cca9e9 276static
8fdba45b 277struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
78af2bcd 278 struct ctf_node *type_specifier_list,
a3cca9e9
MD
279 GQuark *field_name,
280 struct ctf_node *node_type_declarator,
add40b62 281 struct declaration_scope *declaration_scope,
e397791f
MD
282 struct declaration *nested_declaration,
283 struct ctf_trace *trace)
a3cca9e9
MD
284{
285 /*
286 * Visit type declarator by first taking care of sequence/array
287 * (recursively). Then, when we get to the identifier, take care
288 * of pointers.
289 */
290
e397791f
MD
291 if (node_type_declarator) {
292 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
add40b62 293
e397791f
MD
294 /* TODO: gcc bitfields not supported yet. */
295 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
78af2bcd 296 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
e397791f
MD
297 return NULL;
298 }
add40b62 299 }
a3cca9e9
MD
300
301 if (!nested_declaration) {
e397791f 302 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
add40b62
MD
303 GQuark alias_q;
304
a3cca9e9
MD
305 /*
306 * If we have a pointer declarator, it _has_ to be present in
307 * the typealiases (else fail).
308 */
add40b62 309 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 310 type_specifier_list, node_type_declarator);
add40b62
MD
311 nested_declaration = lookup_declaration(alias_q, declaration_scope);
312 if (!nested_declaration) {
78af2bcd 313 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
add40b62
MD
314 return NULL;
315 }
4d5fc303
MD
316 if (nested_declaration->id == CTF_TYPE_INTEGER) {
317 struct declaration_integer *integer_declaration =
318 container_of(nested_declaration, struct declaration_integer, p);
319 /* For base to 16 for pointers (expected pretty-print) */
2527e149
MD
320 if (!integer_declaration->base) {
321 /*
322 * We need to do a copy of the
323 * integer declaration to modify it. There could be other references to
324 * it.
325 */
326 integer_declaration = integer_declaration_new(integer_declaration->len,
327 integer_declaration->byte_order, integer_declaration->signedness,
81dee1bb 328 integer_declaration->p.alignment, 16, integer_declaration->encoding);
2527e149
MD
329 nested_declaration = &integer_declaration->p;
330 }
4d5fc303 331 }
a3cca9e9 332 } else {
78af2bcd
MD
333 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
334 type_specifier_list, declaration_scope, trace);
a3cca9e9 335 }
a3cca9e9
MD
336 }
337
e397791f
MD
338 if (!node_type_declarator)
339 return nested_declaration;
340
a3cca9e9
MD
341 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
342 if (node_type_declarator->u.type_declarator.u.id)
343 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
344 else
345 *field_name = 0;
346 return nested_declaration;
347 } else {
348 struct declaration *declaration;
98df1c9f 349 struct ctf_node *first;
a3cca9e9
MD
350
351 /* TYPEDEC_NESTED */
352
b5bf4179
MD
353 if (!nested_declaration) {
354 fprintf(fd, "[error] %s: nested type is unknown.\n", __func__);
355 return NULL;
356 }
357
a3cca9e9 358 /* create array/sequence, pass nested_declaration as child. */
98df1c9f
MD
359 if (cds_list_empty(&node_type_declarator->u.type_declarator.u.nested.length)) {
360 fprintf(fd, "[error] %s: expecting length field reference or value.\n", __func__);
a0720417
MD
361 return NULL;
362 }
98df1c9f
MD
363 first = _cds_list_first_entry(&node_type_declarator->u.type_declarator.u.nested.length,
364 struct ctf_node, siblings);
365 assert(first->type == NODE_UNARY_EXPRESSION);
366
367 switch (first->u.unary_expression.type) {
368 case UNARY_UNSIGNED_CONSTANT:
a0720417
MD
369 {
370 struct declaration_array *array_declaration;
371 size_t len;
372
98df1c9f 373 len = first->u.unary_expression.u.unsigned_constant;
a0720417
MD
374 array_declaration = array_declaration_new(len, nested_declaration,
375 declaration_scope);
98df1c9f
MD
376
377 if (!array_declaration) {
378 fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__);
379 return NULL;
380 }
a0720417
MD
381 declaration = &array_declaration->p;
382 break;
383 }
98df1c9f 384 case UNARY_STRING:
a0720417 385 {
98df1c9f
MD
386 /* Lookup unsigned integer definition, create sequence */
387 char *length_name = concatenate_unary_strings(&node_type_declarator->u.type_declarator.u.nested.length);
a0720417 388 struct declaration_sequence *sequence_declaration;
a0720417 389
98df1c9f
MD
390 sequence_declaration = sequence_declaration_new(length_name, nested_declaration, declaration_scope);
391 if (!sequence_declaration) {
392 fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__);
2dd46001
MD
393 return NULL;
394 }
a0720417
MD
395 declaration = &sequence_declaration->p;
396 break;
397 }
398 default:
399 assert(0);
a3cca9e9
MD
400 }
401
402 /* Pass it as content of outer container */
403 declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 404 type_specifier_list, field_name,
a3cca9e9 405 node_type_declarator->u.type_declarator.u.nested.type_declarator,
e397791f 406 declaration_scope, declaration, trace);
a3cca9e9
MD
407 return declaration;
408 }
409}
410
411static
8fdba45b 412int ctf_struct_type_declarators_visit(FILE *fd, int depth,
a3cca9e9 413 struct declaration_struct *struct_declaration,
78af2bcd 414 struct ctf_node *type_specifier_list,
a3cca9e9 415 struct cds_list_head *type_declarators,
e397791f
MD
416 struct declaration_scope *declaration_scope,
417 struct ctf_trace *trace)
a3cca9e9
MD
418{
419 struct ctf_node *iter;
420 GQuark field_name;
421
422 cds_list_for_each_entry(iter, type_declarators, siblings) {
423 struct declaration *field_declaration;
424
425 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 426 type_specifier_list,
a3cca9e9
MD
427 &field_name, iter,
428 struct_declaration->scope,
e397791f 429 NULL, trace);
2dd46001
MD
430 if (!field_declaration) {
431 fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
432 return -EINVAL;
433 }
d3006d91
SM
434
435 /* Check if field with same name already exists */
436 if (struct_declaration_lookup_field_index(struct_declaration, field_name) >= 0) {
437 fprintf(fd, "[error] %s: duplicate field %s in struct\n", __func__, g_quark_to_string(field_name));
438 return -EINVAL;
439 }
440
a3cca9e9
MD
441 struct_declaration_add_field(struct_declaration,
442 g_quark_to_string(field_name),
443 field_declaration);
444 }
add40b62
MD
445 return 0;
446}
a3cca9e9 447
add40b62 448static
8fdba45b 449int ctf_variant_type_declarators_visit(FILE *fd, int depth,
a0720417 450 struct declaration_untagged_variant *untagged_variant_declaration,
78af2bcd 451 struct ctf_node *type_specifier_list,
add40b62 452 struct cds_list_head *type_declarators,
e397791f
MD
453 struct declaration_scope *declaration_scope,
454 struct ctf_trace *trace)
add40b62
MD
455{
456 struct ctf_node *iter;
457 GQuark field_name;
458
459 cds_list_for_each_entry(iter, type_declarators, siblings) {
460 struct declaration *field_declaration;
461
462 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 463 type_specifier_list,
add40b62 464 &field_name, iter,
a0720417 465 untagged_variant_declaration->scope,
e397791f 466 NULL, trace);
2dd46001
MD
467 if (!field_declaration) {
468 fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
469 return -EINVAL;
470 }
43f9090c
SM
471
472 if (untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration, field_name) != NULL) {
473 fprintf(fd, "[error] %s: duplicate field %s in variant\n", __func__, g_quark_to_string(field_name));
474 return -EINVAL;
475 }
476
477
a0720417 478 untagged_variant_declaration_add_field(untagged_variant_declaration,
add40b62
MD
479 g_quark_to_string(field_name),
480 field_declaration);
481 }
a3cca9e9
MD
482 return 0;
483}
484
485static
8fdba45b 486int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
78af2bcd 487 struct ctf_node *type_specifier_list,
e397791f
MD
488 struct cds_list_head *type_declarators,
489 struct ctf_trace *trace)
a3cca9e9
MD
490{
491 struct ctf_node *iter;
492 GQuark identifier;
493
494 cds_list_for_each_entry(iter, type_declarators, siblings) {
495 struct declaration *type_declaration;
496 int ret;
497
498 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 499 type_specifier_list,
a3cca9e9 500 &identifier, iter,
e397791f 501 scope, NULL, trace);
2dd46001
MD
502 if (!type_declaration) {
503 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
504 return -EINVAL;
505 }
506 /*
507 * Don't allow typedef and typealias of untagged
508 * variants.
509 */
510 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
511 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
512 declaration_unref(type_declaration);
513 return -EPERM;
514 }
a3cca9e9
MD
515 ret = register_declaration(identifier, type_declaration, scope);
516 if (ret) {
517 type_declaration->declaration_free(type_declaration);
518 return ret;
519 }
520 }
521 return 0;
522}
523
524static
8fdba45b 525int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
e397791f
MD
526 struct ctf_node *target, struct ctf_node *alias,
527 struct ctf_trace *trace)
a3cca9e9
MD
528{
529 struct declaration *type_declaration;
a0720417 530 struct ctf_node *node;
add40b62 531 GQuark dummy_id;
a3cca9e9 532 GQuark alias_q;
a0720417 533 int err;
a3cca9e9
MD
534
535 /* See ctf_visitor_type_declarator() in the semantic validator. */
536
537 /*
538 * Create target type declaration.
539 */
540
427c09b7 541 if (cds_list_empty(&target->u.typealias_target.type_declarators))
a0720417
MD
542 node = NULL;
543 else
427c09b7 544 node = _cds_list_first_entry(&target->u.typealias_target.type_declarators,
a0720417 545 struct ctf_node, siblings);
a3cca9e9 546 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 547 target->u.typealias_target.type_specifier_list,
a0720417 548 &dummy_id, node,
e397791f 549 scope, NULL, trace);
a3cca9e9 550 if (!type_declaration) {
78af2bcd 551 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
a3cca9e9
MD
552 err = -EINVAL;
553 goto error;
554 }
2dd46001
MD
555 /*
556 * Don't allow typedef and typealias of untagged
557 * variants.
558 */
559 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
560 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
561 declaration_unref(type_declaration);
562 return -EPERM;
563 }
a3cca9e9
MD
564 /*
565 * The semantic validator does not check whether the target is
566 * abstract or not (if it has an identifier). Check it here.
567 */
568 if (dummy_id != 0) {
78af2bcd 569 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
a3cca9e9
MD
570 err = -EINVAL;
571 goto error;
572 }
573 /*
574 * Create alias identifier.
575 */
a3cca9e9
MD
576
577 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
a0720417 578 struct ctf_node, siblings);
add40b62 579 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 580 alias->u.typealias_alias.type_specifier_list, node);
a0720417
MD
581 err = register_declaration(alias_q, type_declaration, scope);
582 if (err)
a3cca9e9
MD
583 goto error;
584 return 0;
585
586error:
230da743
SM
587 if (type_declaration) {
588 type_declaration->declaration_free(type_declaration);
589 }
a0720417 590 return err;
a3cca9e9
MD
591}
592
593static
8fdba45b 594int ctf_struct_declaration_list_visit(FILE *fd, int depth,
e397791f
MD
595 struct ctf_node *iter, struct declaration_struct *struct_declaration,
596 struct ctf_trace *trace)
a3cca9e9 597{
a3cca9e9
MD
598 int ret;
599
600 switch (iter->type) {
601 case NODE_TYPEDEF:
602 /* For each declarator, declare type and add type to struct declaration scope */
603 ret = ctf_typedef_visit(fd, depth,
604 struct_declaration->scope,
78af2bcd 605 iter->u._typedef.type_specifier_list,
e397791f 606 &iter->u._typedef.type_declarators, trace);
a3cca9e9
MD
607 if (ret)
608 return ret;
609 break;
610 case NODE_TYPEALIAS:
611 /* Declare type with declarator and add type to struct declaration scope */
612 ret = ctf_typealias_visit(fd, depth,
613 struct_declaration->scope,
614 iter->u.typealias.target,
e397791f 615 iter->u.typealias.alias, trace);
a3cca9e9
MD
616 if (ret)
617 return ret;
618 break;
619 case NODE_STRUCT_OR_VARIANT_DECLARATION:
620 /* Add field to structure declaration */
621 ret = ctf_struct_type_declarators_visit(fd, depth,
622 struct_declaration,
78af2bcd 623 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
624 &iter->u.struct_or_variant_declaration.type_declarators,
625 struct_declaration->scope, trace);
a3cca9e9
MD
626 if (ret)
627 return ret;
628 break;
629 default:
78af2bcd 630 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
a3cca9e9
MD
631 assert(0);
632 }
633 return 0;
634}
635
add40b62 636static
8fdba45b 637int ctf_variant_declaration_list_visit(FILE *fd, int depth,
a0720417
MD
638 struct ctf_node *iter,
639 struct declaration_untagged_variant *untagged_variant_declaration,
e397791f 640 struct ctf_trace *trace)
add40b62 641{
add40b62
MD
642 int ret;
643
644 switch (iter->type) {
645 case NODE_TYPEDEF:
646 /* For each declarator, declare type and add type to variant declaration scope */
647 ret = ctf_typedef_visit(fd, depth,
a0720417 648 untagged_variant_declaration->scope,
78af2bcd 649 iter->u._typedef.type_specifier_list,
e397791f 650 &iter->u._typedef.type_declarators, trace);
add40b62
MD
651 if (ret)
652 return ret;
653 break;
654 case NODE_TYPEALIAS:
655 /* Declare type with declarator and add type to variant declaration scope */
656 ret = ctf_typealias_visit(fd, depth,
a0720417 657 untagged_variant_declaration->scope,
add40b62 658 iter->u.typealias.target,
e397791f 659 iter->u.typealias.alias, trace);
add40b62
MD
660 if (ret)
661 return ret;
662 break;
663 case NODE_STRUCT_OR_VARIANT_DECLARATION:
664 /* Add field to structure declaration */
665 ret = ctf_variant_type_declarators_visit(fd, depth,
a0720417 666 untagged_variant_declaration,
78af2bcd 667 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
668 &iter->u.struct_or_variant_declaration.type_declarators,
669 untagged_variant_declaration->scope, trace);
add40b62
MD
670 if (ret)
671 return ret;
672 break;
673 default:
78af2bcd 674 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
add40b62
MD
675 assert(0);
676 }
677 return 0;
678}
679
a3cca9e9 680static
a0720417 681struct declaration *ctf_declaration_struct_visit(FILE *fd,
a3cca9e9 682 int depth, const char *name, struct cds_list_head *declaration_list,
b7e35bad
MD
683 int has_body, struct cds_list_head *min_align,
684 struct declaration_scope *declaration_scope,
e397791f 685 struct ctf_trace *trace)
a3cca9e9 686{
a3cca9e9
MD
687 struct declaration_struct *struct_declaration;
688 struct ctf_node *iter;
a0720417 689 int ret;
a3cca9e9
MD
690
691 /*
692 * For named struct (without body), lookup in
693 * declaration scope. Don't take reference on struct
694 * declaration: ref is only taken upon definition.
695 */
696 if (!has_body) {
697 assert(name);
698 struct_declaration =
699 lookup_struct_declaration(g_quark_from_string(name),
700 declaration_scope);
a0720417 701 return &struct_declaration->p;
a3cca9e9 702 } else {
b7e35bad
MD
703 uint64_t min_align_value = 0;
704
a3cca9e9
MD
705 /* For unnamed struct, create type */
706 /* For named struct (with body), create type and add to declaration scope */
707 if (name) {
708 if (lookup_struct_declaration(g_quark_from_string(name),
709 declaration_scope)) {
710
78af2bcd 711 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
a3cca9e9
MD
712 return NULL;
713 }
714 }
b7e35bad
MD
715 if (!cds_list_empty(min_align)) {
716 ret = get_unary_unsigned(min_align, &min_align_value);
717 if (ret) {
718 fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
719 ret = -EINVAL;
720 goto error;
721 }
722 }
723 struct_declaration = struct_declaration_new(declaration_scope,
724 min_align_value);
a3cca9e9 725 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f
MD
726 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
727 struct_declaration, trace);
a3cca9e9 728 if (ret)
5c551b40 729 goto error_free_declaration;
a3cca9e9
MD
730 }
731 if (name) {
732 ret = register_struct_declaration(g_quark_from_string(name),
733 struct_declaration,
734 declaration_scope);
735 assert(!ret);
736 }
a0720417 737 return &struct_declaration->p;
a3cca9e9 738 }
5c551b40 739error_free_declaration:
a3cca9e9 740 struct_declaration->p.declaration_free(&struct_declaration->p);
5c551b40 741error:
a3cca9e9
MD
742 return NULL;
743}
744
05628561 745static
a0720417
MD
746struct declaration *ctf_declaration_variant_visit(FILE *fd,
747 int depth, const char *name, const char *choice,
748 struct cds_list_head *declaration_list,
e397791f
MD
749 int has_body, struct declaration_scope *declaration_scope,
750 struct ctf_trace *trace)
05628561 751{
a0720417 752 struct declaration_untagged_variant *untagged_variant_declaration;
add40b62
MD
753 struct declaration_variant *variant_declaration;
754 struct ctf_node *iter;
a0720417 755 int ret;
de47353a 756
add40b62
MD
757 /*
758 * For named variant (without body), lookup in
759 * declaration scope. Don't take reference on variant
760 * declaration: ref is only taken upon definition.
761 */
762 if (!has_body) {
763 assert(name);
a0720417 764 untagged_variant_declaration =
add40b62
MD
765 lookup_variant_declaration(g_quark_from_string(name),
766 declaration_scope);
add40b62 767 } else {
de47353a 768 /* For unnamed variant, create type */
add40b62
MD
769 /* For named variant (with body), create type and add to declaration scope */
770 if (name) {
771 if (lookup_variant_declaration(g_quark_from_string(name),
772 declaration_scope)) {
773
78af2bcd 774 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
add40b62
MD
775 return NULL;
776 }
777 }
a0720417 778 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
add40b62 779 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f 780 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
a0720417 781 untagged_variant_declaration, trace);
add40b62
MD
782 if (ret)
783 goto error;
784 }
785 if (name) {
786 ret = register_variant_declaration(g_quark_from_string(name),
a0720417 787 untagged_variant_declaration,
add40b62
MD
788 declaration_scope);
789 assert(!ret);
790 }
a0720417
MD
791 }
792 /*
793 * if tagged, create tagged variant and return. else return
794 * untagged variant.
795 */
796 if (!choice) {
797 return &untagged_variant_declaration->p;
798 } else {
799 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
800 if (!variant_declaration)
801 goto error;
802 declaration_unref(&untagged_variant_declaration->p);
803 return &variant_declaration->p;
de47353a 804 }
add40b62 805error:
2dd46001 806 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
add40b62 807 return NULL;
05628561
MD
808}
809
05628561 810static
8fdba45b 811int ctf_enumerator_list_visit(FILE *fd, int depth,
add40b62
MD
812 struct ctf_node *enumerator,
813 struct declaration_enum *enum_declaration)
814{
1cfda062
MD
815 GQuark q;
816 struct ctf_node *iter;
817
818 q = g_quark_from_string(enumerator->u.enumerator.id);
a0720417 819 if (enum_declaration->integer_declaration->signedness) {
1cfda062
MD
820 int64_t start, end;
821 int nr_vals = 0;
822
a0720417 823 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
1cfda062
MD
824 int64_t *target;
825
826 assert(iter->type == NODE_UNARY_EXPRESSION);
827 if (nr_vals == 0)
828 target = &start;
829 else
830 target = &end;
831
832 switch (iter->u.unary_expression.type) {
833 case UNARY_SIGNED_CONSTANT:
834 *target = iter->u.unary_expression.u.signed_constant;
835 break;
836 case UNARY_UNSIGNED_CONSTANT:
837 *target = iter->u.unary_expression.u.unsigned_constant;
838 break;
839 default:
78af2bcd 840 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
841 return -EINVAL;
842 }
843 if (nr_vals > 1) {
78af2bcd 844 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
845 return -EINVAL;
846 }
847 nr_vals++;
848 }
849 if (nr_vals == 1)
850 end = start;
851 enum_signed_insert(enum_declaration, start, end, q);
a0720417 852 } else {
1cfda062
MD
853 uint64_t start, end;
854 int nr_vals = 0;
855
a0720417
MD
856 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
857 uint64_t *target;
1cfda062
MD
858
859 assert(iter->type == NODE_UNARY_EXPRESSION);
860 if (nr_vals == 0)
861 target = &start;
862 else
863 target = &end;
864
865 switch (iter->u.unary_expression.type) {
866 case UNARY_UNSIGNED_CONSTANT:
867 *target = iter->u.unary_expression.u.unsigned_constant;
868 break;
869 case UNARY_SIGNED_CONSTANT:
870 /*
871 * We don't accept signed constants for enums with unsigned
872 * container type.
873 */
78af2bcd 874 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
1cfda062
MD
875 return -EINVAL;
876 default:
78af2bcd 877 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
878 return -EINVAL;
879 }
880 if (nr_vals > 1) {
78af2bcd 881 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
882 return -EINVAL;
883 }
884 nr_vals++;
885 }
886 if (nr_vals == 1)
887 end = start;
888 enum_unsigned_insert(enum_declaration, start, end, q);
889 }
add40b62
MD
890 return 0;
891}
892
893static
8fdba45b 894struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
add40b62 895 const char *name,
78af2bcd 896 struct ctf_node *container_type,
add40b62 897 struct cds_list_head *enumerator_list,
1cfda062
MD
898 int has_body,
899 struct declaration_scope *declaration_scope,
900 struct ctf_trace *trace)
05628561 901{
add40b62
MD
902 struct declaration *declaration;
903 struct declaration_enum *enum_declaration;
904 struct declaration_integer *integer_declaration;
78af2bcd 905 struct ctf_node *iter;
1cfda062 906 GQuark dummy_id;
a0720417 907 int ret;
add40b62 908
05628561 909 /*
add40b62
MD
910 * For named enum (without body), lookup in
911 * declaration scope. Don't take reference on enum
912 * declaration: ref is only taken upon definition.
05628561 913 */
add40b62
MD
914 if (!has_body) {
915 assert(name);
916 enum_declaration =
917 lookup_enum_declaration(g_quark_from_string(name),
918 declaration_scope);
a0720417 919 return &enum_declaration->p;
add40b62
MD
920 } else {
921 /* For unnamed enum, create type */
922 /* For named enum (with body), create type and add to declaration scope */
923 if (name) {
924 if (lookup_enum_declaration(g_quark_from_string(name),
925 declaration_scope)) {
926
78af2bcd 927 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
add40b62
MD
928 return NULL;
929 }
930 }
78af2bcd 931 if (!container_type) {
6743829a
MD
932 declaration = lookup_declaration(g_quark_from_static_string("int"),
933 declaration_scope);
934 if (!declaration) {
935 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
936 return NULL;
937 }
938 } else {
939 declaration = ctf_type_declarator_visit(fd, depth,
940 container_type,
941 &dummy_id, NULL,
942 declaration_scope,
943 NULL, trace);
1cfda062 944 }
30ea18a1
MD
945 if (!declaration) {
946 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
947 return NULL;
948 }
949 if (declaration->id != CTF_TYPE_INTEGER) {
950 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
951 return NULL;
1cfda062 952 }
30ea18a1 953 integer_declaration = container_of(declaration, struct declaration_integer, p);
a0720417 954 enum_declaration = enum_declaration_new(integer_declaration);
add40b62
MD
955 declaration_unref(&integer_declaration->p); /* leave ref to enum */
956 cds_list_for_each_entry(iter, enumerator_list, siblings) {
957 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
958 if (ret)
959 goto error;
960 }
961 if (name) {
962 ret = register_enum_declaration(g_quark_from_string(name),
963 enum_declaration,
964 declaration_scope);
965 assert(!ret);
966 }
a0720417 967 return &enum_declaration->p;
05628561 968 }
add40b62
MD
969error:
970 enum_declaration->p.declaration_free(&enum_declaration->p);
971 return NULL;
05628561
MD
972}
973
974static
8fdba45b 975struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
78af2bcd 976 struct ctf_node *type_specifier_list,
d20f5e59 977 struct declaration_scope *declaration_scope)
05628561 978{
add40b62
MD
979 GString *str;
980 struct declaration *declaration;
a0720417
MD
981 char *str_c;
982 int ret;
983 GQuark id_q;
05628561 984
a0720417 985 str = g_string_new("");
78af2bcd 986 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
987 if (ret)
988 return NULL;
989 str_c = g_string_free(str, FALSE);
990 id_q = g_quark_from_string(str_c);
991 g_free(str_c);
992 declaration = lookup_declaration(id_q, declaration_scope);
993 return declaration;
994}
995
ab4cf058
MD
996/*
997 * Returns 0/1 boolean, or < 0 on error.
998 */
999static
a0720417 1000int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
ab4cf058
MD
1001{
1002 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
78af2bcd 1003 fprintf(fd, "[error] %s: expecting unary expression\n",
ab4cf058
MD
1004 __func__);
1005 return -EINVAL;
1006 }
1007 switch (unary_expression->u.unary_expression.type) {
1008 case UNARY_UNSIGNED_CONSTANT:
1009 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
1010 return 0;
1011 else
1012 return 1;
1013 case UNARY_SIGNED_CONSTANT:
1014 if (unary_expression->u.unary_expression.u.signed_constant == 0)
1015 return 0;
1016 else
1017 return 1;
1018 case UNARY_STRING:
1019 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
1020 return 1;
1021 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
1022 return 1;
1023 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
1024 return 0;
1025 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
1026 return 0;
1027 else {
78af2bcd 1028 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
ab4cf058
MD
1029 __func__, unary_expression->u.unary_expression.u.string);
1030 return -EINVAL;
1031 }
1032 break;
1033 default:
78af2bcd 1034 fprintf(fd, "[error] %s: unexpected unary expression type\n",
ab4cf058
MD
1035 __func__);
1036 return -EINVAL;
1037 }
1038
1039}
1040
0f980a35
MD
1041static
1042int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1043{
1044 int byte_order;
1045
1046 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1047 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1048 __func__);
1049 return -EINVAL;
1050 }
1051 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1052 byte_order = BIG_ENDIAN;
1053 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1054 byte_order = LITTLE_ENDIAN;
1055 else {
1056 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1057 __func__, unary_expression->u.unary_expression.u.string);
1058 return -EINVAL;
1059 }
1060 return byte_order;
1061}
1062
ab4cf058 1063static
a0720417
MD
1064int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1065 struct ctf_trace *trace)
ab4cf058
MD
1066{
1067 int byte_order;
1068
1069 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1070 fprintf(fd, "[error] %s: byte_order: expecting string\n",
ab4cf058
MD
1071 __func__);
1072 return -EINVAL;
1073 }
1074 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1075 byte_order = trace->byte_order;
1076 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1077 byte_order = BIG_ENDIAN;
1078 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1079 byte_order = BIG_ENDIAN;
1080 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1081 byte_order = LITTLE_ENDIAN;
1082 else {
78af2bcd 1083 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
a0720417 1084 __func__, unary_expression->u.unary_expression.u.string);
ab4cf058
MD
1085 return -EINVAL;
1086 }
1087 return byte_order;
1088}
1089
add40b62 1090static
8fdba45b 1091struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
ab4cf058
MD
1092 struct cds_list_head *expressions,
1093 struct ctf_trace *trace)
add40b62 1094{
a0720417 1095 struct ctf_node *expression;
5c551b40 1096 uint64_t alignment = 1, size;
ab4cf058
MD
1097 int byte_order = trace->byte_order;
1098 int signedness = 0;
add40b62 1099 int has_alignment = 0, has_size = 0;
4d5fc303 1100 int base = 0;
81dee1bb 1101 enum ctf_string_encoding encoding = CTF_STRING_NONE;
add40b62
MD
1102 struct declaration_integer *integer_declaration;
1103
1104 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1105 struct ctf_node *left, *right;
add40b62 1106
a0720417
MD
1107 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1108 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
add40b62
MD
1109 assert(left->u.unary_expression.type == UNARY_STRING);
1110 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
ab4cf058
MD
1111 signedness = get_boolean(fd, depth, right);
1112 if (signedness < 0)
1113 return NULL;
add40b62 1114 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1115 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1116 if (byte_order < 0)
1117 return NULL;
add40b62 1118 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
ab4cf058 1119 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1120 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
ab4cf058
MD
1121 __func__);
1122 return NULL;
1123 }
1124 size = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
1125 has_size = 1;
1126 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
ab4cf058 1127 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1128 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1129 __func__);
1130 return NULL;
1131 }
1132 alignment = right->u.unary_expression.u.unsigned_constant;
53532829
MD
1133 /* Make sure alignment is a power of two */
1134 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1135 fprintf(fd, "[error] %s: align: expecting power of two\n",
1136 __func__);
1137 return NULL;
1138 }
add40b62 1139 has_alignment = 1;
164078da
MD
1140 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
1141 switch (right->u.unary_expression.type) {
1142 case UNARY_UNSIGNED_CONSTANT:
1143 switch (right->u.unary_expression.u.unsigned_constant) {
1144 case 2:
1145 case 8:
1146 case 10:
1147 case 16:
1148 base = right->u.unary_expression.u.unsigned_constant;
1149 break;
1150 default:
1151 fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
1152 __func__, right->u.unary_expression.u.unsigned_constant);
1153 return NULL;
1154 }
1155 break;
1156 case UNARY_STRING:
1157 {
1158 char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1159 if (!s_right) {
1160 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1161 g_free(s_right);
1162 return NULL;
1163 }
1164 if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
1165 || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
1166 base = 10;
1167 } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
1168 || !strcmp(s_right, "x") || !strcmp(s_right, "X")
1169 || !strcmp(s_right, "p")) {
1170 base = 16;
1171 } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
1172 || !strcmp(s_right, "o")) {
1173 base = 8;
1174 } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
1175 base = 2;
1176 } else {
1177 fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
1178 g_free(s_right);
1179 return NULL;
1180 }
1181
1182 g_free(s_right);
1183 break;
1184 }
1185 default:
1186 fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
1187 __func__);
1188 return NULL;
1189 }
81dee1bb
MD
1190 } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1191 char *s_right;
1192
1193 if (right->u.unary_expression.type != UNARY_STRING) {
1194 fprintf(fd, "[error] %s: encoding: expecting unary string\n",
1195 __func__);
1196 return NULL;
1197 }
1198 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1199 if (!s_right) {
1200 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1201 g_free(s_right);
1202 return NULL;
1203 }
1204 if (!strcmp(s_right, "UTF8")
1205 || !strcmp(s_right, "utf8")
1206 || !strcmp(s_right, "utf-8")
1207 || !strcmp(s_right, "UTF-8"))
1208 encoding = CTF_STRING_UTF8;
1209 else if (!strcmp(s_right, "ASCII")
1210 || !strcmp(s_right, "ascii"))
1211 encoding = CTF_STRING_ASCII;
b5bf4179
MD
1212 else if (!strcmp(s_right, "none"))
1213 encoding = CTF_STRING_NONE;
81dee1bb
MD
1214 else {
1215 fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
1216 g_free(s_right);
1217 return NULL;
1218 }
1219 g_free(s_right);
add40b62 1220 } else {
78af2bcd 1221 fprintf(fd, "[error] %s: unknown attribute name %s\n",
add40b62
MD
1222 __func__, left->u.unary_expression.u.string);
1223 return NULL;
1224 }
05628561 1225 }
add40b62 1226 if (!has_size) {
78af2bcd 1227 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
add40b62
MD
1228 return NULL;
1229 }
ab4cf058
MD
1230 if (!has_alignment) {
1231 if (size % CHAR_BIT) {
1232 /* bit-packed alignment */
1233 alignment = 1;
1234 } else {
1235 /* byte-packed alignment */
1236 alignment = CHAR_BIT;
1237 }
1238 }
add40b62 1239 integer_declaration = integer_declaration_new(size,
81dee1bb
MD
1240 byte_order, signedness, alignment,
1241 base, encoding);
add40b62 1242 return &integer_declaration->p;
05628561
MD
1243}
1244
ab4cf058 1245static
8fdba45b 1246struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
ab4cf058
MD
1247 struct cds_list_head *expressions,
1248 struct ctf_trace *trace)
1249{
a0720417 1250 struct ctf_node *expression;
5c551b40
MD
1251 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0,
1252 byte_order = trace->byte_order;
ab4cf058
MD
1253 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1254 struct declaration_float *float_declaration;
1255
1256 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1257 struct ctf_node *left, *right;
ab4cf058 1258
a0720417
MD
1259 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1260 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1261 assert(left->u.unary_expression.type == UNARY_STRING);
1262 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1263 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1264 if (byte_order < 0)
1265 return NULL;
1266 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1267 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1268 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
ab4cf058
MD
1269 __func__);
1270 return NULL;
1271 }
1272 exp_dig = right->u.unary_expression.u.unsigned_constant;
1273 has_exp_dig = 1;
1274 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1275 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1276 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
ab4cf058
MD
1277 __func__);
1278 return NULL;
1279 }
1280 mant_dig = right->u.unary_expression.u.unsigned_constant;
1281 has_mant_dig = 1;
1282 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1283 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1284 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1285 __func__);
1286 return NULL;
1287 }
1288 alignment = right->u.unary_expression.u.unsigned_constant;
53532829
MD
1289 /* Make sure alignment is a power of two */
1290 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1291 fprintf(fd, "[error] %s: align: expecting power of two\n",
1292 __func__);
1293 return NULL;
1294 }
ab4cf058
MD
1295 has_alignment = 1;
1296 } else {
78af2bcd 1297 fprintf(fd, "[error] %s: unknown attribute name %s\n",
ab4cf058
MD
1298 __func__, left->u.unary_expression.u.string);
1299 return NULL;
1300 }
1301 }
1302 if (!has_mant_dig) {
78af2bcd 1303 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
ab4cf058
MD
1304 return NULL;
1305 }
1306 if (!has_exp_dig) {
78af2bcd 1307 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
ab4cf058
MD
1308 return NULL;
1309 }
1310 if (!has_alignment) {
1311 if ((mant_dig + exp_dig) % CHAR_BIT) {
1312 /* bit-packed alignment */
1313 alignment = 1;
1314 } else {
1315 /* byte-packed alignment */
1316 alignment = CHAR_BIT;
1317 }
1318 }
1319 float_declaration = float_declaration_new(mant_dig, exp_dig,
1320 byte_order, alignment);
1321 return &float_declaration->p;
1322}
1323
1324static
8fdba45b 1325struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
ab4cf058
MD
1326 struct cds_list_head *expressions,
1327 struct ctf_trace *trace)
1328{
a0720417 1329 struct ctf_node *expression;
ab4cf058
MD
1330 const char *encoding_c = NULL;
1331 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1332 struct declaration_string *string_declaration;
1333
1334 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1335 struct ctf_node *left, *right;
ab4cf058 1336
a0720417
MD
1337 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1338 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1339 assert(left->u.unary_expression.type == UNARY_STRING);
1340 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
a0720417 1341 if (right->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1342 fprintf(fd, "[error] %s: encoding: expecting string\n",
ab4cf058
MD
1343 __func__);
1344 return NULL;
1345 }
1346 encoding_c = right->u.unary_expression.u.string;
1347 } else {
78af2bcd 1348 fprintf(fd, "[error] %s: unknown attribute name %s\n",
ab4cf058
MD
1349 __func__, left->u.unary_expression.u.string);
1350 return NULL;
1351 }
1352 }
1353 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1354 encoding = CTF_STRING_ASCII;
1355 string_declaration = string_declaration_new(encoding);
1356 return &string_declaration->p;
1357}
1358
1359
05628561 1360static
78af2bcd
MD
1361struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1362 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
1363 struct declaration_scope *declaration_scope,
1364 struct ctf_trace *trace)
05628561 1365{
a0720417 1366 struct ctf_node *first;
78af2bcd 1367 struct ctf_node *node;
d20f5e59 1368
427c09b7
MD
1369 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1370
78af2bcd 1371 first = _cds_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
05628561 1372
78af2bcd
MD
1373 assert(first->type == NODE_TYPE_SPECIFIER);
1374
1375 node = first->u.type_specifier.node;
1376
1377 switch (first->u.type_specifier.type) {
1378 case TYPESPEC_FLOATING_POINT:
1379 return ctf_declaration_floating_point_visit(fd, depth,
1380 &node->u.floating_point.expressions, trace);
1381 case TYPESPEC_INTEGER:
1382 return ctf_declaration_integer_visit(fd, depth,
1383 &node->u.integer.expressions, trace);
1384 case TYPESPEC_STRING:
1385 return ctf_declaration_string_visit(fd, depth,
5039b4cc 1386 &node->u.string.expressions, trace);
78af2bcd 1387 case TYPESPEC_STRUCT:
add40b62 1388 return ctf_declaration_struct_visit(fd, depth,
78af2bcd
MD
1389 node->u._struct.name,
1390 &node->u._struct.declaration_list,
1391 node->u._struct.has_body,
b7e35bad 1392 &node->u._struct.min_align,
ab4cf058
MD
1393 declaration_scope,
1394 trace);
78af2bcd 1395 case TYPESPEC_VARIANT:
add40b62 1396 return ctf_declaration_variant_visit(fd, depth,
78af2bcd
MD
1397 node->u.variant.name,
1398 node->u.variant.choice,
1399 &node->u.variant.declaration_list,
1400 node->u.variant.has_body,
ab4cf058
MD
1401 declaration_scope,
1402 trace);
78af2bcd 1403 case TYPESPEC_ENUM:
add40b62 1404 return ctf_declaration_enum_visit(fd, depth,
78af2bcd
MD
1405 node->u._enum.enum_id,
1406 node->u._enum.container_type,
1407 &node->u._enum.enumerator_list,
1408 node->u._enum.has_body,
1cfda062 1409 declaration_scope,
ab4cf058 1410 trace);
78af2bcd
MD
1411
1412 case TYPESPEC_VOID:
1413 case TYPESPEC_CHAR:
1414 case TYPESPEC_SHORT:
1415 case TYPESPEC_INT:
1416 case TYPESPEC_LONG:
1417 case TYPESPEC_FLOAT:
1418 case TYPESPEC_DOUBLE:
1419 case TYPESPEC_SIGNED:
1420 case TYPESPEC_UNSIGNED:
1421 case TYPESPEC_BOOL:
1422 case TYPESPEC_COMPLEX:
1423 case TYPESPEC_IMAGINARY:
1424 case TYPESPEC_CONST:
1425 case TYPESPEC_ID_TYPE:
add40b62 1426 return ctf_declaration_type_specifier_visit(fd, depth,
78af2bcd 1427 type_specifier_list, declaration_scope);
a0720417 1428 default:
78af2bcd 1429 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
a0720417 1430 return NULL;
add40b62 1431 }
05628561
MD
1432}
1433
1434static
1435int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1436{
1437 int ret = 0;
1438
1439 switch (node->type) {
1440 case NODE_TYPEDEF:
1441 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1442 event->declaration_scope,
78af2bcd 1443 node->u._typedef.type_specifier_list,
05628561 1444 &node->u._typedef.type_declarators,
a0720417 1445 trace);
05628561
MD
1446 if (ret)
1447 return ret;
1448 break;
1449 case NODE_TYPEALIAS:
1450 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1451 event->declaration_scope,
1452 node->u.typealias.target, node->u.typealias.alias,
1453 trace);
05628561
MD
1454 if (ret)
1455 return ret;
1456 break;
1457 case NODE_CTF_EXPRESSION:
1458 {
1459 char *left;
1460
1461 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1462 if (!strcmp(left, "name")) {
1463 char *right;
1464
427c09b7
MD
1465 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1466 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
0f980a35
MD
1467 ret = -EPERM;
1468 goto error;
427c09b7 1469 }
05628561
MD
1470 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1471 if (!right) {
78af2bcd 1472 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
0f980a35
MD
1473 ret = -EINVAL;
1474 goto error;
05628561
MD
1475 }
1476 event->name = g_quark_from_string(right);
41253107 1477 g_free(right);
05628561
MD
1478 CTF_EVENT_SET_FIELD(event, name);
1479 } else if (!strcmp(left, "id")) {
427c09b7
MD
1480 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1481 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
0f980a35
MD
1482 ret = -EPERM;
1483 goto error;
427c09b7 1484 }
05628561
MD
1485 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1486 if (ret) {
78af2bcd 1487 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
0f980a35
MD
1488 ret = -EINVAL;
1489 goto error;
05628561
MD
1490 }
1491 CTF_EVENT_SET_FIELD(event, id);
1492 } else if (!strcmp(left, "stream_id")) {
427c09b7
MD
1493 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1494 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
0f980a35
MD
1495 ret = -EPERM;
1496 goto error;
427c09b7 1497 }
05628561
MD
1498 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1499 if (ret) {
78af2bcd 1500 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
0f980a35
MD
1501 ret = -EINVAL;
1502 goto error;
05628561
MD
1503 }
1504 event->stream = trace_stream_lookup(trace, event->stream_id);
1505 if (!event->stream) {
78af2bcd 1506 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
0f980a35
MD
1507 ret = -EINVAL;
1508 goto error;
05628561 1509 }
05628561
MD
1510 CTF_EVENT_SET_FIELD(event, stream_id);
1511 } else if (!strcmp(left, "context")) {
1512 struct declaration *declaration;
1513
427c09b7
MD
1514 if (event->context_decl) {
1515 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
0f980a35
MD
1516 ret = -EINVAL;
1517 goto error;
427c09b7 1518 }
78af2bcd
MD
1519 declaration = ctf_type_specifier_list_visit(fd, depth,
1520 _cds_list_first_entry(&node->u.ctf_expression.right,
1521 struct ctf_node, siblings),
ab4cf058 1522 event->declaration_scope, trace);
0f980a35
MD
1523 if (!declaration) {
1524 ret = -EPERM;
1525 goto error;
1526 }
1527 if (declaration->id != CTF_TYPE_STRUCT) {
1528 ret = -EPERM;
1529 goto error;
1530 }
9e29e16e 1531 event->context_decl = container_of(declaration, struct declaration_struct, p);
05628561
MD
1532 } else if (!strcmp(left, "fields")) {
1533 struct declaration *declaration;
1534
427c09b7
MD
1535 if (event->fields_decl) {
1536 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
0f980a35
MD
1537 ret = -EINVAL;
1538 goto error;
427c09b7 1539 }
78af2bcd
MD
1540 declaration = ctf_type_specifier_list_visit(fd, depth,
1541 _cds_list_first_entry(&node->u.ctf_expression.right,
1542 struct ctf_node, siblings),
ab4cf058 1543 event->declaration_scope, trace);
0f980a35
MD
1544 if (!declaration) {
1545 ret = -EPERM;
1546 goto error;
1547 }
1548 if (declaration->id != CTF_TYPE_STRUCT) {
1549 ret = -EPERM;
1550 goto error;
1551 }
9e29e16e 1552 event->fields_decl = container_of(declaration, struct declaration_struct, p);
98df1c9f
MD
1553 } else {
1554 fprintf(fd, "[error] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
1555 ret = -EINVAL;
1556 goto error;
05628561 1557 }
0f980a35 1558error:
41253107 1559 g_free(left);
05628561
MD
1560 break;
1561 }
1562 default:
1563 return -EPERM;
1564 /* TODO: declaration specifier should be added. */
1565 }
1566
0f980a35 1567 return ret;
05628561
MD
1568}
1569
1570static
1571int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1572 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1573{
1574 int ret = 0;
1575 struct ctf_node *iter;
1576 struct ctf_event *event;
1577
1578 event = g_new0(struct ctf_event, 1);
d20f5e59 1579 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
1580 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1581 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1582 if (ret)
1583 goto error;
1584 }
1585 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1586 ret = -EPERM;
427c09b7 1587 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
05628561
MD
1588 goto error;
1589 }
05628561 1590 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
0f980a35 1591 /* Allow missing stream_id if there is only a single stream */
33105c61
MD
1592 switch (trace->streams->len) {
1593 case 0: /* Create stream if there was none. */
1594 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1595 if (ret)
1596 goto error;
1597 /* Fall-through */
1598 case 1:
0f980a35
MD
1599 event->stream_id = 0;
1600 event->stream = trace_stream_lookup(trace, event->stream_id);
33105c61
MD
1601 break;
1602 default:
0f980a35
MD
1603 ret = -EPERM;
1604 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1605 goto error;
1606 }
05628561 1607 }
8c572eba
MD
1608 /* Allow only one event without id per stream */
1609 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1610 && event->stream->events_by_id->len != 0) {
1611 ret = -EPERM;
1612 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1613 goto error;
1614 }
05628561
MD
1615 if (event->stream->events_by_id->len <= event->id)
1616 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1617 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1618 g_hash_table_insert(event->stream->event_quark_to_id,
1619 (gpointer)(unsigned long) event->name,
1620 &event->id);
1621 return 0;
1622
1623error:
98df1c9f
MD
1624 if (event->fields_decl)
1625 declaration_unref(&event->fields_decl->p);
1626 if (event->context_decl)
1627 declaration_unref(&event->context_decl->p);
d20f5e59 1628 free_declaration_scope(event->declaration_scope);
05628561
MD
1629 g_free(event);
1630 return ret;
1631}
1632
1633
1634static
aa6bffae 1635int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_class *stream, struct ctf_trace *trace)
05628561
MD
1636{
1637 int ret = 0;
1638
1639 switch (node->type) {
1640 case NODE_TYPEDEF:
1641 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1642 stream->declaration_scope,
78af2bcd 1643 node->u._typedef.type_specifier_list,
05628561 1644 &node->u._typedef.type_declarators,
a0720417 1645 trace);
05628561
MD
1646 if (ret)
1647 return ret;
1648 break;
1649 case NODE_TYPEALIAS:
1650 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1651 stream->declaration_scope,
1652 node->u.typealias.target, node->u.typealias.alias,
1653 trace);
05628561
MD
1654 if (ret)
1655 return ret;
1656 break;
1657 case NODE_CTF_EXPRESSION:
1658 {
1659 char *left;
1660
1661 left = concatenate_unary_strings(&node->u.ctf_expression.left);
427c09b7
MD
1662 if (!strcmp(left, "id")) {
1663 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1664 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
0f980a35
MD
1665 ret = -EPERM;
1666 goto error;
427c09b7 1667 }
a0720417 1668 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
05628561 1669 if (ret) {
427c09b7 1670 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
0f980a35
MD
1671 ret = -EINVAL;
1672 goto error;
05628561 1673 }
a0720417 1674 CTF_STREAM_SET_FIELD(stream, stream_id);
9e29e16e 1675 } else if (!strcmp(left, "event.header")) {
05628561
MD
1676 struct declaration *declaration;
1677
427c09b7
MD
1678 if (stream->event_header_decl) {
1679 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
0f980a35
MD
1680 ret = -EINVAL;
1681 goto error;
427c09b7 1682 }
78af2bcd
MD
1683 declaration = ctf_type_specifier_list_visit(fd, depth,
1684 _cds_list_first_entry(&node->u.ctf_expression.right,
1685 struct ctf_node, siblings),
a0720417 1686 stream->declaration_scope, trace);
0f980a35
MD
1687 if (!declaration) {
1688 ret = -EPERM;
1689 goto error;
1690 }
1691 if (declaration->id != CTF_TYPE_STRUCT) {
1692 ret = -EPERM;
1693 goto error;
1694 }
9e29e16e
MD
1695 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1696 } else if (!strcmp(left, "event.context")) {
05628561
MD
1697 struct declaration *declaration;
1698
427c09b7
MD
1699 if (stream->event_context_decl) {
1700 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
0f980a35
MD
1701 ret = -EINVAL;
1702 goto error;
427c09b7 1703 }
78af2bcd
MD
1704 declaration = ctf_type_specifier_list_visit(fd, depth,
1705 _cds_list_first_entry(&node->u.ctf_expression.right,
1706 struct ctf_node, siblings),
ab4cf058 1707 stream->declaration_scope, trace);
0f980a35
MD
1708 if (!declaration) {
1709 ret = -EPERM;
1710 goto error;
1711 }
1712 if (declaration->id != CTF_TYPE_STRUCT) {
1713 ret = -EPERM;
1714 goto error;
1715 }
9e29e16e
MD
1716 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1717 } else if (!strcmp(left, "packet.context")) {
05628561
MD
1718 struct declaration *declaration;
1719
427c09b7
MD
1720 if (stream->packet_context_decl) {
1721 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
0f980a35
MD
1722 ret = -EINVAL;
1723 goto error;
427c09b7 1724 }
78af2bcd
MD
1725 declaration = ctf_type_specifier_list_visit(fd, depth,
1726 _cds_list_first_entry(&node->u.ctf_expression.right,
1727 struct ctf_node, siblings),
ab4cf058 1728 stream->declaration_scope, trace);
0f980a35
MD
1729 if (!declaration) {
1730 ret = -EPERM;
1731 goto error;
1732 }
1733 if (declaration->id != CTF_TYPE_STRUCT) {
1734 ret = -EPERM;
1735 goto error;
1736 }
9e29e16e 1737 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
98df1c9f
MD
1738 } else {
1739 fprintf(fd, "[error] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
1740 ret = -EINVAL;
1741 goto error;
05628561 1742 }
98df1c9f 1743
0f980a35 1744error:
41253107 1745 g_free(left);
05628561
MD
1746 break;
1747 }
1748 default:
1749 return -EPERM;
1750 /* TODO: declaration specifier should be added. */
1751 }
1752
0f980a35 1753 return ret;
05628561
MD
1754}
1755
1756static
1757int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1758 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1759{
1760 int ret = 0;
1761 struct ctf_node *iter;
aa6bffae 1762 struct ctf_stream_class *stream;
05628561 1763
aa6bffae 1764 stream = g_new0(struct ctf_stream_class, 1);
d20f5e59 1765 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561 1766 stream->events_by_id = g_ptr_array_new();
068665f5 1767 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
2d0bea29 1768 stream->streams = g_ptr_array_new();
33105c61
MD
1769 if (node) {
1770 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1771 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1772 if (ret)
1773 goto error;
1774 }
05628561 1775 }
0f980a35
MD
1776 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1777 /* check that packet header has stream_id field. */
1778 if (!trace->packet_header_decl
1779 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
1780 ret = -EPERM;
1781 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
1782 goto error;
1783 }
8c572eba
MD
1784 } else {
1785 /* Allow only one id-less stream */
1786 if (trace->streams->len != 0) {
1787 ret = -EPERM;
1788 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
1789 goto error;
1790 }
1791 stream->stream_id = 0;
05628561
MD
1792 }
1793 if (trace->streams->len <= stream->stream_id)
1794 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1795 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
9e29e16e 1796
05628561
MD
1797 return 0;
1798
1799error:
98df1c9f
MD
1800 if (stream->event_header_decl)
1801 declaration_unref(&stream->event_header_decl->p);
1802 if (stream->event_context_decl)
1803 declaration_unref(&stream->event_context_decl->p);
1804 if (stream->packet_context_decl)
1805 declaration_unref(&stream->packet_context_decl->p);
2d0bea29 1806 g_ptr_array_free(stream->streams, TRUE);
05628561 1807 g_ptr_array_free(stream->events_by_id, TRUE);
a0720417 1808 g_hash_table_destroy(stream->event_quark_to_id);
d20f5e59 1809 free_declaration_scope(stream->declaration_scope);
05628561
MD
1810 g_free(stream);
1811 return ret;
1812}
1813
1814static
1815int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1816{
1817 int ret = 0;
1818
1819 switch (node->type) {
1820 case NODE_TYPEDEF:
1821 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1822 trace->declaration_scope,
78af2bcd 1823 node->u._typedef.type_specifier_list,
05628561 1824 &node->u._typedef.type_declarators,
a0720417 1825 trace);
05628561
MD
1826 if (ret)
1827 return ret;
1828 break;
1829 case NODE_TYPEALIAS:
1830 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1831 trace->declaration_scope,
1832 node->u.typealias.target, node->u.typealias.alias,
1833 trace);
05628561
MD
1834 if (ret)
1835 return ret;
1836 break;
1837 case NODE_CTF_EXPRESSION:
1838 {
1839 char *left;
1840
1841 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1842 if (!strcmp(left, "major")) {
427c09b7
MD
1843 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
1844 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
0f980a35
MD
1845 ret = -EPERM;
1846 goto error;
427c09b7 1847 }
05628561
MD
1848 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1849 if (ret) {
78af2bcd 1850 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
0f980a35
MD
1851 ret = -EINVAL;
1852 goto error;
05628561 1853 }
a0720417 1854 CTF_TRACE_SET_FIELD(trace, major);
05628561 1855 } else if (!strcmp(left, "minor")) {
427c09b7
MD
1856 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1857 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
0f980a35
MD
1858 ret = -EPERM;
1859 goto error;
427c09b7 1860 }
05628561
MD
1861 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1862 if (ret) {
78af2bcd 1863 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
0f980a35
MD
1864 ret = -EINVAL;
1865 goto error;
05628561 1866 }
a0720417 1867 CTF_TRACE_SET_FIELD(trace, minor);
05628561 1868 } else if (!strcmp(left, "uuid")) {
b4c19c1e 1869 uuid_t uuid;
a0fe7d97
MD
1870
1871 ret = get_unary_uuid(&node->u.ctf_expression.right, &uuid);
05628561 1872 if (ret) {
78af2bcd 1873 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
0f980a35
MD
1874 ret = -EINVAL;
1875 goto error;
05628561 1876 }
b4c19c1e
MD
1877 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
1878 && uuid_compare(uuid, trace->uuid)) {
1879 fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
1880 ret = -EPERM;
1881 goto error;
a0fe7d97
MD
1882 } else {
1883 memcpy(trace->uuid, uuid, sizeof(uuid));
b4c19c1e 1884 }
a0720417 1885 CTF_TRACE_SET_FIELD(trace, uuid);
0f980a35
MD
1886 } else if (!strcmp(left, "byte_order")) {
1887 struct ctf_node *right;
1888 int byte_order;
1889
0f980a35
MD
1890 right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
1891 byte_order = get_trace_byte_order(fd, depth, right);
1892 if (byte_order < 0)
1893 return -EINVAL;
a0fe7d97
MD
1894
1895 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
1896 && byte_order != trace->byte_order) {
1897 fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
1898 ret = -EPERM;
1899 goto error;
1900 } else {
fdce39de
MD
1901 if (byte_order != trace->byte_order) {
1902 trace->byte_order = byte_order;
1903 /*
1904 * We need to restart
1905 * construction of the
1906 * intermediate representation.
1907 */
1908 return -EINTR;
1909 }
a0fe7d97 1910 }
7c8a1386 1911 CTF_TRACE_SET_FIELD(trace, byte_order);
0f980a35
MD
1912 } else if (!strcmp(left, "packet.header")) {
1913 struct declaration *declaration;
1914
1915 if (trace->packet_header_decl) {
1916 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
1917 ret = -EINVAL;
1918 goto error;
1919 }
1920 declaration = ctf_type_specifier_list_visit(fd, depth,
1921 _cds_list_first_entry(&node->u.ctf_expression.right,
1922 struct ctf_node, siblings),
1923 trace->declaration_scope, trace);
1924 if (!declaration) {
1925 ret = -EPERM;
1926 goto error;
1927 }
1928 if (declaration->id != CTF_TYPE_STRUCT) {
1929 ret = -EPERM;
1930 goto error;
1931 }
1932 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
98df1c9f
MD
1933 } else {
1934 fprintf(fd, "[error] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
1935 ret = -EINVAL;
1936 goto error;
05628561 1937 }
98df1c9f 1938
0f980a35 1939error:
41253107 1940 g_free(left);
05628561
MD
1941 break;
1942 }
1943 default:
1944 return -EPERM;
1945 /* TODO: declaration specifier should be added. */
1946 }
1947
0f980a35 1948 return ret;
05628561
MD
1949}
1950
05628561
MD
1951static
1952int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1953{
1954 int ret = 0;
1955 struct ctf_node *iter;
1956
fdce39de 1957restart:
d20f5e59 1958 if (trace->declaration_scope)
05628561 1959 return -EEXIST;
d20f5e59 1960 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
05628561
MD
1961 trace->streams = g_ptr_array_new();
1962 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1963 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1964 if (ret)
1965 goto error;
1966 }
a0720417 1967 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
05628561 1968 ret = -EPERM;
427c09b7 1969 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
05628561
MD
1970 goto error;
1971 }
a0720417 1972 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
05628561 1973 ret = -EPERM;
427c09b7 1974 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
05628561
MD
1975 goto error;
1976 }
a0720417 1977 if (!CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
05628561 1978 ret = -EPERM;
427c09b7 1979 fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
05628561
MD
1980 goto error;
1981 }
dc48ecad
MD
1982 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1983 ret = -EPERM;
1984 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
1985 goto error;
1986 }
0f980a35 1987
0f980a35
MD
1988 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1989 /* check that the packet header contains a "magic" field */
e28d4618 1990 if (!trace->packet_header_decl
0f980a35
MD
1991 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
1992 ret = -EPERM;
1993 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
98df1c9f 1994 goto error;
0f980a35
MD
1995 }
1996 }
05628561
MD
1997 return 0;
1998
1999error:
98df1c9f
MD
2000 if (trace->packet_header_decl)
2001 declaration_unref(&trace->packet_header_decl->p);
05628561 2002 g_ptr_array_free(trace->streams, TRUE);
a0720417 2003 free_declaration_scope(trace->declaration_scope);
fdce39de
MD
2004 trace->declaration_scope = NULL;
2005 /* byte order changed while creating types, retry. */
7c8a1386
MD
2006 if (ret == -EINTR) {
2007 trace->field_mask = 0;
fdce39de 2008 goto restart;
7c8a1386 2009 }
05628561
MD
2010 return ret;
2011}
2012
78af2bcd
MD
2013static
2014int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2015{
2016 int ret = 0;
2017
2018 switch (node->type) {
2019 case NODE_TYPEDEF:
2020 ret = ctf_typedef_visit(fd, depth + 1,
2021 trace->root_declaration_scope,
2022 node->u._typedef.type_specifier_list,
2023 &node->u._typedef.type_declarators,
2024 trace);
2025 if (ret)
2026 return ret;
2027 break;
2028 case NODE_TYPEALIAS:
2029 ret = ctf_typealias_visit(fd, depth + 1,
2030 trace->root_declaration_scope,
2031 node->u.typealias.target, node->u.typealias.alias,
2032 trace);
2033 if (ret)
2034 return ret;
2035 break;
2036 case NODE_TYPE_SPECIFIER_LIST:
2037 {
2038 struct declaration *declaration;
2039
2040 /*
2041 * Just add the type specifier to the root scope
2042 * declaration scope. Release local reference.
2043 */
2044 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2045 node, trace->root_declaration_scope, trace);
2046 if (!declaration)
2047 return -ENOMEM;
2048 declaration_unref(declaration);
2049 break;
2050 }
2051 default:
2052 return -EPERM;
2053 }
2054
2055 return 0;
2056}
2057
ab4cf058
MD
2058int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2059 struct ctf_trace *trace, int byte_order)
05628561
MD
2060{
2061 int ret = 0;
2062 struct ctf_node *iter;
2063
c8b219a3 2064 printf_verbose("CTF visitor: metadata construction... ");
78af2bcd 2065 trace->root_declaration_scope = new_declaration_scope(NULL);
ab4cf058
MD
2066 trace->byte_order = byte_order;
2067
05628561
MD
2068 switch (node->type) {
2069 case NODE_ROOT:
3e11b713 2070 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
05628561 2071 siblings) {
78af2bcd 2072 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
427c09b7
MD
2073 if (ret) {
2074 fprintf(fd, "[error] %s: root declaration error\n", __func__);
a0fe7d97 2075 goto error;
427c09b7 2076 }
05628561
MD
2077 }
2078 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
2079 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
427c09b7
MD
2080 if (ret) {
2081 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
a0fe7d97 2082 goto error;
427c09b7 2083 }
05628561 2084 }
5039b4cc
MD
2085 if (!trace->streams) {
2086 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
a0fe7d97
MD
2087 ret = -EINVAL;
2088 goto error;
5039b4cc 2089 }
05628561
MD
2090 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
2091 ret = ctf_stream_visit(fd, depth + 1, iter,
41253107 2092 trace->root_declaration_scope, trace);
427c09b7
MD
2093 if (ret) {
2094 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
a0fe7d97 2095 goto error;
427c09b7 2096 }
05628561
MD
2097 }
2098 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
2099 ret = ctf_event_visit(fd, depth + 1, iter,
41253107 2100 trace->root_declaration_scope, trace);
427c09b7
MD
2101 if (ret) {
2102 fprintf(fd, "[error] %s: event declaration error\n", __func__);
a0fe7d97 2103 goto error;
427c09b7 2104 }
05628561
MD
2105 }
2106 break;
05628561
MD
2107 case NODE_UNKNOWN:
2108 default:
78af2bcd 2109 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
05628561 2110 (int) node->type);
a0fe7d97
MD
2111 ret = -EINVAL;
2112 goto error;
05628561 2113 }
c8b219a3 2114 printf_verbose("done.\n");
05628561 2115 return ret;
a0fe7d97
MD
2116
2117error:
2118 free_declaration_scope(trace->root_declaration_scope);
2119 return ret;
05628561 2120}
This page took 0.13715 seconds and 4 git commands to generate.