diff options
Diffstat (limited to 'tests/invoke')
-rw-r--r-- | tests/invoke/Makefile | 28 | ||||
-rw-r--r-- | tests/invoke/invoke.c | 158 | ||||
-rw-r--r-- | tests/invoke/testfns.c | 27 | ||||
-rw-r--r-- | tests/invoke/testfns.xml | 47 |
4 files changed, 260 insertions, 0 deletions
diff --git a/tests/invoke/Makefile b/tests/invoke/Makefile new file mode 100644 index 00000000..57cea963 --- /dev/null +++ b/tests/invoke/Makefile @@ -0,0 +1,28 @@ +AR=ar +CC=gcc -g +CFLAGS=`pkg-config --cflags glib-2.0` -I../../libffi/include -I../../src +LIBS=`pkg-config --libs glib-2.0 gobject-2.0` + +TESTFNS_OBJS = \ + testfns.o \ + testfns-metadata.o + +INVOKE_OBJS = \ + invoke.o + +all: testfns.so invoke + +testfns.so: $(TESTFNS_OBJS) + $(CC) -shared -o $@ $(TESTFNS_OBJS) $(LIBS) ../../src/libirepository.so + +testfns-metadata.c: testfns.xml + ../../src/g-idl-compiler testfns.xml -o testfns-metadata.c + +invoke: $(INVOKE_OBJS) + $(CC) -o $@ $(INVOKE_OBJS) $(LIBS) -ldl ../../src/libirepository.so + +.c.o: + $(CC) -c $< $(CFLAGS) + +clean: + rm -rf *.o *~ *.a *.so diff --git a/tests/invoke/invoke.c b/tests/invoke/invoke.c new file mode 100644 index 00000000..5e093ff4 --- /dev/null +++ b/tests/invoke/invoke.c @@ -0,0 +1,158 @@ +#include <stdlib.h> +#include <dlfcn.h> + +#include <glib.h> +#include <girepository.h> + +int +main (int argc, char *argv[]) +{ + const gchar *testfns = "./testfns.so"; + void *handle; + GIRepository *rep; + GIBaseInfo *info; + GIFunctionInfo *function; + GArgument in_args[3]; + GArgument out_args[3]; + GArgument retval; + gint res; + gchar *blurb; + gint len; + GError *error = NULL; + + g_type_init (); + + rep = g_irepository_get_default (); + + g_print ("before dlopening %s: %d infos in the repository\n", + testfns, + g_irepository_get_n_infos (rep, "test")); + + handle = dlopen (testfns, RTLD_NOW|RTLD_GLOBAL); + if (!handle) + g_print ("dlopen failed: %s\n", dlerror ()); + + g_print ("after dlopening %s: %d infos in the repository\n", + testfns, + g_irepository_get_n_infos (rep, "test")); + + /* test1 calculates x + 4, + * taking x as an in parameter + * and returning the result + */ + info = g_irepository_find_by_name (rep, "test", "test1"); + g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); + function = (GIFunctionInfo *)info; + + retval.v_int = 0; + in_args[0].v_int = 4; + if (!g_function_info_invoke (function, in_args, 1, NULL, 0, &retval, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + g_assert (retval.v_int == 8); + g_base_info_unref (info); + + /* test2 calculates x + 4, + * taking x as an in parameter + * and storing the result in an out parameter + */ + info = g_irepository_find_by_name (rep, "test", "test2"); + g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); + function = (GIFunctionInfo *)info; + + in_args[0].v_int = 5; + res = 0; + out_args[0].v_pointer = &res; + if (!g_function_info_invoke (function, in_args, 1, out_args, 1, &retval, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_assert (res == 9); + g_base_info_unref (info); + + /* test3 calculates x + 4, + * taking x as an inout parameter + * and storing the result in the same parameter + */ + info = g_irepository_find_by_name (rep, "test", "test3"); + g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); + function = (GIFunctionInfo *)info; + + res = 6; + in_args[0].v_pointer = out_args[0].v_pointer = &res; + if (!g_function_info_invoke (function, in_args, 1, out_args, 1, &retval, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_assert (res == 10); + g_base_info_unref (info); + + /* test4 prints out a string + */ + info = g_irepository_find_by_name (rep, "test", "test4"); + g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); + function = (GIFunctionInfo *)info; + + in_args[0].v_pointer = "hello world\n"; + if (!g_function_info_invoke (function, in_args, 1, NULL, 0, NULL, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_base_info_unref (info); + + /* test5 returns a string and a length + */ + info = g_irepository_find_by_name (rep, "test", "test5"); + g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); + function = (GIFunctionInfo *)info; + + blurb = NULL; + len = 0; + out_args[0].v_pointer = &blurb; + out_args[1].v_pointer = &len; + if (!g_function_info_invoke (function, NULL, 0, out_args, 2, NULL, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_assert (strcmp (blurb, "hey there") == 0); + g_assert (len == strlen (blurb)); + g_base_info_unref (info); + + /* test error handling */ + + /* test6 is not implemented */ + info = g_irepository_find_by_name (rep, "test", "test6"); + g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); + function = (GIFunctionInfo *)info; + + if (!g_function_info_invoke (function, NULL, 0, NULL, 0, NULL, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_base_info_unref (info); + g_clear_error (&error); + + /* too few in arguments */ + info = g_irepository_find_by_name (rep, "test", "test2"); + g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION); + function = (GIFunctionInfo *)info; + + if (!g_function_info_invoke (function, NULL, 0, NULL, 0, NULL, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_clear_error (&error); + + /* too few out arguments */ + if (!g_function_info_invoke (function, in_args, 1, NULL, 0, NULL, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_clear_error (&error); + + /* too many in arguments */ + if (!g_function_info_invoke (function, in_args, 2, out_args, 1, NULL, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_clear_error (&error); + + /* too many out arguments */ + if (!g_function_info_invoke (function, in_args, 1, out_args, 2, NULL, &error)) + g_print ("Invokation of %s failed: %s\n", g_base_info_get_name (info), error->message); + + g_clear_error (&error); + + return 0; +} diff --git a/tests/invoke/testfns.c b/tests/invoke/testfns.c new file mode 100644 index 00000000..2a61c6be --- /dev/null +++ b/tests/invoke/testfns.c @@ -0,0 +1,27 @@ +#include <glib.h> + +gint test1 (gint in) +{ + return in + 4; +} + +void test2 (gint in, gint *out) +{ + *out = in + 4; +} + +void test3 (gint *inout) +{ + *inout = *inout + 4; +} + +void test4 (const gchar *blurb) +{ + g_printf (blurb); +} + +void test5 (gchar **blurb, gint *len) +{ + *blurb = g_strdup ("hey there"); + *len = strlen (*blurb); +} diff --git a/tests/invoke/testfns.xml b/tests/invoke/testfns.xml new file mode 100644 index 00000000..db1b44ae --- /dev/null +++ b/tests/invoke/testfns.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<api version="1.0"> + <namespace name="test"> + + <function name="test1" symbol="test1"> + <return-type type="gint"/> + <parameters> + <parameter name="in" type="gint" direction="in"/> + </parameters> + </function> + + <function name="test2" symbol="test2"> + <return-type type="void"/> + <parameters> + <parameter name="in" type="gint" direction="in"/> + <parameter name="out" type="gint" direction="out"/> + </parameters> + </function> + + <function name="test3" symbol="test3"> + <return-type type="void"/> + <parameters> + <parameter name="inout" type="gint" direction="inout"/> + </parameters> + </function> + + <function name="test4" symbol="test4"> + <return-type type="void"/> + <parameters> + <parameter name="blurb" type="gchar*" direction="in"/> + </parameters> + </function> + + <function name="test5" symbol="test5"> + <return-type type="void"/> + <parameters> + <parameter name="blurb" type="gchar*" direction="out" transfer="full"/> + <parameter name="len" type="gint" direction="out"/> + </parameters> + </function> + + <function name="test6" symbol="test6"> + <return-type type="void"/> + </function> + + </namespace> +</api> |