lib: cbprintf: add libc f/printf substitutes

This allows applications that may not use minimal libc avoid the cost
of a second printf-like formatting infrastructure by using printfcb()
instead of printf() for output.  It also helps make sure that the
formatting support (e.g. floats) is consistent between user-directed
output and the logging infrastructure.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2020-11-29 06:59:24 -06:00 committed by Anas Nashif
commit 8528e45897
3 changed files with 121 additions and 0 deletions

View file

@ -1966,6 +1966,7 @@ PREDEFINED = "CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT" \
"CONFIG_BT_USER_PHY_UPDATE" \ "CONFIG_BT_USER_PHY_UPDATE" \
"CONFIG_BT_SMP" \ "CONFIG_BT_SMP" \
"CONFIG_BT_SMP_APP_PAIRING_ACCEPT" \ "CONFIG_BT_SMP_APP_PAIRING_ACCEPT" \
"CONFIG_CBPRINTF_LIBC_SUBSTS" \
"CONFIG_ERRNO" \ "CONFIG_ERRNO" \
"CONFIG_FLASH_JESD216_API" \ "CONFIG_FLASH_JESD216_API" \
"CONFIG_FLASH_PAGE_LAYOUT" \ "CONFIG_FLASH_PAGE_LAYOUT" \

View file

@ -11,6 +11,10 @@
#include <stddef.h> #include <stddef.h>
#include <toolchain.h> #include <toolchain.h>
#ifdef CONFIG_CBPRINTF_LIBC_SUBSTS
#include <stdio.h>
#endif /* CONFIG_CBPRINTF_LIBC_SUBSTS */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -96,6 +100,84 @@ int cbprintf(cbprintf_cb out, void *ctx, const char *format, ...);
*/ */
int cbvprintf(cbprintf_cb out, void *ctx, const char *format, va_list ap); int cbvprintf(cbprintf_cb out, void *ctx, const char *format, va_list ap);
#ifdef CONFIG_CBPRINTF_LIBC_SUBSTS
/** @brief fprintf using Zephyrs cbprintf infrastructure.
*
* @note This function is available only when `CONFIG_CBPRINTF_LIBC_SUBSTS` is
* selected.
*
* @note The functionality of this function is significantly reduced
* when `CONFIG_CBPRINTF_NANO` is selected.
*
* @param stream the stream to which the output should be written.
*
* @param format a standard ISO C format string with characters and
* conversion specifications.
*
* @param ... arguments corresponding to the conversion specifications found
* within @p format.
*
* return The number of characters printed.
*/
__printf_like(2, 3)
int fprintfcb(FILE * stream, const char *format, ...);
/** @brief vfprintf using Zephyrs cbprintf infrastructure.
*
* @note This function is available only when `CONFIG_CBPRINTF_LIBC_SUBSTS` is
* selected.
*
* @note The functionality of this function is significantly reduced when
* `CONFIG_CBPRINTF_NANO` is selected.
*
* @param stream the stream to which the output should be written.
*
* @param format a standard ISO C format string with characters and conversion
* specifications.
*
* @param ap a reference to the values to be converted.
*
* @return The number of characters printed.
*/
int vfprintfcb(FILE *stream, const char *format, va_list ap);
/** @brief printf using Zephyrs cbprintf infrastructure.
*
* @note This function is available only when `CONFIG_CBPRINTF_LIBC_SUBSTS` is
* selected.
*
* @note The functionality of this function is significantly reduced
* when `CONFIG_CBPRINTF_NANO` is selected.
*
* @param format a standard ISO C format string with characters and
* conversion specifications.
*
* @param ... arguments corresponding to the conversion specifications found
* within @p format.
*
* @return The number of characters printed.
*/
__printf_like(1, 2)
int printfcb(const char *format, ...);
/** @brief vprintf using Zephyrs cbprintf infrastructure.
*
* @note This function is available only when `CONFIG_CBPRINTF_LIBC_SUBSTS` is
* selected.
*
* @note The functionality of this function is significantly reduced when
* `CONFIG_CBPRINTF_NANO` is selected.
*
* @param format a standard ISO C format string with characters and conversion
* specifications.
*
* @param ap a reference to the values to be converted.
*
* @return The number of characters printed.
*/
int vprintfcb(const char *format, va_list ap);
/** @brief snprintf using Zephyrs cbprintf infrastructure. /** @brief snprintf using Zephyrs cbprintf infrastructure.
* *
* @note This function is available only when `CONFIG_CBPRINTF_LIBC_SUBSTS` is * @note This function is available only when `CONFIG_CBPRINTF_LIBC_SUBSTS` is
@ -146,6 +228,8 @@ int snprintfcb(char *str, size_t size, const char *format, ...);
*/ */
int vsnprintfcb(char *str, size_t size, const char *format, va_list ap); int vsnprintfcb(char *str, size_t size, const char *format, va_list ap);
#endif /* CONFIG_CBPRINTF_LIBC_SUBSTS */
/** /**
* @} * @}
*/ */

View file

@ -22,6 +22,8 @@ int cbprintf(cbprintf_cb out, void *ctx, const char *format, ...)
#if defined(CONFIG_CBPRINTF_LIBC_SUBSTS) #if defined(CONFIG_CBPRINTF_LIBC_SUBSTS)
#include <stdio.h>
/* Context for sn* variants is the next space in the buffer, and the buffer /* Context for sn* variants is the next space in the buffer, and the buffer
* end. * end.
*/ */
@ -46,6 +48,40 @@ static int str_out(int c,
return c; return c;
} }
int fprintfcb(FILE *stream, const char *format, ...)
{
va_list ap;
int rc;
va_start(ap, format);
rc = vfprintfcb(stream, format, ap);
va_end(ap);
return rc;
}
int vfprintfcb(FILE *stream, const char *format, va_list ap)
{
return cbvprintf(fputc, stream, format, ap);
}
int printfcb(const char *format, ...)
{
va_list ap;
int rc;
va_start(ap, format);
rc = vprintfcb(format, ap);
va_end(ap);
return rc;
}
int vprintfcb(const char *format, va_list ap)
{
return cbvprintf(fputc, stdout, format, ap);
}
int snprintfcb(char *str, size_t size, const char *format, ...) int snprintfcb(char *str, size_t size, const char *format, ...)
{ {
va_list ap; va_list ap;