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