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