1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 10:03:50 +01:00
Marian Buschsieweke 4a84f6f58e
tests/sys/snprintf: use printf_long_long
This is required to support printing 64 bit numbers, as is done in the
test.

In addition that 64 bit formatting test is feature gated, so that users
can simply comment out the `USEMODULE += printf_long_long` to fit tiny
boards.

Co-authored-by: mguetschow <mikolai.guetschow@tu-dresden.de>
2025-08-21 12:08:10 +02:00

300 lines
7.4 KiB
C

/*
* Copyright (C) 2024 Marian Buschsieweke
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief snprintf test (correctness of standard format specifier
* implementation)
*
* @author Marian Buschsieweke <marian.buschsieweke@posteo.net>
*
* @}
*/
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "modules.h"
static bool failed = false;
static void check(const char *expected, const char *got, int retval)
{
if (retval != (int)strlen(expected)) {
failed = true;
printf("snprintf() returned %d, but expected %u\n",
retval, (unsigned)strlen(expected));
}
if (strcmp(expected, got) != 0) {
printf("Expected: \"%s\"\n"
"Got: \"%s\"\n",
expected, got);
failed = true;
}
}
static void test_int8(void)
{
static uint8_t u8 = 10;
static int8_t s8 = -3;
/* memory barrier to prevent the compiler from constant folding on the
* snprintf calls */
__asm__ volatile ("" ::: "memory");
char buf[32];
size_t len;
len = snprintf(buf, sizeof(buf), "%" PRIu8, u8);
check("10", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIx8, u8);
check("a", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIx8, u8);
check("0xa", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIX8, u8);
check("A", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIX8, u8);
check("0XA", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIo8, u8);
check("12", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIo8, u8);
check("012", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRId8, s8);
check("-3", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIi8, s8);
check("-3", buf, len);
}
static void test_int16(void)
{
static uint16_t u16 = 45054;
static int16_t s16 = -1337;
/* memory barrier to prevent the compiler from constant folding on the
* snprintf calls */
__asm__ volatile ("" ::: "memory");
char buf[32];
size_t len;
len = snprintf(buf, sizeof(buf), "%" PRIu16, u16);
check("45054", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIx16, u16);
check("affe", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIx16, u16);
check("0xaffe", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIX16, u16);
check("AFFE", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIX16, u16);
check("0XAFFE", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIo16, u16);
check("127776", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIo16, u16);
check("0127776", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRId16, s16);
check("-1337", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIi16, s16);
check("-1337", buf, len);
}
static void test_int32(void)
{
static uint32_t u32 = 2952663863;
static int32_t s32 = -2147483648;
/* memory barrier to prevent the compiler from constant folding on the
* snprintf calls */
__asm__ volatile ("" ::: "memory");
char buf[32];
size_t len;
len = snprintf(buf, sizeof(buf), "%" PRIu32, u32);
check("2952663863", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIx32, u32);
check("affe1337", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIx32, u32);
check("0xaffe1337", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIX32, u32);
check("AFFE1337", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIX32, u32);
check("0XAFFE1337", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIo32, u32);
check("25777411467", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIo32, u32);
check("025777411467", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRId32, s32);
check("-2147483648", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIi32, s32);
check("-2147483648", buf, len);
}
static void test_int64(void)
{
static uint64_t u64 = 16045690984050070327ULL;
static int64_t s64 = -9223372036854775807LL;
/* memory barrier to prevent the compiler from constant folding on the
* snprintf calls */
__asm__ volatile ("" ::: "memory");
char buf[32];
size_t len;
len = snprintf(buf, sizeof(buf), "%" PRIu64, u64);
check("16045690984050070327", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIx64, u64);
check("deadbeefaffe1337", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIx64, u64);
check("0xdeadbeefaffe1337", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIX64, u64);
check("DEADBEEFAFFE1337", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIX64, u64);
check("0XDEADBEEFAFFE1337", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIo64, u64);
check("1572555756765777411467", buf, len);
len = snprintf(buf, sizeof(buf), "%#" PRIo64, u64);
check("01572555756765777411467", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRId64, s64);
check("-9223372036854775807", buf, len);
len = snprintf(buf, sizeof(buf), "%" PRIi64, s64);
check("-9223372036854775807", buf, len);
}
static void test_size(void)
{
static size_t s = 42;
static ssize_t ss = -1;
static ptrdiff_t p = 1337;
/* memory barrier to prevent the compiler from constant folding on the
* snprintf calls */
__asm__ volatile ("" ::: "memory");
char buf[32];
size_t len;
len = snprintf(buf, sizeof(buf), "%zu", s);
check("42", buf, len);
len = snprintf(buf, sizeof(buf), "%zd", ss);
check("-1", buf, len);
len = snprintf(buf, sizeof(buf), "%td", p);
check("1337", buf, len);
len = snprintf(buf, sizeof(buf), "%tu", p);
check("1337", buf, len);
}
static void test_flags_widths(void)
{
static uint16_t u16 = 42;
static int16_t s16 = -42;
/* memory barrier to prevent the compiler from constant folding on the
* snprintf calls */
__asm__ volatile ("" ::: "memory");
char buf[32];
size_t len;
len = snprintf(buf, sizeof(buf), "%03" PRIu16, u16);
check("042", buf, len);
len = snprintf(buf, sizeof(buf), "%3" PRIu16, u16);
check(" 42", buf, len);
len = snprintf(buf, sizeof(buf), "%-3" PRIu16, u16);
check("42 ", buf, len);
len = snprintf(buf, sizeof(buf), "%*" PRIu16, 8, u16);
check(" 42", buf, len);
len = snprintf(buf, sizeof(buf), "%-*" PRIu16, 8, u16);
check("42 ", buf, len);
len = snprintf(buf, sizeof(buf), "%+" PRId16, (int16_t)u16);
check("+42", buf, len);
len = snprintf(buf, sizeof(buf), "%04" PRId16, s16);
check("-042", buf, len);
len = snprintf(buf, sizeof(buf), "%4" PRId16, s16);
check(" -42", buf, len);
len = snprintf(buf, sizeof(buf), "%-4" PRId16, s16);
check("-42 ", buf, len);
}
int main(void)
{
puts("Testing snprintf() implementation...");
test_int8();
test_int16();
test_int32();
if (IS_USED(MODULE_PRINTF_LONG_LONG)) {
test_int64();
}
else {
puts("WARNING: Module printf_long_long not used, skipping test for 64 bit");
}
test_size();
test_flags_widths();
if (failed) {
puts("TEST FAILED!");
}
else {
puts("Test succeeded");
}
return 0;
}