diff --git a/ChangeLog b/ChangeLog index 635462d395..71baf68cf5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7084,4 +7084,7 @@ own file (2014-3-30). * arch/arm/src/sama5/sam_boot.c: Fix some backward conditional compilation (2014-3-30). + * libc/stdio/lib_sccanf.c: Fix a counting error in the return + value from sscanf(). Noted by kfrolov. Also, sscanf() should + return EOF if no values were converted (2014-3-30). diff --git a/libc/stdio/lib_sscanf.c b/libc/stdio/lib_sscanf.c index b426c4cdf7..1bf9c1ed83 100644 --- a/libc/stdio/lib_sscanf.c +++ b/libc/stdio/lib_sscanf.c @@ -271,7 +271,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) * update the 'ap' variable. */ - tv = NULL; /* To avoid warnings about beign uninitialized */ + tv = NULL; /* To avoid warnings about begin uninitialized */ if (!noassign) { tv = va_arg(ap, char*); @@ -307,6 +307,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) { strncpy(tv, buf, width); tv[width] = '\0'; + count++; } /* Update the buffer pointer past the string in the input */ @@ -339,7 +340,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) if (*buf) { - /* Was a fieldwidth specified? */ + /* Was a field width specified? */ if (!width) { @@ -354,6 +355,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) { strncpy(tv, buf, width); tv[width] = '\0'; + count++; } /* Update the buffer pointer past the character(s) in the @@ -396,7 +398,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) } } - /* But we only perform the data conversion is we still have + /* But we only perform the data conversion if we still have * bytes remaining in the input data stream. */ @@ -489,6 +491,8 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) tmplong, pint); *pint = (int)tmplong; } + + count++; } } } @@ -601,6 +605,8 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) lvdbg("vsscanf: Return %f to %p\n", dvalue, pf); *pf = (float)dvalue; } + + count++; } } #endif @@ -616,6 +622,8 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) { size_t nchars = (size_t)(buf - bufstart); + /* Note %n does not count as a conversion */ + if (lflag) { FAR long *plong = va_arg(ap, long*); @@ -629,13 +637,6 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) } } - /* Note %n does not count as a conversion */ - - if (!noassign && *fmt != 'n') - { - count++; - } - width = 0; noassign = false; lflag = false; @@ -674,5 +675,9 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) } } - return count; + /* sscanf is required to return EOF if the input ends before the first + * matching failure or conversion. + */ + + return count ? count : EOF; }