From 215d83ebb0a7f15b359e9e63fea2715113784ff7 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 May 2011 16:21:13 -0400 Subject: [PATCH] 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 --- gdump.c | 83 +++++++++++++++++++++++++++++++++++--------- gienuminfo.c | 17 +++++++++ gienuminfo.h | 1 + girnode.c | 7 ++++ girnode.h | 1 + girparser.c | 4 +++ girwriter.c | 4 +++ gitypelib-internal.h | 4 ++- 8 files changed, 104 insertions(+), 17 deletions(-) diff --git a/gdump.c b/gdump.c index cb6e74197..e607f3237 100644 --- a/gdump.c +++ b/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, " \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/gienuminfo.c b/gienuminfo.c index 062f3abf2..338a46ee0 100644 --- a/gienuminfo.c +++ b/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/gienuminfo.h b/gienuminfo.h index 6b24fe7ef..fc0f3c842 100644 --- a/gienuminfo.h +++ b/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/girnode.c b/girnode.c index 1c51bfd4b..166ca30a3 100644 --- a/girnode.c +++ b/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/girnode.h b/girnode.h index fb2616b1e..6e03821ba 100644 --- a/girnode.h +++ b/girnode.h @@ -285,6 +285,7 @@ struct _GIrNodeEnum gchar *gtype_name; gchar *gtype_init; + gchar *error_domain; GList *values; }; diff --git a/girparser.c b/girparser.c index 4e5527259..c9b7d6292 100644 --- a/girparser.c +++ b/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/girwriter.c b/girwriter.c index 2cdc9a11f..d9f916c55 100644 --- a/girwriter.c +++ b/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/gitypelib-internal.h b/gitypelib-internal.h index 2bda8d9d0..49fbe4e3e 100644 --- a/gitypelib-internal.h +++ b/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;