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