mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-30 20:33:08 +02:00
Expand aliases when generating typelibs
* gir/Makefile.am: Use --includedir * girepository/girparser.c: Recursively parse includes to pull in aliases and expand them. We need this to avoid putting unknown names in the typelibs. * tools/compiler.c: Add --includedir option. svn path=/trunk/; revision=512
This commit is contained in:
parent
fc1efcef59
commit
7fd9cd094d
225
girparser.c
225
girparser.c
@ -68,15 +68,94 @@ struct _ParseContext
|
|||||||
ParseState state;
|
ParseState state;
|
||||||
ParseState prev_state;
|
ParseState prev_state;
|
||||||
|
|
||||||
|
const char **includes;
|
||||||
|
|
||||||
GList *modules;
|
GList *modules;
|
||||||
|
gboolean prefix_aliases;
|
||||||
GHashTable *aliases;
|
GHashTable *aliases;
|
||||||
|
|
||||||
|
const char *namespace;
|
||||||
GIrModule *current_module;
|
GIrModule *current_module;
|
||||||
GIrNode *current_node;
|
GIrNode *current_node;
|
||||||
GIrNode *current_typed;
|
GIrNode *current_typed;
|
||||||
int type_depth;
|
int type_depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
start_alias (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
const gchar **attribute_names,
|
||||||
|
const gchar **attribute_values,
|
||||||
|
ParseContext *ctx,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
static void
|
||||||
|
firstpass_start_element_handler (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
const gchar **attribute_names,
|
||||||
|
const gchar **attribute_values,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
ParseContext *ctx = user_data;
|
||||||
|
|
||||||
|
if (strcmp (element_name, "alias") == 0)
|
||||||
|
{
|
||||||
|
start_alias (context, element_name, attribute_names, attribute_values,
|
||||||
|
ctx, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
firstpass_end_element_handler (GMarkupParseContext *context,
|
||||||
|
const gchar *element_name,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
ParseContext *ctx = user_data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static GMarkupParser firstpass_parser =
|
||||||
|
{
|
||||||
|
firstpass_start_element_handler,
|
||||||
|
firstpass_end_element_handler,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *
|
||||||
|
locate_gir (const char *name, const char **extra_paths)
|
||||||
|
{
|
||||||
|
const gchar *const *datadirs;
|
||||||
|
const gchar *const *dir;
|
||||||
|
char *girname;
|
||||||
|
char *path = NULL;
|
||||||
|
GSList *link;
|
||||||
|
gboolean firstpass = TRUE;
|
||||||
|
|
||||||
|
datadirs = g_get_system_data_dirs ();
|
||||||
|
|
||||||
|
girname = g_strdup_printf ("%s.gir", name);
|
||||||
|
|
||||||
|
for (dir = datadirs; *dir; dir++)
|
||||||
|
{
|
||||||
|
path = g_build_filename (*dir, "gir", girname, NULL);
|
||||||
|
if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
path = NULL;
|
||||||
|
if (firstpass && !*dir)
|
||||||
|
{
|
||||||
|
firstpass = FALSE;
|
||||||
|
dir = extra_paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free (girname);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
#define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
|
#define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
|
||||||
do { \
|
do { \
|
||||||
int line_number, char_number; \
|
int line_number, char_number; \
|
||||||
@ -946,6 +1025,8 @@ start_alias (GMarkupParseContext *context,
|
|||||||
const gchar *name;
|
const gchar *name;
|
||||||
const gchar *target;
|
const gchar *target;
|
||||||
const gchar *type;
|
const gchar *type;
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
|
||||||
name = find_attribute ("name", attribute_names, attribute_values);
|
name = find_attribute ("name", attribute_names, attribute_values);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
@ -961,7 +1042,12 @@ start_alias (GMarkupParseContext *context,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (ctx->aliases, g_strdup (name), g_strdup (target));
|
if (ctx->prefix_aliases)
|
||||||
|
key = g_strdup_printf ("%s.%s", ctx->namespace, name);
|
||||||
|
else
|
||||||
|
key = g_strdup (name);
|
||||||
|
|
||||||
|
g_hash_table_insert (ctx->aliases, key, g_strdup (target));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1847,6 +1933,63 @@ start_discriminator (GMarkupParseContext *context,
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_include (GMarkupParseContext *context,
|
||||||
|
ParseContext *ctx,
|
||||||
|
const char *name,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
ParseContext sub_ctx = { 0 };
|
||||||
|
GMarkupParseContext *sub_context;
|
||||||
|
gchar *buffer;
|
||||||
|
gsize length;
|
||||||
|
char *girpath;
|
||||||
|
|
||||||
|
girpath = locate_gir (name, ctx->includes);
|
||||||
|
|
||||||
|
if (girpath == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
|
"Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir",
|
||||||
|
name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("Parsing include %s", girpath);
|
||||||
|
|
||||||
|
if (!g_file_get_contents (girpath, &buffer, &length, error))
|
||||||
|
{
|
||||||
|
g_free (girpath);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
g_free (girpath);
|
||||||
|
|
||||||
|
sub_ctx.state = STATE_START;
|
||||||
|
sub_ctx.prefix_aliases = TRUE;
|
||||||
|
sub_ctx.namespace = name;
|
||||||
|
sub_ctx.aliases = ctx->aliases;
|
||||||
|
sub_ctx.type_depth = 0;
|
||||||
|
|
||||||
|
context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
|
||||||
|
|
||||||
|
if (!g_markup_parse_context_parse (context, buffer, length, error))
|
||||||
|
{
|
||||||
|
g_free (buffer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_markup_parse_context_end_parse (context, error))
|
||||||
|
{
|
||||||
|
g_free (buffer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_markup_parse_context_free (context);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
extern GLogLevelFlags logged_levels;
|
extern GLogLevelFlags logged_levels;
|
||||||
|
|
||||||
@ -1972,6 +2115,19 @@ start_element_handler (GMarkupParseContext *context,
|
|||||||
if (strcmp (element_name, "include") == 0 &&
|
if (strcmp (element_name, "include") == 0 &&
|
||||||
ctx->state == STATE_REPOSITORY)
|
ctx->state == STATE_REPOSITORY)
|
||||||
{
|
{
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
name = find_attribute ("name", attribute_names, attribute_values);
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
{
|
||||||
|
MISSING_ATTRIBUTE (context, error, element_name, "name");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_include (context, ctx, name, error))
|
||||||
|
break;
|
||||||
|
|
||||||
state_switch (ctx, STATE_INCLUDE);
|
state_switch (ctx, STATE_INCLUDE);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -2464,44 +2620,6 @@ cleanup (GMarkupParseContext *context,
|
|||||||
ctx->current_module = NULL;
|
ctx->current_module = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
firstpass_start_element_handler (GMarkupParseContext *context,
|
|
||||||
const gchar *element_name,
|
|
||||||
const gchar **attribute_names,
|
|
||||||
const gchar **attribute_values,
|
|
||||||
gpointer user_data,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
ParseContext *ctx = user_data;
|
|
||||||
|
|
||||||
if (strcmp (element_name, "alias") == 0)
|
|
||||||
{
|
|
||||||
start_alias (context, element_name, attribute_names, attribute_values,
|
|
||||||
ctx, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
firstpass_end_element_handler (GMarkupParseContext *context,
|
|
||||||
const gchar *element_name,
|
|
||||||
gpointer user_data,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
ParseContext *ctx = user_data;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static GMarkupParser firstpass_parser =
|
|
||||||
{
|
|
||||||
firstpass_start_element_handler,
|
|
||||||
firstpass_end_element_handler,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static GMarkupParser parser =
|
static GMarkupParser parser =
|
||||||
{
|
{
|
||||||
start_element_handler,
|
start_element_handler,
|
||||||
@ -2512,7 +2630,8 @@ static GMarkupParser parser =
|
|||||||
};
|
};
|
||||||
|
|
||||||
GList *
|
GList *
|
||||||
g_ir_parse_string (const gchar *buffer,
|
g_ir_parse_string (const char *namespace,
|
||||||
|
const gchar *buffer,
|
||||||
gssize length,
|
gssize length,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -2520,6 +2639,8 @@ g_ir_parse_string (const gchar *buffer,
|
|||||||
GMarkupParseContext *context;
|
GMarkupParseContext *context;
|
||||||
|
|
||||||
ctx.state = STATE_START;
|
ctx.state = STATE_START;
|
||||||
|
ctx.prefix_aliases = FALSE;
|
||||||
|
ctx.namespace = namespace;
|
||||||
ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
ctx.type_depth = 0;
|
ctx.type_depth = 0;
|
||||||
|
|
||||||
@ -2530,6 +2651,8 @@ g_ir_parse_string (const gchar *buffer,
|
|||||||
|
|
||||||
if (!g_markup_parse_context_end_parse (context, error))
|
if (!g_markup_parse_context_end_parse (context, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
g_markup_parse_context_free (context);
|
||||||
|
|
||||||
context = g_markup_parse_context_new (&parser, 0, &ctx, NULL);
|
context = g_markup_parse_context_new (&parser, 0, &ctx, NULL);
|
||||||
if (!g_markup_parse_context_parse (context, buffer, length, error))
|
if (!g_markup_parse_context_parse (context, buffer, length, error))
|
||||||
@ -2554,13 +2677,33 @@ g_ir_parse_file (const gchar *filename,
|
|||||||
gchar *buffer;
|
gchar *buffer;
|
||||||
gsize length;
|
gsize length;
|
||||||
GList *modules;
|
GList *modules;
|
||||||
|
const char *slash;
|
||||||
|
char *namespace;
|
||||||
|
|
||||||
|
if (!g_str_has_suffix (filename, ".gir"))
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
|
"Expected filename to end with '.gir'");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_debug ("[parsing] filename %s", filename);
|
g_debug ("[parsing] filename %s", filename);
|
||||||
|
|
||||||
|
slash = g_strrstr (filename, "/");
|
||||||
|
if (!slash)
|
||||||
|
namespace = g_strdup (filename);
|
||||||
|
else
|
||||||
|
namespace = g_strdup (slash+1);
|
||||||
|
namespace[strlen(namespace)-4] = '\0';
|
||||||
|
|
||||||
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_parse_string (buffer, length, error);
|
modules = g_ir_parse_string (namespace, buffer, length, error);
|
||||||
|
|
||||||
|
g_free (namespace);
|
||||||
|
|
||||||
g_free (buffer);
|
g_free (buffer);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user