4 * BabelTrace - Converter
8 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
10 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this software and associated documentation files (the "Software"), to deal
14 * in the Software without restriction, including without limitation the rights
15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the Software is
17 * furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
23 #include <babeltrace/format.h>
24 #include <babeltrace/babeltrace-internal.h>
25 #include <babeltrace/types.h>
31 GQuark
prefix_quark(const char *prefix
, GQuark quark
)
36 str
= g_string_new(prefix
);
37 g_string_append(str
, g_quark_to_string(quark
));
38 nq
= g_quark_from_string(g_string_free(str
, FALSE
));
44 lookup_declaration_scope(GQuark declaration_name
,
45 struct declaration_scope
*scope
)
47 return g_hash_table_lookup(scope
->typedef_declarations
,
48 (gconstpointer
) (unsigned long) declaration_name
);
51 struct declaration
*lookup_declaration(GQuark declaration_name
,
52 struct declaration_scope
*scope
)
54 struct declaration
*declaration
;
57 declaration
= lookup_declaration_scope(declaration_name
,
61 scope
= scope
->parent_scope
;
66 int register_declaration(GQuark name
, struct declaration
*declaration
,
67 struct declaration_scope
*scope
)
72 /* Only lookup in local scope */
73 if (lookup_declaration_scope(name
, scope
))
76 g_hash_table_insert(scope
->typedef_declarations
,
77 (gpointer
) (unsigned long) name
,
79 declaration_ref(declaration
);
85 lookup_field_definition_scope(GQuark field_name
,
86 struct definition_scope
*scope
)
88 return g_hash_table_lookup(scope
->definitions
,
89 (gconstpointer
) (unsigned long) field_name
);
93 * Returns the index at which the paths differ.
94 * If the value returned equals len, it means the paths are identical
95 * from index 0 to len-1.
97 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
101 assert(len
<= a
->len
);
102 assert(len
<= b
->len
);
104 for (i
= 0; i
< len
; i
++) {
107 qa
= g_array_index(a
, GQuark
, i
);
108 qb
= g_array_index(b
, GQuark
, i
);
115 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
119 if (babeltrace_debug
) {
122 printf_debug("Is path \"");
123 for (i
= 0; i
< path
->len
; need_dot
= 1, i
++)
124 printf("%s%s", need_dot
? "." : "",
125 g_quark_to_string(g_array_index(path
, GQuark
, i
)));
127 printf("\" child of \"");
128 for (i
= 0; i
< maybe_parent
->len
; need_dot
= 1, i
++)
129 printf("%s%s", need_dot
? "." : "",
130 g_quark_to_string(g_array_index(maybe_parent
, GQuark
, i
)));
134 if (path
->len
<= maybe_parent
->len
) {
138 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
139 == maybe_parent
->len
)
144 if (babeltrace_debug
)
145 printf("%s\n", ret
? "Yes" : "No");
149 static struct definition_scope
*
150 get_definition_scope(const struct definition
*definition
)
152 return definition
->scope
;
156 * OK, here is the fun. We want to lookup a field that is:
157 * - either in the same dynamic scope:
158 * - either in the current scope, but prior to the current field.
159 * - or in a parent scope (or parent of parent ...) still in a field
160 * prior to the current field position within the parents.
161 * - or in a different dynamic scope:
162 * - either in a upper dynamic scope (walk down a targeted scope from
163 * the dynamic scope root)
164 * - or in a lower dynamic scope (failure)
165 * The dynamic scope roots are linked together, so we can access the
166 * parent dynamic scope from the child dynamic scope by walking up to
168 * If we cannot find such a field that is prior to our current path, we
171 * cur_path: the path leading to the variant definition.
172 * lookup_path: the path leading to the enum we want to look for.
173 * scope: the definition scope containing the variant definition.
176 lookup_path_definition(GArray
*cur_path
,
178 struct definition_scope
*scope
)
180 struct definition
*definition
, *lookup_definition
;
184 /* Going up in the hierarchy. Check where we come from. */
185 assert(is_path_child_of(cur_path
, scope
->scope_path
));
186 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
189 * First, check if the target name is size one, present in
190 * our parent path, located prior to us.
192 if (lookup_path
->len
== 1) {
193 last
= g_array_index(lookup_path
, GQuark
, 0);
194 lookup_definition
= lookup_field_definition_scope(last
, scope
);
195 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
196 definition
= lookup_field_definition_scope(last
, scope
);
198 if (lookup_definition
&& lookup_definition
->index
< definition
->index
)
199 return lookup_definition
;
205 if (is_path_child_of(cur_path
, scope
->scope_path
) &&
206 cur_path
->len
- scope
->scope_path
->len
== 1) {
207 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
208 definition
= lookup_field_definition_scope(last
, scope
);
210 index
= definition
->index
;
213 * Getting to a dynamic scope parent. We are
214 * guaranteed that the parent is entirely
215 * located before the child.
220 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
221 /* Means we can lookup the field in this scope */
222 last
= g_array_index(lookup_path
, GQuark
,
223 scope
->scope_path
->len
);
224 lookup_definition
= lookup_field_definition_scope(last
, scope
);
225 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
227 /* Found it! And it is prior to the current field. */
228 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
230 return lookup_definition
;
232 scope
= get_definition_scope(lookup_definition
);
233 /* Check if the definition has a sub-scope */
237 * Don't compare index anymore, because we are
238 * going within a scope that has been validated
239 * to be entirely prior to the current scope.
246 /* lookup_path is within an upper scope */
247 cur_path
= scope
->scope_path
;
248 scope
= scope
->parent_scope
;
254 int register_field_definition(GQuark field_name
, struct definition
*definition
,
255 struct definition_scope
*scope
)
257 if (!scope
|| !field_name
)
260 /* Only lookup in local scope */
261 if (lookup_field_definition_scope(field_name
, scope
))
264 g_hash_table_insert(scope
->definitions
,
265 (gpointer
) (unsigned long) field_name
,
267 /* Don't keep reference on definition */
271 void declaration_ref(struct declaration
*declaration
)
276 void declaration_unref(struct declaration
*declaration
)
280 if (!--declaration
->ref
)
281 declaration
->declaration_free(declaration
);
284 void definition_ref(struct definition
*definition
)
289 void definition_unref(struct definition
*definition
)
293 if (!--definition
->ref
)
294 definition
->declaration
->definition_free(definition
);
297 struct declaration_scope
*
298 new_declaration_scope(struct declaration_scope
*parent_scope
)
300 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
302 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
303 g_direct_equal
, NULL
,
304 (GDestroyNotify
) declaration_unref
);
305 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
306 g_direct_equal
, NULL
,
307 (GDestroyNotify
) declaration_unref
);
308 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
309 g_direct_equal
, NULL
,
310 (GDestroyNotify
) declaration_unref
);
311 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
312 g_direct_equal
, NULL
,
313 (GDestroyNotify
) declaration_unref
);
314 scope
->parent_scope
= parent_scope
;
318 void free_declaration_scope(struct declaration_scope
*scope
)
320 g_hash_table_destroy(scope
->enum_declarations
);
321 g_hash_table_destroy(scope
->variant_declarations
);
322 g_hash_table_destroy(scope
->struct_declarations
);
323 g_hash_table_destroy(scope
->typedef_declarations
);
328 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
329 struct declaration_scope
*scope
)
331 return g_hash_table_lookup(scope
->struct_declarations
,
332 (gconstpointer
) (unsigned long) struct_name
);
335 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
336 struct declaration_scope
*scope
)
338 struct declaration_struct
*declaration
;
341 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
344 scope
= scope
->parent_scope
;
349 int register_struct_declaration(GQuark struct_name
,
350 struct declaration_struct
*struct_declaration
,
351 struct declaration_scope
*scope
)
359 /* Only lookup in local scope */
360 if (lookup_struct_declaration_scope(struct_name
, scope
))
363 g_hash_table_insert(scope
->struct_declarations
,
364 (gpointer
) (unsigned long) struct_name
,
366 declaration_ref(&struct_declaration
->p
);
368 /* Also add in typedef/typealias scopes */
369 prefix_name
= prefix_quark("struct ", struct_name
);
370 ret
= register_declaration(prefix_name
, &struct_declaration
->p
, scope
);
376 struct declaration_untagged_variant
*
377 lookup_variant_declaration_scope(GQuark variant_name
,
378 struct declaration_scope
*scope
)
380 return g_hash_table_lookup(scope
->variant_declarations
,
381 (gconstpointer
) (unsigned long) variant_name
);
384 struct declaration_untagged_variant
*
385 lookup_variant_declaration(GQuark variant_name
,
386 struct declaration_scope
*scope
)
388 struct declaration_untagged_variant
*declaration
;
391 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
394 scope
= scope
->parent_scope
;
399 int register_variant_declaration(GQuark variant_name
,
400 struct declaration_untagged_variant
*untagged_variant_declaration
,
401 struct declaration_scope
*scope
)
409 /* Only lookup in local scope */
410 if (lookup_variant_declaration_scope(variant_name
, scope
))
413 g_hash_table_insert(scope
->variant_declarations
,
414 (gpointer
) (unsigned long) variant_name
,
415 untagged_variant_declaration
);
416 declaration_ref(&untagged_variant_declaration
->p
);
418 /* Also add in typedef/typealias scopes */
419 prefix_name
= prefix_quark("variant ", variant_name
);
420 ret
= register_declaration(prefix_name
,
421 &untagged_variant_declaration
->p
, scope
);
427 struct declaration_enum
*
428 lookup_enum_declaration_scope(GQuark enum_name
,
429 struct declaration_scope
*scope
)
431 return g_hash_table_lookup(scope
->enum_declarations
,
432 (gconstpointer
) (unsigned long) enum_name
);
435 struct declaration_enum
*
436 lookup_enum_declaration(GQuark enum_name
,
437 struct declaration_scope
*scope
)
439 struct declaration_enum
*declaration
;
442 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
445 scope
= scope
->parent_scope
;
450 int register_enum_declaration(GQuark enum_name
,
451 struct declaration_enum
*enum_declaration
,
452 struct declaration_scope
*scope
)
460 /* Only lookup in local scope */
461 if (lookup_enum_declaration_scope(enum_name
, scope
))
464 g_hash_table_insert(scope
->enum_declarations
,
465 (gpointer
) (unsigned long) enum_name
,
467 declaration_ref(&enum_declaration
->p
);
469 /* Also add in typedef/typealias scopes */
470 prefix_name
= prefix_quark("enum ", enum_name
);
471 ret
= register_declaration(prefix_name
, &enum_declaration
->p
, scope
);
476 static struct definition_scope
*
477 _new_definition_scope(struct definition_scope
*parent_scope
,
480 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
482 scope
->definitions
= g_hash_table_new(g_direct_hash
,
484 scope
->parent_scope
= parent_scope
;
485 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
487 g_array_set_size(scope
->scope_path
, scope_path_len
);
491 GQuark
new_definition_path(struct definition_scope
*parent_scope
,
492 GQuark field_name
, const char *root_name
)
500 str
= g_string_new("");
502 g_string_append(str
, root_name
);
504 } else if (parent_scope
) {
505 for (i
= 0; i
< parent_scope
->scope_path
->len
; i
++) {
506 GQuark q
= g_array_index(parent_scope
->scope_path
,
511 g_string_append(str
, ".");
512 g_string_append(str
, g_quark_to_string(q
));
518 g_string_append(str
, ".");
519 g_string_append(str
, g_quark_to_string(field_name
));
521 c_str
= g_string_free(str
, FALSE
);
522 if (c_str
[0] == '\0')
524 path
= g_quark_from_string(c_str
);
525 printf_debug("new definition path: %s\n", c_str
);
530 struct definition_scope
*
531 new_definition_scope(struct definition_scope
*parent_scope
,
532 GQuark field_name
, const char *root_name
)
534 struct definition_scope
*scope
;
537 scope
= _new_definition_scope(parent_scope
, 0);
538 append_scope_path(root_name
, scope
->scope_path
);
540 int scope_path_len
= 1;
542 assert(parent_scope
);
543 scope_path_len
+= parent_scope
->scope_path
->len
;
544 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
545 memcpy(scope
->scope_path
->data
, parent_scope
->scope_path
->data
,
546 sizeof(GQuark
) * (scope_path_len
- 1));
547 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
550 if (babeltrace_debug
) {
553 printf_debug("new definition scope: ");
554 for (i
= 0; i
< scope
->scope_path
->len
; need_dot
= 1, i
++)
555 printf("%s%s", need_dot
? "." : "",
556 g_quark_to_string(g_array_index(scope
->scope_path
, GQuark
, i
)));
563 * in: path (dot separated), out: q (GArray of GQuark)
565 void append_scope_path(const char *path
, GArray
*q
)
567 const char *ptrbegin
, *ptrend
= path
;
575 ptrend
= strchr(ptrbegin
, '.');
578 len
= ptrend
- ptrbegin
;
579 /* Don't accept two consecutive dots */
581 str
= g_new(char, len
+ 1); /* include \0 */
582 memcpy(str
, ptrbegin
, len
);
584 quark
= g_quark_from_string(str
);
585 g_array_append_val(q
, quark
);
587 ptrend
++; /* skip current dot */
589 /* last. Check for trailing dot (and discard). */
590 if (ptrbegin
[0] != '\0') {
591 quark
= g_quark_from_string(ptrbegin
);
592 g_array_append_val(q
, quark
);
596 void free_definition_scope(struct definition_scope
*scope
)
598 g_array_free(scope
->scope_path
, TRUE
);
599 g_hash_table_destroy(scope
->definitions
);
603 struct definition
*lookup_definition(const struct definition
*definition
,
604 const char *field_name
)
606 struct definition_scope
*scope
= get_definition_scope(definition
);
611 return lookup_field_definition_scope(g_quark_from_string(field_name
),
615 struct definition_integer
*lookup_integer(const struct definition
*definition
,
616 const char *field_name
,
619 struct definition
*lookup
;
620 struct definition_integer
*lookup_integer
;
622 lookup
= lookup_definition(definition
, field_name
);
625 if (lookup
->declaration
->id
!= CTF_TYPE_INTEGER
)
627 lookup_integer
= container_of(lookup
, struct definition_integer
, p
);
628 if (lookup_integer
->declaration
->signedness
!= signedness
)
630 return lookup_integer
;
633 struct definition_enum
*lookup_enum(const struct definition
*definition
,
634 const char *field_name
,
637 struct definition
*lookup
;
638 struct definition_enum
*lookup_enum
;
640 lookup
= lookup_definition(definition
, field_name
);
643 if (lookup
->declaration
->id
!= CTF_TYPE_ENUM
)
645 lookup_enum
= container_of(lookup
, struct definition_enum
, p
);
646 if (lookup_enum
->integer
->declaration
->signedness
!= signedness
)
651 struct definition
*lookup_variant(const struct definition
*definition
,
652 const char *field_name
)
654 struct definition
*lookup
;
655 struct definition_variant
*lookup_variant
;
657 lookup
= lookup_definition(definition
, field_name
);
660 if (lookup
->declaration
->id
!= CTF_TYPE_VARIANT
)
662 lookup_variant
= container_of(lookup
, struct definition_variant
, p
);
663 lookup
= variant_get_current_field(lookup_variant
);