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