lib: os: cbprintf: Add flags to CBPRINTF_MUST_RUNTIME_PACKAGE

Add flags to macro which checks if string must be packaged
using runtime approach.

Added flag CBPRINTF_MUST_RUNTIME_PACKAGE_CONST_CHAR. When flag
is set then const char pointers are considered as pointers to
fixed strings and do not require runtime packaging.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2021-11-29 08:49:57 +01:00 committed by Carles Cufí
commit 7831bfcce8
6 changed files with 58 additions and 33 deletions

View file

@ -358,7 +358,7 @@ do {\
_level, _data, _dlen, ...) \
do { \
Z_LOG_MSG2_STR_VAR(_fmt, ##__VA_ARGS__); \
if (CBPRINTF_MUST_RUNTIME_PACKAGE(_cstr_cnt, __VA_ARGS__)) { \
if (CBPRINTF_MUST_RUNTIME_PACKAGE(_cstr_cnt, 0, __VA_ARGS__)) { \
LOG_MSG2_DBG("create runtime message\n");\
z_log_msg2_runtime_create(_domain_id, (void *)_source, \
_level, (uint8_t *)_data, _dlen,\
@ -375,7 +375,7 @@ do { \
_level, _data, _dlen, ...) \
do { \
Z_LOG_MSG2_STR_VAR(_fmt, ##__VA_ARGS__); \
if (CBPRINTF_MUST_RUNTIME_PACKAGE(_cstr_cnt, __VA_ARGS__)) { \
if (CBPRINTF_MUST_RUNTIME_PACKAGE(_cstr_cnt, 0, __VA_ARGS__)) { \
LOG_MSG2_DBG("create runtime message\n");\
z_log_msg2_runtime_create(_domain_id, (void *)_source, \
_level, (uint8_t *)_data, _dlen,\

View file

@ -77,6 +77,19 @@ extern "C" {
/**@} */
/**@defgroup CBPRINTF_MUST_RUNTIME_PACKAGE_FLAGS Package flags.
* @{
*/
/** @brief Consider constant string pointers as pointing to fixed strings.
*
* When flag is set then const (w)char pointers arguments in the string does
* not trigger runtime packaging.
*/
#define CBPRINTF_MUST_RUNTIME_PACKAGE_CONST_CHAR BIT(0)
/**@} */
/** @brief Signature for a cbprintf callback function.
*
* This function expects two parameters:
@ -103,17 +116,22 @@ typedef int (*cbprintf_cb)(/* int c, void *ctx */);
* if there are no string arguments which might be copied into package body if
* they are considered transient.
*
* @note By default any char pointers are considered to be pointing at transient
* strings. This can be narrowed down to non const pointers by using
* @ref CBPRINTF_MUST_RUNTIME_PACKAGE_CONST_CHAR.
*
* @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.
* @param flags option flags. See @ref CBPRINTF_MUST_RUNTIME_PACKAGE_FLAGS.
*
* @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__)
#define CBPRINTF_MUST_RUNTIME_PACKAGE(skip, flags, ... /* fmt, ... */) \
Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, flags, __VA_ARGS__)
/** @brief Statically package string.
*

View file

@ -9,51 +9,57 @@
#ifdef __cplusplus
/* C++ version for detecting a pointer to a string. */
static inline int z_cbprintf_cxx_is_pchar(char *)
static inline int z_cbprintf_cxx_is_pchar(char *, bool const_as_fixed)
{
return 1;
}
static inline int z_cbprintf_cxx_is_pchar(const char *)
static inline int z_cbprintf_cxx_is_pchar(const char *, bool const_as_fixed)
{
return const_as_fixed ? 0 : 1;
}
static inline int z_cbprintf_cxx_is_pchar(volatile char *, bool const_as_fixed)
{
ARG_UNUSED(const_as_fixed);
return 1;
}
static inline int z_cbprintf_cxx_is_pchar(volatile char *)
static inline int z_cbprintf_cxx_is_pchar(const volatile char *, bool const_as_fixed)
{
ARG_UNUSED(const_as_fixed);
return 1;
}
static inline int z_cbprintf_cxx_is_pchar(const volatile char *)
static inline int z_cbprintf_cxx_is_pchar(wchar_t *, bool const_as_fixed)
{
ARG_UNUSED(const_as_fixed);
return 1;
}
static inline int z_cbprintf_cxx_is_pchar(wchar_t *)
static inline int z_cbprintf_cxx_is_pchar(const wchar_t *, bool const_as_fixed)
{
return const_as_fixed ? 0 : 1;
}
static inline int z_cbprintf_cxx_is_pchar(volatile wchar_t *, bool const_as_fixed)
{
ARG_UNUSED(const_as_fixed);
return 1;
}
static inline int z_cbprintf_cxx_is_pchar(const wchar_t *)
{
return 1;
}
static inline int z_cbprintf_cxx_is_pchar(volatile wchar_t *)
{
return 1;
}
static inline int z_cbprintf_cxx_is_pchar(const volatile wchar_t *)
static inline int z_cbprintf_cxx_is_pchar(const volatile wchar_t *, bool const_as_fixed)
{
ARG_UNUSED(const_as_fixed);
return 1;
}
template < typename T >
static inline int z_cbprintf_cxx_is_pchar(T arg)
static inline int z_cbprintf_cxx_is_pchar(T arg, bool const_as_fixed)
{
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"")
ARG_UNUSED(const_as_fixed);
return 0;
_Pragma("GCC diagnostic pop")
}

View file

@ -85,16 +85,17 @@ extern "C" {
* @return 1 if char * or wchar_t *, 0 otherwise.
*/
#ifdef __cplusplus
#define Z_CBPRINTF_IS_PCHAR(x) z_cbprintf_cxx_is_pchar(x)
#define Z_CBPRINTF_IS_PCHAR(x, flags) \
z_cbprintf_cxx_is_pchar(x, flags & CBPRINTF_MUST_RUNTIME_PACKAGE_CONST_CHAR)
#else
#define Z_CBPRINTF_IS_PCHAR(x) \
#define Z_CBPRINTF_IS_PCHAR(x, flags) \
_Generic((x) + 0, \
char * : 1, \
const char * : 1, \
const char * : (flags & CBPRINTF_MUST_RUNTIME_PACKAGE_CONST_CHAR) ? 0 : 1, \
volatile char * : 1, \
const volatile char * : 1, \
wchar_t * : 1, \
const wchar_t * : 1, \
const wchar_t * : (flags & CBPRINTF_MUST_RUNTIME_PACKAGE_CONST_CHAR) ? 0 : 1, \
volatile wchar_t * : 1, \
const volatile wchar_t * : 1, \
default : \
@ -109,8 +110,8 @@ extern "C" {
*
* @return number of arguments which are char * or wchar_t *.
*/
#define Z_CBPRINTF_HAS_PCHAR_ARGS(fmt, ...) \
(FOR_EACH(Z_CBPRINTF_IS_PCHAR, (+), __VA_ARGS__))
#define Z_CBPRINTF_HAS_PCHAR_ARGS(flags, fmt, ...) \
(FOR_EACH_FIXED_ARG(Z_CBPRINTF_IS_PCHAR, (+), flags, __VA_ARGS__))
/**
* @brief Check if formatted string must be packaged in runtime.
@ -124,17 +125,17 @@ extern "C" {
* @retval 0 if string can be statically packaged.
*/
#if Z_C_GENERIC
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) ({\
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, flags, ...) ({\
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") \
int _rv = COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
(0), \
(((Z_CBPRINTF_HAS_PCHAR_ARGS(__VA_ARGS__) - skip) > 0))); \
(((Z_CBPRINTF_HAS_PCHAR_ARGS(flags, __VA_ARGS__) - skip) > 0))); \
_Pragma("GCC diagnostic pop")\
_rv; \
})
#else
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) 1
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, flags, ...) 1
#endif
/** @brief Get storage size for given argument.
@ -271,7 +272,7 @@ do { \
_align_offset += sizeof(int); \
} \
uint32_t _arg_size = Z_CBPRINTF_ARG_SIZE(_arg); \
if (Z_CBPRINTF_IS_PCHAR(_arg)) { \
if (Z_CBPRINTF_IS_PCHAR(_arg, 0)) { \
_s_buf[_s_idx++] = _idx / sizeof(int); \
} \
if (_buf && _idx < (int)_max) { \

View file

@ -57,7 +57,7 @@ static void unpack(const char *desc, struct out_buffer *buf,
}
#define TEST_PACKAGING(fmt, ...) do { \
int must_runtime = CBPRINTF_MUST_RUNTIME_PACKAGE(0, fmt, __VA_ARGS__); \
int must_runtime = CBPRINTF_MUST_RUNTIME_PACKAGE(0, 0, fmt, __VA_ARGS__); \
zassert_equal(must_runtime, !Z_C_GENERIC, NULL); \
snprintfcb(compare_buf, sizeof(compare_buf), fmt, __VA_ARGS__); \
printk("-----------------------------------------\n"); \

View file

@ -294,7 +294,7 @@ static int rawprf(const char *format, ...)
#define TEST_PRF2(rc, _fmt, ...) do { \
char _buf[512]; \
char *sp_buf = NULL; /* static package buffer */\
if (USE_PACKAGED && !CBPRINTF_MUST_RUNTIME_PACKAGE(0, _fmt, __VA_ARGS__)) { \
if (USE_PACKAGED && !CBPRINTF_MUST_RUNTIME_PACKAGE(0, 0, _fmt, __VA_ARGS__)) { \
int rv = 0; \
size_t _len; \
struct out_buffer package_buf = { \