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)
 
int SDL_SetError (SDL_PRINTF_FORMAT_STRING const char *fmt,...)
 
static char * SDL_GetErrorMsg (char *errstr, int maxlen)
 
const char * SDL_GetError (void)
 
void SDL_ClearError (void)
 
int SDL_Error (SDL_errorcode code)
 

Macro Definition Documentation

#define SDL_ERRBUFIZE   1024

Definition at line 39 of file SDL_error.c.

Referenced by SDL_GetError().

Function Documentation

void SDL_ClearError ( void  )

Definition at line 230 of file SDL_error.c.

References SDL_error::error, and SDL_GetErrBuf().

Referenced by SDL_Error().

231 {
232  SDL_error *error;
233 
234  error = SDL_GetErrBuf();
235  error->error = 0;
236 }
SDL_error * SDL_GetErrBuf(void)
Definition: SDL_thread.c:205
int SDL_Error ( SDL_errorcode  code)

Definition at line 240 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.

241 {
242  switch (code) {
243  case SDL_ENOMEM:
244  return SDL_SetError("Out of memory");
245  case SDL_EFREAD:
246  return SDL_SetError("Error reading from datastream");
247  case SDL_EFWRITE:
248  return SDL_SetError("Error writing to datastream");
249  case SDL_EFSEEK:
250  return SDL_SetError("Error seeking in datastream");
251  case SDL_UNSUPPORTED:
252  return SDL_SetError("That operation is not supported");
253  default:
254  return SDL_SetError("Unknown SDL error");
255  }
256 }
int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt,...)
Definition: SDL_error.c:53
SDL_error* SDL_GetErrBuf ( void  )

Definition at line 205 of file SDL_thread.c.

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

206 {
207  static SDL_SpinLock tls_lock;
208  static SDL_bool tls_being_created;
209  static SDL_TLSID tls_errbuf;
210  static SDL_error SDL_global_errbuf;
211  const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
212  SDL_error *errbuf;
213 
214  /* tls_being_created is there simply to prevent recursion if SDL_TLSCreate() fails.
215  It also means it's possible for another thread to also use SDL_global_errbuf,
216  but that's very unlikely and hopefully won't cause issues.
217  */
218  if (!tls_errbuf && !tls_being_created) {
219  SDL_AtomicLock(&tls_lock);
220  if (!tls_errbuf) {
221  SDL_TLSID slot;
222  tls_being_created = SDL_TRUE;
223  slot = SDL_TLSCreate();
224  tls_being_created = SDL_FALSE;
226  tls_errbuf = slot;
227  }
228  SDL_AtomicUnlock(&tls_lock);
229  }
230  if (!tls_errbuf) {
231  return &SDL_global_errbuf;
232  }
233 
235  errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf);
236  if (errbuf == ALLOCATION_IN_PROGRESS) {
237  return &SDL_global_errbuf;
238  }
239  if (!errbuf) {
240  /* Mark that we're in the middle of allocating our buffer */
241  SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
242  errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf));
243  if (!errbuf) {
244  SDL_TLSSet(tls_errbuf, NULL, NULL);
245  return &SDL_global_errbuf;
246  }
247  SDL_zerop(errbuf);
248  SDL_TLSSet(tls_errbuf, errbuf, SDL_free);
249  }
250  return errbuf;
251 }
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:52
#define SDL_AtomicLock
#define SDL_MemoryBarrierRelease()
Definition: SDL_atomic.h:180
void * SDL_TLSGet(SDL_TLSID id)
Get the value associated with a thread local storage ID for the current thread.
Definition: SDL_thread.c:40
#define SDL_zerop(x)
Definition: SDL_stdinc.h:356
#define SDL_MemoryBarrierAcquire()
Definition: SDL_atomic.h:181
unsigned int SDL_TLSID
Definition: SDL_thread.h:52
#define SDL_AtomicUnlock
SDL_bool
Definition: SDL_stdinc.h:126
void SDL_free(void *mem)
#define NULL
Definition: begin_code.h:143
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:33
#define SDL_malloc
int SDL_SpinLock
Definition: SDL_atomic.h:89
const char* SDL_GetError ( void  )

Definition at line 222 of file SDL_error.c.

References SDL_ERRBUFIZE, and SDL_GetErrorMsg().

Referenced by SDL_Error(), and SDL_SetError().

223 {
224  static char errmsg[SDL_ERRBUFIZE];
225 
226  return SDL_GetErrorMsg(errmsg, SDL_ERRBUFIZE);
227 }
#define SDL_ERRBUFIZE
Definition: SDL_error.c:39
static char * SDL_GetErrorMsg(char *errstr, int maxlen)
Definition: SDL_error.c:123
static char* SDL_GetErrorMsg ( char *  errstr,
int  maxlen 
)
static

Definition at line 123 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, and SDL_error::value_ptr.

Referenced by SDL_GetError().

124 {
125  SDL_error *error;
126 
127  /* Clear the error string */
128  *errstr = '\0';
129  --maxlen;
130 
131  /* Get the thread-safe error, and print it out */
132  error = SDL_GetErrBuf();
133  if (error->error) {
134  const char *fmt;
135  char *msg = errstr;
136  int len;
137  int argi;
138 
139  fmt = SDL_LookupString(error->key);
140  argi = 0;
141  while (*fmt && (maxlen > 0)) {
142  if (*fmt == '%') {
143  char tmp[32], *spot = tmp;
144  *spot++ = *fmt++;
145  while ((*fmt == '.' || (*fmt >= '0' && *fmt <= '9'))
146  && spot < (tmp + SDL_arraysize(tmp) - 2)) {
147  *spot++ = *fmt++;
148  }
149  *spot++ = *fmt++;
150  *spot++ = '\0';
151  switch (spot[-2]) {
152  case '%':
153  *msg++ = '%';
154  maxlen -= 1;
155  break;
156  case 'c':
157  case 'i':
158  case 'd':
159  case 'u':
160  case 'o':
161  case 'x':
162  case 'X':
163  len =
164  SDL_snprintf(msg, maxlen, tmp,
165  error->args[argi++].value_i);
166  if (len > 0) {
167  msg += len;
168  maxlen -= len;
169  }
170  break;
171 
172  case 'f':
173  len =
174  SDL_snprintf(msg, maxlen, tmp,
175  error->args[argi++].value_f);
176  if (len > 0) {
177  msg += len;
178  maxlen -= len;
179  }
180  break;
181 
182  case 'p':
183  len =
184  SDL_snprintf(msg, maxlen, tmp,
185  error->args[argi++].value_ptr);
186  if (len > 0) {
187  msg += len;
188  maxlen -= len;
189  }
190  break;
191 
192  case 's':
193  len =
194  SDL_snprintf(msg, maxlen, tmp,
195  SDL_LookupString(error->args[argi++].
196  buf));
197  if (len > 0) {
198  msg += len;
199  maxlen -= len;
200  }
201  break;
202 
203  }
204  } else {
205  *msg++ = *fmt++;
206  maxlen -= 1;
207  }
208  }
209 
210  /* slide back if we've overshot the end of our buffer. */
211  if (maxlen < 0) {
212  msg -= (-maxlen) + 1;
213  }
214 
215  *msg = 0; /* NULL terminate the string */
216  }
217  return (errstr);
218 }
double value_f
Definition: SDL_error_c.h:54
static const char * SDL_LookupString(const char *key)
Definition: SDL_error.c:44
SDL_error * SDL_GetErrBuf(void)
Definition: SDL_thread.c:205
GLenum GLsizei len
union SDL_error::@22 args[ERR_MAX_ARGS]
GLenum GLuint GLenum GLsizei const GLchar * buf
char key[ERR_MAX_STRLEN]
Definition: SDL_error_c.h:43
#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
static const char* SDL_LookupString ( const char *  key)
static

Definition at line 44 of file SDL_error.c.

Referenced by SDL_GetErrorMsg().

45 {
46  /* FIXME: Add code to lookup key in language string hash-table */
47  return key;
48 }
int SDL_SetError ( SDL_PRINTF_FORMAT_STRING const char *  fmt,
  ... 
)

Definition at line 53 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_GetErrBuf(), SDL_GetError(), SDL_LOG_CATEGORY_ERROR, SDL_LogDebug, SDL_strlcpy, SDL_error::value_f, SDL_error::value_i, and SDL_error::value_ptr.

Referenced by SDL_Error().

54 {
55  va_list ap;
56  SDL_error *error;
57 
58  /* Ignore call if invalid format pointer was passed */
59  if (fmt == NULL) return -1;
60 
61  /* Copy in the key, mark error as valid */
62  error = SDL_GetErrBuf();
63  error->error = 1;
64  SDL_strlcpy((char *) error->key, fmt, sizeof(error->key));
65 
66  va_start(ap, fmt);
67  error->argc = 0;
68  while (*fmt) {
69  if (*fmt++ == '%') {
70  while (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) {
71  ++fmt;
72  }
73  switch (*fmt++) {
74  case 0: /* Malformed format string.. */
75  --fmt;
76  break;
77  case 'c':
78  case 'i':
79  case 'd':
80  case 'u':
81  case 'o':
82  case 'x':
83  case 'X':
84  error->args[error->argc++].value_i = va_arg(ap, int);
85  break;
86  case 'f':
87  error->args[error->argc++].value_f = va_arg(ap, double);
88  break;
89  case 'p':
90  error->args[error->argc++].value_ptr = va_arg(ap, void *);
91  break;
92  case 's':
93  {
94  int i = error->argc;
95  const char *str = va_arg(ap, const char *);
96  if (str == NULL)
97  str = "(null)";
98  SDL_strlcpy((char *) error->args[i].buf, str,
100  error->argc++;
101  }
102  break;
103  default:
104  break;
105  }
106  if (error->argc >= ERR_MAX_ARGS) {
107  break;
108  }
109  }
110  }
111  va_end(ap);
112 
113  /* If we are in debug mode, print out an error message */
115 
116  return -1;
117 }
#define SDL_strlcpy
double value_f
Definition: SDL_error_c.h:54
SDL_error * SDL_GetErrBuf(void)
Definition: SDL_thread.c:205
#define ERR_MAX_STRLEN
Definition: SDL_error_c.h:30
const char * SDL_GetError(void)
Definition: SDL_error.c:222
#define SDL_LogDebug
union SDL_error::@22 args[ERR_MAX_ARGS]
#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:42
#define NULL
Definition: begin_code.h:143
char buf[ERR_MAX_STRLEN]
Definition: SDL_error_c.h:55
void * value_ptr
Definition: SDL_error_c.h:49
int value_i
Definition: SDL_error_c.h:53