1 dnl Copyright © 2021-2022 Nick Bowler
3 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
4 dnl This is free software: you are free to do what the fuck you want to.
5 dnl There is NO WARRANTY, to the extent permitted by law.
7 AT_BANNER([Script tests])
9 AT_SETUP([gen-options.awk])
10 AT_KEYWORDS([gen-options awk script scripts])
12 AT_DATA([options.def],
15 --option-with-flagval (&x, 5)
18 --option-with-optional-arg[=OPTIONAL]
21 -a, --option-with-sopt
23 -b, --option-with-sopt-and-arg=SOPTARG
24 -c, --option-with-sopt-and-optional-arg[=SOPTOPTIONAL]
25 --option-with-arg-and-val=ARGVAL (42)
26 --option-with-arg-and-flagval=ARGFLAGVAL (&a[1], 'x')
27 --option-with-optional-arg-and-val[=OPTIONALARGVAL] (54)
28 --option-with-optional-arg-and-flagval[=OPTIONALFLAGVAL] (0, 0)
31 that has a line randomly indented
40 AT_CHECK([$AWK -f "$builddir/scripts/gen-options.awk" <options.def >options.h])
43 [[struct option { const char *name; int has_arg; int *flag; int val; };
49 [[#include "context.h"
52 static const char sopts[] = SOPT_STRING;
53 static const struct option opts[] = { LOPTS_INITIALIZER, {0} };
60 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [], [ignore])
62 # test 1: long option names and help text
70 static const struct option opts[] = { LOPTS_INITIALIZER };
76 for (i = 0; i < sizeof opts / sizeof opts[0]; i++) {
77 struct lopt_help help = { "INVALID", "INVALID" };
79 if (!lopt_get_help(&opts[i], &help))
82 printf("--%s", opts[i].name);
84 printf("=%s", help.arg);
85 printf("\n%s", help.desc);
94 # pick out interesting bits from the definitions file
95 sed -n '/^-/s/^.*--\([[^\= @<:@]]*\).*$/\1/p' options.def >options
97 s/[[^=]]*\(=[[^@:>@ ]]*\).*$/\1/
101 }' options.def >argnames
103 AS_ECHO(["-"]) | sed -n '1s/^-.*//p
121 s/[[^\n]][[^\n]]*/\\"&\\"/g
126 ' options.def - >helptext
128 exec 3<options 4<argnames 5<helptext 6>expout
129 while read opt <&3 && read arg <&4 && read help <&5; do
130 if test ${arg:+y}; then
131 AS_ECHO(["--$opt=$arg"]) >&6
133 AS_ECHO(["--$opt"]) >&6
135 eval "set x $help"; shift
138 AS_ECHO(["$arg"]) >&6
141 exec 3<&- 4<&- 5<&- 6>&-
143 AT_CHECK([$CC -o test1$EXEEXT test1.c && ./test1$EXEEXT],
144 [0], [expout], [ignore])
146 # test 2: short option string
156 struct option lopts[] = {LOPTS_INITIALIZER};
159 for (i = 0; i < sizeof SOPT_STRING - 1; i++) {
160 if (SOPT_STRING[i] != ':') {
161 for (j = 0; j < sizeof lopts / sizeof lopts[0]; j++) {
162 if (lopts[j].val == SOPT_STRING[i]) {
163 printf("--%s ", lopts[j].name);
168 putchar(SOPT_STRING[i]);
169 if (SOPT_STRING[i+1] != ':')
178 s/^-\([[^-]]\)[[^:]]*/\1/p
180 }' options.def >sopts
182 exec 3<options 4<sopts 5>expout
183 while read lopt <&3 && read sopt <&4; do
184 if test ${sopt:+y}; then
185 AS_ECHO(["--$lopt $sopt"]) >&5
190 AT_CHECK([$CC -o test2$EXEEXT test2.c && ./test2$EXEEXT],
191 [0], [expout], [ignore])
193 # Check that all help strings are translatable
194 sed 's/\([[^\\]]\\\)" /\1\\n\\" /g' helptext >help-po
195 exec 3<options 4<argnames 5<help-po 6>expected.po
196 while read opt <&3 && read arg <&4 && read help <&5; do
197 if test ${arg:+y}; then
198 AS_ECHO(["msgctxt \"$opt\" msgid \"$arg\""]) >&6
200 AS_ECHO(["msgctxt \"$opt\" msgid${help:+ }$help"]) >&6
202 exec 3<&- 4<&- 5<&- 6>&-
204 AT_CHECK([xgettext --keyword=PN_:1c,2 options.h
205 test -f messages.po || exit 77])
207 LC_ALL=C sort expected.po >expout
208 AT_CHECK([sed -n '/^msgctxt/{
219 }' messages.po | LC_ALL=C sort], [0], [expout])
223 AT_SETUP([gen-strtab.awk])
224 AT_KEYWORDS([gen-strtab awk script scripts])
249 AT_CHECK([$AWK -f "$builddir/scripts/gen-strtab.awk" <test.def >test.h])
251 sed -n 's/^[[&]]\([[^ ]]*\).*/\1/p' test.def >identifiers
253 # test 0: sanity test
262 exec 3<identifiers 4>>test0.c
263 while read ident <&3; do
264 AS_ECHO([' printf("%s\n---\n", '"strtab+$ident);"]) >&4
266 AS_ECHO([' return 0;']) >&4
270 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [---
305 AT_SETUP([gen-tree.awk])
306 AT_KEYWORDS([gen-tree awk script scripts])
333 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <tree.def >tree.h])
339 struct tree { unsigned id, subtree; };
341 static const struct tree tree0[] = {
344 static const struct tree tree1[] = {
348 void print_subtree(const struct tree *root, unsigned offset, int depth)
350 const struct tree *node;
352 for (node = &root[offset]; node->id; node++) {
353 printf("%*s%s", 2*depth, "", &tree_strtab[node->id]);
355 printf(", %s_OFFSET\n", &tree_strtab[node->id]);
356 print_subtree(root, node->subtree, depth+1);
366 print_subtree(tree0, 0, 1);
368 print_subtree(tree1, 0, 1);
372 sed '/^#/d' tree.def >expout
373 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [expout])
377 # Test the gen-tree features that avoid creating string labels for nodes.
378 AT_SETUP([gen-tree.awk @nostrtab option])
379 AT_KEYWORDS([gen-tree awk script scripts])
391 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <tree.def >tree.h])
394 [[float tree_strtab = 0;
403 static struct { int num, offset; } root[] = { ROOT_INITIALIZER };
408 for (i = 0; i < sizeof root / sizeof root[0]; i++) {
409 printf("%d, %d\n", root[i].num, root[i].offset);
414 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0],
433 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <flat.def >flat.h])
435 sed -e 's/tree\.h/flat.h/' -e 's/ROOT/FLAT/' test0.c >test1.c
436 AT_CHECK([$CC -o test1$EXEEXT test1.c && ./test1$EXEEXT], [0],
446 AT_KEYWORDS([join awk script scripts])
448 JOIN="$AWK -f $builddir/scripts/join.awk --"
475 AT_CHECK([$JOIN a b], [0],
486 AT_CHECK([$JOIN -v1 a b], [0],
494 AT_CHECK([$JOIN -v2 a b], [0],
501 AT_CHECK([$JOIN -v1 -v2 a b], [0],
513 AT_CHECK([$JOIN -a1 a b], [0],
529 AT_CHECK([$JOIN -a2 a b], [0],
544 AT_CHECK([$JOIN -a1 -a2 a b], [0],
564 AT_CHECK([$JOIN b a], [0],
575 AT_CHECK([$JOIN -v1 b a], [0],
582 AT_CHECK([$JOIN -v2 b a], [0],
590 AT_CHECK([$JOIN -v1 -v2 b a], [0],
602 AT_CHECK([$JOIN -a1 b a], [0],
617 AT_CHECK([$JOIN -a2 b a], [0],
633 AT_CHECK([$JOIN -a1 -a2 b a], [0],
653 AT_CHECK([echo wat | $JOIN -v1 - /dev/null], [0],
659 m4_divert_push([PREPARE_TESTS])dnl
661 $PERL -e 'my $x = 42; exit $x;'; test $? = 42 || exit 77
662 $PERL -f "$srcdir/scripts/fix-ltdl.pl" "$@"
665 $PERL -e 'my $x = 42; exit $x;'; test $? = 42 || exit 77
666 $PERL -f "$srcdir/scripts/fix-gnulib.pl" "$@"
672 sed -n -f - "$srcdir/tests/data/gnulib.mk" <<EOF
673 /^## begin gnulib module $arg/,/^## end gnulib module $arg/p
677 m4_divert_pop([PREPARE_TESTS])
679 AT_SETUP([fix-gnulib.pl SED_HEADER variables])
681 test_gnulib_mk gen-header >test.mk.in
682 AT_CHECK([grep SED_HEADER test.mk.in >expout || exit 99])
683 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
684 grep SED_HEADER test.mk], [0], [expout])
688 AT_SETUP([fix-gnulib.pl %reldir% substitution])
690 test_gnulib_mk sys_types >test.mk.in
691 AT_CHECK([grep '%reldir%' test.mk.in >/dev/null || exit 99])
693 sed -n -f - test.mk.in >expout <<'EOF'
695 /^## begin gnulib/,/^## end gnulib/!b
697 s|(srcdir)|(top_srcdir)|
699 s|BUILT_SOURCES|gnulib_core_headers|
701 /^MOSTLYCLEANFILES/{h;b}
705 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
706 sed -n -e '/^## begin gnulib/,/^## end gnulib/p' \
707 -e '/CLEANFILES/p' test.mk],
712 AT_SETUP([fix-gnulib.pl warning removal])
714 AT_DATA([test.mk.in], [[
716 noinst_LTLIBRARIES += libgnu.la
717 libgnu_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS)
718 noinst_LIBRARIES += libgnu.a
719 libgnu_a_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS)
722 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
723 sed -n '/^## test begin/,/^## test end/p' test.mk], [0], [## test begin
724 EXTRA_LTLIBRARIES += libgnu.la
725 EXTRA_LIBRARIES += libgnu.a
731 AT_SETUP([fix-gnulib.pl header directory creation])
733 AT_DATA([extract.sed],
749 test_gnulib_mk alloca-opt sys_types stddef >test.mk.in
750 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
751 sed -n -f extract.sed test.mk], [0],
753 $(AM_V_GEN)$(MKDIR_P) lib
756 $(AM_V_GEN)$(MKDIR_P) lib/sys
759 $(AM_V_GEN)$(MKDIR_P) lib
765 dnl TEST_FIND_AUTOMAKE_VER([to-check], [test-action])
767 dnl For each whitespace-separated version token in to-check, check if we can
768 dnl run the programs automake-VER and aclocal-VER. The special token 'default'
769 dnl also checks the unversioned automake and aclocal (or, if set in the
770 dnl environment, $AUTOMAKE and $ACLOCAL).
772 dnl Then test-action is expanded such that shell variables $ac and $am refer to
773 dnl the aclocal and automake programs, and $amver is the actual version
774 dnl reported by --version. The action should do nothing if the version is
775 dnl acceptable, or "continue" if the version is unacceptable.
777 dnl If an acceptable version is found, the AUTOMAKE and ACLOCAL environment
778 dnl variables are set accordingly. Otherwise, the test group is skipped.
779 m4_define([TEST_FIND_AUTOMAKE],
783 [default], [ac=${ACLOCAL-aclocal} am=${AUTOMAKE-automake}],
784 [ac=aclocal-$am; am=automake-$am])
785 amver=`$am --version | sed -n '1s/.* //p'`
786 acver=`$ac --version | sed -n '1s/.* //p'`
787 set x $amver $acver; shift; test x"$[]#" = x"2" || continue
788 test x"$amver" = x"$acver" || continue
792 AT_CHECK([$have_am || exit 77])
793 AUTOMAKE=$am; export AUTOMAKE
794 ACLOCAL=$ac; export ACLOCAL
795 AT_CHECK([$ACLOCAL --version && $AUTOMAKE --version], [0], [stdout])
798 m4_define([TEST_LTDL_LIBOBJ_MANGLING],
799 [TEST_CONFIGURE_AC([[AM_INIT_AUTOMAKE([foreign subdir-objects])
802 AC_SUBST([ltdl_LTLIBOBJS], [libltdl/test.lo])
803 AC_CONFIG_FILES([Makefile])
807 AT_DATA([ltdl.mk.in], [[
808 AM_CPPFLAGS += -DSTRING=\"helloworld\"
810 noinst_LTLIBRARIES = libltdl/libltdl.la
811 libltdl_libltdl_la_SOURCES = libltdl/ltdl.c
812 libltdl_libltdl_la_LIBADD = $(ltdl_LTLIBOBJS)
813 libltdl_libltdl_la_DEPENDENCIES = $(ltdl_LTLIBOBJS)
815 EXTRA_DIST += libltdl/test.c
817 AT_DATA([Makefile.am], [[AM_CPPFLAGS =
818 include $(top_srcdir)/ltdl.mk
819 AM_LIBTOOLFLAGS = --quiet
822 test_LDADD = libltdl/libltdl.la
823 all-local: ; @printf '%s\n' $(AM_CPPFLAGS)
825 AT_DATA([libltdl/test.c], [[#include <stdio.h>
826 int foo(void) { printf("%s\n", STRING); return 0; }
828 AT_DATA([libltdl/ltdl.c], [[int foo(void); int main(void) { return foo(); }
831 AT_CHECK([test_fix_ltdl -i ltdl.mk.in -o ltdl.mk])
832 libtoolize; TEST_AUTORECONF
833 TEST_CONFIGURE([--disable-shared])
834 AT_CHECK([make -s && ./test], [0], [
838 AT_SETUP([fix-ltdl.pl LIBOBJ mangling (<automake-1.16)])
840 TEST_FIND_AUTOMAKE([default 1.10 1.11 1.12 1.13 1.14 1.15],
841 [AS_VERSION_COMPARE(["$amver"], [1.16], [], [continue], [continue])])
842 TEST_LTDL_LIBOBJ_MANGLING
846 AT_SETUP([fix-ltdl.pl LIBOBJ mangling (>=automake-1.16)])
848 TEST_FIND_AUTOMAKE([default 1.16 1.17 1.18 1.19],
849 [AS_VERSION_COMPARE(["$amver"], [1.16], [continue])])
850 TEST_LTDL_LIBOBJ_MANGLING