| | |
| | | /* |
| | | Simple DirectMedia Layer |
| | | Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org> |
| | | Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> |
| | | |
| | | This software is provided 'as-is', without any express or implied |
| | | warranty. In no event will the authors be held liable for any damages |
| | |
| | | misrepresented as being the original software. |
| | | 3. This notice may not be removed or altered from any source distribution. |
| | | */ |
| | | #include "SDL_config.h" |
| | | #include "./SDL_internal.h" |
| | | |
| | | #if defined(__WIN32__) |
| | | #include "core/windows/SDL_windows.h" |
| | |
| | | #else /* fprintf, _exit(), etc. */ |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | #if ! defined(__WINRT__) |
| | | #include <unistd.h> |
| | | #endif |
| | | #endif |
| | | |
| | | static SDL_assert_state |
| | | #if defined(__EMSCRIPTEN__) |
| | | #include <emscripten.h> |
| | | #endif |
| | | |
| | | |
| | | static SDL_assert_state SDLCALL |
| | | SDL_PromptAssertion(const SDL_assert_data *data, void *userdata); |
| | | |
| | | /* |
| | |
| | | */ |
| | | static SDL_assert_data *triggered_assertions = NULL; |
| | | |
| | | #ifndef SDL_THREADS_DISABLED |
| | | static SDL_mutex *assertion_mutex = NULL; |
| | | #endif |
| | | |
| | | static SDL_AssertionHandler assertion_handler = SDL_PromptAssertion; |
| | | static void *assertion_userdata = NULL; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | #if defined(__WATCOMC__) |
| | | #pragma aux SDL_ExitProcess aborts; |
| | | #endif |
| | | static void SDL_ExitProcess(int exitcode) |
| | | { |
| | | #ifdef __WIN32__ |
| | | ExitProcess(exitcode); |
| | | /* "if you do not know the state of all threads in your process, it is |
| | | better to call TerminateProcess than ExitProcess" |
| | | https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */ |
| | | TerminateProcess(GetCurrentProcess(), exitcode); |
| | | |
| | | #elif defined(__EMSCRIPTEN__) |
| | | emscripten_cancel_main_loop(); /* this should "kill" the app. */ |
| | | emscripten_force_exit(exitcode); /* this should "kill" the app. */ |
| | | exit(exitcode); |
| | | #else |
| | | _exit(exitcode); |
| | | #endif |
| | | } |
| | | |
| | | |
| | | #if defined(__WATCOMC__) |
| | | #pragma aux SDL_AbortAssertion aborts; |
| | | #endif |
| | | static void SDL_AbortAssertion(void) |
| | | { |
| | | SDL_Quit(); |
| | |
| | | } |
| | | |
| | | |
| | | static SDL_assert_state |
| | | static SDL_assert_state SDLCALL |
| | | SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) |
| | | { |
| | | #ifdef __WIN32__ |
| | |
| | | state = (SDL_assert_state)selected; |
| | | } |
| | | } |
| | | #ifdef HAVE_STDIO_H |
| | | |
| | | else |
| | | { |
| | | #if defined(__EMSCRIPTEN__) |
| | | /* This is nasty, but we can't block on a custom UI. */ |
| | | for ( ; ; ) { |
| | | SDL_bool okay = SDL_TRUE; |
| | | char *buf = (char *) EM_ASM_INT({ |
| | | var str = |
| | | Pointer_stringify($0) + '\n\n' + |
| | | 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; |
| | | var reply = window.prompt(str, "i"); |
| | | if (reply === null) { |
| | | reply = "i"; |
| | | } |
| | | return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); |
| | | }, message); |
| | | |
| | | if (SDL_strcmp(buf, "a") == 0) { |
| | | state = SDL_ASSERTION_ABORT; |
| | | /* (currently) no break functionality on Emscripten |
| | | } else if (SDL_strcmp(buf, "b") == 0) { |
| | | state = SDL_ASSERTION_BREAK; */ |
| | | } else if (SDL_strcmp(buf, "r") == 0) { |
| | | state = SDL_ASSERTION_RETRY; |
| | | } else if (SDL_strcmp(buf, "i") == 0) { |
| | | state = SDL_ASSERTION_IGNORE; |
| | | } else if (SDL_strcmp(buf, "A") == 0) { |
| | | state = SDL_ASSERTION_ALWAYS_IGNORE; |
| | | } else { |
| | | okay = SDL_FALSE; |
| | | } |
| | | free(buf); |
| | | |
| | | if (okay) { |
| | | break; |
| | | } |
| | | } |
| | | #elif defined(HAVE_STDIO_H) |
| | | /* this is a little hacky. */ |
| | | for ( ; ; ) { |
| | | char buf[32]; |
| | |
| | | break; |
| | | } |
| | | |
| | | if (SDL_strcmp(buf, "a") == 0) { |
| | | if (SDL_strncmp(buf, "a", 1) == 0) { |
| | | state = SDL_ASSERTION_ABORT; |
| | | break; |
| | | } else if (SDL_strcmp(buf, "b") == 0) { |
| | | } else if (SDL_strncmp(buf, "b", 1) == 0) { |
| | | state = SDL_ASSERTION_BREAK; |
| | | break; |
| | | } else if (SDL_strcmp(buf, "r") == 0) { |
| | | } else if (SDL_strncmp(buf, "r", 1) == 0) { |
| | | state = SDL_ASSERTION_RETRY; |
| | | break; |
| | | } else if (SDL_strcmp(buf, "i") == 0) { |
| | | } else if (SDL_strncmp(buf, "i", 1) == 0) { |
| | | state = SDL_ASSERTION_IGNORE; |
| | | break; |
| | | } else if (SDL_strcmp(buf, "A") == 0) { |
| | | } else if (SDL_strncmp(buf, "A", 1) == 0) { |
| | | state = SDL_ASSERTION_ALWAYS_IGNORE; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | #endif /* HAVE_STDIO_H */ |
| | | } |
| | | |
| | | /* Re-enter fullscreen mode */ |
| | | if (window) { |
| | |
| | | SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file, |
| | | int line) |
| | | { |
| | | static int assertion_running = 0; |
| | | static SDL_SpinLock spinlock = 0; |
| | | SDL_assert_state state = SDL_ASSERTION_IGNORE; |
| | | static int assertion_running = 0; |
| | | |
| | | #ifndef SDL_THREADS_DISABLED |
| | | static SDL_SpinLock spinlock = 0; |
| | | SDL_AtomicLock(&spinlock); |
| | | if (assertion_mutex == NULL) { /* never called SDL_Init()? */ |
| | | assertion_mutex = SDL_CreateMutex(); |
| | |
| | | if (SDL_LockMutex(assertion_mutex) < 0) { |
| | | return SDL_ASSERTION_IGNORE; /* oh well, I guess. */ |
| | | } |
| | | #endif |
| | | |
| | | /* doing this because Visual C is upset over assigning in the macro. */ |
| | | if (data->trigger_count == 0) { |
| | |
| | | } |
| | | |
| | | assertion_running--; |
| | | |
| | | #ifndef SDL_THREADS_DISABLED |
| | | SDL_UnlockMutex(assertion_mutex); |
| | | #endif |
| | | |
| | | return state; |
| | | } |
| | |
| | | void SDL_AssertionsQuit(void) |
| | | { |
| | | SDL_GenerateAssertionReport(); |
| | | #ifndef SDL_THREADS_DISABLED |
| | | if (assertion_mutex != NULL) { |
| | | SDL_DestroyMutex(assertion_mutex); |
| | | assertion_mutex = NULL; |
| | | } |
| | | #endif |
| | | } |
| | | |
| | | void SDL_SetAssertionHandler(SDL_AssertionHandler handler, void *userdata) |
| | |
| | | triggered_assertions = NULL; |
| | | } |
| | | |
| | | SDL_AssertionHandler SDL_GetDefaultAssertionHandler(void) |
| | | { |
| | | return SDL_PromptAssertion; |
| | | } |
| | | |
| | | SDL_AssertionHandler SDL_GetAssertionHandler(void **userdata) |
| | | { |
| | | if (userdata != NULL) { |
| | | *userdata = assertion_userdata; |
| | | } |
| | | return assertion_handler; |
| | | } |
| | | |
| | | /* vi: set ts=4 sw=4 expandtab: */ |