Rewrite printf to always use callbacks

This commit is contained in:
Alex Kotov 2022-01-19 16:55:13 +05:00
parent 76a711840f
commit 000c26c7d7
2 changed files with 15 additions and 54 deletions

View File

@ -39,26 +39,18 @@ extern "C" {
#include <stdarg.h>
#include <stddef.h>
/**
* Output a character to a custom device like UART, used by the printf() function
* This function is declared here only. You have to write your custom implementation somewhere
* \param character Character to output
*/
void _putchar(char character);
/**
* Tiny printf/vprintf implementation
* You have to implement _putchar if you use printf()
* To avoid conflicts with the regular printf() API it is overridden by macro defines
* and internal underscore-appended functions like printf_() are used
* \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
* \param va A value identifying a variable arguments list
* \return The number of characters that are written into the array, not counting the terminating null character
* \return The number of characters that are sent to the output function, not counting the terminating null character
*/
#define printf printf_
#define vprintf vprintf_
int printf_(const char* format, ...);
int vprintf_(const char* format, va_list va);
int printf_(void (*out)(char character, void* arg), void* arg, const char* format, ...);
int vprintf_(void (*out)(char character, void* arg), void* arg, const char* format, va_list va);
/**
* Tiny sprintf implementation
@ -85,16 +77,6 @@ int sprintf_(char* buffer, const char* format, ...);
int snprintf_(char* buffer, size_t count, const char* format, ...);
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va);
/**
* 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 fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
#ifdef __cplusplus
}
#endif

View File

@ -130,16 +130,6 @@ static inline void _out_null(char character, void* buffer, size_t idx, size_t ma
}
// internal _putchar wrapper
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)buffer; (void)idx; (void)maxlen;
if (character) {
_putchar(character);
}
}
// internal output function wrapper
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
{
@ -844,17 +834,24 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
///////////////////////////////////////////////////////////////////////////////
int printf_(const char* format, ...)
int printf_(void (*out)(char character, void* arg), void* arg, const char* format, ...)
{
va_list va;
va_start(va, format);
char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
const out_fct_wrap_type out_fct_wrap = { out, arg };
const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
va_end(va);
return ret;
}
int vprintf_(void (*out)(char character, void* arg), void* arg, const char* format, va_list va)
{
const out_fct_wrap_type out_fct_wrap = { out, arg };
return _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
}
int sprintf_(char* buffer, const char* format, ...)
{
va_list va;
@ -875,25 +872,7 @@ int snprintf_(char* buffer, size_t count, const char* format, ...)
}
int vprintf_(const char* format, va_list va)
{
char buffer[1];
return _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
}
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va)
{
return _vsnprintf(_out_buffer, buffer, count, format, va);
}
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
{
va_list va;
va_start(va, format);
const out_fct_wrap_type out_fct_wrap = { out, arg };
const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
va_end(va);
return ret;
}