lib: os: cbprintf: Add support for conversion to fsc package
Added support for conversion from a standard package which contains pointers to read only strings to fully self-contained (fsc) package. Fsc package contains all strings associated with the package thus access to read only strings is not needed to format a string. In order to allow conversion to fsc package, standard package must contain locations of all string pointers within the package. Appending that information is optional and is controlled by flags parameter which was added to packaging API. If option flag is set then package contains header, arguments, locations of read only strings and transient strings (each prefixed with string argument location). Package header has been extended with field which contains number of read only string locations. A function for conversion to fsc package has been added (cbprintf_fsc_package()). Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
fbe13b7bc2
commit
5d80cbae59
8 changed files with 282 additions and 49 deletions
|
@ -219,12 +219,13 @@ enum z_log_msg2_mode {
|
|||
#define Z_LOG_MSG2_SYNC(_domain_id, _source, _level, _data, _dlen, ...) do { \
|
||||
int _plen; \
|
||||
CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, Z_LOG_MSG2_ALIGN_OFFSET, \
|
||||
__VA_ARGS__); \
|
||||
0, __VA_ARGS__); \
|
||||
struct log_msg2 *_msg; \
|
||||
Z_LOG_MSG2_ON_STACK_ALLOC(_msg, Z_LOG_MSG2_LEN(_plen, _dlen)); \
|
||||
if (_plen) {\
|
||||
CBPRINTF_STATIC_PACKAGE(_msg->data, _plen, _plen, \
|
||||
Z_LOG_MSG2_ALIGN_OFFSET, __VA_ARGS__); \
|
||||
Z_LOG_MSG2_ALIGN_OFFSET, \
|
||||
0, __VA_ARGS__); \
|
||||
} \
|
||||
struct log_msg2_desc _desc = \
|
||||
Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, \
|
||||
|
@ -238,15 +239,15 @@ do { \
|
|||
if (GET_ARG_N(1, __VA_ARGS__) == NULL) { \
|
||||
_plen = 0; \
|
||||
} else { \
|
||||
CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, \
|
||||
Z_LOG_MSG2_ALIGN_OFFSET, __VA_ARGS__); \
|
||||
CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, Z_LOG_MSG2_ALIGN_OFFSET, \
|
||||
0, __VA_ARGS__); \
|
||||
} \
|
||||
struct log_msg2 *_msg; \
|
||||
Z_LOG_MSG2_ON_STACK_ALLOC(_msg, Z_LOG_MSG2_LEN(_plen, 0)); \
|
||||
if (_plen) { \
|
||||
CBPRINTF_STATIC_PACKAGE(_msg->data, _plen, \
|
||||
_plen, Z_LOG_MSG2_ALIGN_OFFSET, \
|
||||
__VA_ARGS__);\
|
||||
0, __VA_ARGS__);\
|
||||
} \
|
||||
struct log_msg2_desc _desc = \
|
||||
Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, \
|
||||
|
@ -260,7 +261,7 @@ do { \
|
|||
#define Z_LOG_MSG2_SIMPLE_CREATE(_domain_id, _source, _level, ...) do { \
|
||||
int _plen; \
|
||||
CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, Z_LOG_MSG2_ALIGN_OFFSET, \
|
||||
__VA_ARGS__); \
|
||||
0, __VA_ARGS__); \
|
||||
size_t _msg_wlen = Z_LOG_MSG2_ALIGNED_WLEN(_plen, 0); \
|
||||
struct log_msg2 *_msg = z_log_msg2_alloc(_msg_wlen); \
|
||||
struct log_msg2_desc _desc = \
|
||||
|
@ -269,7 +270,8 @@ do { \
|
|||
_plen, _msg); \
|
||||
if (_msg) { \
|
||||
CBPRINTF_STATIC_PACKAGE(_msg->data, _plen, _plen, \
|
||||
Z_LOG_MSG2_ALIGN_OFFSET, __VA_ARGS__); \
|
||||
Z_LOG_MSG2_ALIGN_OFFSET, \
|
||||
0, __VA_ARGS__); \
|
||||
} \
|
||||
z_log_msg2_finalize(_msg, (void *)_source, _desc, NULL); \
|
||||
} while (0)
|
||||
|
|
|
@ -63,6 +63,20 @@ extern "C" {
|
|||
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:
|
||||
|
@ -98,7 +112,7 @@ typedef int (*cbprintf_cb)(/* int c, void *ctx */);
|
|||
* @retval 1 if string must be packaged in run time.
|
||||
* @retval 0 string can be statically packaged.
|
||||
*/
|
||||
#define CBPRINTF_MUST_RUNTIME_PACKAGE(skip, .../* fmt, ... */) \
|
||||
#define CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ... /* fmt, ... */) \
|
||||
Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, __VA_ARGS__)
|
||||
|
||||
/** @brief Statically package string.
|
||||
|
@ -126,12 +140,14 @@ typedef int (*cbprintf_cb)(/* int c, void *ctx */);
|
|||
* 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, \
|
||||
#define CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, align_offset, flags, \
|
||||
... /* fmt, ... */) \
|
||||
Z_CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, \
|
||||
align_offset, __VA_ARGS__)
|
||||
align_offset, flags, __VA_ARGS__)
|
||||
|
||||
/** @brief Capture state required to output formatted data later.
|
||||
*
|
||||
|
@ -158,6 +174,8 @@ typedef int (*cbprintf_cb)(/* int c, void *ctx */);
|
|||
* 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.
|
||||
*
|
||||
|
@ -171,9 +189,10 @@ typedef int (*cbprintf_cb)(/* int c, void *ctx */);
|
|||
* @retval -ENOSPC if @p packaged was not null and the space required to store
|
||||
* exceed @p len.
|
||||
*/
|
||||
__printf_like(3, 4)
|
||||
__printf_like(4, 5)
|
||||
int cbprintf_package(void *packaged,
|
||||
size_t len,
|
||||
uint32_t flags,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
|
@ -197,6 +216,8 @@ int cbprintf_package(void *packaged,
|
|||
* @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.
|
||||
*
|
||||
|
@ -211,9 +232,41 @@ int cbprintf_package(void *packaged,
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -259,7 +259,9 @@ extern "C" {
|
|||
*
|
||||
* @param _arg argument.
|
||||
*/
|
||||
#define Z_CBPRINTF_PACK_ARG2(_buf, _idx, _align_offset, _max, _arg) do { \
|
||||
#define Z_CBPRINTF_PACK_ARG2(_buf, _idx, _align_offset, _max, \
|
||||
_cfg_flags, _s_idx, _s_buf, _arg) \
|
||||
do { \
|
||||
BUILD_ASSERT(!((sizeof(double) < VA_STACK_ALIGN(long double)) && \
|
||||
Z_CBPRINTF_IS_LONGDOUBLE(_arg) && \
|
||||
!IS_ENABLED(CONFIG_CBPRINTF_PACKAGE_LONGDOUBLE)),\
|
||||
|
@ -269,6 +271,9 @@ extern "C" {
|
|||
_align_offset += sizeof(int); \
|
||||
} \
|
||||
uint32_t _arg_size = Z_CBPRINTF_ARG_SIZE(_arg); \
|
||||
if (Z_CBPRINTF_IS_PCHAR(_arg)) { \
|
||||
_s_buf[_s_idx++] = _idx / sizeof(int); \
|
||||
} \
|
||||
if (_buf && _idx < (int)_max) { \
|
||||
Z_CBPRINTF_STORE_ARG(&_buf[_idx], _arg); \
|
||||
} \
|
||||
|
@ -283,7 +288,8 @@ extern "C" {
|
|||
* @param arg argument.
|
||||
*/
|
||||
#define Z_CBPRINTF_PACK_ARG(arg) \
|
||||
Z_CBPRINTF_PACK_ARG2(_pbuf, _pkg_len, _pkg_offset, _pmax, arg)
|
||||
Z_CBPRINTF_PACK_ARG2(_pbuf, _pkg_len, _pkg_offset, _pmax, _flags, \
|
||||
_s_cnt, _s_buffer, arg)
|
||||
|
||||
/** @brief Package descriptor.
|
||||
*
|
||||
|
@ -294,6 +300,7 @@ extern "C" {
|
|||
struct z_cbprintf_desc {
|
||||
uint8_t len;
|
||||
uint8_t str_cnt;
|
||||
uint8_t ro_str_cnt;
|
||||
};
|
||||
|
||||
/** @brief Package header. */
|
||||
|
@ -325,10 +332,12 @@ union z_cbprintf_hdr {
|
|||
* @param _align_offset Input buffer alignment offset in words. Where offset 0
|
||||
* means that buffer is aligned to CBPRINTF_PACKAGE_ALIGNMENT.
|
||||
*
|
||||
* @param _flags Option flags. See @ref CBPRINTF_PACKAGE_FLAGS.
|
||||
*
|
||||
* @param ... String with variable list of arguments.
|
||||
*/
|
||||
#define Z_CBPRINTF_STATIC_PACKAGE_GENERIC(buf, _inlen, _outlen, _align_offset, \
|
||||
... /* fmt, ... */) \
|
||||
_flags, ... /* fmt, ... */) \
|
||||
do { \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") \
|
||||
|
@ -342,9 +351,13 @@ do { \
|
|||
IF_ENABLED(CONFIG_CBPRINTF_STATIC_PACKAGE_CHECK_ALIGNMENT, \
|
||||
(__ASSERT(!((uintptr_t)buf & (CBPRINTF_PACKAGE_ALIGNMENT - 1)), \
|
||||
"Buffer must be aligned.");)) \
|
||||
bool str_idxs = _flags & CBPRINTF_PACKAGE_ADD_STRING_IDXS; \
|
||||
uint8_t *_pbuf = buf; \
|
||||
uint8_t _s_cnt = 0; \
|
||||
uint16_t _s_buffer[16]; \
|
||||
size_t _pmax = (buf != NULL) ? _inlen : INT32_MAX; \
|
||||
int _pkg_len = 0; \
|
||||
int _total_len = 0; \
|
||||
int _pkg_offset = _align_offset; \
|
||||
union z_cbprintf_hdr *_len_loc; \
|
||||
/* package starts with string address and field with length */ \
|
||||
|
@ -357,14 +370,24 @@ do { \
|
|||
_pkg_offset += sizeof(union z_cbprintf_hdr); \
|
||||
/* Pack remaining arguments */\
|
||||
FOR_EACH(Z_CBPRINTF_PACK_ARG, (;), __VA_ARGS__);\
|
||||
_total_len = _pkg_len; \
|
||||
if (str_idxs) {\
|
||||
_total_len += _s_cnt; \
|
||||
if (_pbuf) { \
|
||||
for (int i = 0; i < _s_cnt; i++) { \
|
||||
_pbuf[_pkg_len + i] = _s_buffer[i]; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
/* Store length */ \
|
||||
_outlen = (_pkg_len > (int)_pmax) ? -ENOSPC : _pkg_len; \
|
||||
_outlen = (_total_len > (int)_pmax) ? -ENOSPC : _total_len; \
|
||||
/* Store length in the header, set number of dumped strings to 0 */ \
|
||||
if (_pbuf) { \
|
||||
union z_cbprintf_hdr hdr = { \
|
||||
.desc = { \
|
||||
.len = (uint8_t)(_pkg_len / sizeof(int)), \
|
||||
.str_cnt = 0, \
|
||||
.ro_str_cnt = str_idxs ? _s_cnt : (uint8_t)0, \
|
||||
} \
|
||||
}; \
|
||||
*_len_loc = hdr; \
|
||||
|
@ -373,19 +396,19 @@ do { \
|
|||
} while (0)
|
||||
|
||||
#if Z_C_GENERIC
|
||||
#define Z_CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, align_offset, \
|
||||
#define Z_CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, align_offset, flags, \
|
||||
... /* fmt, ... */) \
|
||||
Z_CBPRINTF_STATIC_PACKAGE_GENERIC(packaged, inlen, outlen, \
|
||||
align_offset, __VA_ARGS__)
|
||||
align_offset, flags, __VA_ARGS__)
|
||||
#else
|
||||
#define Z_CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, align_offset, \
|
||||
#define Z_CBPRINTF_STATIC_PACKAGE(packaged, inlen, outlen, align_offset, flags, \
|
||||
... /* fmt, ... */) \
|
||||
do { \
|
||||
/* Small trick needed to avoid warning on always true */ \
|
||||
if (((uintptr_t)packaged + 1) != 1) { \
|
||||
outlen = cbprintf_package(packaged, inlen, __VA_ARGS__); \
|
||||
outlen = cbprintf_package(packaged, inlen, flags, __VA_ARGS__); \
|
||||
} else { \
|
||||
outlen = cbprintf_package(NULL, align_offset, __VA_ARGS__); \
|
||||
outlen = cbprintf_package(NULL, align_offset, flags, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* Z_C_GENERIC */
|
||||
|
|
|
@ -185,11 +185,18 @@ static int cbprintf_via_va_list(cbprintf_cb out, void *ctx,
|
|||
|
||||
#endif
|
||||
|
||||
int cbvprintf_package(void *packaged, size_t len,
|
||||
int cbvprintf_package(void *packaged, size_t len, uint32_t flags,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
/* Internally, byte is used to store location of a string argument within a
|
||||
* package. MSB bit is set if string is read-only so effectively 7 bits are
|
||||
* used for index, which should be enough.
|
||||
*/
|
||||
#define CBPRINTF_STR_POS_RO_FLAG BIT(7)
|
||||
#define CBPRINTF_STR_POS_MASK BIT_MASK(7)
|
||||
|
||||
char *buf = packaged, *buf0 = buf;
|
||||
unsigned int align, size, i, s_idx = 0;
|
||||
unsigned int align, size, i, s_idx = 0, s_rw_cnt = 0, s_ro_cnt = 0;
|
||||
uint8_t str_ptr_pos[16];
|
||||
const char *s;
|
||||
bool parsing = false;
|
||||
|
@ -395,9 +402,18 @@ process_string:
|
|||
if (buf0) {
|
||||
*(const char **)buf = s;
|
||||
}
|
||||
if (ptr_in_rodata(s)) {
|
||||
|
||||
/* Bother about read only strings only if storing
|
||||
* string indexes is requested.
|
||||
*/
|
||||
bool is_ro = ptr_in_rodata(s);
|
||||
bool str_idxs = flags & CBPRINTF_PACKAGE_ADD_STRING_IDXS;
|
||||
bool need_ro = is_ro && str_idxs;
|
||||
|
||||
if (ptr_in_rodata(s) && !str_idxs) {
|
||||
/* do nothing special */
|
||||
} else if (buf0) {
|
||||
|
||||
/*
|
||||
* Remember string pointer location.
|
||||
* We will append it later.
|
||||
|
@ -406,14 +422,39 @@ process_string:
|
|||
__ASSERT(false, "str_ptr_pos[] too small");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Use same multiple as the arg list size. */
|
||||
str_ptr_pos[s_idx++] = (buf - buf0) / sizeof(int);
|
||||
|
||||
if ((buf - buf0) > CBPRINTF_STR_POS_MASK) {
|
||||
__ASSERT(false, "String with too many arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Add marking to identify if read only string. */
|
||||
uint8_t ro_flag = need_ro ?
|
||||
CBPRINTF_STR_POS_RO_FLAG : 0;
|
||||
|
||||
if (ro_flag) {
|
||||
s_ro_cnt++;
|
||||
} else {
|
||||
s_rw_cnt++;
|
||||
}
|
||||
|
||||
/* Use same multiple as the arg list size. */
|
||||
str_ptr_pos[s_idx++] = ro_flag |
|
||||
(buf - buf0) / sizeof(int);
|
||||
} else {
|
||||
if (!is_ro) {
|
||||
/*
|
||||
* Add the string length, the final '\0'
|
||||
* and size of the pointer position prefix.
|
||||
*/
|
||||
len += strlen(s) + 1 + 1;
|
||||
} else if (need_ro) {
|
||||
/*
|
||||
* Add only pointer position prefix for
|
||||
* read only string is requested.
|
||||
*/
|
||||
len += 1;
|
||||
}
|
||||
}
|
||||
buf += sizeof(char *);
|
||||
} else if (size == sizeof(int)) {
|
||||
|
@ -471,10 +512,34 @@ process_string:
|
|||
|
||||
/* Record end of argument list and number of appended strings. */
|
||||
buf0[0] = (buf - buf0) / sizeof(int);
|
||||
buf0[1] = s_idx;
|
||||
buf0[1] = s_rw_cnt;
|
||||
buf0[2] = s_ro_cnt;
|
||||
|
||||
/* Store strings pointer locations of read only strings. */
|
||||
if (s_ro_cnt) {
|
||||
for (i = 0; i < s_idx; i++) {
|
||||
if (!(str_ptr_pos[i] & CBPRINTF_STR_POS_RO_FLAG)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t pos = str_ptr_pos[i] & CBPRINTF_STR_POS_MASK;
|
||||
|
||||
/* make sure it fits */
|
||||
if (buf - buf0 + 1 > len) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
/* store the pointer position prefix */
|
||||
*buf++ = pos;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store strings prefixed by their pointer location. */
|
||||
for (i = 0; i < s_idx; i++) {
|
||||
/* Process only RW strings. */
|
||||
if (str_ptr_pos[i] & CBPRINTF_STR_POS_RO_FLAG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* retrieve the string pointer */
|
||||
s = *(char **)(buf0 + str_ptr_pos[i] * sizeof(int));
|
||||
/* clear the in-buffer pointer (less entropy if compressed) */
|
||||
|
@ -498,15 +563,19 @@ process_string:
|
|||
*/
|
||||
|
||||
return buf - buf0;
|
||||
|
||||
#undef CBPRINTF_STR_POS_RO_FLAG
|
||||
#undef CBPRINTF_STR_POS_MASK
|
||||
}
|
||||
|
||||
int cbprintf_package(void *packaged, size_t len, const char *format, ...)
|
||||
int cbprintf_package(void *packaged, size_t len, uint32_t flags,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, format);
|
||||
ret = cbvprintf_package(packaged, len, format, ap);
|
||||
ret = cbvprintf_package(packaged, len, flags, format, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
@ -514,7 +583,7 @@ int cbprintf_package(void *packaged, size_t len, const char *format, ...)
|
|||
int cbpprintf(cbprintf_cb out, void *ctx, void *packaged)
|
||||
{
|
||||
char *buf = packaged, *fmt, *s, **ps;
|
||||
unsigned int i, args_size, s_nbr, s_idx;
|
||||
unsigned int i, args_size, s_nbr, ros_nbr, s_idx;
|
||||
|
||||
if (!buf) {
|
||||
return -EINVAL;
|
||||
|
@ -523,9 +592,10 @@ int cbpprintf(cbprintf_cb out, void *ctx, void *packaged)
|
|||
/* Retrieve the size of the arg list and number of strings. */
|
||||
args_size = ((uint8_t *)buf)[0] * sizeof(int);
|
||||
s_nbr = ((uint8_t *)buf)[1];
|
||||
ros_nbr = ((uint8_t *)buf)[2];
|
||||
|
||||
/* Locate the string table */
|
||||
s = buf + args_size;
|
||||
s = buf + args_size + ros_nbr;
|
||||
|
||||
/*
|
||||
* Patch in string pointers.
|
||||
|
@ -549,3 +619,65 @@ int cbpprintf(cbprintf_cb out, void *ctx, void *packaged)
|
|||
/* Turn this into a va_list and print it */
|
||||
return cbprintf_via_va_list(out, ctx, fmt, buf);
|
||||
}
|
||||
|
||||
int cbprintf_fsc_package(void *in_packaged,
|
||||
size_t in_len,
|
||||
void *packaged,
|
||||
size_t len)
|
||||
{
|
||||
uint8_t *buf = in_packaged, *out = packaged;
|
||||
char **ps;
|
||||
unsigned int args_size, s_nbr, ros_nbr, s_idx;
|
||||
size_t out_len;
|
||||
size_t slen;
|
||||
|
||||
if (!buf) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (packaged && (len < in_len)) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/* Retrieve the size of the arg list and number of strings. */
|
||||
args_size = buf[0] * sizeof(int);
|
||||
s_nbr = buf[1];
|
||||
ros_nbr = buf[2];
|
||||
|
||||
out_len = in_len;
|
||||
|
||||
if (packaged) {
|
||||
unsigned int rw_strs_len = in_len - (args_size + ros_nbr);
|
||||
|
||||
memcpy(out, buf, args_size);
|
||||
out[1] = s_nbr + ros_nbr;
|
||||
out[2] = 0;
|
||||
out += args_size;
|
||||
|
||||
/* Append all strings that were already part of the package. */
|
||||
memcpy(out, &buf[args_size + ros_nbr], rw_strs_len);
|
||||
out += rw_strs_len;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < ros_nbr; i++) {
|
||||
/* Get string address location */
|
||||
s_idx = buf[args_size + i];
|
||||
ps = (char **)(buf + s_idx * sizeof(int));
|
||||
|
||||
/* Get string length */
|
||||
slen = strlen(*ps) + 1;
|
||||
out_len += slen;
|
||||
|
||||
/* Copy string into the buffer (if provided) and enough space. */
|
||||
if (packaged) {
|
||||
if (out_len > len) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
*out++ = s_idx;
|
||||
memcpy(out, *ps, slen);
|
||||
out += slen;
|
||||
}
|
||||
}
|
||||
|
||||
return out_len;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ void z_impl_z_log_msg2_runtime_vcreate(uint8_t domain_id, const void *source,
|
|||
va_list ap2;
|
||||
|
||||
va_copy(ap2, ap);
|
||||
plen = cbvprintf_package(NULL, Z_LOG_MSG2_ALIGN_OFFSET,
|
||||
plen = cbvprintf_package(NULL, Z_LOG_MSG2_ALIGN_OFFSET, 0,
|
||||
fmt, ap2);
|
||||
__ASSERT_NO_MSG(plen >= 0);
|
||||
va_end(ap2);
|
||||
|
@ -83,7 +83,7 @@ void z_impl_z_log_msg2_runtime_vcreate(uint8_t domain_id, const void *source,
|
|||
}
|
||||
|
||||
if (msg && fmt) {
|
||||
plen = cbvprintf_package(msg->data, plen, fmt, ap);
|
||||
plen = cbvprintf_package(msg->data, plen, 0, fmt, ap);
|
||||
__ASSERT_NO_MSG(plen >= 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static void unpack(const char *desc, struct out_buffer *buf,
|
|||
struct out_buffer rt_buf = { \
|
||||
.buf = runtime_buf, .idx = 0, .size = sizeof(runtime_buf) \
|
||||
}; \
|
||||
int rc = cbprintf_package(NULL, ALIGN_OFFSET, fmt, __VA_ARGS__); \
|
||||
int rc = cbprintf_package(NULL, ALIGN_OFFSET, 0, fmt, __VA_ARGS__); \
|
||||
zassert_true(rc > 0, "cbprintf_package() returned %d", rc); \
|
||||
int len = rc; \
|
||||
/* Aligned so the package is similar to the static one. */ \
|
||||
|
@ -74,7 +74,7 @@ static void unpack(const char *desc, struct out_buffer *buf,
|
|||
rt_package[len + ALIGN_OFFSET]; \
|
||||
memset(rt_package, 0, len + ALIGN_OFFSET); \
|
||||
pkg = &rt_package[ALIGN_OFFSET]; \
|
||||
rc = cbprintf_package(pkg, len, fmt, __VA_ARGS__); \
|
||||
rc = cbprintf_package(pkg, len, 0, fmt, __VA_ARGS__); \
|
||||
zassert_equal(rc, len, "cbprintf_package() returned %d, expected %d", \
|
||||
rc, len); \
|
||||
dump("runtime", pkg, len); \
|
||||
|
@ -82,13 +82,13 @@ static void unpack(const char *desc, struct out_buffer *buf,
|
|||
struct out_buffer st_buf = { \
|
||||
.buf = static_buf, .idx = 0, .size = sizeof(static_buf) \
|
||||
}; \
|
||||
CBPRINTF_STATIC_PACKAGE(NULL, 0, len, ALIGN_OFFSET, fmt, __VA_ARGS__); \
|
||||
CBPRINTF_STATIC_PACKAGE(NULL, 0, len, ALIGN_OFFSET, 0, fmt, __VA_ARGS__); \
|
||||
zassert_true(len > 0, "CBPRINTF_STATIC_PACKAGE() returned %d", len); \
|
||||
uint8_t __aligned(CBPRINTF_PACKAGE_ALIGNMENT) \
|
||||
package[len + ALIGN_OFFSET];\
|
||||
int outlen; \
|
||||
pkg = &package[ALIGN_OFFSET]; \
|
||||
CBPRINTF_STATIC_PACKAGE(pkg, len, outlen, ALIGN_OFFSET, fmt, __VA_ARGS__);\
|
||||
CBPRINTF_STATIC_PACKAGE(pkg, len, outlen, ALIGN_OFFSET, 0, fmt, __VA_ARGS__);\
|
||||
zassert_equal(len, outlen, NULL); \
|
||||
dump("static", pkg, len); \
|
||||
unpack("static", &st_buf, pkg, len); \
|
||||
|
|
|
@ -102,6 +102,10 @@
|
|||
#define PKG_ALIGN_OFFSET sizeof(void *)
|
||||
#endif
|
||||
|
||||
#if (VIA_TWISTER & 0x2000) != 0
|
||||
#define PACKAGE_FLAGS CBPRINTF_PACKAGE_ADD_STRING_IDXS
|
||||
#endif
|
||||
|
||||
#endif /* VIA_TWISTER */
|
||||
|
||||
/* Can't use IS_ENABLED on symbols that don't start with CONFIG_
|
||||
|
@ -123,6 +127,10 @@
|
|||
#define Z_C_GENERIC 0
|
||||
#endif
|
||||
|
||||
#ifndef PACKAGE_FLAGS
|
||||
#define PACKAGE_FLAGS 0
|
||||
#endif
|
||||
|
||||
#include <sys/cbprintf.h>
|
||||
#include "../../../lib/os/cbprintf.c"
|
||||
|
||||
|
@ -231,7 +239,7 @@ static int prf(char *static_package_str, const char *format, ...)
|
|||
rv = vsnprintf(buf, sizeof(buf), format, ap);
|
||||
#else
|
||||
#if USE_PACKAGED
|
||||
rv = cbvprintf_package(packaged, sizeof(packaged), format, ap);
|
||||
rv = cbvprintf_package(packaged, sizeof(packaged), PACKAGE_FLAGS, format, ap);
|
||||
if (rv >= 0) {
|
||||
rv = cbpprintf(out, &outbuf, packaged);
|
||||
if (rv == 0 && static_package_str) {
|
||||
|
@ -259,11 +267,11 @@ static int rawprf(const char *format, ...)
|
|||
uint8_t *pkg_buf = &packaged[PKG_ALIGN_OFFSET];
|
||||
|
||||
va_copy(ap2, ap);
|
||||
len = cbvprintf_package(NULL, PKG_ALIGN_OFFSET, format, ap2);
|
||||
len = cbvprintf_package(NULL, PKG_ALIGN_OFFSET, PACKAGE_FLAGS, format, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
if (len >= 0) {
|
||||
rv = cbvprintf_package(pkg_buf, len, format, ap);
|
||||
rv = cbvprintf_package(pkg_buf, len, PACKAGE_FLAGS, format, ap);
|
||||
} else {
|
||||
rv = len;
|
||||
}
|
||||
|
@ -293,17 +301,17 @@ static int rawprf(const char *format, ...)
|
|||
.buf = _buf, .size = ARRAY_SIZE(_buf), .idx = 0 \
|
||||
}; \
|
||||
CBPRINTF_STATIC_PACKAGE(NULL, 0, _len, PKG_ALIGN_OFFSET, \
|
||||
_fmt, __VA_ARGS__); \
|
||||
PACKAGE_FLAGS, _fmt, __VA_ARGS__); \
|
||||
uint8_t __aligned(CBPRINTF_PACKAGE_ALIGNMENT) \
|
||||
package[_len + PKG_ALIGN_OFFSET]; \
|
||||
int st_pkg_rv; \
|
||||
CBPRINTF_STATIC_PACKAGE(&package[PKG_ALIGN_OFFSET], _len - 1, \
|
||||
st_pkg_rv, PKG_ALIGN_OFFSET, \
|
||||
_fmt, __VA_ARGS__); \
|
||||
PACKAGE_FLAGS, _fmt, __VA_ARGS__); \
|
||||
zassert_equal(st_pkg_rv, -ENOSPC, NULL); \
|
||||
CBPRINTF_STATIC_PACKAGE(&package[PKG_ALIGN_OFFSET], _len, \
|
||||
st_pkg_rv, PKG_ALIGN_OFFSET, \
|
||||
_fmt, __VA_ARGS__); \
|
||||
PACKAGE_FLAGS, _fmt, __VA_ARGS__); \
|
||||
zassert_equal(st_pkg_rv, _len, NULL); \
|
||||
rv = cbpprintf(out, &package_buf, &package[PKG_ALIGN_OFFSET]); \
|
||||
if (rv >= 0) { \
|
||||
|
@ -1199,7 +1207,7 @@ static void test_cbprintf_package(void)
|
|||
char fmt[] = "/%i/"; /* not const */
|
||||
|
||||
/* Verify we can calculate length without storing */
|
||||
rc = cbprintf_package(NULL, PKG_ALIGN_OFFSET, fmt, 3);
|
||||
rc = cbprintf_package(NULL, PKG_ALIGN_OFFSET, PACKAGE_FLAGS, fmt, 3);
|
||||
zassert_true(rc > sizeof(int), NULL);
|
||||
|
||||
/* Capture the base package information for future tests. */
|
||||
|
@ -1210,12 +1218,12 @@ static void test_cbprintf_package(void)
|
|||
/* Verify we get same length when storing. Pass buffer which may be
|
||||
* unaligned. Same alignment offset was used for space calculation.
|
||||
*/
|
||||
rc = cbprintf_package(&buf[PKG_ALIGN_OFFSET], len, fmt, 3);
|
||||
rc = cbprintf_package(&buf[PKG_ALIGN_OFFSET], len, PACKAGE_FLAGS, fmt, 3);
|
||||
zassert_equal(rc, len, NULL);
|
||||
|
||||
/* Verify we get an error if can't store */
|
||||
len -= 1;
|
||||
rc = cbprintf_package(&buf[PKG_ALIGN_OFFSET], len, fmt, 3);
|
||||
rc = cbprintf_package(&buf[PKG_ALIGN_OFFSET], len, PACKAGE_FLAGS, fmt, 3);
|
||||
zassert_equal(rc, -ENOSPC, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -132,3 +132,18 @@ tests:
|
|||
|
||||
utilities.prf.m64va81: # PACKAGED NANO + FULL + AVOID_C_GENERIC
|
||||
extra_args: M64_MODE=1 EXTRA_CPPFLAGS=-DVIA_TWISTER=0xa81
|
||||
|
||||
utilities.prf.m64v2200: # PACKAGED REDUCED + CBPRINTF_PACKAGE_ADD_STRING_IDXS
|
||||
extra_args: M64_MODE=1 EXTRA_CPPFLAGS=-DVIA_TWISTER=0x2200
|
||||
|
||||
utilities.prf.m64v2201: # PACKAGED FULL + CBPRINTF_PACKAGE_ADD_STRING_IDXS
|
||||
extra_args: M64_MODE=1 EXTRA_CPPFLAGS=-DVIA_TWISTER=0x2201
|
||||
|
||||
utilities.prf.m64v2207: # PACKAGED FULL + FP + FP_A + CBPRINTF_PACKAGE_ADD_STRING_IDXS
|
||||
extra_args: M64_MODE=1 EXTRA_CPPFLAGS=-DVIA_TWISTER=0x2207
|
||||
|
||||
utilities.prf.m64v2208: # PACKAGED %n + CBPRINTF_PACKAGE_ADD_STRING_IDXS
|
||||
extra_args: M64_MODE=1 EXTRA_CPPFLAGS=-DVIA_TWISTER=0x2208
|
||||
|
||||
utilities.prf.m64v2281: # PACKAGED NANO + FULL + CBPRINTF_PACKAGE_ADD_STRING_IDXS
|
||||
extra_args: M64_MODE=1 EXTRA_CPPFLAGS=-DVIA_TWISTER=0x2281
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue