Declaration scope lookup
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 27 Feb 2011 17:34:06 +0000 (12:34 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 27 Feb 2011 17:34:06 +0000 (12:34 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/babeltrace/types.h
types/struct.c
types/types.c
types/variant.c

index 3d396c86b03b5d161ab35bace26cc2b965ad4eed..718d391a0dc9a90aa405da80cc263e8f2d421fd6 100644 (file)
@@ -91,6 +91,8 @@ struct declaration;
 struct declaration_scope {
        /* Hash table mapping type name GQuark to struct type */
        GHashTable *types;
+       /* Hash table mapping field name GQuark to struct declaration */
+       GHashTable *declarations;
        struct declaration_scope *parent_scope;
 };
 
@@ -229,6 +231,7 @@ struct type_field {
 };
 
 struct field {
+       GQuark name;
        struct declaration *declaration;
 };
 
@@ -287,9 +290,14 @@ struct declaration_sequence {
        struct field current_element;           /* struct field */
 };
 
-struct type *lookup_type(GQuark qname, struct declaration_scope *scope);
+struct type *lookup_type(GQuark type_name, struct declaration_scope *scope);
 int register_type(struct type *type, struct declaration_scope *scope);
 
+struct declaration *
+       lookup_declaration(GQuark field_name, struct declaration_scope *scope);
+int register_declaration(GQuark field_name, struct declaration *declaration,
+                        struct declaration_scope *scope);
+
 void type_ref(struct type *type);
 void type_unref(struct type *type);
 
index 92ede5866d65130f90ecc50bf381374eadefb7a9..baedbddb5f4ba6a08b58201cc29da9673a3e7b27 100644 (file)
@@ -102,6 +102,8 @@ struct declaration *
        struct type_struct *struct_type =
                container_of(type, struct type_struct, p);
        struct declaration_struct *_struct;
+       unsigned long i;
+       int ret;
 
        _struct = g_new(struct declaration_struct, 1);
        type_ref(&struct_type->p);
@@ -112,6 +114,22 @@ struct declaration *
        _struct->fields = g_array_sized_new(FALSE, TRUE,
                                            sizeof(struct field),
                                            DEFAULT_NR_STRUCT_FIELDS);
+       g_array_set_size(_struct->fields, struct_type->fields->len);
+       for (i = 0; i < struct_type->fields->len; i++) {
+               struct type_field *type_field =
+                       &g_array_index(struct_type->fields,
+                                      struct type_field, i);
+               struct field *field = &g_array_index(_struct->fields,
+                                                    struct field, i);
+
+               field->name = type_field->name;
+               field->declaration =
+                       type_field->type->declaration_new(type_field->type,
+                                                         _struct->scope);
+               ret = register_declaration(field->name,
+                                          field->declaration, _struct->scope);
+               assert(!ret);
+       }
        return &_struct->p;
 }
 
@@ -122,6 +140,7 @@ void _struct_declaration_free(struct declaration *declaration)
                container_of(declaration, struct declaration_struct, p);
        unsigned long i;
 
+       assert(_struct->fields->len == _struct->type->fields->len);
        for (i = 0; i < _struct->fields->len; i++) {
                struct field *field = &g_array_index(_struct->fields,
                                                     struct field, i);
index 8272b8147db08fdc822a153d44050beabd9fb19c..e001dd0263e05b047db5b7e50f7089f4a739a2d5 100644 (file)
 #include <errno.h>
 
 static
-struct type *lookup_type_scope(GQuark qname, struct declaration_scope *scope)
+struct type *
+       lookup_type_scope(GQuark type_name, struct declaration_scope *scope)
 {
        return g_hash_table_lookup(scope->types,
-                                  (gconstpointer) (unsigned long) qname);
+                                  (gconstpointer) (unsigned long) type_name);
 }
 
-struct type *lookup_type(GQuark qname, struct declaration_scope *scope)
+struct type *lookup_type(GQuark type_name, struct declaration_scope *scope)
 {
        struct type *type;
 
        while (scope) {
-               type = lookup_type_scope(qname, scope);
+               type = lookup_type_scope(type_name, scope);
                if (type)
                        return type;
                scope = scope->parent_scope;
@@ -42,16 +43,6 @@ struct type *lookup_type(GQuark qname, struct declaration_scope *scope)
        return NULL;
 }
 
-static void free_type(struct type *type)
-{
-       type->type_free(type);
-}
-
-static void free_declaration(struct declaration *declaration)
-{
-       declaration->type->declaration_free(declaration);
-}
-
 int register_type(struct type *type, struct declaration_scope *scope)
 {
        if (!type->name)
@@ -64,6 +55,46 @@ int register_type(struct type *type, struct declaration_scope *scope)
        g_hash_table_insert(scope->types,
                            (gpointer) (unsigned long) type->name,
                            type);
+       type_ref(type);
+       return 0;
+}
+
+static
+struct declaration *
+       lookup_declaration_scope(GQuark field_name, struct declaration_scope *scope)
+{
+       return g_hash_table_lookup(scope->declarations,
+                                  (gconstpointer) (unsigned long) field_name);
+}
+
+struct declaration *
+       lookup_declaration(GQuark field_name, struct declaration_scope *scope)
+{
+       struct declaration *declaration;
+
+       while (scope) {
+               declaration = lookup_declaration_scope(field_name, scope);
+               if (declaration)
+                       return declaration;
+               scope = scope->parent_scope;
+       }
+       return NULL;
+}
+
+int register_declaration(GQuark field_name, struct declaration *declaration,
+                        struct declaration_scope *scope)
+{
+       if (!field_name)
+               return -EPERM;
+
+       /* Only lookup in local scope */
+       if (lookup_declaration_scope(field_name, scope))
+               return -EEXIST;
+
+       g_hash_table_insert(scope->declarations,
+                           (gpointer) (unsigned long) field_name,
+                           declaration);
+       declaration_ref(declaration);
        return 0;
 }
 
@@ -75,7 +106,7 @@ void type_ref(struct type *type)
 void type_unref(struct type *type)
 {
        if (!--type->ref)
-               free_type(type);
+               type->type_free(type);
 }
 
 void declaration_ref(struct declaration *declaration)
@@ -86,7 +117,7 @@ void declaration_ref(struct declaration *declaration)
 void declaration_unref(struct declaration *declaration)
 {
        if (!--declaration->ref)
-               free_declaration(declaration);
+               declaration->type->declaration_free(declaration);
 }
 
 struct declaration_scope *
@@ -97,12 +128,16 @@ struct declaration_scope *
        scope->types = g_hash_table_new_full(g_direct_hash,
                                        g_direct_equal, NULL,
                                        (GDestroyNotify) type_unref);
+       scope->declarations = g_hash_table_new_full(g_direct_hash,
+                                       g_direct_equal, NULL,
+                                       (GDestroyNotify) declaration_unref);
        scope->parent_scope = parent_scope;
        return scope;
 }
 
 void free_declaration_scope(struct declaration_scope *scope)
 {
+       g_hash_table_destroy(scope->declarations);
        g_hash_table_destroy(scope->types);
        g_free(scope);
 }
index 91b323ffa70cc6f47f0f02e794abfdf28665d245..3c2244be88bc8c934e123d63ba5785d351a9ad24 100644 (file)
@@ -96,6 +96,7 @@ struct declaration *
        struct type_variant *variant_type =
                container_of(type, struct type_variant, p);
        struct declaration_variant *variant;
+       unsigned long i;
 
        variant = g_new(struct declaration_variant, 1);
        type_ref(&variant_type->p);
@@ -106,6 +107,19 @@ struct declaration *
        variant->fields = g_array_sized_new(FALSE, TRUE,
                                            sizeof(struct field),
                                            DEFAULT_NR_STRUCT_FIELDS);
+       g_array_set_size(variant->fields, variant_type->fields->len);
+       for (i = 0; i < variant_type->fields->len; i++) {
+               struct type_field *type_field =
+                       &g_array_index(variant_type->fields,
+                                      struct type_field, i);
+               struct field *field = &g_array_index(variant->fields,
+                                                    struct field, i);
+
+               field->name = type_field->name;
+               field->declaration =
+                       type_field->type->declaration_new(type_field->type,
+                                                         variant->scope);
+       }
        variant->current_field = NULL;
        return &variant->p;
 }
@@ -117,6 +131,7 @@ void _variant_declaration_free(struct declaration *declaration)
                container_of(declaration, struct declaration_variant, p);
        unsigned long i;
 
+       assert(variant->fields->len == variant->type->fields->len);
        for (i = 0; i < variant->fields->len; i++) {
                struct field *field = &g_array_index(variant->fields,
                                                     struct field, i);
This page took 0.039301 seconds and 4 git commands to generate.