}
typedef GType (*GetTypeFunc)(void);
+typedef GQuark (*ErrorQuarkFunc)(void);
static GType
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)
{
}
}
+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
{
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);
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
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);
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);
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);
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;
gchar *gtype_name;
gchar *gtype_init;
+ gchar *error_domain;
GList *values;
};
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) ||
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)
((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
const gchar *name;
const gchar *type_name;
const gchar *type_init;
+ const gchar *error_domain;
gboolean deprecated;
gint i;
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");
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\"");
* (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.
*/
guint16 n_values;
guint16 reserved2;
- guint32 reserved3;
+ guint32 error_domain;
ValueBlob values[];
} EnumBlob;
self.shadows = None # C symbol string
+class ErrorQuarkFunction(Function):
+
+ def __init__(self, name, retval, parameters, throws, symbol, error_domain):
+ Function.__init__(self, name, retval, parameters, throws, symbol)
+ self.error_domain = error_domain
+
+
class VFunction(Callable):
def __init__(self, name, retval, parameters, throws):
self.c_symbol_prefix = c_symbol_prefix
self.ctype = ctype
self.members = members
- # Associated error quark
- self.error_quark = None
+ # Associated error domain name
+ self.error_domain = None
class Bitfield(Node, Registered):
class DumpCompiler(object):
- def __init__(self, options, get_type_functions):
+ def __init__(self, options, get_type_functions, error_quark_functions):
self._options = options
self._get_type_functions = get_type_functions
+ self._error_quark_functions = error_quark_functions
self._compiler_cmd = os.environ.get('CC', 'gcc')
self._linker_cmd = os.environ.get('CC', self._compiler_cmd)
f = open(c_path, 'w')
f.write(_PROGRAM_TEMPLATE % tpl_args)
- # We need to reference our get_type functions to make sure they are
- # pulled in at the linking stage if the library is a static library
- # rather than a shared library.
+ # We need to reference our get_type and error_quark functions
+ # to make sure they are pulled in at the linking stage if the
+ # library is a static library rather than a shared library.
if len(self._get_type_functions) > 0:
for func in self._get_type_functions:
f.write("extern GType " + func + "(void);\n")
f.write(",\n")
f.write(" " + func)
f.write("\n};\n")
+ if len(self._error_quark_functions) > 0:
+ for func in self._error_quark_functions:
+ f.write("extern GQuark " + func + "(void);\n")
+ f.write("GQuark (*GI_ERROR_QUARK_FUNCS_[])(void) = {\n")
+ first = True
+ for func in self._error_quark_functions:
+ if first:
+ first = False
+ else:
+ f.write(",\n")
+ f.write(" " + func)
+ f.write("\n};\n")
f.close()
o_path = self._generate_tempfile(tmpdir, '.o')
else:
args.append('-l' + library)
-def compile_introspection_binary(options, get_type_functions):
- dc = DumpCompiler(options, get_type_functions)
+def compile_introspection_binary(options, get_type_functions,
+ error_quark_functions):
+ dc = DumpCompiler(options, get_type_functions, error_quark_functions)
return dc.run()
self._namespace = transformer.namespace
self._binary = None
self._get_type_functions = []
- self._gtype_data = {}
+ self._error_quark_functions = []
+ self._error_domains = {}
self._boxed_types = {}
self._private_internal_types = {}
def get_get_type_functions(self):
return self._get_type_functions
+ def get_error_quark_functions(self):
+ return self._error_quark_functions
+
def set_introspection_binary(self, binary):
self._binary = binary
tree = self._execute_binary_get_tree()
root = tree.getroot()
for child in root:
- self._gtype_data[child.attrib['name']] = child
- for child in root:
- self._introspect_type(child)
+ if child.tag == 'error-quark':
+ self._introspect_error_quark(child)
+ else:
+ self._introspect_type(child)
# Pair up boxed types and class records
for name, boxed in self._boxed_types.iteritems():
def _execute_binary_get_tree(self):
"""Load the library (or executable), returning an XML
blob containing data gleaned from GObject's primitive introspection."""
- in_path = os.path.join(self._binary.tmpdir, 'types.txt')
+ in_path = os.path.join(self._binary.tmpdir, 'functions.txt')
f = open(in_path, 'w')
- # TODO: Introspect GQuark functions
for func in self._get_type_functions:
+ f.write('get-type:')
+ f.write(func)
+ f.write('\n')
+ for func in self._error_quark_functions:
+ f.write('error-quark:')
f.write(func)
f.write('\n')
f.close()
return
elif (symbol.endswith('_get_type') or symbol.endswith('_get_gtype')):
self._initparse_get_type_function(func)
+ elif symbol.endswith('_error_quark'):
+ self._initparse_error_quark_function(func)
def _initparse_get_type_function(self, func):
if func.symbol in ('g_object_get_type',
self._get_type_functions.append(func.symbol)
return True
+ def _initparse_error_quark_function(self, func):
+ if (func.retval.type.ctype != 'GQuark'):
+ return False
+ self._error_quark_functions.append(func.symbol)
+ return True
+
def _initparse_gobject_record(self, record):
# Special handling for when we're parsing GObject / GLib
if record.name in ('Object', 'InitiallyUnowned', 'ParamSpec'):
# (see also _find_class_record and transformer.py)
field.writable = False
+ def _introspect_error_quark(self, xmlnode):
+ symbol = xmlnode.attrib['function']
+ error_domain = xmlnode.attrib['domain']
+ function = self._namespace.get_by_symbol(symbol)
+ if function is None:
+ return
+
+ node = ast.ErrorQuarkFunction(function.name, function.retval,
+ function.parameters, function.throws,
+ function.symbol, error_domain)
+ self._namespace.append(node, replace=True)
+
def _pair_boxed_type(self, boxed):
try:
name = self._transformer.strip_identifier(boxed.gtype_name)
ctype = node.attrib.get(_cns('type'))
get_type = node.attrib.get(_glibns('get-type'))
type_name = node.attrib.get(_glibns('type-name'))
- glib_error_quark = node.attrib.get(_glibns('error-quark'))
+ glib_error_domain = node.attrib.get(_glibns('error-domain'))
if node.tag == _corens('bitfield'):
klass = ast.Bitfield
else:
members=members,
gtype_name=type_name,
get_type=get_type)
- obj.error_quark = glib_error_quark
+ obj.error_domain = glib_error_domain
obj.ctype = ctype
self._parse_generic_attribs(node, obj)
self._namespace.append(obj)
self._append_node_generic(enum, attrs)
self._append_registered(enum, attrs)
attrs.append(('c:type', enum.ctype))
- if enum.error_quark:
- attrs.append(('glib:error-quark', enum.error_quark))
+ if enum.error_domain:
+ attrs.append(('glib:error-domain', enum.error_domain))
with self.tagcontext('enumeration', attrs):
self._write_generic(enum)
uscore_enums[no_uscore_prefixed] = enum
for node in self._namespace.itervalues():
- if not isinstance(node, ast.Function):
- continue
- if node.retval.type.target_giname != 'GLib.Quark':
+ if not isinstance(node, ast.ErrorQuarkFunction):
continue
short = node.symbol[:-len('_quark')]
if short == "g_io_error":
if enum is None:
enum = uscore_enums.get(short)
if enum is not None:
- enum.error_quark = node.symbol
+ enum.error_domain = node.error_domain
else:
message.warn_node(node,
"""%s: Couldn't find corresponding enumeration""" % (node.symbol, ))
binary = IntrospectionBinary(args)
else:
binary = compile_introspection_binary(options,
- gdump_parser.get_get_type_functions())
+ gdump_parser.get_get_type_functions(),
+ gdump_parser.get_error_quark_functions())
shlibs = resolve_shlibs(options, binary, options.libraries)
gdump_parser.set_introspection_binary(binary)
glib:type-name="FooError"
glib:get-type="foo_error_get_type"
c:type="FooError"
- glib:error-quark="foo_error_quark">
+ glib:error-domain="foo-error-quark">
<member name="good"
value="0"
c:identifier="FOO_ERROR_GOOD"