libc: switch to cbprintf as basis for printf functionality
The minimal libc provided by Zephyr can use the Zephyr system implementation rather than have its own implementation. When combined with CBPRINTF_NANO some sprintf tests must be skipped as they assume a more capable libc. Add an overlay that supports testing this non-default combination. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
f80c7bed5c
commit
7cf9a8c102
4 changed files with 85 additions and 51 deletions
|
@ -8,19 +8,17 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/cbprintf.h>
|
||||
|
||||
#define DESC(d) ((void *)d)
|
||||
|
||||
extern int z_prf(int (*func)(), void *dest,
|
||||
const char *format, va_list vargs);
|
||||
|
||||
int fprintf(FILE *_MLIBC_RESTRICT F, const char *_MLIBC_RESTRICT format, ...)
|
||||
{
|
||||
va_list vargs;
|
||||
int r;
|
||||
|
||||
va_start(vargs, format);
|
||||
r = z_prf(fputc, DESC(F), format, vargs);
|
||||
r = cbvprintf(fputc, DESC(F), format, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
return r;
|
||||
|
@ -31,7 +29,7 @@ int vfprintf(FILE *_MLIBC_RESTRICT F, const char *_MLIBC_RESTRICT format,
|
|||
{
|
||||
int r;
|
||||
|
||||
r = z_prf(fputc, DESC(F), format, vargs);
|
||||
r = cbvprintf(fputc, DESC(F), format, vargs);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -42,7 +40,7 @@ int printf(const char *_MLIBC_RESTRICT format, ...)
|
|||
int r;
|
||||
|
||||
va_start(vargs, format);
|
||||
r = z_prf(fputc, DESC(stdout), format, vargs);
|
||||
r = cbvprintf(fputc, DESC(stdout), format, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
return r;
|
||||
|
@ -52,7 +50,7 @@ int vprintf(const char *_MLIBC_RESTRICT format, va_list vargs)
|
|||
{
|
||||
int r;
|
||||
|
||||
r = z_prf(fputc, DESC(stdout), format, vargs);
|
||||
r = cbvprintf(fputc, DESC(stdout), format, vargs);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern int z_prf(int (*func)(), void *dest,
|
||||
const char *format, va_list vargs);
|
||||
#include <sys/cbprintf.h>
|
||||
|
||||
struct emitter {
|
||||
char *ptr;
|
||||
|
@ -44,7 +42,7 @@ int snprintf(char *_MLIBC_RESTRICT s, size_t len,
|
|||
p.len = (int) len;
|
||||
|
||||
va_start(vargs, format);
|
||||
r = z_prf(sprintf_out, (void *) (&p), format, vargs);
|
||||
r = cbvprintf(sprintf_out, (void *) (&p), format, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
*(p.ptr) = 0;
|
||||
|
@ -62,7 +60,7 @@ int sprintf(char *_MLIBC_RESTRICT s, const char *_MLIBC_RESTRICT format, ...)
|
|||
p.len = (int) 0x7fffffff; /* allow up to "maxint" characters */
|
||||
|
||||
va_start(vargs, format);
|
||||
r = z_prf(sprintf_out, (void *) (&p), format, vargs);
|
||||
r = cbvprintf(sprintf_out, (void *) (&p), format, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
*(p.ptr) = 0;
|
||||
|
@ -83,7 +81,7 @@ int vsnprintf(char *_MLIBC_RESTRICT s, size_t len,
|
|||
p.ptr = s;
|
||||
p.len = (int) len;
|
||||
|
||||
r = z_prf(sprintf_out, (void *) (&p), format, vargs);
|
||||
r = cbvprintf(sprintf_out, (void *) (&p), format, vargs);
|
||||
|
||||
*(p.ptr) = 0;
|
||||
return r;
|
||||
|
@ -98,7 +96,7 @@ int vsprintf(char *_MLIBC_RESTRICT s, const char *_MLIBC_RESTRICT format,
|
|||
p.ptr = s;
|
||||
p.len = (int) 0x7fffffff; /* allow up to "maxint" characters */
|
||||
|
||||
r = z_prf(sprintf_out, (void *) (&p), format, vargs);
|
||||
r = cbvprintf(sprintf_out, (void *) (&p), format, vargs);
|
||||
|
||||
*(p.ptr) = 0;
|
||||
return r;
|
||||
|
|
5
tests/lib/sprintf/cbprintf_nano.conf
Normal file
5
tests/lib/sprintf/cbprintf_nano.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
|
||||
CONFIG_CBPRINTF_FP_SUPPORT=n
|
||||
CONFIG_CBPRINTF_NANO=y
|
|
@ -27,6 +27,12 @@
|
|||
#define DEADBEEF_OCTAL_ALT_STR "033653337357"
|
||||
#define DEADBEEF_PTR_STR "0xdeadbeef"
|
||||
|
||||
#define IS_MINIMAL_LIBC_NANO (IS_ENABLED(CONFIG_MINIMAL_LIBC) \
|
||||
&& IS_ENABLED(CONFIG_CBPRINTF_NANO))
|
||||
|
||||
#define IS_MINIMAL_LIBC_NOFP (IS_ENABLED(CONFIG_MINIMAL_LIBC) \
|
||||
&& !IS_ENABLED(CONFIG_CBPRINTF_FP_SUPPORT))
|
||||
|
||||
/*
|
||||
* A really long string (330 characters + NULL).
|
||||
* The underlying sprintf() architecture will truncate it.
|
||||
|
@ -64,10 +70,18 @@ void test_sprintf_double(void)
|
|||
char buffer[400];
|
||||
union raw_double_u var;
|
||||
|
||||
#ifndef CONFIG_FPU
|
||||
ztest_test_skip();
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Conversion not supported with minimal_libc without
|
||||
* CBPRINTF_FP_SUPPORT.
|
||||
*
|
||||
* Conversion not supported without FPU except on native POSIX.
|
||||
*/
|
||||
if (IS_MINIMAL_LIBC_NOFP
|
||||
|| !(IS_ENABLED(CONFIG_FPU)
|
||||
|| IS_ENABLED(CONFIG_BOARD_NATIVE_POSIX))) {
|
||||
ztest_test_skip();
|
||||
return;
|
||||
}
|
||||
|
||||
var.u1 = 0x00000000;
|
||||
var.u2 = 0x7ff00000; /* Bit pattern for +INF (double) */
|
||||
|
@ -244,10 +258,14 @@ void test_sprintf_double(void)
|
|||
buffer[241]);
|
||||
|
||||
var.d = 0x1p-400;
|
||||
|
||||
/* 3.872E-121 expressed as " 0.0...387" */
|
||||
sprintf(buffer, "% .380f", var.d);
|
||||
zassert_true((strlen(buffer) == 383),
|
||||
"sprintf(<large output>) - incorrect length %d\n",
|
||||
strlen(buffer));
|
||||
zassert_equal(strncmp(&buffer[119], "00003872", 8), 0,
|
||||
"sprintf(<large output>) - misplaced value\n");
|
||||
buffer[10] = 0; /* log facility doesn't support %.10s */
|
||||
zassert_true((strcmp(buffer, " 0.0000000") == 0),
|
||||
"sprintf(<large output>) - starts with \"%s\" "
|
||||
|
@ -497,31 +515,37 @@ void test_sprintf_misc(void)
|
|||
zassert_false((strcmp(buffer, DEADBEEF_PTR_STR) != 0),
|
||||
"sprintf(%%p). Expected '%s', got '%s'", DEADBEEF_PTR_STR, buffer);
|
||||
/*******************/
|
||||
sprintf(buffer, "test data %n test data", &count);
|
||||
zassert_false((count != 10), "sprintf(%%n). Expected count to be %d, not %d",
|
||||
10, count);
|
||||
if (IS_MINIMAL_LIBC_NANO) {
|
||||
TC_PRINT(" MINIMAL_LIBC+CPBPRINTF skipped tests\n");
|
||||
} else {
|
||||
sprintf(buffer, "test data %n test data", &count);
|
||||
zassert_false((count != 10),
|
||||
"sprintf(%%n). Expected count to be %d, not %d",
|
||||
10, count);
|
||||
|
||||
zassert_false((strcmp(buffer, "test data test data") != 0),
|
||||
"sprintf(%%p). Expected '%s', got '%s'",
|
||||
"test data test data", buffer);
|
||||
zassert_false((strcmp(buffer, "test data test data") != 0),
|
||||
"sprintf(%%p). Expected '%s', got '%s'",
|
||||
"test data test data", buffer);
|
||||
|
||||
/*******************/
|
||||
sprintf(buffer, "%*d", 10, 1234);
|
||||
zassert_true((strcmp(buffer, " 1234") == 0),
|
||||
"sprintf(%%p). Expected '%s', got '%s'",
|
||||
" 1234", buffer);
|
||||
|
||||
/*******************/
|
||||
sprintf(buffer, "%*d", -10, 1234);
|
||||
zassert_true((strcmp(buffer, "1234 ") == 0),
|
||||
"sprintf(%%p). Expected '%s', got '%s'",
|
||||
"1234 ", buffer);
|
||||
/*******************/
|
||||
sprintf(buffer, "%*d", 10, 1234);
|
||||
zassert_true((strcmp(buffer, " 1234") == 0),
|
||||
"sprintf(%%p). Expected '%s', got '%s'",
|
||||
" 1234", buffer);
|
||||
|
||||
/*******************/
|
||||
sprintf(buffer, "% d", 1234);
|
||||
zassert_true((strcmp(buffer, " 1234") == 0),
|
||||
"sprintf(%% d). Expected '%s', got '%s'",
|
||||
" 1234", buffer);
|
||||
/*******************/
|
||||
sprintf(buffer, "%*d", -10, 1234);
|
||||
zassert_true((strcmp(buffer, "1234 ") == 0),
|
||||
"sprintf(%%p). Expected '%s', got '%s'",
|
||||
"1234 ", buffer);
|
||||
|
||||
/*******************/
|
||||
sprintf(buffer, "% d", 1234);
|
||||
zassert_true((strcmp(buffer, " 1234") == 0),
|
||||
"sprintf(%% d). Expected '%s', got '%s'",
|
||||
" 1234", buffer);
|
||||
}
|
||||
|
||||
/*******************/
|
||||
sprintf(buffer, "%hx", (unsigned short)1234);
|
||||
|
@ -572,9 +596,12 @@ void test_sprintf_integer(void)
|
|||
"sprintf(%%X). Expected %zu bytes written, not %d\n",
|
||||
strlen(DEADBEEF_UHEX_STR), len);
|
||||
|
||||
zassert_true((strcmp(buffer, DEADBEEF_UHEX_STR) == 0),
|
||||
"sprintf(%%X). Expected '%s', got '%s'\n",
|
||||
DEADBEEF_UHEX_STR, buffer);
|
||||
/* no upper-case hex support */
|
||||
if (!IS_MINIMAL_LIBC_NANO) {
|
||||
zassert_true((strcmp(buffer, DEADBEEF_UHEX_STR) == 0),
|
||||
"sprintf(%%X). Expected '%s', got '%s'\n",
|
||||
DEADBEEF_UHEX_STR, buffer);
|
||||
}
|
||||
|
||||
/*******************/
|
||||
len = sprintf(buffer, "%u", DEADBEEF);
|
||||
|
@ -596,15 +623,11 @@ void test_sprintf_integer(void)
|
|||
"sprintf(%%d). Expected '%s', got '%s'\n",
|
||||
DEADBEEF_SIGNED_STR, buffer);
|
||||
|
||||
/*******************/
|
||||
len = sprintf(buffer, "%o", DEADBEEF);
|
||||
zassert_true((len == strlen(DEADBEEF_OCTAL_STR)),
|
||||
"sprintf(%%o). Expected %zu bytes written, not %d\n",
|
||||
strlen(DEADBEEF_OCTAL_STR), len);
|
||||
|
||||
zassert_true((strcmp(buffer, DEADBEEF_OCTAL_STR) == 0),
|
||||
"sprintf(%%o). Expected '%s', got '%s'\n",
|
||||
DEADBEEF_OCTAL_STR, buffer);
|
||||
/* MINIMAL_LIBC+NANO doesn't support the following tests */
|
||||
if (IS_MINIMAL_LIBC_NANO) {
|
||||
TC_PRINT(" MINIMAL_LIBC+CBPRINTF_NANO skipped tests\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************/
|
||||
len = sprintf(buffer, "%#o", DEADBEEF);
|
||||
|
@ -616,6 +639,16 @@ void test_sprintf_integer(void)
|
|||
"sprintf(%%#o). Expected '%s', got '%s'\n",
|
||||
DEADBEEF_OCTAL_ALT_STR, buffer);
|
||||
|
||||
/*******************/
|
||||
len = sprintf(buffer, "%o", DEADBEEF);
|
||||
zassert_true((len == strlen(DEADBEEF_OCTAL_STR)),
|
||||
"sprintf(%%#o). Expected %zu bytes written, not %d\n",
|
||||
strlen(DEADBEEF_OCTAL_STR), len);
|
||||
|
||||
zassert_true((strcmp(buffer, DEADBEEF_OCTAL_STR) == 0),
|
||||
"sprintf(%%o). Expected '%s', got '%s'\n",
|
||||
DEADBEEF_OCTAL_STR, buffer);
|
||||
|
||||
/*******************/
|
||||
len = sprintf(buffer, "%#x", DEADBEEF);
|
||||
zassert_true((len == strlen(DEADBEEF_LHEX_ALT_STR)),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue