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.

Function Documentation

◆ SDL_ClearError()

void SDL_ClearError ( void  )

Definition at line 148 of file SDL_error.c.

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

References SDL_error::error, and SDL_GetErrBuf().

◆ SDL_Error()

int SDL_Error ( SDL_errorcode  code)

Definition at line 158 of file SDL_error.c.

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_EFSEEK
Definition: SDL_error.h:60
@ SDL_EFWRITE
Definition: SDL_error.h:59
@ SDL_UNSUPPORTED
Definition: SDL_error.h:61
@ SDL_EFREAD
Definition: SDL_error.h:58
@ SDL_ENOMEM
Definition: SDL_error.h:57

References SDL_EFREAD, SDL_EFSEEK, SDL_EFWRITE, SDL_ENOMEM, SDL_SetError(), and SDL_UNSUPPORTED.

◆ SDL_GetErrBuf()

SDL_error * SDL_GetErrBuf ( void  )

Definition at line 206 of file SDL_thread.c.

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}
#define SDL_MemoryBarrierRelease()
Definition: SDL_atomic.h:207
int SDL_SpinLock
Definition: SDL_atomic.h:89
#define SDL_MemoryBarrierAcquire()
Definition: SDL_atomic.h:208
#define SDL_AtomicLock
#define SDL_malloc
#define SDL_AtomicUnlock
#define SDL_free
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
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
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
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
unsigned int SDL_TLSID
Definition: SDL_thread.h:52
#define NULL
Definition: begin_code.h:167

References NULL, SDL_AtomicLock, SDL_AtomicUnlock, SDL_FALSE, SDL_free, SDL_malloc, SDL_MemoryBarrierAcquire, SDL_MemoryBarrierRelease, SDL_TLSCreate(), SDL_TLSGet(), SDL_TLSSet(), SDL_TRUE, and SDL_zerop.

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

◆ SDL_GetError()

const char * SDL_GetError ( void  )

Definition at line 140 of file SDL_error.c.

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

References SDL_ERRBUFIZE, and SDL_GetErrorMsg().

◆ SDL_GetErrorMsg()

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

Definition at line 206 of file SDL_error.c.

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': case 'x': case 'X':
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}
#define SDL_snprintf
static const char * SDL_LookupString(const char *key)
Definition: SDL_error.c:44
GLenum GLsizei len
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
int value_i
Definition: SDL_error_c.h:53
long value_l
Definition: SDL_error_c.h:54
void * value_ptr
Definition: SDL_error_c.h:49
char key[ERR_MAX_STRLEN]
Definition: SDL_error_c.h:43
union SDL_error::@35 args[ERR_MAX_ARGS]
double value_f
Definition: SDL_error_c.h:55

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(), and SDL_SetError().

◆ SDL_LookupString()

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

Definition at line 44 of file SDL_error.c.

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

Referenced by SDL_GetErrorMsg().

◆ SDL_SetError()

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

Definition at line 55 of file SDL_error.c.

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': case 'x': case 'X':
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));
134 }
135 return -1;
136}
#define SDL_LogGetPriority
#define SDL_strlcpy
#define SDL_LogDebug
#define ERR_MAX_ARGS
Definition: SDL_error_c.h:31
#define ERR_MAX_STRLEN
Definition: SDL_error_c.h:30
@ SDL_LOG_PRIORITY_DEBUG
Definition: SDL_log.h:105
@ SDL_LOG_CATEGORY_ERROR
Definition: SDL_log.h:67
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
char buf[ERR_MAX_STRLEN]
Definition: SDL_error_c.h:56

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().