dnl Copyright © 2019 Nick Bowler dnl License GPLv2+: GNU General Public License version 2 or any later version. dnl This is free software: you are free to change and redistribute it. dnl There is NO WARRANTY, to the extent permitted by law. AT_SETUP([test.gob compilation]) AT_CHECK([gob2 "$abs_top_srcdir/t/test.gob"]) AT_CHECK([$HAVE_GTK2 || exit 77]) TEST_COMPILE_GOBJECT([$GTK_CFLAGS test-object.c], [0], [], [ignore]) AT_CLEANUP AT_SETUP([test.gob C++ compilation]) AT_CHECK([gob2 --for-cpp "$abs_top_srcdir/t/test.gob"]) AT_CHECK([$HAVE_GTK2 || exit 77]) TEST_COMPILEXX_GOBJECT([$GTK_CFLAGS test-object.cc], [0], [], [ignore]) AT_CLEANUP AT_SETUP([str.gob]) AT_DATA([main.c], [[#include "str.h" int main(void) { g_type_init (); int the_answer = 42; char *stupid_pointer = "ug"; /* This works fine. */ Str *test_good = (Str *) (str_new ("%d", the_answer)); test_good = test_good; /* This gets a warning thanks to our function attribute. */ Str *test_bad = (Str *) (str_new ("%d", stupid_pointer)); test_bad = test_bad; return 0; } ]]) str_gob=$abs_top_srcdir/t/str.gob AT_CHECK([gob2 "$str_gob"]) TEST_COMPILE_GOBJECT([str.c], [0], [], [stderr]) mv stderr str_stderr # Check for correct diagnostic messages on the target lines... AT_CHECK([awk '/want a string/ { print NR }' "$str_gob" >str_lines]) total=0 exec 3 %} class :Test from G:Object (dynamic) { public gchar *s = { g_strdup("(nil)") }; property STRING s (link); public void test(self) { printf("%s\n", self->s); } } ]]) AT_DATA([mod.gob], [[%{ #include "test.h" %} class :Mod from G:Type:Module { override (G:Type:Module) gboolean load(G:Type:Module *m) { test_register_type(m); return TRUE; } } ]]) AT_DATA([main.c], [[#include #include "mod.h" #include "test.h" void devnull(const char *a, GLogLevelFlags b, const char *c, gpointer d) { } int main(void) { GTypeModule *m = g_object_new(mod_get_type(), NULL); guint handler; Test *t; /* should fail, suppress internal glib logging... */ handler = g_log_set_handler("GLib-GObject", G_LOG_LEVEL_MASK, devnull, 0); t = g_object_new(test_get_type(), NULL); if (t != NULL) return EXIT_FAILURE; g_log_remove_handler("GLib-GObject", handler); g_type_module_use(m); /* should work now */ t = g_object_new(test_get_type(), "s", "Hello, World", (char *)NULL); if (!t) return EXIT_FAILURE; test_test(t); return EXIT_SUCCESS; } ]]) AT_CHECK([gob2 mod.gob]) AT_CHECK([gob2 test.gob]) TEST_COMPILE_GOBJECT([mod.c], [0], [], [ignore]) TEST_COMPILE_GOBJECT([test.c], [0], [], [ignore]) TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore]) AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main mod.o test.o main.o]) AT_CHECK([./main], [0], [Hello, World ]) AT_CLEANUP dnl Dynamic types: check that we can call interface methods of dynamic types. AT_SETUP([dynamic interface implementation]) AT_KEYWORDS([dynamic runtime interface]) AT_DATA([iface.h], [[#define IF_TYPE_TEST if_test_get_type() typedef struct IFTestIface { GTypeInterface parent; void (*test)(GObject *obj); } IFTestIface; GType if_test_get_type(void); ]]) AT_DATA([test.gob], [[%{ #include #include "iface.h" %} class :Test from G:Object (dynamic) (interface IF:Test) { private const char *s = { "Hello, World!" }; interface IF:Test private void test(G:Object *o) { Self *self = SELF(o); printf("%s\n", self->_priv->s); } } ]]) AT_DATA([mod.gob], [[%{ #include "test.h" %} class :Mod from G:Type:Module { override (G:Type:Module) gboolean load(G:Type:Module *m) { test_register_type(m); return TRUE; } } ]]) AT_DATA([main.c], [[#include "test.h" #include "mod.h" #include "iface.h" GType if_test_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof (IFTestIface), NULL, NULL, }; type = g_type_register_static(G_TYPE_INTERFACE, "IFTest", &info, 0); } return type; } int main(void) { GTypeModule *m = g_object_new(TYPE_MOD, NULL); GObject *t; g_type_module_use(m); t = g_object_new(TYPE_TEST, NULL); g_return_val_if_fail(G_TYPE_CHECK_INSTANCE_TYPE(t, IF_TYPE_TEST), EXIT_FAILURE); G_TYPE_INSTANCE_GET_INTERFACE(t, IF_TYPE_TEST, IFTestIface)->test(t); return EXIT_SUCCESS; } ]]) AT_CHECK([gob2 mod.gob]) AT_CHECK([gob2 test.gob]) TEST_COMPILE_GOBJECT([mod.c], [0], [], [ignore]) TEST_COMPILE_GOBJECT([test.c], [0], [], [ignore]) TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore]) AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main mod.o test.o main.o]) AT_CHECK([./main], [0], [Hello, World! ]) AT_CLEANUP