#
# OI Makefile
# wersja 1.04
# Autor: Tomasz Walen, Rafal Rusin
# Data: 2004.06.29

include makefile.in

BIN_TIME = /usr/bin/time
TMP1     = .__tmp_1__~
TMP2     = .__tmp_2__~
TMP3     = .__tmp_3__~


INGEN    = $(shell if [ `find prog -name "$(ID)ingen.*" | wc -l` -gt 0 ] ; then echo 1 ; else echo 0 ; fi)
INWER    = $(shell if [ `find prog -name "$(ID)inwer.*" | wc -l` -gt 0 ] ; then echo 1 ; else echo 0 ; fi)
CHECKER  = $(shell if [ `find prog -name "$(ID)chk.*" | wc -l` -gt 0 ] ; then echo 1 ; else echo 0 ; fi)
PROGS_OPT= $(shell find prog -regex "prog/$(ID)[0-9]*\.\(c\|cpp\|pas\|ml\)")
PROGS_SLW= $(shell find prog -regex "prog/$(ID)s[0-9]*\.\(c\|cpp\|pas\|ml\)")
PROGS_BAD= $(shell find prog -regex "prog/$(ID)b[0-9]*\.\(c\|cpp\|pas\|ml\)")
.PHONY : clean clean-gen export verify tgz run inwer outgen

REPFILE  = testruns-$(MODE).txt

all:
	# Podaj konkretny cel #

export:
	## Przygotowanie paczki dla SInOl'a ##
	make -C doc
	make -C prog
	make clean-gen
	make clean
	tar cvzf $(SIG).tgz --exclude "$(ID)/$(SIG).tgz" ../$(ID)

run:
	## Uruchomienie rozwizania wzorcowego ##
	make _run_ver_n_$(ID).e

run_%:  
	make _run_ver_n_$(ID)$*.e

verify: _verify_mode clean verify_$(MODE)

verify_red:
	## Automatyczna weryfikacja redacji ##
	make -s "_verify_doc_$(ID)zad.tex"
	make -s "_verify_in_$(ID)0.in"
	make -s "_verify_out_$(ID)0.out"
	make -C doc all

verify_opr: verify_red
	## Automatyczna weryfikacja opracowania ##
	make -s "_verify_doc_$(ID)opr.tex"
	make -C doc all
	make -C prog all
	make ingen
	make inwer
	make outgen
	make testruns_header
	@for i in `echo $(PROGS_OPT)`; do j="`basename $$i`"; j="`(echo $$j) | rev | cut -d. -f2- | rev`.e"; if ! make _run_ver_o_$$j; then exit 1; fi; done
	@for i in `echo $(PROGS_SLW)`; do j="`basename $$i`"; j="`(echo $$j) | rev | cut -d. -f2- | rev`.e"; if ! make _run_ver_s_$$j; then exit 1; fi; done
	@for i in `echo $(PROGS_BAD)`; do j="`basename $$i`"; j="`(echo $$j) | rev | cut -d. -f2- | rev`.e"; if ! make _run_ver_n_$$j; then exit 1; fi; done

verify_wer: verify_opr
	## Automatyczna weryfikacja weryfikacji ##
	make -s "_verify_doc_$(ID)wer.tex"

verify_sio: verify_wer
	## Automatyczna weryfikacja paczki na SIO ##

_verify_mode:
	@echo; \
    echo 'Znane rodzaje paczek:'; \
	echo '   red - redakcja';\
	echo '   opr - opracowanie';\
	echo '   wer - weryfikacja';\
	echo '   sio - do wrzucenia na SIO';\
	echo;\
	echo 'Aktualny rodzaj paczki (patrz plik makefile.in) to'; \
	echo; \
	echo '$(MODE)'; \
	echo; \
	echo -n "Czy jest to poprawny rodzaj paczki? (T/N) "; \
	read CONFIRM; \
	if [ "$$CONFIRM" != "T" -a "$$CONFIRM" != "t" ]; then \
		exit 1; \
	fi;

_verify_in_%:
	@if [ ! -f "in/$*" ] ; then echo Brak pliku in/$* ; exit 1 ; fi

_verify_out_%:
	@if [ ! -f "out/$*" ] ; then echo Brak pliku out/$* ; exit 1 ; fi

_verify_prog_%:
	@if [ ! -f "prog/$*" ] ; then echo Brak pliku prog/$* ; exit 1 ; fi

_verify_doc_%:
	@if [ ! -f "doc/$*" ] ; then echo Brak pliku doc/$* ; exit 1 ; fi

clean:
	rm -f *~
	make -C doc clean
	make -C prog clean

######################################################################
# Usunicie testw genereowanych automatycznie
######################################################################
clean-gen:
	@if [ "$(INGEN)" -eq 1 ] ; then \
		if [ -e in/tmp ]; then rm -r in/tmp; fi ; \
		mkdir in/tmp ; \
		if [ -f prog/$(ID)ingen.sh ] ; then \
			cd in/tmp ; ../../prog/$(ID)ingen.sh ; \
		else \
			make -C prog $(ID)ingen.e ; \
			cd in/tmp ; ../../prog/$(ID)ingen.e ; \
		fi ; \
		INGEN_FILES="`echo *.in`"; \
		cd ../.. ; \
		rm -r in/tmp ; \
		for i in $$INGEN_FILES; do \
			j=`basename $$i .in`; \
			echo Kasuje in/$$j.in; rm -f in/$$j.in; \
			echo Kasuje out/$$j.out; rm -f out/$$j.out; \
		done ;\
	fi

mrproper:
	make -C doc mrproper
	make -C prog mrproper
	@if [ "$(INGEN)" -eq 1 ] ; then \
	    make clean-gen ; \
	fi
	@echo Usuwanie plikow OUT 
	rm -f out/*

############################################################################
# Przygotowanie danych wejciowych generowanych automatycznie
############################################################################
ingen:
	@if [ "$(INGEN)" -eq 1 ] ; then \
		if [ -f prog/$(ID)ingen.sh ] ; then \
			cd in ; ../prog/$(ID)ingen.sh ; \
		else \
			make -C prog $(ID)ingen.e ; \
			cd in ; ../prog/$(ID)ingen.e ; \
		fi ; \
	fi

############################################################################
# Weryfikacja poprawnoci danych wejciowych 
############################################################################
inwer:
	@if [ "$(INWER)" -eq 1 ] ; then \
		make -C prog $(ID)inwer.e ; \
		for i in in/*.in ; do \
			printf "%-10s ... " `basename $$i` ; \
			if ! prog/$(ID)inwer.e < $$i ;  then \
				echo "ZLE!!!" ; \
				exit 1 ; \
			fi ; \
		done ; \
	else \
		echo "Brak weryfikatora do testw" ; \
		exit 2 ; \
	fi 


############################################################################
# Wygenerowanie wzorcowych odpowiedzi dla biecego zestawu testw 
############################################################################
outgen:
	make -C prog $(ID).e
	@for i in in/*.in ; do \
		ulimit -s unlimited; \
	    echo -n "$$i ... " ; \
	    prog/$(ID).e < $$i > out/`basename $$i .in`.out ; \
	    echo OK ; \
	done 


############################################################################
# Uruchomienie programu prog/$(ID)%.e na biecym zestawie testw 
# Ustawienie zmiennej ACC_TERM na 1 powoduje, ze wywlaszczane testy
# sa uwazane za OK.
# Ustawienie STOP_ON_WRONG na 1 powoduje przerwanie po napotkaniu
# testu, ktorego program nie przechodzi
############################################################################
_run_ver_n_%:
	make -s -C prog $*
	@if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi
	@ACC_TERM=0;\
	STOP_ON_WRONG=0;\
	T_LIMIT=$(TIMELIMIT);\
    printf "\n%-10s " $* >> $(REPFILE); \
	for i in in/*.in ; do \
		j=out/`basename $$i .in`.out ; \
		\
		printf "%-10s " `basename $$i` ; \
		\
		rm -f $(TMP3);\
		rm -f $(TMP1);\
		(ulimit -v $(MEMLIMIT) -t $$T_LIMIT -s unlimited; if $(BIN_TIME) -f "%U" -o $(TMP2) prog/$* < $$i > $(TMP1); then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi ); \
		if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\
		rm -f $(TMP3);\
		TIME=`tail -n1 $(TMP2)` ; echo -n "$$TIME " ; \
		\
		if [ "$(CHECKER)" -eq "1" ] ; then \
			prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \
			RES=`head -1 $(TMP2)` ; \
			COMMENT=`head -2 $(TMP2) | tail -1` ; \
			if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \
		else \
			if diff -q $$j $(TMP1) > /dev/null ; then \
				RES="OK" ; \
			else \
				RES="WRONG_ANSWER" ; \
			fi ; \
			COMMENT="" ; \
		fi ; \
		if [ $$TERM -eq 1 ]; then RES="TERMINATED"; fi; \
		echo $$RES $$COMMENT ; \
		printf "%5s %1s " "$$TIME" "$${RES:0:1}" >> $(REPFILE); \
		if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \
		rm -f $(TMP1) $(TMP2) ; \
		if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\
	done;

_run_ver_o_%:
	make -s -C prog $*
	@if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi
	@ACC_TERM=0;\
	STOP_ON_WRONG=1;\
	T_LIMIT=$(TIMELIMIT);\
    printf "\n%-10s " $* >> $(REPFILE); \
	for i in in/*.in ; do \
		j=out/`basename $$i .in`.out ; \
		\
		printf "%-10s " `basename $$i` ; \
		\
		rm -f $(TMP3);\
		rm -f $(TMP1);\
		(ulimit -v $(MEMLIMIT) -t $$T_LIMIT -s unlimited;\
		if $(BIN_TIME) -f "%U" -o $(TMP2) prog/$* < $$i > $(TMP1); then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi ); \
		if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\
		rm -f $(TMP3);\
		TIME=`tail -n1 $(TMP2)` ; echo -n "$$TIME " ; \
		\
		if [ "$(CHECKER)" -eq "1" ] ; then \
			prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \
			RES=`head -1 $(TMP2)` ; \
			COMMENT=`head -2 $(TMP2) | tail -1` ; \
			if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \
		else \
			if diff -q $$j $(TMP1) > /dev/null ; then \
				RES="OK" ; \
			else \
				RES="WRONG_ANSWER" ; \
			fi ; \
			COMMENT="" ; \
		fi ; \
		if [ $$TERM -eq 1 ]; then RES="TERMINATED"; fi; \
		echo $$RES $$COMMENT ; \
		printf "%5s %1s " "$$TIME" "$${RES:0:1}" >> $(REPFILE); \
		if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \
		rm -f $(TMP1) $(TMP2) ; \
		if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\
	done

_run_ver_s_%:
	make -s -C prog $*
	@if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi
	@ACC_TERM=1;\
	STOP_ON_WRONG=1;\
	T_LIMIT=$(SLOW_TIMELIMIT);\
    printf "\n%-10s " $* >> $(REPFILE); \
	for i in in/*.in ; do \
		j=out/`basename $$i .in`.out ; \
		\
		printf "%-10s " `basename $$i` ; \
		\
		rm -f $(TMP3);\
		rm -f $(TMP1);\
		(ulimit -v $(MEMLIMIT) -t $$T_LIMIT -s unlimited; if $(BIN_TIME) -f "%U" -o $(TMP2) prog/$* < $$i > $(TMP1); then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi ); \
		if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\
		rm -f $(TMP3);\
		TIME=`tail -n1 $(TMP2)` ; echo -n "$$TIME " ; \
		\
		if [ "$(CHECKER)" -eq "1" ] ; then \
			prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \
			RES=`head -1 $(TMP2)` ; \
			COMMENT=`head -2 $(TMP2) | tail -1` ; \
			if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \
		else \
			if diff -q $$j $(TMP1) > /dev/null ; then \
				RES="OK" ; \
			else \
				RES="WRONG_ANSWER" ; \
			fi ; \
			COMMENT="" ; \
		fi ; \
		if [ $$TERM -eq 1 ]; then RES="TERMINATED"; fi; \
		echo $$RES $$COMMENT ; \
		printf "%5s %1s " "$$TIME" "$${RES:0:1}" >> $(REPFILE); \
		if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \
		rm -f $(TMP1) $(TMP2) ; \
		if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\
	done


############################################################################
# Przygotowanie pliku z opisem testrunw
############################################################################
testruns_header:
	@( \
	echo 'Raport z testowania';\
	echo '===================';\
	echo;\
	echo 'Rodzaj paczki: $(MODE)';\
	echo "Data:          `date`";\
	echo;\
	echo 'Procesor'; \
	echo '--------'; \
	echo ;\
	cat /proc/cpuinfo; \
	\
	echo 'Wyniki testowania'; \
	echo '-----------------'; \
	echo ;\
	echo -n 'prog/test  '; \
	for i in in/*.in ; do \
        BN="`basename $$i .in`"; \
        printf " %-7s" "$${BN:0:7}"; \
    done; \
	) > $(REPFILE);
