There might be a sign extension when a long is promoted to int_value_type and the former type is smaller than the later. This produces the wrong output if the specified format is unsigned. Let's avoid this problem by handling signed and unsigned cases explicitly. When the type already matches int_value_type then the compiler is smart enough to recognize the redundancy and removes unneeded duplications automatically, meaning that the code will stay small when code size matters. A similar issue also existed in the restricted %llu case. The fix is the same as above. Those fixes exposed wrong results in the printk.c test with %llx so fix that as well. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
159 lines
4.7 KiB
C
159 lines
4.7 KiB
C
/*
|
|
* Copyright (c) 2015 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <ztest.h>
|
|
|
|
#define BUF_SZ 1024
|
|
|
|
static int pos;
|
|
char pk_console[BUF_SZ];
|
|
|
|
void __printk_hook_install(int (*fn)(int));
|
|
void *__printk_get_hook(void);
|
|
int (*_old_char_out)(int);
|
|
|
|
#if defined(CONFIG_CBPRINTF_FULL_INTEGRAL)
|
|
char *expected = "22 113 10000 32768 40000 22\n"
|
|
"p 112 -10000 -32768 -40000 -22\n"
|
|
"0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
|
|
"0x1 0x 1 0x 1 0x 1\n"
|
|
"42 42 0042 00000042\n"
|
|
"-42 -42 -042 -0000042\n"
|
|
"42 42 42 42\n"
|
|
"42 42 0042 00000042\n"
|
|
"255 42 abcdef 42\n"
|
|
"68719476735 -1 18446744073709551615 ffffffffffffffff\n"
|
|
"0xcafebabe 0xbeef 0x2a\n"
|
|
;
|
|
#elif defined(CONFIG_CBPRINTF_COMPLETE)
|
|
char *expected = "22 113 10000 32768 40000 %llu\n"
|
|
"p 112 -10000 -32768 -40000 %lld\n"
|
|
"0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
|
|
"0x1 0x 1 0x 1 0x 1\n"
|
|
"42 42 0042 00000042\n"
|
|
"-42 -42 -042 -0000042\n"
|
|
"42 42 42 42\n"
|
|
"42 42 0042 00000042\n"
|
|
"255 42 abcdef 42\n"
|
|
"%lld %lld %llu %llx\n"
|
|
"0xcafebabe 0xbeef 0x2a\n"
|
|
;
|
|
#elif defined(CONFIG_CBPRINTF_NANO)
|
|
char *expected = "22 113 10000 32768 40000 22\n"
|
|
"p 112 -10000 -32768 -40000 -22\n"
|
|
"0x1 0x01 0x0001 0x00000001 0x0000000000000001\n"
|
|
"0x1 0x 1 0x 1 0x 1\n"
|
|
"42 42 0042 00000042\n"
|
|
"-42 -42 -042 -0000042\n"
|
|
"42 42 42 42\n"
|
|
"42 42 0042 00000042\n"
|
|
"255 42 abcdef 42\n"
|
|
"ERR -1 ERR ERR\n"
|
|
"0xcafebabe 0xbeef 0x2a\n"
|
|
;
|
|
#endif
|
|
|
|
size_t stv = 22;
|
|
unsigned char uc = 'q';
|
|
unsigned short int usi = 10000U;
|
|
unsigned int ui = 32768U;
|
|
unsigned long ul = 40000;
|
|
|
|
/* FIXME
|
|
* we know printk doesn't have full support for 64-bit values.
|
|
* at least show it can print uint64_t values less than 32-bits wide
|
|
*/
|
|
unsigned long long ull = 22;
|
|
|
|
char c = 'p';
|
|
signed short int ssi = -10000;
|
|
signed int si = -32768;
|
|
signed long sl = -40000;
|
|
signed long long sll = -22;
|
|
|
|
uint32_t hex = 0xCAFEBABE;
|
|
|
|
void *ptr = (void *)0xBEEF;
|
|
|
|
static int ram_console_out(int character)
|
|
{
|
|
pk_console[pos] = (char)character;
|
|
pos = (pos + 1) % BUF_SZ;
|
|
return _old_char_out(character);
|
|
}
|
|
/**
|
|
* @addtogroup kernel_common_tests
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Test printk() functionality
|
|
*
|
|
* @see printk(), __printk_get_hook(),
|
|
* __printk_hook_install(), snprintk()
|
|
*
|
|
*/
|
|
void test_printk(void)
|
|
{
|
|
int count;
|
|
|
|
if (IS_ENABLED(CONFIG_LOG_PRINTK)) {
|
|
ztest_test_skip();
|
|
}
|
|
|
|
_old_char_out = __printk_get_hook();
|
|
__printk_hook_install(ram_console_out);
|
|
|
|
printk("%zu %hhu %hu %u %lu %llu\n", stv, uc, usi, ui, ul, ull);
|
|
printk("%c %hhd %hd %d %ld %lld\n", c, c, ssi, si, sl, sll);
|
|
printk("0x%x 0x%02x 0x%04x 0x%08x 0x%016x\n", 1, 1, 1, 1, 1);
|
|
printk("0x%x 0x%2x 0x%4x 0x%8x\n", 1, 1, 1, 1);
|
|
printk("%d %02d %04d %08d\n", 42, 42, 42, 42);
|
|
printk("%d %02d %04d %08d\n", -42, -42, -42, -42);
|
|
printk("%u %2u %4u %8u\n", 42, 42, 42, 42);
|
|
printk("%u %02u %04u %08u\n", 42, 42, 42, 42);
|
|
printk("%-8u%-6d%-4x %8d\n", 0xFF, 42, 0xABCDEF, 42);
|
|
printk("%lld %lld %llu %llx\n", 0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
|
|
printk("0x%x %p %-2p\n", hex, ptr, (char *)42);
|
|
|
|
pk_console[pos] = '\0';
|
|
zassert_true((strcmp(pk_console, expected) == 0), "printk failed");
|
|
|
|
(void)memset(pk_console, 0, sizeof(pk_console));
|
|
count = 0;
|
|
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%zu %hhu %hu %u %lu %llu\n",
|
|
stv, uc, usi, ui, ul, ull);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%c %hhd %hd %d %ld %lld\n", c, c, ssi, si, sl, sll);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"0x%x 0x%02x 0x%04x 0x%08x 0x%016x\n", 1, 1, 1, 1, 1);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"0x%x 0x%2x 0x%4x 0x%8x\n", 1, 1, 1, 1);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%d %02d %04d %08d\n", 42, 42, 42, 42);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%d %02d %04d %08d\n", -42, -42, -42, -42);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%u %2u %4u %8u\n", 42, 42, 42, 42);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%u %02u %04u %08u\n", 42, 42, 42, 42);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%-8u%-6d%-4x %8d\n",
|
|
0xFF, 42, 0xABCDEF, 42);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"%lld %lld %llu %llx\n",
|
|
0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
|
|
count += snprintk(pk_console + count, sizeof(pk_console) - count,
|
|
"0x%x %p %-2p\n", hex, ptr, (char *)42);
|
|
pk_console[count] = '\0';
|
|
zassert_true((strcmp(pk_console, expected) == 0), "snprintk failed");
|
|
}
|
|
/**
|
|
* @}
|
|
*/
|