gobject-introspection r773 - in trunk: . girepository giscanner tests/repository tests/scanner
- From: jobi svn gnome org
- To: svn-commits-list gnome org
- Subject: gobject-introspection r773 - in trunk: . girepository giscanner tests/repository tests/scanner
- Date: Tue, 21 Oct 2008 17:04:12 +0000 (UTC)
Author: jobi
Date: Tue Oct 21 17:04:11 2008
New Revision: 773
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=773&view=rev
Log:
2008-10-21 Johan Bilien <jobi via ecp fr>
Bug 557241 â "throws" flag for functions
* tests/scanner/drawable-1.0-expected.gir,
tests/scanner/drawable-injected-1.0-expected.gir,
tests/scanner/drawable.[ch]: add simple test for throwing
function (has GError ** as last argument)
* giscanner/ast.py: add a 'throws' flag to Function
* giscanner/glibtransformer.py: if a function's last paramerter is
a GError, set the 'throws' flag and remove that parameter
* giscanner/girwriter.py: write out the 'throws' attribute
* giscanner/girparser.py: support parsing the 'throws' attribute
* tests/repository/gitestthrows.c: add a simple test to check the
throws flag in a typelib and invoke the function
* girepository/ginfo.c, girepository/girnode.[ch],
girepository/girnode.h, girepository/girparser.c,
girepository/girepository.h: Add and parse the GI_FUNCTION_THROWS flag
* girepository/ginvoke.c: if a function throws, add a GError as last
arguments, and propagate the error to the invoker.
Added:
trunk/tests/repository/gitestthrows.c
Modified:
trunk/ChangeLog
trunk/girepository/ginfo.c
trunk/girepository/ginvoke.c
trunk/girepository/girepository.h
trunk/girepository/girnode.c
trunk/girepository/girnode.h
trunk/girepository/girparser.c
trunk/girepository/gtypelib.h
trunk/giscanner/ast.py
trunk/giscanner/girparser.py
trunk/giscanner/girwriter.py
trunk/giscanner/glibtransformer.py
trunk/tests/repository/Makefile.am
trunk/tests/scanner/drawable-1.0-expected.gir
trunk/tests/scanner/drawable-injected-1.0-expected.gir
trunk/tests/scanner/drawable.c
trunk/tests/scanner/drawable.h
Modified: trunk/girepository/ginfo.c
==============================================================================
--- trunk/girepository/ginfo.c (original)
+++ trunk/girepository/ginfo.c Tue Oct 21 17:04:11 2008
@@ -492,6 +492,9 @@
if (blob->wraps_vfunc)
flags = flags | GI_FUNCTION_WRAPS_VFUNC;
+ if (blob->throws)
+ flags = flags | GI_FUNCTION_THROWS;
+
return flags;
}
Modified: trunk/girepository/ginvoke.c
==============================================================================
--- trunk/girepository/ginvoke.c (original)
+++ trunk/girepository/ginvoke.c Tue Oct 21 17:04:11 2008
@@ -159,9 +159,11 @@
GITypeInfo *tinfo;
GIArgInfo *ainfo;
gboolean is_method;
+ gboolean throws;
gint n_args, n_invoke_args, in_pos, out_pos, i;
gpointer *args;
gboolean success = FALSE;
+ GError *local_error;
symbol = g_function_info_get_symbol (info);
@@ -178,6 +180,7 @@
is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
&& (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0;
+ throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS;
tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
rtype = get_ffi_type (tinfo);
@@ -202,6 +205,11 @@
}
else
n_invoke_args = n_args;
+
+ if (throws)
+ /* Add an argument for the GError */
+ n_invoke_args ++;
+
atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args);
args = g_alloca (sizeof (gpointer) * n_invoke_args);
@@ -279,6 +287,15 @@
}
g_base_info_unref ((GIBaseInfo *)ainfo);
}
+
+ local_error = NULL;
+ if (throws)
+ {
+ gpointer address = &local_error;
+ args[n_invoke_args - 1] = &address;
+ atypes[n_invoke_args - 1] = &ffi_type_pointer;
+ }
+
if (in_pos < n_in_args)
{
g_set_error (error,
@@ -301,7 +318,15 @@
ffi_call (&cif, func, return_value, args);
- success = TRUE;
+ if (local_error)
+ {
+ g_propagate_error (error, local_error);
+ success = FALSE;
+ }
+ else
+ {
+ success = TRUE;
+ }
out:
return success;
}
Modified: trunk/girepository/girepository.h
==============================================================================
--- trunk/girepository/girepository.h (original)
+++ trunk/girepository/girepository.h Tue Oct 21 17:04:11 2008
@@ -190,7 +190,8 @@
GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1,
GI_FUNCTION_IS_GETTER = 1 << 2,
GI_FUNCTION_IS_SETTER = 1 << 3,
- GI_FUNCTION_WRAPS_VFUNC = 1 << 4
+ GI_FUNCTION_WRAPS_VFUNC = 1 << 4,
+ GI_FUNCTION_THROWS = 1 << 5
} GIFunctionInfoFlags;
const gchar * g_function_info_get_symbol (GIFunctionInfo *info);
Modified: trunk/girepository/girnode.c
==============================================================================
--- trunk/girepository/girnode.c (original)
+++ trunk/girepository/girnode.c Tue Oct 21 17:04:11 2008
@@ -1477,7 +1477,7 @@
blob->getter = function->is_getter;
blob->constructor = function->is_constructor;
blob->wraps_vfunc = function->wraps_vfunc;
- blob->reserved = 0;
+ blob->throws = function->throws;
blob->index = 0;
blob->name = write_string (node->name, strings, data, offset2);
blob->symbol = write_string (function->symbol, strings, data, offset2);
Modified: trunk/girepository/girnode.h
==============================================================================
--- trunk/girepository/girnode.h (original)
+++ trunk/girepository/girnode.h Tue Oct 21 17:04:11 2008
@@ -92,6 +92,7 @@
gboolean is_getter;
gboolean is_constructor;
gboolean wraps_vfunc;
+ gboolean throws;
gchar *symbol;
Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c (original)
+++ trunk/girepository/girparser.c Tue Oct 21 17:04:11 2008
@@ -527,6 +527,7 @@
const gchar *name;
const gchar *symbol;
const gchar *deprecated;
+ const gchar *throws;
GIrNodeFunction *function;
gboolean found = FALSE;
@@ -557,6 +558,7 @@
name = find_attribute ("name", attribute_names, attribute_values);
symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
+ throws = find_attribute ("throws", attribute_names, attribute_values);
if (name == NULL)
{
@@ -598,7 +600,12 @@
if (strcmp (element_name, "callback") == 0)
((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
}
-
+
+ if (throws && strcmp (throws, "1") == 0)
+ function->throws = TRUE;
+ else
+ function->throws = FALSE;
+
if (ctx->current_node == NULL)
{
ctx->current_module->entries =
Modified: trunk/girepository/gtypelib.h
==============================================================================
--- trunk/girepository/gtypelib.h (original)
+++ trunk/girepository/gtypelib.h Tue Oct 21 17:04:11 2008
@@ -166,11 +166,11 @@
guint16 blob_type; /* 1 */
guint16 deprecated : 1;
- guint16 setter : 1;
+ guint16 setter : 1;
guint16 getter : 1;
guint16 constructor : 1;
guint16 wraps_vfunc : 1;
- guint16 reserved : 1;
+ guint16 throws : 1;
guint16 index :10;
guint32 name;
Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py (original)
+++ trunk/giscanner/ast.py Tue Oct 21 17:04:11 2008
@@ -188,11 +188,12 @@
class Function(Node):
- def __init__(self, name, retval, parameters, symbol):
+ def __init__(self, name, retval, parameters, symbol, throws=None):
Node.__init__(self, name)
self.retval = retval
self.parameters = parameters
self.symbol = symbol
+ self.throws = not not throws
def __repr__(self):
return '%s(%r, %r, %r)' % (self.__class__.__name__,
Modified: trunk/giscanner/girparser.py
==============================================================================
--- trunk/giscanner/girparser.py (original)
+++ trunk/giscanner/girparser.py Tue Oct 21 17:04:11 2008
@@ -178,7 +178,8 @@
node.attrib.get(_cns('type')))
else:
identifier = node.attrib.get(_cns('identifier'))
- return klass(name, retval, parameters, identifier)
+ throws = (node.attrib.get('throws') == '1')
+ return klass(name, retval, parameters, identifier, throws)
def _parse_struct(self, node):
if _glibns('type-name') in node.attrib:
Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py (original)
+++ trunk/giscanner/girwriter.py Tue Oct 21 17:04:11 2008
@@ -95,6 +95,10 @@
attrs.append(('deprecated-version',
node.deprecated_version))
+ def _append_throws(self, func, attrs):
+ if func.throws:
+ attrs.append(('throws', '1'))
+
def _write_alias(self, alias):
attrs = [('name', alias.name), ('target', alias.target)]
if alias.ctype is not None:
@@ -105,6 +109,7 @@
attrs = [('name', func.name),
('c:identifier', func.symbol)]
self._append_deprecated(func, attrs)
+ self._append_throws(func, attrs)
with self.tagcontext(tag_name, attrs):
self._write_return_type(func.retval)
self._write_parameters(func.parameters)
Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py (original)
+++ trunk/giscanner/glibtransformer.py Tue Oct 21 17:04:11 2008
@@ -790,9 +790,23 @@
and param.type.name == 'Object'))):
param.transfer = 'full'
+ def _adjust_throws(self, func):
+ if func.parameters == []:
+ return
+
+ last_param = func.parameters.pop()
+
+ if (last_param.type.name == 'GLib.Error' or
+ (self._namespace_name == 'GLib' and
+ last_param.type.name == 'Error')):
+ func.throws = True
+ else:
+ func.parameters.append(last_param)
+
def _resolve_function(self, func):
self._resolve_parameters(func.parameters)
func.retval.type = self._resolve_param_type(func.retval.type)
+ self._adjust_throws(func)
self._adjust_transfer(func.retval)
def _resolve_parameters(self, parameters):
Modified: trunk/tests/repository/Makefile.am
==============================================================================
--- trunk/tests/repository/Makefile.am (original)
+++ trunk/tests/repository/Makefile.am Tue Oct 21 17:04:11 2008
@@ -2,11 +2,15 @@
AM_LDFLAGS = -module -avoid-version
LIBS = $(GOBJECT_LIBS)
-noinst_PROGRAMS = gitestrepo
+noinst_PROGRAMS = gitestrepo gitestthrows
gitestrepo_SOURCES = $(srcdir)/gitestrepo.c
gitestrepo_CPPFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository
gitestrepo_LDADD = $(GIREPO_LIBS) $(top_builddir)/girepository/libgirepository.la
-TESTS = gitestrepo
-TESTS_ENVIRONMENT=env top_builddir="$(top_builddir)" $(DEBUG)
\ No newline at end of file
+gitestthrows_SOURCES = $(srcdir)/gitestthrows.c
+gitestthrows_CPPFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository
+gitestthrows_LDADD = $(GIREPO_LIBS) $(top_builddir)/girepository/libgirepository.la
+
+TESTS = gitestrepo gitestthrows
+TESTS_ENVIRONMENT=env top_builddir="$(top_builddir)" $(DEBUG)
Added: trunk/tests/repository/gitestthrows.c
==============================================================================
--- (empty file)
+++ trunk/tests/repository/gitestthrows.c Tue Oct 21 17:04:11 2008
@@ -0,0 +1,55 @@
+
+#include "girepository.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+
+int
+main(int argc, char **argv)
+{
+ GIRepository *repo;
+ gboolean ret;
+ GIBaseInfo *info;
+ char *girdir;
+ GArgument in_arg[1];
+ GArgument ret_arg;
+ GError *error;
+ gboolean invoke_return;
+
+ g_type_init ();
+
+ repo = g_irepository_get_default ();
+
+ girdir = g_build_filename (g_getenv ("top_builddir"), "gir", NULL);
+ g_irepository_prepend_search_path (girdir);
+ g_free (girdir);
+
+ error = NULL;
+ ret = g_irepository_require (repo, "GLib", NULL, 0, &error);
+ g_assert (ret);
+ g_assert (error == NULL);
+
+ info = g_irepository_find_by_name (repo, "GLib", "file_read_link");
+ g_assert (info != NULL);
+ g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
+ g_assert (g_function_info_get_flags ((GIFunctionInfo *)info) & GI_FUNCTION_THROWS);
+
+ in_arg[0].v_string = g_strdup ("non-existent-file/hope");
+ error = NULL;
+ invoke_return = g_function_info_invoke ((GIFunctionInfo *)info,
+ in_arg,
+ 1,
+ NULL,
+ 0,
+ &ret_arg,
+ &error);
+ g_free(in_arg[0].v_string);
+
+ g_assert (invoke_return == FALSE);
+ g_assert (error != NULL);
+ g_assert (error->domain == G_FILE_ERROR);
+ g_assert (error->code == G_FILE_ERROR_NOENT);
+
+ exit(0);
+}
Modified: trunk/tests/scanner/drawable-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/drawable-1.0-expected.gir (original)
+++ trunk/tests/scanner/drawable-1.0-expected.gir Tue Oct 21 17:04:11 2008
@@ -49,6 +49,18 @@
</parameter>
</parameters>
</method>
+ <method name="do_foo_maybe_throw"
+ c:identifier="test_drawable_do_foo_maybe_throw"
+ throws="1">
+ <return-value>
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="x">
+ <type name="int" c:type="int"/>
+ </parameter>
+ </parameters>
+ </method>
<field name="parent_instance">
<type name="GObject.Object" c:type="GObject"/>
</field>
Modified: trunk/tests/scanner/drawable-injected-1.0-expected.gir
==============================================================================
--- trunk/tests/scanner/drawable-injected-1.0-expected.gir (original)
+++ trunk/tests/scanner/drawable-injected-1.0-expected.gir Tue Oct 21 17:04:11 2008
@@ -49,6 +49,18 @@
</parameter>
</parameters>
</method>
+ <method name="do_foo_maybe_throw"
+ c:identifier="test_drawable_do_foo_maybe_throw"
+ throws="1">
+ <return-value>
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="x">
+ <type name="int" c:type="int"/>
+ </parameter>
+ </parameters>
+ </method>
<method name="get_width" c:identifier="girepo_test_drawable_get_width">
<return-value>
<type name="int" c:type="gint"/>
Modified: trunk/tests/scanner/drawable.c
==============================================================================
--- trunk/tests/scanner/drawable.c (original)
+++ trunk/tests/scanner/drawable.c Tue Oct 21 17:04:11 2008
@@ -33,3 +33,10 @@
*width = 42;
*height = 42;
}
+
+void
+test_drawable_do_foo_maybe_throw (TestDrawable *drawable, int x, GError **error)
+{
+ if (x != 42)
+ g_set_error(error, 0, 12, "The answer should be 42!");
+}
Modified: trunk/tests/scanner/drawable.h
==============================================================================
--- trunk/tests/scanner/drawable.h (original)
+++ trunk/tests/scanner/drawable.h Tue Oct 21 17:04:11 2008
@@ -21,6 +21,7 @@
void test_drawable_do_foo (TestDrawable *drawable, int x);
void test_drawable_get_origin (TestDrawable *drawable, int *x, int *y);
void test_drawable_get_size (TestDrawable *drawable, guint *width, guint *height);
+void test_drawable_do_foo_maybe_throw (TestDrawable *drawable, int x, GError **error);
struct _TestPixmapObjectClass
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]