source = mile32.c

ifeq ($(OSTYPE),cygwin)
eext = .exe
endif

cc = gcc

# -pedantic causes test_output_empty to fail, due to:
# ISO C forbids empty initializer braces [-Werror=pedantic]
cflags = -std=c90 -Wall -Werror -O3

# -Wno-misleading-indentation is due to this bug:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89549
test_cflags = $(cflags) -Wno-misleading-indentation

all: mile$(eext) cppp$(eext)

mile$(eext): $(source)
	$(cc) $(cflags) $< -o $@

cppp$(eext): cppp.cc
	g++ -Wall -Werror -O3 -std=c++17 $< -o $@
	./cppp_test.sh

test: test_output_all_passed.ok

test_output_all_passed.ok: \
	test_output_gcc_c90.ok \
	test_output_gcc_c99.ok \
	test_output_gcc_c11.ok \
	test_output_clang_c90.ok \
	test_output_clang_c99.ok \
	test_output_clang_c11.ok
	touch test_output_all_passed.ok

test_output_gcc_c90.ok: $(source) test_output_fast_tests.ok
	./test_compiler_variation.sh $< gcc c90 && touch $@

test_output_gcc_c99.ok: $(source) test_output_fast_tests.ok
	./test_compiler_variation.sh $< gcc c99 && touch $@

test_output_gcc_c11.ok: $(source) test_output_fast_tests.ok
	./test_compiler_variation.sh $< gcc c11 && touch $@

test_output_clang_c90.ok: $(source) test_output_fast_tests.ok
	./test_compiler_variation.sh $< clang c90 && touch $@

test_output_clang_c99.ok: $(source) test_output_fast_tests.ok
	./test_compiler_variation.sh $< clang c99 && touch $@

test_output_clang_c11.ok: $(source) test_output_fast_tests.ok
	./test_compiler_variation.sh $< clang c11 && touch $@

test_output_fast_tests.ok: \
	test_output_usage.ok \
	test_output_empty.ok \
	test_output_randomized.ok \
	test_output_txt0.ok \
	test_output_txt1.ok \
	test_output_txt2.ok \
	test_output_txt3.ok \
	test_output_bin0.ok \
	test_output_bin1.ok
	touch $@

test_output_usage.ok: mile$(eext) usage.txt
	./$< | diff -q - usage.txt && touch $@

test_output_empty.ok: test_output_empty$(eext)
	./$< | diff -q - /dev/null && touch $@

test_output_txt0.ok: test_output_txt0$(eext)
	./$< | grep -qF OK && touch $@

test_output_txt1.ok: test_output_txt1$(eext) sample_input1.txt
	./$< | diff -q - sample_input1.txt && touch $@

test_output_txt2.ok: test_output_txt2$(eext) sample_input2.txt
	./$< | diff -q - sample_input2.txt && touch $@

test_output_txt3.ok: test_output_txt3$(eext) sample_input3.txt
	./$< | diff -q - sample_input3.txt && touch $@

test_output_bin0.ok: test_output_bin0$(eext) test_output_generated_input0.bin
	./$< | diff -q - test_output_generated_input0.bin && touch $@

test_output_bin1.ok: test_output_bin1$(eext) test_output_generated_input1.bin
	./$< | diff -q - test_output_generated_input1.bin && touch $@

test_output_empty$(eext): test_output_empty.c
	$(cc) $(test_cflags) -DPIN=1 $< -o $@

test_output_txt0$(eext): test_output_txt0.c
	$(cc) $(test_cflags) -DPIN=7 $< -o $@

test_output_txt1$(eext): test_output_txt1.c
	$(cc) $(test_cflags) $< -o $@

test_output_txt2$(eext): test_output_txt2.c
	$(cc) $(test_cflags) $< -o $@

test_output_txt3$(eext): test_output_txt3.c
	$(cc) $(test_cflags) $< -o $@

test_output_bin0$(eext): test_output_bin0.c
	$(cc) $(test_cflags) $< -o $@

test_output_bin1$(eext): test_output_bin1.c
	$(cc) $(test_cflags) $< -o $@

test_output_empty.c: mile$(eext)
	./$< 1 < /dev/null > $@

test_output_txt0.c: mile$(eext)
	echo "OK" | ./mile$(eext) 7 > $@

test_output_txt1.c: sample_input1.txt mile$(eext) cppp$(eext)
	./mile$(eext) 1 < $< | ./cppp$(eext) -DPIN=1 > $@

test_output_txt2.c: sample_input2.txt mile$(eext) cppp$(eext)
	./mile$(eext) 257 < $< | ./cppp$(eext) -DPIN=257 > $@

test_output_txt3.c: sample_input3.txt mile$(eext) cppp$(eext)
	./mile$(eext) 65535 < $< | ./cppp$(eext) -DPIN=65535 > $@

test_output_bin0.c: test_output_generated_input0.bin mile$(eext) cppp$(eext)
	./mile$(eext) 12345 < $< | ./cppp$(eext) -DPIN=12345 > $@

test_output_bin1.c: test_output_generated_input1.bin mile$(eext) cppp$(eext)
	./mile$(eext) 56789 < $< | ./cppp$(eext) -DPIN=56789 > $@

test_output_randomized.ok: mile$(eext)
	echo "A" | ./mile$(eext) 2 > test_output_randomized1.c
	sleep 2
	echo "A" | ./mile$(eext) 2 > test_output_randomized2.c
	( diff -q test_output_randomized1.c test_output_randomized2.c > /dev/null && echo "Output not randomized" ) || touch $@

test_output_generated_input0.bin: generate_ordered_binary.pl
	perl $< > $@

test_output_generated_input1.bin: generate_random_binary.pl
	perl $< 54321 2048 > $@

clean:
	-rm -f cppp$(eext) mile$(eext) test_output*

backup:
	-rm -f backup.tar.gz
	tar czf backup.tar.gz *.c *.cc *.pl *.sh *.log *.csv *.txt Makefile
