src/SDL_assert.c
changeset 3670 62b6a5b99918
parent 3669 46d27a9571fa
child 3671 0d6f520c0eb9
     1.1 --- a/src/SDL_assert.c	Wed Jan 13 16:58:24 2010 +0000
     1.2 +++ b/src/SDL_assert.c	Wed Jan 13 19:29:33 2010 +0000
     1.3 @@ -23,8 +23,6 @@
     1.4  #include "SDL.h"
     1.5  #include "SDL_assert.h"
     1.6  
     1.7 -#if (SDL_ASSERT_LEVEL > 0)
     1.8 -
     1.9  #ifdef _WINDOWS
    1.10  #define WIN32_LEAN_AND_MEAN 1
    1.11  #include <windows.h>
    1.12 @@ -34,13 +32,19 @@
    1.13  #include <unistd.h>
    1.14  #endif
    1.15  
    1.16 -/* We can keep all triggered assertions in a singly-linked list so we can
    1.17 +static SDL_assert_state
    1.18 +SDL_PromptAssertion(const SDL_assert_data *data, void *userdata);
    1.19 +
    1.20 +/*
    1.21 + * We keep all triggered assertions in a singly-linked list so we can
    1.22   *  generate a report later.
    1.23   */
    1.24 -#if !SDL_ASSERTION_REPORT_DISABLED
    1.25  static SDL_assert_data assertion_list_terminator = { 0, 0, 0, 0, 0, 0, 0 };
    1.26  static SDL_assert_data *triggered_assertions = &assertion_list_terminator;
    1.27 -#endif
    1.28 +
    1.29 +static SDL_mutex *assertion_mutex = NULL;
    1.30 +static SDL_AssertionHandler assertion_handler = SDL_PromptAssertion;
    1.31 +static void *assertion_userdata = NULL;
    1.32  
    1.33  #ifdef __GNUC__
    1.34  static void
    1.35 @@ -198,27 +202,30 @@
    1.36  
    1.37  static void SDL_AddAssertionToReport(SDL_assert_data *data)
    1.38  {
    1.39 -#if !SDL_ASSERTION_REPORT_DISABLED
    1.40      /* (data) is always a static struct defined with the assert macros, so
    1.41         we don't have to worry about copying or allocating them. */
    1.42      if (data->next == NULL) {  /* not yet added? */
    1.43          data->next = triggered_assertions;
    1.44          triggered_assertions = data;
    1.45      }
    1.46 -#endif
    1.47  }
    1.48  
    1.49 +
    1.50  static void SDL_GenerateAssertionReport(void)
    1.51  {
    1.52 -#if !SDL_ASSERTION_REPORT_DISABLED
    1.53 -    if (triggered_assertions != &assertion_list_terminator)
    1.54 +    const SDL_assert_data *item;
    1.55 +
    1.56 +    /* only do this if the app hasn't assigned an assertion handler. */
    1.57 +    if (assertion_handler != SDL_PromptAssertion)
    1.58 +        return;
    1.59 +
    1.60 +    item = SDL_GetAssertionReport();
    1.61 +    if (item->condition)
    1.62      {
    1.63 -        SDL_assert_data *item = triggered_assertions;
    1.64 -
    1.65          debug_print("\n\nSDL assertion report.\n");
    1.66          debug_print("All SDL assertions between last init/quit:\n\n");
    1.67  
    1.68 -        while (item != &assertion_list_terminator) {
    1.69 +        while (item->condition) {
    1.70              debug_print(
    1.71                  "'%s'\n"
    1.72                  "    * %s (%s:%d)\n"
    1.73 @@ -232,9 +239,8 @@
    1.74          }
    1.75          debug_print("\n");
    1.76  
    1.77 -        triggered_assertions = &assertion_list_terminator;
    1.78 +        SDL_ResetAssertionReport();
    1.79      }
    1.80 -#endif
    1.81  }
    1.82  
    1.83  static void SDL_ExitProcess(int exitcode)
    1.84 @@ -253,12 +259,15 @@
    1.85  }
    1.86  
    1.87  
    1.88 -static SDL_assert_state SDL_PromptAssertion(const SDL_assert_data *data)
    1.89 +static SDL_assert_state
    1.90 +SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
    1.91  {
    1.92      const char *envr;
    1.93      SDL_assert_state state = SDL_ASSERTION_ABORT;
    1.94      SDL_WindowID window;
    1.95  
    1.96 +    (void) userdata;  /* unused in default handler. */
    1.97 +
    1.98      debug_print("\n\n"
    1.99                  "Assertion failure at %s (%s:%d), triggered %u time%s:\n"
   1.100                  "  '%s'\n"
   1.101 @@ -291,6 +300,7 @@
   1.102          if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
   1.103              SDL_MinimizeWindow(window);
   1.104          } else {
   1.105 +            /* !!! FIXME: ungrab the input if we're not fullscreen? */
   1.106              /* No need to mess with the window */
   1.107              window = 0;
   1.108          }
   1.109 @@ -344,8 +354,6 @@
   1.110  }
   1.111  
   1.112  
   1.113 -static SDL_mutex *assertion_mutex = NULL;
   1.114 -
   1.115  SDL_assert_state
   1.116  SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file,
   1.117                      int line)
   1.118 @@ -391,7 +399,7 @@
   1.119      }
   1.120  
   1.121      if (!data->always_ignore) {
   1.122 -        state = SDL_PromptAssertion(data);
   1.123 +        state = assertion_handler(data, assertion_userdata);
   1.124      }
   1.125  
   1.126      switch (state)
   1.127 @@ -417,8 +425,6 @@
   1.128      return state;
   1.129  }
   1.130  
   1.131 -#endif  /* SDL_ASSERT_LEVEL > 0 */
   1.132 -
   1.133  
   1.134  int SDL_AssertionsInit(void)
   1.135  {
   1.136 @@ -428,13 +434,41 @@
   1.137  
   1.138  void SDL_AssertionsQuit(void)
   1.139  {
   1.140 -#if (SDL_ASSERT_LEVEL > 0)
   1.141      SDL_GenerateAssertionReport();
   1.142      if (assertion_mutex != NULL) {
   1.143          SDL_DestroyMutex(assertion_mutex);
   1.144          assertion_mutex = NULL;
   1.145      }
   1.146 -#endif
   1.147 +}
   1.148 +
   1.149 +void SDL_SetAssertionHandler(SDL_AssertionHandler handler, void *userdata)
   1.150 +{
   1.151 +    if (handler != NULL) {
   1.152 +        assertion_handler = handler;
   1.153 +        assertion_userdata = userdata;
   1.154 +    } else {
   1.155 +        assertion_handler = SDL_PromptAssertion;
   1.156 +        assertion_userdata = NULL;
   1.157 +    }
   1.158 +}
   1.159 +
   1.160 +const SDL_assert_data *SDL_GetAssertionReport(void)
   1.161 +{
   1.162 +    return triggered_assertions;
   1.163 +}
   1.164 +
   1.165 +void SDL_ResetAssertionReport(void)
   1.166 +{
   1.167 +    SDL_assert_data *item = triggered_assertions;
   1.168 +    SDL_assert_data *next = NULL;
   1.169 +    for (item = triggered_assertions; item->condition; item = next) {
   1.170 +        next = (SDL_assert_data *) item->next;
   1.171 +        item->always_ignore = SDL_FALSE;
   1.172 +        item->trigger_count = 0;
   1.173 +        item->next = NULL;
   1.174 +    }
   1.175 +
   1.176 +    triggered_assertions = &assertion_list_terminator;
   1.177  }
   1.178  
   1.179  /* vi: set ts=4 sw=4 expandtab: */