1 #!/bin/sh 2 3 # This tool runs the toolchain for each of the tests, optionally building and 4 # running the test programs. 5 # 6 # Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk> 7 # 8 # This program is free software; you can redistribute it and/or modify it under 9 # the terms of the GNU General Public License as published by the Free Software 10 # Foundation; either version 3 of the License, or (at your option) any later 11 # version. 12 # 13 # This program is distributed in the hope that it will be useful, but WITHOUT 14 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 # details. 17 # 18 # You should have received a copy of the GNU General Public License along with 19 # this program. If not, see <http://www.gnu.org/licenses/>. 20 21 PROGNAME=$0 22 OPTION=$1 23 24 LPLC="./lplc" 25 DATADIR="_main.lplc" 26 TESTINPUT="_results/testinput.txt" 27 28 # Expect failure from the "bad" tests. 29 30 expect_failure() { 31 echo "$FILENAME" | grep -q '_bad[._/]' 32 return $? 33 } 34 35 # Check deduction output for type warnings, indicating that the program contains 36 # errors. 37 38 check_type_warnings() { 39 40 if [ -e "$DATADIR/_deduced/type_warnings" ] && \ 41 [ `stat -c %s "$DATADIR/_deduced/type_warnings"` -ne 0 ] ; then 42 43 echo "Type warnings in deduced information." 1>&2 44 return 1 45 fi 46 47 return 0 48 } 49 50 # Main program. 51 52 # Show help if requested. 53 54 if [ "$OPTION" = '--help' ] ; then 55 cat 1>&2 <<EOF 56 Usage: $0 [ --build | --build-only | --run-built ] 57 58 Run the toolchain over all tests in the tests directory. 59 60 If --build is specified, the generated program code will be compiled and run, 61 with the results collected in the _results directory. 62 63 If --build-only is specified, the generated programs themselves will be 64 collected in the _results directory, each taking their name from that of the 65 main program file used as input. 66 67 If --run-built is specified, any generated programs in the _results directory 68 will be run and their output collected in the _results directory. 69 70 By using --build-only on one system, copying the _results directory to another 71 system, and then running this script with the --run-built option on the other 72 system, it becomes possible to test the toolchain output on the other system 73 without needing to actually use the toolchain on that system. This permits the 74 testing of cross-compiled programs. 75 76 For example, to build on one system but not run the generated programs: 77 78 ARCH=mipsel-linux-gnu $PROGNAME --build-only 79 80 And to run the generated programs on another system: 81 82 $PROGNAME --run-built 83 84 Of course, this script will need to be copied to the target system if it is not 85 already available there. 86 87 Build and output logs are stored in the _results directory with the .build and 88 .out suffixes employed respectively, one of each kind for each generated 89 program. 90 EOF 91 exit 1 92 fi 93 94 # If just running existing programs, do so now and exit. 95 96 if [ "$OPTION" = '--run-built' ] ; then 97 for FILENAME in _results/* ; do 98 TESTNAME=`basename "$FILENAME"` 99 100 # Skip non-program files. 101 102 if [ ! -x "$FILENAME" ]; then 103 continue 104 fi 105 106 echo "$FILENAME..." 1>&2 107 OUTLOG="_results/$TESTNAME.out" 108 OUTCODE="_results/$TESTNAME.exitcode" 109 110 echo " (run)..." 1>&2 111 "$FILENAME" > "$OUTLOG" < "$TESTINPUT" 112 echo $? > "$OUTCODE" 113 done 114 115 exit 0 116 fi 117 118 # Make any required results directory. 119 120 if [ "$OPTION" = '--build' ] || [ "$OPTION" = '--build-only' ] ; then 121 if [ ! -e "_results" ]; then 122 mkdir "_results" 123 else 124 rm "_results/"* 125 fi 126 127 cp "tests/testinput.txt" "$TESTINPUT" 128 fi 129 130 # Perform each test. 131 132 for FILENAME in tests/* ; do 133 TESTNAME=`basename "$FILENAME" .py` 134 135 # Detect tests in their own subdirectories. 136 137 if [ -d "$FILENAME" ] ; then 138 if [ -e "$FILENAME/main.py" ] ; then 139 FILENAME="$FILENAME/main.py" 140 else 141 continue 142 fi 143 fi 144 145 # Skip non-program files. 146 147 if [ `basename "$FILENAME"` = "$TESTNAME" ]; then 148 continue 149 fi 150 151 # Compile tests without an existing cache. 152 153 echo "$FILENAME..." 1>&2 154 if ! "$LPLC" -c -r "$FILENAME" ; then 155 if ! expect_failure ; then 156 exit 1 157 else 158 echo 1>&2 159 continue 160 fi 161 fi 162 163 # Check for unresolved names in the cache. 164 165 echo " (depends)..." 1>&2 166 for CACHEFILE in "$DATADIR/_cache/"* ; do 167 STARTLINE=`grep -n '^deferred:' "$CACHEFILE" | cut -d: -f 1` 168 if tail -n +$(($STARTLINE + 2)) "$CACHEFILE" | grep -q '<depends>' ; then 169 echo "Unresolved names in the cache." 1>&2 170 exit 1 171 fi 172 done 173 174 # Check for type warnings in deduction output. 175 176 echo " (warnings)..." 1>&2 177 if ! check_type_warnings ; then exit 1 ; fi 178 179 # Compile tests with an existing cache. 180 181 echo " (cached)..." 1>&2 182 if ! "$LPLC" -c "$FILENAME" ; then exit 1 ; fi 183 184 echo " (warnings)..." 1>&2 185 if ! check_type_warnings ; then exit 1 ; fi 186 187 # Build and run if appropriate. 188 189 if [ "$OPTION" = '--build' ] || [ "$OPTION" = "--build-only" ] ; then 190 BUILDLOG="_results/$TESTNAME.build" 191 OUTLOG="_results/$TESTNAME.out" 192 OUTCODE="_results/$TESTNAME.exitcode" 193 194 echo " (build)..." 1>&2 195 if ! make -C "$DATADIR/_generated" clean > "$BUILDLOG" 2>&1 || \ 196 ! make -C "$DATADIR/_generated" > "$BUILDLOG" 2>&1 ; then 197 exit 1 198 fi 199 200 if [ "$OPTION" = "--build-only" ]; then 201 mv "$DATADIR/_generated/main" "_results/$TESTNAME" 202 else 203 echo " (run)..." 1>&2 204 "$DATADIR/_generated/main" > "$OUTLOG" < "$TESTINPUT" 205 echo $? > "$OUTCODE" 206 fi 207 fi 208 209 echo 1>&2 210 done