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])
11 AT_DATA([options.def],
14 --option-with-flagval (&x, 5)
17 --option-with-optional-arg[=OPTIONAL]
20 -a, --option-with-sopt
22 -b, --option-with-sopt-and-arg=SOPTARG
23 -c, --option-with-sopt-and-optional-arg[=SOPTOPTIONAL]
24 --option-with-arg-and-val=ARGVAL (42)
25 --option-with-arg-and-flagval=ARGFLAGVAL (&a[1], 'x')
26 --option-with-optional-arg-and-val[=OPTIONALARGVAL] (54)
27 --option-with-optional-arg-and-flagval[=OPTIONALFLAGVAL] (0, 0)
30 that has a line randomly indented
39 AT_CHECK([$AWK -f "$builddir/scripts/gen-options.awk" <options.def >options.h])
42 [[struct option { const char *name; int has_arg; int *flag; int val; };
48 [[#include "context.h"
51 static const char sopts[] = SOPT_STRING;
52 static const struct option opts[] = { LOPTS_INITIALIZER, {0} };
59 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [], [ignore])
61 # test 1: long option names and help text
69 static const struct option opts[] = { LOPTS_INITIALIZER };
75 for (i = 0; i < sizeof opts / sizeof opts[0]; i++) {
76 struct lopt_help help = { "INVALID", "INVALID" };
78 if (!lopt_get_help(&opts[i], &help))
81 printf("--%s", opts[i].name);
83 printf("=%s", help.arg);
84 printf("\n%s", help.desc);
93 # pick out interesting bits from the definitions file
94 sed -n '/^-/s/^.*--\([[^\= @<:@]]*\).*$/\1/p' options.def >options
96 s/[[^=]]*\(=[[^@:>@ ]]*\).*$/\1/
100 }' options.def >argnames
102 AS_ECHO(["-"]) | sed -n '1s/^-.*//p
120 s/[[^\n]][[^\n]]*/\\"&\\"/g
125 ' options.def - >helptext
127 exec 3<options 4<argnames 5<helptext 6>expout
128 while read opt <&3 && read arg <&4 && read help <&5; do
129 if test ${arg:+y}; then
130 AS_ECHO(["--$opt=$arg"]) >&6
132 AS_ECHO(["--$opt"]) >&6
134 eval "set x $help"; shift
137 AS_ECHO(["$arg"]) >&6
140 exec 3<&- 4<&- 5<&- 6>&-
142 AT_CHECK([$CC -o test1$EXEEXT test1.c && ./test1$EXEEXT],
143 [0], [expout], [ignore])
145 # test 2: short option string
155 struct option lopts[] = {LOPTS_INITIALIZER};
158 for (i = 0; i < sizeof SOPT_STRING - 1; i++) {
159 if (SOPT_STRING[i] != ':') {
160 for (j = 0; j < sizeof lopts / sizeof lopts[0]; j++) {
161 if (lopts[j].val == SOPT_STRING[i]) {
162 printf("--%s ", lopts[j].name);
167 putchar(SOPT_STRING[i]);
168 if (SOPT_STRING[i+1] != ':')
177 s/^-\([[^-]]\)[[^:]]*/\1/p
179 }' options.def >sopts
181 exec 3<options 4<sopts 5>expout
182 while read lopt <&3 && read sopt <&4; do
183 if test ${sopt:+y}; then
184 AS_ECHO(["--$lopt $sopt"]) >&5
189 AT_CHECK([$CC -o test2$EXEEXT test2.c && ./test2$EXEEXT],
190 [0], [expout], [ignore])
192 # Check that all help strings are translatable
193 sed 's/\([[^\\]]\\\)" /\1\\n\\" /g' helptext >help-po
194 exec 3<options 4<argnames 5<help-po 6>expected.po
195 while read opt <&3 && read arg <&4 && read help <&5; do
196 if test ${arg:+y}; then
197 AS_ECHO(["msgctxt \"$opt\" msgid \"$arg\""]) >&6
199 AS_ECHO(["msgctxt \"$opt\" msgid${help:+ }$help"]) >&6
201 exec 3<&- 4<&- 5<&- 6>&-
203 AT_CHECK([xgettext --keyword=PN_:1c,2 options.h
204 test -f messages.po || exit 77])
206 LC_ALL=C sort expected.po >expout
207 AT_CHECK([sed -n '/^msgctxt/{
218 }' messages.po | LC_ALL=C sort], [0], [expout])
222 AT_SETUP([gen-strtab.awk])
247 AT_CHECK([$AWK -f "$builddir/scripts/gen-strtab.awk" <test.def >test.h])
249 sed -n 's/^[[&]]\([[^ ]]*\).*/\1/p' test.def >identifiers
251 # test 0: sanity test
260 exec 3<identifiers 4>>test0.c
261 while read ident <&3; do
262 AS_ECHO([' printf("%s\n---\n", '"strtab+$ident);"]) >&4
264 AS_ECHO([' return 0;']) >&4
268 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [---
303 AT_SETUP([gen-tree.awk])
326 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <tree.def >tree.h])
332 struct tree { unsigned id, subtree; };
334 static const struct tree tree0[] = {
337 static const struct tree tree1[] = {
341 void print_subtree(const struct tree *root, unsigned offset, int depth)
343 const struct tree *node;
345 for (node = &root[offset]; node->id; node++) {
346 printf("%*s%s", 2*depth, "", &tree_strtab[node->id]);
348 printf(", %s_OFFSET\n", &tree_strtab[node->id]);
349 print_subtree(root, node->subtree, depth+1);
359 print_subtree(tree0, 0, 1);
361 print_subtree(tree1, 0, 1);
365 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [expout])
371 JOIN="$AWK -f $builddir/scripts/join.awk --"
398 AT_CHECK([$JOIN a b], [0],
409 AT_CHECK([$JOIN -v1 a b], [0],
417 AT_CHECK([$JOIN -v2 a b], [0],
424 AT_CHECK([$JOIN -v1 -v2 a b], [0],
436 AT_CHECK([$JOIN -a1 a b], [0],
452 AT_CHECK([$JOIN -a2 a b], [0],
467 AT_CHECK([$JOIN -a1 -a2 a b], [0],
487 AT_CHECK([$JOIN b a], [0],
498 AT_CHECK([$JOIN -v1 b a], [0],
505 AT_CHECK([$JOIN -v2 b a], [0],
513 AT_CHECK([$JOIN -v1 -v2 b a], [0],
525 AT_CHECK([$JOIN -a1 b a], [0],
540 AT_CHECK([$JOIN -a2 b a], [0],
556 AT_CHECK([$JOIN -a1 -a2 b a], [0],
576 AT_CHECK([echo wat | $JOIN -v1 - /dev/null], [0],
582 m4_divert_push([PREPARE_TESTS])dnl
584 $PERL -e 'my $x = 42; exit $x;'; test $? = 42 || exit 77
585 $PERL -f "$srcdir/scripts/fix-ltdl.pl" "$@"
588 $PERL -e 'my $x = 42; exit $x;'; test $? = 42 || exit 77
589 $PERL -f "$srcdir/scripts/fix-gnulib.pl" "$@"
595 sed -n -f - "$srcdir/tests/data/gnulib.mk" <<EOF
596 /^## begin gnulib module $arg/,/^## end gnulib module $arg/p
600 m4_divert_pop([PREPARE_TESTS])
602 AT_SETUP([fix-gnulib.pl SED_HEADER variables])
604 test_gnulib_mk gen-header >test.mk.in
605 AT_CHECK([grep SED_HEADER test.mk.in >expout || exit 99])
606 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
607 grep SED_HEADER test.mk], [0], [expout])
611 AT_SETUP([fix-gnulib.pl %reldir% substitution])
613 test_gnulib_mk sys_types >test.mk.in
614 AT_CHECK([grep '%reldir%' test.mk.in >/dev/null || exit 99])
616 sed -n -f - test.mk.in >expout <<'EOF'
618 /^## begin gnulib/,/^## end gnulib/!b
620 s|(srcdir)|(top_srcdir)|
622 s|BUILT_SOURCES|gnulib_core_headers|
624 /^MOSTLYCLEANFILES/{h;b}
628 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
629 sed -n -e '/^## begin gnulib/,/^## end gnulib/p' \
630 -e '/CLEANFILES/p' test.mk],
635 AT_SETUP([fix-gnulib.pl warning removal])
637 AT_DATA([test.mk.in], [[
639 noinst_LTLIBRARIES += libgnu.la
640 libgnu_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS)
641 noinst_LIBRARIES += libgnu.a
642 libgnu_a_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS)
645 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
646 sed -n '/^## test begin/,/^## test end/p' test.mk], [0], [## test begin
647 EXTRA_LTLIBRARIES += libgnu.la
648 EXTRA_LIBRARIES += libgnu.a
654 AT_SETUP([fix-gnulib.pl header directory creation])
656 AT_DATA([extract.sed],
672 test_gnulib_mk alloca-opt sys_types stddef >test.mk.in
673 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
674 sed -n -f extract.sed test.mk], [0],
676 $(AM_V_GEN)$(MKDIR_P) lib
679 $(AM_V_GEN)$(MKDIR_P) lib/sys
682 $(AM_V_GEN)$(MKDIR_P) lib
688 dnl TEST_FIND_AUTOMAKE_VER([to-check], [test-action])
690 dnl For each whitespace-separated version token in to-check, check if we can
691 dnl run the programs automake-VER and aclocal-VER. The special token 'default'
692 dnl also checks the unversioned automake and aclocal (or, if set in the
693 dnl environment, $AUTOMAKE and $ACLOCAL).
695 dnl Then test-action is expanded such that shell variables $ac and $am refer to
696 dnl the aclocal and automake programs, and $amver is the actual version
697 dnl reported by --version. The action should do nothing if the version is
698 dnl acceptable, or "continue" if the version is unacceptable.
700 dnl If an acceptable version is found, the AUTOMAKE and ACLOCAL environment
701 dnl variables are set accordingly. Otherwise, the test group is skipped.
702 m4_define([TEST_FIND_AUTOMAKE],
706 [default], [ac=${ACLOCAL-aclocal} am=${AUTOMAKE-automake}],
707 [ac=aclocal-$am; am=automake-$am])
708 amver=`$am --version | sed -n '1s/.* //p'`
709 acver=`$ac --version | sed -n '1s/.* //p'`
710 set x $amver $acver; shift; test x"$[]#" = x"2" || continue
711 test x"$amver" = x"$acver" || continue
715 AT_CHECK([$have_am || exit 77])
716 AUTOMAKE=$am; export AUTOMAKE
717 ACLOCAL=$ac; export ACLOCAL
718 AT_CHECK([$ACLOCAL --version && $AUTOMAKE --version], [0], [stdout])
721 m4_define([TEST_LTDL_LIBOBJ_MANGLING],
722 [TEST_CONFIGURE_AC([[AM_INIT_AUTOMAKE([foreign subdir-objects])
725 AC_SUBST([ltdl_LTLIBOBJS], [libltdl/test.lo])
726 AC_CONFIG_FILES([Makefile])
730 AT_DATA([ltdl.mk.in], [[
731 AM_CPPFLAGS += -DSTRING=\"helloworld\"
733 noinst_LTLIBRARIES = libltdl/libltdl.la
734 libltdl_libltdl_la_SOURCES = libltdl/ltdl.c
735 libltdl_libltdl_la_LIBADD = $(ltdl_LTLIBOBJS)
736 libltdl_libltdl_la_DEPENDENCIES = $(ltdl_LTLIBOBJS)
738 EXTRA_DIST += libltdl/test.c
740 AT_DATA([Makefile.am], [[AM_CPPFLAGS =
741 include $(top_srcdir)/ltdl.mk
742 AM_LIBTOOLFLAGS = --quiet
745 test_LDADD = libltdl/libltdl.la
746 all-local: ; @printf '%s\n' $(AM_CPPFLAGS)
748 AT_DATA([libltdl/test.c], [[#include <stdio.h>
749 int foo(void) { printf("%s\n", STRING); return 0; }
751 AT_DATA([libltdl/ltdl.c], [[int foo(void); int main(void) { return foo(); }
754 AT_CHECK([test_fix_ltdl -i ltdl.mk.in -o ltdl.mk])
755 libtoolize; TEST_AUTORECONF
756 TEST_CONFIGURE([--disable-shared])
757 AT_CHECK([make -s && ./test], [0], [
761 AT_SETUP([fix-ltdl.pl LIBOBJ mangling (<automake-1.16)])
763 TEST_FIND_AUTOMAKE([default 1.10 1.11 1.12 1.13 1.14 1.15],
764 [AS_VERSION_COMPARE(["$amver"], [1.16], [], [continue], [continue])])
765 TEST_LTDL_LIBOBJ_MANGLING
769 AT_SETUP([fix-ltdl.pl LIBOBJ mangling (>=automake-1.16)])
771 TEST_FIND_AUTOMAKE([default 1.16 1.17 1.18 1.19],
772 [AS_VERSION_COMPARE(["$amver"], [1.16], [continue])])
773 TEST_LTDL_LIBOBJ_MANGLING