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