#!/bin/bash

#
# rv <-cpp> <file> <arg1> <arg2> ...
#
# <file> is the pascal filename without extention.
# <-cpp> optionally runs the c preprocessor
# <arg1> is a file that is bound to the first parameter in the program heading
# program is compiled if it doesn't exist or if source is newer than program
# use c preprocessor for conditional compilation, include, etc
# p5c compiler is in current directory or in env variable $P5CDIR
#

# show brief help if no pascal file specified on command line
if [ -z "$1" ]
then
   echo  "test pascal program for memory errors with valgrind and p5c pascal"
   echo usage:
   echo $0 \[-cpp\] 'testfile arg1 arg2 ...'
   echo "where testfile is a pascal file, optionally without the extension (.pas or .p)"
   echo "arg1, etc are the command line arguments to testfile"
   echo "run the c preprocessor if"
   echo "    - optional command line parameter -cpp is present on the command line"
   echo "    - one of the first 10 lines of the pascal file starts with a '#' char"
   exit 0
fi

if ! which valgrind > /dev/null 2>&1; then
    echo "can't find valgrind, quitting"
    exit
fi

test -z "$P5CDIR" && P5CDIR=.

if [ ! -x $P5CDIR/p5c ]
then
  echo "compiler not found at $P5CDIR/p5c - quitting"
  exit 1
fi

if [ "$1" = "-cpp" ]; then
  WITHCPP=1
  shift
else
  WITHCPP=0
fi

PASFILE="${1##*.}"
shift


if [ -f $PASFILE.pas ]
then
    EXT=pas
elif [ -f $PASFILE.p ]
then
    EXT=p
elif [ -f $PASFILE.pp ]
then
    EXT=pp
else
    echo "can't find $PASFILE.pas or $PASFILE.pp or $PASFILE.p"  > /dev/stderr
    exit 1
fi

echo
echo valgrind test for $PASFILE $@ ...
echo
echo "building $PASFILE with debug symbols"
echo '{$n+,d- -- force line numbers, omit debug code }' > $PASFILE.t.$EXT
echo "{@@#line 1 \"$PASFILE.$EXT\" @@}" >> $PASFILE.t.$EXT
cat $PASFILE.$EXT >> $PASFILE.t.$EXT


$P5CDIR/pc -g $PASFILE.t.$EXT

# The status of the compile is not returned,
# so convert a non-zero error message to fail status
if ! grep -qF "Errors in program: 0" $PASFILE.lst
then
    #tail  $PASFILE.lst
    awk '{ if( $2=="****" ) {print l0 "\n" l1 "\n" $0 ;} \
           else { l0=l1; l1 = $0; }; } \
           /^Errors in program/,0; \
        ' $PASFILE.lst > /dev/stderr

    echo "cannot compile $PASFILE, quitting" > /dev/stderr
    exit 1
fi

# now run the program with arguments
if ! test -x ./$PASFILE ; then
    echo "failed: executable file not created"
    exit 1
fi

# now we can run the test program
echo
echo valgrind test for $PASFILE $@ ...
echo
echo -n ".... this is likely to take quite a while ...."
echo
    # remove old test results
    # rm -f $PASFILE.vlg

# run the test program
valgrind -s --track-origins=yes --leak-check=full  ./$PASFILE.t $@ 2> "$PASFILE".vlg

#echo results are in "$PASFILE".vlg
cat "$PASFILE".vlg
