mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
tools/nolibc/printf: Special case 0 and add support for %#x
The output for %#x is almost the same as that for %p, both output in hexadecimal with a leading "0x". However for zero %#x should just output "0" (the same as decimal and ocal). For %p match glibc and output "(nil)" rather than "0x0" or "0". Add tests for "%#x", "% d", "%+d" and passing NULL to "%p". Signed-off-by: David Laight <david.laight.linux@gmail.com> Acked-by: Willy Tarreau <w@1wt.eu> Link: https://patch.msgid.link/20260308113742.12649-14-david.laight.linux@gmail.com [Thomas: fix up testcases for musl libc] Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
This commit is contained in:
committed by
Thomas Weißschuh
parent
a30d20588f
commit
5eae5f1a01
@@ -296,7 +296,7 @@ int fseek(FILE *stream, long offset, int whence)
|
||||
* - %% generates a single %
|
||||
* - %m outputs strerror(errno).
|
||||
* - %X outputs a..f the same as %x.
|
||||
* - The modifiers [#-0] are currently ignored.
|
||||
* - The modifiers [-0] are currently ignored.
|
||||
* - No support for precision or variable widths.
|
||||
* - No support for floating point or wide characters.
|
||||
* - Invalid formats are copied to the output buffer.
|
||||
@@ -410,8 +410,11 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
|
||||
* so that 'X' can be allowed through.
|
||||
* 'X' gets treated and 'x' because _NOLIBC_PF_FLAG() returns the same
|
||||
* value for both.
|
||||
*
|
||||
* We need to check for "%p" or "%#x" later, merging here gives better code.
|
||||
* But '#' collides with 'c' so shift right.
|
||||
*/
|
||||
ch_flag = _NOLIBC_PF_FLAG(ch);
|
||||
ch_flag = _NOLIBC_PF_FLAG(ch) | (flags & _NOLIBC_PF_FLAG('#')) >> 1;
|
||||
if (((ch >= 'a' && ch <= 'z') || ch == 'X') &&
|
||||
_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p', 's')) {
|
||||
/* 'long' is needed for pointer/string conversions and ltz lengths.
|
||||
@@ -471,17 +474,30 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
|
||||
*/
|
||||
out = outbuf + 2;
|
||||
|
||||
/* Convert the number to ascii in the required base. */
|
||||
if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) {
|
||||
/* Base 10 */
|
||||
len = u64toa_r(v, out);
|
||||
} else {
|
||||
/* Base 16 */
|
||||
if (v == 0) {
|
||||
/* There are special rules for zero. */
|
||||
if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p')) {
|
||||
/* "%p" needs "0x" prepending. */
|
||||
sign_prefix = '0' << 8 | 'x';
|
||||
/* "%p" match glibc, precision is ignored */
|
||||
outstr = "(nil)";
|
||||
len = 5;
|
||||
goto do_output;
|
||||
}
|
||||
/* All other formats (including "%#x") just output "0". */
|
||||
out[0] = '0';
|
||||
len = 1;
|
||||
} else {
|
||||
/* Convert the number to ascii in the required base. */
|
||||
if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) {
|
||||
/* Base 10 */
|
||||
len = u64toa_r(v, out);
|
||||
} else {
|
||||
/* Base 16 */
|
||||
if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p', '#' - 1)) {
|
||||
/* "%p" and "%#x" need "0x" prepending. */
|
||||
sign_prefix = '0' << 8 | 'x';
|
||||
}
|
||||
len = u64toh_r(v, out);
|
||||
}
|
||||
len = u64toh_r(v, out);
|
||||
}
|
||||
|
||||
/* Add the 0, 1 or 2 ("0x") sign/prefix characters at the front. */
|
||||
|
||||
Reference in New Issue
Block a user