You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
485 lines
17 KiB
485 lines
17 KiB
/* |
|
* Copyright (c) 2020 Nordic Semiconductor ASA |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#ifndef ZEPHYR_INCLUDE_SYS_CBPRINTF_H_ |
|
#define ZEPHYR_INCLUDE_SYS_CBPRINTF_H_ |
|
|
|
#include <stdarg.h> |
|
#include <stddef.h> |
|
#include <stdint.h> |
|
#include <toolchain.h> |
|
|
|
#ifdef CONFIG_CBPRINTF_LIBC_SUBSTS |
|
#include <stdio.h> |
|
#endif /* CONFIG_CBPRINTF_LIBC_SUBSTS */ |
|
|
|
/* Determine if _Generic is supported. |
|
* In general it's a C11 feature but it was added also in: |
|
* - GCC 4.9.0 https://gcc.gnu.org/gcc-4.9/changes.html |
|
* - Clang 3.0 https://releases.llvm.org/3.0/docs/ClangReleaseNotes.html |
|
* |
|
* @note Z_C_GENERIC is also set for C++ where functionality is implemented |
|
* using overloading and templates. |
|
*/ |
|
#ifndef Z_C_GENERIC |
|
#if defined(__cplusplus) || (((__STDC_VERSION__ >= 201112L) || \ |
|
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40900) || \ |
|
((__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) >= 30000))) |
|
#define Z_C_GENERIC 1 |
|
#else |
|
#define Z_C_GENERIC 0 |
|
#endif |
|
#endif |
|
|
|
/* Z_C_GENERIC is used there */ |
|
#include <sys/cbprintf_internal.h> |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
/** |
|
* @defgroup cbprintf_apis Formatted Output APIs |
|
* @ingroup support_apis |
|
* @{ |
|
*/ |
|
|
|
/** @brief Required alignment of the buffer used for packaging. */ |
|
#ifdef __xtensa__ |
|
#define CBPRINTF_PACKAGE_ALIGNMENT 16 |
|
#elif defined(CONFIG_X86) && !defined(CONFIG_64BIT) |
|
/* sizeof(long double) is 12 on x86-32, which is not power of 2. |
|
* So set it manually. |
|
*/ |
|
#define CBPRINTF_PACKAGE_ALIGNMENT \ |
|
(IS_ENABLED(CONFIG_CBPRINTF_PACKAGE_LONGDOUBLE) ? \ |
|
16 : MAX(sizeof(double), sizeof(long long))) |
|
#else |
|
#define CBPRINTF_PACKAGE_ALIGNMENT \ |
|
(IS_ENABLED(CONFIG_CBPRINTF_PACKAGE_LONGDOUBLE) ? \ |
|
sizeof(long double) : MAX(sizeof(double), sizeof(long long))) |
|
#endif |
|
|
|
/**@defgroup CBPRINTF_PACKAGE_FLAGS Package flags. |
|
* @{ |
|
*/ |
|
|
|
/** @brief Append indexes of read-only string arguments in the package. |
|
* |
|
* When used, package contains locations of read-only string arguments. Package |
|
* with that information can be converted to fully self-contain package using |
|
* @ref cbprintf_fsc_package. |
|
*/ |
|
#define CBPRINTF_PACKAGE_ADD_STRING_IDXS BIT(0) |
|
|
|
/**@} */ |
|
|
|
/** @brief Signature for a cbprintf callback function. |
|
* |
|
* This function expects two parameters: |
|
* |
|
* * @p c a character to output. The output behavior should be as if |
|
* this was cast to an unsigned char. |
|
* * @p ctx a pointer to an object that provides context for the |
|
* output operation. |
|
* |
|
* The declaration does not specify the parameter types. This allows a |
|
* function like @c fputc to be used without requiring all context pointers to |
|
* be to a @c FILE object. |
|
* |
|
* @return the value of @p c cast to an unsigned char then back to |
|
* int, or a negative error code that will be returned from |
|
* cbprintf(). |
|
*/ |
|
typedef int (*cbprintf_cb)(/* int c, void *ctx */); |
|
|
|
/** @brief Determine if string must be packaged in run time. |
|
* |
|
* Static packaging can be applied if size of the package can be determined |
|
* at compile time. In general, package size can be determined at compile time |
|
* if there are no string arguments which might be copied into package body if |
|
* they are considered transient. |
|
* |
|
* @param skip number of read only string arguments in the parameter list. It |
|
* shall be non-zero if there are known read only string arguments present |
|
* in the string (e.g. function name prefix in the log message). |
|
* |
|
* @param ... String with arguments. |
|
* |
|
* @retval 1 if string must be packaged in run time. |
|
* @retval 0 string can be statically packaged. |
|
*/ |
|
#define CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ... /* fmt, ... */) \ |
|
Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, __VA_ARGS__) |
|
|
|
/** @brief Statically package string. |
|
* |
|
* Build string package from formatted string. It assumes that formatted |
|
* string is in the read only memory. |
|
* |
|
* If _Generic is not supported then runtime packaging is performed. |
|
* |
|
* @param packaged pointer to where the packaged data can be stored. Pass a null |
|
* pointer to skip packaging but still calculate the total space required. |
|
* The data stored here is relocatable, that is it can be moved to another |
|
* contiguous block of memory. It must be aligned to the size of the longest |
|
* argument. It is recommended to use CBPRINTF_PACKAGE_ALIGNMENT for alignment. |
|
* |
|
* @param inlen set to the number of bytes available at @p packaged. If |
|
* @p packaged is NULL the value is ignored. |
|
* |
|
* @param outlen variable updated to the number of bytes required to completely |
|
* store the packed information. If input buffer was too small it is set to |
|
* -ENOSPC. |
|
* |
|
* @param align_offset input buffer alignment offset in bytes. Where offset 0 |
|
* means that buffer is aligned to CBPRINTF_PACKAGE_ALIGNMENT. Xtensa requires |
|
* that @p packaged is aligned to CBPRINTF_PACKAGE_ALIGNMENT so it must be |
|
* multiply of CBPRINTF_PACKAGE_ALIGNMENT or 0. |
|
* |
|
* @param flags option flags. See @ref CBPRINTF_PACKAGE_FLAGS. |
|
* |
|
* @param ... formatted string with arguments. Format string must be constant. |
|
*/ |
|
#define CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, align_offset, flags, \ |
|
... /* fmt, ... */) \ |
|
Z_CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, \ |
|
align_offset, flags, __VA_ARGS__) |
|
|
|
/** @brief Capture state required to output formatted data later. |
|
* |
|
* Like cbprintf() but instead of processing the arguments and emitting the |
|
* formatted results immediately all arguments are captured so this can be |
|
* done in a different context, e.g. when the output function can block. |
|
* |
|
* In addition to the values extracted from arguments this will ensure that |
|
* copies are made of the necessary portions of any string parameters that are |
|
* not confirmed to be stored in read-only memory (hence assumed to be safe to |
|
* refer to directly later). |
|
* |
|
* @param packaged pointer to where the packaged data can be stored. Pass a |
|
* null pointer to store nothing but still calculate the total space required. |
|
* The data stored here is relocatable, that is it can be moved to another |
|
* contiguous block of memory. However, under condition that alignment is |
|
* maintained. It must be aligned to at least the size of a pointer. |
|
* |
|
* @param len this must be set to the number of bytes available at @p packaged |
|
* if it is not null. If @p packaged is null then it indicates hypothetical |
|
* buffer alignment offset in bytes compared to CBPRINTF_PACKAGE_ALIGNMENT |
|
* alignment. Buffer alignment offset impacts returned size of the package. |
|
* Xtensa requires that buffer is always aligned to CBPRINTF_PACKAGE_ALIGNMENT |
|
* so it must be multiply of CBPRINTF_PACKAGE_ALIGNMENT or 0 when @p packaged is |
|
* null. |
|
* |
|
* @param flags option flags. See @ref CBPRINTF_PACKAGE_FLAGS. |
|
* |
|
* @param format a standard ISO C format string with characters and conversion |
|
* specifications. |
|
* |
|
* @param ... arguments corresponding to the conversion specifications found |
|
* within @p format. |
|
* |
|
* @retval nonegative the number of bytes successfully stored at @p packaged. |
|
* This will not exceed @p len. |
|
* @retval -EINVAL if @p format is not acceptable |
|
* @retval -EFAULT if @p packaged alignment is not acceptable |
|
* @retval -ENOSPC if @p packaged was not null and the space required to store |
|
* exceed @p len. |
|
*/ |
|
__printf_like(4, 5) |
|
int cbprintf_package(void *packaged, |
|
size_t len, |
|
uint32_t flags, |
|
const char *format, |
|
...); |
|
|
|
/** @brief Capture state required to output formatted data later. |
|
* |
|
* Like cbprintf() but instead of processing the arguments and emitting the |
|
* formatted results immediately all arguments are captured so this can be |
|
* done in a different context, e.g. when the output function can block. |
|
* |
|
* In addition to the values extracted from arguments this will ensure that |
|
* copies are made of the necessary portions of any string parameters that are |
|
* not confirmed to be stored in read-only memory (hence assumed to be safe to |
|
* refer to directly later). |
|
* |
|
* @param packaged pointer to where the packaged data can be stored. Pass a |
|
* null pointer to store nothing but still calculate the total space required. |
|
* The data stored here is relocatable, that is it can be moved to another |
|
* contiguous block of memory. The pointer must be aligned to a multiple of |
|
* the largest element in the argument list. |
|
* |
|
* @param len this must be set to the number of bytes available at @p packaged. |
|
* Ignored if @p packaged is NULL. |
|
* |
|
* @param flags option flags. See @ref CBPRINTF_PACKAGE_FLAGS. |
|
* |
|
* @param format a standard ISO C format string with characters and conversion |
|
* specifications. |
|
* |
|
* @param ap captured stack arguments corresponding to the conversion |
|
* specifications found within @p format. |
|
* |
|
* @retval nonegative the number of bytes successfully stored at @p packaged. |
|
* This will not exceed @p len. |
|
* @retval -EINVAL if @p format is not acceptable |
|
* @retval -ENOSPC if @p packaged was not null and the space required to store |
|
* exceed @p len. |
|
*/ |
|
int cbvprintf_package(void *packaged, |
|
size_t len, |
|
uint32_t flags, |
|
const char *format, |
|
va_list ap); |
|
|
|
/** @brief Convert package to fully self-contained (fsc) package. |
|
* |
|
* By default, package does not contain read only strings. However, if needed |
|
* it may be converted to a fully self-contained package which contains all |
|
* strings. In order to allow such conversion, original package must be created |
|
* with @ref CBPRINTF_PACKAGE_ADD_STRING_IDXS flag. Such package will contain |
|
* necessary data to find read only strings in the package and copy them into |
|
* package body. |
|
* |
|
* @param in_packaged pointer to original package created with |
|
* @ref CBPRINTF_PACKAGE_ADD_STRING_IDXS. |
|
* |
|
* @param in_len @p in_packaged length. |
|
* |
|
* @param packaged pointer to location where fully self-contained version of the |
|
* input package will be written. Pass a null pointer to calculate space required. |
|
* |
|
* @param len must be set to the number of bytes available at @p packaged. Not |
|
* used if @p packaged is null. |
|
* |
|
* @retval nonegative the number of bytes successfully stored at @p packaged. |
|
* This will not exceed @p len. If @p packaged is null, calculated length. |
|
* @retval -ENOSPC if @p packaged was not null and the space required to store |
|
* exceed @p len. |
|
* @retval -EINVAL if @p in_packaged is null. |
|
*/ |
|
int cbprintf_fsc_package(void *in_packaged, |
|
size_t in_len, |
|
void *packaged, |
|
size_t len); |
|
|
|
/** @brief Generate the output for a previously captured format |
|
* operation. |
|
* |
|
* @param out the function used to emit each generated character. |
|
* |
|
* @param ctx context provided when invoking out |
|
* |
|
* @param packaged the data required to generate the formatted output, as |
|
* captured by cbprintf_package() or cbvprintf_package(). The alignment |
|
* requirement on this data is the same as when it was initially created. |
|
* |
|
* @note Memory indicated by @p packaged will be modified in a non-destructive |
|
* way, meaning that it could still be reused with this function again. |
|
* |
|
* @return the number of characters printed, or a negative error value |
|
* returned from invoking @p out. |
|
*/ |
|
int cbpprintf(cbprintf_cb out, |
|
void *ctx, |
|
void *packaged); |
|
|
|
/** @brief *printf-like output through a callback. |
|
* |
|
* This is essentially printf() except the output is generated |
|
* character-by-character using the provided @p out function. This allows |
|
* formatting text of unbounded length without incurring the cost of a |
|
* temporary buffer. |
|
* |
|
* All formatting specifiers of C99 are recognized, and most are supported if |
|
* the functionality is enabled. |
|
* |
|
* @note The functionality of this function is significantly reduced |
|
* when @kconfig{CONFIG_CBPRINTF_NANO} is selected. |
|
* |
|
* @param out the function used to emit each generated character. |
|
* |
|
* @param ctx context provided when invoking out |
|
* |
|
* @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, or a negative error value |
|
* returned from invoking @p out. |
|
*/ |
|
__printf_like(3, 4) |
|
int cbprintf(cbprintf_cb out, void *ctx, const char *format, ...); |
|
|
|
/** @brief varargs-aware *printf-like output through a callback. |
|
* |
|
* This is essentially vsprintf() except the output is generated |
|
* character-by-character using the provided @p out function. This allows |
|
* formatting text of unbounded length without incurring the cost of a |
|
* temporary buffer. |
|
* |
|
* @note This function is available only when |
|
* @kconfig{CONFIG_CBPRINTF_LIBC_SUBSTS} is selected. |
|
* |
|
* @note The functionality of this function is significantly reduced when |
|
* @kconfig{CONFIG_CBPRINTF_NANO} is selected. |
|
* |
|
* @param out the function used to emit each generated character. |
|
* |
|
* @param ctx context provided when invoking out |
|
* |
|
* @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 generated, or a negative error value |
|
* returned from invoking @p out. |
|
*/ |
|
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 |
|
* @kconfig{CONFIG_CBPRINTF_LIBC_SUBSTS} is selected. |
|
* |
|
* @note The functionality of this function is significantly reduced |
|
* when @kconfig{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 |
|
* @kconfig{CONFIG_CBPRINTF_LIBC_SUBSTS} is selected. |
|
* |
|
* @note The functionality of this function is significantly reduced when |
|
* @kconfig{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 |
|
* @kconfig{CONFIG_CBPRINTF_LIBC_SUBSTS} is selected. |
|
* |
|
* @note The functionality of this function is significantly reduced |
|
* when @kconfig{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 |
|
* @kconfig{CONFIG_CBPRINTF_LIBC_SUBSTS} is selected. |
|
* |
|
* @note The functionality of this function is significantly reduced when |
|
* @kconfig{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. |
|
* |
|
* @note This function is available only when |
|
* @kconfig{CONFIG_CBPRINTF_LIBC_SUBSTS} is selected. |
|
* |
|
* @note The functionality of this function is significantly reduced |
|
* when @kconfig{CONFIG_CBPRINTF_NANO} is selected. |
|
* |
|
* @param str where the formatted content should be written |
|
* |
|
* @param size maximum number of chaacters for the formatted output, |
|
* including the terminating null byte. |
|
* |
|
* @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 that would have been written to @p |
|
* str, excluding the terminating null byte. This is greater than the |
|
* number actually written if @p size is too small. |
|
*/ |
|
__printf_like(3, 4) |
|
int snprintfcb(char *str, size_t size, const char *format, ...); |
|
|
|
/** @brief vsnprintf using Zephyrs cbprintf infrastructure. |
|
* |
|
* @note This function is available only when |
|
* @kconfig{CONFIG_CBPRINTF_LIBC_SUBSTS} is selected. |
|
* |
|
* @note The functionality of this function is significantly reduced when |
|
* @kconfig{CONFIG_CBPRINTF_NANO} is selected. |
|
* |
|
* @param str where the formatted content should be written |
|
* |
|
* @param size maximum number of chaacters for the formatted output, including |
|
* the terminating null byte. |
|
* |
|
* @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 that would have been written to @p |
|
* str, excluding the terminating null byte. This is greater than the |
|
* number actually written if @p size is too small. |
|
*/ |
|
int vsnprintfcb(char *str, size_t size, const char *format, va_list ap); |
|
|
|
#endif /* CONFIG_CBPRINTF_LIBC_SUBSTS */ |
|
|
|
/** |
|
* @} |
|
*/ |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif /* ZEPHYR_INCLUDE_SYS_CBPRINTF_H_ */
|
|
|