#!/bin/bash ############################################################################## # __ # # ________ ___ / / ___ Scala Tools Launch Script # # / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL # # __\ \/ /__/ __ |/ /__/ __ | # # /____/\___/_/ |_/____/_/ | | # # |/ # ############################################################################## # $Id$ ############################################################################## # Error functions # Prints a warning message on stderr. warning() { echo "$0: warning:" "$@" 1>&2; } # Prints an error message on stderr. error() { echo "$0:" "$@" 1>&2; } # Prints an error message on stderr and exits with a non-zero status. abort() { error "$@"; exit 1; } ############################################################################## # Printing functions # Initializes the printf functions printf_initialization() { case "$1" in many ) printf_font_outline="printf \\033[1;39m"; printf_font_success="printf \\033[1;32m"; printf_font_failure="printf \\033[1;31m"; printf_font_warning="printf \\033[1;33m"; printf_font_default="printf \\033[0;39m"; ;; some ) printf_font_outline="printf \\033[1m"; printf_font_success="printf \\033[0m"; printf_font_failure="printf \\033[1m"; printf_font_warning="printf \\033[1m"; printf_font_default="printf \\033[0m"; ;; none ) printf_font_outline=""; printf_font_success=""; printf_font_failure=""; printf_font_warning=""; printf_font_default=""; ;; * ) abort "unknown color mode \`$1'"; ;; esac; } # Prints formated text in outline font. printf_outline() { $printf_font_outline; printf "$@"; $printf_font_default; } # Prints formated text in success font. printf_success() { $printf_font_success; printf "$@"; $printf_font_default; } # Prints formated text in failure font. printf_failure() { $printf_font_failure; printf "$@"; $printf_font_default; } # Prints formated text in warning font. printf_warning() { $printf_font_warning; printf "$@"; $printf_font_default; } ############################################################################## # File name and path list conversion functions # Prints the OS-specific form of the specified Unix form file name. get_os_filename() { [ $# = 1 ] || abort "internal error"; case "$UNAME" in CYGWIN* ) cygpath --windows "$1";; * ) echo "$@";; esac; } # Prints the Unix form of the specified OS-specific form file name. get_unix_filename() { [ $# = 1 ] || abort "internal error"; case "$UNAME" in CYGWIN* ) cygpath --unix "$1";; * ) echo "$@";; esac; } # Prints the OS-specific form of the specified Unix form path list. get_os_pathlist() { [ $# = 1 ] || abort "internal error"; case "$UNAME" in CYGWIN* ) cygpath --window --path "$1";; * ) echo "$@";; esac; } # Prints the Unix form of the specified OS-specific form path list. get_unix_pathlist() { [ $# = 1 ] || abort "internal error"; case "$UNAME" in CYGWIN* ) cygpath --unix --path "$1";; * ) echo "$@";; esac; } ############################################################################## # Implementation of scalatest # Prints the scalatest usage. test_print_usage() { [ $# = 0 ] || abort "internal error"; echo "Usage: $0 [OPTION]..." } # Prints the scalatest help. test_print_help() { [ $# = 0 ] || abort "internal error"; test_print_usage; echo ""; echo "--auto use filenames to select the test to run"; echo "--run next files test the interpreter and all backends"; echo "--jvm next files test the JVM backend"; echo "--pos next files test a compilation success"; echo "--neg next files test a compilation failure"; echo "--msil next files test the .NET backend"; echo "--quick use the 'quick' build instead of distribution"; echo "--no-run run no test, use results of last run"; echo "--show-log show output of failed tests"; echo "--show-diff show differences between actual and expected output"; echo "--failed test only files that failed last time"; echo "--errors= specify the number of expected errors"; echo "--flags= specify flags to pass on to the executable"; echo "--color=USAGE control the color usage (USAGE=none|some|many)"; echo "--objdir= specify where to place generated files"; echo "--help, -? display this help and exit"; echo "--version output version information and exit"; } # Prints the scalatest version. test_print_version() { [ $# = 0 ] || abort "internal error"; echo "$SCRIPT "'$Revision$'; } # Prints the name of the specified test file. test_print_testing() { [ $# = 1 ] || abort "internal error"; printf_outline "testing: "; case "$1" in "$TESTROOT"* ) printf "%-60s " "[...]`expr "$1" : "$TESTROOT\(.*\)"`"; return 0; ;; esac; printf "%-60s " "$1"; } # Prints a test success notification. test_print_success() { [ $# = 0 ] || abort "internal error"; printf "["; printf_success " OK "; printf "]\\n"; } # Prints a test failure notification. test_print_failure() { [ $# = 0 ] || abort "internal error"; printf "["; printf_failure "FAILED"; printf "]\\n"; } # Tests a compilation success. test_run_pos() { rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && $SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && rm -rf "$dstbase".obj; } # Tests a compilation failure. test_run_neg() { rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && ( cd "$srcdir" && $SOCOS -d "$os_dstbase".obj "$@" "$testname".scala; ); if [ "$?" = 0 ]; then status=1; else status=0; fi; rm -rf "$dstbase".obj; return $status; } # Tests the JVM backend. test_run_jvm() { rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && $SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && classpath=`get_os_pathlist "$os_dstbase".obj:$CLASSPATH` && $SCALA -classpath $classpath Test "jvm" && rm -rf "$dstbase".obj; } # Test the disassemblers. test_run_dis() { argsfile="$srcbase".args; if [ ! -f "$argsfile" ]; then argsfile=/dev/null; fi; rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && $SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && $SCALAP -classpath "$os_dstbase".obj `cat "$argsfile"` && rm -rf "$dstbase".obj; } # Tests the .NET backend. test_run_msil() { assemblies=`get_os_pathlist "/home/linuxsoft/apps/msil"`; rm -f "$dstbase".il && rm -f "$dstbase".EXE && $SOCOS -nowarn -target:msil -o "$os_dstbase" -r $assemblies "$@" \ "$os_srcbase".scala && case "$UNAME" in CYGWIN* ) ilasm /qui /nol /out="$os_dstbase".EXE "$os_dstbase".il \ > /dev/null && # peverify /il "$os_dstbase".EXE > /dev/null && "$dstbase".EXE "msil";; * ) ilasm /output:"$os_dstbase".EXE "$os_dstbase".il \ > /dev/null && mono "$dstbase".EXE "msil";; esac && rm -f "$dstbase".EXE && rm -f "$dstbase".il; } # Checks the specified test. test_check_test() { [ $# = 1 ] || abort "internal error"; testfile="$1"; shift 1; # compute test name testname=`basename "$testfile" .scala`; # compute source and destination directories (absolute paths) srcdir=`dirname "$testfile"`; srcdir=`cd "$srcdir"; pwd`; dstdir="$OBJDIR""$srcdir"; # compute source and destination base names srcbase="$srcdir"/"$testname"; dstbase="$dstdir"/"$testname"-$kind; os_srcbase=`get_os_filename "$srcbase"`; os_dstbase=`get_os_filename "$dstbase"`; # compute flags file flagsfile="$srcbase".flags; if [ ! -f "$flagsfile" ]; then flagsfile=/dev/null; fi; # compute check file checkfile="$srcbase"-$kind.check; if [ ! -f "$checkfile" ]; then checkfile="$srcbase".check; fi; if [ ! -f "$checkfile" ]; then checkfile=/dev/null; fi; # compute log file logfile="$dstbase".log; # if we are testing only failed tests, skip successful tests if [ "$FAILED" = "true" -a ! -f "$logfile" ]; then return 0; fi; # if that's the first file of the section print section header if [ -n "$header" ]; then printf_outline "$header\\n"; unset header; fi; # print tested file test_print_testing "$testfile"; # run test if [ "$NORUN" = "true" ]; then [ ! -f "$logfile" ]; else rm -f "$logfile"; { [ -d "$dstdir" ] || mkdir -p "$dstdir"; } && ( test_run_$kind `cat "$flagsfile"` $FLAGS 1> "$logfile" 2>&1; ) && $DIFF "$logfile" "$checkfile" 1> /dev/null 2>&1 && rm -f "$logfile"; fi; # print result if [ "$?" = 0 ]; then SUCCESS_COUNT=`echo "$SUCCESS_COUNT+1" | bc`; test_print_success; else FAILURE_COUNT=`echo "$FAILURE_COUNT+1" | bc`; test_print_failure; if [ ! -f "$logfile" ]; then logfile=/dev/null; fi; if [ "$SHOWLOG" = "true" ]; then cat "$logfile"; fi; if [ "$SHOWDIFF" = "true" ]; then $DIFF "$logfile" "$checkfile"; fi; fi; } # Checks the specified file test_check_file() { [ $# = 1 ] || abort "internal error"; file="$1"; shift 1; for testfile in "" `find "$file" -name "*.obj" -prune -o -name "*.scala" -a -type f -print`; do [ -z "$testfile" ] && continue; test_check_test "$testfile"; done; } # Checks all files of the specified kind. test_check_kind() { [ $# -ge 2 ] || abort "internal error"; header="$1"; shift 1; kind="$1"; shift 1; for file in "" "$@"; do [ -z "$file" ] && continue; test_check_file "$file"; done if [ -z "$header" ]; then echo ""; fi; } # Checks everything. test_check_all() { [ $# = 0 ] || abort "internal error"; test_check_kind "Testing JVM backend" \ "jvm" $FILES_RUN $FILES_JVM; test_check_kind "Testing compiler (on files whose compilation should succeed)" \ "pos" $FILES_POS; test_check_kind "Testing compiler (on files whose compilation should fail)" \ "neg" $FILES_NEG; test_check_kind "Testing .NET backend" \ "msil" $FILES_MSIL; } # Adds a new file to the appropriate file list(s). test_add_file() { [ $# = 1 ] || abort "internal error"; case "$1" in *.scala ) if [ ! \( -d "$1" -o -f "$1" \) ]; then abort "don't know what to do with '$1'"; fi;; * ) if [ ! -d "$1" ]; then abort "don't know what to do with '$1'"; fi;; esac; TEST_ALL="false"; case "$TEST_TYPE" in auto ) ;; run ) FILES_RUN="$FILES_RUN $1"; return;; jvm ) FILES_JVM="$FILES_JVM $1"; return;; pos ) FILES_POS="$FILES_POS $1"; return;; neg ) FILES_NEG="$FILES_NEG $1"; return;; msil ) FILES_MSIL="$FILES_MSIL $1"; return;; * ) abort "unknown test type \`$TEST_TYPE'";; esac; case "$1" in run | */run | */run/* | run/* ) FILES_RUN="$FILES_RUN $1";; jvm | */jvm | */jvm/* | jvm/* ) FILES_JVM="$FILES_JVM $1";; pos | */pos | */pos/* | pos/* ) FILES_POS="$FILES_POS $1";; neg | */neg | */neg/* | neg/* ) FILES_NEG="$FILES_NEG $1";; msil | */msil | */msil/* | msil/* ) FILES_MSIL="$FILES_MSIL $1";; * ) abort "don't known what to do with \`$1'";; esac; } ############################################################################## # Definition of UNAME, SOURCE, SCRIPT and PREFIX unset SCRIPT; UNAME=`uname`; SOURCE=$0; SCRIPT=`basename "$SOURCE"`; while [ -h "$SOURCE" ]; do SCRIPT=`basename "$SOURCE"`; LOOKUP=`ls -ld "$SOURCE"`; TARGET=`expr "$LOOKUP" : '.*-> \(.*\)$'`; if expr "${TARGET:-.}/" : '/.*/$' > /dev/null; then SOURCE=${TARGET:-.}; else SOURCE=`dirname "$SOURCE"`/${TARGET:-.}; fi; done; PREFIX=`dirname "$SOURCE"`/..; prefix=$PREFIX; PREFIX=`cd "$PREFIX"; pwd`; ############################################################################## # Invocation of $SCRIPT NORUN="false"; SHOWLOG="false"; SHOWDIFF="false"; FAILED="false"; ERRORS=0; SUCCESS_COUNT=0; FAILURE_COUNT=0; TESTROOT="$PREFIX/test/files"; SRCDIR="$PREFIX/test/files"; OBJDIR=""""; TEST_ALL="true"; TEST_TYPE="auto"; FILES_RUN=""; FILES_JVM=""; FILES_POS=""; FILES_NEG=""; FILES_MSIL=""; QUICK="$PREFIX/build/quick/exec" if [ -d "$PREFIX/dists" ]; then LATEST="$PREFIX/dists/latest/bin"; else if [ -d "$PREFIX/build" ]; then LATEST="$QUICK"; else LATEST="$PREFIX/bin"; fi; fi; BIN_DIR="$LATEST" DIFF="diff"; case `uname` in CYGWIN* ) DIFF="diff --text --strip-trailing-cr"; ;; esac; while [ $# -gt 0 ]; do case "$1" in --auto ) TEST_TYPE="auto"; shift 1;; --run ) TEST_TYPE="run"; shift 1;; --jvm ) TEST_TYPE="jvm"; shift 1;; --pos ) TEST_TYPE="pos"; shift 1;; --neg ) TEST_TYPE="neg"; shift 1;; --msil ) TEST_TYPE="msil"; shift 1;; --quick ) BIN_DIR="$QUICK"; shift 1;; --no-run ) NORUN="true"; shift 1;; --show-log ) SHOWLOG="true"; shift 1;; --show-diff ) SHOWDIFF="true"; shift 1;; --failed ) FAILED="true"; shift 1;; --errors= ) abort "illegal empty argument for option --errors";; --errors=* ) ERRORS=`expr "$1" : "--errors=\([0-9]*\)$"`;shift 1;; --flags= ) abort "illegal empty argument for option --flags";; --flags=* ) FLAGS=`expr "$1" : "--flags=\(.*\)"`; shift 1;; --color= ) abort "illegal empty argument for option --color";; --color=* ) COLOR=`expr "$1" : "--color=\(.*\)"`; shift 1;; --objdir=* ) OBJDIR=`expr "$1" : "--objdir=\(.*\)"`; shift 1;; --help| -? ) test_print_help; exit 0;; --version ) test_print_version; exit 0;; -* ) abort "unknown option $1";; * ) test_add_file "$1"; shift 1;; esac; done; if [ -z "$ERRORS" ]; then abort "illegal non-numerical argument for option --errors"; fi; if [ -z "$COLOR" -a -n "$EMACS" ]; then COLOR="none"; fi; printf_initialization "${COLOR:-many}"; if [ "$TEST_ALL" = "true" ]; then case "$TEST_TYPE" in run ) FILES_RUN="$FILES_RUN $SRCDIR/run";; esac; case "$TEST_TYPE" in auto | jvm ) FILES_JVM="$FILES_JVM $SRCDIR/run $SRCDIR/jvm";; esac; case "$TEST_TYPE" in auto | pos ) FILES_POS="$FILES_POS $SRCDIR/pos";; esac; case "$TEST_TYPE" in auto | neg ) FILES_NEG="$FILES_NEG $SRCDIR/neg";; esac; case "$TEST_TYPE" in msil ) FILES_MSIL="$FILES_MSIL $SRCDIR/run";; esac; fi; SCALA="$BIN_DIR/scala"; SOCOS="$BIN_DIR/scalac"; SCALAP="$LATEST/scalap"; SCALA_SCALA_ARGS="-Xmx512M $SCALA_SCALA_ARGS"; export SCALA_SCALA_ARGS; if [ -n "$OBJDIR" ]; then if [ -d "$OBJDIR" ] || mkdir -p "$OBJDIR"; then OBJDIR=`cd "$OBJDIR"; pwd`; else abort "could not create directory '$OBJDIR'"; fi fi printf_outline "Source directory is : $SRCDIR\\n"; printf_outline "Scala binaries in : $BIN_DIR\\n"; jvm_version=`${JAVACMD:=java} -version 2>&1 | head -3 | tail -1` printf_outline "Java runtime is : $jvm_version\\n\\n"; test_check_all; TOTAL_COUNT=`echo "$FAILURE_COUNT+$SUCCESS_COUNT" | bc`; if [ $FAILURE_COUNT -eq 0 ]; then printf_success "All of $TOTAL_COUNT tests were successful\\n"; else printf_failure "$FAILURE_COUNT of $TOTAL_COUNT tests failed\\n"; fi; if [ $FAILURE_COUNT -eq "$ERRORS" ]; then exit 0; else exit 1; fi; ##############################################################################