#include <sm/gen.h>
SM_RCSID("@(#)$Id: assert.c,v 1.25.2.1 2003/12/05 22:44:17 ca Exp $")
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sm/assert.h>
#include <sm/exc.h>
#include <sm/io.h>
#include <sm/varargs.h>
SM_DEBUG_T SmExpensiveAssert = SM_DEBUG_INITIALIZER("sm_check_assert",
"@(#)$Debug: sm_check_assert - check assertions $");
SM_DEBUG_T SmExpensiveRequire = SM_DEBUG_INITIALIZER("sm_check_require",
"@(#)$Debug: sm_check_require - check function preconditions $");
SM_DEBUG_T SmExpensiveEnsure = SM_DEBUG_INITIALIZER("sm_check_ensure",
"@(#)$Debug: sm_check_ensure - check function postconditions $");
SM_DEBUG_T SmAbortStop = SM_DEBUG_INITIALIZER("sm_abort_stop",
"@(#)$Debug: sm_abort_stop - stop process on fatal error $");
static void
sm_abort_defaulthandler __P((
const char *filename,
int lineno,
const char *msg));
static void
sm_abort_defaulthandler(filename, lineno, msg)
const char *filename;
int lineno;
const char *msg;
{
if (filename != NULL)
sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s:%d: %s\n", filename,
lineno, msg);
else
sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n", msg);
sm_io_flush(smioerr, SM_TIME_DEFAULT);
#ifdef SIGSTOP
if (sm_debug_active(&SmAbortStop, 1))
kill(getpid(), SIGSTOP);
#endif
abort();
}
static SM_ABORT_HANDLER_T SmAbortHandler = sm_abort_defaulthandler;
void
sm_abort_sethandler(f)
SM_ABORT_HANDLER_T f;
{
if (f == NULL)
SmAbortHandler = sm_abort_defaulthandler;
else
SmAbortHandler = f;
}
void SM_DEAD_D
#if SM_VA_STD
sm_abort(char *fmt, ...)
#else
sm_abort(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
char msg[128];
SM_VA_LOCAL_DECL
SM_VA_START(ap, fmt);
sm_vsnprintf(msg, sizeof msg, fmt, ap);
SM_VA_END(ap);
sm_abort_at(NULL, 0, msg);
}
void SM_DEAD_D
sm_abort_at(filename, lineno, msg)
const char *filename;
int lineno;
const char *msg;
{
SM_TRY
(*SmAbortHandler)(filename, lineno, msg);
SM_EXCEPT(exc, "*")
sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
"exception raised by abort handler:\n");
sm_exc_print(exc, smioerr);
sm_io_flush(smioerr, SM_TIME_DEFAULT);
SM_END_TRY
abort();
}