From cb289b215faa89e61b57ac00244e455992b85f06 Mon Sep 17 00:00:00 2001 From: Kester Maddock Date: Sun, 16 Jan 2005 04:28:55 +0000 Subject: Advanced MT_assert macro. It will attempt to break into the debugger instead of aborting the program. On Windows you have a nice MessageBox function, so you can choose to break, ignore, or permanently ignore the assert. --- intern/moto/include/MT_assert.h | 48 +++++++++++++++++++++++++++-- intern/moto/intern/MT_Assert.cpp | 65 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 intern/moto/intern/MT_Assert.cpp (limited to 'intern/moto') diff --git a/intern/moto/include/MT_assert.h b/intern/moto/include/MT_assert.h index b9680c1e684..dce57b91272 100644 --- a/intern/moto/include/MT_assert.h +++ b/intern/moto/include/MT_assert.h @@ -38,9 +38,53 @@ #else -#include +#include +#include -#define MT_assert(predicate) assert(predicate) +// BREAKPOINT() will cause a break into the debugger +#if defined(__i386) && defined(__GNUC__) +// gcc on intel... +#define BREAKPOINT() \ + asm("int $3") +#elif defined(_MSC_VER) +// Visual C++ (on Intel) +#define BREAKPOINT() \ + { _asm int 3 } +#elif defined(SIGTRAP) +// POSIX compatible... +#define BREAKPOINT() \ + raise(SIGTRAP); +#else +// FIXME: Don't know how to do a decent break! +// Add some code for your cpu type, or get a posix +// system. +// abort instead +#define BREAKPOINT() \ + abort(); +#endif + +// So it can be used from C +#ifdef __cplusplus +#define MT_CDECL extern "C" +#else +#define MT_CDECL +#endif + +// Ask the user if they wish to abort/break, ignore, or ignore for good. +// file, line, predicate form the message to ask, *do_assert should be set +// to 0 to ignore. +// returns 1 to break, false to ignore +MT_CDECL int MT_QueryAssert(char *file, int line, char *predicate, int *do_assert); + +// Abort the program if predicate is not true +#define MT_assert(predicate) \ +{ \ + static int do_assert = 1; \ + if (!(predicate) && MT_QueryAssert(__FILE__, __LINE__, #predicate, &do_assert)) \ + { \ + BREAKPOINT(); \ + } \ +} #endif /* MT_NDEBUG */ diff --git a/intern/moto/intern/MT_Assert.cpp b/intern/moto/intern/MT_Assert.cpp new file mode 100644 index 00000000000..47ff372084b --- /dev/null +++ b/intern/moto/intern/MT_Assert.cpp @@ -0,0 +1,65 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * 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 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include + +#ifdef _WIN32 +#include +#endif + +#include "MT_assert.h" + +#ifdef _MSC_VER +#define _snprintf snprintf +#endif + +// Query the user if they want to break/abort the program, ignore the assert, or ignore all future +// occurance of the assert. +int MT_QueryAssert(char *file, int line, char *predicate, int *do_assert) +{ +#ifdef _WIN32 + if (*do_assert) + { + char buffer[1024]; + snprintf(buffer, 1024, "ASSERT %s:%d: %s failed.\nWould you like to debug? (Cancel = ignore)", file, line, predicate); + int result = MessageBox(NULL, buffer, "ASSERT failed.", MB_YESNOCANCEL|MB_ICONERROR); + if (result == IDCANCEL) + { + *do_assert = 0; + return 0; + } + + return result == IDYES; + } +#endif + printf("ASSERT %s:%d: %s failed.\n", file, line, predicate); + return *do_assert; +} -- cgit v1.2.3