| #!/bin/sh | |
| # Check GNU m4 against examples from the manual source. | |
| # Copyright (C) 1992, 2006-2014, 2016-2017, 2020-2025 Free Software | |
| # Foundation, Inc. | |
| # | |
| # This file is part of GNU M4. | |
| # | |
| # GNU M4 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 3 of the License, or | |
| # (at your option) any later version. | |
| # | |
| # GNU M4 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 <https://www.gnu.org/licenses/>. | |
| # Clean up temp files on exit | |
| pwd=`pwd` | |
| tmp=m4-tmp.$$ | |
| trap 'stat=$?; cd "$pwd"; rm -rf $tmp && exit $stat' 0 | |
| trap '(exit $?); exit $?' 1 2 13 15 | |
| # Create scratch dir | |
| framework_failure=0 | |
| mkdir $tmp || framework_failure=1 | |
| if test $framework_failure = 1; then | |
| echo "$0: failure in testing framework" 1>&2 | |
| (exit 1); exit 1 | |
| fi | |
| out=$tmp/m4-out | |
| err=$tmp/m4-err | |
| xout=$tmp/m4-xout | |
| xerr=$tmp/m4-xerr | |
| xaux=$tmp/m4-xaux | |
| failed= | |
| skipped= | |
| strip_needed=false | |
| diffopts=-c | |
| # Allow user to select sed | |
| : ${SED=sed} | |
| # Find out where the examples live. | |
| examples=. | |
| if test "x$1" = x-I ; then | |
| examples="$2" | |
| shift; shift | |
| fi | |
| # Find out how to run m4. | |
| m4=m4 | |
| if test "x$1" = x-m ; then | |
| m4="$2" | |
| shift; shift | |
| fi | |
| # Find out how the executable prints argv[0] | |
| m4name=`"$m4" --help | ${SED} -e 's/Usage: \(.*\) \[OPTION.*/\1/' \ | |
| -e 's/\\\\/\\\\\\\\/g' -e 1q` | |
| # Find out if we should strip \r in the output | |
| "$m4" --version | tee $out | |
| "$m4" --version | tr -d '\015' > $xout | |
| if cmp -s $out $xout; then | |
| : | |
| else | |
| echo "Ignoring carriage returns" | |
| strip_needed=: | |
| fi | |
| # Find out what version the executable claims to be | |
| m4version=`${SED} -n 's/.* //p;q' $out` | |
| # Find out if diff supports useful options. | |
| if diff -u /dev/null /dev/null 2>/dev/null ; then | |
| diffopts="-u" | |
| fi | |
| if diff -a /dev/null /dev/null 2>/dev/null ; then | |
| diffopts="$diffopts -a" | |
| fi | |
| # Run the tests. | |
| for file | |
| do | |
| test -f "$file" || { | |
| echo "No such file: $file" | |
| continue | |
| } | |
| echo "Checking $file" | |
| case $file in | |
| *stackovf.test) | |
| "$file" "$m4" | |
| case $? in | |
| 77) skipped="$skipped $file";; | |
| 0) ;; | |
| *) failed="$failed $file" | |
| esac | |
| continue ;; | |
| esac | |
| options=`${SED} -ne "3 { s|TMP/|$tmp/|g; s/^dnl @ extra options: //p; q }" \ | |
| "$file"` | |
| ${SED} -e '/^dnl @/d' -e '/^\^D$/q' "$file" \ | |
| | LC_MESSAGES=C LANG=C M4PATH=$examples "$m4" -d $options - >$out 2>$err | |
| stat=$? | |
| xstat=`${SED} -ne '2s/^dnl @ expected status: //p;2q' "$file"` | |
| case $stat in | |
| 77) | |
| skipped="$skipped $file" | |
| cat $err | |
| continue | |
| ;; | |
| $xstat) ;; | |
| *) | |
| failed="$failed $file:status" | |
| echo `${SED} -e 's/^dnl //' -e 1q $file` | |
| echo "$file: status was $stat, expected $xstat" | |
| ;; | |
| esac | |
| xoutfile=`${SED} -n 's/^dnl @ expected output: //p' "$file"` | |
| if test -z "$xoutfile" ; then | |
| ${SED} -e '/^dnl @result{}/!d' -e 's///' -e "s|examples/|$examples/|" \ | |
| -e "s|@value{VERSION}|$m4version|" "$file" > $xout | |
| else | |
| cp "$examples/$xoutfile" $xout | |
| fi | |
| xerrfile=`${SED} -n 's/^dnl @ expected error: //p' "$file"` | |
| case $xerrfile in | |
| ignore) | |
| cp $err $xerr ;; | |
| '') | |
| ${SED} '/^dnl @error{}/!d | |
| s///; '"s|^m4:|$m4name:|; s|examples/|$examples/|" \ | |
| "$file" > $xerr ;; | |
| *) | |
| # This is a no-op for GNU sed, but is important for Solaris sed | |
| # which strips NUL bytes from input. | |
| ${SED} 's,x,x,' $err > $err.1 | |
| mv $err.1 $err | |
| ${SED} "s|^m4:|$m4name:|; s|examples/|$examples/|" \ | |
| "$examples/$xerrfile" > $xerr ;; | |
| esac | |
| auxfile=`${SED} -n 's/^dnl @ expected auxfile: //p' "$file"` | |
| # For the benefit of mingw, normalize \r\n line endings | |
| if $strip_needed ; then | |
| tr -d '\015' < $out > $out.t | |
| mv $out.t $out | |
| tr -d '\015' < $xout > $xout.t | |
| mv $xout.t $xout | |
| tr -d '\015' < $err > $err.t | |
| mv $err.t $err | |
| tr -d '\015' < $xerr > $xerr.t | |
| mv $xerr.t $xerr | |
| fi | |
| if cmp -s $out $xout; then | |
| : | |
| else | |
| failed="$failed $file:out" | |
| echo `${SED} -e 's/^dnl //' -e 1q $file` | |
| echo "$file: stdout mismatch" | |
| diff $diffopts $xout $out | |
| fi | |
| if cmp -s $err $xerr; then | |
| : | |
| else | |
| failed="$failed $file:err" | |
| echo `${SED} -e 's/^dnl //' -e 1q $file` | |
| echo "$file: stderr mismatch" | |
| diff $diffopts $xerr $err | |
| fi | |
| if test -n "$auxfile"; then | |
| tauxfile=`echo "$auxfile" | ${SED} -e "s|TMP/|$tmp/|g"` | |
| if test -f "$tauxfile"; then | |
| ${SED} -ne 's|^dnl @auxresult{[A-Za-z0-9_/]*}||p' < $file >$xaux | |
| if $strip_needed ; then | |
| tr -d '\015' < $tauxfile > $tauxfile.t | |
| mv $tauxfile.t $tauxfile | |
| tr -d '\015' < $xaux > $xaux.t | |
| mv $xaux.t $xaux | |
| fi | |
| if cmp -s $tauxfile $xaux; then | |
| : | |
| else | |
| failed="$failed $file:aux" | |
| echo `${SED} -e 's/^dnl //' -e 1q $file` | |
| echo "$file auxfile mismatch" | |
| diff $diffopts $xaux $tauxfile | |
| fi | |
| rm -f $tauxfile | |
| else | |
| failed="$failed $file:aux" | |
| echo `${SED} -e 's/^dnl //' -e 1q $file` | |
| echo "$file aux outfile $auxfile does not exist" | |
| fi | |
| fi | |
| done | |
| rm -f $out $err $xout $xerr | |
| echo | |
| if test -n "$skipped"; then | |
| echo "Skipped checks were:" | |
| echo " $skipped" | |
| fi | |
| if test -z "$failed"; then | |
| echo "All checks successful" | |
| stat=0 | |
| else | |
| echo "Failed checks were:" | |
| echo " $failed" | |
| stat=1 | |
| fi | |
| (exit $stat); exit $stat |