From eb147a19783b1cee960502697124e68e4c109df5 Mon Sep 17 00:00:00 2001 From: Stefano Lattarini Date: Wed, 25 May 2011 19:05:15 +0200 Subject: [PATCH] lex tests: avoid spurious failures when LEXLIB isn't found The AC_PROG_LEX Autoconf macro does not diagnose a failure to find the "lex library" expected to provide a `yywrap' function (function which is required to link most lex-generated programs). On the contrary, when all the link attempts (i.e., with `-ll' and `-lfl') fail, configure declares that no lex library is needed, and simply proceeds with the configuration process -- only for the build to possibly fail later, at make time. This behaviour might be (partly) intended; the Autoconf manual reads: ``You are encouraged to use Flex in your sources, since it is both more pleasant to use than plain Lex and the C source it produces is portable. In order to ensure portability, however, you must either provide a function `yywrap' or, if you don't use it (e.g., your scanner has no `#include'-like feature), simply include a `%noyywrap' statement in the scanner's source.'' This AC_PROG_LEX behaviour is causing some spurious failures of the Automake testsuite in environments which lack a proper library providing `yywrap' (this happens for example in Linux->MinGW cross compilations). But at this point is clear that a proper workaround is to simply provide a fall-back implementation of `yywrap' in our lexers. * tests/cond35.test: Provide a dummy `yywrap' function. * tests/lex3.test: Likewise. * tests/lexvpath.test: Likewise. * tests/silent-many-gcc.test: Likewise. * tests/silent-many-generic.test: Likewise. * tests/silent-lex-gcc.test: Likewise, and a dummy `main' too. * tests/silent-lex-generic.test: Likewise. * tests/lex-lib.test: New test. * tests/lex-libobj.test: New test. * tests/lex-nowrap.test: New test. * tests/Makefile.am (TESTS): Update. * THANKS: Update. Thanks to Russ Allbery for the suggestion. --- ChangeLog | 39 ++++++++++++++++++ THANKS | 1 + tests/Makefile.am | 3 ++ tests/Makefile.in | 3 ++ tests/cond35.test | 6 +++ tests/lex-lib.test | 67 ++++++++++++++++++++++++++++++ tests/lex-libobj.test | 75 ++++++++++++++++++++++++++++++++++ tests/lex-noyywrap.test | 72 ++++++++++++++++++++++++++++++++ tests/lex3.test | 10 ++++- tests/lexvpath.test | 12 +++++- tests/silent-lex-gcc.test | 9 ++++ tests/silent-lex-generic.test | 9 ++++ tests/silent-many-gcc.test | 5 +++ tests/silent-many-generic.test | 5 +++ 14 files changed, 312 insertions(+), 4 deletions(-) create mode 100755 tests/lex-lib.test create mode 100755 tests/lex-libobj.test create mode 100755 tests/lex-noyywrap.test diff --git a/ChangeLog b/ChangeLog index d26268d15..3e6269bc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2011-05-25 Stefano Lattarini + + lex tests: avoid spurious failures when LEXLIB isn't found + The AC_PROG_LEX Autoconf macro does not diagnose a failure to find + the "lex library" expected to provide a `yywrap' function (function + which is required to link most lex-generated programs). On the + contrary, when all the link attempts (i.e., with `-ll' and `-lfl') + fail, configure declares that no lex library is needed, and simply + proceeds with the configuration process -- only for the build to + possibly fail later, at make time. + This behaviour might be (partly) intended; the Autoconf manual + reads: + ``You are encouraged to use Flex in your sources, since it is + both more pleasant to use than plain Lex and the C source + it produces is portable. In order to ensure portability, + however, you must either provide a function `yywrap' or, if + you don't use it (e.g., your scanner has no `#include'-like + feature), simply include a `%noyywrap' statement in the + scanner's source.'' + This AC_PROG_LEX behaviour is causing some spurious failures of the + Automake testsuite in environments which lack a proper library + providing `yywrap' (this happens for example in Linux->MinGW cross + compilations). But at this point is clear that a proper workaround + is to simply provide a fall-back implementation of `yywrap' in our + lexers. + * tests/cond35.test: Provide a dummy `yywrap' function. + * tests/lex3.test: Likewise. + * tests/lexvpath.test: Likewise. + * tests/silent-many-gcc.test: Likewise. + * tests/silent-many-generic.test: Likewise. + * tests/silent-lex-gcc.test: Likewise, and a dummy `main' too. + * tests/silent-lex-generic.test: Likewise. + * tests/lex-lib.test: New test. + * tests/lex-libobj.test: New test. + * tests/lex-nowrap.test: New test. + * tests/Makefile.am (TESTS): Update. + * THANKS: Update. + Thanks to Russ Allbery for the suggestion. + 2011-05-25 Stefano Lattarini testsuite: require C++ compiler explicitly in tests needing it diff --git a/THANKS b/THANKS index 5ee0e4c7c..96d215e60 100644 --- a/THANKS +++ b/THANKS @@ -310,6 +310,7 @@ Roberto Bagnara bagnara@cs.unipr.it Roman Fietze roman.fietze@telemotive.de Ronald Landheer ronald@landheer.com Roumen Petrov bugtrack@roumenpetrov.info +Russ Allbery rra@stanford.edu Rusty Ballinger rusty@rlyeh.engr.sgi.com Ryan T. Sammartino ryants@shaw.ca Sam Hocevar sam@zoy.org diff --git a/tests/Makefile.am b/tests/Makefile.am index ff20e25d7..976883341 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -566,6 +566,9 @@ lex5.test \ lexcpp.test \ lexvpath.test \ lex-subobj-nodep.test \ +lex-lib.test \ +lex-libobj.test \ +lex-noyywrap.test \ lflags.test \ lflags2.test \ libexec.test \ diff --git a/tests/Makefile.in b/tests/Makefile.in index 55647eeea..55fb244fd 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -831,6 +831,9 @@ lex5.test \ lexcpp.test \ lexvpath.test \ lex-subobj-nodep.test \ +lex-lib.test \ +lex-libobj.test \ +lex-noyywrap.test \ lflags.test \ lflags2.test \ libexec.test \ diff --git a/tests/cond35.test b/tests/cond35.test index 2fba1f1e1..348b9c7c2 100755 --- a/tests/cond35.test +++ b/tests/cond35.test @@ -59,6 +59,12 @@ test `grep tparse.h: Makefile.in | wc -l` = 1 cat > tscan.l << 'END' %% "END" return EOF; +%% +/* Avoid possible link errors. */ +int yywrap (void) +{ + return 0; +} END cat > tparse.y << 'END' diff --git a/tests/lex-lib.test b/tests/lex-lib.test new file mode 100755 index 000000000..07af3ff19 --- /dev/null +++ b/tests/lex-lib.test @@ -0,0 +1,67 @@ +#! /bin/sh +# Copyright (C) 1999, 2001, 2002, 2003, 2004, 2010, 2011 Free Software +# Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check that we can provide a personal `yywrap' function in a custom +# library. + +required='cc lex' +. ./defs || Exit 1 + +cat >> configure.in << 'END' +AC_PROG_CC +AC_PROG_RANLIB +LEXLIB=libmylex.a +AC_PROG_LEX +AC_OUTPUT +END + +cat > Makefile.am << 'END' +bin_PROGRAMS = lexer +lexer_SOURCES = foo.l +lexer_LDADD = $(LEXLIB) +EXTRA_lexer_DEPENDENCIES = $(LEXLIB) +noinst_LIBRARIES = libmylex.a +libmylex_a_SOURCES = mu.c +END + +cat > mu.c << 'END' +int yywrap (void) +{ + return 0; +} +END + +cat > foo.l <<'END' +%% +. +%% +int main (void) +{ + return 0; +} +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE -a + +./configure +$MAKE +test -f foo.c +test -f libmylex.a + +: diff --git a/tests/lex-libobj.test b/tests/lex-libobj.test new file mode 100755 index 000000000..1ca1d4c9b --- /dev/null +++ b/tests/lex-libobj.test @@ -0,0 +1,75 @@ +#! /bin/sh +# Copyright (C) 1999, 2001, 2002, 2003, 2004, 2010, 2011 Free Software +# Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check that we can provide a personal `yywrap' function through the +# LIBOBJ machinery. + +required='cc lex' +. ./defs || Exit 1 + +cat >> configure.in << 'END' +AC_PROG_CC +AC_PROG_RANLIB +AC_PROG_LEX +save_LIBS=$LIBS +LIBS="$LEXLIB $LIBS" +AC_REPLACE_FUNCS([yywrap]) +LIBS=$save_LIBS +AC_OUTPUT +END + +cat > Makefile.am << 'END' +noinst_PROGRAMS = foo +foo_SOURCES = foo.l +foo_LDADD = $(LEXLIB) $(LIBOBJS) +END + +cat > yywrap.c << 'END' +int yywrap (void) +{ + return 0; +} +END + +cat > foo.l <<'END' +%% +. +%% +int main (void) +{ + return 0; +} +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE -a + +./configure +grep LIBOBJS Makefile # For debugging. +$MAKE +$MAKE distclean + +# Force no "system lex library". +./configure LEXLIB='-L /lib' +grep LIBOBJS Makefile # For debugging. +grep '^LIBOBJS *=.*yywrap.*\.o' Makefile # Sanity check. +$MAKE + +$MAKE distcheck + +: diff --git a/tests/lex-noyywrap.test b/tests/lex-noyywrap.test new file mode 100755 index 000000000..9431970f9 --- /dev/null +++ b/tests/lex-noyywrap.test @@ -0,0 +1,72 @@ +#! /bin/sh +# Copyright (C) 1999, 2001, 2002, 2003, 2004, 2010, 2011 Free Software +# Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check Lex support with flex using the `%noyywrap' option. + +required='cc flex' +. ./defs || Exit 1 + +cat >> configure.in << 'END' +AC_PROG_CC +AM_PROG_LEX +AC_OUTPUT +END + +cat > Makefile.am << 'END' +bin_PROGRAMS = foo +foo_SOURCES = foo.l + +.PHONY: test-no-lexlib +check-local: test-no-lexlib +test-no-lexlib: + test x'$(LEXLIB)' = x'none needed' +END + +cat > foo.l << 'END' +%option noyywrap +%% +"GOOD" return EOF; +. +%% +int main (void) +{ + /* We don't use a 'while' loop here (like a real lexer would do) + to avoid possible hangs. */ + if (yylex () == EOF) + return 0; + else + return 1; +} +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE -a + +./configure LEXLIB="none needed" + +# Program should build and run. +$MAKE +if cross_compiling; then :; else + echo GOOD | ./foo + echo BAD | ./foo && Exit 1 +fi + +# Sanity check on distribution. +$MAKE distcheck DISTCHECK_CONFIGURE_FLAGS='LEXLIB="none needed"' + +: diff --git a/tests/lex3.test b/tests/lex3.test index 7def55ad9..9c2f5b492 100755 --- a/tests/lex3.test +++ b/tests/lex3.test @@ -39,8 +39,8 @@ cat > foo.l << 'END' "GOOD" return EOF; . %% -int -main () + +int main (void) { /* We don't use a 'while' loop here (like a real lexer would do) to avoid possible hangs. */ @@ -49,6 +49,12 @@ main () else return 1; } + +/* Avoid possible link errors. */ +int yywrap (void) +{ + return 0; +} END $ACLOCAL diff --git a/tests/lexvpath.test b/tests/lexvpath.test index 212db3143..93902b303 100755 --- a/tests/lexvpath.test +++ b/tests/lexvpath.test @@ -52,7 +52,15 @@ cat > lexer.l << 'END' END cat > foo.c << 'END' -int main () { return 0; } +int main (void) +{ + return 0; +} +/* Avoid possible link errors. */ +int yywrap (void) +{ + return 0; +} END $ACLOCAL @@ -61,7 +69,7 @@ $AUTOMAKE -a mkdir sub -# We must run configure early, to find out whay $LEX_OUTPUT_ROOT is. +# We must run configure early, to find out why $LEX_OUTPUT_ROOT is. cd sub ../configure . ./lexoutroot diff --git a/tests/silent-lex-gcc.test b/tests/silent-lex-gcc.test index a55f35802..2a691c314 100755 --- a/tests/silent-lex-gcc.test +++ b/tests/silent-lex-gcc.test @@ -55,6 +55,15 @@ cat > foo.l <<'EOF' "END" return EOF; . %% +/* Avoid possible link errors. */ +int yywrap (void) +{ + return 0; +} +int main (void) +{ + return 0; +} EOF cp foo.l sub/bar.l diff --git a/tests/silent-lex-generic.test b/tests/silent-lex-generic.test index 7e74d6466..bc3ffffae 100755 --- a/tests/silent-lex-generic.test +++ b/tests/silent-lex-generic.test @@ -55,6 +55,15 @@ cat > foo.l <<'EOF' "END" return EOF; . %% +/* Avoid possible link errors. */ +int yywrap (void) +{ + return 0; +} +int main (void) +{ + return 0; +} EOF cp foo.l sub/bar.l diff --git a/tests/silent-many-gcc.test b/tests/silent-many-gcc.test index 79fa4a634..8cdb35b9f 100755 --- a/tests/silent-many-gcc.test +++ b/tests/silent-many-gcc.test @@ -158,6 +158,11 @@ cat > foo5.l <<'EOF' "END" return EOF; . %% +/* Avoid possible link errors. */ +int yywrap (void) +{ + return 0; +} EOF cat > foo6.y <<'EOF' %{ diff --git a/tests/silent-many-generic.test b/tests/silent-many-generic.test index 9897b0c29..c81f52c88 100755 --- a/tests/silent-many-generic.test +++ b/tests/silent-many-generic.test @@ -160,6 +160,11 @@ cat > foo5.l <<'EOF' "END" return EOF; . %% +/* Avoid possible link errors. */ +int yywrap (void) +{ + return 0; +} EOF cat > foo6.y <<'EOF' %{ -- 2.47.2