libs/libc/stdio/lib_libvsprintf.c: Correct another discrepancy between NuttX printf() output and glibc printf() output.

This commit is contained in:
Gregory Nutt 2018-10-06 09:57:06 -06:00
parent 82d1c17cd8
commit 0487fa90f8
2 changed files with 85 additions and 82 deletions

21
TODO
View File

@ -1,4 +1,4 @@
NuttX TODO List (Last updated October 5, 2018) NuttX TODO List (Last updated October 6, 2018)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with This file summarizes known NuttX bugs, limitations, inconsistencies with
@ -22,7 +22,7 @@ nuttx/:
(18) Network (net/, drivers/net) (18) Network (net/, drivers/net)
(4) USB (drivers/usbdev, drivers/usbhost) (4) USB (drivers/usbdev, drivers/usbhost)
(2) Other drivers (drivers/) (2) Other drivers (drivers/)
(12) Libraries (libs/libc/, libs/libm/) (11) Libraries (libs/libc/, libs/libm/)
(11) File system/Generic drivers (fs/, drivers/) (11) File system/Generic drivers (fs/, drivers/)
(10) Graphics Subsystem (graphics/) (10) Graphics Subsystem (graphics/)
(1) Build system / Toolchains (1) Build system / Toolchains
@ -2044,23 +2044,6 @@ o File system / Generic drivers (fs/, drivers/)
Priority: Medium. It is certain a file system failure, but I think that Priority: Medium. It is certain a file system failure, but I think that
the exposure in real world uses cases is very small. the exposure in real world uses cases is very small.
Title: DISCREPANCY IN PRINTF OUTUPUT
Description: Under glibc, this printf statment:
printf("%05.3#x %05.3#x %05.3#x %05.3#x %05.3#x\n",
9, 99, 999, 9999, 99999);
Generates this output:
0x009 0x063 0x3e7 0x270f 0x1869f
But under NuttX, the same printf statement generates:
0x9 0x63 0x3e7 0x270f 0x1869f
Status: Open
Priority: Low. That is a very obscure use to case.
o Graphics Subsystem (graphics/) o Graphics Subsystem (graphics/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -185,9 +185,9 @@ static int getllusize(uint8_t fmt, FAR uint8_t flags,
#endif #endif
static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, int fieldwidth, int valwidth, uint8_t justify, uint8_t flags, int fieldwidth,
int trunc); int valwidth, int trunc);
static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, static void postjustify(FAR struct lib_outstream_s *obj, uint8_t justify,
uint8_t flags, int fieldwidth, int valwidth, uint8_t flags, int fieldwidth, int valwidth,
int trunc); int trunc);
@ -376,17 +376,11 @@ static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
case 'x': case 'x':
case 'X': case 'X':
{ {
/* Check for alternate form */ /* Convert the unsigned value to a string.
*
if (IS_ALTFORM(flags)) * NOTE that the alternate form prefix was already applied in
{ * prejustify().
/* Prefix the number with "0x" */ */
obj->put(obj, '0');
obj->put(obj, 'x');
}
/* Convert the unsigned value to a string. */
if (fmt == 'X') if (fmt == 'X')
{ {
@ -607,17 +601,11 @@ static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
case 'x': /* Hexadecimal */ case 'x': /* Hexadecimal */
case 'X': case 'X':
{ {
/* Check for alternate form */ /* Convert the unsigned value to a string.
*
if (IS_ALTFORM(flags)) * NOTE that the alternate form prefix was already applied in
{ * prejustify().
/* Prefix the number with "0x" */ */
obj->put(obj, '0');
obj->put(obj, 'x');
}
/* Convert the unsigned value to a string. */
if (fmt == 'X') if (fmt == 'X')
{ {
@ -822,17 +810,11 @@ static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
case 'x': /* Hexadecimal */ case 'x': /* Hexadecimal */
case 'X': case 'X':
{ {
/* Check for alternate form */ /* Convert the unsigned value to a string.
*
if (IS_ALTFORM(flags)) * NOTE that the alternate form prefix was already applied in
{ * prejustify().
/* Prefix the number with "0x" */ */
obj->put(obj, '0');
obj->put(obj, 'x');
}
/* Convert the unsigned value to a string. */
if (fmt == 'X') if (fmt == 'X')
{ {
@ -932,23 +914,24 @@ static int getllusize(uint8_t fmt, uint8_t flags, unsigned long long lln)
****************************************************************************/ ****************************************************************************/
static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, int fieldwidth, int valwidth, uint8_t justify, uint8_t flags, int fieldwidth,
int trunc) int valwidth, int trunc)
{ {
bool althex = (fmt == 'x' || fmt == 'X') && IS_ALTFORM(flags);
int i; int i;
/* If there is integer precision, then use FMT_RJUST vs FMT_RJUST0 */ /* If there is integer precision, then use FMT_RJUST vs FMT_RJUST0 */
if (trunc > 0 && fmt == FMT_RJUST0) if (trunc > 0 && justify == FMT_RJUST0)
{ {
/* Force right justification in the case. Leading zeros application /* Force right justification in the case. Leading zeros application
* only to "precision" which is implied anyway. * only to "precision" which is implied anyway.
*/ */
fmt = FMT_RJUST; justify = FMT_RJUST;
} }
switch (fmt) switch (justify)
{ {
default: default:
case FMT_RJUST: case FMT_RJUST:
@ -966,6 +949,11 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
padlen--; padlen--;
} }
if (althex)
{
padlen -= 2;
}
for (i = padlen; i > 0; i--) for (i = padlen; i > 0; i--)
{ {
obj->put(obj, ' '); obj->put(obj, ' ');
@ -980,6 +968,12 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
obj->put(obj, '+'); obj->put(obj, '+');
} }
if (althex)
{
obj->put(obj, '0');
obj->put(obj, 'x');
}
for (i = trunc - valwidth; i > 0; i--) for (i = trunc - valwidth; i > 0; i--)
{ {
obj->put(obj, '0'); obj->put(obj, '0');
@ -994,6 +988,11 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
valwidth++; valwidth++;
} }
if (althex)
{
valwidth += 2;
}
for (i = fieldwidth - valwidth; i > 0; i--) for (i = fieldwidth - valwidth; i > 0; i--)
{ {
obj->put(obj, ' '); obj->put(obj, ' ');
@ -1007,6 +1006,12 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
{ {
obj->put(obj, '+'); obj->put(obj, '+');
} }
if (althex)
{
obj->put(obj, '0');
obj->put(obj, 'x');
}
} }
} }
break; break;
@ -1024,6 +1029,13 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
valwidth++; valwidth++;
} }
if (althex)
{
obj->put(obj, '0');
obj->put(obj, 'x');
valwidth += 2;
}
for (i = fieldwidth - valwidth; i > 0; i--) for (i = fieldwidth - valwidth; i > 0; i--)
{ {
obj->put(obj, '0'); obj->put(obj, '0');
@ -1042,6 +1054,12 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
obj->put(obj, '+'); obj->put(obj, '+');
} }
if (althex)
{
obj->put(obj, '0');
obj->put(obj, 'x');
}
/* Pad with zeros up to the size of the value width. */ /* Pad with zeros up to the size of the value width. */
for (i = trunc - valwidth; i > 0; i--) for (i = trunc - valwidth; i > 0; i--)
@ -1057,7 +1075,7 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
* Name: postjustify * Name: postjustify
****************************************************************************/ ****************************************************************************/
static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, static void postjustify(FAR struct lib_outstream_s *obj, uint8_t justify,
uint8_t flags, int fieldwidth, int valwidth, uint8_t flags, int fieldwidth, int valwidth,
int trunc) int trunc)
{ {
@ -1065,7 +1083,7 @@ static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
/* Apply field justification to the integer value. */ /* Apply field justification to the integer value. */
switch (fmt) switch (justify)
{ {
default: default:
case FMT_RJUST: case FMT_RJUST:
@ -1106,7 +1124,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
FAR char *ptmp; FAR char *ptmp;
int width; int width;
int trunc; int trunc;
uint8_t fmt; uint8_t justify;
uint8_t flags; uint8_t flags;
#ifdef CONFIG_ARCH_ROMGETC #ifdef CONFIG_ARCH_ROMGETC
char ch; char ch;
@ -1142,10 +1160,10 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Assume defaults */ /* Assume defaults */
flags = 0; flags = 0;
fmt = FMT_RJUST; justify = FMT_RJUST;
width = 0; width = 0;
trunc = 0; trunc = 0;
/* Process each format qualifier. */ /* Process each format qualifier. */
@ -1162,21 +1180,21 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
else if (FMT_CHAR == '-') else if (FMT_CHAR == '-')
{ {
fmt = FMT_LJUST; justify = FMT_LJUST;
} }
/* Check for leading zero fill right justification. */ /* Check for leading zero fill right justification. */
else if (FMT_CHAR == '0') else if (FMT_CHAR == '0')
{ {
fmt = FMT_RJUST0; justify = FMT_RJUST0;
} }
#if 0 #if 0
/* Center justification. */ /* Center justification. */
else if (FMT_CHAR == '~') else if (FMT_CHAR == '~')
{ {
fmt = FMT_CENTER; justify = FMT_CENTER;
} }
#endif #endif
@ -1282,7 +1300,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
swidth = (IS_HASDOT(flags) && trunc >= 0) swidth = (IS_HASDOT(flags) && trunc >= 0)
? strnlen(ptmp, trunc) : strlen(ptmp); ? strnlen(ptmp, trunc) : strlen(ptmp);
prejustify(obj, fmt, 0, width, swidth, 0); prejustify(obj, FMT_CHAR, justify, 0, width, swidth, 0);
left = swidth; left = swidth;
/* Concatenate the string into the output */ /* Concatenate the string into the output */
@ -1300,7 +1318,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform left-justification operations. */ /* Perform left-justification operations. */
postjustify(obj, fmt, 0, width, swidth, 0); postjustify(obj, justify, 0, width, swidth, 0);
continue; continue;
} }
@ -1357,7 +1375,8 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform left field justification actions */ /* Perform left field justification actions */
prejustify(obj, fmt, flags, width, lluwidth, trunc); prejustify(obj, FMT_CHAR, justify, flags, width, lluwidth,
trunc);
/* Output the number */ /* Output the number */
@ -1365,7 +1384,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform right field justification actions */ /* Perform right field justification actions */
postjustify(obj, fmt, flags, width, lluwidth, trunc); postjustify(obj, justify, flags, width, lluwidth, trunc);
} }
else else
#endif /* CONFIG_HAVE_LONG_LONG */ #endif /* CONFIG_HAVE_LONG_LONG */
@ -1389,7 +1408,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform left field justification actions */ /* Perform left field justification actions */
prejustify(obj, fmt, flags, width, trunc); prejustify(obj, FMT_CHAR, justify, flags, width, trunc);
/* Output the number */ /* Output the number */
@ -1397,7 +1416,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform right field justification actions */ /* Perform right field justification actions */
postjustify(obj, fmt, flags, width, luwidth, trunc); postjustify(obj, justify, flags, width, luwidth, trunc);
} }
else else
#endif /* CONFIG_LONG_IS_NOT_INT */ #endif /* CONFIG_LONG_IS_NOT_INT */
@ -1421,7 +1440,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform left field justification actions */ /* Perform left field justification actions */
prejustify(obj, fmt, flags, width, pwidth, 0); prejustify(obj, FMT_CHAR, justify, flags, width, pwidth, 0);
/* Output the pointer value */ /* Output the pointer value */
@ -1429,7 +1448,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform right field justification actions */ /* Perform right field justification actions */
postjustify(obj, fmt, flags, width, pwidth, 0); postjustify(obj, justify, flags, width, pwidth, 0);
} }
else else
#endif #endif
@ -1451,7 +1470,8 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform left field justification actions */ /* Perform left field justification actions */
prejustify(obj, fmt, flags, width, uwidth, trunc); prejustify(obj, FMT_CHAR, justify, flags, width, uwidth,
trunc);
/* Output the number */ /* Output the number */
@ -1459,7 +1479,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform right field justification actions */ /* Perform right field justification actions */
postjustify(obj, fmt, flags, width, uwidth, trunc); postjustify(obj, justify, flags, width, uwidth, trunc);
} }
} }
@ -1477,7 +1497,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform left field justification actions */ /* Perform left field justification actions */
prejustify(obj, fmt, 0, width, dblsize, 0); prejustify(obj, FMT_CHAR, justify, 0, width, dblsize, 0);
/* Output the number */ /* Output the number */
@ -1485,7 +1505,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
/* Perform right field justification actions */ /* Perform right field justification actions */
postjustify(obj, fmt, 0, width, dblsize, 0); postjustify(obj, justify, 0, width, dblsize, 0);
} }
#endif /* CONFIG_LIBC_FLOATINGPOINT */ #endif /* CONFIG_LIBC_FLOATINGPOINT */
} }