X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=types%2Ftypes.c;h=08324acc481dd5e594525282d3329d4a15459f41;hp=208b303f1e00c270694572ee48a1667db0a01001;hb=dc48ecad637fc7fb8479da563ef2dfd3948cee73;hpb=05c749e538ebc3a4f6735f62d022655cf92fc17e diff --git a/types/types.c b/types/types.c index 208b303f..08324acc 100644 --- a/types/types.c +++ b/types/types.c @@ -19,41 +19,54 @@ */ #include +#include #include #include static -struct definition * - lookup_typedef_declaration_scope(GQuark declaration_name, +GQuark prefix_quark(const char *prefix, GQuark quark) +{ + GQuark nq; + GString *str; + + str = g_string_new(prefix); + g_string_append(str, g_quark_to_string(quark)); + nq = g_quark_from_string(g_string_free(str, FALSE)); + return nq; +} + +static +struct declaration * + lookup_declaration_scope(GQuark declaration_name, struct declaration_scope *scope) { return g_hash_table_lookup(scope->typedef_declarations, (gconstpointer) (unsigned long) declaration_name); } -struct definition *lookup_typedef_declaration(GQuark declaration_name, +struct declaration *lookup_declaration(GQuark declaration_name, struct declaration_scope *scope) { - struct definition *definition; + struct declaration *declaration; while (scope) { - definition = lookup_typedef_declaration_scope(declaration_name, - scope); - if (definition) - return definition; + declaration = lookup_declaration_scope(declaration_name, + scope); + if (declaration) + return declaration; scope = scope->parent_scope; } return NULL; } -int register_typedef_declaration(GQuark name, struct declaration *declaration, +int register_declaration(GQuark name, struct declaration *declaration, struct declaration_scope *scope) { if (!name) return -EPERM; /* Only lookup in local scope */ - if (lookup_typedef_declaration_scope(name, scope)) + if (lookup_declaration_scope(name, scope)) return -EEXIST; g_hash_table_insert(scope->typedef_declarations, @@ -147,12 +160,17 @@ static struct definition_scope * /* * OK, here is the fun. We want to lookup a field that is: - * - either in the current scope, but prior to the current field. - * - or in a parent scope (or parent of parent ...) still in a field - * prior to the current field position within the parents. - * A reaching through a dynamic scoping (e.g. from payload structure to - * event header structure), the parent fields are always entirely prior - * to the child. + * - either in the same dynamic scope: + * - either in the current scope, but prior to the current field. + * - or in a parent scope (or parent of parent ...) still in a field + * prior to the current field position within the parents. + * - or in a different dynamic scope: + * - either in a upper dynamic scope (walk down a targeted scope from + * the dynamic scope root) + * - or in a lower dynamic scope (failure) + * The dynamic scope roots are linked together, so we can access the + * parent dynamic scope from the child dynamic scope by walking up to + * the parent. * If we cannot find such a field that is prior to our current path, we * return NULL. * @@ -237,6 +255,8 @@ void declaration_ref(struct declaration *declaration) void declaration_unref(struct declaration *declaration) { + if (!declaration) + return; if (!--declaration->ref) declaration->declaration_free(declaration); } @@ -248,6 +268,8 @@ void definition_ref(struct definition *definition) void definition_unref(struct definition *definition) { + if (!definition) + return; if (!--definition->ref) definition->declaration->definition_free(definition); } @@ -308,6 +330,9 @@ int register_struct_declaration(GQuark struct_name, struct declaration_struct *struct_declaration, struct declaration_scope *scope) { + GQuark prefix_name; + int ret; + if (!struct_name) return -EPERM; @@ -319,11 +344,16 @@ int register_struct_declaration(GQuark struct_name, (gpointer) (unsigned long) struct_name, struct_declaration); declaration_ref(&struct_declaration->p); + + /* Also add in typedef/typealias scopes */ + prefix_name = prefix_quark("struct ", struct_name); + ret = register_declaration(prefix_name, &struct_declaration->p, scope); + assert(!ret); return 0; } static -struct declaration_variant * +struct declaration_untagged_variant * lookup_variant_declaration_scope(GQuark variant_name, struct declaration_scope *scope) { @@ -331,11 +361,11 @@ struct declaration_variant * (gconstpointer) (unsigned long) variant_name); } -struct declaration_variant * +struct declaration_untagged_variant * lookup_variant_declaration(GQuark variant_name, struct declaration_scope *scope) { - struct declaration_variant *declaration; + struct declaration_untagged_variant *declaration; while (scope) { declaration = lookup_variant_declaration_scope(variant_name, scope); @@ -347,9 +377,12 @@ struct declaration_variant * } int register_variant_declaration(GQuark variant_name, - struct declaration_variant *variant_declaration, + struct declaration_untagged_variant *untagged_variant_declaration, struct declaration_scope *scope) { + GQuark prefix_name; + int ret; + if (!variant_name) return -EPERM; @@ -359,8 +392,14 @@ int register_variant_declaration(GQuark variant_name, g_hash_table_insert(scope->variant_declarations, (gpointer) (unsigned long) variant_name, - variant_declaration); - declaration_ref(&variant_declaration->p); + untagged_variant_declaration); + declaration_ref(&untagged_variant_declaration->p); + + /* Also add in typedef/typealias scopes */ + prefix_name = prefix_quark("variant ", variant_name); + ret = register_declaration(prefix_name, + &untagged_variant_declaration->p, scope); + assert(!ret); return 0; } @@ -392,6 +431,9 @@ int register_enum_declaration(GQuark enum_name, struct declaration_enum *enum_declaration, struct declaration_scope *scope) { + GQuark prefix_name; + int ret; + if (!enum_name) return -EPERM; @@ -403,33 +445,95 @@ int register_enum_declaration(GQuark enum_name, (gpointer) (unsigned long) enum_name, enum_declaration); declaration_ref(&enum_declaration->p); + + /* Also add in typedef/typealias scopes */ + prefix_name = prefix_quark("enum ", enum_name); + ret = register_declaration(prefix_name, &enum_declaration->p, scope); + assert(!ret); return 0; } -struct definition_scope * - new_definition_scope(struct definition_scope *parent_scope, - GQuark field_name) +static struct definition_scope * + _new_definition_scope(struct definition_scope *parent_scope, + int scope_path_len) { struct definition_scope *scope = g_new(struct definition_scope, 1); - int scope_path_len = 1; scope->definitions = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) definition_unref); scope->parent_scope = parent_scope; - if (scope->parent_scope) - scope_path_len += scope->parent_scope->scope_path->len; scope->scope_path = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), scope_path_len); g_array_set_size(scope->scope_path, scope_path_len); - if (scope->parent_scope) - memcpy(scope->scope_path, scope->parent_scope->scope_path, + return scope; +} + +struct definition_scope * + new_definition_scope(struct definition_scope *parent_scope, + GQuark field_name) +{ + struct definition_scope *scope; + int scope_path_len = 1; + + if (parent_scope) + scope_path_len += parent_scope->scope_path->len; + scope = _new_definition_scope(parent_scope, scope_path_len); + if (parent_scope) + memcpy(scope->scope_path, parent_scope->scope_path, sizeof(GQuark) * (scope_path_len - 1)); g_array_index(scope->scope_path, GQuark, scope_path_len - 1) = field_name; return scope; } +/* + * in: path (dot separated), out: q (GArray of GQuark) + */ +void append_scope_path(const char *path, GArray *q) +{ + const char *ptrbegin, *ptrend = path; + GQuark quark; + + for (;;) { + char *str; + size_t len; + + ptrbegin = ptrend; + ptrend = strchr(ptrbegin, '.'); + if (!ptrend) + break; + len = ptrend - ptrbegin; + /* Don't accept two consecutive dots */ + assert(len != 0); + str = g_new(char, len + 1); /* include \0 */ + memcpy(str, ptrbegin, len); + str[len] = '\0'; + quark = g_quark_from_string(str); + g_array_append_val(q, quark); + g_free(str); + ptrend++; /* skip current dot */ + } + /* last. Check for trailing dot (and discard). */ + if (ptrbegin[0] != '\0') { + quark = g_quark_from_string(ptrbegin); + g_array_append_val(q, quark); + } +} + +void set_dynamic_definition_scope(struct definition *definition, + struct definition_scope *scope, + const char *root_name) +{ + g_array_set_size(scope->scope_path, 0); + append_scope_path(root_name, scope->scope_path); + /* + * Use INT_MAX order to ensure that all fields of the parent + * scope are seen as being prior to this scope. + */ + definition->index = INT_MAX; +} + void free_definition_scope(struct definition_scope *scope) { g_array_free(scope->scope_path, TRUE);