Subject: Re: bug#10436: New testsuite driver and extra trailing backslash in recipes

From: Stefano Lattarini <[email-masked]>
Date: Thu, 05 Jan 2012 14:08:41 +0100

On 01/05/2012 01:47 PM, Stefano Lattarini wrote:
> [adding bug-automake in CC:]
> 
> Reference: <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=104367#8>
> 
And here is the definitive version of the patch that I'll push by this
evening (to master) if there is no objection.

Thanks,
  Stefano
>From c891eff22b84027ea56cf67b4c5aac55b75390d9 Mon Sep 17 00:00:00 2001
Message-Id: <c891eff22[email-masked]>
From: Stefano Lattarini <[email-masked]>
Date: Thu, 5 Jan 2012 13:41:13 +0100
Subject: [PATCH] parallel-tests: avoid trailing backslashes in make recipes

The new testsuite-harness could generate recipes with a trailing
backslash character (possibly followed by blank characters only),
in the very common case where the user hadn't defined the special
$(AM_TESTS_FD_REDIRECT) variable.  This caused spurious syntax
errors with at least older bash versions (e.g., bash 2.05b), and
could be potentially unportable to other weaker shells.

See automake bug#10436:
  <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=10436>
and coreutils bug#10427:
  <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=10427#8>

* lib/am/check2.am: Rework line breaks so that no backslash can
be at the end of a line.
* tests/parallel-tests-trailing-bslash.test: New test.
* tests/list-of-tests.mk: Add it.
---
 lib/am/check2.am                          |   10 +-
 tests/list-of-tests.mk                    |    1 +
 tests/parallel-tests-trailing-bslash.test |  114 +++++++++++++++++++++++++++++
 3 files changed, 120 insertions(+), 5 deletions(-)
 create mode 100755 tests/parallel-tests-trailing-bslash.test

diff --git a/lib/am/check2.am b/lib/am/check2.am
index ad0a4aa..9a0fe9d 100644
--- a/lib/am/check2.am
+++ b/lib/am/check2.am
@@ -1,5 +1,5 @@
 ## automake - create Makefile.in from Makefile.am
-## Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+## Copyright (C) 2008, 2009, 2011, 2012 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
@@ -19,8 +19,8 @@
 ?!GENERIC?%OBJ%: %SOURCE%
 	@p='%SOURCE%'; $(am__check_pre) %DRIVER% --test-name "$$f" \
 	--log-file '%BASE%.log' --trs-file '%BASE%.trs' \
-	$(am__common_driver_flags) %DRIVER_FLAGS% -- %COMPILE% "$$tst" \
-	$(AM_TESTS_FD_REDIRECT)
+	$(am__common_driver_flags) %DRIVER_FLAGS% -- %COMPILE% \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
 ## If no programs are built in this package, then this rule is removed
 ## at automake time.  Otherwise, %am__EXEEXT% expands to a configure time
@@ -30,6 +30,6 @@ if %am__EXEEXT%
 ?GENERIC?%EXT%$(EXEEXT).log:
 	@p='%SOURCE%'; $(am__check_pre) %DRIVER% --test-name "$$f" \
 	--log-file '%BASE%.log' --trs-file '%BASE%.trs' \
-	$(am__common_driver_flags) %DRIVER_FLAGS% -- %COMPILE% "$$tst" \
-	$(AM_TESTS_FD_REDIRECT)
+	$(am__common_driver_flags) %DRIVER_FLAGS% -- %COMPILE% \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 endif %am__EXEEXT%
diff --git a/tests/list-of-tests.mk b/tests/list-of-tests.mk
index 8b4f2ca..dbadfdc 100644
--- a/tests/list-of-tests.mk
+++ b/tests/list-of-tests.mk
@@ -709,6 +709,7 @@ parallel-tests-no-spurious-summary.test \
 parallel-tests-exit-statuses.test \
 parallel-tests-console-output.test \
 parallel-tests-once.test \
+parallel-tests-trailing-bslash.test \
 tests-environment.test \
 am-tests-environment.test \
 tests-environment-backcompat.test \
diff --git a/tests/parallel-tests-trailing-bslash.test b/tests/parallel-tests-trailing-bslash.test
new file mode 100755
index 0000000..418b722
--- /dev/null
+++ b/tests/parallel-tests-trailing-bslash.test
@@ -0,0 +1,114 @@
+#! /bin/sh
+# Copyright (C) 2012 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 that the new testsuite harness do not generate recipes that can
+# have a trailing `\', since that can cause spurious syntax errors with
+# older bash versions (e.g., bash 2.05b).
+# See automake bug#10436.
+
+am_parallel_tests=yes
+. ./defs || Exit 1
+
+echo AC_OUTPUT >> configure.in
+
+cat > Makefile.am <<'END'
+TESTS = foo.test
+EXTRA_DIST = $(TESTS)
+am__backslash = \\ # foo
+.PHONY: bad-recipe
+bad-recipe:
+	@printf '%s\n' $(am__backslash)
+END
+
+cat > foo.test <<'END'
+#!/bin/sh
+exit 0
+END
+chmod +x foo.test
+
+am__SHELL=$SHELL; export am__SHELL
+am__PERL=$PERL; export am__PERL
+
+cat > my-shell <<'END'
+#!/bin/sh -e
+set -u
+tab='	'
+nl='
+'
+am__shell_flags=
+am__shell_command=; unset am__shell_command
+while test $# -gt 0; do
+  case $1 in
+    # If the shell is invoked by make e.g. as "sh -ec" (seen on
+    # GNU make in POSIX mode) or "sh -ce" (seen on Solaris make).
+    -*c*)
+        flg=`echo x"$1" | sed -e 's/^x-//' -e 's/c//g'`
+        if test x"$flg" != x; then
+          am__shell_flags="$am__shell_flags -$flg"
+        fi
+        am__shell_command=$2
+        shift
+        ;;
+    -?*)
+        am__shell_flags="$am__shell_flags $1"
+        ;;
+      *)
+        break
+        ;;
+  esac
+  shift
+done
+if test x${am__shell_command+"set"} != x"set"; then
+  # Some make implementations, like *BSD's, pass the recipes to the shell
+  # through its standard input.  Trying to run our extra checks in this
+  # case would be too tricky, so we just skip them.
+  exec $am__SHELL $am__shell_flags ${1+"$@"}
+else
+  am__tweaked_shell_command=`printf '%s\n' "$am__shell_command" \
+    | tr -d " $tab$nl"`
+  case ${am__tweaked_shell_command-} in
+    *\\)
+      echo "my-shell: recipe ends with backslash character" >&2
+      printf '%s\n' "=== BEGIN recipe" >&2
+      printf '%s\n' "${am__shell_command-}" >&2
+      printf '%s\n' "=== END recipe" >&2
+      exit 99
+      ;;
+  esac
+  exec $am__SHELL $am__shell_flags -c "$am__shell_command" ${1+"$@"}
+fi
+END
+chmod a+x my-shell
+
+cat my-shell
+
+CONFIG_SHELL=`pwd`/my-shell; export CONFIG_SHELL
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+
+./configure CONFIG_SHELL="$CONFIG_SHELL"
+
+st=0
+$MAKE bad-recipe 2>stderr && st=1
+cat stderr >&2
+$FGREP "my-shell: recipe ends with backslash character" stderr || st=1
+test $st -eq 0 || skip_ "can't catch trailing backslashes in make recipes"
+
+$MAKE check
+
+:
-- 
1.7.7.3