Files
mercury/library/require.m
Fergus Henderson 14a25f4af5 Fix a bug caused by zs's recent change to runtime/mercury_stack_trace.{h,c}:
Estimated hours taken: 0.25

Fix a bug caused by zs's recent change to runtime/mercury_stack_trace.{h,c}:

library/require.m:
library/math.m:
	Update calls to MR_dump_stack() to pass as the new
	`include_trace_data' argument the value `FALSE'.
1998-11-13 14:06:56 +00:00

110 lines
2.9 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1993-1998 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%-----------------------------------------------------------------------------%
:- module require.
% Main author: fjh.
% Stability: medium to high.
% This module provides features similar to <assert.h> in C.
%-----------------------------------------------------------------------------%
:- interface.
:- pred error(string).
:- mode error(in) is erroneous.
% error(Message).
% Abort with error message.
:- pred require(pred, string).
:- mode require((pred) is semidet, in) is det.
% require(Goal, Message).
% Call goal, and abort with error message if Goal fails.
% This is not as useful as you might imagine, since it requires
% that the goal not produce any output variables. In
% most circumstances you should use an explicit if-then-else
% with a call to error/1 in the "else".
%-----------------------------------------------------------------------------%
:- implementation.
require(Goal, Message) :-
( call(Goal) ->
true
;
error(Message),
fail
).
%-----------------------------------------------------------------------------%
/* error/1, from require.m */
:- pragma c_header_code("
#include <stdio.h>
#include ""mercury_trace_base.h""
#include ""mercury_stack_trace.h""
").
% Hopefully error/1 won't be called often (!), so no point inlining it.
:- pragma no_inline(error/1).
error(Message) :-
error_internal(Message).
:- pred error_internal(string::in) is erroneous.
% We define error using handwritten code in error_internal because we
% need complete control over it if we want to call MR_dump_stack. In
% particular we don't want to have to explicitly tell MR_dump_stack whether
% a stack frame was generated by its caller. The easiest way to do
% this is to make sure it wasn't.
:- external(error_internal/1).
:- pragma c_code("
Define_extern_entry(mercury__require__error_internal_1_0);
BEGIN_MODULE(require_internal_module)
init_entry(mercury__require__error_internal_1_0);
BEGIN_CODE
/* code for predicate 'error_internal'/1 in mode 0 */
Define_entry(mercury__require__error_internal_1_0);
{
String Message;
Message = (String) r1;
fflush(stdout);
fprintf(stderr, ""Software error: %s\\n"", Message);
MR_trace_report(stderr);
MR_dump_stack(MR_succip, MR_sp, MR_curfr, FALSE);
exit(1);
}
END_MODULE
/*
** Ensure that the initialization function for the above module gets run.
*/
/*
INIT sys_init_require_internal_module
*/
extern ModuleFunc require_internal_module;
void sys_init_require_internal_module(void);
void sys_init_require_internal_module(void) {
require_internal_module();
}
").
:- end_module require.
%-----------------------------------------------------------------------------%