#
# Makefile.fpc for Free Pascal Tests directory
#

[defaults]
defaultrule=info

[sections]
none=1
exts=1

[rules]
.PHONY: all units tests cont_tests

# For linux by default no graph tests
ifdef inlinux
NOGRAPH=1
endif

DIRS=tf ts tbs tbf test tesi to webtbs webtbf

# defining NOGRAPH excludes tests using the graph unit, defining
# GRAPH includes those tests.
ifdef NOGRAPH
include graph.lst
endif
ifdef GRAPH
graphlst=
endif

all : info

units :
	$(MAKE) -C units

tests : clean all_compilations

cont_tests : all_compilations

setdate :
	$(FPC) setdate.pp
	setdate$(EXEEXT)
	call setdate.bat

.PHONY : setdate

getret$(EXEEXT) : getret.pp
	$(FPC) getret

getreturncode : getret$(EXEEXT)
ifndef inlinux
	redir -ea $(FILE).log -oa $(FILE).log getret $(COMMAND)
	cp retcode $(FILE).$(RESEXT)
else
	getret $(COMMAND) > $(FILE).log 2>$(FILE).log
	cp retcode $(FILE).$(RESEXT)
#	@echo "Return code of $(FILE) is $(cat retcode)"
endif


# retcode should be between 0 and 255
# 256 is for halt
# 512+doserror if doserror<>0
# 1024 RESFILE does not exist
# 2048 RESFILE is not set
ifndef RESFILE
RETVAL=2048
else
ifeq ($(wildcard $(RESFILE)*),$(RESFILE))
RETVAL=$(shell cat $(RESFILE))
else
RETVAL=1024
endif
endif

ifeq ($(RETVAL),0)
testsuccess:
	@echo "Test for $(FILE) success (compiles)"
	@echo "Test for $(FILE) success (compiles)" >>$(LOG)
else
testsuccess:
	@echo "Test for $(FILE) fails (does not compile) error $(RETVAL)"
	@echo "Test for $(FILE) fails (does not compile) error $(RETVAL)" >> $(LOG)
ifdef LONGLOG
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $(LONGLOG)
	@echo "Test for $(FILE) fails (does not compile) error $(RETVAL)" >> $(LONGLOG)
	@echo "" >> $(LONGLOG)
	cat $(FILE).log >> $(LONGLOG)
	@echo "" >> $(LONGLOG)
endif
	@echo $(FILE) does not compile >> ts_fail
	@echo $(FILE) does not compile error $(RETVAL) >> faillist
endif

ifdef EXCFILE
ifeq ($(wildcard $(EXCFILE)*),$(EXCFILE))
EXERETVAL:=$(shell cat $(EXCFILE))
else
EXERETVAL=$(EXCFILE) does not exist
endif
else
EXERETVAL=No EXCFILE variable defined
endif

ifdef REEFILE
ifeq ($(wildcard $(REEFILE)*),$(REEFILE))
export EXPECTEDRETVAL:=$(strip $(shell cat $(REEFILE)))
else
export EXPECTEDRETVAL=0
endif
endif

ifdef FILE
ifneq ($(CFGFILE),$(FILE).cfg)
ifneq ($(wildcard $(FILE).cfg),)
export CFGFILE:=$(FILE).cfg
export COMPILEROPT:=$(filter-out COMPILEROPT=,$(shell grep COMPILEROPT= $(CFGFILE)))
export RUNARGS:=$(filter-out RUNARGS=,$(shell grep RUNARGS= $(CFGFILE)))
export POSTPROCESS:=$(filter-out POSTPROCESS=,$(shell grep POSTPROCESS= $(CFGFILE)))
else
CFGFILE=
COMPILEROPT=
RUNARGS=
POSTPROCESS=
endif
endif
endif

ifeq ($(EXERETVAL),$(EXPECTEDRETVAL))
ifeq ($(EXPECTEDRETVAL),0)
testexecsuccess:
	@echo "Test for exec $(FILE) success (runs without error)"
	@echo "Test for $(FILE) success (runs without error)" >> $(LOG)
else
testexecsuccess:
	@echo "Test for exec $(FILE) success (gives correct error $(EXERETVAL))"
	@echo "Test for $(FILE) success (gives correct error $(EXERETVAL))" >> $(LOG)
endif
else
ifeq ($(EXPECTEDRETVAL),0)
testexecsuccess:
	@echo "Test for exec $(FILE) fails exec error $(EXERETVAL)"
	@echo "Test for exec $(FILE) fails exec error $(EXERETVAL)" >> $(LOG)
	@echo "Running $(FILE) fails with error $(EXERETVAL)" >> faillist
ifdef LONGLOG
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $(LONGLOG)
	@echo "Test for exec $(FILE) fails exec error $(EXERETVAL)" >> $(LONGLOG)
	@echo "" >> $(LONGLOG)
	cat $(FILE).elg >> $(LONGLOG)
	@echo $(FILE) >> ex_fail
endif
else
testexecsuccess:
	@echo "Test for exec $(FILE) fails exec error $(EXERETVAL) ($(EXPECTEDRETVAL) expected)"
	@echo "Test for exec $(FILE) fails exec error $(EXERETVAL) ($(EXPECTEDRETVAL) expected)" >> $(LOG)
	@echo "Running $(FILE) fails with error $(EXERETVAL) ($(EXPECTEDRETVAL) expected)" >> faillist
ifdef LONGLOG
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $(LONGLOG)
	@echo "Test for exec $(FILE) fails exec error $(EXERETVAL) ($(EXPECTEDRETVAL) expected)" >> $(LONGLOG)
	@echo "" >> $(LONGLOG)
	cat $(FILE).elg >> $(LONGLOG)
	@echo $(FILE) >> ex_fail
endif
endif
endif

ifeq ($(wildcard $(FILE)$(EXEEXT)),$(FILE)$(EXEEXT))
testexec:
	@echo "Testing $(FILE)$(EXEEXT)"
ifdef NOREDIR
	getret $(FILE)$(EXEEXT)
	@echo CFGFILE is $(CFGFILE)
ifdef POSTPROCESS
	echo Running post process
	-$(POSTPROCESS)
endif
else
ifndef inlinux
	redir -e $(FILE).elg -o $(FILE).elg getret $(FILE)$(EXEEXT) $(RUNARGS)
	@echo CFGFILE is $(CFGFILE)
ifdef POSTPROCESS
	@echo Running post process
	-redir -ea $(FILE).elg -oa $(FILE).elg $(POSTPROCESS)
endif
else
	getret $(FILE)$(EXEEXT) $(RUNARGS) > $(FILE).elg 2>$(FILE).elg
	@echo CFGFILE is $(CFGFILE)
ifdef POSTPROCESS
	echo Running post process
	-$(POSTPROCESS) >> $(FILE).elg 2>> $(FILE).elg
endif
endif
endif
	cp -f retcode $(FILE).exc
	$(MAKE) testexecsuccess 'FILE=$(FILE)' 'EXCFILE=$(FILE).exc' 'REEFILE=$(FILE).ree'
else
testexec:
ifeq ($(wildcard $(FILE)$(PPUEXT)),$(FILE)$(PPUEXT))
	@echo "file is a unit $(FILE)$(PPUEXT)"
	@echo "unit" > $(FILE).elg
else
ifeq ($(wildcard $(FILE).dll),$(FILE).dll)
	@echo "file is a DLL $(FILE)$(PPUEXT)"
	@echo "DLL" > $(FILE).elg
else
	@echo "No exefile $(FILE)$(EXEEXT)"
ifdef LONGLOG
	@echo "No exefile $(FILE)$(EXEEXT) was generated" >> $(LONGLOG)
endif
endif
endif
endif

test_exc :
	@echo $(wildcard $(FILE).exc*)
	@echo xx$(wildcard $(EXCFILE)*)xx xx$(EXCFILE)xx
	cat $(FILE).exc

ifneq ($(RETVAL),0)
testfail:
	@echo "Test for $(FILE) success (does not compile) error $(RETVAL)"
	@echo "Test for $(FILE) success (does not compile) error $(RETVAL)" >> $(LOG)
else
testfail:
	@echo "Test for $(FILE) fails (does compile and should not)"
	@echo "Test for $(FILE) fails (does compile and should not)" >> $(LOG)
ifdef LONGLOG
	@echo "Test for $(FILE) fails (does compile and should not)" >> $(LONGLOG)
endif
	@echo $(FILE) >> tf_fail
	@echo $(FILE) compiles >> faillist
endif

ifndef LONGLOG
export LONGLOG:=longlog
endif

ifndef LOG
export LOG:=log
endif


listcfg :
	@echo CFGFILE is "$(CFGFILE)"
	@echo COMPILEROPT is "$(COMPILEROPT)"
	@echo RUNARGS is "$(RUNARGS)"
	@echo EXPECTEDRETVAL is "$(EXPECTEDRETVAL)"
	@echo POSTPROCESS is "$(POSTPROCESS)"

ifdef FILE
OPTFILE=$(wildcard $(FILE).opt)
endif

ifdef OPTFILE
override OPT+=$(OPTFILE)
endif

ifndef FILE
FILE=ts/ts00001.pp
endif

testone :
	$(MAKE) getreturncode 'COMMAND=$(FPC) $(OPT) $(COMPILEROPT) $(FILE).pp' 'RESEXT=$(RESEXT)' 'FILE=$(FILE)'


%.res : %.pp
	$(MAKE) testone 'FILE=$*' 'RESEXT=res'
	$(MAKE) testsuccess 'FILE=$*' 'RESFILE=$*.res'

%.ref : %.pp
	$(MAKE) testone 'FILE=$*' 'RESEXT=ref'
	$(MAKE) testfail 'FILE=$*' 'RESFILE=$*.ref'

# exec log files
# creates two files
# *.elg log file
# *.exc exicode of program
%.elg : %.res
	$(MAKE) testexec 'FILE=$*'

%.eli : %.res
	$(MAKE) testexec 'FILE=$*' 'NOREDIR=YES'

allts : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard ts/ts*.pp)))

alltbs : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard tbs/tbs*.pp)))

allwebtbs : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard webtbs/tbug*.pp)))

tbs0to99    : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard tbs/tbs00*.pp)))
tbs100to199 : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard tbs/tbs01*.pp)))
tbs200to299 : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard tbs/tbs02*.pp)))
tbs300to399 : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard tbs/tbs03*.pp)))

alltest : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard test/test*.pp)))

alltesi : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard tesi/tesi*.pp)))

alltis : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard tis/tis*.pp)))

alltf : $(patsubst %.pp,%.ref,$(filter-out $(graphlst),$(wildcard tf/tf*.pp)))

alltbf : $(patsubst %.pp,%.ref,$(filter-out $(graphlst),$(wildcard tbf/tbf*.pp)))

allwebtbf : $(patsubst %.pp,%.ref,$(filter-out $(graphlst),$(wildcard webtbf/tbug*.pp)))

allto : $(patsubst %.pp,%.res,$(filter-out $(graphlst),$(wildcard to/to*.pp)))

ifndef TS_FAIL_LIST
ifeq ($(wildcard ts_fail*),ts_fail)
TS_FAIL_LIST=$(shell cat ts_fail)
export TS_FAIL_LIST
endif
endif

ifndef TF_FAIL_LIST
ifeq ($(wildcard tf_fail*),tf_fail)
TF_FAIL_LIST=$(shell cat tf_fail)
export TF_FAIL_LIST
endif
endif

ifndef EXEC_FAIL_LIST
ifeq ($(wildcard ex_fail*),ex_fail)
EXEC_FAIL_LIST=$(shell cat ex_fail)
export EXEC_FAIL_LIST
endif
endif

clean_fail :
	-rm -f $(addsuffix .res,$(TS_FAIL_LIST))
	-rm -f $(addsuffix .ref,$(TF_FAIL_LIST))
	-rm -f $(addsuffix .res,$(EXEC_FAIL_LIST))
	-rm -f $(addsuffix .elg,$(EXEC_FAIL_LIST))

# Test all failure of last time
# don't forget to try to run them again
again :
	$(MAKE) internal_again LOG=again.log LONGLOG=again.llg

internal_again : clean_fail $(addsuffix .res,$(TS_FAIL_LIST)) \
	$(addsuffix .ref,$(TF_FAIL_LIST)) \
	$(addsuffix .elg,$(EXEC_FAIL_LIST) $(TS_FAIL_LIST))
	grep fails $(LOG)

all_compilations : allts alltbs allwebtbs alltf alltbf allwebtbf allto alltest alltesi alltis
	grep fails $(LOG)

allexec : alltsexec alltbsexec allwebtbsexec alltestexec
	grep fails  $(LOG)

alltestexec: $(patsubst %.pp,%.elg,$(wildcard test/test*.pp))

allfails :
	grep fails $(LOG) > fails.log

# these test are interactive
# no redirection !!!

alltesiexec: $(patsubst %.pp,%.eli,$(filter-out $(graphlst),$(wildcard tesi/tesi*.pp)))

alltsexec: $(patsubst %.pp,%.elg,$(filter-out $(graphlst),$(wildcard ts/ts*.pp)))

alltbsexec: $(patsubst %.pp,%.elg,$(filter-out $(graphlst),$(wildcard tbs/tbs*.pp)))

allwebtbsexec: $(patsubst %.pp,%.elg,$(filter-out $(graphlst),$(wildcard webtbs/tbug*.pp)))

tbsexec0to99 : $(patsubst %.pp,%.elg,$(filter-out $(graphlst),$(wildcard tbs/tbs00*.pp)))
tbsexec100to199 : $(patsubst %.pp,%.elg,$(filter-out $(graphlst),$(wildcard tbs/tbs01*.pp)))
tbsexec200to299 : $(patsubst %.pp,%.elg,$(filter-out $(graphlst),$(wildcard tbs/tbs02*.pp)))
tbsexec300to399 : $(patsubst %.pp,%.elg,$(filter-out $(graphlst),$(wildcard tbs/tbs03*.pp)))

alltisexec: $(patsubst %.pp,%.eli,$(filter-out $(graphlst),$(wildcard tis/tis*.pp)))

clean:
	-rm -f $(addsuffix /*.ref,$(DIRS))
	-rm -f $(addsuffix /*.res,$(DIRS))
        -rm -f $(addsuffix /*$(PPUEXT),$(DIRS))
	-rm -f $(addsuffix /*$(OEXT),$(DIRS))
	-rm -f $(addsuffix /*.log,$(DIRS))
	-rm -f $(addsuffix /*.elg,$(DIRS))
	-rm -f $(addsuffix /*.exc,$(DIRS))
ifdef inlinux
	-rm -f $(patsubst %.pp,%$(EXEEXT),$(wildcard $(addsuffix /t*.pp,$(DIRS))))
else
	-rm -f $(addsuffix /*$(EXEEXT),$(DIRS))
endif
	-rm -f *.tmp
	-rm -f $(LOG) $(LONGLOG) faillist ts_fail tf_fail ex_fail
	-rm -f fpcmaked ppas.sh ppas.bat retcode

full : clean all_compilations allexec

info :
	@echo This Makefile allows to test the compiler
	@echo compilation of 'ts*.pp' should succeed
	@echo compilation of 'tf*.pp' should fail
	@echo compilation of 'test*.pp' should succeed
	@echo 'to*.pp' files should also compile
	@echo simply run \'make tests\' to test all compilation
	@echo run \'make allexec\' to test also if the executables
	@echo created behave like the should
	@echo run \'make tesiexec\' to test executables
	@echo that require interactive mode