slouken@libsdl.org
#include "SDL_config.h"
#include "SDL_error.h"
#include "SDL_error_c.h"
#if SDL_THREADS_DISABLED
static SDL_error SDL_global_error;
#define SDL_GetErrBuf() (&SDL_global_error)
#else
extern SDL_error *SDL_GetErrBuf(void);
#endif
#define SDL_ERRBUFIZE 1024
static const char *SDL_LookupString(const char *key)
{
FIXME:
return key;
}
void SDL_SetError (const char *fmt, ...)
{
va_list ap;
SDL_error *error;
error = SDL_GetErrBuf();
error->error = 1;
SDL_strlcpy((char *)error->key, fmt, sizeof(error->key));
va_start(ap, fmt);
error->argc = 0;
while ( *fmt ) {
if ( *fmt++ == '%' ) {
while ( *fmt == '.' || (*fmt >= '0' && *fmt <= '9') ) {
++fmt;
}
switch (*fmt++) {
case 0:
--fmt;
break;
case 'c':
case 'i':
case 'd':
case 'u':
case 'o':
case 'x':
case 'X':
error->args[error->argc++].value_i =
va_arg(ap, int);
break;
case 'f':
error->args[error->argc++].value_f =
va_arg(ap, double);
break;
case 'p':
error->args[error->argc++].value_ptr =
va_arg(ap, void *);
break;
case 's':
{
int i = error->argc;
const char *str = va_arg(ap, const char *);
if (str == NULL)
str = "(null)";
SDL_strlcpy((char *)error->args[i].buf, str, ERR_MAX_STRLEN);
error->argc++;
}
break;
default:
break;
}
if ( error->argc >= ERR_MAX_ARGS ) {
break;
}
}
}
va_end(ap);
#ifdef DEBUG_ERROR
fprintf(stderr, "SDL_SetError: %s\n", SDL_GetError());
#endif
}
char *SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
{
SDL_error *error;
*errstr = '\0'; --maxlen;
error = SDL_GetErrBuf();
if ( error->error ) {
const char *fmt;
char *msg = errstr;
int len;
int argi;
fmt = SDL_LookupString(error->key);
argi = 0;
while ( *fmt && (maxlen > 0) ) {
if ( *fmt == '%' ) {
char tmp[32], *spot = tmp;
*spot++ = *fmt++;
while ( (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) && spot < (tmp+SDL_arraysize(tmp)-2) ) {
*spot++ = *fmt++;
}
*spot++ = *fmt++;
*spot++ = '\0';
switch (spot[-2]) {
case '%':
*msg++ = '%';
maxlen -= 1;
break;
case 'c':
case 'i':
case 'd':
case 'u':
case 'o':
case 'x':
case 'X':
len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_i);
msg += len;
maxlen -= len;
break;
case 'f':
len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_f);
msg += len;
maxlen -= len;
break;
case 'p':
len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_ptr);
msg += len;
maxlen -= len;
break;
case 's':
len = SDL_snprintf(msg, maxlen, tmp, SDL_LookupString(error->args[argi++].buf));
msg += len;
maxlen -= len;
break;
}
} else {
*msg++ = *fmt++;
maxlen -= 1;
}
}
*msg = 0;
}
return(errstr);
}
char *SDL_GetError (void)
{
static char errmsg[SDL_ERRBUFIZE];
return((char *)SDL_GetErrorMsg(errmsg, SDL_ERRBUFIZE));
}
void SDL_ClearError(void)
{
SDL_error *error;
error = SDL_GetErrBuf();
error->error = 0;
}
void SDL_Error(SDL_errorcode code)
{
switch (code) {
case SDL_ENOMEM:
SDL_SetError("Out of memory");
break;
case SDL_EFREAD:
SDL_SetError("Error reading from datastream");
break;
case SDL_EFWRITE:
SDL_SetError("Error writing to datastream");
break;
case SDL_EFSEEK:
SDL_SetError("Error seeking in datastream");
break;
default:
SDL_SetError("Unknown SDL error");
break;
}
}
#ifdef TEST_ERROR
int main(int argc, char *argv[])
{
char buffer[BUFSIZ+1];
SDL_SetError("Hi there!");
printf("Error 1: %s\n", SDL_GetError());
SDL_ClearError();
SDL_memset(buffer, '1', BUFSIZ);
buffer[BUFSIZ] = 0;
SDL_SetError("This is the error: %s (%f)", buffer, 1.0);
printf("Error 2: %s\n", SDL_GetError());
exit(0);
}
#endif