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;