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>
27 GQuark
prefix_quark(const char *prefix
, GQuark quark
)
32 str
= g_string_new(prefix
);
33 g_string_append(str
, g_quark_to_string(quark
));
34 nq
= g_quark_from_string(g_string_free(str
, FALSE
));
40 lookup_declaration_scope(GQuark declaration_name
,
41 struct declaration_scope
*scope
)
43 return g_hash_table_lookup(scope
->typedef_declarations
,
44 (gconstpointer
) (unsigned long) declaration_name
);
47 struct declaration
*lookup_declaration(GQuark declaration_name
,
48 struct declaration_scope
*scope
)
50 struct declaration
*declaration
;
53 declaration
= lookup_declaration_scope(declaration_name
,
57 scope
= scope
->parent_scope
;
62 int register_declaration(GQuark name
, struct declaration
*declaration
,
63 struct declaration_scope
*scope
)
68 /* Only lookup in local scope */
69 if (lookup_declaration_scope(name
, scope
))
72 g_hash_table_insert(scope
->typedef_declarations
,
73 (gpointer
) (unsigned long) name
,
75 declaration_ref(declaration
);
81 lookup_field_definition_scope(GQuark field_name
,
82 struct definition_scope
*scope
)
84 return g_hash_table_lookup(scope
->definitions
,
85 (gconstpointer
) (unsigned long) field_name
);
89 * Returns the index at which the paths differ.
90 * If the value returned equals len, it means the paths are identical
91 * from index 0 to len-1.
93 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
97 assert(len
<= a
->len
);
98 assert(len
<= b
->len
);
100 for (i
= 0; i
< len
; i
++) {
103 qa
= g_array_index(a
, GQuark
, i
);
104 qb
= g_array_index(b
, GQuark
, i
);
111 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
113 if (path
->len
<= maybe_parent
->len
)
115 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
116 == maybe_parent
->len
)
122 static struct definition_scope
*
123 get_definition_scope(struct definition
*definition
)
125 switch (definition
->declaration
->id
) {
126 case CTF_TYPE_STRUCT
:
128 struct definition_struct
*def
=
129 container_of(definition
, struct definition_struct
, p
);
132 case CTF_TYPE_VARIANT
:
134 struct definition_variant
*def
=
135 container_of(definition
, struct definition_variant
, p
);
140 struct definition_array
*def
=
141 container_of(definition
, struct definition_array
, p
);
144 case CTF_TYPE_SEQUENCE
:
146 struct definition_sequence
*def
=
147 container_of(definition
, struct definition_sequence
, p
);
151 case CTF_TYPE_INTEGER
:
154 case CTF_TYPE_STRING
:
155 case CTF_TYPE_UNKNOWN
:
162 * OK, here is the fun. We want to lookup a field that is:
163 * - either in the same dynamic scope:
164 * - either in the current scope, but prior to the current field.
165 * - or in a parent scope (or parent of parent ...) still in a field
166 * prior to the current field position within the parents.
167 * - or in a different dynamic scope:
168 * - either in a upper dynamic scope (walk down a targeted scope from
169 * the dynamic scope root)
170 * - or in a lower dynamic scope (failure)
171 * The dynamic scope roots are linked together, so we can access the
172 * parent dynamic scope from the child dynamic scope by walking up to
174 * If we cannot find such a field that is prior to our current path, we
177 * cur_path: the path leading to the variant definition.
178 * lookup_path: the path leading to the enum we want to look for.
179 * scope: the definition scope containing the variant definition.
182 lookup_definition(GArray
*cur_path
,
184 struct definition_scope
*scope
)
186 struct definition
*definition
, *lookup_definition
;
191 /* going up in the hierarchy. Check where we come from. */
192 assert(is_path_child_of(cur_path
, scope
->scope_path
));
193 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
194 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
195 definition
= lookup_field_definition_scope(last
, scope
);
197 index
= definition
->index
;
199 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
200 /* Means we can lookup the field in this scope */
201 last
= g_array_index(lookup_path
, GQuark
,
202 scope
->scope_path
->len
);
203 lookup_definition
= lookup_field_definition_scope(last
, scope
);
204 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
206 /* Found it! And it is prior to the current field. */
207 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
209 return lookup_definition
;
211 scope
= get_definition_scope(lookup_definition
);
212 /* Check if the definition has a sub-scope */
216 * Don't compare index anymore, because we are
217 * going within a scope that has been validated
218 * to be entirely prior to the current scope.
226 /* lookup_path is within an upper scope */
227 cur_path
= scope
->scope_path
;
228 scope
= scope
->parent_scope
;
234 int register_field_definition(GQuark field_name
, struct definition
*definition
,
235 struct definition_scope
*scope
)
240 /* Only lookup in local scope */
241 if (lookup_field_definition_scope(field_name
, scope
))
244 g_hash_table_insert(scope
->definitions
,
245 (gpointer
) (unsigned long) field_name
,
247 definition_ref(definition
);
251 void declaration_ref(struct declaration
*declaration
)
256 void declaration_unref(struct declaration
*declaration
)
258 if (!--declaration
->ref
)
259 declaration
->declaration_free(declaration
);
262 void definition_ref(struct definition
*definition
)
267 void definition_unref(struct definition
*definition
)
269 if (!--definition
->ref
)
270 definition
->declaration
->definition_free(definition
);
273 struct declaration_scope
*
274 new_declaration_scope(struct declaration_scope
*parent_scope
)
276 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
278 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
279 g_direct_equal
, NULL
,
280 (GDestroyNotify
) definition_unref
);
281 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
282 g_direct_equal
, NULL
,
283 (GDestroyNotify
) declaration_unref
);
284 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
285 g_direct_equal
, NULL
,
286 (GDestroyNotify
) declaration_unref
);
287 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
288 g_direct_equal
, NULL
,
289 (GDestroyNotify
) declaration_unref
);
290 scope
->parent_scope
= parent_scope
;
294 void free_declaration_scope(struct declaration_scope
*scope
)
296 g_hash_table_destroy(scope
->enum_declarations
);
297 g_hash_table_destroy(scope
->variant_declarations
);
298 g_hash_table_destroy(scope
->struct_declarations
);
299 g_hash_table_destroy(scope
->typedef_declarations
);
304 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
305 struct declaration_scope
*scope
)
307 return g_hash_table_lookup(scope
->struct_declarations
,
308 (gconstpointer
) (unsigned long) struct_name
);
311 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
312 struct declaration_scope
*scope
)
314 struct declaration_struct
*declaration
;
317 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
320 scope
= scope
->parent_scope
;
325 int register_struct_declaration(GQuark struct_name
,
326 struct declaration_struct
*struct_declaration
,
327 struct declaration_scope
*scope
)
335 /* Only lookup in local scope */
336 if (lookup_struct_declaration_scope(struct_name
, scope
))
339 g_hash_table_insert(scope
->struct_declarations
,
340 (gpointer
) (unsigned long) struct_name
,
342 declaration_ref(&struct_declaration
->p
);
344 /* Also add in typedef/typealias scopes */
345 prefix_name
= prefix_quark("struct ", struct_name
);
346 ret
= register_declaration(prefix_name
, &struct_declaration
->p
, scope
);
352 struct declaration_untagged_variant
*
353 lookup_variant_declaration_scope(GQuark variant_name
,
354 struct declaration_scope
*scope
)
356 return g_hash_table_lookup(scope
->variant_declarations
,
357 (gconstpointer
) (unsigned long) variant_name
);
360 struct declaration_untagged_variant
*
361 lookup_variant_declaration(GQuark variant_name
,
362 struct declaration_scope
*scope
)
364 struct declaration_untagged_variant
*declaration
;
367 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
370 scope
= scope
->parent_scope
;
375 int register_variant_declaration(GQuark variant_name
,
376 struct declaration_untagged_variant
*untagged_variant_declaration
,
377 struct declaration_scope
*scope
)
385 /* Only lookup in local scope */
386 if (lookup_variant_declaration_scope(variant_name
, scope
))
389 g_hash_table_insert(scope
->variant_declarations
,
390 (gpointer
) (unsigned long) variant_name
,
391 untagged_variant_declaration
);
392 declaration_ref(&untagged_variant_declaration
->p
);
394 /* Also add in typedef/typealias scopes */
395 prefix_name
= prefix_quark("variant ", variant_name
);
396 ret
= register_declaration(prefix_name
,
397 &untagged_variant_declaration
->p
, scope
);
403 struct declaration_enum
*
404 lookup_enum_declaration_scope(GQuark enum_name
,
405 struct declaration_scope
*scope
)
407 return g_hash_table_lookup(scope
->enum_declarations
,
408 (gconstpointer
) (unsigned long) enum_name
);
411 struct declaration_enum
*
412 lookup_enum_declaration(GQuark enum_name
,
413 struct declaration_scope
*scope
)
415 struct declaration_enum
*declaration
;
418 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
421 scope
= scope
->parent_scope
;
426 int register_enum_declaration(GQuark enum_name
,
427 struct declaration_enum
*enum_declaration
,
428 struct declaration_scope
*scope
)
436 /* Only lookup in local scope */
437 if (lookup_enum_declaration_scope(enum_name
, scope
))
440 g_hash_table_insert(scope
->enum_declarations
,
441 (gpointer
) (unsigned long) enum_name
,
443 declaration_ref(&enum_declaration
->p
);
445 /* Also add in typedef/typealias scopes */
446 prefix_name
= prefix_quark("enum ", enum_name
);
447 ret
= register_declaration(prefix_name
, &enum_declaration
->p
, scope
);
452 static struct definition_scope
*
453 _new_definition_scope(struct definition_scope
*parent_scope
,
456 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
458 scope
->definitions
= g_hash_table_new_full(g_direct_hash
,
459 g_direct_equal
, NULL
,
460 (GDestroyNotify
) definition_unref
);
461 scope
->parent_scope
= parent_scope
;
462 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
464 g_array_set_size(scope
->scope_path
, scope_path_len
);
468 struct definition_scope
*
469 new_definition_scope(struct definition_scope
*parent_scope
,
472 struct definition_scope
*scope
;
473 int scope_path_len
= 1;
476 scope_path_len
+= parent_scope
->scope_path
->len
;
477 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
479 memcpy(scope
->scope_path
, parent_scope
->scope_path
,
480 sizeof(GQuark
) * (scope_path_len
- 1));
481 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
487 * in: path (dot separated), out: q (GArray of GQuark)
489 void append_scope_path(const char *path
, GArray
*q
)
491 const char *ptrbegin
, *ptrend
= path
;
499 ptrend
= strchr(ptrbegin
, '.');
502 len
= ptrend
- ptrbegin
;
503 /* Don't accept two consecutive dots */
505 str
= g_new(char, len
+ 1); /* include \0 */
506 memcpy(str
, ptrbegin
, len
);
508 quark
= g_quark_from_string(str
);
509 g_array_append_val(q
, quark
);
511 ptrend
++; /* skip current dot */
513 /* last. Check for trailing dot (and discard). */
514 if (ptrbegin
[0] != '\0') {
515 quark
= g_quark_from_string(ptrbegin
);
516 g_array_append_val(q
, quark
);
520 void set_dynamic_definition_scope(struct definition
*definition
,
521 struct definition_scope
*scope
,
522 const char *root_name
)
524 g_array_set_size(scope
->scope_path
, 0);
525 append_scope_path(root_name
, scope
->scope_path
);
527 * Use INT_MAX order to ensure that all fields of the parent
528 * scope are seen as being prior to this scope.
530 definition
->index
= INT_MAX
;
533 void free_definition_scope(struct definition_scope
*scope
)
535 g_array_free(scope
->scope_path
, TRUE
);
536 g_hash_table_destroy(scope
->definitions
);