summaryrefslogtreecommitdiff
path: root/girepository
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2011-05-19 16:21:13 -0400
committerDan Winship <danw@gnome.org>2011-08-12 11:10:43 -0400
commit5fd2fa5bf5a07a66d2150740d534a398598e8dd1 (patch)
treed40cb5a96e53cd518c8a00e14855bf6196fcf03b /girepository
parent4dabe20ed5753bccd2abf8ad02e95ce6ab53036c (diff)
downloadgobject-introspection-5fd2fa5bf5a07a66d2150740d534a398598e8dd1.tar.gz
Switch to storing string form of error quarks
Instead of storing the name of the function to call to get the error quark, store the string form of the error quark, which we derive from the introspection binary during scanning. Update EnumBlob and GIEnumInfo to include the new information. This will allow determining a back-mapping from error quark to error domain without having to dlsym() and call all the known error quark functions. Based on earlier patches from Owen Taylor and Maxim Ermilov. https://bugzilla.gnome.org/show_bug.cgi?id=602516
Diffstat (limited to 'girepository')
-rw-r--r--girepository/gdump.c83
-rw-r--r--girepository/gienuminfo.c17
-rw-r--r--girepository/gienuminfo.h1
-rw-r--r--girepository/girnode.c7
-rw-r--r--girepository/girnode.h1
-rw-r--r--girepository/girparser.c4
-rw-r--r--girepository/girwriter.c4
-rw-r--r--girepository/gitypelib-internal.h4
8 files changed, 104 insertions, 17 deletions
diff --git a/girepository/gdump.c b/girepository/gdump.c
index cb6e7419..e607f323 100644
--- a/girepository/gdump.c
+++ b/girepository/gdump.c
@@ -70,6 +70,7 @@ goutput_write (GOutputStream *out, const char *str)
}
typedef GType (*GetTypeFunc)(void);
+typedef GQuark (*ErrorQuarkFunc)(void);
static GType
invoke_get_type (GModule *self, const char *symbol, GError **error)
@@ -97,6 +98,23 @@ invoke_get_type (GModule *self, const char *symbol, GError **error)
return ret;
}
+static GQuark
+invoke_error_quark (GModule *self, const char *symbol, GError **error)
+{
+ ErrorQuarkFunc sym;
+
+ if (!g_module_symbol (self, symbol, (void**)&sym))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Failed to find symbol '%s'", symbol);
+ return G_TYPE_INVALID;
+ }
+
+ return sym ();
+}
+
static void
dump_properties (GType type, GOutputStream *out)
{
@@ -365,6 +383,13 @@ dump_type (GType type, const char *symbol, GOutputStream *out)
}
}
+static void
+dump_error_quark (GQuark quark, const char *symbol, GOutputStream *out)
+{
+ escaped_printf (out, " <error-quark function=\"%s\" domain=\"%s\"/>\n",
+ symbol, g_quark_to_string (quark));
+}
+
/**
* g_irepository_dump:
* @arg: Comma-separated pair of input and output filenames
@@ -437,29 +462,55 @@ g_irepository_dump (const char *arg, GError **error)
{
gsize len;
char *line = g_data_input_stream_read_line (in, &len, NULL, NULL);
- GType type;
+ const char *function;
if (line == NULL || *line == '\0')
- {
- g_free (line);
- break;
- }
+ {
+ g_free (line);
+ break;
+ }
g_strchomp (line);
- type = invoke_get_type (self, line, error);
- if (type == G_TYPE_INVALID)
- {
- caught_error = TRUE;
- g_free (line);
- break;
- }
+ if (strncmp (line, "get-type:", strlen ("get-type:")) == 0)
+ {
+ GType type;
- if (g_hash_table_lookup (output_types, (gpointer) type))
- goto next;
- g_hash_table_insert (output_types, (gpointer) type, (gpointer) type);
+ function = line + strlen ("get-type:");
+
+ type = invoke_get_type (self, function, error);
+
+ if (type == G_TYPE_INVALID)
+ {
+ g_printerr ("Invalid GType function: '%s'\n", function);
+ caught_error = TRUE;
+ g_free (line);
+ break;
+ }
+
+ if (g_hash_table_lookup (output_types, (gpointer) type))
+ goto next;
+ g_hash_table_insert (output_types, (gpointer) type, (gpointer) type);
+
+ dump_type (type, function, G_OUTPUT_STREAM (output));
+ }
+ else if (strncmp (line, "error-quark:", strlen ("error-quark:")) == 0)
+ {
+ GQuark quark;
+ function = line + strlen ("error-quark:");
+ quark = invoke_error_quark (self, function, error);
+
+ if (quark == 0)
+ {
+ g_printerr ("Invalid error quark function: '%s'\n", function);
+ caught_error = TRUE;
+ g_free (line);
+ break;
+ }
+
+ dump_error_quark (quark, function, G_OUTPUT_STREAM (output));
+ }
- dump_type (type, line, G_OUTPUT_STREAM (output));
next:
g_free (line);
diff --git a/girepository/gienuminfo.c b/girepository/gienuminfo.c
index 062f3abf..338a46ee 100644
--- a/girepository/gienuminfo.c
+++ b/girepository/gienuminfo.c
@@ -66,6 +66,23 @@ g_enum_info_get_n_values (GIEnumInfo *info)
return blob->n_values;
}
+const gchar *
+g_enum_info_get_error_domain (GIEnumInfo *info)
+{
+ GIRealInfo *rinfo = (GIRealInfo *)info;
+ EnumBlob *blob;
+
+ g_return_val_if_fail (info != NULL, 0);
+ g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0);
+
+ blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
+
+ if (blob->error_domain)
+ return g_typelib_get_string (rinfo->typelib, blob->error_domain);
+ else
+ return NULL;
+}
+
/**
* g_enum_info_get_value:
* @info: a #GIEnumInfo
diff --git a/girepository/gienuminfo.h b/girepository/gienuminfo.h
index 6b24fe7e..fc0f3c84 100644
--- a/girepository/gienuminfo.h
+++ b/girepository/gienuminfo.h
@@ -41,6 +41,7 @@ gint g_enum_info_get_n_values (GIEnumInfo *info);
GIValueInfo * g_enum_info_get_value (GIEnumInfo *info,
gint n);
GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info);
+const gchar * g_enum_info_get_error_domain (GIEnumInfo *info);
gint64 g_value_info_get_value (GIValueInfo *info);
diff --git a/girepository/girnode.c b/girepository/girnode.c
index 1c51bfd4..166ca30a 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -328,6 +328,7 @@ _g_ir_node_free (GIrNode *node)
g_free (node->name);
g_free (enum_->gtype_name);
g_free (enum_->gtype_init);
+ g_free (enum_->error_domain);
for (l = enum_->values; l; l = l->next)
_g_ir_node_free ((GIrNode *)l->data);
@@ -712,6 +713,8 @@ _g_ir_node_get_full_size_internal (GIrNode *parent,
size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
}
+ if (enum_->error_domain)
+ size += ALIGN_VALUE (strlen (enum_->error_domain) + 1, 4);
for (l = enum_->values; l; l = l->next)
size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
@@ -2021,6 +2024,10 @@ _g_ir_node_build_typelib (GIrNode *node,
blob->gtype_name = 0;
blob->gtype_init = 0;
}
+ if (enum_->error_domain)
+ blob->error_domain = _g_ir_write_string (enum_->error_domain, strings, data, offset2);
+ else
+ blob->error_domain = 0;
blob->n_values = 0;
blob->reserved2 = 0;
diff --git a/girepository/girnode.h b/girepository/girnode.h
index fb2616b1..6e03821b 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -285,6 +285,7 @@ struct _GIrNodeEnum
gchar *gtype_name;
gchar *gtype_init;
+ gchar *error_domain;
GList *values;
};
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 4e552725..c9b7d629 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1332,6 +1332,7 @@ start_enum (GMarkupParseContext *context,
const gchar *typename;
const gchar *typeinit;
const gchar *deprecated;
+ const gchar *error_domain;
GIrNodeEnum *enum_;
if (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
@@ -1344,6 +1345,7 @@ start_enum (GMarkupParseContext *context,
name = find_attribute ("name", attribute_names, attribute_values);
typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
+ error_domain = find_attribute ("glib:error-domain", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
if (name == NULL)
@@ -1361,6 +1363,8 @@ start_enum (GMarkupParseContext *context,
((GIrNode *)enum_)->name = g_strdup (name);
enum_->gtype_name = g_strdup (typename);
enum_->gtype_init = g_strdup (typeinit);
+ enum_->error_domain = g_strdup (error_domain);
+
if (deprecated)
enum_->deprecated = TRUE;
else
diff --git a/girepository/girwriter.c b/girepository/girwriter.c
index 2cdc9a11..d9f916c5 100644
--- a/girepository/girwriter.c
+++ b/girepository/girwriter.c
@@ -805,6 +805,7 @@ write_enum_info (const gchar *namespace,
const gchar *name;
const gchar *type_name;
const gchar *type_init;
+ const gchar *error_domain;
gboolean deprecated;
gint i;
@@ -813,6 +814,7 @@ write_enum_info (const gchar *namespace,
type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
+ error_domain = g_enum_info_get_error_domain (info);
if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
xml_start_element (file, "enumeration");
@@ -822,6 +824,8 @@ write_enum_info (const gchar *namespace,
if (type_init)
xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
+ if (error_domain)
+ xml_printf (file, " glib:error-domain=\"%s\"", error_domain);
if (deprecated)
xml_printf (file, " deprecated=\"1\"");
diff --git a/girepository/gitypelib-internal.h b/girepository/gitypelib-internal.h
index 2bda8d9d..49fbe4e3 100644
--- a/girepository/gitypelib-internal.h
+++ b/girepository/gitypelib-internal.h
@@ -798,6 +798,8 @@ typedef struct {
* (will be a signed or unsigned integral type)
* @gtype_name: String name of the associated #GType
* @gtype_init: String naming the symbol which gets the runtime #GType
+ * @error_domain: String naming the #GError domain this enum is
+ * associated with
* @n_values: The lengths of the values arrays.
* @values: Describes the enum values.
*/
@@ -817,7 +819,7 @@ typedef struct {
guint16 n_values;
guint16 reserved2;
- guint32 reserved3;
+ guint32 error_domain;
ValueBlob values[];
} EnumBlob;