Fixed bug 3341 - SDL_sscanf() problem

e_pluschauskas

Why does SDL_sscanf() always returns the number of format specifiers and doesn't implements standard C library behavior?
Sam Lantinga 2017-08-11 19:36:12 -07:00
parent 1da252c2d8
commit 441d9ba2b0
1 changed files with 26 additions and 16 deletions

View File

@ -78,7 +78,7 @@ SDL_ScanLong(const char *text, int radix, long *valuep)
value += v; value += v;
++text; ++text;
} }
if (valuep) { if (valuep && text > textstart) {
if (negative && value) { if (negative && value) {
*valuep = -value; *valuep = -value;
} else { } else {
@ -114,7 +114,7 @@ SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep)
value += v; value += v;
++text; ++text;
} }
if (valuep) { if (valuep && text > textstart) {
*valuep = value; *valuep = value;
} }
return (text - textstart); return (text - textstart);
@ -146,7 +146,7 @@ SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep)
value += v; value += v;
++text; ++text;
} }
if (valuep) { if (valuep && text > textstart) {
*valuep = value; *valuep = value;
} }
return (text - textstart); return (text - textstart);
@ -183,7 +183,7 @@ SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)
value += v; value += v;
++text; ++text;
} }
if (valuep) { if (valuep && text > textstart) {
if (negative && value) { if (negative && value) {
*valuep = -value; *valuep = -value;
} else { } else {
@ -219,7 +219,7 @@ SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep)
value += v; value += v;
++text; ++text;
} }
if (valuep) { if (valuep && text > textstart) {
*valuep = value; *valuep = value;
} }
return (text - textstart); return (text - textstart);
@ -251,7 +251,7 @@ SDL_ScanFloat(const char *text, double *valuep)
++text; ++text;
} }
} }
if (valuep) { if (valuep && text > textstart) {
if (negative && value) { if (negative && value) {
*valuep = -value; *valuep = -value;
} else { } else {
@ -1025,6 +1025,10 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
{ {
int retval = 0; int retval = 0;
if (!text || !*text) {
return -1;
}
while (*fmt) { while (*fmt) {
if (*fmt == ' ') { if (*fmt == ' ') {
while (SDL_isspace((unsigned char) *text)) { while (SDL_isspace((unsigned char) *text)) {
@ -1044,6 +1048,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
DO_LONG, DO_LONG,
DO_LONGLONG DO_LONGLONG
} inttype = DO_INT; } inttype = DO_INT;
size_t advance;
SDL_bool suppress = SDL_FALSE; SDL_bool suppress = SDL_FALSE;
++fmt; ++fmt;
@ -1131,8 +1136,9 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
} }
} else { } else {
long value; long value;
text += SDL_ScanLong(text, radix, &value); advance = SDL_ScanLong(text, radix, &value);
if (!suppress) { text += advance;
if (advance && !suppress) {
switch (inttype) { switch (inttype) {
case DO_SHORT: case DO_SHORT:
{ {
@ -1175,16 +1181,18 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
case 'u': case 'u':
if (inttype == DO_LONGLONG) { if (inttype == DO_LONGLONG) {
Uint64 value; Uint64 value;
text += SDL_ScanUnsignedLongLong(text, radix, &value); advance = SDL_ScanUnsignedLongLong(text, radix, &value);
if (!suppress) { text += advance;
if (advance && !suppress) {
Uint64 *valuep = va_arg(ap, Uint64 *); Uint64 *valuep = va_arg(ap, Uint64 *);
*valuep = value; *valuep = value;
++retval; ++retval;
} }
} else { } else {
unsigned long value; unsigned long value;
text += SDL_ScanUnsignedLong(text, radix, &value); advance = SDL_ScanUnsignedLong(text, radix, &value);
if (!suppress) { text += advance;
if (advance && !suppress) {
switch (inttype) { switch (inttype) {
case DO_SHORT: case DO_SHORT:
{ {
@ -1216,8 +1224,9 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
case 'p': case 'p':
{ {
uintptr_t value; uintptr_t value;
text += SDL_ScanUintPtrT(text, 16, &value); advance = SDL_ScanUintPtrT(text, 16, &value);
if (!suppress) { text += advance;
if (advance && !suppress) {
void **valuep = va_arg(ap, void **); void **valuep = va_arg(ap, void **);
*valuep = (void *) value; *valuep = (void *) value;
++retval; ++retval;
@ -1228,8 +1237,9 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
case 'f': case 'f':
{ {
double value; double value;
text += SDL_ScanFloat(text, &value); advance = SDL_ScanFloat(text, &value);
if (!suppress) { text += advance;
if (advance && !suppress) {
float *valuep = va_arg(ap, float *); float *valuep = va_arg(ap, float *);
*valuep = (float) value; *valuep = (float) value;
++retval; ++retval;