mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 22:46:15 +01:00
Bug 560250 - Fully parse included modules
For some things, like computing structure offsets to put into the typelib we need more than just the aliases from included modules. Do a completel parse of included modules and store in module->included_modules. Also add g_ir_find_node() to find node information from within the active set of modules and their includes. svn path=/trunk/; revision=874
This commit is contained in:
parent
d041deae59
commit
6d9212674a
@ -62,6 +62,10 @@ g_ir_module_free (GIrModule *module)
|
|||||||
g_list_free (module->entries);
|
g_list_free (module->entries);
|
||||||
/* Don't free dependencies, we inherit that from the parser */
|
/* Don't free dependencies, we inherit that from the parser */
|
||||||
|
|
||||||
|
/* FIXME: we leak the included modules themelves; they may be shared
|
||||||
|
* between multiple modules, so we would need refcounting */
|
||||||
|
g_list_free (module->include_modules);
|
||||||
|
|
||||||
g_free (module);
|
g_free (module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ struct _GIrModule
|
|||||||
gchar *shared_library;
|
gchar *shared_library;
|
||||||
GList *dependencies;
|
GList *dependencies;
|
||||||
GList *entries;
|
GList *entries;
|
||||||
|
GList *include_modules;
|
||||||
};
|
};
|
||||||
|
|
||||||
GIrModule *g_ir_module_new (const gchar *name,
|
GIrModule *g_ir_module_new (const gchar *name,
|
||||||
|
86
girnode.c
86
girnode.c
@ -1070,6 +1070,92 @@ find_entry (GIrModule *module,
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GIrNode *
|
||||||
|
find_name_in_module (GIrModule *module,
|
||||||
|
const gchar *name)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = module->entries; l; l = l->next)
|
||||||
|
{
|
||||||
|
GIrNode *node = (GIrNode *)l->data;
|
||||||
|
|
||||||
|
if (strcmp (node->name, name) == 0)
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_ir_find_node (GIrModule *module,
|
||||||
|
GList *modules,
|
||||||
|
const char *name,
|
||||||
|
GIrNode **node_out,
|
||||||
|
GIrModule **module_out)
|
||||||
|
{
|
||||||
|
char **names = g_strsplit (name, ".", 0);
|
||||||
|
gint n_names = g_strv_length (names);
|
||||||
|
GIrNode *node = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
*module_out = module;
|
||||||
|
node = find_name_in_module (module, names[0]);
|
||||||
|
}
|
||||||
|
else if (strcmp (names[0], module->name) == 0)
|
||||||
|
{
|
||||||
|
*module_out = module;
|
||||||
|
node = find_name_in_module (module, names[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (l = module->include_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
*node_out = node;
|
||||||
|
|
||||||
|
return node != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
serialize_type (GIrModule *module,
|
serialize_type (GIrModule *module,
|
||||||
GList *modules,
|
GList *modules,
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "girmodule.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GIrNode GIrNode;
|
typedef struct _GIrNode GIrNode;
|
||||||
@ -340,6 +342,12 @@ 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,
|
||||||
|
GList *modules,
|
||||||
|
const char *name,
|
||||||
|
GIrNode **node_out,
|
||||||
|
GIrModule **module_out);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_IR_NODE_H__ */
|
#endif /* __G_IR_NODE_H__ */
|
||||||
|
92
girparser.c
92
girparser.c
@ -72,6 +72,7 @@ struct _ParseContext
|
|||||||
const char * const*includes;
|
const char * const*includes;
|
||||||
|
|
||||||
GList *modules;
|
GList *modules;
|
||||||
|
GList *include_modules;
|
||||||
gboolean prefix_aliases;
|
gboolean prefix_aliases;
|
||||||
GList *dependencies;
|
GList *dependencies;
|
||||||
GHashTable *aliases;
|
GHashTable *aliases;
|
||||||
@ -87,6 +88,34 @@ struct _ParseContext
|
|||||||
int type_depth;
|
int type_depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void start_element_handler (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
const gchar **attribute_names,
|
||||||
|
const gchar **attribute_values,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error);
|
||||||
|
static void end_element_handler (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error);
|
||||||
|
static void text_handler (GMarkupParseContext *context,
|
||||||
|
const gchar *text,
|
||||||
|
gsize text_len,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error);
|
||||||
|
static void cleanup (GMarkupParseContext *context,
|
||||||
|
GError *error,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
static GMarkupParser parser =
|
||||||
|
{
|
||||||
|
start_element_handler,
|
||||||
|
end_element_handler,
|
||||||
|
text_handler,
|
||||||
|
NULL,
|
||||||
|
cleanup
|
||||||
|
};
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
start_alias (GMarkupParseContext *context,
|
start_alias (GMarkupParseContext *context,
|
||||||
const gchar *element_name,
|
const gchar *element_name,
|
||||||
@ -2116,6 +2145,30 @@ parse_include (GMarkupParseContext *context,
|
|||||||
gchar *buffer;
|
gchar *buffer;
|
||||||
gsize length;
|
gsize length;
|
||||||
char *girpath;
|
char *girpath;
|
||||||
|
gboolean success = FALSE;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = ctx->include_modules; l; l = l->next)
|
||||||
|
{
|
||||||
|
GIrModule *m = l->data;
|
||||||
|
|
||||||
|
if (strcmp (m->name, name) == 0)
|
||||||
|
{
|
||||||
|
if (strcmp (m->version, version) == 0)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
|
"Module '%s' imported with conflicting versions '%s' and '%s'",
|
||||||
|
name, m->version, version);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
girpath = locate_gir (name, version, ctx->includes);
|
girpath = locate_gir (name, version, ctx->includes);
|
||||||
|
|
||||||
@ -2149,19 +2202,30 @@ parse_include (GMarkupParseContext *context,
|
|||||||
context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
|
context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
|
||||||
|
|
||||||
if (!g_markup_parse_context_parse (context, buffer, length, error))
|
if (!g_markup_parse_context_parse (context, buffer, length, error))
|
||||||
{
|
goto out;
|
||||||
g_free (buffer);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_markup_parse_context_end_parse (context, error))
|
if (!g_markup_parse_context_end_parse (context, error))
|
||||||
{
|
goto out;
|
||||||
g_free (buffer);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_markup_parse_context_free (context);
|
g_markup_parse_context_free (context);
|
||||||
return TRUE;
|
|
||||||
|
context = g_markup_parse_context_new (&parser, 0, &sub_ctx, NULL);
|
||||||
|
if (!g_markup_parse_context_parse (context, buffer, length, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!g_markup_parse_context_end_parse (context, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
success = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
ctx->include_modules = g_list_concat (ctx->include_modules,
|
||||||
|
sub_ctx.modules);
|
||||||
|
|
||||||
|
g_markup_parse_context_free (context);
|
||||||
|
g_free (buffer);
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern GLogLevelFlags logged_levels;
|
extern GLogLevelFlags logged_levels;
|
||||||
@ -2358,6 +2422,7 @@ start_element_handler (GMarkupParseContext *context,
|
|||||||
ctx->current_module = g_ir_module_new (name, version, shared_library);
|
ctx->current_module = g_ir_module_new (name, version, shared_library);
|
||||||
ctx->modules = g_list_append (ctx->modules, ctx->current_module);
|
ctx->modules = g_list_append (ctx->modules, ctx->current_module);
|
||||||
ctx->current_module->dependencies = ctx->dependencies;
|
ctx->current_module->dependencies = ctx->dependencies;
|
||||||
|
ctx->current_module->include_modules = g_list_copy (ctx->include_modules);
|
||||||
|
|
||||||
state_switch (ctx, STATE_NAMESPACE);
|
state_switch (ctx, STATE_NAMESPACE);
|
||||||
goto out;
|
goto out;
|
||||||
@ -2819,15 +2884,6 @@ cleanup (GMarkupParseContext *context,
|
|||||||
ctx->current_module = NULL;
|
ctx->current_module = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GMarkupParser parser =
|
|
||||||
{
|
|
||||||
start_element_handler,
|
|
||||||
end_element_handler,
|
|
||||||
text_handler,
|
|
||||||
NULL,
|
|
||||||
cleanup
|
|
||||||
};
|
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
post_filter_varargs_functions (GList *list)
|
post_filter_varargs_functions (GList *list)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user