#!/usr/unsupported/bin/bash

# 990517 bkoz 
# Script to do automated testing and data collection for
# various test files, and avoid doing this on every test file.
# It attempts to collect some diagnostic info about size
# and speed that should be useful in the future as the library gets
# tuned for size and speed.

# invocation == mkcheck [01] (path to build) (path to src) (path to install)

echo "running mkcheck"

#
# 1: variables
#
# WHICH determines if you are testing the installed binary and headers, or
# the build binary and headers.
WHICH=$1
if [ $WHICH != "1" ]; then
  WHICH=0
elif [ $WHICH -eq 1 ]; then
  echo "$0: testing the install directory $1"
fi

BUILD_DIR=$2
if [ ! -d "$BUILD_DIR" ]; then
  echo "build directory $BUILD_DIR not found, exiting."
  exit 1
fi

SRC_DIR=$3
if [ ! -d "$SRC_DIR" ]; then
  echo "source directory $SRC_DIR not found, exiting."
  exit 1
fi

if [ $WHICH -eq 1 ]; then 
    PREFIX_DIR=$4
    if [ ! -d "$PREFIX_DIR" ]; then
    echo "install directory $PREFIX_DIR not found, exiting."
    exit 1
    fi
fi

# Set up the testing directory, which should be in a directory called
# "testsuite" in the root level of the build directory.
TEST_DIR="`pwd`/testsuite"
if [ ! -d "$TEST_DIR" ]; then
    echo "making directory $TEST_DIR . . ."
    mkdir $TEST_DIR
    chmod 777 $TEST_DIR
fi

# INC_PATH == include path to new headers for use on gcc command-line
if [ $WHICH != "1" ]; then
  INC_PATH="-I$SRC_DIR/std -I$SRC_DIR -I$SRC_DIR/stl -I$SRC_DIR/libio -I$BUILD_DIR"
elif [ $WHICH -eq 1 ]; then
  INC_PATH="-I$PREFIX_DIR/include/g++-v3"
fi

#LIB_PATH == where to find the build library binaries.
if [ $WHICH != "1" ]; then
  LIB_PATH="-L$BUILD_DIR/src/.libs"
elif [ $WHICH -eq 1 ]; then
  LIB_PATH="-L$PREFIX_DIR/lib"
fi

# gcc compiler flags
CXX_FLAG="-g -O2 -DDEBUG_ASSERT "
# a specific flag to force the use of shared libraries, if any
SH_FLAG=
# a specific flag to force the use of static libraries, if any
ST_FLAG="-static"
# the name of the file that will collect and hold all this useful data:
RESULTS_FILE="$TEST_DIR/$(date +%y%m%d)-mkcheck.txt"
# the name of the log file that will append compiler diagnostics:
LOG_FILE="$TEST_DIR/$(date +%y%m%d)-mkchecklog.txt"

#
# 2: clean, append general test info
#
if [ -f $RESULTS_FILE ]; then
    rm $RESULTS_FILE
fi
if [ -f $LOG_FILE ]; then
    rm $LOG_FILE
fi
# Remove old executables.
rm -rf "$TEST_DIR/*exe"
rm -rf "$TEST_DIR/core" "$TEST_DIR/*/core"
# Copy over the data files for filebufs
cp $SRC_DIR/testsuite/27_io/*.txt $TEST_DIR

# Emit useful info about compiler and platform
echo "host: $(uname -mrsv)" >> $RESULTS_FILE
echo "compiler: $(g++ --version)" >> $RESULTS_FILE
echo "compiler flags: $CXX_FLAG" >> $RESULTS_FILE
echo "" >> $RESULTS_FILE

echo "time" "exec" | awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
echo "text" "data" | awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
echo "total" "name" | awk '{printf("%s\t%s\t", $1, $2)}' >> $RESULTS_FILE
echo "" >> $RESULTS_FILE

for NAME in $SRC_DIR/testsuite/*/*.cc
do
    PRE_NAME="$TEST_DIR/`basename $NAME`"
    echo "testing . . . $PRE_NAME"
    ST_NAME="`echo $PRE_NAME | sed 's/cc$/st-exe/'`"
    SH_NAME="`echo $PRE_NAME | sed 's/cc$/sh-exe/'`"

    #
    # 3: static compile, link, execute, time
    #
    ST_TIME_START="$(date +%s)"
#    g++ $CXX_FLAG $ST_FLAG $INC_PATH $LIB_PATH $NAME -o $ST_NAME >& $LOG_FILE
    g++ $CXX_FLAG $ST_FLAG $INC_PATH $LIB_PATH $NAME -o $ST_NAME 
    ST_TIME_END="$(date +%s)"
    if [ $ST_TIME_START -lt $ST_TIME_END ]; then
	ST_TIME=$[ $ST_TIME_END - $ST_TIME_START ]
    else
	ST_TIME="0"
    fi

    if [ -f $ST_NAME ]; then
	ST_TEXT="$(size -A $ST_NAME | grep text | awk '{print $2}')"
	ST_DATA="$(size -A $ST_NAME | grep data | awk '{print $2}')"
	ST_SIZE="$(size -A $ST_NAME | grep otal | awk '{print $2}')"
	if [ -f core ]; then
	    ST_EXEC="fail"
	    echo "st_fail" | awk '{printf("\t%s\n", $1)}'
	    rm core
	else
	    # XXX this should probably be a function? 

	    # This checks for emitted output files, which is useful
	    # when testing file-related output. The rules for this
	    # working are as follows: the emitted file must have the
	    # ".txt" extension, and be based on the actual *.cc file's
	    # name. For example, 27/filbuf.cc currently outputs files
	    # named 27/filebuf-2.txt and 27/filebuf-3.txt. Also, the first
	    # emitted file must be in the form $NAME-1.txt. The
	    # control file must follow the same constraints, but have
	    # a ".tst" extension. Thus, you have 27/filebuf-2.tst, etc
	    # etc.

	    # NAME contains the source name, like 27/filebuf.cc
	    # From that NAME, we want to generate some possible names, using
	    # ls on MATCH, a pattern description generated with sed.

	    # this is the name of the resulting diff file, if any
	    DIFF_FILE="`echo $PRE_NAME | sed 's/cc$/diff/'`"
	    # construct wildcard names,ie for $NAME=filebuf.cc, makes
	    # "filebuf*.tst"
	    ST_DATA_FILES="`echo $NAME | sed 's/\.cc/\*\.tst/g'`"
	    # make sure there is at least one, then go
	    ST_E="`echo $NAME | sed 's/\.cc/\-1\.tst/g'`"
	    if [ -f $ST_E ]; then
		# list of actual files that match the wildcard above, ie
		# "filebuf-1.tst"
		ST_MATCH_LIST="`ls $ST_DATA_FILES`"
		for i in $ST_MATCH_LIST
		    do
			# ST_OUT_FILE is generated in the build directory.
			PRE_NAME2="$TEST_DIR/`basename $i`"
			ST_OUT_FILE="`echo $PRE_NAME2 | sed 's/tst$/txt/'`"
			diff $ST_OUT_FILE $i > $DIFF_FILE
			if [ -s $DIFF_FILE ]; then
			    ST_EXEC="fail"
			    echo "st_fail" | awk '{printf("\t%s\n", $1)}'
			else
			    ST_EXEC="pass"
			    echo "st_pass" | awk '{printf("\t%s\n", $1)}'
			fi
			rm $DIFF_FILE
		    done
		else
		    # the file does no output, and didn't core, so
		    # assume passed.
		    ST_EXEC="pass"
		    echo "st_pass" | awk '{printf("\t%s\t", $1)}'
		fi
	    fi
#	rm "$ST_NAME"
    else
	ST_EXEC="fail"
	echo "st_fail" | awk '{printf("\t%s\t", $1)}'
	ST_TEXT="0"
	ST_DATA="0"
	ST_SIZE="0"
    fi
    echo $ST_TIME $ST_EXEC | awk '{printf ("%s\t%s\t", $1, $2)}'>>$RESULTS_FILE
    echo $ST_TEXT $ST_DATA | awk '{printf ("%s\t%s\t", $1, $2)}'>>$RESULTS_FILE
    echo $ST_SIZE | awk '{printf ("%s\t", $1)}'>>$RESULTS_FILE
    echo `basename $ST_NAME` | awk '{printf ("%s\n", $1)}'>>$RESULTS_FILE

    echo "" >> $RESULTS_FILE
    echo ""
done

cd $TEST_DIR

exit 0









