[gircompiler] Clean up parsing

We never actually include multiple modules in the compiler,
so just nuke that.  Also rather than passing around GIrModule
consistently pass around a GIrTypelibBuild structure which
has various things.

This lets us maintain a stack there which we can walk for
better error messages.

Also, fix up the node lookup in giroffsets.c; previously
it didn't really handle includes correctly.  We really need to
switch to always using Foo.Bar (i.e. GIName) names internally...
This commit is contained in:
Colin Walters 2010-07-26 16:26:46 -04:00
parent 9b1bb64e83
commit 62f1b65cc8
7 changed files with 243 additions and 216 deletions

View File

@ -78,7 +78,7 @@ g_ir_module_free (GIrModule *module)
/** /**
* g_ir_module_fatal: * g_ir_module_fatal:
* @module: Current module * @build: Current build
* @line: Origin line number, or 0 if unknown * @line: Origin line number, or 0 if unknown
* @msg: printf-format string * @msg: printf-format string
* @args: Remaining arguments * @args: Remaining arguments
@ -86,12 +86,14 @@ g_ir_module_free (GIrModule *module)
* Report a fatal error, then exit. * Report a fatal error, then exit.
*/ */
void void
g_ir_module_fatal (GIrModule *module, g_ir_module_fatal (GIrTypelibBuild *build,
guint line, guint line,
const char *msg, const char *msg,
...) ...)
{ {
GString *context;
char *formatted; char *formatted;
GList *link;
va_list args; va_list args;
@ -99,10 +101,27 @@ g_ir_module_fatal (GIrModule *module,
formatted = g_strdup_vprintf (msg, args); formatted = g_strdup_vprintf (msg, args);
if (line) context = g_string_new ("");
g_printerr ("%s-%s.gir:%d: error: %s\n", module->name, module->version, line, formatted); if (line > 0)
else g_string_append_printf (context, "%d: ", line);
g_printerr ("%s-%s.gir: error: %s\n", module->name, module->version, formatted); if (build->stack)
g_string_append (context, "In ");
for (link = g_list_last (build->stack); link; link = link->prev)
{
GIrNode *node = link->data;
const char *name = node->name;
if (name)
g_string_append (context, name);
if (link->prev)
g_string_append (context, ".");
}
if (build->stack)
g_string_append (context, ": ");
g_printerr ("%s-%s.gir:%serror: %s\n", build->module->name,
build->module->version,
context->str, formatted);
g_string_free (context, TRUE);
exit (1); exit (1);
@ -203,8 +222,7 @@ node_cmp_offset_func (gconstpointer a,
GTypelib * GTypelib *
g_ir_module_build_typelib (GIrModule *module, g_ir_module_build_typelib (GIrModule *module)
GList *modules)
{ {
GError *error = NULL; GError *error = NULL;
GTypelib *typelib; GTypelib *typelib;
@ -393,8 +411,8 @@ g_ir_module_build_typelib (GIrModule *module,
entry->offset = offset; entry->offset = offset;
entry->name = write_string (node->name, strings, data, &offset2); entry->name = write_string (node->name, strings, data, &offset2);
memset (&build, 0, sizeof (build));
build.module = module; build.module = module;
build.modules = modules;
build.strings = strings; build.strings = strings;
build.types = types; build.types = types;
build.nodes_with_attributes = nodes_with_attributes; build.nodes_with_attributes = nodes_with_attributes;

View File

@ -26,9 +26,19 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef struct _GIrTypelibBuild GIrTypelibBuild;
typedef struct _GIrModule GIrModule; typedef struct _GIrModule GIrModule;
struct _GIrTypelibBuild {
GIrModule *module;
GHashTable *strings;
GHashTable *types;
GList *nodes_with_attributes;
guint32 n_attributes;
guchar *data;
GList *stack;
};
struct _GIrModule struct _GIrModule
{ {
gchar *name; gchar *name;
@ -58,10 +68,9 @@ void g_ir_module_free (GIrModule *module);
void g_ir_module_add_include_module (GIrModule *module, void g_ir_module_add_include_module (GIrModule *module,
GIrModule *include_module); GIrModule *include_module);
GTypelib * g_ir_module_build_typelib (GIrModule *module, GTypelib * g_ir_module_build_typelib (GIrModule *module);
GList *modules);
void g_ir_module_fatal (GIrModule *module, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN; void g_ir_module_fatal (GIrTypelibBuild *build, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN;
void _g_irnode_init_stats (void); void _g_irnode_init_stats (void);
void _g_irnode_dump_stats (void); void _g_irnode_dump_stats (void);

165
girnode.c
View File

@ -113,7 +113,8 @@ g_ir_node_type_to_string (GIrNodeTypeId type)
} }
GIrNode * GIrNode *
g_ir_node_new (GIrNodeTypeId type) g_ir_node_new (GIrNodeTypeId type,
GIrModule *module)
{ {
GIrNode *node = NULL; GIrNode *node = NULL;
@ -192,6 +193,7 @@ g_ir_node_new (GIrNodeTypeId type)
} }
node->type = type; node->type = type;
node->module = module;
node->offset = 0; node->offset = 0;
node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free); g_free, g_free);
@ -1040,12 +1042,12 @@ parse_boolean_value (const gchar *str)
} }
static GIrNode * static GIrNode *
find_entry_node (GIrModule *module, find_entry_node (GIrTypelibBuild *build,
GList *modules,
const gchar *name, const gchar *name,
guint16 *idx) guint16 *idx)
{ {
GIrModule *module = build->module;
GList *l; GList *l;
gint i; gint i;
gchar **names; gchar **names;
@ -1086,7 +1088,7 @@ find_entry_node (GIrModule *module,
if (n_names > 1) if (n_names > 1)
{ {
GIrNode *node = g_ir_node_new (G_IR_NODE_XREF); GIrNode *node = g_ir_node_new (G_IR_NODE_XREF, module);
((GIrNodeXRef *)node)->namespace = g_strdup (names[0]); ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]);
node->name = g_strdup (names[1]); node->name = g_strdup (names[1]);
@ -1103,8 +1105,9 @@ find_entry_node (GIrModule *module,
goto out; goto out;
} }
g_ir_module_fatal (module, 0, "Type reference '%s' not found", name);
g_ir_module_fatal (build, -1, "type reference '%s' not found",
name);
out: out:
g_strfreev (names); g_strfreev (names);
@ -1113,101 +1116,77 @@ find_entry_node (GIrModule *module,
} }
static guint16 static guint16
find_entry (GIrModule *module, find_entry (GIrTypelibBuild *build,
GList *modules,
const gchar *name) const gchar *name)
{ {
guint16 idx = 0; guint16 idx = 0;
find_entry_node (module, modules, name, &idx); find_entry_node (build, name, &idx);
return idx; return idx;
} }
static GIrNode * static GIrModule *
find_name_in_module (GIrModule *module, find_namespace (GIrModule *module,
const gchar *name) const char *name)
{ {
GIrModule *target;
GList *l; GList *l;
if (strcmp (module->name, name) == 0)
return module;
for (l = module->entries; l; l = l->next) for (l = module->include_modules; l; l = l->next)
{ {
GIrNode *node = (GIrNode *)l->data; GIrModule *submodule = l->data;
if (strcmp (node->name, name) == 0) if (strcmp (submodule->name, name) == 0)
return node; return submodule;
target = find_namespace (submodule, name);
if (target)
return target;
} }
return NULL; return NULL;
} }
gboolean GIrNode *
g_ir_find_node (GIrModule *module, g_ir_find_node (GIrTypelibBuild *build,
GList *modules, GIrModule *src_module,
const char *name, const char *name)
GIrNode **node_out,
GIrModule **module_out)
{ {
GList *l;
GIrNode *return_node = NULL;
char **names = g_strsplit (name, ".", 0); char **names = g_strsplit (name, ".", 0);
gint n_names = g_strv_length (names); gint n_names = g_strv_length (names);
GIrNode *node = NULL; const char *target_name;
GList *l; GIrModule *target_module;
if (n_names == 0)
{
g_warning ("Name can't be empty");
goto out;
}
if (n_names > 2)
{
g_warning ("Too many name parts in '%s'", name);
goto out;
}
if (n_names == 1) if (n_names == 1)
{ {
*module_out = module; target_module = src_module;
node = find_name_in_module (module, names[0]); target_name = name;
}
else if (strcmp (names[0], module->name) == 0)
{
*module_out = module;
node = find_name_in_module (module, names[1]);
} }
else else
{ {
for (l = module->include_modules; l; l = l->next) target_module = find_namespace (build->module, names[0]);
target_name = names[1];
}
for (l = target_module->entries; l; l = l->next)
{
GIrNode *node = (GIrNode *)l->data;
if (strcmp (node->name, target_name) == 0)
{ {
GIrModule *m = l->data; return_node = node;
break;
if (strcmp (names[0], m->name) == 0)
{
*module_out = m;
node = find_name_in_module (m, names[1]);
goto out;
}
}
for (l = modules; l; l = l->next)
{
GIrModule *m = l->data;
if (strcmp (names[0], m->name) == 0)
{
*module_out = m;
node = find_name_in_module (m, names[1]);
goto out;
}
} }
} }
out:
g_strfreev (names); g_strfreev (names);
*node_out = node; return return_node;
return node != NULL;
} }
static int static int
@ -1235,8 +1214,7 @@ get_index_of_member_type (GIrNodeInterface *node,
} }
static void static void
serialize_type (GIrModule *module, serialize_type (GIrTypelibBuild *build,
GList *modules,
GIrNodeType *node, GIrNodeType *node,
GString *str) GString *str)
{ {
@ -1275,7 +1253,7 @@ serialize_type (GIrModule *module,
} }
else if (node->tag == GI_TYPE_TAG_ARRAY) else if (node->tag == GI_TYPE_TAG_ARRAY)
{ {
serialize_type (module, modules, node->parameter_type1, str); serialize_type (build, node->parameter_type1, str);
g_string_append (str, "["); g_string_append (str, "[");
if (node->has_length) if (node->has_length)
@ -1294,7 +1272,7 @@ serialize_type (GIrModule *module,
GIrNode *iface; GIrNode *iface;
gchar *name; gchar *name;
iface = find_entry_node (module, modules, node->interface, NULL); iface = find_entry_node (build, node->interface, NULL);
if (iface) if (iface)
{ {
if (iface->type == G_IR_NODE_XREF) if (iface->type == G_IR_NODE_XREF)
@ -1316,7 +1294,7 @@ serialize_type (GIrModule *module,
if (node->parameter_type1) if (node->parameter_type1)
{ {
g_string_append (str, "<"); g_string_append (str, "<");
serialize_type (module, modules, node->parameter_type1, str); serialize_type (build, node->parameter_type1, str);
g_string_append (str, ">"); g_string_append (str, ">");
} }
} }
@ -1326,7 +1304,7 @@ serialize_type (GIrModule *module,
if (node->parameter_type1) if (node->parameter_type1)
{ {
g_string_append (str, "<"); g_string_append (str, "<");
serialize_type (module, modules, node->parameter_type1, str); serialize_type (build, node->parameter_type1, str);
g_string_append (str, ">"); g_string_append (str, ">");
} }
} }
@ -1336,9 +1314,9 @@ serialize_type (GIrModule *module,
if (node->parameter_type1) if (node->parameter_type1)
{ {
g_string_append (str, "<"); g_string_append (str, "<");
serialize_type (module, modules, node->parameter_type1, str); serialize_type (build, node->parameter_type1, str);
g_string_append (str, ","); g_string_append (str, ",");
serialize_type (module, modules, node->parameter_type2, str); serialize_type (build, node->parameter_type2, str);
g_string_append (str, ">"); g_string_append (str, ">");
} }
} }
@ -1421,8 +1399,7 @@ g_ir_node_build_typelib (GIrNode *node,
guint32 *offset, guint32 *offset,
guint32 *offset2) guint32 *offset2)
{ {
GIrModule *module = build->module; gboolean appended_stack;
GList *modules = build->modules;
GHashTable *strings = build->strings; GHashTable *strings = build->strings;
GHashTable *types = build->types; GHashTable *types = build->types;
guchar *data = build->data; guchar *data = build->data;
@ -1437,7 +1414,14 @@ g_ir_node_build_typelib (GIrNode *node,
node->name ? " " : "", node->name ? " " : "",
g_ir_node_type_to_string (node->type)); g_ir_node_type_to_string (node->type));
g_ir_node_compute_offsets (node, module, modules); if (build->stack)
appended_stack = node != (GIrNode*)build->stack->data;
else
appended_stack = TRUE;
if (appended_stack)
build->stack = g_list_prepend (build->stack, node);
g_ir_node_compute_offsets (build, node);
/* We should only be building each node once. If we do a typelib expansion, we also /* We should only be building each node once. If we do a typelib expansion, we also
* reset the offset in girmodule.c. * reset the offset in girmodule.c.
@ -1474,7 +1458,7 @@ g_ir_node_build_typelib (GIrNode *node,
gpointer value; gpointer value;
str = g_string_new (0); str = g_string_new (0);
serialize_type (module, modules, type, str); serialize_type (build, type, str);
s = g_string_free (str, FALSE); s = g_string_free (str, FALSE);
types_count += 1; types_count += 1;
@ -1529,7 +1513,7 @@ g_ir_node_build_typelib (GIrNode *node,
iface->reserved = 0; iface->reserved = 0;
iface->tag = type->tag; iface->tag = type->tag;
iface->reserved2 = 0; iface->reserved2 = 0;
iface->interface = find_entry (module, modules, type->interface); iface->interface = find_entry (build, type->interface);
} }
break; break;
@ -1592,7 +1576,7 @@ g_ir_node_build_typelib (GIrNode *node,
*offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains) *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains)
+ 2 * blob->n_domains, 4); + 2 * blob->n_domains, 4);
for (i = 0; i < blob->n_domains; i++) for (i = 0; i < blob->n_domains; i++)
blob->domains[i] = find_entry (module, modules, type->errors[i]); blob->domains[i] = find_entry (build, type->errors[i]);
} }
break; break;
@ -2121,11 +2105,11 @@ g_ir_node_build_typelib (GIrNode *node,
if (object->get_value_func) if (object->get_value_func)
blob->get_value_func = write_string (object->get_value_func, strings, data, offset2); blob->get_value_func = write_string (object->get_value_func, strings, data, offset2);
if (object->parent) if (object->parent)
blob->parent = find_entry (module, modules, object->parent); blob->parent = find_entry (build, object->parent);
else else
blob->parent = 0; blob->parent = 0;
if (object->glib_type_struct) if (object->glib_type_struct)
blob->gtype_struct = find_entry (module, modules, object->glib_type_struct); blob->gtype_struct = find_entry (build, object->glib_type_struct);
else else
blob->gtype_struct = 0; blob->gtype_struct = 0;
@ -2141,7 +2125,7 @@ g_ir_node_build_typelib (GIrNode *node,
for (l = object->interfaces; l; l = l->next) for (l = object->interfaces; l; l = l->next)
{ {
blob->n_interfaces++; blob->n_interfaces++;
*(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data);
*offset += 2; *offset += 2;
} }
@ -2190,7 +2174,7 @@ g_ir_node_build_typelib (GIrNode *node,
blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2); blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2); blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
if (iface->glib_type_struct) if (iface->glib_type_struct)
blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct); blob->gtype_struct = find_entry (build, iface->glib_type_struct);
else else
blob->gtype_struct = 0; blob->gtype_struct = 0;
blob->n_prerequisites = 0; blob->n_prerequisites = 0;
@ -2204,7 +2188,7 @@ g_ir_node_build_typelib (GIrNode *node,
for (l = iface->prerequisites; l; l = l->next) for (l = iface->prerequisites; l; l = l->next)
{ {
blob->n_prerequisites++; blob->n_prerequisites++;
*(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data);
*offset += 2; *offset += 2;
} }
@ -2261,7 +2245,7 @@ g_ir_node_build_typelib (GIrNode *node,
blob->reserved = 0; blob->reserved = 0;
blob->name = write_string (node->name, strings, data, offset2); blob->name = write_string (node->name, strings, data, offset2);
blob->get_quark = write_string (domain->getquark, strings, data, offset2); blob->get_quark = write_string (domain->getquark, strings, data, offset2);
blob->error_codes = find_entry (module, modules, domain->codes); blob->error_codes = find_entry (build, domain->codes);
blob->reserved2 = 0; blob->reserved2 = 0;
} }
break; break;
@ -2352,6 +2336,9 @@ g_ir_node_build_typelib (GIrNode *node,
if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node)) if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node))
g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d", g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
*offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node)); *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node));
if (appended_stack)
build->stack = g_list_delete_link (build->stack, build->stack);
} }
/* if str is already in the pool, return previous location, otherwise write str /* if str is already in the pool, return previous location, otherwise write str

View File

@ -27,7 +27,6 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef struct _GIrTypelibBuild GIrTypelibBuild;
typedef struct _GIrNode GIrNode; typedef struct _GIrNode GIrNode;
typedef struct _GIrNodeFunction GIrNodeFunction; typedef struct _GIrNodeFunction GIrNodeFunction;
typedef struct _GIrNodeParam GIrNodeParam; typedef struct _GIrNodeParam GIrNodeParam;
@ -46,16 +45,6 @@ typedef struct _GIrNodeErrorDomain GIrNodeErrorDomain;
typedef struct _GIrNodeXRef GIrNodeXRef; typedef struct _GIrNodeXRef GIrNodeXRef;
typedef struct _GIrNodeUnion GIrNodeUnion; typedef struct _GIrNodeUnion GIrNodeUnion;
struct _GIrTypelibBuild {
GIrModule *module;
GList *modules;
GHashTable *strings;
GHashTable *types;
GList *nodes_with_attributes;
guint32 n_attributes;
guchar *data;
};
typedef enum typedef enum
{ {
G_IR_NODE_INVALID = 0, G_IR_NODE_INVALID = 0,
@ -84,6 +73,7 @@ struct _GIrNode
{ {
GIrNodeTypeId type; GIrNodeTypeId type;
gchar *name; gchar *name;
GIrModule *module;
guint32 offset; /* Assigned as we build the typelib */ guint32 offset; /* Assigned as we build the typelib */
@ -364,7 +354,8 @@ struct _GIrNodeErrorDomain
}; };
GIrNode * g_ir_node_new (GIrNodeTypeId type); GIrNode * g_ir_node_new (GIrNodeTypeId type,
GIrModule *module);
void g_ir_node_free (GIrNode *node); void g_ir_node_free (GIrNode *node);
guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node);
guint32 g_ir_node_get_full_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node);
@ -386,17 +377,14 @@ guint32 write_string (const gchar *str,
const gchar * g_ir_node_param_direction_string (GIrNodeParam * node); const gchar * g_ir_node_param_direction_string (GIrNodeParam * node);
const gchar * g_ir_node_type_to_string (GIrNodeTypeId type); const gchar * g_ir_node_type_to_string (GIrNodeTypeId type);
gboolean g_ir_find_node (GIrModule *module, GIrNode *g_ir_find_node (GIrTypelibBuild *build,
GList *modules, GIrModule *module,
const char *name, const char *name);
GIrNode **node_out,
GIrModule **module_out);
/* In giroffsets.c */ /* In giroffsets.c */
void g_ir_node_compute_offsets (GIrNode *node, void g_ir_node_compute_offsets (GIrTypelibBuild *build,
GIrModule *module, GIrNode *node);
GList *modules);
G_END_DECLS G_END_DECLS

View File

@ -20,6 +20,7 @@
#include "girepository-private.h" #include "girepository-private.h"
#include "girnode.h" #include "girnode.h"
#include <string.h>
/* The C standard specifies that an enumeration can be any char or any signed /* The C standard specifies that an enumeration can be any char or any signed
* or unsigned integer type capable of resresenting all the values of the * or unsigned integer type capable of resresenting all the values of the
@ -144,26 +145,24 @@ get_enum_size_alignment (GIrNodeEnum *enum_node,
} }
static gboolean static gboolean
get_interface_size_alignment (GIrNodeType *type, get_interface_size_alignment (GIrTypelibBuild *build,
GIrModule *module, GIrNodeType *type,
GList *modules,
gint *size, gint *size,
gint *alignment, gint *alignment,
const char *who) const char *who)
{ {
GIrNode *iface; GIrNode *iface;
GIrModule *iface_module;
if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module)) iface = g_ir_find_node (build, ((GIrNode*)type)->module, type->interface);
if (!iface)
{ {
g_ir_module_fatal (module, 0, "Can't resolve type '%s' for %s", type->interface, who); g_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->interface, who);
*size = -1; *size = -1;
*alignment = -1; *alignment = -1;
return FALSE; return FALSE;
} }
g_ir_node_compute_offsets (iface, iface_module, g_ir_node_compute_offsets (build, iface);
iface_module == module ? modules : NULL);
switch (iface->type) switch (iface->type)
{ {
@ -223,9 +222,8 @@ get_interface_size_alignment (GIrNodeType *type,
} }
static gboolean static gboolean
get_type_size_alignment (GIrNodeType *type, get_type_size_alignment (GIrTypelibBuild *build,
GIrModule *module, GIrNodeType *type,
GList *modules,
gint *size, gint *size,
gint *alignment, gint *alignment,
const char *who) const char *who)
@ -241,7 +239,7 @@ get_type_size_alignment (GIrNodeType *type,
gint elt_size, elt_alignment; gint elt_size, elt_alignment;
if (!type->has_size if (!type->has_size
|| !get_type_size_alignment(type->parameter_type1, module, modules, || !get_type_size_alignment(build, type->parameter_type1,
&elt_size, &elt_alignment, who)) &elt_size, &elt_alignment, who))
{ {
*size = -1; *size = -1;
@ -258,7 +256,7 @@ get_type_size_alignment (GIrNodeType *type,
{ {
if (type->tag == GI_TYPE_TAG_INTERFACE) if (type->tag == GI_TYPE_TAG_INTERFACE)
{ {
return get_interface_size_alignment (type, module, modules, size, alignment, who); return get_interface_size_alignment (build, type, size, alignment, who);
} }
else else
{ {
@ -291,13 +289,13 @@ get_type_size_alignment (GIrNodeType *type,
} }
static gboolean static gboolean
get_field_size_alignment (GIrNodeField *field, get_field_size_alignment (GIrTypelibBuild *build,
GIrNodeField *field,
GIrNode *parent_node, GIrNode *parent_node,
GIrModule *module,
GList *modules,
gint *size, gint *size,
gint *alignment) gint *alignment)
{ {
GIrModule *module = build->module;
gchar *who; gchar *who;
gboolean success; gboolean success;
@ -310,7 +308,7 @@ get_field_size_alignment (GIrNodeField *field,
success = TRUE; success = TRUE;
} }
else else
success = get_type_size_alignment (field->type, module, modules, size, alignment, who); success = get_type_size_alignment (build, field->type, size, alignment, who);
g_free (who); g_free (who);
return success; return success;
@ -319,10 +317,9 @@ get_field_size_alignment (GIrNodeField *field,
#define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) #define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1))
static gboolean static gboolean
compute_struct_field_offsets (GIrNode *node, compute_struct_field_offsets (GIrTypelibBuild *build,
GIrNode *node,
GList *members, GList *members,
GIrModule *module,
GList *modules,
gint *size_out, gint *size_out,
gint *alignment_out) gint *alignment_out)
{ {
@ -346,8 +343,7 @@ compute_struct_field_offsets (GIrNode *node,
int member_size; int member_size;
int member_alignment; int member_alignment;
if (get_field_size_alignment (field, node, if (get_field_size_alignment (build, field, node,
module, modules,
&member_size, &member_alignment)) &member_size, &member_alignment))
{ {
size = ALIGN (size, member_alignment); size = ALIGN (size, member_alignment);
@ -388,10 +384,9 @@ compute_struct_field_offsets (GIrNode *node,
} }
static gboolean static gboolean
compute_union_field_offsets (GIrNode *node, compute_union_field_offsets (GIrTypelibBuild *build,
GIrNode *node,
GList *members, GList *members,
GIrModule *module,
GList *modules,
gint *size_out, gint *size_out,
gint *alignment_out) gint *alignment_out)
{ {
@ -415,8 +410,7 @@ compute_union_field_offsets (GIrNode *node,
int member_size; int member_size;
int member_alignment; int member_alignment;
if (get_field_size_alignment (field, node, if (get_field_size_alignment (build,field, node,
module, modules,
&member_size, &member_alignment)) &member_size, &member_alignment))
{ {
size = MAX (size, member_size); size = MAX (size, member_size);
@ -446,10 +440,11 @@ compute_union_field_offsets (GIrNode *node,
} }
static gboolean static gboolean
check_needs_computation (GIrNode *node, check_needs_computation (GIrTypelibBuild *build,
GIrModule *module, GIrNode *node,
gint alignment) gint alignment)
{ {
GIrModule *module = build->module;
/* /*
* 0: Not yet computed * 0: Not yet computed
* >0: Previously succeeded * >0: Previously succeeded
@ -467,30 +462,36 @@ check_needs_computation (GIrNode *node,
/** /**
* g_ir_node_compute_offsets: * g_ir_node_compute_offsets:
* @build: Current typelib build
* @node: a #GIrNode * @node: a #GIrNode
* @module: Current module being processed
* @modules: all currently loaded modules
* *
* If a node is a a structure or union, makes sure that the field * If a node is a a structure or union, makes sure that the field
* offsets have been computed, and also computes the overall size and * offsets have been computed, and also computes the overall size and
* alignment for the type. * alignment for the type.
*/ */
void void
g_ir_node_compute_offsets (GIrNode *node, g_ir_node_compute_offsets (GIrTypelibBuild *build,
GIrModule *module, GIrNode *node)
GList *modules)
{ {
gboolean appended_stack;
if (build->stack)
appended_stack = node != (GIrNode*)build->stack->data;
else
appended_stack = TRUE;
if (appended_stack)
build->stack = g_list_prepend (build->stack, node);
switch (node->type) switch (node->type)
{ {
case G_IR_NODE_BOXED: case G_IR_NODE_BOXED:
{ {
GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
if (!check_needs_computation (node, module, boxed->alignment)) if (!check_needs_computation (build, node, boxed->alignment))
return; return;
compute_struct_field_offsets (node, boxed->members, compute_struct_field_offsets (build, node, boxed->members,
module, modules,
&boxed->size, &boxed->alignment); &boxed->size, &boxed->alignment);
break; break;
} }
@ -498,11 +499,10 @@ g_ir_node_compute_offsets (GIrNode *node,
{ {
GIrNodeStruct *struct_ = (GIrNodeStruct *)node; GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
if (!check_needs_computation (node, module, struct_->alignment)) if (!check_needs_computation (build, node, struct_->alignment))
return; return;
compute_struct_field_offsets (node, struct_->members, compute_struct_field_offsets (build, node, struct_->members,
module, modules,
&struct_->size, &struct_->alignment); &struct_->size, &struct_->alignment);
break; break;
} }
@ -511,11 +511,10 @@ g_ir_node_compute_offsets (GIrNode *node,
{ {
GIrNodeInterface *iface = (GIrNodeInterface *)node; GIrNodeInterface *iface = (GIrNodeInterface *)node;
if (!check_needs_computation (node, module, iface->alignment)) if (!check_needs_computation (build, node, iface->alignment))
return; return;
compute_struct_field_offsets (node, iface->members, compute_struct_field_offsets (build, node, iface->members,
module, modules,
&iface->size, &iface->alignment); &iface->size, &iface->alignment);
break; break;
} }
@ -523,11 +522,10 @@ g_ir_node_compute_offsets (GIrNode *node,
{ {
GIrNodeUnion *union_ = (GIrNodeUnion *)node; GIrNodeUnion *union_ = (GIrNodeUnion *)node;
if (!check_needs_computation (node, module, union_->alignment)) if (!check_needs_computation (build, node, union_->alignment))
return; return;
compute_union_field_offsets (node, union_->members, compute_union_field_offsets (build, (GIrNode*)union_, union_->members,
module, modules,
&union_->size, &union_->alignment); &union_->size, &union_->alignment);
break; break;
} }
@ -544,7 +542,9 @@ g_ir_node_compute_offsets (GIrNode *node,
break; break;
} }
default: default:
/* Nothing to do */ break;
return;
} }
if (appended_stack)
build->stack = g_list_delete_link (build->stack, build->stack);
} }

View File

@ -324,7 +324,8 @@ push_node (ParseContext *ctx, GIrNode *node)
ctx->node_stack = g_slist_prepend (ctx->node_stack, node); ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
} }
static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib, static GIrNodeType * parse_type_internal (GIrModule *module,
const gchar *str, gchar **next, gboolean in_glib,
gboolean in_gobject); gboolean in_gobject);
typedef struct { typedef struct {
@ -423,14 +424,15 @@ parse_basic (const char *str)
} }
static GIrNodeType * static GIrNodeType *
parse_type_internal (const gchar *str, char **next, gboolean in_glib, parse_type_internal (GIrModule *module,
const gchar *str, char **next, gboolean in_glib,
gboolean in_gobject) gboolean in_gobject)
{ {
const BasicTypeInfo *basic; const BasicTypeInfo *basic;
GIrNodeType *type; GIrNodeType *type;
char *temporary_type = NULL; char *temporary_type = NULL;
type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE, module);
type->unparsed = g_strdup (str); type->unparsed = g_strdup (str);
@ -644,7 +646,7 @@ parse_type (ParseContext *ctx, const gchar *type)
if (basic == NULL) if (basic == NULL)
type = resolve_aliases (ctx, type); type = resolve_aliases (ctx, type);
node = parse_type_internal (type, NULL, in_glib, in_gobject); node = parse_type_internal (ctx->current_module, type, NULL, in_glib, in_gobject);
if (node) if (node)
g_debug ("Parsed type: %s => %d", type, node->tag); g_debug ("Parsed type: %s => %d", type, node->tag);
else else
@ -721,7 +723,8 @@ start_glib_boxed (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED); boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED,
ctx->current_module);
((GIrNode *)boxed)->name = g_strdup (name); ((GIrNode *)boxed)->name = g_strdup (name);
boxed->gtype_name = g_strdup (typename); boxed->gtype_name = g_strdup (typename);
@ -804,7 +807,8 @@ start_function (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION); function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION,
ctx->current_module);
((GIrNode *)function)->name = g_strdup (name); ((GIrNode *)function)->name = g_strdup (name);
function->symbol = g_strdup (symbol); function->symbol = g_strdup (symbol);
@ -1005,7 +1009,8 @@ start_parameter (GMarkupParseContext *context,
if (name == NULL) if (name == NULL)
name = "unknown"; name = "unknown";
param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM,
ctx->current_module);
ctx->current_typed = (GIrNode*) param; ctx->current_typed = (GIrNode*) param;
ctx->current_typed->name = g_strdup (name); ctx->current_typed->name = g_strdup (name);
@ -1141,7 +1146,8 @@ start_field (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD); field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD,
ctx->current_module);
ctx->current_typed = (GIrNode*) field; ctx->current_typed = (GIrNode*) field;
((GIrNode *)field)->name = g_strdup (name); ((GIrNode *)field)->name = g_strdup (name);
/* Fields are assumed to be read-only. /* Fields are assumed to be read-only.
@ -1203,7 +1209,8 @@ start_field (GMarkupParseContext *context,
{ {
GIrNodeConstant *constant; GIrNodeConstant *constant;
constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT,
ctx->current_module);
((GIrNode *)constant)->name = g_strdup (name); ((GIrNode *)constant)->name = g_strdup (name);
constant->value = g_strdup (branch); constant->value = g_strdup (branch);
constant->type = union_->discriminator_type; constant->type = union_->discriminator_type;
@ -1298,9 +1305,11 @@ start_enum (GMarkupParseContext *context,
} }
if (strcmp (element_name, "enumeration") == 0) if (strcmp (element_name, "enumeration") == 0)
enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM,
ctx->current_module);
else else
enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS,
ctx->current_module);
((GIrNode *)enum_)->name = g_strdup (name); ((GIrNode *)enum_)->name = g_strdup (name);
enum_->gtype_name = g_strdup (typename); enum_->gtype_name = g_strdup (typename);
enum_->gtype_init = g_strdup (typeinit); enum_->gtype_init = g_strdup (typeinit);
@ -1363,7 +1372,8 @@ start_property (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY,
ctx->current_module);
ctx->current_typed = (GIrNode*) property; ctx->current_typed = (GIrNode*) property;
((GIrNode *)property)->name = g_strdup (name); ((GIrNode *)property)->name = g_strdup (name);
@ -1445,7 +1455,8 @@ start_member (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE,
ctx->current_module);
((GIrNode *)value_)->name = g_strdup (name); ((GIrNode *)value_)->name = g_strdup (name);
@ -1518,7 +1529,8 @@ start_constant (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT,
ctx->current_module);
((GIrNode *)constant)->name = g_strdup (name); ((GIrNode *)constant)->name = g_strdup (name);
constant->value = g_strdup (value); constant->value = g_strdup (value);
@ -1590,7 +1602,8 @@ start_errordomain (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN,
ctx->current_module);
((GIrNode *)domain)->name = g_strdup (name); ((GIrNode *)domain)->name = g_strdup (name);
domain->getquark = g_strdup (getquark); domain->getquark = g_strdup (getquark);
@ -1652,7 +1665,8 @@ start_interface (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE,
ctx->current_module);
((GIrNode *)iface)->name = g_strdup (name); ((GIrNode *)iface)->name = g_strdup (name);
iface->gtype_name = g_strdup (typename); iface->gtype_name = g_strdup (typename);
iface->gtype_init = g_strdup (typeinit); iface->gtype_init = g_strdup (typeinit);
@ -1727,7 +1741,8 @@ start_class (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT,
ctx->current_module);
((GIrNode *)iface)->name = g_strdup (name); ((GIrNode *)iface)->name = g_strdup (name);
iface->gtype_name = g_strdup (typename); iface->gtype_name = g_strdup (typename);
iface->gtype_init = g_strdup (typeinit); iface->gtype_init = g_strdup (typeinit);
@ -1820,7 +1835,8 @@ start_type (GMarkupParseContext *context,
const char *len; const char *len;
const char *size; const char *size;
typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE,
ctx->current_module);
typenode->tag = GI_TYPE_TAG_ARRAY; typenode->tag = GI_TYPE_TAG_ARRAY;
typenode->is_pointer = TRUE; typenode->is_pointer = TRUE;
@ -1870,7 +1886,10 @@ start_type (GMarkupParseContext *context,
name = find_attribute ("name", attribute_names, attribute_values); name = find_attribute ("name", attribute_names, attribute_values);
if (name == NULL) if (name == NULL)
MISSING_ATTRIBUTE (context, error, element_name, "name"); {
MISSING_ATTRIBUTE (context, error, element_name, "name");
return FALSE;
}
pointer_depth = 0; pointer_depth = 0;
ctype = find_attribute ("c:type", attribute_names, attribute_values); ctype = find_attribute ("c:type", attribute_names, attribute_values);
@ -2097,7 +2116,8 @@ start_return_value (GMarkupParseContext *context,
ctx->state == STATE_FUNCTION)) ctx->state == STATE_FUNCTION))
return FALSE; return FALSE;
param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM,
ctx->current_module);
param->in = FALSE; param->in = FALSE;
param->out = FALSE; param->out = FALSE;
param->retval = TRUE; param->retval = TRUE;
@ -2206,7 +2226,8 @@ start_glib_signal (GMarkupParseContext *context,
MISSING_ATTRIBUTE (context, error, element_name, "name"); MISSING_ATTRIBUTE (context, error, element_name, "name");
return FALSE; return FALSE;
} }
signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL,
ctx->current_module);
((GIrNode *)signal)->name = g_strdup (name); ((GIrNode *)signal)->name = g_strdup (name);
@ -2287,7 +2308,8 @@ start_vfunc (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC,
ctx->current_module);
((GIrNode *)vfunc)->name = g_strdup (name); ((GIrNode *)vfunc)->name = g_strdup (name);
@ -2383,7 +2405,8 @@ start_struct (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT,
ctx->current_module);
((GIrNode *)struct_)->name = g_strdup (name ? name : ""); ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
if (deprecated) if (deprecated)
@ -2443,7 +2466,8 @@ start_union (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION,
ctx->current_module);
((GIrNode *)union_)->name = g_strdup (name ? name : ""); ((GIrNode *)union_)->name = g_strdup (name ? name : "");
union_->gtype_name = g_strdup (typename); union_->gtype_name = g_strdup (typename);
@ -2505,7 +2529,7 @@ parse_include (GMarkupParseContext *context,
gchar *buffer; gchar *buffer;
gsize length; gsize length;
gchar *girpath, *girname; gchar *girpath, *girname;
GList *modules; GIrModule *module;
GList *l; GList *l;
for (l = ctx->parser->parsed_modules; l; l = l->next) for (l = ctx->parser->parsed_modules; l; l = l->next)
@ -2541,7 +2565,7 @@ parse_include (GMarkupParseContext *context,
} }
g_free (girname); g_free (girname);
g_debug ("Parsing include %s", girpath); g_debug ("Parsing include %s\n", girpath);
if (!g_file_get_contents (girpath, &buffer, &length, &error)) if (!g_file_get_contents (girpath, &buffer, &length, &error))
{ {
@ -2551,7 +2575,7 @@ parse_include (GMarkupParseContext *context,
return FALSE; return FALSE;
} }
modules = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); module = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error);
g_free (buffer); g_free (buffer);
if (error != NULL) if (error != NULL)
{ {
@ -2564,8 +2588,8 @@ parse_include (GMarkupParseContext *context,
} }
g_free (girpath); g_free (girpath);
ctx->include_modules = g_list_concat (ctx->include_modules, ctx->include_modules = g_list_append (ctx->include_modules,
modules); module);
return TRUE; return TRUE;
} }
@ -3357,10 +3381,9 @@ cleanup (GMarkupParseContext *context,
* Parse a string that holds a complete GIR XML file, and return a list of a * Parse a string that holds a complete GIR XML file, and return a list of a
* a #GirModule for each &lt;namespace/&gt; element within the file. * a #GirModule for each &lt;namespace/&gt; element within the file.
* *
* Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves * Returns: (transfer none): a new #GirModule
* are owned by the #GIrParser and will be freed along with the parser.
*/ */
GList * GIrModule *
g_ir_parser_parse_string (GIrParser *parser, g_ir_parser_parse_string (GIrParser *parser,
const gchar *namespace, const gchar *namespace,
const gchar *filename, const gchar *filename,
@ -3418,7 +3441,7 @@ g_ir_parser_parse_string (GIrParser *parser,
g_markup_parse_context_free (context); g_markup_parse_context_free (context);
return ctx.modules; return ctx.modules->data;
} }
/** /**
@ -3433,14 +3456,14 @@ g_ir_parser_parse_string (GIrParser *parser,
* Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves
* are owned by the #GIrParser and will be freed along with the parser. * are owned by the #GIrParser and will be freed along with the parser.
*/ */
GList * GIrModule *
g_ir_parser_parse_file (GIrParser *parser, g_ir_parser_parse_file (GIrParser *parser,
const gchar *filename, const gchar *filename,
GError **error) GError **error)
{ {
gchar *buffer; gchar *buffer;
gsize length; gsize length;
GList *modules; GIrModule *module;
const char *slash; const char *slash;
char *dash; char *dash;
char *namespace; char *namespace;
@ -3471,13 +3494,13 @@ g_ir_parser_parse_file (GIrParser *parser,
if (!g_file_get_contents (filename, &buffer, &length, error)) if (!g_file_get_contents (filename, &buffer, &length, error))
return NULL; return NULL;
modules = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); module = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error);
g_free (namespace); g_free (namespace);
g_free (buffer); g_free (buffer);
return modules; return module;
} }

View File

@ -25,6 +25,8 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#include "girmodule.h"
typedef struct _GIrParser GIrParser; typedef struct _GIrParser GIrParser;
GIrParser *g_ir_parser_new (void); GIrParser *g_ir_parser_new (void);
@ -32,15 +34,15 @@ void g_ir_parser_free (GIrParser *parser);
void g_ir_parser_set_includes (GIrParser *parser, void g_ir_parser_set_includes (GIrParser *parser,
const gchar *const *includes); const gchar *const *includes);
GList *g_ir_parser_parse_string (GIrParser *parser, GIrModule *g_ir_parser_parse_string (GIrParser *parser,
const gchar *namespace, const gchar *namespace,
const gchar *filename, const gchar *filename,
const gchar *buffer, const gchar *buffer,
gssize length, gssize length,
GError **error); GError **error);
GList *g_ir_parser_parse_file (GIrParser *parser, GIrModule *g_ir_parser_parse_file (GIrParser *parser,
const gchar *filename, const gchar *filename,
GError **error); GError **error);
G_END_DECLS G_END_DECLS