casaroli opened a new pull request, #21730:
URL: https://github.com/apache/nuttx/pull/21730
depends-on: apache/nuttx/pull/21729
## Summary
scanf() took the `L` length modifier as `l`. For `%Lf`, `%Le` and `%Lg` it
stored a double through a `long double *`. Where a long double is not a double
(arm64, RISC-V 64, x86_64), the value was wrong and the other bytes kept their
old value: `sscanf("3.75", "%Lf", &ld)` gave inf on arm64. Now `L` sets the
length of `ll`. A floating point conversion with it calls strtold() and stores
a long double, and an integer conversion (`%Ld`) stores a long long, as in GNU
libc. #21474 made the same change in printf().
The first commit only fixes the older nxstyle errors of lib_libvscanf.c (the
case labels of the switch statements), so that the check job can pass. The
object code does not change, with and without CONFIG_LIBC_FLOATINGPOINT
(compared on arm64). The last commit updates the lib_bscanf() note in
Documentation/os/libs/libc/stream.rst, which said that `%Lf` is not supported.
## Impact
- C library only, the same in flat, protected and kernel builds. Without
CONFIG_HAVE_LONG_DOUBLE the floating point conversions do not change.
- strtold() is in lib_strtold.c with strtod() and strtof(). That file is
built when LIBM_NONE is not set, and LIBC_FLOATINGPOINT depends on !LIBM_NONE,
so every configuration that compiles the new call has the function, with every
LIBM choice.
- Behavior: `%Ld`, `%Li`, `%Lu` and `%Lx` store a long long (they stored a
long, which is smaller on a 32-bit CPU), and `%llf` stores a long double, as in
GNU libc. lib_bscanf() with `%Lf` now fills a long double field of the
structure.
- Size of lib_libvscanf.o text: +152 bytes on arm64, +96 bytes on Cortex-M4
(stm32f4discovery:nsh with LIBC_FLOATINGPOINT), +92 bytes on mps2-an500:knsh.
The image text of qemu-armv8a:nsh grows by 8 bytes, and stm32f4discovery:nsh
does not change.
## Testing
Two test programs: ldprintf.c (15 cases of the `L` modifier in printf() and
scanf()) and printfld.c (long double in the printf and scanf families, and
strtold(); `sscanf`, `fscanf` and `vsscanf` with `%Lf`, `%Le`, `%Lg`, widths,
`%*Lf`, mixed arguments, and text read back).
- qemu-armv8a:knsh (kernel build), LIBC_FLOATINGPOINT and
LIBC_NUMBERED_ARGS: master ldprintf 2 failed (scanf, scanf-whole), printfld 120
passed, 30 failed; this branch ldprintf 0 failed, printfld 148 passed, 2
failed. ostest exits with status 0.
- qemu-armv8a:nsh (flat), the tests as built-in applications: master
ldprintf 2 failed, printfld 122 passed, 31 failed; this branch ldprintf 0
failed, printfld 151 passed, 2 failed. ostest exits with status 0.
- rv-virt:knsh64 (RISC-V 64, kernel build, TCG), LIBC_FLOATINGPOINT,
LIBC_NUMBERED_ARGS, ELF_STACKSIZE 8192: master ldprintf 2 failed, printfld 120
passed, 30 failed; this branch ldprintf 0 failed, printfld 148 passed, 2
failed. ostest exits with status 0.
- Not run: x86_64 (its 80-bit long double).
- The 2 cases that still fail are not in this PR: swprintf() of a long
double, and the value that scanf() stores after a failed conversion.
- Built, not run: stm32f4discovery:nsh with LIBC_FLOATINGPOINT (flat,
Cortex-M4) and mps2-an500:knsh with LIBC_FLOATINGPOINT (protected).
- `tools/checkpatch.sh -c -u -m -g` passes.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]