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