summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-03-30 14:24:38 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-03-30 14:24:38 -0600
commitf469ebe852be64d8839117ee818ede523fc0b99f (patch)
treeff2a53e5c5f80280bde89a9b82ae02a9214b3d09
parent1272dfcdd4f1aaf5aca3066c130b17e160e6c82b (diff)
downloadnuttx-f469ebe852be64d8839117ee818ede523fc0b99f.tar.gz
nuttx-f469ebe852be64d8839117ee818ede523fc0b99f.tar.bz2
nuttx-f469ebe852be64d8839117ee818ede523fc0b99f.zip
sscanf(): Was returning the wrong number of conversions in many cases; Also, needs to return EOF if there were no conversions
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/libc/stdio/lib_sscanf.c27
2 files changed, 19 insertions, 11 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 635462d39..71baf68cf 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/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/nuttx/libc/stdio/lib_sscanf.c b/nuttx/libc/stdio/lib_sscanf.c
index b426c4cdf..1bf9c1ed8 100644
--- a/nuttx/libc/stdio/lib_sscanf.c
+++ b/nuttx/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;
}