CPP = gcc -E
CPPFLAGS = -DNO_STDARG -DNO_STRTOUL -DNO_PROTOTYPES ../../runtime/gcc-builtin.h

PARSE = ../cilk2c
PARSEFLAGS = -Wall -notrans

CC = gcc
CFLAGS = -Wall -DNO_STDARG -DNO_STRTOUL -DNO_PROTOTYPES

KNOWN_UNFIXABLE_BUGS = enum.err ptrarith.err extern.err

ERROR_MESSAGE_C_SOURCES = const.c cfold.c signed.c undecl.c coerce.c \
   array-field.c switch.c tq.c anonstruct.c escapes.c \
   A.c B.c char2.c expr.c old.c proc.c \
   scope.c test.c tricky.c \
   empty.c enumargs.c unused.c preced.c voidptr.c bt.c sdcls.c \
   callargs.c arr.c include.c f.c \
   pragma_lang0.c pragma_lang1.c pragma_lang2.c pragma_lang3.c pragma_lang4.c


ERROR_MESSAGE_I_SOURCES = \
 init.i \
 labelerr.i \
 constructor-ansi.i \
 initializer2-ansi.i \
 ternary-ansi.i \
 voidstar-plus-zero-ansi.i \
 conditional-omited-operand-ansi.i \
 return-void-ansi.i


ERROR_MESSAGE_TESTS = $(patsubst %.c,%.err,$(ERROR_MESSAGE_C_SOURCES))  $(patsubst %.i,%.err,$(ERROR_MESSAGE_I_SOURCES))

ANALYSIS_TESTS = \
   analysis.an

TRANSLATION_FILES =  \
   inlinevoid \
   voidfun \
   goodtypedef \
   unused-arg \
   unsign enumconst tdef weirdtypes label sizeofstr \
   int nasty S  \
   cpp fact string-concat nodim sizeof switch2 \
   cond ec tdefreturn struct bitfield  \
   undim gnu ifelse attrib incompl ptrarr

CILK2C_FILES = \
   cilk-array-init.cilk2c

C2C_SOURCE =  \
   ../ast.end            ../complex-types.end  ../container.end    \
   ../constexpr.end      ../conversions.end    ../initializer.end  \
   ../list.end           ../main.end           ../operators.end    \
   ../output.end         ../print-ast.end      ../procedure.end    \
   ../sem-check.end      ../strings.end        ../sue.end          \
   ../symbol.end         ../transform.end      ../type.end         \
   ../type2.end          ../verify-parse.end   ../warning.end      \
   ../dataflow.end       ../analyze.end \
   ../profile.end

OTHER_END2END = paren.endi \
                pragma4.endi memmove.end memmove2.end memmove3.end \
                structinit.end structinit2.end structinit3.end \
                struct-packed.end packed-char.end pragma_packed.end \
                arrayinit.end typeof2.endI \
                typeof.endI typeof3.end typeof4.end \
                initializer_test.endI initializer_test2.endI constructor.end lvalue-test.end initializer2.end struct-nested-init.end tq2.endi const-qual.endi volatile-qual.endi ternary.end attrib-doubled.end voidstar-plus-zero.endI conditional-omited-operand.end return-void.end \
                plan9date.end \
                fieldname_is_typedef.endI fieldname_is_typedef2.endI \
		test-stdarg.end \
		include-complex.end \
	        extension-empty-array.end

extension-empty-array-END-CFLAGS=-pedantic-errors -ansi

.SUFFIXES: .msg .ast .end .err .an .err.test .ast.test .c .endi .i .endI .endp

CLEAN = rm -f *.p.c *.p.i *.g.c *.ast *~ *.BAK *.bak *.orig *.o *.out *.err *.err.test *.ast.test .\#* *.an ../*.end ../*.endp *.endI *.prof.i $(patsubst ../%.end,%.i,$(C2C_SOURCE)) $(patsubst ../%.end,%.prof.c,$(C2C_SOURCE)) $(patsubst %,%.prof.c,$(TRANSLATION_FILES))  $(patsubst %,%.i,$(TRANSLATION_FILES)) $(patsubst %.c,%.i,$(ERROR_MESSAGE_C_SOURCES)) $(patsubst %.an,%.i,$(ANALYSIS_TESTS)) $(patsubst %.end,%.i,$(OTHER_END2END))  $(patsubst %.endi,%.withbuiltin.i,$(OTHER_END2END)) *.astp simplify1.c2c.i simplify1.i simplify1.other *.prof.c *.endierr $(OTHER_TESTS) gcc-3.3.1-void-error.i gcc-3.3.1-void-error.o gcc-3.3.1-void-error.p.c gcc-3.3.1-void-error.p.o \
  $(CILK2C_TESTS) \
  test-stdarg.ot \
  comma.other \
  run-test-stdarg.other \
  run-profile-tester \
  gcc-3.3.1-void-error.other \
  solaris-pragma.stderr solaris-pragma.other \
  char.stderr char.out char.other

all: error-messages \
  translation \
  analysis \
  self-parse \
  other_end2end \
  other_tests \
  profile-tests \
  cilk2c_tests
	@echo all tests passed OK

other_end2end: $(OTHER_END2END)

ERROR-TESTS = $(patsubst %.err,%.err.test,$(ERROR_MESSAGE_TESTS))
error-messages: $(ERROR-TESTS)

analysis: $(ANALYSIS_TESTS)

TRANSLATION_TESTS = $(patsubst %,%.ast.test,$(TRANSLATION_FILES))
translation: $(TRANSLATION_TESTS)

CILK2C_TESTS = $(patsubst %.cilk2c, %.cilkc, $(CILK2C_FILES))
cilk2c_tests: $(CILK2C_TESTS)
%.cilkc: %.cilki ../cilk2c
	@echo "--------------------------------- cilk-to-c transaction test: $<"
	../cilk2c $< -o $@

self-parse: $(C2C_SOURCE)

# profile-tests: $(patsubst %, %.astp, $(filter-out gnu,$(TRANSLATION_FILES)))

profile-tester: profile-tester.o profile-testee.o
profile-tester.o: profile-tester.c profile-testee.h
	$(CC) profile-tester.c -W -Wall -Werror -O2 -c
profile-testee.o: profile-testee.c profile-testee.h ../cilk2c
	$(CPP) profile-testee.c > profile-testee.prec2c.i
	../cilk2c -notrans -profile profile-testee.prec2c.i -o profile-testee.i
	$(CC) profile-testee.i -c -W -Wall -Werror -O2
run-profile-tester: profile-tester
	./profile-tester
	touch run-profile-tester

# attrib.c produces warnings from gcc, and I want to catch warnings with -Werror for this test.
profile-tests: run-profile-tester $(patsubst %, %.astp, $(filter-out attrib,$(TRANSLATION_FILES))) $(patsubst %.end, %.endp, $(C2C_SOURCE)) profile-bitfield.astp constructor.astp lvalue-test.astp asm2.astp constructor-prof.astp sue-elaborated.astp keep-const.astp arrow.astp

known-bugs: $(KNOWN_UNFIXABLE_BUGS)

clean:
	$(CLEAN)

.PHONY: clean known-bugs self-parse translation analysis error-messages profile-tests all


voidptr_CPPFLAGS = -DNOP
voidptr_PARSEFLAGS = -ansi -Wall -notrans
tq_CPPFLAGS = -DNOP
tq_PARSEFLAGS = -ansi -Wall -notrans
empty_CPPFLAGS = -DNOP
empty_PARSEFLAGS = -ansi -Wall -notrans
init_PARSEFLAGS = -ansi
labelerr_PARSEFLAGS = -ansi
constructor-ansi_PARSEFLAGS = -ansi
initializer2-ansi_PARSEFLAGS = -ansi
ternary-ansi_PARSEFLAGS = -ansi
voidstar-plus-zero-ansi_PARSEFLAGS = -ansi
conditional-omited-operand-ansi_PARSEFLAGS = -ansi
return-void-ansi_PARSEFLAGS = -ansi

%.ast: %.c ../cilk2c
	@echo "--------------------------------- AST test: $<"
	$(CPP)   $(if $($(*F)_CPPFLAGS),   $($(*F)_CPPFLAGS),   $(CPPFLAGS)) $< > $(*F).i
	$(PARSE) $(if $($(*F)_PARSEFLAGS),$($(*F)_PARSEFLAGS),$(PARSEFLAGS))  -name $< $(*F).i   -o $(*F).p.c -ast > $*.ast
	$(CPP)   $(if $($(*F)_CPPFLAGS),   $($(*F)_CPPFLAGS),   $(CPPFLAGS)) $(*F).p.c > $(*F).p.i
	$(PARSE) $(if $($(*F)_PARSEFLAGS),$($(*F)_PARSEFLAGS),$(PARSEFLAGS)) -name $< $(*F).p.i -o $(*F).p.p.c -ast > $*.p.ast

%.astp: %.c ../cilk2c
	@echo "-------------------------------- AST test with profiling: $<"
	$(CPP)   $(if $($(*F)_CPPFLAGS),   $($(*F)_CPPFLAGS),   $(CPPFLAGS)) $< > $(*F).prof.i
	$(PARSE) -profile $(if $($(*F)_PARSEFLAGS),$($(*F)_PARSEFLAGS),$(PARSEFLAGS))  -name $< $(*F).prof.i   -o $(*F).prof.c
	if $(CC) $< -c; then $(CC) $(*F).prof.c -c; else if $(CC) $(*F).prof.c -c; then echo Test failed; exit 1; fi; fi
	touch $@

.PRECIOUS: %.ast
%.ast.test: %.ast
	diff $(*F).ast $(*F).p.ast
	diff -w $(*F).p.c $(*F).p.p.c
	@touch $@
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $< tested successfully."
	@echo

# This sed junk is because of Bug172 (gcc changed its error message)
# I just change it back...

.PRECIOUS: %.err
%.err: %.c %.msg ../cilk2c
	@echo "--------------------------------- Error-message test: $<"
	-($(CPP) $(if $($(*F)_CPPFLAGS),   $($(*F)_CPPFLAGS),   $(CPPFLAGS)) $< > $(*F).i  && $(PARSE) $(PARSEFLAGS) $($(*F)_PARSEFLAGS) -name $< $(*F).i -o /dev/null) 2>&1 | sed -e "s/syntax error/parse error/" > $(*F).err 

%.err: %.i %.msg ../cilk2c
	@echo "--------------------------------- Error-message test: $<"
	- $(PARSE) $(PARSEFLAGS) $($(*F)_PARSEFLAGS) -name $< $(*F).i -o /dev/null > $(*F).err 2>&1

%.err.test: %.err
	diff $(*F).err $(*F).msg 
	@touch $@
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $< tested successfully."
	@echo


%.an: %.c ../cilk2c
	@echo "--------------------------------- Analysis test: $<"
	$(CPP)  $(if $($(*F)_CPPFLAGS),   $($(*F)_CPPFLAGS),   $(CPPFLAGS)) $< > $(*F).i
	$(PARSE) $(if $($(*F)_PARSEFLAGS),$($(*F)_PARSEFLAGS),$(PARSEFLAGS)) -live -o $(*F).p.c $(*F).i > $*.err 2>&1
	diff $(*F).err $(*F).msg
	grep -v "^#" $(*F).p.c | (tr \\n " " ;echo)> $(*F).p.g.c
	grep -v "^#" $(*F).a.c | (tr \\n " ";echo) > $(*F).a.g.c
	diff -w $(*F).p.g.c $(*F).a.g.c
	@touch $@
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $< tested successfully."
	@echo


ENDTOENDFLAGS = -DHAVE_CONFIG_H -I.. -I../.. -I../../runtime
%.end: %.c ../cilk2c
	@echo "--------------------------------- End-to-end test: $<"
	cp $< $(*F).p.c
	$(CPP)      $(ENDTOENDFLAGS) $($(patsubst %.end,%-END-CFLAGS,$@)) $(*F).p.c > $(*F).i
	cp $(*F).i $(*F).p.i
	$(CC) -Wall $(ENDTOENDFLAGS) $($(patsubst %.end,%-END-CFLAGS,$@)) -c -o $(*F).o $(*F).p.i
	mv $(*F).o $(*F).p.o
	$(CPP) $(ENDTOENDFLAGS)  $($(patsubst %.end,%-END-CFLAGS,$@)) ../../runtime/gcc-builtin.h $(*F).p.c > $(*F).p.i
	$(PARSE) -Wall -notrans -name $(*F).p.c  -o $(*F).p.c $(*F).p.i
	mv $(*F).p.c $(*F).p.i
	$(CC) -Wall $($(patsubst %.end,%-END-CFLAGS,$@)) -c -o $(*F).o $(*F).p.i
	diff $(*F).o $(*F).p.o
	@touch $@
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $< tested successfully."
	@echo
%.endp: %.c ../cilk2c
	@echo "--------------------------------- End-to-end test with profiling: $<"
	$(CPP) $(ENDTOENDFLAGS) ../../runtime/gcc-builtin.h $< > $(*F).prof.c
	$(PARSE) -notrans -profile -o $(*F).prof.i $(*F).prof.c
	$(CC) -Wall -c $(*F).prof.i
	touch $@
# the business with the .endierr is to make sure that no error messages print out.  NOne of the endi tests should produce warnings or errors
%.endi: %.i ../cilk2c
	@echo "--------------------------------- End-to-end test: $<"
	$(CC) -Wall -c -o $(*F).o $<
	mv $(*F).o $(*F).p.o
	($(CPP) ../../runtime/gcc-builtin.h ; cat $(*F).i) > $(*F).withbuiltin.i
	$(PARSE) -Wall -notrans -name $(*F).c $(*F).withbuiltin.i > $(*F).p.i
	$(CC) -Wall -c -o $(*F).o $(*F).p.i 2> $(*F).endierr
	diff $(*F).endierr /dev/null
	diff $(*F).o $(*F).p.o
	@touch $@
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $< tested successfully."
	@echo
# endI is when you don't need the builtins
%.endI: %.i ../cilk2c
	@echo "--------------------------------- End-to-end test: $<"
	$(CC) -Wall -c -o $(*F).o $<
	mv $(*F).o $(*F).p.o
	$(PARSE) -Wall -notrans -name $(*F).c $< > $(*F).p.i
	$(CC) -Wall -c -o $(*F).o $(*F).p.i
	diff $(*F).o $(*F).p.o
	@touch $@
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $< tested successfully."
	@echo
# endI is when you don't need the builtins
.i.endI:
	@echo "--------------------------------- End-to-end test: $<"
	$(CC) -Wall -c -o $(*F).o $<
	mv $(*F).o $(*F).p.o
	$(PARSE) -Wall -notrans -name $(*F).c $< > $(*F).p.i
	$(CC) -Wall -c -o $(*F).o $(*F).p.i
	diff $(*F).o $(*F).p.o
	@touch $@
	@echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $< tested successfully."
	@echo

OTHER_TESTS = pragma_order_test_1 pragma_order_test_2 no_such_file simplify1.other comma.other gcc-3.3.1-void-error.other run-test-stdarg.other \
	      solaris-pragma.other \
	      char.other \
              maybe.mk_thread_kern.endi \
	      complex-rh8.other

other_tests: $(OTHER_TESTS)

complex-rh8.other: ../cilk2c complex-rh8.i
	../cilk2c -Wall -notrans -o complex-rh8.p.c complex-rh8.i
	touch $@

# For the pragma order test, make sure that the pr
pragma_order_test_1: ../cilk2c pragma1.c
	../cilk2c -Wall -notrans pragma1.c -o pragma1.p.c
	tail +3 pragma1.p.c > pragma1.p.c.tail
	diff pragma1.c pragma1.p.c.tail
	touch $@

pragma_order_test_2: ../cilk2c pragma2.c
	../cilk2c -Wall -notrans pragma2.c -o pragma2.p.c
	tail +3 pragma2.p.c > pragma2.p.c.tail
	diff pragma2.c pragma2.p.c.tail
	touch $@

no_such_file: ../cilk2c
	-../cilk2c no-such-file.c > no-such-file.err 2>&1
	touch $@

simplify1.other: simplify1.c ../cilk2c
	@echo "--------------------------------- simplify1.other test"
	$(CPP) simplify1.c > simplify1.i
	$(PARSE) -simplify -notrans -name simplify1.c simplify1.i -o simplify1.c2c.i
	fgrep "(x,y =z)" simplify1.c2c.i > /dev/null
	fgrep "(x,y +=z)" simplify1.c2c.i > /dev/null
	fgrep "(x,y /=z)" simplify1.c2c.i > /dev/null
	fgrep "(x,y ++)" simplify1.c2c.i > /dev/null
	fgrep "w= (x,&y)" simplify1.c2c.i > /dev/null
	fgrep "( int)   (ww=(char*)(int)5);" simplify1.c2c.i > /dev/null
	fgrep "(int)  (zz=(char*)(int)5);" simplify1.c2c.i > /dev/null
	fgrep "(*f_p).a++;" simplify1.c2c.i > /dev/null
	fgrep "(*(*g_p).f_p).a++" simplify1.c2c.i > /dev/null
	fgrep "f_v . a++" simplify1.c2c.i > /dev/null
	@touch $@
	@echo "--------------------------------- simplify1.other successful"

comma.other: comma.i ../cilk2c
	@echo "--------------------------------- comma.other test"
	../cilk2c -N -Wall -notrans comma.i -o comma.p.i
	diff comma.i comma.p.i
	touch comma.other
	@echo "--------------------------------- comma.other successful"

gcc-3.3.1-void-error.other: gcc-3.3.1-void-error.c ../cilk2c
	gcc -c gcc-3.3.1-void-error.c
	gcc -E gcc-3.3.1-void-error.c > gcc-3.3.1-void-error.i
	../cilk2c gcc-3.3.1-void-error.i -notrans >  gcc-3.3.1-void-error.p.c
	gcc -c gcc-3.3.1-void-error.p.c
	touch gcc-3.3.1-void-error.other

run-test-stdarg.other: 
	gcc -E -DHAVE_CONFIG_H -I.. -I../.. -I../../runtime ../../runtime/gcc-builtin.h test-stdarg.c > test-stdarg.ot.i
	../cilk2c -Wall -notrans test-stdarg.ot.i -o test-stdarg.ot.p.i
	gcc -Wall test-stdarg.ot.p.i -o test-stdarg.ot
	./test-stdarg.ot
	touch run-test-stdarg.other

solaris-pragma.other:
	../cilk2c solaris-pragma.c 1>solaris-pragma.out 2>solaris-pragma.stderr
	if fgrep Warning solaris-pragma.stderr > /dev/null; then echo solaris-pragma.other test failed; exit 1; fi
	touch solaris-pragma.other
char.other:
	-../cilk2c char.c 1>char.out 2>char.stderr
	diff char.stderr char.msg
	touch char.other

maybe.mk_thread_kern.endi:
	if test `uname -m` = i686; then make mk_thread_kern.endi; fi
	touch maybe.mk_thread_kern.endi

# Probably don't want do to this by mistake
#.c.msg:
#	-$(PARSE) $(PARSEFLAGS) $< >$@ 2>&1 

a:
	 /home/bradley/sandbox/cilk/current.Bug66/cilk2c/cilk2c -notrans -profile -o delete.me3.i -name open.c delete.me3.c2c.i
	gcc -c delete.me3.i
b:
	gcc -c delete.me3.c2c.i
