core: printf: switch to an enhanced version of embedded printf

This commit is contained in:
2025-09-22 10:30:40 +01:00
parent 072903f896
commit d52992c8ba
2 changed files with 1794 additions and 1016 deletions

View File

@@ -1,59 +1,161 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
// embedded systems with a very limited resources.
// Use this instead of bloated standard/newlib printf.
// These routines are thread safe and reentrant.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _PRINTF_H_
#define _PRINTF_H_
#include <stdarg.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* printf with output function
* You may use this as dynamic alternative to printf() with its fixed _putchar()
* output \param out An output function which takes one character and an
* argument pointer \param arg An argument pointer for user data passed to
* output function \param format A string that specifies the format of the
* output \return The number of characters that are sent to the output function,
* not counting the terminating null character
*/
int z__b_fctprintf(
void (*out)(char character, void *arg), void *arg, const char *format,
va_list va);
#ifdef __cplusplus
}
#endif
#endif // _PRINTF_H_
/**
* @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
* 2021-2023, Haifa, Palestine/Israel
* @author (c) Marco Paland (info@paland.com)
* 2014-2019, PALANDesign Hannover, Germany
*
* @note Others have made smaller contributions to this file: see the
* contributors page at https://github.com/eyalroz/printf/graphs/contributors
* or ask one of the authors.
*
* @brief Small stand-alone implementation of the printf family of functions
* (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems
* with a very limited resources.
*
* @note the implementations are thread-safe; re-entrant; use no functions from
* the standard library; and do not dynamically allocate any memory.
*
* @license The MIT License (MIT)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef PRINTF_H_
#define PRINTF_H_
#ifdef __cplusplus
#include <cstdarg>
#include <cstddef>
extern "C" {
#else
#include <stdarg.h>
#include <stddef.h>
#endif
#ifdef __GNUC__
#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4)
#define ATTR_PRINTF(one_based_format_index, first_arg) \
__attribute__((format(gnu_printf, (one_based_format_index), (first_arg))))
#else
#define ATTR_PRINTF(one_based_format_index, first_arg) \
__attribute__((format(printf, (one_based_format_index), (first_arg))))
#endif
#define ATTR_VPRINTF(one_based_format_index) \
ATTR_PRINTF((one_based_format_index), 0)
#else
#define ATTR_PRINTF(one_based_format_index, first_arg)
#define ATTR_VPRINTF(one_based_format_index)
#endif
#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_SOFT
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_SOFT 0
#endif
#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD 0
#endif
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD
#define printf_ printf
#define sprintf_ sprintf
#define vsprintf_ vsprintf
#define snprintf_ snprintf
#define vsnprintf_ vsnprintf
#define vprintf_ vprintf
#endif
// If you want to include this implementation file directly rather than
// link against it, this will let you control the functions' visibility,
// e.g. make them static so as not to clash with other objects also
// using them.
#ifndef PRINTF_VISIBILITY
#define PRINTF_VISIBILITY
#endif
/**
* Prints/send a single character to some opaque output entity
*
* @note This function is not implemented by the library, only declared; you
* must provide an implementation if you wish to use the @ref printf / @ref
* vprintf function (and possibly for linking against the library, if your
* toolchain does not support discarding unused functions)
*
* @note The output could be as simple as a wrapper for the `write()` system
* call on a Unix-like * system, or even libc's @ref putchar , for replicating
* actual functionality of libc's @ref printf * function; but on an embedded
* system it may involve interaction with a special output device, like a UART,
* etc.
*
* @note in libc's @ref putchar, the parameter type is an int; this was intended
* to support the representation of either a proper character or EOF in a
* variable - but this is really not meaningful to pass into @ref putchar and is
* discouraged today. See further discussion in:
* @link https://stackoverflow.com/q/17452847/1593077
*
* @param c the single character to print
*/
PRINTF_VISIBILITY
void putchar_(char c);
/**
* printf/vprintf with user-specified output function
*
* An alternative to @ref printf_, in which the output function is specified
* dynamically (rather than @ref putchar_ being used)
*
* @param out An output function which takes one character and a type-erased
* additional parameters
* @param extra_arg The type-erased argument to pass to the output function @p
* out with each call
* @param format A string specifying the format of the output, with %-marked
* specifiers of how to interpret additional arguments.
* @param arg Additional arguments to the function, one for each specifier in
* @p format
* @return The number of characters for which the output f unction was invoked,
* not counting the terminating null character
*
*/
PRINTF_VISIBILITY
int z__b_fctprintf(
void (*out)(char c, void *extra_arg), void *extra_arg,
const char *format, va_list arg) ATTR_VPRINTF(3);
#ifdef __cplusplus
} // extern "C"
#endif
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD
#undef printf_
#undef sprintf_
#undef vsprintf_
#undef snprintf_
#undef vsnprintf_
#undef vprintf_
#else
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_SOFT
#define printf printf_
#define sprintf sprintf_
#define vsprintf vsprintf_
#define snprintf snprintf_
#define vsnprintf vsnprintf_
#define vprintf vprintf_
#endif
#endif
#endif // PRINTF_H_