#-----------------------------------------------------------------------------#
# vim: ts=8 sw=8 noexpandtab ft=make
#-----------------------------------------------------------------------------#

TESTS_DIR = ..
THIS_DIR = declarative_debugger
MAYBE_J1 = -j1
# Most test cases share library_forwarding.m. We could allow the tests
# to be done in parallel if we made a separate copy of that module
# for each test case that needs it.

#-----------------------------------------------------------------------------#

DECLARATIVE_PROGS =		\
	aadebug			\
	all_trusted		\
	app			\
	args			\
	backtrack		\
	big			\
	binary_search		\
	browser_mode		\
	browse_arg		\
	catch			\
	closure_dependency	\
	comp_gen		\
	confirm_abort		\
	change_search		\
	dd_params		\
	deep_warning		\
	dependency		\
	dependency2		\
	dice			\
	divide_and_query1	\
	empty_command		\
	exceptions		\
	explicit_subtree	\
	failed_cond		\
	family			\
	filter			\
	find_origin		\
	func_call		\
	gcf			\
	higher_order		\
	ho_2			\
	ho_3			\
	ho_4			\
	ho_5			\
	ignore			\
	if_then_else		\
	inadmissible		\
	info			\
	input_term_dep		\
	io_stream_test		\
	io_tab_impure		\
	ite_2			\
	lpe_example		\
	mapinit			\
	mismatch_on_call	\
	named_fields		\
	negation		\
	neg_conj		\
	nodescend_tracking	\
	oracle_db		\
	output_term_dep		\
	partial			\
	pd			\
	propositional		\
	queens			\
	remember_modes		\
	resume			\
	revise_1		\
	revise_2		\
	small			\
	special_term_dep	\
	skip			\
	solns			\
	supertree_warning	\
	tabled_read_decl	\
	tabled_read_decl_goto	\
	throw			\
	trust			\
	undo			\
	unsafe_cast

# The following should not be run in `debug' or `mm' grades.
#
NONDEBUG_DECLARATIVE_PROGS=	\
	untraced_subgoal

# The following should only be run when the library is compiled in
# decldebug grade.
#
DECLDEBUG_DECLARATIVE_PROGS=	\
	builtin_call_rep	\
	catch_retry		\
	condition_bug		\
	priv_builtin_bug	\
	sort			\
	track_through_catch	\
	typed_unify

# The following should not be run in decldebug grades.
#
NONDECLDEBUG_DECLARATIVE_PROGS=	\
	shallow

NONWORKING_DECLARATIVE_PROGS=	\
	io_read_bug

# Some of the test cases require a different input in debug or decldebug
# grades, so we set DEBUG_INP and DECLDEBUG_INP to the appropriate extension to
# use for those tests. All other tests ignore these variables.
# Test cases that require different input for each of the non-debug, debug and
# decldebug grades should use the DECLDEBUG_INP variable and should have their
# input extensions as .inp, .inp2 and .inp3 for the non-debug, debug and
# decldebug grades respectively.
# Test cases that require different input for the debug and non-debug grades,
# but can use the same input for the debug and decldebug grades should use the
# DEBUG_INP variable and use the extensions .inp and .inp2 for their non-debug
# and debug/decldebug input files respectively.
#
ifneq "$(findstring .debug,$(GRADE))" ""
    PROGS_2 = $(DECLARATIVE_PROGS) $(NONDECLDEBUG_DECLARATIVE_PROGS)
    DEBUG_INP = inp2
    DECLDEBUG_INP = inp2
else
    ifneq "$(findstring .decldebug,$(GRADE))" ""
        PROGS_2 = $(DECLARATIVE_PROGS) $(DECLDEBUG_DECLARATIVE_PROGS)
        DEBUG_INP = inp2
        DECLDEBUG_INP = inp3
    else
        ifneq "$(findstring mm,$(GRADE))" ""
            PROGS_2 = $(DECLARATIVE_PROGS) $(NONDECLDEBUG_DECLARATIVE_PROGS)
            DEBUG_INP = inp
            DECLDEBUG_INP = inp
        else
            PROGS_2 = $(DECLARATIVE_PROGS) $(NONDEBUG_DECLARATIVE_PROGS) \
	    	$(NONDECLDEBUG_DECLARATIVE_PROGS)
            DEBUG_INP = inp
            DECLDEBUG_INP = inp
        endif
    endif
endif

# Debugging does not work in MLDS (hl*, csharp*, java*) grades,
# parallel grades, or deep profiling (profdeep) grades.
# Base grades `jump' and `fast' cannot be used with
# stack layouts (which are required for tracing).
# Also, declarative debugging only works in `.gc' grades.

ifeq "$(filter hl% csharp% java%,$(GRADE))$(findstring par,$(GRADE))$(findstring profdeep,$(GRADE))" ""
    ifneq "$(findstring .gc,$(GRADE))" ""
       ifneq "$(findstring asm_,$(GRADE))" ""
           PROGS = $(PROGS_2)
       else
           ifneq "$(findstring jump,$(GRADE))" ""
               PROGS =
           else
               ifneq "$(findstring fast,$(GRADE))" ""
                   PROGS =
               else
                   PROGS = $(PROGS_2)
               endif
           endif
       endif
    else
        PROGS =
    endif
else
    PROGS =
endif

TESTS = $(sort $(PROGS))
include ../Mmake.common

MCFLAGS += --trace decl
MLFLAGS += --trace

# Module-specific options should go in Mercury.options so they
# can be found by `mmc --make'.
include Mercury.options

%.runtest: %.res ;

#-----------------------------------------------------------------------------#
#
# Note that the "|| { grep . $@ /dev/null; exit 1; }" at the ends of actions
# prints the contents of the (presumably incomplete) .out file
# if the process of building the .out file fails.
# (The grep is executed only if the command before the || fails,
# $@ expands to the target (left hand side) of the rule, i.e. the .out file,
# "grep ." matches every line, and the '/dev/null' tells grep to print
# the file name before each line.)
#

aadebug.out: aadebug aadebug.inp
	$(MDB_STD) ./aadebug < aadebug.inp > aadebug.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

all_trusted.out: all_trusted all_trusted.inp
	$(MDB_STD) ./all_trusted < all_trusted.inp > all_trusted.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

app.out: app app.inp
	$(MDB_STD) ./app < app.inp > app.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

args.out: args args.inp
	$(MDB_STD) ./args < args.inp > args.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

backtrack.out: backtrack backtrack.inp
	$(MDB) ./backtrack < backtrack.inp > backtrack.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

big.out: big big.inp
	$(MDB_STD) ./big < big.inp > big.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

binary_search.out: binary_search binary_search.$(DEBUG_INP)
	$(MDB_STD) ./binary_search < binary_search.$(DEBUG_INP) \
		> binary_search.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

browse_arg.out: browse_arg browse_arg.inp
	$(MDB) ./browse_arg < browse_arg.inp > browse_arg.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

browser_mode.out: browser_mode browser_mode.inp
	$(MDB_STD) ./browser_mode < browser_mode.inp > browser_mode.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

builtin_call_rep.out: builtin_call_rep builtin_call_rep.inp
	$(MDB_STD) ./builtin_call_rep  < builtin_call_rep.inp \
		| sed 's/\"int\.m\", [0-9]\+/\"int\.m\", NN/' \
		> builtin_call_rep.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
catch.out: catch catch.inp
	$(MDB_STD) ./catch < catch.inp 2>&1 | \
		sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
		> catch.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

catch_retry.out: catch_retry catch_retry.inp
	$(MDB_STD) ./catch_retry < catch_retry.inp 2>&1 | \
		sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
		> catch_retry.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

closure_dependency.out: closure_dependency closure_dependency.$(DEBUG_INP)
	$(MDB_STD) ./closure_dependency  < closure_dependency.$(DEBUG_INP) \
		> closure_dependency.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

comp_gen.out: comp_gen comp_gen.inp
	$(MDB) ./comp_gen < comp_gen.inp > comp_gen.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular memory addresses and line numbers in the standard library source
# code.
condition_bug.out: condition_bug condition_bug.inp
	$(MDB_STD) ./condition_bug < condition_bug.inp 2>&1 | \
		sed -e 's/io.m:[0-9]*/io.m:NNNN/g' | \
		sed -e 's/stream.m:[0-9]*/stream.m:NNNN/g' | \
		sed -e 's/term_to_xml.m:[0-9]*/term_to_xml.m:NNNN/g' | \
		sed 's/0x[-0-9A-Fa-f]*/0xXXXX/g' | \
		sed 's/(nil)/0xXXXX/g' | \
		sed 's/stream, [0-9a-fA-F]\{2\}[0-9a-fA-F]*/stream, 0xXXXX/g' | \
		sed 's/system_error, 0\{2\}[0-9]*/system_error, 0xXXXX/g' | \
		sed 's/state, 0\{2\}[0-9]*/state, 0xXXXX/g' \
		> condition_bug.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

confirm_abort.out: confirm_abort confirm_abort.inp
	$(MDB) ./confirm_abort < confirm_abort.inp > confirm_abort.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

change_search.out: change_search change_search.inp
	$(MDB_STD) ./change_search < change_search.inp \
		> change_search.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

dd_params.out: dd_params dd_params.inp
	$(MDB) ./dd_params < dd_params.inp > dd_params.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

deep_warning.out: deep_warning deep_warning.inp
	$(MDB) ./deep_warning < deep_warning.inp > deep_warning.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

dependency.out: dependency dependency.inp
	$(MDB) ./dependency < dependency.inp > dependency.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

dependency2.out: dependency2 dependency2.inp
	$(MDB) ./dependency2 < dependency2.inp > dependency2.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

dice.pass: dice
	/bin/rm -f .mercury_trace_counts.*dice.*
	MERCURY_OPTIONS="--trace-count --tc-output-file dice.pass --deep-std-name" \
		./dice 1 2 3 4

dice.fail: dice
	/bin/rm -f .mercury_trace_counts.*dice.*
	MERCURY_OPTIONS="--trace-count --tc-output-file dice.fail --deep-std-name" \
		./dice 4 1 2 3

dice.out: dice dice.inp dice.pass dice.fail
	$(MDB_STD) ./dice 4 1 2 3 < dice.inp > dice.out 2>&1

divide_and_query1.out: divide_and_query1 divide_and_query1.inp
	$(MDB_STD) ./divide_and_query1 < divide_and_query1.inp \
		> divide_and_query1.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

empty_command.out: empty_command empty_command.inp
	$(MDB) ./empty_command < empty_command.inp > empty_command.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

exceptions.out: exceptions exceptions.inp
	$(MDB_STD) ./exceptions < exceptions.inp \
		> exceptions.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

explicit_subtree.out: explicit_subtree explicit_subtree.$(DEBUG_INP)
	$(MDB_STD) ./explicit_subtree < explicit_subtree.$(DEBUG_INP) \
		> explicit_subtree.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

family.out: family family.inp
	$(MDB) ./family < family.inp > family.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

failed_cond.out: failed_cond failed_cond.inp
	$(MDB_STD) ./failed_cond < failed_cond.inp > failed_cond.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

filter.out: filter filter.inp
	$(MDB_STD) ./filter < filter.inp > filter.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

find_origin.out: find_origin find_origin.$(DECLDEBUG_INP)
	$(MDB_STD) ./find_origin < find_origin.$(DECLDEBUG_INP) \
		> find_origin.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

func_call.out: func_call func_call.inp
	$(MDB) ./func_call < func_call.inp > func_call.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

gcf.out: gcf gcf.inp
	$(MDB) ./gcf < gcf.inp > gcf.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

higher_order.out: higher_order higher_order.inp
	$(MDB) ./higher_order < higher_order.inp > higher_order.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

ho_2.out: ho_2 ho_2.inp
	$(MDB) ./ho_2 < ho_2.inp > ho_2.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

ho_3.out: ho_3 ho_3.inp
	$(MDB) ./ho_3 < ho_3.inp > ho_3.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

ho_4.out: ho_4 ho_4.inp
	$(MDB) ./ho_4 < ho_4.inp > ho_4.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
ho_5.out: ho_5 ho_5.inp
	$(MDB_STD) ./ho_5 < ho_5.inp 2>&1 | \
		sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
		> ho_5.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

if_then_else.out: if_then_else if_then_else.inp
	$(MDB_STD) ./if_then_else < if_then_else.inp > if_then_else.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

ignore.out: ignore ignore.$(DEBUG_INP)
	$(MDB_STD) ./ignore < ignore.$(DEBUG_INP) \
		> ignore.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

inadmissible.out: inadmissible inadmissible.inp
	$(MDB_STD) ./inadmissible < inadmissible.inp \
		> inadmissible.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

info.out: info info.inp
	$(MDB_STD) ./info < info.inp > info.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

input_term_dep.out: input_term_dep input_term_dep.inp
	$(MDB_STD) ./input_term_dep < input_term_dep.inp \
		> input_term_dep.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

io_read_bug.out: io_read_bug io_read_bug.inp
	$(MDB_STD) ./io_read_bug < io_read_bug.inp > io_read_bug.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

io_stream_test.out: io_stream_test io_stream_test.inp
	$(MDB_STD) ./io_stream_test < io_stream_test.inp | \
		sed 's/0x[-0-9A-Fa-f]*/0xXXXX/g' | \
		sed 's/(nil)/0xXXXX/g' | \
		sed 's/stream, [0-9a-fA-F]\{2\}[0-9a-fA-F]*/stream, 0xXXXX/g' | \
		sed 's/system_error, 0\{2\}0*/system_error, 0xXXXX/g' \
		> io_stream_test.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

io_tab_impure.out: io_tab_impure io_tab_impure.inp
	$(MDB_STD) ./io_tab_impure < io_tab_impure.inp \
		> io_tab_impure.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

ite_2.out: ite_2 ite_2.inp
	$(MDB) ./ite_2 < ite_2.inp > ite_2.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

lpe_example.out: lpe_example lpe_example.inp
	$(MDB) ./lpe_example < lpe_example.inp > lpe_example.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

mapinit.out: mapinit mapinit.inp
	$(MDB_STD) ./mapinit < mapinit.inp > mapinit.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

mismatch_on_call.out: mismatch_on_call mismatch_on_call.$(DEBUG_INP)
	$(MDB_STD) ./mismatch_on_call < mismatch_on_call.$(DEBUG_INP) \
		> mismatch_on_call.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

neg_conj.out: neg_conj neg_conj.inp
	$(MDB) ./neg_conj < neg_conj.inp > neg_conj.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

nodescend_tracking.out: nodescend_tracking nodescend_tracking.inp
	$(MDB_STD) ./nodescend_tracking < nodescend_tracking.inp \
		> nodescend_tracking.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

named_fields.out: named_fields named_fields.inp
	$(MDB_STD) ./named_fields < named_fields.inp \
		> named_fields.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

negation.out: negation negation.inp
	$(MDB) ./negation < negation.inp > negation.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

oracle_db.out: oracle_db oracle_db.inp
	$(MDB) ./oracle_db < oracle_db.inp > oracle_db.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

output_term_dep.out: output_term_dep output_term_dep.inp
	$(MDB_STD) ./output_term_dep < output_term_dep.inp	\
			> output_term_dep.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

partial.out: partial partial.inp
	$(MDB_STD) ./partial < partial.inp > partial.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

pd.out: pd pd.inp
	$(MDB) ./pd < pd.inp > pd.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

priv_builtin_bug.out: priv_builtin_bug priv_builtin_bug.inp
	$(MDB_STD) ./priv_builtin_bug < priv_builtin_bug.inp > \
		priv_builtin_bug.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
track_through_catch.out: track_through_catch track_through_catch.inp
	$(MDB_STD) ./track_through_catch < track_through_catch.inp 2>&1 | \
		sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
		> track_through_catch.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

typed_unify.out: typed_unify typed_unify.inp
	$(MDB_STD) ./typed_unify < typed_unify.inp 2>&1 | \
		sed -e 's/univ.m:[0-9]*/univ.m:NNNN/g' \
		> typed_unify.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

propositional.out: propositional propositional.inp
	$(MDB_STD) ./propositional < propositional.inp > \
		propositional.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

queens.out: queens queens.inp
	$(MDB) ./queens < queens.inp > queens.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

remember_modes.out: remember_modes remember_modes.inp
	$(MDB_STD) ./remember_modes < remember_modes.inp \
			> remember_modes.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

resume.out: resume resume.inp
	$(MDB_STD) ./resume < resume.inp > resume.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

revise_1.out: revise_1 revise_1.inp
	$(MDB) ./revise_1 < revise_1.inp > revise_1.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

revise_2.out: revise_2 revise_2.inp
	$(MDB) ./revise_2 < revise_2.inp > revise_2.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

shallow.out: shallow shallow.inp
	$(MDB) ./shallow < shallow.inp > shallow.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

small.out: small small.inp
	$(MDB) ./small < small.inp > small.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
solns.out: solns solns.$(DECLDEBUG_INP)
	$(MDB) ./solns < solns.$(DECLDEBUG_INP) 2>&1 | \
		sed -e 's/solutions.m:[0-9]*/solutions.m:NNNN/g' \
		> solns.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

sort.out: sort sort.inp
	$(MDB_STD) ./sort sort.input < sort.inp 2>&1 | \
		sed -e 's/0x[0-9a-f]*/0xNNNN/g' | \
		sed 's/(nil)/0xNNNN/g' | \
		sed 's/stream, [0-9a-fA-F]\{2\}[0-9a-fA-F]*/stream, 0xNNNN/g' | \
		sed 's/system_error, 0\{2\}0*/system_error, 0xNNNN/g' \
		> sort.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

special_term_dep.out: special_term_dep special_term_dep.inp
	$(MDB_STD) ./special_term_dep < special_term_dep.inp \
		> special_term_dep.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

skip.out: skip skip.inp
	$(MDB_STD) ./skip < skip.inp > skip.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

supertree_warning.out: supertree_warning supertree_warning.inp
	$(MDB_STD) ./supertree_warning < supertree_warning.inp > supertree_warning.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

tabled_read_decl.out: tabled_read_decl tabled_read_decl.inp
	$(MDB_STD) ./tabled_read_decl < tabled_read_decl.inp 2>&1 | \
		sed 's/c_pointer(0x[-0-9A-Fa-f]*)/c_pointer(0xXXXX)/g' \
		> tabled_read_decl.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

tabled_read_decl_goto.out: tabled_read_decl_goto tabled_read_decl_goto.inp
	$(MDB_STD) ./tabled_read_decl_goto < tabled_read_decl_goto.inp 2>&1 | \
		sed 's/c_pointer(0x[-0-9A-Fa-f]*)/c_pointer(0xXXXX)/g' \
		> tabled_read_decl_goto.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

# We need to pipe the output through sed to avoid hard-coding dependencies on
# particular line numbers in the standard library source code.
throw.out: throw throw.inp
	$(MDB_STD) ./throw < throw.inp 2>&1 | \
		sed -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
		> throw.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

trust.out: trust trust.inp
	$(MDB_STD) ./trust < trust.inp > trust.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

undo.out: undo undo.inp
	$(MDB_STD) ./undo < undo.inp > undo.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

unsafe_cast.out: unsafe_cast unsafe_cast.inp
	$(MDB) ./unsafe_cast < unsafe_cast.inp > unsafe_cast.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

untraced_subgoal.out: untraced_subgoal untraced_subgoal.inp
	$(MDB) ./untraced_subgoal < untraced_subgoal.inp \
			> untraced_subgoal.out 2>&1 \
	|| { grep . $@ /dev/null; exit 1; }

#-----------------------------------------------------------------------------#
