Bug introduced by commit v1.11-413-geab64df, ``ylwrap: move "update if changed" logic out of `handle_renaming'``
* lib/ylwrap (tempfile_deploy): New option `--header'; it allows to easily update header files' timestamps only when their content has really changed, while at the same time preserving the correct target name in postprocessing of "#..." C directives. Update other code consequently. * tests/yacclex-cpp-directives.test: New test. * tests/makefile.am (TESTS): Update. --- ChangeLog | 13 ++++ lib/ylwrap | 25 ++++++--- tests/Makefile.am | 1 + tests/Makefile.in | 1 + tests/yacclex-cpp-directives.test | 114 +++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 8 deletions(-) create mode 100755 tests/yacclex-cpp-directives.test diff --git a/ChangeLog b/ChangeLog index 448aa9a..02cf573 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2011-05-06 Stefano Lattarini <stefano.lattar...@gmail.com> + ylwrap: bugfix in postprocessing of "#..." C directives + Bug introduced by commit v1.11-413-geab64df, ``ylwrap: move + "update if changed" logic out of `handle_renaming'`` + * lib/ylwrap (tempfile_deploy): New option `--header'; it allows + to easily update header files' timestamps only when their content + has really changed, while at the same time preserving the correct + target name in postprocessing of "#..." C directives. + Update other code consequently. + * tests/yacclex-cpp-directives.test: New test. + * tests/makefile.am (TESTS): Update. + +2011-05-06 Stefano Lattarini <stefano.lattar...@gmail.com> + tests: add a workaround for automake bug#8485 * tests/yacc-d-cxx.test (Makefile.am): Add temporary workaround for automake bug#8485. The bug is still exposed by the testcase diff --git a/lib/ylwrap b/lib/ylwrap index 7edebb5..58541da 100755 --- a/lib/ylwrap +++ b/lib/ylwrap @@ -78,11 +78,23 @@ set_yacc_filenames () y_output=y.output } -# Usage: tempfile_deploy FROM TARGET +# Usage: tempfile_deploy [--header] FROM TARGET tempfile_deploy () { + if test x"$1" = x"--header"; then + # We do not want to overwrite a header file if it hasn't changed. + # This avoid useless recompilations. However, generated non-header + # C/C++ filed should always be updated, because they are the + # destination of, e.g., `.y.c' rules in the Makefile. + install_target=move_if_change + shift + else + install_target='mv -f' + fi + from=$1 target=$2 + if test ! -f $tempdir/$from; then echo "ylwrap: expected file \`$from' not found" >&2 ret=1 @@ -108,7 +120,9 @@ tempfile_deploy () TARGET=`tr_cpp "$target"` sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$target," \ - -e "s,$FROM,$TARGET," $tempdir/"$from" >"$target" || ret=$? + -e "s,$FROM,$TARGET," $tempdir/"$from" >$tempdir/ylwrap.tmp || ret=$? + + $install_target $tempdir/ylwrap.tmp "$target" } move_if_change () @@ -239,17 +253,12 @@ case $wrapped in c_ext=`echo $y_ext | tr 'y' 'c'` h_ext=`echo $y_ext | tr 'y' 'h'` output_stem=`echo "$output" | sed "s/\\\\.$c_ext$//"` - # We do not want to overwrite a header file if it hasn't - # changed. This avoid useless recompilations. However the - # parser itself should always be updated, because it is the - # destination of the .y.c rule in the Makefile. tempfile_deploy $y_tab_c $output_stem.$c_ext # If the `-d' option is not used, we don't want an error when the # header file is "missing". Similarly, if `-v' is not used, we # don't want an error when the `y.output' file is "missing". if test -f $tempdir/$y_tab_h; then - tempfile_deploy $y_tab_h $tempdir/header.tmp - move_if_change $tempdir/header.tmp $output_stem.$h_ext + tempfile_deploy --header $y_tab_h $output_stem.$h_ext fi if test -f $tempdir/$y_output; then tempfile_deploy $y_output $output_stem.output diff --git a/tests/Makefile.am b/tests/Makefile.am index fc84450..855cc26 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -869,6 +869,7 @@ yflags-force-override.test \ yflags-force-conditional.test \ yflags-var-expand.test \ yacclex-line.test \ +yacclex-cpp-directives.test \ ylwrap-chdir-back-fail.test \ ylwrap-cleanup-fail.test \ ylwrap-extra-args.test \ diff --git a/tests/Makefile.in b/tests/Makefile.in index 108e26d..41a0140 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -1140,6 +1140,7 @@ yflags-force-override.test \ yflags-force-conditional.test \ yflags-var-expand.test \ yacclex-line.test \ +yacclex-cpp-directives.test \ ylwrap-chdir-back-fail.test \ ylwrap-cleanup-fail.test \ ylwrap-extra-args.test \ diff --git a/tests/yacclex-cpp-directives.test b/tests/yacclex-cpp-directives.test new file mode 100755 index 0000000..755b6b4 --- /dev/null +++ b/tests/yacclex-cpp-directives.test @@ -0,0 +1,114 @@ +#! /bin/sh +# Copyright (C) 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 <http://www.gnu.org/licenses/>. + +# Check postprocessing of yacc and lex generated directives "#line", +# "#include", "#define", etc. + +required='lex yacc' +. ./defs || Exit 1 + +set -e + +cat >> configure.in << 'END' +AC_PROG_CC +AC_SUBST([YACC], ['$(abs_top_srcdir)/fake-yacc']) +AC_SUBST([LEX], ['$(abs_top_srcdir)/fake-lex']) +AC_SUBST([LEX_OUTPUT_ROOT], [lex.yy]) +AC_SUBST([LEXLIB], ['']) +AC_OUTPUT +END + +cat > fake-yacc <<'END' +#!/bin/sh -e +sed 's/^ *//' > y.tab.c <<'EOC' + #include "parse.h" + #line 2 "y.tab.c" + #define Y_TAB_C 0 + int yfoo (void) { return PARSE_C; }; +EOC +sed 's/^ *//' > y.tab.h <<'EOH' + #line 1 "y.tab.h" + #define Y_TAB_H 0 + extern int yfoo (void); +EOH +END +chmod a+x fake-yacc + +cat > fake-lex <<'END' +#!/bin/sh -e +sed 's/^ *//' > lex.yy.c <<'EOC' + #line 1 "lex.yy.c" + #define LEX_YY_C 0 + int lbar (void) { return LEXER_C; }; +EOC +END + +chmod a+x fake-yacc fake-lex + +cat > Makefile.am << 'END' +bin_PROGRAMS = foo +foo_SOURCES = parse.y lexer.l foo.c +BUILT_SOURCES = parse.h +AM_YFLAGS = -d +END + +: > parse.y +: > lexer.l + +cat > foo.c << 'END' +#include "parse.h" +extern int lbar (void); +int main (void) +{ + return PARSE_H + yfoo () + lbar (); +} +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE -a + +debug_info () +{ + ls -l + cat parse.c + cat parse.h + cat lexer.c +} + +for vpath in : false; do + + if $vpath; then + mkdir build + cd build + srcdir=.. + else + srcdir=. + fi + + $srcdir/configure + + $MAKE || { debug_info; Exit 1; } + debug_info + + $EGREP '#.*(Y.TAB|YLWRAP)|y\.tab' parse.[ch] && Exit 1 + $EGREP '#.*(LEX.Y|YLWRAP)|lex\.yy' lexer.c && Exit 1 + + cd $srcdir + +done + +: -- 1.7.2.3