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