SDL  2.0
SDL_error.c File Reference
#include "./SDL_internal.h"
#include "SDL_log.h"
#include "SDL_error.h"
#include "SDL_error_c.h"
+ Include dependency graph for SDL_error.c:

Go to the source code of this file.

Macros

#define SDL_ERRBUFIZE   1024
 

Functions

SDL_errorSDL_GetErrBuf (void)
 
static const char * SDL_LookupString (const char *key)
 
static char * SDL_GetErrorMsg (char *errstr, int maxlen)
 
int SDL_SetError (SDL_PRINTF_FORMAT_STRING const char *fmt,...)
 
const char * SDL_GetError (void)
 
void SDL_ClearError (void)
 
int SDL_Error (SDL_errorcode code)
 

Macro Definition Documentation

◆ SDL_ERRBUFIZE

#define SDL_ERRBUFIZE   1024

Definition at line 39 of file SDL_error.c.

Referenced by SDL_GetError(), and SDL_SetError().

Function Documentation

◆ SDL_ClearError()

void SDL_ClearError ( void  )

Definition at line 148 of file SDL_error.c.

References SDL_error::error, and SDL_GetErrBuf().

Referenced by SDL_Error().

149 {
150  SDL_error *error;
151 
152  error = SDL_GetErrBuf();
153  error->error = 0;
154 }
SDL_error * SDL_GetErrBuf(void)
Definition: SDL_thread.c:206

◆ SDL_Error()

int SDL_Error ( SDL_errorcode  code)

Definition at line 158 of file SDL_error.c.

References main, SDL_ClearError(), SDL_EFREAD, SDL_EFSEEK, SDL_EFWRITE, SDL_ENOMEM, SDL_GetError(), SDL_memset, SDL_SetError(), and SDL_UNSUPPORTED.

159 {
160  switch (code) {
161  case SDL_ENOMEM:
162  return SDL_SetError("Out of memory");
163  case SDL_EFREAD:
164  return SDL_SetError("Error reading from datastream");
165  case SDL_EFWRITE:
166  return SDL_SetError("Error writing to datastream");
167  case SDL_EFSEEK:
168  return SDL_SetError("Error seeking in datastream");
169  case SDL_UNSUPPORTED:
170  return SDL_SetError("That operation is not supported");
171  default:
172  return SDL_SetError("Unknown SDL error");
173  }
174 }
int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt,...)
Definition: SDL_error.c:55

◆ SDL_GetErrBuf()

SDL_error* SDL_GetErrBuf ( void  )

Definition at line 206 of file SDL_thread.c.

Referenced by SDL_ClearError(), SDL_GetErrorMsg(), and SDL_SetError().

207 {
208  static SDL_SpinLock tls_lock;
209  static SDL_bool tls_being_created;
210  static SDL_TLSID tls_errbuf;
211  static SDL_error SDL_global_errbuf;
212  const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
213  SDL_error *errbuf;
214 
215  /* tls_being_created is there simply to prevent recursion if SDL_TLSCreate() fails.
216  It also means it's possible for another thread to also use SDL_global_errbuf,
217  but that's very unlikely and hopefully won't cause issues.
218  */
219  if (!tls_errbuf && !tls_being_created) {
220  SDL_AtomicLock(&tls_lock);
221  if (!tls_errbuf) {
222  SDL_TLSID slot;
223  tls_being_created = SDL_TRUE;
224  slot = SDL_TLSCreate();
225  tls_being_created = SDL_FALSE;
227  tls_errbuf = slot;
228  }
229  SDL_AtomicUnlock(&tls_lock);
230  }
231  if (!tls_errbuf) {
232  return &SDL_global_errbuf;
233  }
234 
236  errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf);
237  if (errbuf == ALLOCATION_IN_PROGRESS) {
238  return &SDL_global_errbuf;
239  }
240  if (!errbuf) {
241  /* Mark that we're in the middle of allocating our buffer */
242  SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
243  errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf));
244  if (!errbuf) {
245  SDL_TLSSet(tls_errbuf, NULL, NULL);
246  return &SDL_global_errbuf;
247  }
248  SDL_zerop(errbuf);
249  SDL_TLSSet(tls_errbuf, errbuf, SDL_free);
250  }
251  return errbuf;
252 }
int SDL_TLSSet(SDL_TLSID id, const void *value, void(*destructor)(void *))
Set the value associated with a thread local storage ID for the current thread.
Definition: SDL_thread.c:53
#define SDL_AtomicLock
#define SDL_MemoryBarrierRelease()
Definition: SDL_atomic.h:189
void * SDL_TLSGet(SDL_TLSID id)
Get the value associated with a thread local storage ID for the current thread.
Definition: SDL_thread.c:41
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
#define SDL_MemoryBarrierAcquire()
Definition: SDL_atomic.h:190
unsigned int SDL_TLSID
Definition: SDL_thread.h:52
#define SDL_AtomicUnlock
#define SDL_free
#define NULL
Definition: begin_code.h:164
SDL_bool
Definition: SDL_stdinc.h:139
SDL_TLSID SDL_TLSCreate()
Create an identifier that is globally visible to all threads but refers to data that is thread-specif...
Definition: SDL_thread.c:34
#define SDL_malloc
int SDL_SpinLock
Definition: SDL_atomic.h:89

◆ SDL_GetError()

const char* SDL_GetError ( void  )

Definition at line 140 of file SDL_error.c.

References SDL_ERRBUFIZE, and SDL_GetErrorMsg().

Referenced by SDL_Error().

141 {
142  static char errmsg[SDL_ERRBUFIZE];
143 
144  return SDL_GetErrorMsg(errmsg, SDL_ERRBUFIZE);
145 }
#define SDL_ERRBUFIZE
Definition: SDL_error.c:39
static char * SDL_GetErrorMsg(char *errstr, int maxlen)
Definition: SDL_error.c:206

◆ SDL_GetErrorMsg()

static char * SDL_GetErrorMsg ( char *  errstr,
int  maxlen 
)
static

Definition at line 206 of file SDL_error.c.

References SDL_error::args, SDL_error::error, SDL_error::key, SDL_arraysize, SDL_GetErrBuf(), SDL_LookupString(), SDL_snprintf, SDL_error::value_f, SDL_error::value_i, SDL_error::value_l, and SDL_error::value_ptr.

Referenced by SDL_GetError(), SDL_LookupString(), and SDL_SetError().

207 {
208  SDL_error *error;
209 
210  /* Clear the error string */
211  *errstr = '\0';
212  --maxlen;
213 
214  /* Get the thread-safe error, and print it out */
215  error = SDL_GetErrBuf();
216  if (error->error) {
217  const char *fmt;
218  char *msg = errstr;
219  int len;
220  int argi;
221 
222  fmt = SDL_LookupString(error->key);
223  argi = 0;
224  while (*fmt && (maxlen > 0)) {
225  if (*fmt == '%') {
226  char tmp[32], *spot = tmp;
227  *spot++ = *fmt++;
228  while ((*fmt == '.' || (*fmt >= '0' && *fmt <= '9'))
229  && spot < (tmp + SDL_arraysize(tmp) - 2)) {
230  *spot++ = *fmt++;
231  }
232  if (*fmt == 'l') {
233  *spot++ = *fmt++;
234  *spot++ = *fmt++;
235  *spot++ = '\0';
236  switch (spot[-2]) {
237  case 'i': case 'd': case 'u':
238  len = SDL_snprintf(msg, maxlen, tmp,
239  error->args[argi++].value_l);
240  if (len > 0) {
241  msg += len;
242  maxlen -= len;
243  }
244  break;
245  }
246  continue;
247  }
248  *spot++ = *fmt++;
249  *spot++ = '\0';
250  switch (spot[-2]) {
251  case '%':
252  *msg++ = '%';
253  maxlen -= 1;
254  break;
255  case 'c':
256  case 'i':
257  case 'd':
258  case 'u':
259  case 'o':
260  case 'x':
261  case 'X':
262  len =
263  SDL_snprintf(msg, maxlen, tmp,
264  error->args[argi++].value_i);
265  if (len > 0) {
266  msg += len;
267  maxlen -= len;
268  }
269  break;
270 
271  case 'f':
272  len =
273  SDL_snprintf(msg, maxlen, tmp,
274  error->args[argi++].value_f);
275  if (len > 0) {
276  msg += len;
277  maxlen -= len;
278  }
279  break;
280 
281  case 'p':
282  len =
283  SDL_snprintf(msg, maxlen, tmp,
284  error->args[argi++].value_ptr);
285  if (len > 0) {
286  msg += len;
287  maxlen -= len;
288  }
289  break;
290 
291  case 's':
292  len =
293  SDL_snprintf(msg, maxlen, tmp,
294  SDL_LookupString(error->args[argi++].
295  buf));
296  if (len > 0) {
297  msg += len;
298  maxlen -= len;
299  }
300  break;
301 
302  }
303  } else {
304  *msg++ = *fmt++;
305  maxlen -= 1;
306  }
307  }
308 
309  /* slide back if we've overshot the end of our buffer. */
310  if (maxlen < 0) {
311  msg -= (-maxlen) + 1;
312  }
313 
314  *msg = 0; /* NULL terminate the string */
315  }
316  return (errstr);
317 }
union SDL_error::@29 args[ERR_MAX_ARGS]
double value_f
Definition: SDL_error_c.h:55
static const char * SDL_LookupString(const char *key)
Definition: SDL_error.c:44
SDL_error * SDL_GetErrBuf(void)
Definition: SDL_thread.c:206
GLenum GLsizei len
GLenum GLuint GLenum GLsizei const GLchar * buf
char key[ERR_MAX_STRLEN]
Definition: SDL_error_c.h:43
long value_l
Definition: SDL_error_c.h:54
#define SDL_snprintf
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
void * value_ptr
Definition: SDL_error_c.h:49
int value_i
Definition: SDL_error_c.h:53

◆ SDL_LookupString()

static const char* SDL_LookupString ( const char *  key)
static

Definition at line 44 of file SDL_error.c.

References SDL_GetErrorMsg().

Referenced by SDL_GetErrorMsg().

45 {
46  /* FIXME: Add code to lookup key in language string hash-table */
47  return key;
48 }
GLuint64 key
Definition: gl2ext.h:2192

◆ SDL_SetError()

int SDL_SetError ( SDL_PRINTF_FORMAT_STRING const char *  fmt,
  ... 
)

Definition at line 55 of file SDL_error.c.

References SDL_error::argc, SDL_error::args, SDL_error::buf, ERR_MAX_ARGS, ERR_MAX_STRLEN, SDL_error::error, i, SDL_error::key, NULL, SDL_ERRBUFIZE, SDL_GetErrBuf(), SDL_GetErrorMsg(), SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_DEBUG, SDL_LogDebug, SDL_LogGetPriority, SDL_strlcpy, SDL_error::value_f, SDL_error::value_i, SDL_error::value_l, and SDL_error::value_ptr.

Referenced by SDL_Error().

56 {
57  va_list ap;
58  SDL_error *error;
59 
60  /* Ignore call if invalid format pointer was passed */
61  if (fmt == NULL) return -1;
62 
63  /* Copy in the key, mark error as valid */
64  error = SDL_GetErrBuf();
65  error->error = 1;
66  SDL_strlcpy((char *) error->key, fmt, sizeof(error->key));
67 
68  va_start(ap, fmt);
69  error->argc = 0;
70  while (*fmt) {
71  if (*fmt++ == '%') {
72  while (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) {
73  ++fmt;
74  }
75  switch (*fmt++) {
76  case 0: /* Malformed format string.. */
77  --fmt;
78  break;
79  case 'l':
80  switch (*fmt++) {
81  case 0: /* Malformed format string.. */
82  --fmt;
83  break;
84  case 'i': case 'd': case 'u':
85  error->args[error->argc++].value_l = va_arg(ap, long);
86  break;
87  }
88  break;
89  case 'c':
90  case 'i':
91  case 'd':
92  case 'u':
93  case 'o':
94  case 'x':
95  case 'X':
96  error->args[error->argc++].value_i = va_arg(ap, int);
97  break;
98  case 'f':
99  error->args[error->argc++].value_f = va_arg(ap, double);
100  break;
101  case 'p':
102  error->args[error->argc++].value_ptr = va_arg(ap, void *);
103  break;
104  case 's':
105  {
106  int i = error->argc;
107  const char *str = va_arg(ap, const char *);
108  if (str == NULL)
109  str = "(null)";
110  SDL_strlcpy((char *) error->args[i].buf, str,
112  error->argc++;
113  }
114  break;
115  default:
116  break;
117  }
118  if (error->argc >= ERR_MAX_ARGS) {
119  break;
120  }
121  }
122  }
123  va_end(ap);
124 
126  /* If we are in debug mode, print out an error message
127  * Avoid stomping on the static buffer in GetError, just
128  * in case this is called while processing a ShowMessageBox to
129  * show an error already in that static buffer.
130  */
131  char errmsg[SDL_ERRBUFIZE];
132  SDL_GetErrorMsg(errmsg, sizeof(errmsg));
133  SDL_LogDebug(SDL_LOG_CATEGORY_ERROR, "%s", errmsg);
134  }
135  return -1;
136 }
#define SDL_strlcpy
#define SDL_ERRBUFIZE
Definition: SDL_error.c:39
union SDL_error::@29 args[ERR_MAX_ARGS]
double value_f
Definition: SDL_error_c.h:55
#define SDL_LogGetPriority
SDL_error * SDL_GetErrBuf(void)
Definition: SDL_thread.c:206
#define ERR_MAX_STRLEN
Definition: SDL_error_c.h:30
#define SDL_LogDebug
#define ERR_MAX_ARGS
Definition: SDL_error_c.h:31
char key[ERR_MAX_STRLEN]
Definition: SDL_error_c.h:43
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:164
long value_l
Definition: SDL_error_c.h:54
char buf[ERR_MAX_STRLEN]
Definition: SDL_error_c.h:56
void * value_ptr
Definition: SDL_error_c.h:49
int value_i
Definition: SDL_error_c.h:53
static char * SDL_GetErrorMsg(char *errstr, int maxlen)
Definition: SDL_error.c:206