API : add_trace return the trace_handle id
[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>
70bd0a12 28#include <babeltrace/babeltrace-internal.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
82ace6d6
MD
42int opt_clock_force_correlate;
43
a3cca9e9 44static
78af2bcd
MD
45struct declaration *ctf_type_specifier_list_visit(FILE *fd,
46 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
47 struct declaration_scope *declaration_scope,
48 struct ctf_trace *trace);
a3cca9e9 49
33105c61
MD
50static
51int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
52 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
53
05628561 54/*
41253107 55 * String returned must be freed by the caller using g_free.
05628561
MD
56 */
57static
add40b62 58char *concatenate_unary_strings(struct cds_list_head *head)
05628561 59{
41253107
MD
60 struct ctf_node *node;
61 GString *str;
62 int i = 0;
63
a0720417 64 str = g_string_new("");
41253107
MD
65 cds_list_for_each_entry(node, head, siblings) {
66 char *src_string;
67
68 assert(node->type == NODE_UNARY_EXPRESSION);
69 assert(node->u.unary_expression.type == UNARY_STRING);
70 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
a0720417 71 ^ (i != 0));
41253107
MD
72 switch (node->u.unary_expression.link) {
73 case UNARY_DOTLINK:
a0720417 74 g_string_append(str, ".");
41253107
MD
75 break;
76 case UNARY_ARROWLINK:
a0720417 77 g_string_append(str, "->");
41253107
MD
78 break;
79 case UNARY_DOTDOTDOT:
a0720417
MD
80 g_string_append(str, "...");
81 break;
82 default:
41253107
MD
83 break;
84 }
a0720417 85 src_string = node->u.unary_expression.u.string;
41253107
MD
86 g_string_append(str, src_string);
87 i++;
88 }
89 return g_string_free(str, FALSE);
05628561
MD
90}
91
56e60373
MD
92static
93GQuark get_map_clock_name_value(struct cds_list_head *head)
94{
95 struct ctf_node *node;
96 const char *name = NULL;
97 int i = 0;
98
99 cds_list_for_each_entry(node, head, siblings) {
100 char *src_string;
101
102 assert(node->type == NODE_UNARY_EXPRESSION);
103 assert(node->u.unary_expression.type == UNARY_STRING);
104 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
105 ^ (i != 0));
106 /* needs to be chained with . */
107 switch (node->u.unary_expression.link) {
108 case UNARY_DOTLINK:
109 break;
110 case UNARY_ARROWLINK:
111 case UNARY_DOTDOTDOT:
112 return 0;
113 default:
114 break;
115 }
116 src_string = node->u.unary_expression.u.string;
117 switch (i) {
118 case 0: if (strcmp("clock", src_string) != 0) {
119 return 0;
120 }
121 break;
122 case 1: name = src_string;
123 break;
124 case 2: if (strcmp("value", src_string) != 0) {
125 return 0;
126 }
127 break;
128 default:
129 return 0; /* extra identifier, unknown */
130 }
131 i++;
132 }
133 return g_quark_from_string(name);
134}
135
05628561 136static
add40b62 137int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
05628561 138{
41253107
MD
139 struct ctf_node *node;
140 int i = 0;
141
142 cds_list_for_each_entry(node, head, siblings) {
143 assert(node->type == NODE_UNARY_EXPRESSION);
144 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
145 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
146 assert(i == 0);
a0720417 147 *value = node->u.unary_expression.u.unsigned_constant;
41253107
MD
148 i++;
149 }
150 return 0;
05628561
MD
151}
152
d86d62f8
MD
153static
154int get_unary_signed(struct cds_list_head *head, int64_t *value)
155{
156 struct ctf_node *node;
157 int i = 0;
158
159 cds_list_for_each_entry(node, head, siblings) {
160 assert(node->type == NODE_UNARY_EXPRESSION);
209209be
MD
161 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT
162 || node->u.unary_expression.type == UNARY_SIGNED_CONSTANT);
d86d62f8
MD
163 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
164 assert(i == 0);
209209be
MD
165 switch (node->u.unary_expression.type) {
166 case UNARY_UNSIGNED_CONSTANT:
167 *value = (int64_t) node->u.unary_expression.u.unsigned_constant;
168 break;
169 case UNARY_SIGNED_CONSTANT:
170 *value = node->u.unary_expression.u.signed_constant;
171 break;
172 default:
173 assert(0);
174 }
d86d62f8
MD
175 i++;
176 }
177 return 0;
178}
179
05628561 180static
add40b62 181int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
05628561 182{
41253107
MD
183 struct ctf_node *node;
184 int i = 0;
185 int ret = -1;
186
187 cds_list_for_each_entry(node, head, siblings) {
188 const char *src_string;
189
190 assert(node->type == NODE_UNARY_EXPRESSION);
191 assert(node->u.unary_expression.type == UNARY_STRING);
192 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
193 assert(i == 0);
a0720417 194 src_string = node->u.unary_expression.u.string;
5c551b40 195 ret = uuid_parse(src_string, *uuid);
41253107
MD
196 }
197 return ret;
05628561
MD
198}
199
200static
aa6bffae 201struct ctf_stream_class *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
05628561
MD
202{
203 if (trace->streams->len <= stream_id)
204 return NULL;
205 return g_ptr_array_index(trace->streams, stream_id);
206}
207
56e60373
MD
208static
209struct ctf_clock *trace_clock_lookup(struct ctf_trace *trace, GQuark clock_name)
210{
211 return g_hash_table_lookup(trace->clocks, (gpointer) (unsigned long) clock_name);
212}
213
add40b62 214static
78af2bcd
MD
215int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
216{
217 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
218
219 switch (type_specifier->u.type_specifier.type) {
220 case TYPESPEC_VOID:
221 g_string_append(str, "void");
222 break;
223 case TYPESPEC_CHAR:
224 g_string_append(str, "char");
225 break;
226 case TYPESPEC_SHORT:
227 g_string_append(str, "short");
228 break;
229 case TYPESPEC_INT:
230 g_string_append(str, "int");
231 break;
232 case TYPESPEC_LONG:
233 g_string_append(str, "long");
234 break;
235 case TYPESPEC_FLOAT:
236 g_string_append(str, "float");
237 break;
238 case TYPESPEC_DOUBLE:
239 g_string_append(str, "double");
240 break;
241 case TYPESPEC_SIGNED:
242 g_string_append(str, "signed");
243 break;
244 case TYPESPEC_UNSIGNED:
245 g_string_append(str, "unsigned");
246 break;
247 case TYPESPEC_BOOL:
248 g_string_append(str, "bool");
249 break;
250 case TYPESPEC_COMPLEX:
251 g_string_append(str, "_Complex");
252 break;
253 case TYPESPEC_IMAGINARY:
254 g_string_append(str, "_Imaginary");
255 break;
256 case TYPESPEC_CONST:
257 g_string_append(str, "const");
258 break;
259 case TYPESPEC_ID_TYPE:
260 if (type_specifier->u.type_specifier.id_type)
261 g_string_append(str, type_specifier->u.type_specifier.id_type);
262 break;
263 case TYPESPEC_STRUCT:
264 {
265 struct ctf_node *node = type_specifier->u.type_specifier.node;
266
267 if (!node->u._struct.name) {
268 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
269 return -EINVAL;
270 }
271 g_string_append(str, "struct ");
272 g_string_append(str, node->u._struct.name);
273 break;
274 }
275 case TYPESPEC_VARIANT:
276 {
277 struct ctf_node *node = type_specifier->u.type_specifier.node;
278
279 if (!node->u.variant.name) {
280 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
281 return -EINVAL;
282 }
283 g_string_append(str, "variant ");
284 g_string_append(str, node->u.variant.name);
285 break;
286 }
287 case TYPESPEC_ENUM:
288 {
289 struct ctf_node *node = type_specifier->u.type_specifier.node;
290
291 if (!node->u._enum.enum_id) {
292 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
293 return -EINVAL;
294 }
295 g_string_append(str, "enum ");
296 g_string_append(str, node->u._enum.enum_id);
297 break;
298 }
299 case TYPESPEC_FLOATING_POINT:
300 case TYPESPEC_INTEGER:
301 case TYPESPEC_STRING:
302 default:
303 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
304 return -EINVAL;
305 }
306 return 0;
307}
308
309static
310int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
add40b62
MD
311{
312 struct ctf_node *iter;
313 int alias_item_nr = 0;
78af2bcd 314 int ret;
add40b62 315
78af2bcd 316 cds_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
add40b62
MD
317 if (alias_item_nr != 0)
318 g_string_append(str, " ");
319 alias_item_nr++;
78af2bcd
MD
320 ret = visit_type_specifier(fd, iter, str);
321 if (ret)
322 return ret;
add40b62
MD
323 }
324 return 0;
add40b62
MD
325}
326
327static
8fdba45b 328GQuark create_typealias_identifier(FILE *fd, int depth,
78af2bcd 329 struct ctf_node *type_specifier_list,
add40b62
MD
330 struct ctf_node *node_type_declarator)
331{
a0720417 332 struct ctf_node *iter;
add40b62 333 GString *str;
a0720417 334 char *str_c;
add40b62
MD
335 GQuark alias_q;
336 int ret;
337
a0720417 338 str = g_string_new("");
78af2bcd 339 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
340 if (ret) {
341 g_string_free(str, TRUE);
342 return 0;
343 }
344 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
345 g_string_append(str, " *");
346 if (iter->u.pointer.const_qualifier)
347 g_string_append(str, " const");
348 }
349 str_c = g_string_free(str, FALSE);
350 alias_q = g_quark_from_string(str_c);
351 g_free(str_c);
352 return alias_q;
353}
354
a3cca9e9 355static
8fdba45b 356struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
78af2bcd 357 struct ctf_node *type_specifier_list,
a3cca9e9
MD
358 GQuark *field_name,
359 struct ctf_node *node_type_declarator,
add40b62 360 struct declaration_scope *declaration_scope,
e397791f
MD
361 struct declaration *nested_declaration,
362 struct ctf_trace *trace)
a3cca9e9
MD
363{
364 /*
365 * Visit type declarator by first taking care of sequence/array
366 * (recursively). Then, when we get to the identifier, take care
367 * of pointers.
368 */
369
e397791f
MD
370 if (node_type_declarator) {
371 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
add40b62 372
e397791f
MD
373 /* TODO: gcc bitfields not supported yet. */
374 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
78af2bcd 375 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
e397791f
MD
376 return NULL;
377 }
add40b62 378 }
a3cca9e9
MD
379
380 if (!nested_declaration) {
e397791f 381 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
add40b62
MD
382 GQuark alias_q;
383
a3cca9e9
MD
384 /*
385 * If we have a pointer declarator, it _has_ to be present in
386 * the typealiases (else fail).
387 */
add40b62 388 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 389 type_specifier_list, node_type_declarator);
add40b62
MD
390 nested_declaration = lookup_declaration(alias_q, declaration_scope);
391 if (!nested_declaration) {
78af2bcd 392 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
add40b62
MD
393 return NULL;
394 }
4d5fc303
MD
395 if (nested_declaration->id == CTF_TYPE_INTEGER) {
396 struct declaration_integer *integer_declaration =
397 container_of(nested_declaration, struct declaration_integer, p);
398 /* For base to 16 for pointers (expected pretty-print) */
2527e149
MD
399 if (!integer_declaration->base) {
400 /*
401 * We need to do a copy of the
402 * integer declaration to modify it. There could be other references to
403 * it.
404 */
405 integer_declaration = integer_declaration_new(integer_declaration->len,
406 integer_declaration->byte_order, integer_declaration->signedness,
56e60373
MD
407 integer_declaration->p.alignment, 16, integer_declaration->encoding,
408 integer_declaration->clock);
2527e149
MD
409 nested_declaration = &integer_declaration->p;
410 }
4d5fc303 411 }
a3cca9e9 412 } else {
78af2bcd
MD
413 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
414 type_specifier_list, declaration_scope, trace);
a3cca9e9 415 }
a3cca9e9
MD
416 }
417
e397791f
MD
418 if (!node_type_declarator)
419 return nested_declaration;
420
a3cca9e9
MD
421 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
422 if (node_type_declarator->u.type_declarator.u.id)
423 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
424 else
425 *field_name = 0;
426 return nested_declaration;
427 } else {
428 struct declaration *declaration;
98df1c9f 429 struct ctf_node *first;
a3cca9e9
MD
430
431 /* TYPEDEC_NESTED */
432
b5bf4179
MD
433 if (!nested_declaration) {
434 fprintf(fd, "[error] %s: nested type is unknown.\n", __func__);
435 return NULL;
436 }
437
a3cca9e9 438 /* create array/sequence, pass nested_declaration as child. */
98df1c9f
MD
439 if (cds_list_empty(&node_type_declarator->u.type_declarator.u.nested.length)) {
440 fprintf(fd, "[error] %s: expecting length field reference or value.\n", __func__);
a0720417
MD
441 return NULL;
442 }
98df1c9f
MD
443 first = _cds_list_first_entry(&node_type_declarator->u.type_declarator.u.nested.length,
444 struct ctf_node, siblings);
445 assert(first->type == NODE_UNARY_EXPRESSION);
446
447 switch (first->u.unary_expression.type) {
448 case UNARY_UNSIGNED_CONSTANT:
a0720417
MD
449 {
450 struct declaration_array *array_declaration;
451 size_t len;
452
98df1c9f 453 len = first->u.unary_expression.u.unsigned_constant;
a0720417
MD
454 array_declaration = array_declaration_new(len, nested_declaration,
455 declaration_scope);
98df1c9f
MD
456
457 if (!array_declaration) {
458 fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__);
459 return NULL;
460 }
a0720417
MD
461 declaration = &array_declaration->p;
462 break;
463 }
98df1c9f 464 case UNARY_STRING:
a0720417 465 {
98df1c9f
MD
466 /* Lookup unsigned integer definition, create sequence */
467 char *length_name = concatenate_unary_strings(&node_type_declarator->u.type_declarator.u.nested.length);
a0720417 468 struct declaration_sequence *sequence_declaration;
a0720417 469
98df1c9f
MD
470 sequence_declaration = sequence_declaration_new(length_name, nested_declaration, declaration_scope);
471 if (!sequence_declaration) {
472 fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__);
2dd46001
MD
473 return NULL;
474 }
a0720417
MD
475 declaration = &sequence_declaration->p;
476 break;
477 }
478 default:
479 assert(0);
a3cca9e9
MD
480 }
481
482 /* Pass it as content of outer container */
483 declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 484 type_specifier_list, field_name,
a3cca9e9 485 node_type_declarator->u.type_declarator.u.nested.type_declarator,
e397791f 486 declaration_scope, declaration, trace);
a3cca9e9
MD
487 return declaration;
488 }
489}
490
491static
8fdba45b 492int ctf_struct_type_declarators_visit(FILE *fd, int depth,
a3cca9e9 493 struct declaration_struct *struct_declaration,
78af2bcd 494 struct ctf_node *type_specifier_list,
a3cca9e9 495 struct cds_list_head *type_declarators,
e397791f
MD
496 struct declaration_scope *declaration_scope,
497 struct ctf_trace *trace)
a3cca9e9
MD
498{
499 struct ctf_node *iter;
500 GQuark field_name;
501
502 cds_list_for_each_entry(iter, type_declarators, siblings) {
503 struct declaration *field_declaration;
504
505 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 506 type_specifier_list,
a3cca9e9
MD
507 &field_name, iter,
508 struct_declaration->scope,
e397791f 509 NULL, trace);
2dd46001
MD
510 if (!field_declaration) {
511 fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
512 return -EINVAL;
513 }
d3006d91
SM
514
515 /* Check if field with same name already exists */
516 if (struct_declaration_lookup_field_index(struct_declaration, field_name) >= 0) {
517 fprintf(fd, "[error] %s: duplicate field %s in struct\n", __func__, g_quark_to_string(field_name));
518 return -EINVAL;
519 }
520
a3cca9e9
MD
521 struct_declaration_add_field(struct_declaration,
522 g_quark_to_string(field_name),
523 field_declaration);
524 }
add40b62
MD
525 return 0;
526}
a3cca9e9 527
add40b62 528static
8fdba45b 529int ctf_variant_type_declarators_visit(FILE *fd, int depth,
a0720417 530 struct declaration_untagged_variant *untagged_variant_declaration,
78af2bcd 531 struct ctf_node *type_specifier_list,
add40b62 532 struct cds_list_head *type_declarators,
e397791f
MD
533 struct declaration_scope *declaration_scope,
534 struct ctf_trace *trace)
add40b62
MD
535{
536 struct ctf_node *iter;
537 GQuark field_name;
538
539 cds_list_for_each_entry(iter, type_declarators, siblings) {
540 struct declaration *field_declaration;
541
542 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 543 type_specifier_list,
add40b62 544 &field_name, iter,
a0720417 545 untagged_variant_declaration->scope,
e397791f 546 NULL, trace);
2dd46001
MD
547 if (!field_declaration) {
548 fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
549 return -EINVAL;
550 }
43f9090c
SM
551
552 if (untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration, field_name) != NULL) {
553 fprintf(fd, "[error] %s: duplicate field %s in variant\n", __func__, g_quark_to_string(field_name));
554 return -EINVAL;
555 }
556
557
a0720417 558 untagged_variant_declaration_add_field(untagged_variant_declaration,
add40b62
MD
559 g_quark_to_string(field_name),
560 field_declaration);
561 }
a3cca9e9
MD
562 return 0;
563}
564
565static
8fdba45b 566int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
78af2bcd 567 struct ctf_node *type_specifier_list,
e397791f
MD
568 struct cds_list_head *type_declarators,
569 struct ctf_trace *trace)
a3cca9e9
MD
570{
571 struct ctf_node *iter;
572 GQuark identifier;
573
574 cds_list_for_each_entry(iter, type_declarators, siblings) {
575 struct declaration *type_declaration;
576 int ret;
577
578 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 579 type_specifier_list,
a3cca9e9 580 &identifier, iter,
e397791f 581 scope, NULL, trace);
2dd46001
MD
582 if (!type_declaration) {
583 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
584 return -EINVAL;
585 }
586 /*
587 * Don't allow typedef and typealias of untagged
588 * variants.
589 */
590 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
591 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
592 declaration_unref(type_declaration);
593 return -EPERM;
594 }
a3cca9e9
MD
595 ret = register_declaration(identifier, type_declaration, scope);
596 if (ret) {
597 type_declaration->declaration_free(type_declaration);
598 return ret;
599 }
600 }
601 return 0;
602}
603
604static
8fdba45b 605int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
e397791f
MD
606 struct ctf_node *target, struct ctf_node *alias,
607 struct ctf_trace *trace)
a3cca9e9
MD
608{
609 struct declaration *type_declaration;
a0720417 610 struct ctf_node *node;
add40b62 611 GQuark dummy_id;
a3cca9e9 612 GQuark alias_q;
a0720417 613 int err;
a3cca9e9
MD
614
615 /* See ctf_visitor_type_declarator() in the semantic validator. */
616
617 /*
618 * Create target type declaration.
619 */
620
427c09b7 621 if (cds_list_empty(&target->u.typealias_target.type_declarators))
a0720417
MD
622 node = NULL;
623 else
427c09b7 624 node = _cds_list_first_entry(&target->u.typealias_target.type_declarators,
a0720417 625 struct ctf_node, siblings);
a3cca9e9 626 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 627 target->u.typealias_target.type_specifier_list,
a0720417 628 &dummy_id, node,
e397791f 629 scope, NULL, trace);
a3cca9e9 630 if (!type_declaration) {
78af2bcd 631 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
a3cca9e9
MD
632 err = -EINVAL;
633 goto error;
634 }
2dd46001
MD
635 /*
636 * Don't allow typedef and typealias of untagged
637 * variants.
638 */
639 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
640 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
641 declaration_unref(type_declaration);
642 return -EPERM;
643 }
a3cca9e9
MD
644 /*
645 * The semantic validator does not check whether the target is
646 * abstract or not (if it has an identifier). Check it here.
647 */
648 if (dummy_id != 0) {
78af2bcd 649 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
a3cca9e9
MD
650 err = -EINVAL;
651 goto error;
652 }
653 /*
654 * Create alias identifier.
655 */
a3cca9e9
MD
656
657 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
a0720417 658 struct ctf_node, siblings);
add40b62 659 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 660 alias->u.typealias_alias.type_specifier_list, node);
a0720417
MD
661 err = register_declaration(alias_q, type_declaration, scope);
662 if (err)
a3cca9e9
MD
663 goto error;
664 return 0;
665
666error:
230da743
SM
667 if (type_declaration) {
668 type_declaration->declaration_free(type_declaration);
669 }
a0720417 670 return err;
a3cca9e9
MD
671}
672
673static
8fdba45b 674int ctf_struct_declaration_list_visit(FILE *fd, int depth,
e397791f
MD
675 struct ctf_node *iter, struct declaration_struct *struct_declaration,
676 struct ctf_trace *trace)
a3cca9e9 677{
a3cca9e9
MD
678 int ret;
679
680 switch (iter->type) {
681 case NODE_TYPEDEF:
682 /* For each declarator, declare type and add type to struct declaration scope */
683 ret = ctf_typedef_visit(fd, depth,
684 struct_declaration->scope,
78af2bcd 685 iter->u._typedef.type_specifier_list,
e397791f 686 &iter->u._typedef.type_declarators, trace);
a3cca9e9
MD
687 if (ret)
688 return ret;
689 break;
690 case NODE_TYPEALIAS:
691 /* Declare type with declarator and add type to struct declaration scope */
692 ret = ctf_typealias_visit(fd, depth,
693 struct_declaration->scope,
694 iter->u.typealias.target,
e397791f 695 iter->u.typealias.alias, trace);
a3cca9e9
MD
696 if (ret)
697 return ret;
698 break;
699 case NODE_STRUCT_OR_VARIANT_DECLARATION:
700 /* Add field to structure declaration */
701 ret = ctf_struct_type_declarators_visit(fd, depth,
702 struct_declaration,
78af2bcd 703 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
704 &iter->u.struct_or_variant_declaration.type_declarators,
705 struct_declaration->scope, trace);
a3cca9e9
MD
706 if (ret)
707 return ret;
708 break;
709 default:
78af2bcd 710 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
a3cca9e9
MD
711 assert(0);
712 }
713 return 0;
714}
715
add40b62 716static
8fdba45b 717int ctf_variant_declaration_list_visit(FILE *fd, int depth,
a0720417
MD
718 struct ctf_node *iter,
719 struct declaration_untagged_variant *untagged_variant_declaration,
e397791f 720 struct ctf_trace *trace)
add40b62 721{
add40b62
MD
722 int ret;
723
724 switch (iter->type) {
725 case NODE_TYPEDEF:
726 /* For each declarator, declare type and add type to variant declaration scope */
727 ret = ctf_typedef_visit(fd, depth,
a0720417 728 untagged_variant_declaration->scope,
78af2bcd 729 iter->u._typedef.type_specifier_list,
e397791f 730 &iter->u._typedef.type_declarators, trace);
add40b62
MD
731 if (ret)
732 return ret;
733 break;
734 case NODE_TYPEALIAS:
735 /* Declare type with declarator and add type to variant declaration scope */
736 ret = ctf_typealias_visit(fd, depth,
a0720417 737 untagged_variant_declaration->scope,
add40b62 738 iter->u.typealias.target,
e397791f 739 iter->u.typealias.alias, trace);
add40b62
MD
740 if (ret)
741 return ret;
742 break;
743 case NODE_STRUCT_OR_VARIANT_DECLARATION:
744 /* Add field to structure declaration */
745 ret = ctf_variant_type_declarators_visit(fd, depth,
a0720417 746 untagged_variant_declaration,
78af2bcd 747 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
748 &iter->u.struct_or_variant_declaration.type_declarators,
749 untagged_variant_declaration->scope, trace);
add40b62
MD
750 if (ret)
751 return ret;
752 break;
753 default:
78af2bcd 754 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
add40b62
MD
755 assert(0);
756 }
757 return 0;
758}
759
a3cca9e9 760static
a0720417 761struct declaration *ctf_declaration_struct_visit(FILE *fd,
a3cca9e9 762 int depth, const char *name, struct cds_list_head *declaration_list,
b7e35bad
MD
763 int has_body, struct cds_list_head *min_align,
764 struct declaration_scope *declaration_scope,
e397791f 765 struct ctf_trace *trace)
a3cca9e9 766{
a3cca9e9
MD
767 struct declaration_struct *struct_declaration;
768 struct ctf_node *iter;
a0720417 769 int ret;
a3cca9e9
MD
770
771 /*
772 * For named struct (without body), lookup in
773 * declaration scope. Don't take reference on struct
774 * declaration: ref is only taken upon definition.
775 */
776 if (!has_body) {
777 assert(name);
778 struct_declaration =
779 lookup_struct_declaration(g_quark_from_string(name),
780 declaration_scope);
a0720417 781 return &struct_declaration->p;
a3cca9e9 782 } else {
b7e35bad
MD
783 uint64_t min_align_value = 0;
784
a3cca9e9
MD
785 /* For unnamed struct, create type */
786 /* For named struct (with body), create type and add to declaration scope */
787 if (name) {
788 if (lookup_struct_declaration(g_quark_from_string(name),
789 declaration_scope)) {
790
78af2bcd 791 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
a3cca9e9
MD
792 return NULL;
793 }
794 }
b7e35bad
MD
795 if (!cds_list_empty(min_align)) {
796 ret = get_unary_unsigned(min_align, &min_align_value);
797 if (ret) {
798 fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
799 ret = -EINVAL;
800 goto error;
801 }
802 }
803 struct_declaration = struct_declaration_new(declaration_scope,
804 min_align_value);
a3cca9e9 805 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f
MD
806 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
807 struct_declaration, trace);
a3cca9e9 808 if (ret)
5c551b40 809 goto error_free_declaration;
a3cca9e9
MD
810 }
811 if (name) {
812 ret = register_struct_declaration(g_quark_from_string(name),
813 struct_declaration,
814 declaration_scope);
815 assert(!ret);
816 }
a0720417 817 return &struct_declaration->p;
a3cca9e9 818 }
5c551b40 819error_free_declaration:
a3cca9e9 820 struct_declaration->p.declaration_free(&struct_declaration->p);
5c551b40 821error:
a3cca9e9
MD
822 return NULL;
823}
824
05628561 825static
a0720417
MD
826struct declaration *ctf_declaration_variant_visit(FILE *fd,
827 int depth, const char *name, const char *choice,
828 struct cds_list_head *declaration_list,
e397791f
MD
829 int has_body, struct declaration_scope *declaration_scope,
830 struct ctf_trace *trace)
05628561 831{
a0720417 832 struct declaration_untagged_variant *untagged_variant_declaration;
add40b62
MD
833 struct declaration_variant *variant_declaration;
834 struct ctf_node *iter;
a0720417 835 int ret;
de47353a 836
add40b62
MD
837 /*
838 * For named variant (without body), lookup in
839 * declaration scope. Don't take reference on variant
840 * declaration: ref is only taken upon definition.
841 */
842 if (!has_body) {
843 assert(name);
a0720417 844 untagged_variant_declaration =
add40b62
MD
845 lookup_variant_declaration(g_quark_from_string(name),
846 declaration_scope);
add40b62 847 } else {
de47353a 848 /* For unnamed variant, create type */
add40b62
MD
849 /* For named variant (with body), create type and add to declaration scope */
850 if (name) {
851 if (lookup_variant_declaration(g_quark_from_string(name),
852 declaration_scope)) {
853
78af2bcd 854 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
add40b62
MD
855 return NULL;
856 }
857 }
a0720417 858 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
add40b62 859 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f 860 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
a0720417 861 untagged_variant_declaration, trace);
add40b62
MD
862 if (ret)
863 goto error;
864 }
865 if (name) {
866 ret = register_variant_declaration(g_quark_from_string(name),
a0720417 867 untagged_variant_declaration,
add40b62
MD
868 declaration_scope);
869 assert(!ret);
870 }
a0720417
MD
871 }
872 /*
873 * if tagged, create tagged variant and return. else return
874 * untagged variant.
875 */
876 if (!choice) {
877 return &untagged_variant_declaration->p;
878 } else {
879 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
880 if (!variant_declaration)
881 goto error;
882 declaration_unref(&untagged_variant_declaration->p);
883 return &variant_declaration->p;
de47353a 884 }
add40b62 885error:
2dd46001 886 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
add40b62 887 return NULL;
05628561
MD
888}
889
05628561 890static
8fdba45b 891int ctf_enumerator_list_visit(FILE *fd, int depth,
add40b62
MD
892 struct ctf_node *enumerator,
893 struct declaration_enum *enum_declaration)
894{
1cfda062
MD
895 GQuark q;
896 struct ctf_node *iter;
897
898 q = g_quark_from_string(enumerator->u.enumerator.id);
a0720417 899 if (enum_declaration->integer_declaration->signedness) {
1cfda062
MD
900 int64_t start, end;
901 int nr_vals = 0;
902
a0720417 903 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
1cfda062
MD
904 int64_t *target;
905
906 assert(iter->type == NODE_UNARY_EXPRESSION);
907 if (nr_vals == 0)
908 target = &start;
909 else
910 target = &end;
911
912 switch (iter->u.unary_expression.type) {
913 case UNARY_SIGNED_CONSTANT:
914 *target = iter->u.unary_expression.u.signed_constant;
915 break;
916 case UNARY_UNSIGNED_CONSTANT:
917 *target = iter->u.unary_expression.u.unsigned_constant;
918 break;
919 default:
78af2bcd 920 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
921 return -EINVAL;
922 }
923 if (nr_vals > 1) {
78af2bcd 924 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
925 return -EINVAL;
926 }
927 nr_vals++;
928 }
929 if (nr_vals == 1)
930 end = start;
931 enum_signed_insert(enum_declaration, start, end, q);
a0720417 932 } else {
1cfda062
MD
933 uint64_t start, end;
934 int nr_vals = 0;
935
a0720417
MD
936 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
937 uint64_t *target;
1cfda062
MD
938
939 assert(iter->type == NODE_UNARY_EXPRESSION);
940 if (nr_vals == 0)
941 target = &start;
942 else
943 target = &end;
944
945 switch (iter->u.unary_expression.type) {
946 case UNARY_UNSIGNED_CONSTANT:
947 *target = iter->u.unary_expression.u.unsigned_constant;
948 break;
949 case UNARY_SIGNED_CONSTANT:
950 /*
951 * We don't accept signed constants for enums with unsigned
952 * container type.
953 */
78af2bcd 954 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
1cfda062
MD
955 return -EINVAL;
956 default:
78af2bcd 957 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
958 return -EINVAL;
959 }
960 if (nr_vals > 1) {
78af2bcd 961 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
962 return -EINVAL;
963 }
964 nr_vals++;
965 }
966 if (nr_vals == 1)
967 end = start;
968 enum_unsigned_insert(enum_declaration, start, end, q);
969 }
add40b62
MD
970 return 0;
971}
972
973static
8fdba45b 974struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
add40b62 975 const char *name,
78af2bcd 976 struct ctf_node *container_type,
add40b62 977 struct cds_list_head *enumerator_list,
1cfda062
MD
978 int has_body,
979 struct declaration_scope *declaration_scope,
980 struct ctf_trace *trace)
05628561 981{
add40b62
MD
982 struct declaration *declaration;
983 struct declaration_enum *enum_declaration;
984 struct declaration_integer *integer_declaration;
78af2bcd 985 struct ctf_node *iter;
1cfda062 986 GQuark dummy_id;
a0720417 987 int ret;
add40b62 988
05628561 989 /*
add40b62
MD
990 * For named enum (without body), lookup in
991 * declaration scope. Don't take reference on enum
992 * declaration: ref is only taken upon definition.
05628561 993 */
add40b62
MD
994 if (!has_body) {
995 assert(name);
996 enum_declaration =
997 lookup_enum_declaration(g_quark_from_string(name),
998 declaration_scope);
a0720417 999 return &enum_declaration->p;
add40b62
MD
1000 } else {
1001 /* For unnamed enum, create type */
1002 /* For named enum (with body), create type and add to declaration scope */
1003 if (name) {
1004 if (lookup_enum_declaration(g_quark_from_string(name),
1005 declaration_scope)) {
1006
78af2bcd 1007 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
add40b62
MD
1008 return NULL;
1009 }
1010 }
78af2bcd 1011 if (!container_type) {
6743829a
MD
1012 declaration = lookup_declaration(g_quark_from_static_string("int"),
1013 declaration_scope);
1014 if (!declaration) {
1015 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
1016 return NULL;
1017 }
1018 } else {
1019 declaration = ctf_type_declarator_visit(fd, depth,
1020 container_type,
1021 &dummy_id, NULL,
1022 declaration_scope,
1023 NULL, trace);
1cfda062 1024 }
30ea18a1
MD
1025 if (!declaration) {
1026 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
1027 return NULL;
1028 }
1029 if (declaration->id != CTF_TYPE_INTEGER) {
1030 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
1031 return NULL;
1cfda062 1032 }
30ea18a1 1033 integer_declaration = container_of(declaration, struct declaration_integer, p);
a0720417 1034 enum_declaration = enum_declaration_new(integer_declaration);
add40b62
MD
1035 declaration_unref(&integer_declaration->p); /* leave ref to enum */
1036 cds_list_for_each_entry(iter, enumerator_list, siblings) {
1037 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
1038 if (ret)
1039 goto error;
1040 }
1041 if (name) {
1042 ret = register_enum_declaration(g_quark_from_string(name),
1043 enum_declaration,
1044 declaration_scope);
1045 assert(!ret);
1046 }
a0720417 1047 return &enum_declaration->p;
05628561 1048 }
add40b62
MD
1049error:
1050 enum_declaration->p.declaration_free(&enum_declaration->p);
1051 return NULL;
05628561
MD
1052}
1053
1054static
8fdba45b 1055struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
78af2bcd 1056 struct ctf_node *type_specifier_list,
d20f5e59 1057 struct declaration_scope *declaration_scope)
05628561 1058{
add40b62
MD
1059 GString *str;
1060 struct declaration *declaration;
a0720417
MD
1061 char *str_c;
1062 int ret;
1063 GQuark id_q;
05628561 1064
a0720417 1065 str = g_string_new("");
78af2bcd 1066 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
1067 if (ret)
1068 return NULL;
1069 str_c = g_string_free(str, FALSE);
1070 id_q = g_quark_from_string(str_c);
1071 g_free(str_c);
1072 declaration = lookup_declaration(id_q, declaration_scope);
1073 return declaration;
1074}
1075
ab4cf058
MD
1076/*
1077 * Returns 0/1 boolean, or < 0 on error.
1078 */
1079static
a0720417 1080int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
ab4cf058
MD
1081{
1082 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
78af2bcd 1083 fprintf(fd, "[error] %s: expecting unary expression\n",
ab4cf058
MD
1084 __func__);
1085 return -EINVAL;
1086 }
1087 switch (unary_expression->u.unary_expression.type) {
1088 case UNARY_UNSIGNED_CONSTANT:
1089 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
1090 return 0;
1091 else
1092 return 1;
1093 case UNARY_SIGNED_CONSTANT:
1094 if (unary_expression->u.unary_expression.u.signed_constant == 0)
1095 return 0;
1096 else
1097 return 1;
1098 case UNARY_STRING:
1099 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
1100 return 1;
1101 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
1102 return 1;
1103 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
1104 return 0;
1105 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
1106 return 0;
1107 else {
78af2bcd 1108 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
ab4cf058
MD
1109 __func__, unary_expression->u.unary_expression.u.string);
1110 return -EINVAL;
1111 }
1112 break;
1113 default:
78af2bcd 1114 fprintf(fd, "[error] %s: unexpected unary expression type\n",
ab4cf058
MD
1115 __func__);
1116 return -EINVAL;
1117 }
1118
1119}
1120
0f980a35
MD
1121static
1122int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1123{
1124 int byte_order;
1125
1126 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1127 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1128 __func__);
1129 return -EINVAL;
1130 }
1131 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1132 byte_order = BIG_ENDIAN;
1133 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1134 byte_order = LITTLE_ENDIAN;
1135 else {
1136 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1137 __func__, unary_expression->u.unary_expression.u.string);
1138 return -EINVAL;
1139 }
1140 return byte_order;
1141}
1142
ab4cf058 1143static
a0720417
MD
1144int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1145 struct ctf_trace *trace)
ab4cf058
MD
1146{
1147 int byte_order;
1148
1149 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1150 fprintf(fd, "[error] %s: byte_order: expecting string\n",
ab4cf058
MD
1151 __func__);
1152 return -EINVAL;
1153 }
1154 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1155 byte_order = trace->byte_order;
1156 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1157 byte_order = BIG_ENDIAN;
1158 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1159 byte_order = BIG_ENDIAN;
1160 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1161 byte_order = LITTLE_ENDIAN;
1162 else {
78af2bcd 1163 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
a0720417 1164 __func__, unary_expression->u.unary_expression.u.string);
ab4cf058
MD
1165 return -EINVAL;
1166 }
1167 return byte_order;
1168}
1169
add40b62 1170static
8fdba45b 1171struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
ab4cf058
MD
1172 struct cds_list_head *expressions,
1173 struct ctf_trace *trace)
add40b62 1174{
a0720417 1175 struct ctf_node *expression;
68262b11 1176 uint64_t alignment = 1, size = 0;
ab4cf058
MD
1177 int byte_order = trace->byte_order;
1178 int signedness = 0;
add40b62 1179 int has_alignment = 0, has_size = 0;
4d5fc303 1180 int base = 0;
81dee1bb 1181 enum ctf_string_encoding encoding = CTF_STRING_NONE;
56e60373 1182 struct ctf_clock *clock = NULL;
add40b62
MD
1183 struct declaration_integer *integer_declaration;
1184
1185 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1186 struct ctf_node *left, *right;
add40b62 1187
a0720417
MD
1188 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1189 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
add40b62
MD
1190 assert(left->u.unary_expression.type == UNARY_STRING);
1191 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
ab4cf058
MD
1192 signedness = get_boolean(fd, depth, right);
1193 if (signedness < 0)
1194 return NULL;
add40b62 1195 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1196 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1197 if (byte_order < 0)
1198 return NULL;
add40b62 1199 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
ab4cf058 1200 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1201 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
ab4cf058
MD
1202 __func__);
1203 return NULL;
1204 }
1205 size = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
1206 has_size = 1;
1207 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
ab4cf058 1208 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1209 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1210 __func__);
1211 return NULL;
1212 }
1213 alignment = right->u.unary_expression.u.unsigned_constant;
53532829
MD
1214 /* Make sure alignment is a power of two */
1215 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1216 fprintf(fd, "[error] %s: align: expecting power of two\n",
1217 __func__);
1218 return NULL;
1219 }
add40b62 1220 has_alignment = 1;
164078da
MD
1221 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
1222 switch (right->u.unary_expression.type) {
1223 case UNARY_UNSIGNED_CONSTANT:
1224 switch (right->u.unary_expression.u.unsigned_constant) {
1225 case 2:
1226 case 8:
1227 case 10:
1228 case 16:
1229 base = right->u.unary_expression.u.unsigned_constant;
1230 break;
1231 default:
1232 fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
1233 __func__, right->u.unary_expression.u.unsigned_constant);
1234 return NULL;
1235 }
1236 break;
1237 case UNARY_STRING:
1238 {
1239 char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1240 if (!s_right) {
1241 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1242 g_free(s_right);
1243 return NULL;
1244 }
1245 if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
1246 || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
1247 base = 10;
1248 } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
1249 || !strcmp(s_right, "x") || !strcmp(s_right, "X")
1250 || !strcmp(s_right, "p")) {
1251 base = 16;
1252 } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
1253 || !strcmp(s_right, "o")) {
1254 base = 8;
1255 } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
1256 base = 2;
1257 } else {
1258 fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
1259 g_free(s_right);
1260 return NULL;
1261 }
1262
1263 g_free(s_right);
1264 break;
1265 }
1266 default:
1267 fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
1268 __func__);
1269 return NULL;
1270 }
81dee1bb
MD
1271 } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1272 char *s_right;
1273
1274 if (right->u.unary_expression.type != UNARY_STRING) {
1275 fprintf(fd, "[error] %s: encoding: expecting unary string\n",
1276 __func__);
1277 return NULL;
1278 }
1279 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1280 if (!s_right) {
1281 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1282 g_free(s_right);
1283 return NULL;
1284 }
1285 if (!strcmp(s_right, "UTF8")
1286 || !strcmp(s_right, "utf8")
1287 || !strcmp(s_right, "utf-8")
1288 || !strcmp(s_right, "UTF-8"))
1289 encoding = CTF_STRING_UTF8;
1290 else if (!strcmp(s_right, "ASCII")
1291 || !strcmp(s_right, "ascii"))
1292 encoding = CTF_STRING_ASCII;
b5bf4179
MD
1293 else if (!strcmp(s_right, "none"))
1294 encoding = CTF_STRING_NONE;
81dee1bb
MD
1295 else {
1296 fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
1297 g_free(s_right);
1298 return NULL;
1299 }
1300 g_free(s_right);
73d15916 1301 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
56e60373 1302 GQuark clock_name;
73d15916
MD
1303
1304 if (right->u.unary_expression.type != UNARY_STRING) {
1305 fprintf(fd, "[error] %s: map: expecting identifier\n",
1306 __func__);
1307 return NULL;
1308 }
56e60373
MD
1309 /* currently only support clock.name.value */
1310 clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
1311 if (!clock_name) {
1312 char *s_right;
1313
1314 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1315 if (!s_right) {
1316 fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
1317 g_free(s_right);
1318 return NULL;
1319 }
1320 fprintf(fd, "[warning] %s: unknown map %s in integer declaration\n", __func__,
1321 s_right);
73d15916 1322 g_free(s_right);
56e60373
MD
1323 continue;
1324 }
1325 clock = trace_clock_lookup(trace, clock_name);
1326 if (!clock) {
1327 fprintf(fd, "[error] %s: map: unable to find clock %s declaration\n",
1328 __func__, g_quark_to_string(clock_name));
73d15916
MD
1329 return NULL;
1330 }
add40b62 1331 } else {
b3ab6665 1332 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
add40b62 1333 __func__, left->u.unary_expression.u.string);
b3ab6665 1334 /* Fall-through after warning */
add40b62 1335 }
05628561 1336 }
add40b62 1337 if (!has_size) {
78af2bcd 1338 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
add40b62
MD
1339 return NULL;
1340 }
ab4cf058
MD
1341 if (!has_alignment) {
1342 if (size % CHAR_BIT) {
1343 /* bit-packed alignment */
1344 alignment = 1;
1345 } else {
1346 /* byte-packed alignment */
1347 alignment = CHAR_BIT;
1348 }
1349 }
add40b62 1350 integer_declaration = integer_declaration_new(size,
81dee1bb 1351 byte_order, signedness, alignment,
56e60373 1352 base, encoding, clock);
add40b62 1353 return &integer_declaration->p;
05628561
MD
1354}
1355
ab4cf058 1356static
8fdba45b 1357struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
ab4cf058
MD
1358 struct cds_list_head *expressions,
1359 struct ctf_trace *trace)
1360{
a0720417 1361 struct ctf_node *expression;
5c551b40
MD
1362 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0,
1363 byte_order = trace->byte_order;
ab4cf058
MD
1364 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1365 struct declaration_float *float_declaration;
1366
1367 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1368 struct ctf_node *left, *right;
ab4cf058 1369
a0720417
MD
1370 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1371 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1372 assert(left->u.unary_expression.type == UNARY_STRING);
1373 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1374 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1375 if (byte_order < 0)
1376 return NULL;
1377 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1378 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1379 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
ab4cf058
MD
1380 __func__);
1381 return NULL;
1382 }
1383 exp_dig = right->u.unary_expression.u.unsigned_constant;
1384 has_exp_dig = 1;
1385 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1386 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1387 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
ab4cf058
MD
1388 __func__);
1389 return NULL;
1390 }
1391 mant_dig = right->u.unary_expression.u.unsigned_constant;
1392 has_mant_dig = 1;
1393 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1394 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1395 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1396 __func__);
1397 return NULL;
1398 }
1399 alignment = right->u.unary_expression.u.unsigned_constant;
53532829
MD
1400 /* Make sure alignment is a power of two */
1401 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1402 fprintf(fd, "[error] %s: align: expecting power of two\n",
1403 __func__);
1404 return NULL;
1405 }
ab4cf058
MD
1406 has_alignment = 1;
1407 } else {
b3ab6665 1408 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
ab4cf058 1409 __func__, left->u.unary_expression.u.string);
b3ab6665 1410 /* Fall-through after warning */
ab4cf058
MD
1411 }
1412 }
1413 if (!has_mant_dig) {
78af2bcd 1414 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
ab4cf058
MD
1415 return NULL;
1416 }
1417 if (!has_exp_dig) {
78af2bcd 1418 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
ab4cf058
MD
1419 return NULL;
1420 }
1421 if (!has_alignment) {
1422 if ((mant_dig + exp_dig) % CHAR_BIT) {
1423 /* bit-packed alignment */
1424 alignment = 1;
1425 } else {
1426 /* byte-packed alignment */
1427 alignment = CHAR_BIT;
1428 }
1429 }
1430 float_declaration = float_declaration_new(mant_dig, exp_dig,
1431 byte_order, alignment);
1432 return &float_declaration->p;
1433}
1434
1435static
8fdba45b 1436struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
ab4cf058
MD
1437 struct cds_list_head *expressions,
1438 struct ctf_trace *trace)
1439{
a0720417 1440 struct ctf_node *expression;
ab4cf058
MD
1441 const char *encoding_c = NULL;
1442 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1443 struct declaration_string *string_declaration;
1444
1445 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1446 struct ctf_node *left, *right;
ab4cf058 1447
a0720417
MD
1448 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1449 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1450 assert(left->u.unary_expression.type == UNARY_STRING);
1451 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
a0720417 1452 if (right->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1453 fprintf(fd, "[error] %s: encoding: expecting string\n",
ab4cf058
MD
1454 __func__);
1455 return NULL;
1456 }
1457 encoding_c = right->u.unary_expression.u.string;
1458 } else {
b3ab6665 1459 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
ab4cf058 1460 __func__, left->u.unary_expression.u.string);
b3ab6665 1461 /* Fall-through after warning */
ab4cf058
MD
1462 }
1463 }
1464 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1465 encoding = CTF_STRING_ASCII;
1466 string_declaration = string_declaration_new(encoding);
1467 return &string_declaration->p;
1468}
1469
1470
05628561 1471static
78af2bcd
MD
1472struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1473 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
1474 struct declaration_scope *declaration_scope,
1475 struct ctf_trace *trace)
05628561 1476{
a0720417 1477 struct ctf_node *first;
78af2bcd 1478 struct ctf_node *node;
d20f5e59 1479
427c09b7
MD
1480 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1481
78af2bcd 1482 first = _cds_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
05628561 1483
78af2bcd
MD
1484 assert(first->type == NODE_TYPE_SPECIFIER);
1485
1486 node = first->u.type_specifier.node;
1487
1488 switch (first->u.type_specifier.type) {
1489 case TYPESPEC_FLOATING_POINT:
1490 return ctf_declaration_floating_point_visit(fd, depth,
1491 &node->u.floating_point.expressions, trace);
1492 case TYPESPEC_INTEGER:
1493 return ctf_declaration_integer_visit(fd, depth,
1494 &node->u.integer.expressions, trace);
1495 case TYPESPEC_STRING:
1496 return ctf_declaration_string_visit(fd, depth,
5039b4cc 1497 &node->u.string.expressions, trace);
78af2bcd 1498 case TYPESPEC_STRUCT:
add40b62 1499 return ctf_declaration_struct_visit(fd, depth,
78af2bcd
MD
1500 node->u._struct.name,
1501 &node->u._struct.declaration_list,
1502 node->u._struct.has_body,
b7e35bad 1503 &node->u._struct.min_align,
ab4cf058
MD
1504 declaration_scope,
1505 trace);
78af2bcd 1506 case TYPESPEC_VARIANT:
add40b62 1507 return ctf_declaration_variant_visit(fd, depth,
78af2bcd
MD
1508 node->u.variant.name,
1509 node->u.variant.choice,
1510 &node->u.variant.declaration_list,
1511 node->u.variant.has_body,
ab4cf058
MD
1512 declaration_scope,
1513 trace);
78af2bcd 1514 case TYPESPEC_ENUM:
add40b62 1515 return ctf_declaration_enum_visit(fd, depth,
78af2bcd
MD
1516 node->u._enum.enum_id,
1517 node->u._enum.container_type,
1518 &node->u._enum.enumerator_list,
1519 node->u._enum.has_body,
1cfda062 1520 declaration_scope,
ab4cf058 1521 trace);
78af2bcd
MD
1522
1523 case TYPESPEC_VOID:
1524 case TYPESPEC_CHAR:
1525 case TYPESPEC_SHORT:
1526 case TYPESPEC_INT:
1527 case TYPESPEC_LONG:
1528 case TYPESPEC_FLOAT:
1529 case TYPESPEC_DOUBLE:
1530 case TYPESPEC_SIGNED:
1531 case TYPESPEC_UNSIGNED:
1532 case TYPESPEC_BOOL:
1533 case TYPESPEC_COMPLEX:
1534 case TYPESPEC_IMAGINARY:
1535 case TYPESPEC_CONST:
1536 case TYPESPEC_ID_TYPE:
add40b62 1537 return ctf_declaration_type_specifier_visit(fd, depth,
78af2bcd 1538 type_specifier_list, declaration_scope);
a0720417 1539 default:
78af2bcd 1540 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
a0720417 1541 return NULL;
add40b62 1542 }
05628561
MD
1543}
1544
1545static
1546int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1547{
1548 int ret = 0;
1549
1550 switch (node->type) {
1551 case NODE_TYPEDEF:
1552 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1553 event->declaration_scope,
78af2bcd 1554 node->u._typedef.type_specifier_list,
05628561 1555 &node->u._typedef.type_declarators,
a0720417 1556 trace);
05628561
MD
1557 if (ret)
1558 return ret;
1559 break;
1560 case NODE_TYPEALIAS:
1561 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1562 event->declaration_scope,
1563 node->u.typealias.target, node->u.typealias.alias,
1564 trace);
05628561
MD
1565 if (ret)
1566 return ret;
1567 break;
1568 case NODE_CTF_EXPRESSION:
1569 {
1570 char *left;
1571
1572 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1573 if (!strcmp(left, "name")) {
1574 char *right;
1575
427c09b7
MD
1576 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1577 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
0f980a35
MD
1578 ret = -EPERM;
1579 goto error;
427c09b7 1580 }
05628561
MD
1581 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1582 if (!right) {
78af2bcd 1583 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
0f980a35
MD
1584 ret = -EINVAL;
1585 goto error;
05628561
MD
1586 }
1587 event->name = g_quark_from_string(right);
41253107 1588 g_free(right);
05628561
MD
1589 CTF_EVENT_SET_FIELD(event, name);
1590 } else if (!strcmp(left, "id")) {
427c09b7
MD
1591 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1592 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
0f980a35
MD
1593 ret = -EPERM;
1594 goto error;
427c09b7 1595 }
05628561
MD
1596 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1597 if (ret) {
78af2bcd 1598 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
0f980a35
MD
1599 ret = -EINVAL;
1600 goto error;
05628561
MD
1601 }
1602 CTF_EVENT_SET_FIELD(event, id);
1603 } else if (!strcmp(left, "stream_id")) {
427c09b7
MD
1604 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1605 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
0f980a35
MD
1606 ret = -EPERM;
1607 goto error;
427c09b7 1608 }
05628561
MD
1609 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1610 if (ret) {
78af2bcd 1611 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
0f980a35
MD
1612 ret = -EINVAL;
1613 goto error;
05628561
MD
1614 }
1615 event->stream = trace_stream_lookup(trace, event->stream_id);
1616 if (!event->stream) {
78af2bcd 1617 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
0f980a35
MD
1618 ret = -EINVAL;
1619 goto error;
05628561 1620 }
05628561
MD
1621 CTF_EVENT_SET_FIELD(event, stream_id);
1622 } else if (!strcmp(left, "context")) {
1623 struct declaration *declaration;
1624
427c09b7
MD
1625 if (event->context_decl) {
1626 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
0f980a35
MD
1627 ret = -EINVAL;
1628 goto error;
427c09b7 1629 }
78af2bcd
MD
1630 declaration = ctf_type_specifier_list_visit(fd, depth,
1631 _cds_list_first_entry(&node->u.ctf_expression.right,
1632 struct ctf_node, siblings),
ab4cf058 1633 event->declaration_scope, trace);
0f980a35
MD
1634 if (!declaration) {
1635 ret = -EPERM;
1636 goto error;
1637 }
1638 if (declaration->id != CTF_TYPE_STRUCT) {
1639 ret = -EPERM;
1640 goto error;
1641 }
9e29e16e 1642 event->context_decl = container_of(declaration, struct declaration_struct, p);
05628561
MD
1643 } else if (!strcmp(left, "fields")) {
1644 struct declaration *declaration;
1645
427c09b7
MD
1646 if (event->fields_decl) {
1647 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
0f980a35
MD
1648 ret = -EINVAL;
1649 goto error;
427c09b7 1650 }
78af2bcd
MD
1651 declaration = ctf_type_specifier_list_visit(fd, depth,
1652 _cds_list_first_entry(&node->u.ctf_expression.right,
1653 struct ctf_node, siblings),
ab4cf058 1654 event->declaration_scope, trace);
0f980a35
MD
1655 if (!declaration) {
1656 ret = -EPERM;
1657 goto error;
1658 }
1659 if (declaration->id != CTF_TYPE_STRUCT) {
1660 ret = -EPERM;
1661 goto error;
1662 }
9e29e16e 1663 event->fields_decl = container_of(declaration, struct declaration_struct, p);
306eeaa6
MD
1664 } else if (!strcmp(left, "loglevel")) {
1665 int64_t loglevel = -1;
d86d62f8 1666
306eeaa6
MD
1667 if (CTF_EVENT_FIELD_IS_SET(event, loglevel)) {
1668 fprintf(fd, "[error] %s: loglevel already declared in event declaration\n", __func__);
d86d62f8
MD
1669 ret = -EPERM;
1670 goto error;
1671 }
306eeaa6 1672 ret = get_unary_signed(&node->u.ctf_expression.right, &loglevel);
d86d62f8 1673 if (ret) {
306eeaa6 1674 fprintf(fd, "[error] %s: unexpected unary expression for event loglevel\n", __func__);
d86d62f8
MD
1675 ret = -EINVAL;
1676 goto error;
1677 }
209209be 1678 event->loglevel = (int) loglevel;
306eeaa6 1679 CTF_EVENT_SET_FIELD(event, loglevel);
98df1c9f 1680 } else {
b3ab6665
MD
1681 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
1682 /* Fall-through after warning */
05628561 1683 }
0f980a35 1684error:
41253107 1685 g_free(left);
05628561
MD
1686 break;
1687 }
1688 default:
1689 return -EPERM;
1690 /* TODO: declaration specifier should be added. */
1691 }
1692
0f980a35 1693 return ret;
05628561
MD
1694}
1695
1696static
1697int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1698 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1699{
1700 int ret = 0;
1701 struct ctf_node *iter;
1702 struct ctf_event *event;
1703
1704 event = g_new0(struct ctf_event, 1);
d20f5e59 1705 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
306eeaa6 1706 event->loglevel = -1;
05628561
MD
1707 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1708 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1709 if (ret)
1710 goto error;
1711 }
1712 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1713 ret = -EPERM;
427c09b7 1714 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
05628561
MD
1715 goto error;
1716 }
05628561 1717 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
0f980a35 1718 /* Allow missing stream_id if there is only a single stream */
33105c61
MD
1719 switch (trace->streams->len) {
1720 case 0: /* Create stream if there was none. */
1721 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1722 if (ret)
1723 goto error;
1724 /* Fall-through */
1725 case 1:
0f980a35
MD
1726 event->stream_id = 0;
1727 event->stream = trace_stream_lookup(trace, event->stream_id);
33105c61
MD
1728 break;
1729 default:
0f980a35
MD
1730 ret = -EPERM;
1731 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1732 goto error;
1733 }
05628561 1734 }
8c572eba
MD
1735 /* Allow only one event without id per stream */
1736 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1737 && event->stream->events_by_id->len != 0) {
1738 ret = -EPERM;
1739 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1740 goto error;
1741 }
05628561
MD
1742 if (event->stream->events_by_id->len <= event->id)
1743 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1744 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1745 g_hash_table_insert(event->stream->event_quark_to_id,
56e60373 1746 (gpointer) (unsigned long) event->name,
05628561
MD
1747 &event->id);
1748 return 0;
1749
1750error:
98df1c9f
MD
1751 if (event->fields_decl)
1752 declaration_unref(&event->fields_decl->p);
1753 if (event->context_decl)
1754 declaration_unref(&event->context_decl->p);
d20f5e59 1755 free_declaration_scope(event->declaration_scope);
05628561
MD
1756 g_free(event);
1757 return ret;
1758}
1759
1760
1761static
aa6bffae 1762int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_class *stream, struct ctf_trace *trace)
05628561
MD
1763{
1764 int ret = 0;
1765
1766 switch (node->type) {
1767 case NODE_TYPEDEF:
1768 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1769 stream->declaration_scope,
78af2bcd 1770 node->u._typedef.type_specifier_list,
05628561 1771 &node->u._typedef.type_declarators,
a0720417 1772 trace);
05628561
MD
1773 if (ret)
1774 return ret;
1775 break;
1776 case NODE_TYPEALIAS:
1777 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1778 stream->declaration_scope,
1779 node->u.typealias.target, node->u.typealias.alias,
1780 trace);
05628561
MD
1781 if (ret)
1782 return ret;
1783 break;
1784 case NODE_CTF_EXPRESSION:
1785 {
1786 char *left;
1787
1788 left = concatenate_unary_strings(&node->u.ctf_expression.left);
427c09b7
MD
1789 if (!strcmp(left, "id")) {
1790 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1791 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
0f980a35
MD
1792 ret = -EPERM;
1793 goto error;
427c09b7 1794 }
a0720417 1795 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
05628561 1796 if (ret) {
427c09b7 1797 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
0f980a35
MD
1798 ret = -EINVAL;
1799 goto error;
05628561 1800 }
a0720417 1801 CTF_STREAM_SET_FIELD(stream, stream_id);
9e29e16e 1802 } else if (!strcmp(left, "event.header")) {
05628561
MD
1803 struct declaration *declaration;
1804
427c09b7
MD
1805 if (stream->event_header_decl) {
1806 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
0f980a35
MD
1807 ret = -EINVAL;
1808 goto error;
427c09b7 1809 }
78af2bcd
MD
1810 declaration = ctf_type_specifier_list_visit(fd, depth,
1811 _cds_list_first_entry(&node->u.ctf_expression.right,
1812 struct ctf_node, siblings),
a0720417 1813 stream->declaration_scope, trace);
0f980a35
MD
1814 if (!declaration) {
1815 ret = -EPERM;
1816 goto error;
1817 }
1818 if (declaration->id != CTF_TYPE_STRUCT) {
1819 ret = -EPERM;
1820 goto error;
1821 }
9e29e16e
MD
1822 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1823 } else if (!strcmp(left, "event.context")) {
05628561
MD
1824 struct declaration *declaration;
1825
427c09b7
MD
1826 if (stream->event_context_decl) {
1827 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
0f980a35
MD
1828 ret = -EINVAL;
1829 goto error;
427c09b7 1830 }
78af2bcd
MD
1831 declaration = ctf_type_specifier_list_visit(fd, depth,
1832 _cds_list_first_entry(&node->u.ctf_expression.right,
1833 struct ctf_node, siblings),
ab4cf058 1834 stream->declaration_scope, trace);
0f980a35
MD
1835 if (!declaration) {
1836 ret = -EPERM;
1837 goto error;
1838 }
1839 if (declaration->id != CTF_TYPE_STRUCT) {
1840 ret = -EPERM;
1841 goto error;
1842 }
9e29e16e
MD
1843 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1844 } else if (!strcmp(left, "packet.context")) {
05628561
MD
1845 struct declaration *declaration;
1846
427c09b7
MD
1847 if (stream->packet_context_decl) {
1848 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
0f980a35
MD
1849 ret = -EINVAL;
1850 goto error;
427c09b7 1851 }
78af2bcd
MD
1852 declaration = ctf_type_specifier_list_visit(fd, depth,
1853 _cds_list_first_entry(&node->u.ctf_expression.right,
1854 struct ctf_node, siblings),
ab4cf058 1855 stream->declaration_scope, trace);
0f980a35
MD
1856 if (!declaration) {
1857 ret = -EPERM;
1858 goto error;
1859 }
1860 if (declaration->id != CTF_TYPE_STRUCT) {
1861 ret = -EPERM;
1862 goto error;
1863 }
9e29e16e 1864 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
98df1c9f 1865 } else {
b3ab6665
MD
1866 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
1867 /* Fall-through after warning */
05628561 1868 }
98df1c9f 1869
0f980a35 1870error:
41253107 1871 g_free(left);
05628561
MD
1872 break;
1873 }
1874 default:
1875 return -EPERM;
1876 /* TODO: declaration specifier should be added. */
1877 }
1878
0f980a35 1879 return ret;
05628561
MD
1880}
1881
1882static
1883int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1884 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1885{
1886 int ret = 0;
1887 struct ctf_node *iter;
aa6bffae 1888 struct ctf_stream_class *stream;
05628561 1889
aa6bffae 1890 stream = g_new0(struct ctf_stream_class, 1);
d20f5e59 1891 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561 1892 stream->events_by_id = g_ptr_array_new();
068665f5 1893 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
2d0bea29 1894 stream->streams = g_ptr_array_new();
33105c61
MD
1895 if (node) {
1896 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1897 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1898 if (ret)
1899 goto error;
1900 }
05628561 1901 }
0f980a35
MD
1902 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1903 /* check that packet header has stream_id field. */
1904 if (!trace->packet_header_decl
1905 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
1906 ret = -EPERM;
1907 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
1908 goto error;
1909 }
8c572eba
MD
1910 } else {
1911 /* Allow only one id-less stream */
1912 if (trace->streams->len != 0) {
1913 ret = -EPERM;
1914 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
1915 goto error;
1916 }
1917 stream->stream_id = 0;
05628561
MD
1918 }
1919 if (trace->streams->len <= stream->stream_id)
1920 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1921 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
82662ad4 1922 stream->trace = trace;
9e29e16e 1923
05628561
MD
1924 return 0;
1925
1926error:
98df1c9f
MD
1927 if (stream->event_header_decl)
1928 declaration_unref(&stream->event_header_decl->p);
1929 if (stream->event_context_decl)
1930 declaration_unref(&stream->event_context_decl->p);
1931 if (stream->packet_context_decl)
1932 declaration_unref(&stream->packet_context_decl->p);
2d0bea29 1933 g_ptr_array_free(stream->streams, TRUE);
05628561 1934 g_ptr_array_free(stream->events_by_id, TRUE);
a0720417 1935 g_hash_table_destroy(stream->event_quark_to_id);
d20f5e59 1936 free_declaration_scope(stream->declaration_scope);
05628561
MD
1937 g_free(stream);
1938 return ret;
1939}
1940
1941static
1942int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1943{
1944 int ret = 0;
1945
1946 switch (node->type) {
1947 case NODE_TYPEDEF:
1948 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1949 trace->declaration_scope,
78af2bcd 1950 node->u._typedef.type_specifier_list,
05628561 1951 &node->u._typedef.type_declarators,
a0720417 1952 trace);
05628561
MD
1953 if (ret)
1954 return ret;
1955 break;
1956 case NODE_TYPEALIAS:
1957 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1958 trace->declaration_scope,
1959 node->u.typealias.target, node->u.typealias.alias,
1960 trace);
05628561
MD
1961 if (ret)
1962 return ret;
1963 break;
1964 case NODE_CTF_EXPRESSION:
1965 {
1966 char *left;
1967
1968 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1969 if (!strcmp(left, "major")) {
427c09b7
MD
1970 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
1971 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
0f980a35
MD
1972 ret = -EPERM;
1973 goto error;
427c09b7 1974 }
05628561
MD
1975 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1976 if (ret) {
78af2bcd 1977 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
0f980a35
MD
1978 ret = -EINVAL;
1979 goto error;
05628561 1980 }
a0720417 1981 CTF_TRACE_SET_FIELD(trace, major);
05628561 1982 } else if (!strcmp(left, "minor")) {
427c09b7
MD
1983 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1984 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
0f980a35
MD
1985 ret = -EPERM;
1986 goto error;
427c09b7 1987 }
05628561
MD
1988 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1989 if (ret) {
78af2bcd 1990 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
0f980a35
MD
1991 ret = -EINVAL;
1992 goto error;
05628561 1993 }
a0720417 1994 CTF_TRACE_SET_FIELD(trace, minor);
05628561 1995 } else if (!strcmp(left, "uuid")) {
b4c19c1e 1996 uuid_t uuid;
a0fe7d97
MD
1997
1998 ret = get_unary_uuid(&node->u.ctf_expression.right, &uuid);
05628561 1999 if (ret) {
78af2bcd 2000 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
0f980a35
MD
2001 ret = -EINVAL;
2002 goto error;
05628561 2003 }
b4c19c1e
MD
2004 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
2005 && uuid_compare(uuid, trace->uuid)) {
2006 fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
2007 ret = -EPERM;
2008 goto error;
a0fe7d97
MD
2009 } else {
2010 memcpy(trace->uuid, uuid, sizeof(uuid));
b4c19c1e 2011 }
a0720417 2012 CTF_TRACE_SET_FIELD(trace, uuid);
0f980a35
MD
2013 } else if (!strcmp(left, "byte_order")) {
2014 struct ctf_node *right;
2015 int byte_order;
2016
0f980a35
MD
2017 right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2018 byte_order = get_trace_byte_order(fd, depth, right);
2019 if (byte_order < 0)
2020 return -EINVAL;
a0fe7d97
MD
2021
2022 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
2023 && byte_order != trace->byte_order) {
2024 fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
2025 ret = -EPERM;
2026 goto error;
2027 } else {
fdce39de
MD
2028 if (byte_order != trace->byte_order) {
2029 trace->byte_order = byte_order;
2030 /*
2031 * We need to restart
2032 * construction of the
2033 * intermediate representation.
2034 */
2e0c6b58
MD
2035 trace->field_mask = 0;
2036 CTF_TRACE_SET_FIELD(trace, byte_order);
2037 ret = -EINTR;
2038 goto error;
fdce39de 2039 }
a0fe7d97 2040 }
7c8a1386 2041 CTF_TRACE_SET_FIELD(trace, byte_order);
0f980a35
MD
2042 } else if (!strcmp(left, "packet.header")) {
2043 struct declaration *declaration;
2044
2045 if (trace->packet_header_decl) {
2046 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
2047 ret = -EINVAL;
2048 goto error;
2049 }
2050 declaration = ctf_type_specifier_list_visit(fd, depth,
2051 _cds_list_first_entry(&node->u.ctf_expression.right,
2052 struct ctf_node, siblings),
2053 trace->declaration_scope, trace);
2054 if (!declaration) {
2055 ret = -EPERM;
2056 goto error;
2057 }
2058 if (declaration->id != CTF_TYPE_STRUCT) {
2059 ret = -EPERM;
2060 goto error;
2061 }
2062 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
98df1c9f 2063 } else {
b3ab6665 2064 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
05628561 2065 }
98df1c9f 2066
0f980a35 2067error:
41253107 2068 g_free(left);
05628561
MD
2069 break;
2070 }
2071 default:
2072 return -EPERM;
2073 /* TODO: declaration specifier should be added. */
2074 }
2075
0f980a35 2076 return ret;
05628561
MD
2077}
2078
05628561
MD
2079static
2080int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2081{
2082 int ret = 0;
2083 struct ctf_node *iter;
2084
d20f5e59 2085 if (trace->declaration_scope)
05628561 2086 return -EEXIST;
d20f5e59 2087 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
05628561
MD
2088 trace->streams = g_ptr_array_new();
2089 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
2090 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
2091 if (ret)
2092 goto error;
2093 }
a0720417 2094 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
05628561 2095 ret = -EPERM;
427c09b7 2096 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
05628561
MD
2097 goto error;
2098 }
a0720417 2099 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
05628561 2100 ret = -EPERM;
427c09b7 2101 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
05628561
MD
2102 goto error;
2103 }
a0720417 2104 if (!CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
05628561 2105 ret = -EPERM;
427c09b7 2106 fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
05628561
MD
2107 goto error;
2108 }
dc48ecad
MD
2109 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2110 ret = -EPERM;
2111 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
2112 goto error;
2113 }
0f980a35 2114
0f980a35
MD
2115 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2116 /* check that the packet header contains a "magic" field */
e28d4618 2117 if (!trace->packet_header_decl
0f980a35
MD
2118 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
2119 ret = -EPERM;
2120 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
98df1c9f 2121 goto error;
0f980a35
MD
2122 }
2123 }
05628561
MD
2124 return 0;
2125
2126error:
0d72513f 2127 if (trace->packet_header_decl) {
98df1c9f 2128 declaration_unref(&trace->packet_header_decl->p);
0d72513f
MD
2129 trace->packet_header_decl = NULL;
2130 }
05628561 2131 g_ptr_array_free(trace->streams, TRUE);
a0720417 2132 free_declaration_scope(trace->declaration_scope);
fdce39de 2133 trace->declaration_scope = NULL;
05628561
MD
2134 return ret;
2135}
2136
50cb9c56
MD
2137static
2138int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2139 struct ctf_clock *clock, struct ctf_trace *trace)
2140{
2141 int ret = 0;
2142
2143 switch (node->type) {
2144 case NODE_CTF_EXPRESSION:
2145 {
2146 char *left;
2147
2148 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2149 if (!strcmp(left, "name")) {
2150 char *right;
2151
2152 if (CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2153 fprintf(fd, "[error] %s: name already declared in clock declaration\n", __func__);
2154 ret = -EPERM;
2155 goto error;
2156 }
2157 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2158 if (!right) {
2159 fprintf(fd, "[error] %s: unexpected unary expression for clock name\n", __func__);
2160 ret = -EINVAL;
2161 goto error;
2162 }
2163 clock->name = g_quark_from_string(right);
2164 g_free(right);
bf94ab2b 2165 CTF_CLOCK_SET_FIELD(clock, name);
50cb9c56
MD
2166 } else if (!strcmp(left, "uuid")) {
2167 char *right;
2168
2169 if (clock->uuid) {
2170 fprintf(fd, "[error] %s: uuid already declared in clock declaration\n", __func__);
2171 ret = -EPERM;
2172 goto error;
2173 }
2174 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2175 if (!right) {
2176 fprintf(fd, "[error] %s: unexpected unary expression for clock uuid\n", __func__);
2177 ret = -EINVAL;
2178 goto error;
2179 }
2180 clock->uuid = g_quark_from_string(right);
2181 g_free(right);
2182 } else if (!strcmp(left, "description")) {
2183 char *right;
2184
2185 if (clock->description) {
2186 fprintf(fd, "[warning] %s: duplicated clock description\n", __func__);
2187 goto error; /* ret is 0, so not an actual error, just warn. */
2188 }
2189 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2190 if (!right) {
2191 fprintf(fd, "[warning] %s: unexpected unary expression for clock description\n", __func__);
2192 goto error; /* ret is 0, so not an actual error, just warn. */
2193 }
2194 clock->description = right;
2195 } else if (!strcmp(left, "freq")) {
bf94ab2b 2196 if (CTF_CLOCK_FIELD_IS_SET(clock, freq)) {
50cb9c56
MD
2197 fprintf(fd, "[error] %s: freq already declared in clock declaration\n", __func__);
2198 ret = -EPERM;
2199 goto error;
2200 }
2201 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->freq);
2202 if (ret) {
2203 fprintf(fd, "[error] %s: unexpected unary expression for clock freq\n", __func__);
2204 ret = -EINVAL;
2205 goto error;
2206 }
bf94ab2b 2207 CTF_CLOCK_SET_FIELD(clock, freq);
50cb9c56
MD
2208 } else if (!strcmp(left, "precision")) {
2209 if (clock->precision) {
2210 fprintf(fd, "[error] %s: precision already declared in clock declaration\n", __func__);
2211 ret = -EPERM;
2212 goto error;
2213 }
2214 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->precision);
2215 if (ret) {
2216 fprintf(fd, "[error] %s: unexpected unary expression for clock precision\n", __func__);
2217 ret = -EINVAL;
2218 goto error;
2219 }
2220 } else if (!strcmp(left, "offset_s")) {
2221 if (clock->offset_s) {
2222 fprintf(fd, "[error] %s: offset_s already declared in clock declaration\n", __func__);
2223 ret = -EPERM;
2224 goto error;
2225 }
2226 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset_s);
2227 if (ret) {
2228 fprintf(fd, "[error] %s: unexpected unary expression for clock offset_s\n", __func__);
2229 ret = -EINVAL;
2230 goto error;
2231 }
2232 } else if (!strcmp(left, "offset")) {
2233 if (clock->offset) {
2234 fprintf(fd, "[error] %s: offset already declared in clock declaration\n", __func__);
2235 ret = -EPERM;
2236 goto error;
2237 }
2238 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset);
2239 if (ret) {
2240 fprintf(fd, "[error] %s: unexpected unary expression for clock offset\n", __func__);
2241 ret = -EINVAL;
2242 goto error;
2243 }
11ac6674
MD
2244 } else if (!strcmp(left, "absolute")) {
2245 struct ctf_node *right;
2246
2247 right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2248 ret = get_boolean(fd, depth, right);
2249 if (ret < 0) {
2250 fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__);
2251 ret = -EINVAL;
2252 goto error;
2253 }
2254 clock->absolute = ret;
50cb9c56
MD
2255 } else {
2256 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left);
2257 }
2258
2259error:
2260 g_free(left);
2261 break;
2262 }
2263 default:
2264 return -EPERM;
2265 /* TODO: declaration specifier should be added. */
2266 }
2267
2268 return ret;
2269}
2270
2271static
2272int ctf_clock_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2273{
2274 int ret = 0;
2275 struct ctf_node *iter;
2276 struct ctf_clock *clock;
2277
2278 clock = g_new0(struct ctf_clock, 1);
25ccc85b
MD
2279 /* Default clock frequency is set to 1000000000 */
2280 clock->freq = 1000000000ULL;
50cb9c56
MD
2281 cds_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
2282 ret = ctf_clock_declaration_visit(fd, depth + 1, iter, clock, trace);
2283 if (ret)
2284 goto error;
2285 }
82ace6d6
MD
2286 if (opt_clock_force_correlate) {
2287 /*
2288 * User requested to forcibly correlate the clock
2289 * sources, even if we have no correlatation
2290 * information.
2291 */
2292 if (!clock->absolute) {
2293 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2294 }
2295 clock->absolute = 1;
2296 }
50cb9c56
MD
2297 if (!CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2298 ret = -EPERM;
2299 fprintf(fd, "[error] %s: missing namefield in clock declaration\n", __func__);
2300 goto error;
2301 }
25ccc85b 2302 if (g_hash_table_size(trace->clocks) > 0) {
82ace6d6 2303 fprintf(fd, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
25ccc85b
MD
2304 ret = -EINVAL;
2305 goto error;
2306 }
2307 trace->single_clock = clock;
50cb9c56
MD
2308 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2309 return 0;
2310
2311error:
2312 g_free(clock->description);
2313 g_free(clock);
2314 return ret;
2315}
2316
f57447bd
JN
2317static
2318void ctf_clock_default(FILE *fd, int depth, struct ctf_trace *trace)
2319{
2320 struct ctf_clock *clock;
2321
2322 clock = g_new0(struct ctf_clock, 1);
2323 clock->name = g_quark_from_string("monotonic");
2324 clock->uuid = 0;
2325 clock->description = g_strdup("Default clock");
2326 /* Default clock frequency is set to 1000000000 */
2327 clock->freq = 1000000000ULL;
82ace6d6
MD
2328 if (opt_clock_force_correlate) {
2329 /*
2330 * User requested to forcibly correlate the clock
2331 * sources, even if we have no correlatation
2332 * information.
2333 */
2334 if (!clock->absolute) {
2335 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2336 }
2337 clock->absolute = 1;
2338 } else {
2339 clock->absolute = 0; /* Not an absolute reference across traces */
2340 }
f57447bd
JN
2341
2342 trace->single_clock = clock;
2343 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2344}
2345
50cb9c56
MD
2346static
2347void clock_free(gpointer data)
2348{
2349 struct ctf_clock *clock = data;
2350
2351 g_free(clock->description);
2352 g_free(clock);
2353}
2354
cadd09e9
MD
2355static
2356int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2357 struct ctf_trace *trace)
2358{
2359 int ret = 0;
2360 struct ctf_tracer_env *env = &trace->env;
2361
2362 switch (node->type) {
2363 case NODE_CTF_EXPRESSION:
2364 {
2365 char *left;
2366
2367 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2368 if (!strcmp(left, "vpid")) {
2369 uint64_t v;
2370
2371 if (env->vpid != -1) {
2372 fprintf(fd, "[error] %s: vpid already declared in env declaration\n", __func__);
2373 goto error; /* ret is 0, so not an actual error, just warn. */
2374 }
2375 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2376 if (ret) {
2377 fprintf(fd, "[error] %s: unexpected unary expression for env vpid\n", __func__);
2378 goto error; /* ret is 0, so not an actual error, just warn. */
2379 }
2380 env->vpid = (int) v;
6070d2f1 2381 printf_verbose("env.vpid = %d\n", env->vpid);
cadd09e9
MD
2382 } else if (!strcmp(left, "procname")) {
2383 char *right;
2384
2385 if (env->procname[0]) {
2386 fprintf(fd, "[warning] %s: duplicated env procname\n", __func__);
2387 goto error; /* ret is 0, so not an actual error, just warn. */
2388 }
2389 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2390 if (!right) {
2391 fprintf(fd, "[warning] %s: unexpected unary expression for env procname\n", __func__);
2392 goto error; /* ret is 0, so not an actual error, just warn. */
2393 }
2394 strncpy(env->procname, right, TRACER_ENV_LEN);
2395 env->procname[TRACER_ENV_LEN - 1] = '\0';
6070d2f1 2396 printf_verbose("env.procname = %s\n", env->procname);
cadd09e9
MD
2397 } else if (!strcmp(left, "domain")) {
2398 char *right;
2399
2400 if (env->domain[0]) {
2401 fprintf(fd, "[warning] %s: duplicated env domain\n", __func__);
2402 goto error; /* ret is 0, so not an actual error, just warn. */
2403 }
2404 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2405 if (!right) {
2406 fprintf(fd, "[warning] %s: unexpected unary expression for env domain\n", __func__);
2407 goto error; /* ret is 0, so not an actual error, just warn. */
2408 }
2409 strncpy(env->domain, right, TRACER_ENV_LEN);
2410 env->domain[TRACER_ENV_LEN - 1] = '\0';
6070d2f1 2411 printf_verbose("env.domain = %s\n", env->domain);
cadd09e9
MD
2412 } else if (!strcmp(left, "sysname")) {
2413 char *right;
2414
2415 if (env->sysname[0]) {
2416 fprintf(fd, "[warning] %s: duplicated env sysname\n", __func__);
2417 goto error; /* ret is 0, so not an actual error, just warn. */
2418 }
2419 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2420 if (!right) {
2421 fprintf(fd, "[warning] %s: unexpected unary expression for env sysname\n", __func__);
2422 goto error; /* ret is 0, so not an actual error, just warn. */
2423 }
2424 strncpy(env->sysname, right, TRACER_ENV_LEN);
2425 env->sysname[TRACER_ENV_LEN - 1] = '\0';
6070d2f1 2426 printf_verbose("env.sysname = %s\n", env->sysname);
cadd09e9
MD
2427 } else if (!strcmp(left, "release")) {
2428 char *right;
2429
2430 if (env->release[0]) {
2431 fprintf(fd, "[warning] %s: duplicated env release\n", __func__);
2432 goto error; /* ret is 0, so not an actual error, just warn. */
2433 }
2434 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2435 if (!right) {
2436 fprintf(fd, "[warning] %s: unexpected unary expression for env release\n", __func__);
2437 goto error; /* ret is 0, so not an actual error, just warn. */
2438 }
2439 strncpy(env->release, right, TRACER_ENV_LEN);
2440 env->release[TRACER_ENV_LEN - 1] = '\0';
6070d2f1 2441 printf_verbose("env.release = %s\n", env->release);
cadd09e9
MD
2442 } else if (!strcmp(left, "version")) {
2443 char *right;
2444
2445 if (env->version[0]) {
2446 fprintf(fd, "[warning] %s: duplicated env version\n", __func__);
2447 goto error; /* ret is 0, so not an actual error, just warn. */
2448 }
2449 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2450 if (!right) {
2451 fprintf(fd, "[warning] %s: unexpected unary expression for env version\n", __func__);
2452 goto error; /* ret is 0, so not an actual error, just warn. */
2453 }
2454 strncpy(env->version, right, TRACER_ENV_LEN);
2455 env->version[TRACER_ENV_LEN - 1] = '\0';
6070d2f1 2456 printf_verbose("env.version = %s\n", env->version);
cadd09e9
MD
2457 } else {
2458 printf_verbose("%s: attribute \"%s\" is unknown in environment declaration.\n", __func__, left);
2459 }
2460
2461error:
2462 g_free(left);
2463 break;
2464 }
2465 default:
2466 return -EPERM;
2467 }
2468
2469 return ret;
2470}
2471
e2c76a4d
MD
2472static
2473int ctf_env_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2474{
cadd09e9
MD
2475 int ret = 0;
2476 struct ctf_node *iter;
2477
2478 trace->env.vpid = -1;
2479 trace->env.procname[0] = '\0';
2480 trace->env.domain[0] = '\0';
2481 trace->env.sysname[0] = '\0';
2482 trace->env.release[0] = '\0';
2483 trace->env.version[0] = '\0';
2484 cds_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
2485 ret = ctf_env_declaration_visit(fd, depth + 1, iter, trace);
2486 if (ret)
2487 goto error;
2488 }
2489error:
2490 return 0;
e2c76a4d
MD
2491}
2492
78af2bcd
MD
2493static
2494int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2495{
2496 int ret = 0;
2497
2498 switch (node->type) {
2499 case NODE_TYPEDEF:
2500 ret = ctf_typedef_visit(fd, depth + 1,
2501 trace->root_declaration_scope,
2502 node->u._typedef.type_specifier_list,
2503 &node->u._typedef.type_declarators,
2504 trace);
2505 if (ret)
2506 return ret;
2507 break;
2508 case NODE_TYPEALIAS:
2509 ret = ctf_typealias_visit(fd, depth + 1,
2510 trace->root_declaration_scope,
2511 node->u.typealias.target, node->u.typealias.alias,
2512 trace);
2513 if (ret)
2514 return ret;
2515 break;
2516 case NODE_TYPE_SPECIFIER_LIST:
2517 {
2518 struct declaration *declaration;
2519
2520 /*
2521 * Just add the type specifier to the root scope
2522 * declaration scope. Release local reference.
2523 */
2524 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2525 node, trace->root_declaration_scope, trace);
2526 if (!declaration)
2527 return -ENOMEM;
2528 declaration_unref(declaration);
2529 break;
2530 }
2531 default:
2532 return -EPERM;
2533 }
2534
2535 return 0;
2536}
2537
50cb9c56 2538/* TODO: missing metadata "destroy" (memory leak) */
ab4cf058
MD
2539int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2540 struct ctf_trace *trace, int byte_order)
05628561
MD
2541{
2542 int ret = 0;
2543 struct ctf_node *iter;
e2c76a4d 2544 int env_clock_done = 0;
05628561 2545
c8b219a3 2546 printf_verbose("CTF visitor: metadata construction... ");
ab4cf058 2547 trace->byte_order = byte_order;
50cb9c56
MD
2548 trace->clocks = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2549 NULL, clock_free);
ab4cf058 2550
00f7c1a5
MD
2551retry:
2552 trace->root_declaration_scope = new_declaration_scope(NULL);
2553
05628561
MD
2554 switch (node->type) {
2555 case NODE_ROOT:
e2c76a4d 2556 if (!env_clock_done) {
56e60373
MD
2557 /*
2558 * declarations need to query clock hash table,
2559 * so clock need to be treated first.
2560 */
f57447bd
JN
2561 if (cds_list_empty(&node->u.root.clock)) {
2562 ctf_clock_default(fd, depth + 1, trace);
2563 } else {
2564 cds_list_for_each_entry(iter, &node->u.root.clock, siblings) {
2565 ret = ctf_clock_visit(fd, depth + 1, iter,
2566 trace);
2567 if (ret) {
2568 fprintf(fd, "[error] %s: clock declaration error\n", __func__);
2569 goto error;
2570 }
56e60373
MD
2571 }
2572 }
e2c76a4d 2573 env_clock_done = 1;
56e60373 2574 }
3e11b713 2575 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
05628561 2576 siblings) {
78af2bcd 2577 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
427c09b7
MD
2578 if (ret) {
2579 fprintf(fd, "[error] %s: root declaration error\n", __func__);
a0fe7d97 2580 goto error;
427c09b7 2581 }
05628561
MD
2582 }
2583 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
2584 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
00f7c1a5
MD
2585 if (ret == -EINTR) {
2586 free_declaration_scope(trace->root_declaration_scope);
2587 /*
2588 * Need to restart creation of type
2589 * definitions, aliases and
2590 * trace header declarations.
2591 */
2592 goto retry;
2593 }
427c09b7
MD
2594 if (ret) {
2595 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
a0fe7d97 2596 goto error;
427c09b7 2597 }
05628561 2598 }
5039b4cc
MD
2599 if (!trace->streams) {
2600 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
a0fe7d97
MD
2601 ret = -EINVAL;
2602 goto error;
5039b4cc 2603 }
cadd09e9
MD
2604 cds_list_for_each_entry(iter, &node->u.root.env, siblings) {
2605 ret = ctf_env_visit(fd, depth + 1, iter, trace);
2606 if (ret) {
2607 fprintf(fd, "[error] %s: env declaration error\n", __func__);
2608 goto error;
2609 }
2610 }
05628561
MD
2611 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
2612 ret = ctf_stream_visit(fd, depth + 1, iter,
41253107 2613 trace->root_declaration_scope, trace);
427c09b7
MD
2614 if (ret) {
2615 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
a0fe7d97 2616 goto error;
427c09b7 2617 }
05628561
MD
2618 }
2619 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
2620 ret = ctf_event_visit(fd, depth + 1, iter,
41253107 2621 trace->root_declaration_scope, trace);
427c09b7
MD
2622 if (ret) {
2623 fprintf(fd, "[error] %s: event declaration error\n", __func__);
a0fe7d97 2624 goto error;
427c09b7 2625 }
05628561
MD
2626 }
2627 break;
05628561
MD
2628 case NODE_UNKNOWN:
2629 default:
78af2bcd 2630 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
05628561 2631 (int) node->type);
a0fe7d97
MD
2632 ret = -EINVAL;
2633 goto error;
05628561 2634 }
c8b219a3 2635 printf_verbose("done.\n");
05628561 2636 return ret;
a0fe7d97
MD
2637
2638error:
2639 free_declaration_scope(trace->root_declaration_scope);
50cb9c56 2640 g_hash_table_destroy(trace->clocks);
a0fe7d97 2641 return ret;
05628561 2642}
This page took 0.16435 seconds and 4 git commands to generate.