From ce639810a7989c96ef837569b4bb2b45c085e1d1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 11 May 2006 21:03:23 +0000 Subject: [PATCH] Fixed some bugs in string handling Cleaned up error message code, UTF-8 is used instead of UCS2 Added detection for MPEG Layer 3 audio for more informative errors. --- src/SDL_error.c | 159 ++++++++++------------------------------ src/audio/SDL_wave.c | 5 ++ src/audio/SDL_wave.h | 1 + src/stdlib/SDL_string.c | 27 ++++--- 4 files changed, 58 insertions(+), 134 deletions(-) diff --git a/src/SDL_error.c b/src/SDL_error.c index 11d89b3d3..85777a63d 100644 --- a/src/SDL_error.c +++ b/src/SDL_error.c @@ -39,15 +39,10 @@ extern SDL_error *SDL_GetErrBuf(void); /* Private functions */ -static void SDL_LookupString(const Uint8 *key, Uint16 *buf, int buflen) +static const char *SDL_LookupString(const char *key) { /* FIXME: Add code to lookup key in language string hash-table */ - - /* Key not found in language string hash-table */ - while ( *key && (--buflen > 0) ) { - *buf++ = *key++; - } - *buf = 0; /* NULL terminate string */ + return key; } /* Public functions */ @@ -66,17 +61,20 @@ void SDL_SetError (const char *fmt, ...) error->argc = 0; while ( *fmt ) { if ( *fmt++ == '%' ) { + while ( *fmt == '.' || (*fmt >= '0' && *fmt <= '9') ) { + ++fmt; + } switch (*fmt++) { case 0: /* Malformed format string.. */ --fmt; break; -#if 0 /* What is a character anyway? (UNICODE issues) */ case 'c': - error->args[error->argc++].value_c = - va_arg(ap, unsigned char); - break; -#endif + case 'i': case 'd': + case 'u': + case 'o': + case 'x': + case 'X': error->args[error->argc++].value_i = va_arg(ap, int); break; @@ -114,124 +112,67 @@ void SDL_SetError (const char *fmt, ...) #endif } -/* Print out an integer value to a UNICODE buffer */ -static int PrintInt(Uint16 *str, unsigned int maxlen, int value) -{ - char tmp[128]; - int len, i; - - SDL_snprintf(tmp, SDL_arraysize(tmp), "%d", value); - len = 0; - if ( SDL_strlen(tmp) < maxlen ) { - for ( i=0; tmp[i]; ++i ) { - *str++ = tmp[i]; - ++len; - } - } - return(len); -} -/* Print out a double value to a UNICODE buffer */ -static int PrintDouble(Uint16 *str, unsigned int maxlen, double value) -{ - char tmp[128]; - int len, i; - - SDL_snprintf(tmp, SDL_arraysize(tmp), "%f", value); - len = 0; - if ( SDL_strlen(tmp) < maxlen ) { - for ( i=0; tmp[i]; ++i ) { - *str++ = tmp[i]; - ++len; - } - } - return(len); -} -/* Print out a pointer value to a UNICODE buffer */ -static int PrintPointer(Uint16 *str, unsigned int maxlen, void *value) -{ - char tmp[128]; - int len, i; - - SDL_snprintf(tmp, SDL_arraysize(tmp), "%p", value); - len = 0; - if ( SDL_strlen(tmp) < maxlen ) { - for ( i=0; tmp[i]; ++i ) { - *str++ = tmp[i]; - ++len; - } - } - return(len); -} - /* This function has a bit more overhead than most error functions so that it supports internationalization and thread-safe errors. */ -Uint16 *SDL_GetErrorMsgUNICODE(Uint16 *errstr, unsigned int maxlen) +char *SDL_GetErrorMsg(char *errstr, unsigned int maxlen) { SDL_error *error; /* Clear the error string */ - *errstr = 0; --maxlen; + *errstr = '\0'; --maxlen; /* Get the thread-safe error, and print it out */ error = SDL_GetErrBuf(); if ( error->error ) { - Uint16 translated[ERR_MAX_STRLEN], *fmt, *msg; + const char *fmt; + char *msg = errstr; int len; int argi; - /* Print out the UNICODE error message */ - SDL_LookupString(error->key, translated, sizeof(translated)); - msg = errstr; + fmt = SDL_LookupString(error->key); argi = 0; - for ( fmt=translated; *fmt && (maxlen > 0); ) { + while ( *fmt && (maxlen > 0) ) { if ( *fmt == '%' ) { - switch (fmt[1]) { - case 'S': /* Special SKIP operand */ - argi += (fmt[2] - '0'); - ++fmt; - break; + 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; -#if 0 /* What is a character anyway? (UNICODE issues) */ case 'c': - *msg++ = (unsigned char) - error->args[argi++].value_c; - maxlen -= 1; - break; -#endif - case 'd': - len = PrintInt(msg, maxlen, - error->args[argi++].value_i); + 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 = PrintDouble(msg, maxlen, - error->args[argi++].value_f); + len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_f); msg += len; maxlen -= len; break; case 'p': - len = PrintPointer(msg, maxlen, - error->args[argi++].value_ptr); + len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_ptr); msg += len; maxlen -= len; break; - case 's': /* UNICODE string */ - { Uint16 buf[ERR_MAX_STRLEN], *str; - SDL_LookupString(error->args[argi++].buf, buf, sizeof(buf)); - str = buf; - while ( *str && (maxlen > 0) ) { - *msg++ = *str++; - maxlen -= 1; - } - } + case 's': + len = SDL_snprintf(msg, maxlen, tmp, SDL_LookupString(error->args[argi++].buf)); + msg += len; + maxlen -= len; break; } - fmt += 2; } else { *msg++ = *fmt++; maxlen -= 1; @@ -242,32 +183,6 @@ Uint16 *SDL_GetErrorMsgUNICODE(Uint16 *errstr, unsigned int maxlen) return(errstr); } -Uint8 *SDL_GetErrorMsg(Uint8 *errstr, unsigned int maxlen) -{ - Uint16 *errstr16; - unsigned int i; - - /* Allocate the UNICODE buffer */ - errstr16 = (Uint16 *)SDL_malloc(maxlen * (sizeof *errstr16)); - if ( ! errstr16 ) { - SDL_strlcpy((char *)errstr, "Out of memory", maxlen); - return(errstr); - } - - /* Get the error message */ - SDL_GetErrorMsgUNICODE(errstr16, maxlen); - - /* Convert from UNICODE to Latin1 encoding */ - for ( i=0; iencoding)); + was_error = 1; + goto done; default: SDL_SetError("Unknown WAVE data format: 0x%.4x", SDL_SwapLE16(format->encoding)); diff --git a/src/audio/SDL_wave.h b/src/audio/SDL_wave.h index e01ea77bb..a0af6ebd8 100644 --- a/src/audio/SDL_wave.h +++ b/src/audio/SDL_wave.h @@ -35,6 +35,7 @@ #define PCM_CODE 0x0001 #define MS_ADPCM_CODE 0x0002 #define IMA_ADPCM_CODE 0x0011 +#define MP3_CODE 0x0055 #define WAVE_MONO 1 #define WAVE_STEREO 2 diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 3f2a1e280..b36b64998 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -985,10 +985,10 @@ static size_t SDL_PrintLong(char *text, long value, int radix, size_t maxlen) SDL_ltoa(value, num, radix); size = SDL_strlen(num); - if ( size > maxlen ) { - size = maxlen; + if ( size >= maxlen ) { + size = maxlen-1; } - SDL_strlcpy(text, num, size); + SDL_strlcpy(text, num, size+1); return size; } @@ -999,10 +999,10 @@ static size_t SDL_PrintUnsignedLong(char *text, unsigned long value, int radix, SDL_ultoa(value, num, radix); size = SDL_strlen(num); - if ( size > maxlen ) { - size = maxlen; + if ( size >= maxlen ) { + size = maxlen-1; } - SDL_strlcpy(text, num, size); + SDL_strlcpy(text, num, size+1); return size; } @@ -1014,10 +1014,10 @@ static size_t SDL_PrintLongLong(char *text, Sint64 value, int radix, size_t maxl SDL_lltoa(value, num, radix); size = SDL_strlen(num); - if ( size > maxlen ) { - size = maxlen; + if ( size >= maxlen ) { + size = maxlen-1; } - SDL_strlcpy(text, num, size); + SDL_strlcpy(text, num, size+1); return size; } @@ -1028,10 +1028,10 @@ static size_t SDL_PrintUnsignedLongLong(char *text, Uint64 value, int radix, siz SDL_ulltoa(value, num, radix); size = SDL_strlen(num); - if ( size > maxlen ) { - size = maxlen; + if ( size >= maxlen ) { + size = maxlen-1; } - SDL_strlcpy(text, num, size); + SDL_strlcpy(text, num, size+1); return size; } @@ -1101,6 +1101,9 @@ int SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap) ++fmt; /* FIXME: implement more of the format specifiers */ + while ( *fmt == '.' || (*fmt >= '0' && *fmt <= '9') ) { + ++fmt; + } while (!done) { switch(*fmt) { case '%':