X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=types%2Ftypes.c;h=7369f30d09ffb5a272c3d54f14e5466ac3b005b2;hp=227a1e5e3125976730b79197a987e291e82a1714;hb=312623540c466defab45503fbe0ce7ec79dcce85;hpb=9e29e16ee50d03cf4fdc0cea0220832323939dc3 diff --git a/types/types.c b/types/types.c index 227a1e5e..7369f30d 100644 --- a/types/types.c +++ b/types/types.c @@ -1,5 +1,5 @@ /* - * declarations.c + * types.c * * BabelTrace - Converter * @@ -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, @@ -242,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); } @@ -253,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); } @@ -313,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; @@ -324,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) { @@ -336,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); @@ -352,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; @@ -364,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; } @@ -397,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; @@ -408,6 +445,11 @@ 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; } @@ -427,6 +469,30 @@ static struct definition_scope * return scope; } +GQuark new_definition_path(struct definition_scope *parent_scope, GQuark field_name) +{ + GQuark path; + GString *str; + gchar *c_str; + int i; + + str = g_string_new(""); + if (parent_scope) { + for (i = 0; i < parent_scope->scope_path->len; i++) { + GQuark q = g_array_index(parent_scope->scope_path, + GQuark, i); + + g_string_append(str, g_quark_to_string(q)); + g_string_append(str, "."); + } + } + g_string_append(str, g_quark_to_string(field_name)); + c_str = g_string_free(str, FALSE); + path = g_quark_from_string(c_str); + g_free(c_str); + return path; +} + struct definition_scope * new_definition_scope(struct definition_scope *parent_scope, GQuark field_name) @@ -446,17 +512,50 @@ struct definition_scope * } /* - * Same as new_definition_scope, but reset the scope path. + * in: path (dot separated), out: q (GArray of GQuark) */ -struct definition_scope * - new_dynamic_definition_scope(struct definition_scope *parent_scope, - GQuark field_name) +void append_scope_path(const char *path, GArray *q) { - struct definition_scope *scope; + 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); + } +} - scope = _new_definition_scope(parent_scope, 1); - g_array_index(scope->scope_path, GQuark, 0) = field_name; - return scope; +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)