├── CHANGELOG ├── README.md └── grader.sh /CHANGELOG: -------------------------------------------------------------------------------- 1 | Bug fixes [Feb. 22, 2020]: 2 | 3 | 1. Fixed escape sequences for colors. It seems that \e is not supported in some systems so I replaced it with \033. 4 | 2. Time Limit Exceeded used to be interpreted as Runtime error in some system. Temporary fix applied: Interpret both return codes 152 and 137 as "terminated by SIGXCPU" which is the signal ulimit is supposed to send when CPU time is exceeded. A more permanent/universal solution is still pending. 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Purpose 2 | ======== 3 | 4 | This simplistic shell script was created as a quick and dirty way to automatically run a program against a set of inputs and evaluate the validity of the outputs. The typical use-case I had in mind was programming competitions. It's important to notice that this script does not provide any sandboxing so make sure any code you are evaluating is not malicious. 5 | 6 | *Disclaimer:* At the time of writing I admit I did not have the expertise of writing good software and especially software that works well across platforms. As a consequence there are probably many bugs in the code which I have not come across if they didn't appear on my platform. I recently tried patching some of those bugs (see CHANGELOG) that people brought to my attention but I'm sure there are many more. Feel free to contact me for bugs, suggestions and general feedback at marsenis 'at' gmail 'dot' com. 7 | 8 | Configuration 9 | ============= 10 | 11 | There are a couple of things you can configure manually in the script. (unfortunately not much yet..) 12 | 13 | Those are: 14 | 15 | * input/output filename format (defaults are 'input.#.txt' and 'output.#.txt') 16 | * time limit (default is 1 second) 17 | * the compiler and compiling options for each language (the language is detected based on the file extension) 18 | 19 | Note: the '#' character in the input/output filename description will be replaced by 1, 2, 3, ... for each test case. For example 'input.#.txt' means that the input files are: input.1.txt , input.2.txt , ... up to the maximum numbered test case existing in the current directory. 20 | 21 | Usage 22 | ===== 23 | 24 | Just run the script with one parameter, the source code filename. 25 | 26 | Example: ./grader.sh test.cpp 27 | 28 | The above command will first compile test.cpp and then run the executable for each test case of the form described by the user. 29 | After each run (and if the program terminates with exit code 0 within the time limit), the output is judged based on the given correct output files. 30 | 31 | Important Notes 32 | =============== 33 | 34 | * Your program should read data from stdin and write on stdout. The required input/output redirections are handled automatically by the script. 35 | * Output is judged based on the given correct output files using the diff tool. As a result, the grading script might give wrong results for problems in which more than one outputs are considered correct by the problem statement. 36 | * The script, the source code and the test cases should be placed under the same directory. 37 | 38 | License 39 | ======= 40 | 41 | Copyright (c) 2012 Makis Arsenis 42 | 43 | Permission is hereby granted, free of charge, to any person obtaining a copy 44 | of this software and associated documentation files (the "Software"), to 45 | deal in the Software without restriction, including without limitation the 46 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 47 | sell copies of the Software, and to permit persons to whom the Software is 48 | furnished to do so, subject to the following conditions: 49 | 50 | The above copyright notice and this permission notice shall be included in 51 | all copies or substantial portions of the Software. 52 | 53 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 54 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 56 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 57 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 58 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 59 | IN THE SOFTWARE. 60 | -------------------------------------------------------------------------------- /grader.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## Version 2.4 3 | 4 | ## ****** BEGIN - Configuration ******* 5 | 6 | # Input/Output format 7 | # '#' will be replaced by 1, 2, ... 8 | IN="input.#.txt" 9 | OUT="output.#.txt" 10 | 11 | # Limits 12 | TL=1 # Time limit (in seconds) 13 | 14 | # Compiling options 15 | CPP="g++ -O2 -w -lm" # C++ 16 | C="gcc -O2 -w -lm" # C 17 | PAS="gpc" # Pascal 18 | 19 | ## ****** END - Configuration ******** 20 | 21 | #-------------------------------------------------- 22 | 23 | #Copyright (c) 2012 Makis Arsenis 24 | 25 | #Permission is hereby granted, free of charge, to any person obtaining a copy 26 | #of this software and associated documentation files (the "Software"), to 27 | #deal in the Software without restriction, including without limitation the 28 | #rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 29 | #sell copies of the Software, and to permit persons to whom the Software is 30 | #furnished to do so, subject to the following conditions: 31 | 32 | #The above copyright notice and this permission notice shall be included in 33 | #all copies or substantial portions of the Software. 34 | 35 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 40 | #FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 41 | #IN THE SOFTWARE. 42 | 43 | # Color Codes 44 | red='\033[0;31m' 45 | RED='\033[1;31m' 46 | GREEN='\033[1;32m' 47 | green='\033[0;32m' 48 | blue='\033[0;34m' 49 | BLUE='\033[1;34m' 50 | cyan='\033[0;36m' 51 | CYAN='\033[1;36m' 52 | NC='\033[0m' # No Color 53 | 54 | # Cleanup on exit 55 | rm -f .overview .compiler_report .time_info .$1.out 56 | trap "{ rm -f .overview .compiler_report .time_info .$1.out; }" SIGINT SIGTERM EXIT 57 | 58 | if [ $# -ne 1 ] 59 | then 60 | echo "Usage: $0 source_code" 61 | echo " e.g. $0 test.cpp" 62 | echo " use the above to grade file test.cpp" 63 | exit 2 64 | fi 65 | 66 | # Language detection 67 | LANG=`echo $1 | awk -F . '{print $NF}'` 68 | if [ "$LANG" == "cpp" ] 69 | then 70 | COMPILER="$CPP $1 2> .compiler_report" # C++ 71 | elif [ "$LANG" == "c" ] 72 | then 73 | COMPILER="$C $1 2> .compiler_report" # C 74 | elif [ "$LANG" == "pas" ] 75 | then 76 | COMPILER="$PAS $1 2> .compiler_report" # Pascal 77 | fi 78 | 79 | # Compilation 80 | echo -e " ${CYAN}* Compiling source code${NC}"; 81 | echo "$COMPILER" | sh 82 | if [ $? -ne 0 ] 83 | then 84 | echo -e " ${RED}X Compilation Error${NC}"; 85 | cat .compiler_report; 86 | exit 1; 87 | fi 88 | 89 | echo -e " ${GREEN}* Successful compilation!${NC}"; 90 | echo 91 | 92 | ulimit -t $TL; 93 | 94 | rm -rf .overview; 95 | CORRECT=0 96 | MAX_N=50 97 | 98 | for (( i=1; i<=$MAX_N; i++)) 99 | do 100 | TEST_CASE_IN=`echo $IN | sed "s/#/$i/g"` 101 | TEST_CASE_OUT=`echo $OUT | sed "s/#/$i/g"` 102 | 103 | # If i-th test case doesn't exist then stop here. 104 | if [ ! -e $TEST_CASE_IN ] 105 | then 106 | break 107 | fi 108 | echo -e "${BLUE}Test case $i:${NC}"; 109 | 110 | time -p (./a.out < $TEST_CASE_IN > .$1.out) 2> .time_info; 111 | 112 | EX_CODE=$?; 113 | if [ $EX_CODE -eq 137 ] || [ $EX_CODE -eq 152 ] 114 | then 115 | echo -e " ${RED}X TLE: Time Limit Exceeded${NC}"; 116 | echo -n "T" >> .overview; 117 | elif [ $EX_CODE -ne 0 ] 118 | then 119 | echo -e " ${RED}X RE: Runtime Error${NC}"; 120 | echo -n "E" >> .overview; 121 | else 122 | PROG_TIME=`cat .time_info | grep real | cut -d" " -f2`; 123 | diff --strip-trailing-cr .$1.out $TEST_CASE_OUT > /dev/null 124 | if [ $? -eq 0 ] 125 | then 126 | echo -e " ${GREEN}* OK${NC} [$PROG_TIME]" 127 | echo -n "*" >> .overview 128 | CORRECT=`expr $CORRECT + 1` 129 | else 130 | echo -e " ${RED}X WA: Wrong Answer${NC} [$PROG_TIME]" 131 | echo -n "X" >> .overview 132 | fi 133 | fi 134 | 135 | echo; 136 | done 137 | N=`expr $i - 1` 138 | 139 | echo; 140 | 141 | echo >> .overview; 142 | echo -n "Overview: "; cat .overview 143 | if [ $CORRECT -ne $N ] 144 | then 145 | echo -e "${RED}X${NC}: Wrong Answer, ${RED}T${NC}: Time Limit Exceeded, ${RED}E${NC}: Probably runtime error" 146 | echo 147 | fi 148 | 149 | echo -n "$CORRECT / $N" 150 | if [ $CORRECT -eq $N ] 151 | then 152 | echo -en " ${GREEN}All test cases passed!!${NC}" 153 | fi 154 | echo 155 | --------------------------------------------------------------------------------