4 * BabelTrace - Converter
8 * Copyright 2010, 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
21 #include <babeltrace/format.h>
28 lookup_typedef_declaration_scope(GQuark declaration_name
,
29 struct declaration_scope
*scope
)
31 return g_hash_table_lookup(scope
->typedef_declarations
,
32 (gconstpointer
) (unsigned long) declaration_name
);
35 struct definition
*lookup_typedef_declaration(GQuark declaration_name
,
36 struct declaration_scope
*scope
)
38 struct definition
*definition
;
41 definition
= lookup_typedef_declaration_scope(declaration_name
,
45 scope
= scope
->parent_scope
;
50 int register_typedef_declaration(GQuark name
, struct declaration
*declaration
,
51 struct declaration_scope
*scope
)
56 /* Only lookup in local scope */
57 if (lookup_typedef_declaration_scope(name
, scope
))
60 g_hash_table_insert(scope
->typedef_declarations
,
61 (gpointer
) (unsigned long) name
,
63 declaration_ref(declaration
);
69 lookup_field_definition_scope(GQuark field_name
,
70 struct definition_scope
*scope
)
72 return g_hash_table_lookup(scope
->definitions
,
73 (gconstpointer
) (unsigned long) field_name
);
77 * Returns the index at which the paths differ.
78 * If the value returned equals len, it means the paths are identical
79 * from index 0 to len-1.
81 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
85 assert(len
<= a
->len
);
86 assert(len
<= b
->len
);
88 for (i
= 0; i
< len
; i
++) {
91 qa
= g_array_index(a
, GQuark
, i
);
92 qb
= g_array_index(b
, GQuark
, i
);
99 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
101 if (path
->len
<= maybe_parent
->len
)
103 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
104 == maybe_parent
->len
)
110 static struct definition_scope
*
111 get_definition_scope(struct definition
*definition
)
113 switch (definition
->declaration
->id
) {
114 case CTF_TYPE_STRUCT
:
116 struct definition_struct
*def
=
117 container_of(definition
, struct definition_struct
, p
);
120 case CTF_TYPE_VARIANT
:
122 struct definition_variant
*def
=
123 container_of(definition
, struct definition_variant
, p
);
128 struct definition_array
*def
=
129 container_of(definition
, struct definition_array
, p
);
132 case CTF_TYPE_SEQUENCE
:
134 struct definition_sequence
*def
=
135 container_of(definition
, struct definition_sequence
, p
);
139 case CTF_TYPE_INTEGER
:
142 case CTF_TYPE_STRING
:
143 case CTF_TYPE_UNKNOWN
:
150 * OK, here is the fun. We want to lookup a field that is:
151 * - either in the same dynamic scope:
152 * - either in the current scope, but prior to the current field.
153 * - or in a parent scope (or parent of parent ...) still in a field
154 * prior to the current field position within the parents.
155 * - or in a different dynamic scope:
156 * - either in a upper dynamic scope (walk down a targeted scope from
157 * the dynamic scope root)
158 * - or in a lower dynamic scope (failure)
159 * The dynamic scope roots are linked together, so we can access the
160 * parent dynamic scope from the child dynamic scope by walking up to
162 * If we cannot find such a field that is prior to our current path, we
165 * cur_path: the path leading to the variant definition.
166 * lookup_path: the path leading to the enum we want to look for.
167 * scope: the definition scope containing the variant definition.
170 lookup_definition(GArray
*cur_path
,
172 struct definition_scope
*scope
)
174 struct definition
*definition
, *lookup_definition
;
179 /* going up in the hierarchy. Check where we come from. */
180 assert(is_path_child_of(cur_path
, scope
->scope_path
));
181 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
182 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
183 definition
= lookup_field_definition_scope(last
, scope
);
185 index
= definition
->index
;
187 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
188 /* Means we can lookup the field in this scope */
189 last
= g_array_index(lookup_path
, GQuark
,
190 scope
->scope_path
->len
);
191 lookup_definition
= lookup_field_definition_scope(last
, scope
);
192 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
194 /* Found it! And it is prior to the current field. */
195 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
197 return lookup_definition
;
199 scope
= get_definition_scope(lookup_definition
);
200 /* Check if the definition has a sub-scope */
204 * Don't compare index anymore, because we are
205 * going within a scope that has been validated
206 * to be entirely prior to the current scope.
214 /* lookup_path is within an upper scope */
215 cur_path
= scope
->scope_path
;
216 scope
= scope
->parent_scope
;
222 int register_field_definition(GQuark field_name
, struct definition
*definition
,
223 struct definition_scope
*scope
)
228 /* Only lookup in local scope */
229 if (lookup_field_definition_scope(field_name
, scope
))
232 g_hash_table_insert(scope
->definitions
,
233 (gpointer
) (unsigned long) field_name
,
235 definition_ref(definition
);
239 void declaration_ref(struct declaration
*declaration
)
244 void declaration_unref(struct declaration
*declaration
)
246 if (!--declaration
->ref
)
247 declaration
->declaration_free(declaration
);
250 void definition_ref(struct definition
*definition
)
255 void definition_unref(struct definition
*definition
)
257 if (!--definition
->ref
)
258 definition
->declaration
->definition_free(definition
);
261 struct declaration_scope
*
262 new_declaration_scope(struct declaration_scope
*parent_scope
)
264 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
266 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
267 g_direct_equal
, NULL
,
268 (GDestroyNotify
) definition_unref
);
269 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
270 g_direct_equal
, NULL
,
271 (GDestroyNotify
) declaration_unref
);
272 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
273 g_direct_equal
, NULL
,
274 (GDestroyNotify
) declaration_unref
);
275 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
276 g_direct_equal
, NULL
,
277 (GDestroyNotify
) declaration_unref
);
278 scope
->parent_scope
= parent_scope
;
282 void free_declaration_scope(struct declaration_scope
*scope
)
284 g_hash_table_destroy(scope
->enum_declarations
);
285 g_hash_table_destroy(scope
->variant_declarations
);
286 g_hash_table_destroy(scope
->struct_declarations
);
287 g_hash_table_destroy(scope
->typedef_declarations
);
292 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
293 struct declaration_scope
*scope
)
295 return g_hash_table_lookup(scope
->struct_declarations
,
296 (gconstpointer
) (unsigned long) struct_name
);
299 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
300 struct declaration_scope
*scope
)
302 struct declaration_struct
*declaration
;
305 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
308 scope
= scope
->parent_scope
;
313 int register_struct_declaration(GQuark struct_name
,
314 struct declaration_struct
*struct_declaration
,
315 struct declaration_scope
*scope
)
320 /* Only lookup in local scope */
321 if (lookup_struct_declaration_scope(struct_name
, scope
))
324 g_hash_table_insert(scope
->struct_declarations
,
325 (gpointer
) (unsigned long) struct_name
,
327 declaration_ref(&struct_declaration
->p
);
332 struct declaration_untagged_variant
*
333 lookup_variant_declaration_scope(GQuark variant_name
,
334 struct declaration_scope
*scope
)
336 return g_hash_table_lookup(scope
->variant_declarations
,
337 (gconstpointer
) (unsigned long) variant_name
);
340 struct declaration_untagged_variant
*
341 lookup_variant_declaration(GQuark variant_name
,
342 struct declaration_scope
*scope
)
344 struct declaration_untagged_variant
*declaration
;
347 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
350 scope
= scope
->parent_scope
;
355 int register_variant_declaration(GQuark variant_name
,
356 struct declaration_untagged_variant
*untagged_variant_declaration
,
357 struct declaration_scope
*scope
)
362 /* Only lookup in local scope */
363 if (lookup_variant_declaration_scope(variant_name
, scope
))
366 g_hash_table_insert(scope
->variant_declarations
,
367 (gpointer
) (unsigned long) variant_name
,
368 untagged_variant_declaration
);
369 declaration_ref(&untagged_variant_declaration
->p
);
374 struct declaration_enum
*
375 lookup_enum_declaration_scope(GQuark enum_name
,
376 struct declaration_scope
*scope
)
378 return g_hash_table_lookup(scope
->enum_declarations
,
379 (gconstpointer
) (unsigned long) enum_name
);
382 struct declaration_enum
*
383 lookup_enum_declaration(GQuark enum_name
,
384 struct declaration_scope
*scope
)
386 struct declaration_enum
*declaration
;
389 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
392 scope
= scope
->parent_scope
;
397 int register_enum_declaration(GQuark enum_name
,
398 struct declaration_enum
*enum_declaration
,
399 struct declaration_scope
*scope
)
404 /* Only lookup in local scope */
405 if (lookup_enum_declaration_scope(enum_name
, scope
))
408 g_hash_table_insert(scope
->enum_declarations
,
409 (gpointer
) (unsigned long) enum_name
,
411 declaration_ref(&enum_declaration
->p
);
415 static struct definition_scope
*
416 _new_definition_scope(struct definition_scope
*parent_scope
,
419 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
421 scope
->definitions
= g_hash_table_new_full(g_direct_hash
,
422 g_direct_equal
, NULL
,
423 (GDestroyNotify
) definition_unref
);
424 scope
->parent_scope
= parent_scope
;
425 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
427 g_array_set_size(scope
->scope_path
, scope_path_len
);
431 struct definition_scope
*
432 new_definition_scope(struct definition_scope
*parent_scope
,
435 struct definition_scope
*scope
;
436 int scope_path_len
= 1;
439 scope_path_len
+= parent_scope
->scope_path
->len
;
440 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
442 memcpy(scope
->scope_path
, parent_scope
->scope_path
,
443 sizeof(GQuark
) * (scope_path_len
- 1));
444 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
450 * in: path (dot separated), out: q (GArray of GQuark)
452 void append_scope_path(const char *path
, GArray
*q
)
454 const char *ptrbegin
, *ptrend
= path
;
462 ptrend
= strchr(ptrbegin
, '.');
465 len
= ptrend
- ptrbegin
;
466 /* Don't accept two consecutive dots */
468 str
= g_new(char, len
+ 1); /* include \0 */
469 memcpy(str
, ptrbegin
, len
);
471 quark
= g_quark_from_string(str
);
472 g_array_append_val(q
, quark
);
475 /* last. Check for trailing dot (and discard). */
476 if (ptrbegin
[0] != '\0') {
477 quark
= g_quark_from_string(ptrbegin
);
478 g_array_append_val(q
, quark
);
482 void set_dynamic_definition_scope(struct definition
*definition
,
483 struct definition_scope
*scope
,
484 const char *root_name
)
486 g_array_set_size(scope
->scope_path
, 0);
487 append_scope_path(root_name
, scope
->scope_path
);
489 * Use INT_MAX order to ensure that all fields of the parent
490 * scope are seen as being prior to this scope.
492 definition
->index
= INT_MAX
;
495 void free_definition_scope(struct definition_scope
*scope
)
497 g_array_free(scope
->scope_path
, TRUE
);
498 g_hash_table_destroy(scope
->definitions
);