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

# This file is part of GDB.

# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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, see <http://www.gnu.org/licenses/>.

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/mips/run ]; then \
    echo ../../../sim/mips/run ; \
  else \
    echo $(target_alias)-run ; \
  fi`

TESTS = 

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 .uue .ok .ok .run .hi .ko .ko
.run.ok:
	rm -f tmp-$* $*.ok
	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.

.run.u:
	uuencode < $*.run $*.run > $*.u
	@echo "Move $*.u $*.uue"
.uue.run:
	uudecode $(srcdir)/$*.uue
.o.run:
	$(LD_FOR_TARGET) -Ttext 0xa0020000 -o $*.run $*.o
.s.o:
	$(AS_FOR_TARGET) -I $(srcdir) $(srcdir)/$*.s -o $*.o


#
# Standard
#
clean mostlyclean:
	-rm -f *~ core *.o a.out *.x *.grt *.run tmp-* diff-*
	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
