summaryrefslogtreecommitdiff
path: root/tests/invoke
diff options
context:
space:
mode:
Diffstat (limited to 'tests/invoke')
-rw-r--r--tests/invoke/Makefile28
-rw-r--r--tests/invoke/invoke.c158
-rw-r--r--tests/invoke/testfns.c27
-rw-r--r--tests/invoke/testfns.xml47
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>