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