dnl Copyright © 2020-2023 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. dnl Check that the --help option exits successfully and prints only to dnl standard output. AT_SETUP([--help option]) AT_KEYWORDS([option])dnl AT_CHECK([gob2 invalid-file.gob --help --invalid-option], [0], [ignore-nolog]) AT_CLEANUP dnl Check that the --version option exits successfully, prints only to dnl standard output, and contains the correct version number. AT_SETUP([--version option]) AT_KEYWORDS([option])dnl AT_CHECK([gob2 invalid-file.gob --version --invalid-option], [0], [stdout]) AT_CHECK([$AWK 'NR == 1 { print $NF }' stdout], [0], [AT_PACKAGE_VERSION ]) AT_CLEANUP AT_SETUP([--exit-on-warn option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object { private int x; /* gob produces a warning due to override and nick combination */ property INT x ( override, nick = "hello", link ); } ]]) AT_CHECK([gob2 test.gob], [0], [], [ignore]) AT_CHECK([gob2 test.gob --exit-on-warn], [1], [], [ignore]) AT_CHECK([gob2 test.gob --no-exit-on-warn -w], [1], [], [ignore]) AT_CLEANUP AT_SETUP([--no-exit-on-warn option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object { private int x; /* gob produces a warning due to override and nick combination */ property INT x ( override, nick = "hello", link ); } ]]) AT_CHECK([gob2 test.gob], [0], [], [ignore]) AT_CHECK([gob2 test.gob --exit-on-warn], [1], [], [ignore]) AT_CHECK([gob2 test.gob -w --no-exit-on-warn], [0], [], [ignore]) AT_CHECK([gob2 test.gob --exit-on-warn --no-exit-on-warn], [0], [], [ignore]) AT_CLEANUP AT_SETUP([--ondemand-private-header option]) AT_KEYWORDS([option])dnl AT_DATA([priv.gob], [[class A:B:C from G:Object { private int x; } %{ TEST_WITNESS_C %} %h{ TEST_WITNESS_H %} %privateheader{ TEST_WITNESS_PRIVATE %} ]]) sed '/private int/d' priv.gob >nopriv.gob rm -f *.c *.h AT_CHECK([gob2 nopriv.gob]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C TEST_WITNESS_PRIVATE ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([test ! -f a-b-c-private.h]) rm -f *.c *.h AT_CHECK([gob2 priv.gob]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c-private.h], [0], [TEST_WITNESS_PRIVATE ]) rm -f *.c *.h AT_CHECK([gob2 nopriv.gob --always-private-header --ondemand-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C TEST_WITNESS_PRIVATE ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([test ! -f a-b-c-private.h]) rm -f *.c *.h AT_CHECK([gob2 priv.gob --no-private-header --ondemand-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c-private.h], [0], [TEST_WITNESS_PRIVATE ]) AT_CLEANUP AT_SETUP([--always-private-header option]) AT_KEYWORDS([option])dnl AT_DATA([priv.gob], [[class A:B:C from G:Object { private int x; } %{ TEST_WITNESS_C %} %h{ TEST_WITNESS_H %} %privateheader{ TEST_WITNESS_PRIVATE %} ]]) sed '/private int/d' priv.gob >nopriv.gob rm -f *.c *.h AT_CHECK([gob2 nopriv.gob --always-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c-private.h], [0], [TEST_WITNESS_PRIVATE ]) rm -f *.c *.h AT_CHECK([gob2 priv.gob --no-private-header --always-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c-private.h], [0], [TEST_WITNESS_PRIVATE ]) rm -f *.c *.h AT_CHECK([gob2 nopriv.gob --ondemand-private-header --always-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c-private.h], [0], [TEST_WITNESS_PRIVATE ]) AT_CLEANUP AT_SETUP([--no-private-header option]) AT_KEYWORDS([option])dnl AT_DATA([priv.gob], [[class A:B:C from G:Object { private int x; } %{ TEST_WITNESS_C %} %h{ TEST_WITNESS_H %} %privateheader{ TEST_WITNESS_PRIVATE %} ]]) sed '/private int/d' priv.gob >nopriv.gob rm -f *.c *.h AT_CHECK([gob2 priv.gob --no-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C TEST_WITNESS_PRIVATE ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([test ! -f a-b-c-private.h]) rm -f *.c *.h AT_CHECK([gob2 nopriv.gob --always-private-header --no-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C TEST_WITNESS_PRIVATE ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([test ! -f a-b-c-private.h]) rm -f *.c *.h AT_CHECK([gob2 priv.gob --ondemand-private-header --no-private-header]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.c], [0], [TEST_WITNESS_C TEST_WITNESS_PRIVATE ]) AT_CHECK([grep '^TEST_WITNESS' a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([test ! -f a-b-c-private.h]) AT_CLEANUP AT_SETUP([--file-sep option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class A:B:C from G:Object { } %{ TEST_WITNESS_C %} %h{ TEST_WITNESS_H %} %privateheader{ TEST_WITNESS_PRIVATE %} ]]) mkdir a; mkdir a/b AT_CHECK([gob2 test.gob --file-sep=/]) AT_CHECK([grep '^TEST_WITNESS' a/b/c.c], [0], [TEST_WITNESS_C TEST_WITNESS_PRIVATE ]) AT_CHECK([grep '^TEST_WITNESS' a/b/c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([gob2 test.gob --always-private-header --file-sep=]) AT_CHECK([grep '^TEST_WITNESS' abc.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' abc.h], [0], [TEST_WITNESS_H ]) AT_CHECK([grep '^TEST_WITNESS' abcprivate.h], [0], [TEST_WITNESS_PRIVATE ]) rm -f abc* AT_CHECK([gob2 test.gob --file-sep]) AT_CHECK([grep '^TEST_WITNESS' abc.c], [0], [TEST_WITNESS_C TEST_WITNESS_PRIVATE ]) AT_CHECK([grep '^TEST_WITNESS' abc.h], [0], [TEST_WITNESS_H ]) AT_CLEANUP AT_SETUP([--output-dir option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class A:B:C from G:Object { } %{ TEST_WITNESS_C %} %h{ TEST_WITNESS_H %} ]]) mkdir output-dir o AT_CHECK([gob2 test.gob --output-dir=output-dir]) AT_CHECK([grep '^TEST_WITNESS' output-dir/a-b-c.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' output-dir/a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CHECK([gob2 test.gob -o o]) AT_CHECK([grep '^TEST_WITNESS' o/a-b-c.c], [0], [TEST_WITNESS_C ]) AT_CHECK([grep '^TEST_WITNESS' o/a-b-c.h], [0], [TEST_WITNESS_H ]) AT_CLEANUP dnl Check that the --no-touch option does not modify any files that would be dnl unchanged by gob, and that the --no-touch-headers option does not modify dnl any header files. m4_foreach([OPTION], [[[--no-touch]], [[--no-touch-headers]]], [AT_SETUP([OPTION option]) AT_KEYWORDS([option])dnl # Sanity check for make implementation echo >>test.h; echo >>test-h AT_CHECK([mtime_uptodate test-h test.h || exit 77]) TEST_MTIME_DELAY; echo >>test.h AT_CHECK([mtime_uptodate test-h test.h && exit 77], [1]) rm -f test.h AT_DATA([test.gob], [[class :Test from G:Object { private int x; } ]]) AT_CHECK([gob2 test.gob]) echo >>test-c; echo >>test-h; echo >>test-private TEST_MTIME_DELAY AT_CHECK([gob2 test.gob]) AT_CHECK([mtime_uptodate test-c test.c], [1]) AT_CHECK([mtime_uptodate test-h test.h], [1]) AT_CHECK([mtime_uptodate test-private test-private.h], [1]) echo >>test-c; echo >>test-h; echo >>test-private TEST_MTIME_DELAY AT_CHECK([gob2 test.gob OPTION]) AT_CHECK([mtime_uptodate test-c test.c], m4_if(OPTION, [--no-touch], [0], [1])) AT_CHECK([mtime_uptodate test-h test.h], [0]) AT_CHECK([mtime_uptodate test-private test-private.h], [0]) cat >>test.gob <<'EOF' %{ /* some code */ %} EOF echo >>test-c; echo >>test-h; echo >>test-private TEST_MTIME_DELAY AT_CHECK([gob2 test.gob OPTION]) AT_CHECK([mtime_uptodate test-c test.c], [1]) AT_CHECK([mtime_uptodate test-h test.h], [0]) AT_CHECK([mtime_uptodate test-private test-private.h], [0]) cat >>test.gob <<'EOF' %h{ /* yonder comment */ %} EOF echo >>test-c; echo >>test-h; echo >>test-private TEST_MTIME_DELAY AT_CHECK([gob2 test.gob OPTION]) AT_CHECK([mtime_uptodate test-c test.c], m4_if(OPTION, [--no-touch], [0], [1])) AT_CHECK([mtime_uptodate test-h test.h], [1]) AT_CHECK([mtime_uptodate test-private test-private.h], [0]) cat >>test.gob <<'EOF' %privateheader{ /* once more unto the breach */ %} EOF echo >>test-c; echo >>test-h; echo >>test-private TEST_MTIME_DELAY AT_CHECK([gob2 test.gob OPTION]) AT_CHECK([mtime_uptodate test-c test.c], m4_if(OPTION, [--no-touch], [0], [1])) AT_CHECK([mtime_uptodate test-h test.h], [0]) AT_CHECK([mtime_uptodate test-private test-private.h], [1]) AT_CLEANUP ]) AT_SETUP([--no-write option]) AT_KEYWORDS([option])dnl mkdir outdir AT_DATA([outdir/test.gob], [[class :Test from G:Object { private int x; } ]]) AT_CHECK([cd outdir && ls -Al], [0], [stdout-nolog]) mv -f stdout expout AT_CHECK([cd outdir && gob2 test.gob --no-write && ls -Al], [0], [expout]) AT_CHECK([cd outdir && gob2 test.gob -n && ls -Al], [0], [expout]) AT_CHECK([cd outdir && gob2 test.gob && ls -Al], [0], [stdout-nolog]) mv -f stdout expout AT_CHECK([cd outdir && gob2 test.gob --no-write && ls -Al], [0], [expout]) AT_CHECK([cd outdir && gob2 test.gob -n && ls -Al], [0], [expout]) AT_CLEANUP AT_SETUP([--no-extern-c option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object { private int x; } ]]) AT_CHECK([gob2 test.gob]) AT_CHECK([cat *.h | grep 'extern "C"'], [0], [extern "C" { extern "C" { ]) AT_CHECK([gob2 --no-extern-c test.gob]) AT_CHECK([cat *.h | grep 'extern "C"'], [1]) AT_CLEANUP AT_SETUP([--no-gnu option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[enum TEST_ENUM { TEST_ENUM_A } Test:Enum; flags TEST_FLAGS { TEST_FLAG_A } Test:Flags; error TEST_ERROR { TEST_ERROR_A } Test:Error; class :Test from G:Object { private int x; } ]]) AT_CHECK([gob2 test.gob]) AT_CHECK([cat test*.h test.c | grep '_GNUC_' >/dev/null], [0]) AT_CHECK([gob2 --no-gnu test.gob]) AT_CHECK([cat test*.h test.c | grep '_GNUC_'], [1]) AT_CLEANUP dnl Check that --no-self-alias works as documented. The self_xxx method dnl aliases are not documented to be affected by this option, so check that dnl they are unaffected. AT_SETUP([--no-self-alias option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object { public void myfunction(self) { }; } ]]) AT_CHECK([gob2 test.gob]) AT_CHECK([:; { grep '#define.*SELF' test.c && grep 'typedef.*Self' test.c && grep '#define.*self_myfunction' test.c; } >/dev/null], [0]) AT_CHECK([gob2 --no-self-alias test.gob]) AT_CHECK([grep '#.*define.*SELF' test.c], [1]) AT_CHECK([grep 'typedef.*Self' test.c], [1]) AT_CHECK([grep '#define.*self_myfunction' test.c >/dev/null], [0]) AT_CLEANUP AT_SETUP([--no-lines option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object { public int foo(void) { return 42; } private int x; } ]]) AT_CHECK([gob2 test.gob]) AT_CHECK([cat test.h test-private.h test.c | grep '#.*line' >/dev/null]) AT_CHECK([gob2 --no-lines test.gob]) AT_CHECK([cat test.h test-private.h test.c | grep '#.*line'], [1]) AT_CLEANUP dnl Check that the --no-kill-underscores option is ignored for compatibility. AT_SETUP([--no-kill-underscores option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object { } ]]) mkdir orig AT_CHECK([gob2 --output-dir orig test.gob]) AT_CHECK([gob2 --no-kill-underscores test.gob]) cp -f orig/test.c expout AT_CHECK([cat test.c], [0], [expout]) cp -f orig/test.h expout AT_CHECK([cat test.h], [0], [expout]) AT_CLEANUP AT_SETUP([--always-private-struct option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object { public int my_public_member; } ]]) AT_CHECK([gob2 test.gob]) AT_CHECK([sed -n '/my_public_member/,/^}/s/_priv/&/p' test.h]) AT_CHECK([gob2 --always-private-struct test.gob]) AT_CHECK([sed -n '/my_public_member/,/^}/s/[[ ]]*\(.*_priv;\)/\1/p' test.h], [0], [TestPrivate *_priv; ]) AT_CLEANUP dnl Check the --gtk3 option. The only effect of this option seems to be to dnl change the normal "Iface" suffix on interface types to "Interface". So dnl let's make sure that behaviour is tested. AT_SETUP([--gtk3 option]) AT_KEYWORDS([option])dnl AT_DATA([test.gob], [[class :Test from G:Object (interface Gtk:Actionable) { } ]]) AT_CHECK([gob2 test.gob]) AT_CHECK([sed -n \ 's/.*Gtk_Actionable_init.*\(GtkActionable[[^ *]]*\).*/\1/p' test.c], [0], [GtkActionableIface ]) AT_CHECK([gob2 --gtk3 test.gob]) AT_CHECK([sed -n \ 's/.*Gtk_Actionable_init.*\(GtkActionable[[^ *]]*\).*/\1/p' test.c], [0], [GtkActionableInterface ]) AT_CLEANUP AT_SETUP([--m4-dir option]) AT_KEYWORDS([option])dnl AT_CHECK_UNQUOTED([gob2 --m4-dir], [0], [$pkgdatadir/m4 ]) AT_CLEANUP dnl Check that the --m4 option shells out to m4 and passes through dnl all remaining arguments. AT_SETUP([--m4 option]) AT_KEYWORDS([option])dnl mkdir bin AT_DATA([bin/m4], [[#!/bin/sh test $][# != 0 && printf '%s\n' "$][*" >&2 cat <<'EOF' class M4:Test from G:Object { } EOF ]]) chmod +x bin/m4 PATH=$PWD/bin${PATH:+":$PATH"} AT_CHECK([gob2 --m4 filename], [0], [], [stderr]) read gob_m4_args experr <experr <&2 cat <<'EOF' class M4:Test from G:Object { } EOF ]]) chmod +x bin/m4 PATH=$PWD/bin${PATH:+":$PATH"} AT_CHECK([gob2 --m4-clean filename], [0], [], [filename ]) AT_CHECK([test -f m4-test.c]) rm -f m4-test.c m4-test.h AT_CHECK( [gob2 --m4-clean filename --help I am trapped in a test case factory --], [0], [], [filename --help I am trapped in a test case factory -- ]) AT_CHECK([test -f m4-test.c]) AT_CLEANUP