Files
BC2D-POS-firmware/3rd-part/lwprintf/lwprintf.h

313 lines
13 KiB
C
Raw Normal View History

/**
* \file lwprintf.h
* \brief Lightweight stdio manager
*/
/*
* Copyright (c) 2024 Tilen MAJERLE
*
* 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.
*
* This file is part of LwPRINTF - Lightweight stdio manager library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v1.0.5
*/
#ifndef LWPRINTF_HDR_H
#define LWPRINTF_HDR_H
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include "lwprintf_opt.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* \defgroup LWPRINTF Lightweight stdio manager
* \brief Lightweight stdio manager
* \{
*/
/**
* \brief Unused variable macro
* \param[in] x: Unused variable
*/
#define LWPRINTF_UNUSED(x) ((void)(x))
/**
* \brief Calculate size of statically allocated array
* \param[in] x: Input array
* \return Number of array elements
*/
#define LWPRINTF_ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
/**
* \brief Forward declaration for LwPRINTF instance
*/
struct lwprintf;
/**
* \brief Callback function for character output
* \param[in] ch: Character to print
* \param[in] lwobj: LwPRINTF instance
* \return `ch` on success, `0` to terminate further string processing
*/
typedef int (*lwprintf_output_fn)(int ch, struct lwprintf* lwobj);
/**
* \brief LwPRINTF instance
*/
typedef struct lwprintf {
lwprintf_output_fn out_fn; /*!< Output function for direct print operations */
#if LWPRINTF_CFG_OS || __DOXYGEN__
LWPRINTF_CFG_OS_MUTEX_HANDLE mutex; /*!< OS mutex handle */
#endif /* LWPRINTF_CFG_OS || __DOXYGEN__ */
} lwprintf_t;
uint8_t lwprintf_init_ex(lwprintf_t* lwobj, lwprintf_output_fn out_fn);
int lwprintf_vprintf_ex(lwprintf_t* const lwobj, const char* format, va_list arg);
int lwprintf_printf_ex(lwprintf_t* const lwobj, const char* format, ...);
int lwprintf_vsnprintf_ex(lwprintf_t* const lwobj, char* s, size_t n, const char* format, va_list arg);
int lwprintf_snprintf_ex(lwprintf_t* const lwobj, char* s, size_t n, const char* format, ...);
uint8_t lwprintf_protect_ex(lwprintf_t* const lwobj);
uint8_t lwprintf_unprotect_ex(lwprintf_t* const lwobj);
/**
* \brief Write formatted data from variable argument list to sized buffer
* \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance
* \param[in] s: Pointer to a buffer where the resulting C-string is stored.
* The buffer should have a size of at least `n` characters
* \param[in] format: C string that contains a format string that follows the same specifications as format in printf
* \param[in] ...: Optional arguments for format string
* \return The number of characters that would have been written,
* not counting the terminating null character.
*/
#define lwprintf_sprintf_ex(lwobj, s, format, ...) lwprintf_snprintf_ex((lwobj), (s), SIZE_MAX, (format), ##__VA_ARGS__)
/**
* \brief Initialize default LwPRINTF instance
* \param[in] out_fn: Output function used for print operation
* \return `1` on success, `0` otherwise
* \sa lwprintf_init_ex
*/
#define lwprintf_init(out_fn) lwprintf_init_ex(NULL, (out_fn))
/**
* \brief Print formatted data from variable argument list to the output with default LwPRINTF instance
* \param[in] format: C string that contains the text to be written to output
* \param[in] arg: A value identifying a variable arguments list initialized with `va_start`.
* `va_list` is a special type defined in `<cstdarg>`.
* \return The number of characters that would have been written if `n` had been sufficiently large,
* not counting the terminating null character.
*/
#define lwprintf_vprintf(format, arg) lwprintf_vprintf_ex(NULL, (format), (arg))
/**
* \brief Print formatted data to the output with default LwPRINTF instance
* \param[in] format: C string that contains the text to be written to output
* \param[in] ...: Optional arguments for format string
* \return The number of characters that would have been written if `n` had been sufficiently large,
* not counting the terminating null character.
*/
#define lwprintf_printf(format, ...) lwprintf_printf_ex(NULL, (format), ##__VA_ARGS__)
/**
* \brief Write formatted data from variable argument list to sized buffer with default LwPRINTF instance
* \param[in] s: Pointer to a buffer where the resulting C-string is stored.
* The buffer should have a size of at least `n` characters
* \param[in] n: Maximum number of bytes to be used in the buffer.
* The generated string has a length of at most `n - 1`,
* leaving space for the additional terminating null character
* \param[in] format: C string that contains a format string that follows the same specifications as format in printf
* \param[in] arg: A value identifying a variable arguments list initialized with `va_start`.
* `va_list` is a special type defined in `<cstdarg>`.
* \return The number of characters that would have been written if `n` had been sufficiently large,
* not counting the terminating null character.
*/
#define lwprintf_vsnprintf(s, n, format, arg) lwprintf_vsnprintf_ex(NULL, (s), (n), (format), (arg))
/**
* \brief Write formatted data from variable argument list to sized buffer with default LwPRINTF instance
* \param[in] s: Pointer to a buffer where the resulting C-string is stored.
* The buffer should have a size of at least `n` characters
* \param[in] n: Maximum number of bytes to be used in the buffer.
* The generated string has a length of at most `n - 1`,
* leaving space for the additional terminating null character
* \param[in] format: C string that contains a format string that follows the same specifications as format in printf
* \param[in] ...: Optional arguments for format string
* \return The number of characters that would have been written if `n` had been sufficiently large,
* not counting the terminating null character.
*/
#define lwprintf_snprintf(s, n, format, ...) lwprintf_snprintf_ex(NULL, (s), (n), (format), ##__VA_ARGS__)
/**
* \brief Write formatted data from variable argument list to sized buffer with default LwPRINTF instance
* \param[in] s: Pointer to a buffer where the resulting C-string is stored.
* The buffer should have a size of at least `n` characters
* \param[in] format: C string that contains a format string that follows the same specifications as format in printf
* \param[in] ...: Optional arguments for format string
* \return The number of characters that would have been written,
* not counting the terminating null character.
*/
#define lwprintf_sprintf(s, format, ...) lwprintf_sprintf_ex(NULL, (s), (format), ##__VA_ARGS__)
/**
* \brief Manually enable mutual exclusion
* \return `1` if protected, `0` otherwise
*/
#define lwprintf_protect() lwprintf_protect_ex(NULL)
/**
* \brief Manually disable mutual exclusion
* \return `1` if protected, `0` otherwise
*/
#define lwprintf_unprotect() lwprintf_unprotect_ex(NULL)
#if LWPRINTF_CFG_ENABLE_SHORTNAMES || __DOXYGEN__
/**
* \copydoc lwprintf_printf
* \note This function is equivalent to \ref lwprintf_printf
* and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled
*/
#define lwprintf lwprintf_printf
/**
* \copydoc lwprintf_vprintf
* \note This function is equivalent to \ref lwprintf_vprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled
*/
#define lwvprintf lwprintf_vprintf
/**
* \copydoc lwprintf_vsnprintf
* \note This function is equivalent to \ref lwprintf_vsnprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled
*/
#define lwvsnprintf lwprintf_vsnprintf
/**
* \copydoc lwprintf_snprintf
* \note This function is equivalent to \ref lwprintf_snprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled
*/
#define lwsnprintf lwprintf_snprintf
/**
* \copydoc lwprintf_sprintf
* \note This function is equivalent to \ref lwprintf_sprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled
*/
#define lwsprintf lwprintf_sprintf
#endif /* LWPRINTF_CFG_ENABLE_SHORTNAMES || __DOXYGEN__ */
#if LWPRINTF_CFG_ENABLE_STD_NAMES || __DOXYGEN__
/**
* \copydoc lwprintf_printf
* \note This function is equivalent to \ref lwprintf_printf
* and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled
*/
#define printf lwprintf_printf
/**
* \copydoc lwprintf_vprintf
* \note This function is equivalent to \ref lwprintf_vprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled
*/
#define vprintf lwprintf_vprintf
/**
* \copydoc lwprintf_vsnprintf
* \note This function is equivalent to \ref lwprintf_vsnprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled
*/
#define vsnprintf lwprintf_vsnprintf
/**
* \copydoc lwprintf_snprintf
* \note This function is equivalent to \ref lwprintf_snprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled
*/
#define snprintf lwprintf_snprintf
/**
* \copydoc lwprintf_sprintf
* \note This function is equivalent to \ref lwprintf_sprintf
* and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled
*/
#define sprintf lwprintf_sprintf
#endif /* LWPRINTF_CFG_ENABLE_STD_NAMES || __DOXYGEN__ */
/* Debug module */
#if !defined(NDEBUG)
/**
* \brief Debug output function
*
* Its purpose is to have a debug printout to the defined output,
* which will get disabled for the release build (when NDEBUG is defined).
*
* \note It calls \ref lwprintf_printf to execute the print
* \note Defined as empty when \ref NDEBUG is enabled
* \param[in] fmt: Format text
* \param[in] ...: Optional formatting parameters
*/
#define lwprintf_debug(fmt, ...) lwprintf_printf((fmt), ##__VA_ARGS__)
/**
* \brief Conditional debug output
*
* It prints the formatted text only if condition is true
*
* Its purpose is to have a debug printout to the defined output,
* which will get disabled for the release build (when NDEBUG is defined).
*
* \note It calls \ref lwprintf_debug to execute the print
* \note Defined as empty when \ref NDEBUG is enabled
* \param[in] cond: Condition to check before outputing the message
* \param[in] fmt: Format text
* \param[in] ...: Optional formatting parameters
*/
#define lwprintf_debug_cond(cond, fmt, ...) \
do { \
if ((cond)) { \
lwprintf_debug((fmt), ##__VA_ARGS__) \
} \
} while (0)
#else
#define lwprintf_debug(fmt, ...) ((void)0)
#define lwprintf_debug_cond(cond, fmt, ...) ((void)0)
#endif
/**
* \}
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LWPRINTF_HDR_H */