SDL standard library

Dependents:   H261_encoder

Committer:
miruga27
Date:
Wed Sep 07 18:46:53 2016 +0000
Revision:
0:dda4f4550403
7/09/2016;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
miruga27 0:dda4f4550403 1 /*
miruga27 0:dda4f4550403 2 Simple DirectMedia Layer
miruga27 0:dda4f4550403 3 Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
miruga27 0:dda4f4550403 4
miruga27 0:dda4f4550403 5 This software is provided 'as-is', without any express or implied
miruga27 0:dda4f4550403 6 warranty. In no event will the authors be held liable for any damages
miruga27 0:dda4f4550403 7 arising from the use of this software.
miruga27 0:dda4f4550403 8
miruga27 0:dda4f4550403 9 Permission is granted to anyone to use this software for any purpose,
miruga27 0:dda4f4550403 10 including commercial applications, and to alter it and redistribute it
miruga27 0:dda4f4550403 11 freely, subject to the following restrictions:
miruga27 0:dda4f4550403 12
miruga27 0:dda4f4550403 13 1. The origin of this software must not be misrepresented; you must not
miruga27 0:dda4f4550403 14 claim that you wrote the original software. If you use this software
miruga27 0:dda4f4550403 15 in a product, an acknowledgment in the product documentation would be
miruga27 0:dda4f4550403 16 appreciated but is not required.
miruga27 0:dda4f4550403 17 2. Altered source versions must be plainly marked as such, and must not be
miruga27 0:dda4f4550403 18 misrepresented as being the original software.
miruga27 0:dda4f4550403 19 3. This notice may not be removed or altered from any source distribution.
miruga27 0:dda4f4550403 20 */
miruga27 0:dda4f4550403 21
miruga27 0:dda4f4550403 22 #ifndef _SDL_assert_h
miruga27 0:dda4f4550403 23 #define _SDL_assert_h
miruga27 0:dda4f4550403 24
miruga27 0:dda4f4550403 25 #include "SDL_config.h"
miruga27 0:dda4f4550403 26
miruga27 0:dda4f4550403 27 #include "begin_code.h"
miruga27 0:dda4f4550403 28 /* Set up for C function definitions, even when using C++ */
miruga27 0:dda4f4550403 29 #ifdef __cplusplus
miruga27 0:dda4f4550403 30 extern "C" {
miruga27 0:dda4f4550403 31 #endif
miruga27 0:dda4f4550403 32
miruga27 0:dda4f4550403 33 #ifndef SDL_ASSERT_LEVEL
miruga27 0:dda4f4550403 34 #ifdef SDL_DEFAULT_ASSERT_LEVEL
miruga27 0:dda4f4550403 35 #define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL
miruga27 0:dda4f4550403 36 #elif defined(_DEBUG) || defined(DEBUG) || \
miruga27 0:dda4f4550403 37 (defined(__GNUC__) && !defined(__OPTIMIZE__))
miruga27 0:dda4f4550403 38 #define SDL_ASSERT_LEVEL 2
miruga27 0:dda4f4550403 39 #else
miruga27 0:dda4f4550403 40 #define SDL_ASSERT_LEVEL 1
miruga27 0:dda4f4550403 41 #endif
miruga27 0:dda4f4550403 42 #endif /* SDL_ASSERT_LEVEL */
miruga27 0:dda4f4550403 43
miruga27 0:dda4f4550403 44 /*
miruga27 0:dda4f4550403 45 These are macros and not first class functions so that the debugger breaks
miruga27 0:dda4f4550403 46 on the assertion line and not in some random guts of SDL, and so each
miruga27 0:dda4f4550403 47 assert can have unique static variables associated with it.
miruga27 0:dda4f4550403 48 */
miruga27 0:dda4f4550403 49
miruga27 0:dda4f4550403 50 #if defined(_MSC_VER)
miruga27 0:dda4f4550403 51 /* Don't include intrin.h here because it contains C++ code */
miruga27 0:dda4f4550403 52 extern void __cdecl __debugbreak(void);
miruga27 0:dda4f4550403 53 #define SDL_TriggerBreakpoint() __debugbreak()
miruga27 0:dda4f4550403 54 #elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
miruga27 0:dda4f4550403 55 #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
miruga27 0:dda4f4550403 56 #elif defined(HAVE_SIGNAL_H)
miruga27 0:dda4f4550403 57 #include <signal.h>
miruga27 0:dda4f4550403 58 #define SDL_TriggerBreakpoint() raise(SIGTRAP)
miruga27 0:dda4f4550403 59 #else
miruga27 0:dda4f4550403 60 /* How do we trigger breakpoints on this platform? */
miruga27 0:dda4f4550403 61 #define SDL_TriggerBreakpoint()
miruga27 0:dda4f4550403 62 #endif
miruga27 0:dda4f4550403 63
miruga27 0:dda4f4550403 64 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */
miruga27 0:dda4f4550403 65 # define SDL_FUNCTION __func__
miruga27 0:dda4f4550403 66 #elif ((__GNUC__ >= 2) || defined(_MSC_VER))
miruga27 0:dda4f4550403 67 # define SDL_FUNCTION __FUNCTION__
miruga27 0:dda4f4550403 68 #else
miruga27 0:dda4f4550403 69 # define SDL_FUNCTION "???"
miruga27 0:dda4f4550403 70 #endif
miruga27 0:dda4f4550403 71 #define SDL_FILE __FILE__
miruga27 0:dda4f4550403 72 #define SDL_LINE __LINE__
miruga27 0:dda4f4550403 73
miruga27 0:dda4f4550403 74 /*
miruga27 0:dda4f4550403 75 sizeof (x) makes the compiler still parse the expression even without
miruga27 0:dda4f4550403 76 assertions enabled, so the code is always checked at compile time, but
miruga27 0:dda4f4550403 77 doesn't actually generate code for it, so there are no side effects or
miruga27 0:dda4f4550403 78 expensive checks at run time, just the constant size of what x WOULD be,
miruga27 0:dda4f4550403 79 which presumably gets optimized out as unused.
miruga27 0:dda4f4550403 80 This also solves the problem of...
miruga27 0:dda4f4550403 81
miruga27 0:dda4f4550403 82 int somevalue = blah();
miruga27 0:dda4f4550403 83 SDL_assert(somevalue == 1);
miruga27 0:dda4f4550403 84
miruga27 0:dda4f4550403 85 ...which would cause compiles to complain that somevalue is unused if we
miruga27 0:dda4f4550403 86 disable assertions.
miruga27 0:dda4f4550403 87 */
miruga27 0:dda4f4550403 88
miruga27 0:dda4f4550403 89 #ifdef _MSC_VER /* stupid /W4 warnings. */
miruga27 0:dda4f4550403 90 #define SDL_NULL_WHILE_LOOP_CONDITION (-1 == __LINE__)
miruga27 0:dda4f4550403 91 #else
miruga27 0:dda4f4550403 92 #define SDL_NULL_WHILE_LOOP_CONDITION (0)
miruga27 0:dda4f4550403 93 #endif
miruga27 0:dda4f4550403 94
miruga27 0:dda4f4550403 95 #define SDL_disabled_assert(condition) \
miruga27 0:dda4f4550403 96 do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION)
miruga27 0:dda4f4550403 97
miruga27 0:dda4f4550403 98 typedef enum
miruga27 0:dda4f4550403 99 {
miruga27 0:dda4f4550403 100 SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */
miruga27 0:dda4f4550403 101 SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */
miruga27 0:dda4f4550403 102 SDL_ASSERTION_ABORT, /**< Terminate the program. */
miruga27 0:dda4f4550403 103 SDL_ASSERTION_IGNORE, /**< Ignore the assert. */
miruga27 0:dda4f4550403 104 SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */
miruga27 0:dda4f4550403 105 } SDL_assert_state;
miruga27 0:dda4f4550403 106
miruga27 0:dda4f4550403 107 typedef struct SDL_assert_data
miruga27 0:dda4f4550403 108 {
miruga27 0:dda4f4550403 109 int always_ignore;
miruga27 0:dda4f4550403 110 unsigned int trigger_count;
miruga27 0:dda4f4550403 111 const char *condition;
miruga27 0:dda4f4550403 112 const char *filename;
miruga27 0:dda4f4550403 113 int linenum;
miruga27 0:dda4f4550403 114 const char *function;
miruga27 0:dda4f4550403 115 const struct SDL_assert_data *next;
miruga27 0:dda4f4550403 116 } SDL_assert_data;
miruga27 0:dda4f4550403 117
miruga27 0:dda4f4550403 118 #if (SDL_ASSERT_LEVEL > 0)
miruga27 0:dda4f4550403 119
miruga27 0:dda4f4550403 120 /* Never call this directly. Use the SDL_assert* macros. */
miruga27 0:dda4f4550403 121 extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *,
miruga27 0:dda4f4550403 122 const char *,
miruga27 0:dda4f4550403 123 const char *, int)
miruga27 0:dda4f4550403 124 #if defined(__clang__)
miruga27 0:dda4f4550403 125 #if __has_feature(attribute_analyzer_noreturn)
miruga27 0:dda4f4550403 126 /* this tells Clang's static analysis that we're a custom assert function,
miruga27 0:dda4f4550403 127 and that the analyzer should assume the condition was always true past this
miruga27 0:dda4f4550403 128 SDL_assert test. */
miruga27 0:dda4f4550403 129 __attribute__((analyzer_noreturn))
miruga27 0:dda4f4550403 130 #endif
miruga27 0:dda4f4550403 131 #endif
miruga27 0:dda4f4550403 132 ;
miruga27 0:dda4f4550403 133
miruga27 0:dda4f4550403 134 /* the do {} while(0) avoids dangling else problems:
miruga27 0:dda4f4550403 135 if (x) SDL_assert(y); else blah();
miruga27 0:dda4f4550403 136 ... without the do/while, the "else" could attach to this macro's "if".
miruga27 0:dda4f4550403 137 We try to handle just the minimum we need here in a macro...the loop,
miruga27 0:dda4f4550403 138 the static vars, and break points. The heavy lifting is handled in
miruga27 0:dda4f4550403 139 SDL_ReportAssertion(), in SDL_assert.c.
miruga27 0:dda4f4550403 140 */
miruga27 0:dda4f4550403 141 #define SDL_enabled_assert(condition) \
miruga27 0:dda4f4550403 142 do { \
miruga27 0:dda4f4550403 143 while ( !(condition) ) { \
miruga27 0:dda4f4550403 144 static struct SDL_assert_data assert_data = { \
miruga27 0:dda4f4550403 145 0, 0, #condition, 0, 0, 0, 0 \
miruga27 0:dda4f4550403 146 }; \
miruga27 0:dda4f4550403 147 const SDL_assert_state state = SDL_ReportAssertion(&assert_data, \
miruga27 0:dda4f4550403 148 SDL_FUNCTION, \
miruga27 0:dda4f4550403 149 SDL_FILE, \
miruga27 0:dda4f4550403 150 SDL_LINE); \
miruga27 0:dda4f4550403 151 if (state == SDL_ASSERTION_RETRY) { \
miruga27 0:dda4f4550403 152 continue; /* go again. */ \
miruga27 0:dda4f4550403 153 } else if (state == SDL_ASSERTION_BREAK) { \
miruga27 0:dda4f4550403 154 SDL_TriggerBreakpoint(); \
miruga27 0:dda4f4550403 155 } \
miruga27 0:dda4f4550403 156 break; /* not retrying. */ \
miruga27 0:dda4f4550403 157 } \
miruga27 0:dda4f4550403 158 } while (SDL_NULL_WHILE_LOOP_CONDITION)
miruga27 0:dda4f4550403 159
miruga27 0:dda4f4550403 160 #endif /* enabled assertions support code */
miruga27 0:dda4f4550403 161
miruga27 0:dda4f4550403 162 /* Enable various levels of assertions. */
miruga27 0:dda4f4550403 163 #if SDL_ASSERT_LEVEL == 0 /* assertions disabled */
miruga27 0:dda4f4550403 164 # define SDL_assert(condition) SDL_disabled_assert(condition)
miruga27 0:dda4f4550403 165 # define SDL_assert_release(condition) SDL_disabled_assert(condition)
miruga27 0:dda4f4550403 166 # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
miruga27 0:dda4f4550403 167 #elif SDL_ASSERT_LEVEL == 1 /* release settings. */
miruga27 0:dda4f4550403 168 # define SDL_assert(condition) SDL_disabled_assert(condition)
miruga27 0:dda4f4550403 169 # define SDL_assert_release(condition) SDL_enabled_assert(condition)
miruga27 0:dda4f4550403 170 # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
miruga27 0:dda4f4550403 171 #elif SDL_ASSERT_LEVEL == 2 /* normal settings. */
miruga27 0:dda4f4550403 172 # define SDL_assert(condition) SDL_enabled_assert(condition)
miruga27 0:dda4f4550403 173 # define SDL_assert_release(condition) SDL_enabled_assert(condition)
miruga27 0:dda4f4550403 174 # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
miruga27 0:dda4f4550403 175 #elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */
miruga27 0:dda4f4550403 176 # define SDL_assert(condition) SDL_enabled_assert(condition)
miruga27 0:dda4f4550403 177 # define SDL_assert_release(condition) SDL_enabled_assert(condition)
miruga27 0:dda4f4550403 178 # define SDL_assert_paranoid(condition) SDL_enabled_assert(condition)
miruga27 0:dda4f4550403 179 #else
miruga27 0:dda4f4550403 180 # error Unknown assertion level.
miruga27 0:dda4f4550403 181 #endif
miruga27 0:dda4f4550403 182
miruga27 0:dda4f4550403 183 /* this assertion is never disabled at any level. */
miruga27 0:dda4f4550403 184 #define SDL_assert_always(condition) SDL_enabled_assert(condition)
miruga27 0:dda4f4550403 185
miruga27 0:dda4f4550403 186
miruga27 0:dda4f4550403 187 typedef SDL_assert_state (SDLCALL *SDL_AssertionHandler)(
miruga27 0:dda4f4550403 188 const SDL_assert_data* data, void* userdata);
miruga27 0:dda4f4550403 189
miruga27 0:dda4f4550403 190 /**
miruga27 0:dda4f4550403 191 * \brief Set an application-defined assertion handler.
miruga27 0:dda4f4550403 192 *
miruga27 0:dda4f4550403 193 * This allows an app to show its own assertion UI and/or force the
miruga27 0:dda4f4550403 194 * response to an assertion failure. If the app doesn't provide this, SDL
miruga27 0:dda4f4550403 195 * will try to do the right thing, popping up a system-specific GUI dialog,
miruga27 0:dda4f4550403 196 * and probably minimizing any fullscreen windows.
miruga27 0:dda4f4550403 197 *
miruga27 0:dda4f4550403 198 * This callback may fire from any thread, but it runs wrapped in a mutex, so
miruga27 0:dda4f4550403 199 * it will only fire from one thread at a time.
miruga27 0:dda4f4550403 200 *
miruga27 0:dda4f4550403 201 * Setting the callback to NULL restores SDL's original internal handler.
miruga27 0:dda4f4550403 202 *
miruga27 0:dda4f4550403 203 * This callback is NOT reset to SDL's internal handler upon SDL_Quit()!
miruga27 0:dda4f4550403 204 *
miruga27 0:dda4f4550403 205 * \return SDL_assert_state value of how to handle the assertion failure.
miruga27 0:dda4f4550403 206 *
miruga27 0:dda4f4550403 207 * \param handler Callback function, called when an assertion fails.
miruga27 0:dda4f4550403 208 * \param userdata A pointer passed to the callback as-is.
miruga27 0:dda4f4550403 209 */
miruga27 0:dda4f4550403 210 extern DECLSPEC void SDLCALL SDL_SetAssertionHandler(
miruga27 0:dda4f4550403 211 SDL_AssertionHandler handler,
miruga27 0:dda4f4550403 212 void *userdata);
miruga27 0:dda4f4550403 213
miruga27 0:dda4f4550403 214 /**
miruga27 0:dda4f4550403 215 * \brief Get the default assertion handler.
miruga27 0:dda4f4550403 216 *
miruga27 0:dda4f4550403 217 * This returns the function pointer that is called by default when an
miruga27 0:dda4f4550403 218 * assertion is triggered. This is an internal function provided by SDL,
miruga27 0:dda4f4550403 219 * that is used for assertions when SDL_SetAssertionHandler() hasn't been
miruga27 0:dda4f4550403 220 * used to provide a different function.
miruga27 0:dda4f4550403 221 *
miruga27 0:dda4f4550403 222 * \return The default SDL_AssertionHandler that is called when an assert triggers.
miruga27 0:dda4f4550403 223 */
miruga27 0:dda4f4550403 224 extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void);
miruga27 0:dda4f4550403 225
miruga27 0:dda4f4550403 226 /**
miruga27 0:dda4f4550403 227 * \brief Get the current assertion handler.
miruga27 0:dda4f4550403 228 *
miruga27 0:dda4f4550403 229 * This returns the function pointer that is called when an assertion is
miruga27 0:dda4f4550403 230 * triggered. This is either the value last passed to
miruga27 0:dda4f4550403 231 * SDL_SetAssertionHandler(), or if no application-specified function is
miruga27 0:dda4f4550403 232 * set, is equivalent to calling SDL_GetDefaultAssertionHandler().
miruga27 0:dda4f4550403 233 *
miruga27 0:dda4f4550403 234 * \param puserdata Pointer to a void*, which will store the "userdata"
miruga27 0:dda4f4550403 235 * pointer that was passed to SDL_SetAssertionHandler().
miruga27 0:dda4f4550403 236 * This value will always be NULL for the default handler.
miruga27 0:dda4f4550403 237 * If you don't care about this data, it is safe to pass
miruga27 0:dda4f4550403 238 * a NULL pointer to this function to ignore it.
miruga27 0:dda4f4550403 239 * \return The SDL_AssertionHandler that is called when an assert triggers.
miruga27 0:dda4f4550403 240 */
miruga27 0:dda4f4550403 241 extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata);
miruga27 0:dda4f4550403 242
miruga27 0:dda4f4550403 243 /**
miruga27 0:dda4f4550403 244 * \brief Get a list of all assertion failures.
miruga27 0:dda4f4550403 245 *
miruga27 0:dda4f4550403 246 * Get all assertions triggered since last call to SDL_ResetAssertionReport(),
miruga27 0:dda4f4550403 247 * or the start of the program.
miruga27 0:dda4f4550403 248 *
miruga27 0:dda4f4550403 249 * The proper way to examine this data looks something like this:
miruga27 0:dda4f4550403 250 *
miruga27 0:dda4f4550403 251 * <code>
miruga27 0:dda4f4550403 252 * const SDL_assert_data *item = SDL_GetAssertionReport();
miruga27 0:dda4f4550403 253 * while (item) {
miruga27 0:dda4f4550403 254 * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
miruga27 0:dda4f4550403 255 * item->condition, item->function, item->filename,
miruga27 0:dda4f4550403 256 * item->linenum, item->trigger_count,
miruga27 0:dda4f4550403 257 * item->always_ignore ? "yes" : "no");
miruga27 0:dda4f4550403 258 * item = item->next;
miruga27 0:dda4f4550403 259 * }
miruga27 0:dda4f4550403 260 * </code>
miruga27 0:dda4f4550403 261 *
miruga27 0:dda4f4550403 262 * \return List of all assertions.
miruga27 0:dda4f4550403 263 * \sa SDL_ResetAssertionReport
miruga27 0:dda4f4550403 264 */
miruga27 0:dda4f4550403 265 extern DECLSPEC const SDL_assert_data * SDLCALL SDL_GetAssertionReport(void);
miruga27 0:dda4f4550403 266
miruga27 0:dda4f4550403 267 /**
miruga27 0:dda4f4550403 268 * \brief Reset the list of all assertion failures.
miruga27 0:dda4f4550403 269 *
miruga27 0:dda4f4550403 270 * Reset list of all assertions triggered.
miruga27 0:dda4f4550403 271 *
miruga27 0:dda4f4550403 272 * \sa SDL_GetAssertionReport
miruga27 0:dda4f4550403 273 */
miruga27 0:dda4f4550403 274 extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void);
miruga27 0:dda4f4550403 275
miruga27 0:dda4f4550403 276 /* Ends C function definitions when using C++ */
miruga27 0:dda4f4550403 277 #ifdef __cplusplus
miruga27 0:dda4f4550403 278 }
miruga27 0:dda4f4550403 279 #endif
miruga27 0:dda4f4550403 280 #include "close_code.h"
miruga27 0:dda4f4550403 281
miruga27 0:dda4f4550403 282 #endif /* _SDL_assert_h */
miruga27 0:dda4f4550403 283
miruga27 0:dda4f4550403 284 /* vi: set ts=4 sw=4 expandtab: */