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>
30 GQuark
prefix_quark(const char *prefix
, GQuark quark
)
35 str
= g_string_new(prefix
);
36 g_string_append(str
, g_quark_to_string(quark
));
37 nq
= g_quark_from_string(g_string_free(str
, FALSE
));
43 lookup_declaration_scope(GQuark declaration_name
,
44 struct declaration_scope
*scope
)
46 return g_hash_table_lookup(scope
->typedef_declarations
,
47 (gconstpointer
) (unsigned long) declaration_name
);
50 struct declaration
*lookup_declaration(GQuark declaration_name
,
51 struct declaration_scope
*scope
)
53 struct declaration
*declaration
;
56 declaration
= lookup_declaration_scope(declaration_name
,
60 scope
= scope
->parent_scope
;
65 int register_declaration(GQuark name
, struct declaration
*declaration
,
66 struct declaration_scope
*scope
)
71 /* Only lookup in local scope */
72 if (lookup_declaration_scope(name
, scope
))
75 g_hash_table_insert(scope
->typedef_declarations
,
76 (gpointer
) (unsigned long) name
,
78 declaration_ref(declaration
);
84 lookup_field_definition_scope(GQuark field_name
,
85 struct definition_scope
*scope
)
87 return g_hash_table_lookup(scope
->definitions
,
88 (gconstpointer
) (unsigned long) field_name
);
92 * Returns the index at which the paths differ.
93 * If the value returned equals len, it means the paths are identical
94 * from index 0 to len-1.
96 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
100 assert(len
<= a
->len
);
101 assert(len
<= b
->len
);
103 for (i
= 0; i
< len
; i
++) {
106 qa
= g_array_index(a
, GQuark
, i
);
107 qb
= g_array_index(b
, GQuark
, i
);
114 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
118 if (babeltrace_debug
) {
121 printf_debug("Is path \"");
122 for (i
= 0; i
< path
->len
; need_dot
= 1, i
++)
123 printf("%s%s", need_dot
? "." : "",
124 g_quark_to_string(g_array_index(path
, GQuark
, i
)));
126 printf("\" child of \"");
127 for (i
= 0; i
< maybe_parent
->len
; need_dot
= 1, i
++)
128 printf("%s%s", need_dot
? "." : "",
129 g_quark_to_string(g_array_index(maybe_parent
, GQuark
, i
)));
133 if (path
->len
<= maybe_parent
->len
) {
137 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
138 == maybe_parent
->len
)
143 if (babeltrace_debug
)
144 printf("%s\n", ret
? "Yes" : "No");
148 static struct definition_scope
*
149 get_definition_scope(struct definition
*definition
)
151 return definition
->scope
;
155 * OK, here is the fun. We want to lookup a field that is:
156 * - either in the same dynamic scope:
157 * - either in the current scope, but prior to the current field.
158 * - or in a parent scope (or parent of parent ...) still in a field
159 * prior to the current field position within the parents.
160 * - or in a different dynamic scope:
161 * - either in a upper dynamic scope (walk down a targeted scope from
162 * the dynamic scope root)
163 * - or in a lower dynamic scope (failure)
164 * The dynamic scope roots are linked together, so we can access the
165 * parent dynamic scope from the child dynamic scope by walking up to
167 * If we cannot find such a field that is prior to our current path, we
170 * cur_path: the path leading to the variant definition.
171 * lookup_path: the path leading to the enum we want to look for.
172 * scope: the definition scope containing the variant definition.
175 lookup_path_definition(GArray
*cur_path
,
177 struct definition_scope
*scope
)
179 struct definition
*definition
, *lookup_definition
;
183 /* Going up in the hierarchy. Check where we come from. */
184 assert(is_path_child_of(cur_path
, scope
->scope_path
));
185 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
188 * First, check if the target name is size one, present in
189 * our parent path, located prior to us.
191 if (lookup_path
->len
== 1) {
192 last
= g_array_index(lookup_path
, GQuark
, 0);
193 lookup_definition
= lookup_field_definition_scope(last
, scope
);
194 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
195 definition
= lookup_field_definition_scope(last
, scope
);
197 if (lookup_definition
&& lookup_definition
->index
< definition
->index
)
198 return lookup_definition
;
204 if (is_path_child_of(cur_path
, scope
->scope_path
) &&
205 cur_path
->len
- scope
->scope_path
->len
== 1) {
206 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
207 definition
= lookup_field_definition_scope(last
, scope
);
209 index
= definition
->index
;
212 * Getting to a dynamic scope parent. We are
213 * guaranteed that the parent is entirely
214 * located before the child.
219 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
220 /* Means we can lookup the field in this scope */
221 last
= g_array_index(lookup_path
, GQuark
,
222 scope
->scope_path
->len
);
223 lookup_definition
= lookup_field_definition_scope(last
, scope
);
224 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
226 /* Found it! And it is prior to the current field. */
227 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
229 return lookup_definition
;
231 scope
= get_definition_scope(lookup_definition
);
232 /* Check if the definition has a sub-scope */
236 * Don't compare index anymore, because we are
237 * going within a scope that has been validated
238 * to be entirely prior to the current scope.
245 /* lookup_path is within an upper scope */
246 cur_path
= scope
->scope_path
;
247 scope
= scope
->parent_scope
;
253 int register_field_definition(GQuark field_name
, struct definition
*definition
,
254 struct definition_scope
*scope
)
256 if (!scope
|| !field_name
)
259 /* Only lookup in local scope */
260 if (lookup_field_definition_scope(field_name
, scope
))
263 g_hash_table_insert(scope
->definitions
,
264 (gpointer
) (unsigned long) field_name
,
266 /* Don't keep reference on definition */
270 void declaration_ref(struct declaration
*declaration
)
275 void declaration_unref(struct declaration
*declaration
)
279 if (!--declaration
->ref
)
280 declaration
->declaration_free(declaration
);
283 void definition_ref(struct definition
*definition
)
288 void definition_unref(struct definition
*definition
)
292 if (!--definition
->ref
)
293 definition
->declaration
->definition_free(definition
);
296 struct declaration_scope
*
297 new_declaration_scope(struct declaration_scope
*parent_scope
)
299 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
301 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
302 g_direct_equal
, NULL
,
303 (GDestroyNotify
) declaration_unref
);
304 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
305 g_direct_equal
, NULL
,
306 (GDestroyNotify
) declaration_unref
);
307 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
308 g_direct_equal
, NULL
,
309 (GDestroyNotify
) declaration_unref
);
310 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
311 g_direct_equal
, NULL
,
312 (GDestroyNotify
) declaration_unref
);
313 scope
->parent_scope
= parent_scope
;
317 void free_declaration_scope(struct declaration_scope
*scope
)
319 g_hash_table_destroy(scope
->enum_declarations
);
320 g_hash_table_destroy(scope
->variant_declarations
);
321 g_hash_table_destroy(scope
->struct_declarations
);
322 g_hash_table_destroy(scope
->typedef_declarations
);
327 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
328 struct declaration_scope
*scope
)
330 return g_hash_table_lookup(scope
->struct_declarations
,
331 (gconstpointer
) (unsigned long) struct_name
);
334 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
335 struct declaration_scope
*scope
)
337 struct declaration_struct
*declaration
;
340 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
343 scope
= scope
->parent_scope
;
348 int register_struct_declaration(GQuark struct_name
,
349 struct declaration_struct
*struct_declaration
,
350 struct declaration_scope
*scope
)
358 /* Only lookup in local scope */
359 if (lookup_struct_declaration_scope(struct_name
, scope
))
362 g_hash_table_insert(scope
->struct_declarations
,
363 (gpointer
) (unsigned long) struct_name
,
365 declaration_ref(&struct_declaration
->p
);
367 /* Also add in typedef/typealias scopes */
368 prefix_name
= prefix_quark("struct ", struct_name
);
369 ret
= register_declaration(prefix_name
, &struct_declaration
->p
, scope
);
375 struct declaration_untagged_variant
*
376 lookup_variant_declaration_scope(GQuark variant_name
,
377 struct declaration_scope
*scope
)
379 return g_hash_table_lookup(scope
->variant_declarations
,
380 (gconstpointer
) (unsigned long) variant_name
);
383 struct declaration_untagged_variant
*
384 lookup_variant_declaration(GQuark variant_name
,
385 struct declaration_scope
*scope
)
387 struct declaration_untagged_variant
*declaration
;
390 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
393 scope
= scope
->parent_scope
;
398 int register_variant_declaration(GQuark variant_name
,
399 struct declaration_untagged_variant
*untagged_variant_declaration
,
400 struct declaration_scope
*scope
)
408 /* Only lookup in local scope */
409 if (lookup_variant_declaration_scope(variant_name
, scope
))
412 g_hash_table_insert(scope
->variant_declarations
,
413 (gpointer
) (unsigned long) variant_name
,
414 untagged_variant_declaration
);
415 declaration_ref(&untagged_variant_declaration
->p
);
417 /* Also add in typedef/typealias scopes */
418 prefix_name
= prefix_quark("variant ", variant_name
);
419 ret
= register_declaration(prefix_name
,
420 &untagged_variant_declaration
->p
, scope
);
426 struct declaration_enum
*
427 lookup_enum_declaration_scope(GQuark enum_name
,
428 struct declaration_scope
*scope
)
430 return g_hash_table_lookup(scope
->enum_declarations
,
431 (gconstpointer
) (unsigned long) enum_name
);
434 struct declaration_enum
*
435 lookup_enum_declaration(GQuark enum_name
,
436 struct declaration_scope
*scope
)
438 struct declaration_enum
*declaration
;
441 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
444 scope
= scope
->parent_scope
;
449 int register_enum_declaration(GQuark enum_name
,
450 struct declaration_enum
*enum_declaration
,
451 struct declaration_scope
*scope
)
459 /* Only lookup in local scope */
460 if (lookup_enum_declaration_scope(enum_name
, scope
))
463 g_hash_table_insert(scope
->enum_declarations
,
464 (gpointer
) (unsigned long) enum_name
,
466 declaration_ref(&enum_declaration
->p
);
468 /* Also add in typedef/typealias scopes */
469 prefix_name
= prefix_quark("enum ", enum_name
);
470 ret
= register_declaration(prefix_name
, &enum_declaration
->p
, scope
);
475 static struct definition_scope
*
476 _new_definition_scope(struct definition_scope
*parent_scope
,
479 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
481 scope
->definitions
= g_hash_table_new(g_direct_hash
,
483 scope
->parent_scope
= parent_scope
;
484 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
486 g_array_set_size(scope
->scope_path
, scope_path_len
);
490 GQuark
new_definition_path(struct definition_scope
*parent_scope
,
491 GQuark field_name
, const char *root_name
)
499 str
= g_string_new("");
501 g_string_append(str
, root_name
);
503 } else if (parent_scope
) {
504 for (i
= 0; i
< parent_scope
->scope_path
->len
; i
++) {
505 GQuark q
= g_array_index(parent_scope
->scope_path
,
510 g_string_append(str
, ".");
511 g_string_append(str
, g_quark_to_string(q
));
517 g_string_append(str
, ".");
518 g_string_append(str
, g_quark_to_string(field_name
));
520 c_str
= g_string_free(str
, FALSE
);
521 if (c_str
[0] == '\0')
523 path
= g_quark_from_string(c_str
);
524 printf_debug("new definition path: %s\n", c_str
);
529 struct definition_scope
*
530 new_definition_scope(struct definition_scope
*parent_scope
,
531 GQuark field_name
, const char *root_name
)
533 struct definition_scope
*scope
;
536 scope
= _new_definition_scope(parent_scope
, 0);
537 append_scope_path(root_name
, scope
->scope_path
);
539 int scope_path_len
= 1;
541 assert(parent_scope
);
542 scope_path_len
+= parent_scope
->scope_path
->len
;
543 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
544 memcpy(scope
->scope_path
->data
, parent_scope
->scope_path
->data
,
545 sizeof(GQuark
) * (scope_path_len
- 1));
546 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
549 if (babeltrace_debug
) {
552 printf_debug("new definition scope: ");
553 for (i
= 0; i
< scope
->scope_path
->len
; need_dot
= 1, i
++)
554 printf("%s%s", need_dot
? "." : "",
555 g_quark_to_string(g_array_index(scope
->scope_path
, GQuark
, i
)));
562 * in: path (dot separated), out: q (GArray of GQuark)
564 void append_scope_path(const char *path
, GArray
*q
)
566 const char *ptrbegin
, *ptrend
= path
;
574 ptrend
= strchr(ptrbegin
, '.');
577 len
= ptrend
- ptrbegin
;
578 /* Don't accept two consecutive dots */
580 str
= g_new(char, len
+ 1); /* include \0 */
581 memcpy(str
, ptrbegin
, len
);
583 quark
= g_quark_from_string(str
);
584 g_array_append_val(q
, quark
);
586 ptrend
++; /* skip current dot */
588 /* last. Check for trailing dot (and discard). */
589 if (ptrbegin
[0] != '\0') {
590 quark
= g_quark_from_string(ptrbegin
);
591 g_array_append_val(q
, quark
);
595 void free_definition_scope(struct definition_scope
*scope
)
597 g_array_free(scope
->scope_path
, TRUE
);
598 g_hash_table_destroy(scope
->definitions
);
602 struct definition
*lookup_definition(struct definition
*definition
,
603 const char *field_name
)
605 struct definition_scope
*scope
= get_definition_scope(definition
);
610 return lookup_field_definition_scope(g_quark_from_string(field_name
),
614 struct definition_integer
*lookup_integer(struct definition
*definition
,
615 const char *field_name
,
618 struct definition
*lookup
;
619 struct definition_integer
*lookup_integer
;
621 lookup
= lookup_definition(definition
, field_name
);
624 if (lookup
->declaration
->id
!= CTF_TYPE_INTEGER
)
626 lookup_integer
= container_of(lookup
, struct definition_integer
, p
);
627 if (lookup_integer
->declaration
->signedness
!= signedness
)
629 return lookup_integer
;
632 struct definition_enum
*lookup_enum(struct definition
*definition
,
633 const char *field_name
,
636 struct definition
*lookup
;
637 struct definition_enum
*lookup_enum
;
639 lookup
= lookup_definition(definition
, field_name
);
642 if (lookup
->declaration
->id
!= CTF_TYPE_ENUM
)
644 lookup_enum
= container_of(lookup
, struct definition_enum
, p
);
645 if (lookup_enum
->integer
->declaration
->signedness
!= signedness
)
650 struct definition
*lookup_variant(struct definition
*definition
,
651 const char *field_name
)
653 struct definition
*lookup
;
654 struct definition_variant
*lookup_variant
;
656 lookup
= lookup_definition(definition
, field_name
);
659 if (lookup
->declaration
->id
!= CTF_TYPE_VARIANT
)
661 lookup_variant
= container_of(lookup
, struct definition_variant
, p
);
662 lookup
= variant_get_current_field(lookup_variant
);