# Makefile for regression testing the GNU debugger.
# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.

# This file is part of GDB.

# GDB is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# GDB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

VPATH = @srcdir@
srcdir = @srcdir@
srcroot = $(srcdir)/..

prefix = @prefix@
exec_prefix = @exec_prefix@

host_alias = @host_alias@
target_alias = @target_alias@
program_transform_name = @program_transform_name@
build_canonical = @build@
host_canonical = @host@
target_canonical = @target@
target_cpu = @target_cpu@


SHELL = /bin/sh
SUBDIRS = @subdirs@
RPATH_ENVVAR = @RPATH_ENVVAR@

EXPECT = `if [ -f $${rootme}/../../expect/expect ] ; then \
          echo $${rootme}/../../expect/expect ; \
          else echo expect ; fi`

RUNTEST = $(RUNTEST_FOR_TARGET)

RUNTESTFLAGS =

RUNTEST_FOR_TARGET = `\
  if [ -f $${srcdir}/../../../dejagnu/runtest ]; then \
    echo $${srcdir}/../../../dejagnu/runtest; \
  else \
    if [ "$(host_canonical)" = "$(target_canonical)" ]; then \
      echo runtest; \
    else \
      t='$(program_transform_name)'; echo runtest | sed -e '' $$t; \
    fi; \
  fi`


AS_FOR_TARGET = `\
  if [ -x ../../../gas/as-new ]; then \
    echo ../../../gas/as-new ; \
  else \
    echo $(target_alias)-as ; \
  fi`

LD_FOR_TARGET = `\
  if [ -x ../../../ld/ld-new ]; then \
    echo ../../../ld/ld-new ; \
  else \
    echo $(target_alias)-ld ; \
  fi`

RUN_FOR_TARGET = `\
  if [ -x ../../../sim/${target_cpu}/run ]; then \
    echo ../../../sim/${target_cpu}/run ; \
  else \
    echo $(target_alias)-run ; \
  fi`

TESTS = \
	em-e0.ok \
	em-e47.ko \
	em-pstr.hi \
	em-pchr.hi \
	\
	ls-ld2h.ko \
	ls-ld2w.ko \
	ls-ld4bh.ko \
	ls-ld4bhu.ko \
	ls-ldb.ko \
	ls-ldbu.ko \
	ls-ldh.ko \
	ls-ldhh.ko \
	ls-ldhu.ko \
	ls-ldw.ko \
	ls-moddec.ko \
	ls-modinc.ko \
	ls-modaddr.ok \
	ls-st2h.hi \
	ls-st2w.hi \
	ls-st4hb.hi \
	ls-stb.hi \
	ls-sth.hi \
	ls-sthh.hi \
	ls-stw.hi \
	\
	br-bra.ok \
	br-bratnz.ok \
	br-bratzr.ok \
	br-bsr.ok \
	br-dbra.ko \
	br-djmp.ko \
	br-djsr.ok \
	\
	os-dbt.ok \
	do-flags.ok \
	do-shifts.ok \
	do-2wordops.ok \
	\
	trap.ok

check: sanity $(TESTS)
sanity:
	@eval echo AS_FOR_TARGET = $(AS_FOR_TARGET)
	@eval echo LD_FOR_TARGET = $(LD_FOR_TARGET)
	@eval echo RUN_FOR_TARGET = $(RUN_FOR_TARGET)



# Rules for running all the tests, put into three types
# exit success, exit fail, print "Hello World"

.u.log:
	uudecode $*.u
	$(RUN_FOR_TARGET) $* > $*.log


# Rules for running the tests

.SUFFIXES: .u .ok .run .hi .ko
.run.ok:
	rm -f tmp-$* $*.hi
	ulimit -t 5 ; $(RUN_FOR_TARGET) $*.run > tmp-$*
	mv tmp-$* $*.ok
.run.hi:
	rm -f tmp-$* $*.hi diff-$*
	ulimit -t 5 ; $(RUN_FOR_TARGET) $*.run > tmp-$*
	echo "Hello World" | diff - tmp-$* > diff-$*
	cat tmp-$* diff-$* > $*.hi
.run.ko:
	rm -f tmp-$* $*.ko
	set +e ; \
	ulimit -t 5 ; $(RUN_FOR_TARGET) $*.run > tmp-$* ; \
	if [ $$? -eq 47 ] ; then \
	  exit 0 ; \
	else \
	  exit 1 ; \
	fi
	mv tmp-$* $*.ko


# Rules for building all the tests and packing them into
# uuencoded files.

uuencode: em-pstr.u em-e0.u em-e47.u em-pchr.u

.SUFFIXES: .u .S .run
.S.u:
	rm -f $*.o $*.run
	$(AS_FOR_TARGET) $(srcdir)/$*.S -o $*.o
	$(LD_FOR_TARGET) -o $* $*.o
	uuencode < $* $* > $*.u
	rm -f $*.o $*
.S.run:
	rm -f $*.o $*.run
	$(AS_FOR_TARGET) $(srcdir)/$*.S -o $*.o
	$(LD_FOR_TARGET) -o $*.run $*.o
	rm -f $*.o $*



#
# Standard
#
clean mostlyclean:
	-rm -f *~ core *.o a.out *.x *.grt
	rm -f $(TESTS)
#	if [ x"${SUBDIRS}" != x ] ; then \
#	    for dir in ${SUBDIRS}; \
#	    do \
#		    echo "$$dir:"; \
#		    if [ -d $$dir ]; then \
#			    (cd $$dir; $(MAKE) clean); \
#		    fi; \
#	    done ; \
#	else true; fi

distclean maintainer-clean realclean: clean
	-rm -f *~ core
	-rm -f Makefile config.status *-init.exp
	-rm -fr *.log summary detail *.plog *.sum *.psum site.*
#	if [ x"${SUBDIRS}" != x ] ; then \
#	    for dir in ${SUBDIRS}; \
#	    do \
#		    echo "$$dir:"; \
#		    if [ -d $$dir ]; then \
#			    (cd $$dir; $(MAKE) distclean); \
#		    fi; \
#	    done ; \
#	else true; fi

Makefile : Makefile.in config.status
	$(SHELL) config.status

config.status: configure
	$(SHELL) config.status --recheck
