/*
- * declarations.c
+ * types.c
*
* BabelTrace - Converter
*
#include <errno.h>
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,
void declaration_unref(struct declaration *declaration)
{
+ if (!declaration)
+ return;
if (!--declaration->ref)
declaration->declaration_free(declaration);
}
void definition_unref(struct definition *definition)
{
+ if (!definition)
+ return;
if (!--definition->ref)
definition->declaration->definition_free(definition);
}
struct declaration_struct *struct_declaration,
struct declaration_scope *scope)
{
+ GQuark prefix_name;
+ int ret;
+
if (!struct_name)
return -EPERM;
(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)
{
(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);
}
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;
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;
}
struct declaration_enum *enum_declaration,
struct declaration_scope *scope)
{
+ GQuark prefix_name;
+ int ret;
+
if (!enum_name)
return -EPERM;
(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;
}
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);
+ if (!q)
+ continue;
+ g_string_append(str, g_quark_to_string(q));
+ g_string_append(str, ".");
+ }
+ }
+ if (field_name)
+ g_string_append(str, g_quark_to_string(field_name));
+ c_str = g_string_free(str, FALSE);
+ if (c_str[0] == '\0')
+ return 0;
+ 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)
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,
- GQuark root_name)
+ const char *root_name)
{
- g_array_set_size(scope->scope_path, 1);
- g_array_index(scope->scope_path, GQuark, 0) = 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.