qse/qse/lib/cmn/assert.c

182 lines
4.6 KiB
C
Raw Normal View History

2009-06-04 15:50:32 +00:00
/*
* $Id: assert.c 223 2008-06-26 06:44:41Z baconevi $
*
2011-04-23 08:28:43 +00:00
Copyright 2006-2011 Chung, Hyung-Hwan.
2009-09-16 04:01:02 +00:00
This file is part of QSE.
2009-06-04 15:50:32 +00:00
2009-09-16 04:01:02 +00:00
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
2009-06-04 15:50:32 +00:00
2009-09-16 04:01:02 +00:00
QSE 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 Lesser General Public License for more details.
2009-06-04 15:50:32 +00:00
2009-09-16 04:01:02 +00:00
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
2009-06-04 15:50:32 +00:00
*/
#include <qse/types.h>
#include <qse/macros.h>
#ifndef NDEBUG
#include <qse/cmn/sio.h>
#include "mem.h"
2009-06-05 07:36:02 +00:00
#ifdef HAVE_EXECINFO_H
# include <execinfo.h>
# include <stdlib.h>
# include <qse/cmn/str.h>
#endif
2011-03-15 09:40:35 +00:00
#if defined(_WIN32)
2011-03-17 02:37:06 +00:00
# include <windows.h>
#elif defined(__OS2__)
# define INCL_DOSPROCESS
2011-03-15 09:40:35 +00:00
# include <os2.h>
2011-05-04 08:00:38 +00:00
#elif defined(__DOS__)
# include <dos.h>
# include <dosfunc.h>
2012-04-27 14:33:14 +00:00
#elif defined(vms) || defined(__vms)
# include <starlet.h> /* (SYS$...) */
# include <ssdef.h> /* (SS$...) */
2009-06-05 07:36:02 +00:00
#else
# include "syscall.h"
#endif
#define NTOC(n) (QSE_MT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")[n])
#define WRITE_CHAR(sio,c) \
2009-06-05 07:36:02 +00:00
do { \
qse_mchar_t __xxx_c = c; \
if (qse_sio_putmbsn (sio, &__xxx_c, 1) != 1) return -1; \
2009-06-05 07:36:02 +00:00
} while (0)
static int write_num (qse_sio_t* sio, qse_size_t x, int base)
2009-06-05 07:36:02 +00:00
{
qse_size_t last = x % base;
qse_size_t y = 0;
int dig = 0;
x = x / base;
while (x > 0)
{
y = y * base + (x % base);
x = x / base;
dig++;
}
while (y > 0)
{
WRITE_CHAR (sio, NTOC(y % base));
2009-06-05 07:36:02 +00:00
y = y / base;
dig--;
}
while (dig > 0)
{
dig--;
WRITE_CHAR (sio, QSE_T('0'));
2009-06-05 07:36:02 +00:00
}
WRITE_CHAR (sio, NTOC(last));
2009-06-05 07:36:02 +00:00
return 0;
}
2009-06-04 15:50:32 +00:00
void qse_assert_failed (
const qse_char_t* expr, const qse_char_t* desc,
const qse_char_t* file, qse_size_t line)
{
#ifdef HAVE_BACKTRACE
void *btarray[128];
qse_size_t btsize, i;
char **btsyms;
#endif
qse_sio_t* sio, siobuf;
sio = &siobuf;
qse_sio_initstd (
sio, QSE_MMGR_GETDFL(), QSE_SIO_STDERR,
QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR | QSE_SIO_NOAUTOFLUSH);
qse_sio_putmbs (sio, QSE_MT("=[ASSERTION FAILURE]============================================================\n"));
2009-06-04 15:50:32 +00:00
2011-02-22 03:11:21 +00:00
#if 1
qse_sio_putmbs (sio, QSE_MT(" __ \n"));
qse_sio_putmbs (sio, QSE_MT(" _____ _____ _____ _____| |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | _ | __| |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | | | __|__ |__|\n"));
qse_sio_putmbs (sio, QSE_MT("|_____|_____|__| |_____|__|\n"));
qse_sio_putmbs (sio, QSE_MT(" \n"));
2011-02-22 03:11:21 +00:00
#else
qse_sio_putmbs (sio, QSE_MT(" __ \n"));
qse_sio_putmbs (sio, QSE_MT(" _____ _____ _____ _____ | |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | _ | __| | |\n"));
qse_sio_putmbs (sio, QSE_MT("| | | | | __|__ | |__|\n"));
qse_sio_putmbs (sio, QSE_MT("|_____|_____|__| |_____| |__|\n"));
qse_sio_putmbs (sio, QSE_MT(" __ \n"));
2011-02-22 03:11:21 +00:00
#endif
qse_sio_putmbs (sio, QSE_MT("FILE: "));
qse_sio_putstr (sio, file);
qse_sio_putmbs (sio, QSE_MT(" LINE: "));
2009-06-04 15:50:32 +00:00
write_num (sio, line, 10);
2009-06-04 15:50:32 +00:00
qse_sio_putmbs (sio, QSE_MT("\nEXPRESSION: "));
qse_sio_putstr (sio, expr);
qse_sio_putmbs (sio, QSE_MT("\n"));
2009-06-04 15:50:32 +00:00
if (desc != QSE_NULL)
{
qse_sio_putmbs (sio, QSE_MT("DESCRIPTION: "));
qse_sio_putstr (sio, desc);
qse_sio_putmbs (sio, QSE_MT("\n"));
2009-06-04 15:50:32 +00:00
}
#ifdef HAVE_BACKTRACE
btsize = backtrace (btarray, QSE_COUNTOF(btarray));
btsyms = backtrace_symbols (btarray, btsize);
if (btsyms != QSE_NULL)
{
qse_sio_putmbs (sio, QSE_MT("=[BACKTRACES]===================================================================\n"));
for (i = 0; i < btsize; i++)
{
qse_sio_putmbs (sio, btsyms[i]);
qse_sio_putmbs (sio, QSE_MT("\n"));
}
free (btsyms);
}
#endif
qse_sio_putmbs (sio, QSE_MT("================================================================================\n"));
qse_sio_flush (sio);
qse_sio_fini (sio);
2009-06-04 15:50:32 +00:00
2011-03-15 09:40:35 +00:00
#if defined(_WIN32)
2011-05-04 08:00:38 +00:00
ExitProcess (249);
2011-03-17 02:37:06 +00:00
#elif defined(__OS2__)
2011-05-04 08:00:38 +00:00
DosExit (EXIT_PROCESS, 249);
#elif defined(__DOS__)
{
union REGS regs;
regs.h.ah = DOS_EXIT;
regs.h.al = 249;
intdos (&regs, &regs);
}
2012-04-27 14:33:14 +00:00
#elif defined(vms) || defined(__vms)
sys$exit (SS$_ABORT); /* this condition code can be shown with
* 'show symbol $status' from the command-line. */
2009-06-05 07:36:02 +00:00
#else
QSE_KILL (QSE_GETPID(), SIGABRT);
QSE_EXIT (1);
#endif
2009-06-04 15:50:32 +00:00
}
#endif