1 dnl Copyright © 2021-2023 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-strtab.awk @nozero option])
306 AT_KEYWORDS([gen-strtab awk script scripts])
311 AT_CHECK([$AWK -f "$builddir/scripts/gen-strtab.awk" <test0.def >test0.h])
317 AT_CHECK([$AWK -f "$builddir/scripts/gen-strtab.awk" <test1.def >test1.h])
322 int main(void) { printf("%d %s\n", hello, strtab+hello); return 0; }
324 AT_CHECK([$CC -DHEADER='"test0.h"' -o test0$EXEEXT test.c && ./test0$EXEEXT],
327 AT_CHECK([$CC -DHEADER='"test1.h"' -o test1$EXEEXT test.c && ./test1$EXEEXT],
333 AT_SETUP([gen-tree.awk])
334 AT_KEYWORDS([gen-tree awk script scripts])
361 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <tree.def >tree.h])
367 struct tree { unsigned id, subtree; };
369 static const struct tree tree0[] = {
372 static const struct tree tree1[] = {
376 void print_subtree(const struct tree *root, unsigned offset, int depth)
378 const struct tree *node;
380 for (node = &root[offset]; node->id; node++) {
381 printf("%*s%s", 2*depth, "", &tree_strtab[node->id]);
383 printf(", %s_OFFSET\n", &tree_strtab[node->id]);
384 print_subtree(root, node->subtree, depth+1);
394 print_subtree(tree0, 0, 1);
396 print_subtree(tree1, 0, 1);
400 sed '/^#/d' tree.def >expout
401 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [expout])
405 # Test the gen-tree features that avoid creating string labels for nodes.
406 AT_SETUP([gen-tree.awk @nostrtab option])
407 AT_KEYWORDS([gen-tree awk script scripts])
419 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <tree.def >tree.h])
422 [[float tree_strtab = 0;
431 static struct { int num, offset; } root[] = { ROOT_INITIALIZER };
436 for (i = 0; i < sizeof root / sizeof root[0]; i++) {
437 printf("%d, %d\n", root[i].num, root[i].offset);
442 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0],
461 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <flat.def >flat.h])
463 sed -e 's/tree\.h/flat.h/' -e 's/ROOT/FLAT/' test0.c >test1.c
464 AT_CHECK([$CC -o test1$EXEEXT test1.c && ./test1$EXEEXT], [0],
474 AT_KEYWORDS([join awk script scripts])
476 JOIN="$AWK -f $builddir/scripts/join.awk --"
503 AT_CHECK([$JOIN a b], [0],
514 AT_CHECK([$JOIN -v1 a b], [0],
522 AT_CHECK([$JOIN -v2 a b], [0],
529 AT_CHECK([$JOIN -v1 -v2 a b], [0],
541 AT_CHECK([$JOIN -a1 a b], [0],
557 AT_CHECK([$JOIN -a2 a b], [0],
572 AT_CHECK([$JOIN -a1 -a2 a b], [0],
592 AT_CHECK([$JOIN b a], [0],
603 AT_CHECK([$JOIN -v1 b a], [0],
610 AT_CHECK([$JOIN -v2 b a], [0],
618 AT_CHECK([$JOIN -v1 -v2 b a], [0],
630 AT_CHECK([$JOIN -a1 b a], [0],
645 AT_CHECK([$JOIN -a2 b a], [0],
661 AT_CHECK([$JOIN -a1 -a2 b a], [0],
681 AT_CHECK([echo wat | $JOIN -v1 - /dev/null], [0],
687 m4_divert_push([PREPARE_TESTS])dnl
689 $PERL -e 'my $x = 42; exit $x;'; test $? = 42 || exit 77
690 $PERL -f "$srcdir/scripts/fix-ltdl.pl" "$@"
693 $PERL -e 'my $x = 42; exit $x;'; test $? = 42 || exit 77
694 $PERL -f "$srcdir/scripts/fix-gnulib.pl" "$@"
700 sed -n -f - "$srcdir/tests/data/gnulib.mk" <<EOF
701 /^## begin gnulib module $arg/,/^## end gnulib module $arg/p
705 m4_divert_pop([PREPARE_TESTS])
707 AT_SETUP([fix-gnulib.pl SED_HEADER variables])
709 test_gnulib_mk gen-header >test.mk.in
710 AT_CHECK([grep SED_HEADER test.mk.in >expout || exit 99])
711 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
712 grep SED_HEADER test.mk], [0], [expout])
716 AT_SETUP([fix-gnulib.pl %reldir% substitution])
718 test_gnulib_mk sys_types >test.mk.in
719 AT_CHECK([grep '%reldir%' test.mk.in >/dev/null || exit 99])
721 sed -n -f - test.mk.in >expout <<'EOF'
723 /^## begin gnulib/,/^## end gnulib/!b
725 s|(srcdir)|(top_srcdir)|
727 s|BUILT_SOURCES|gnulib_core_headers|
729 /^MOSTLYCLEANFILES/{h;b}
733 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
734 sed -n -e '/^## begin gnulib/,/^## end gnulib/p' \
735 -e '/CLEANFILES/p' test.mk],
740 AT_SETUP([fix-gnulib.pl warning removal])
742 AT_DATA([test.mk.in], [[
744 noinst_LTLIBRARIES += libgnu.la
745 libgnu_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS)
746 noinst_LIBRARIES += libgnu.a
747 libgnu_a_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS)
750 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
751 sed -n '/^## test begin/,/^## test end/p' test.mk], [0], [## test begin
752 EXTRA_LTLIBRARIES += libgnu.la
753 EXTRA_LIBRARIES += libgnu.a
759 AT_SETUP([fix-gnulib.pl header directory creation])
761 AT_DATA([extract.sed],
777 test_gnulib_mk alloca-opt sys_types stddef >test.mk.in
778 AT_CHECK([test_fix_gnulib -i test.mk.in -o test.mk || exit
779 sed -n -f extract.sed test.mk], [0],
781 $(AM_V_GEN)$(MKDIR_P) lib
784 $(AM_V_GEN)$(MKDIR_P) lib/sys
787 $(AM_V_GEN)$(MKDIR_P) lib
793 dnl TEST_FIND_AUTOMAKE_VER([to-check], [test-action])
795 dnl For each whitespace-separated version token in to-check, check if we can
796 dnl run the programs automake-VER and aclocal-VER. The special token 'default'
797 dnl also checks the unversioned automake and aclocal (or, if set in the
798 dnl environment, $AUTOMAKE and $ACLOCAL).
800 dnl Then test-action is expanded such that shell variables $ac and $am refer to
801 dnl the aclocal and automake programs, and $amver is the actual version
802 dnl reported by --version. The action should do nothing if the version is
803 dnl acceptable, or "continue" if the version is unacceptable.
805 dnl If an acceptable version is found, the AUTOMAKE and ACLOCAL environment
806 dnl variables are set accordingly. Otherwise, the test group is skipped.
807 m4_define([TEST_FIND_AUTOMAKE],
811 [default], [ac=${ACLOCAL-aclocal} am=${AUTOMAKE-automake}],
812 [ac=aclocal-$am; am=automake-$am])
813 amver=`$am --version | sed -n '1s/.* //p'`
814 acver=`$ac --version | sed -n '1s/.* //p'`
815 set x $amver $acver; shift; test x"$[]#" = x"2" || continue
816 test x"$amver" = x"$acver" || continue
820 AT_CHECK([$have_am || exit 77])
821 AUTOMAKE=$am; export AUTOMAKE
822 ACLOCAL=$ac; export ACLOCAL
823 AT_CHECK([$ACLOCAL --version && $AUTOMAKE --version], [0], [stdout])
826 m4_define([TEST_LTDL_LIBOBJ_MANGLING],
827 [TEST_CONFIGURE_AC([[AM_INIT_AUTOMAKE([foreign subdir-objects])
830 AC_SUBST([ltdl_LTLIBOBJS], [libltdl/test.lo])
831 AC_CONFIG_FILES([Makefile])
835 AT_DATA([ltdl.mk.in], [[
836 AM_CPPFLAGS += -DSTRING=\"helloworld\"
838 noinst_LTLIBRARIES = libltdl/libltdl.la
839 libltdl_libltdl_la_SOURCES = libltdl/ltdl.c
840 libltdl_libltdl_la_LIBADD = $(ltdl_LTLIBOBJS)
841 libltdl_libltdl_la_DEPENDENCIES = $(ltdl_LTLIBOBJS)
843 EXTRA_DIST += libltdl/test.c
845 AT_DATA([Makefile.am], [[AM_CPPFLAGS =
846 include $(top_srcdir)/ltdl.mk
847 AM_LIBTOOLFLAGS = --quiet
850 test_LDADD = libltdl/libltdl.la
851 all-local: ; @printf '%s\n' $(AM_CPPFLAGS)
853 AT_DATA([libltdl/test.c], [[#include <stdio.h>
854 int foo(void) { printf("%s\n", STRING); return 0; }
856 AT_DATA([libltdl/ltdl.c], [[int foo(void); int main(void) { return foo(); }
859 AT_CHECK([test_fix_ltdl -i ltdl.mk.in -o ltdl.mk])
860 libtoolize; TEST_AUTORECONF
861 TEST_CONFIGURE([--disable-shared])
862 AT_CHECK([make -s && ./test], [0], [
866 AT_SETUP([fix-ltdl.pl LIBOBJ mangling (<automake-1.16)])
868 TEST_FIND_AUTOMAKE([default 1.10 1.11 1.12 1.13 1.14 1.15],
869 [AS_VERSION_COMPARE(["$amver"], [1.16], [], [continue], [continue])])
870 TEST_LTDL_LIBOBJ_MANGLING
874 AT_SETUP([fix-ltdl.pl LIBOBJ mangling (>=automake-1.16)])
876 TEST_FIND_AUTOMAKE([default 1.16 1.17 1.18 1.19],
877 [AS_VERSION_COMPARE(["$amver"], [1.16], [continue])])
878 TEST_LTDL_LIBOBJ_MANGLING