include/SDL_assert.h
changeset 3647 c5925cd41955
child 3649 1e74d7984d0b
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/include/SDL_assert.h	Wed Jan 13 06:47:17 2010 +0000
     1.3 @@ -0,0 +1,151 @@
     1.4 +/*
     1.5 +    SDL - Simple DirectMedia Layer
     1.6 +    Copyright (C) 1997-2009 Sam Lantinga
     1.7 +
     1.8 +    This library is free software; you can redistribute it and/or
     1.9 +    modify it under the terms of the GNU Lesser General Public
    1.10 +    License as published by the Free Software Foundation; either
    1.11 +    version 2.1 of the License, or (at your option) any later version.
    1.12 +
    1.13 +    This library is distributed in the hope that it will be useful,
    1.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +    Lesser General Public License for more details.
    1.17 +
    1.18 +    You should have received a copy of the GNU Lesser General Public
    1.19 +    License along with this library; if not, write to the Free Software
    1.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1.21 +
    1.22 +    Sam Lantinga
    1.23 +    slouken@libsdl.org
    1.24 +*/
    1.25 +#include "SDL_config.h"
    1.26 +
    1.27 +/* This is an assert macro for SDL's internal use. Not for the public API! */
    1.28 +
    1.29 +#ifndef _SDL_assert_h
    1.30 +#define _SDL_assert_h
    1.31 +
    1.32 +#ifndef SDL_ASSERT_LEVEL
    1.33 +#error SDL_ASSERT_LEVEL is not defined. Please fix your SDL_config.h.
    1.34 +#endif
    1.35 +
    1.36 +/*
    1.37 +sizeof (x) makes the compiler still parse the expression even without
    1.38 +assertions enabled, so the code is always checked at compile time, but
    1.39 +doesn't actually generate code for it, so there are no side effects or
    1.40 +expensive checks at run time, just the constant size of what x WOULD be,
    1.41 +which presumably gets optimized out as unused.
    1.42 +This also solves the problem of...
    1.43 +
    1.44 +    int somevalue = blah();
    1.45 +    SDL_assert(somevalue == 1);
    1.46 +
    1.47 +...which would cause compiles to complain that somevalue is unused if we
    1.48 +disable assertions.
    1.49 +*/
    1.50 +
    1.51 +#define SDL_disabled_assert(condition) \
    1.52 +    do { (void) sizeof ((condition)); } while (0)
    1.53 +
    1.54 +#if (SDL_ASSERT_LEVEL > 0)
    1.55 +
    1.56 +/*
    1.57 +These are macros and not first class functions so that the debugger breaks
    1.58 +on the assertion line and not in some random guts of SDL, and so each
    1.59 +macro can have unique static variables associated with it.
    1.60 +*/
    1.61 +
    1.62 +#if (defined(_MSC_VER) && ((_M_IX86) || (_M_X64)))
    1.63 +    #define SDL_TriggerBreakpoint() __asm { int 3 }
    1.64 +#elif (defined(__GNUC__) && ((__i386__) || (__x86_64__)))
    1.65 +    #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
    1.66 +#elif defined(unix)
    1.67 +    #include <signal.h>
    1.68 +    #define SDL_TriggerBreakpoint() raise(SIGTRAP)
    1.69 +#else
    1.70 +    #error Please define your platform or set SDL_ASSERT_LEVEL to 0.
    1.71 +#endif
    1.72 +
    1.73 +#if (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */
    1.74 +#   define SDL_FUNCTION __func__
    1.75 +#elif ((__GNUC__ >= 2) || defined(_MSC_VER))
    1.76 +#   define SDL_FUNCTION __FUNCTION__
    1.77 +#else
    1.78 +#   define SDL_FUNCTION "???"
    1.79 +#endif
    1.80 +
    1.81 +typedef enum
    1.82 +{
    1.83 +    SDL_ASSERTION_RETRY,  /**< Retry the assert immediately. */
    1.84 +    SDL_ASSERTION_BREAK,  /**< Make the debugger trigger a breakpoint. */
    1.85 +    SDL_ASSERTION_ABORT,  /**< Terminate the program. */
    1.86 +    SDL_ASSERTION_IGNORE,  /**< Ignore the assert. */
    1.87 +    SDL_ASSERTION_ALWAYS_IGNORE,  /**< Ignore the assert from now on. */
    1.88 +} SDL_assert_state;
    1.89 +
    1.90 +typedef struct SDL_assert_data
    1.91 +{
    1.92 +    int always_ignore;
    1.93 +    unsigned int trigger_count;
    1.94 +    const char *condition;
    1.95 +    const char *filename;
    1.96 +    int linenum;
    1.97 +    const char *function;
    1.98 +    struct SDL_assert_data *next;
    1.99 +} SDL_assert_data;
   1.100 +
   1.101 +SDL_assert_state SDL_ReportAssertion(SDL_assert_data *, const char *, int);
   1.102 +
   1.103 +/* the do {} while(0) avoids dangling else problems:
   1.104 +    if (x) SDL_assert(y); else blah();
   1.105 +       ... without the do/while, the "else" could attach to this macro's "if".
   1.106 +   We try to handle just the minimum we need here in a macro...the loop,
   1.107 +   the static vars, and break points. The heavy lifting is handled in
   1.108 +   SDL_ReportAssertion(), in SDL_assert.c.
   1.109 +*/
   1.110 +#define SDL_enabled_assert(condition) \
   1.111 +    do { \
   1.112 +        while ( !(condition) ) { \
   1.113 +			static struct SDL_assert_data assert_data = { \
   1.114 +                0, 0, #condition, __FILE__, 0, 0, 0 \
   1.115 +            }; \
   1.116 +			const SDL_assert_state state = SDL_ReportAssertion(&assert_data, \
   1.117 +                                                               SDL_FUNCTION, \
   1.118 +															   __LINE__); \
   1.119 +            if (state == SDL_ASSERTION_RETRY) { \
   1.120 +                continue; /* go again. */ \
   1.121 +            } else if (state == SDL_ASSERTION_BREAK) { \
   1.122 +                SDL_TriggerBreakpoint(); \
   1.123 +            } \
   1.124 +            break; /* not retrying. */ \
   1.125 +        } \
   1.126 +    } while (0)
   1.127 +
   1.128 +#endif  /* enabled assertions support code */
   1.129 +
   1.130 +/* Enable various levels of assertions. */
   1.131 +#if SDL_ASSERT_LEVEL == 0   /* assertions disabled */
   1.132 +#   define SDL_assert(condition) SDL_disabled_assert(condition)
   1.133 +#   define SDL_assert_release(condition) SDL_disabled_assert(condition)
   1.134 +#   define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
   1.135 +#elif SDL_ASSERT_LEVEL == 1  /* release settings. */
   1.136 +#   define SDL_assert(condition) SDL_enabled_assert(condition)
   1.137 +#   define SDL_assert_release(condition) SDL_enabled_assert(condition)
   1.138 +#   define SDL_assert_paranoid(condition) SDL_enabled_assert(condition)
   1.139 +#elif SDL_ASSERT_LEVEL == 2  /* normal settings. */
   1.140 +#   define SDL_assert(condition) SDL_enabled_assert(condition)
   1.141 +#   define SDL_assert_release(condition) SDL_enabled_assert(condition)
   1.142 +#   define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
   1.143 +#elif SDL_ASSERT_LEVEL == 3  /* paranoid settings. */
   1.144 +#   define SDL_assert(condition) SDL_enabled_assert(condition)
   1.145 +#   define SDL_assert_release(condition) SDL_enabled_assert(condition)
   1.146 +#   define SDL_assert_paranoid(condition) SDL_enabled_assert(condition)
   1.147 +#else
   1.148 +#   error Unknown assertion level. Please fix your SDL_config.h.
   1.149 +#endif
   1.150 +
   1.151 +#endif /* _SDL_assert_h */
   1.152 +
   1.153 +/* vi: set ts=4 sw=4 expandtab: */
   1.154 +