Skip to content

Commit 14e5e98

Browse files
Nicolas Pitrecarlescufi
authored andcommitted
lib: cbprintf: add support for deferred formatting
In applications like logging the call site where arguments to formatting are available may not be suitable for performing the formatting, e.g. when the output operation can sleep. Add API that supports capturing data that may be transient into a buffer that can be saved, and API that then produces the output later using the packaged arguments. [ Documentation and commit log from Peter Bigot. ] Signed-off-by: Nicolas Pitre <[email protected]> Signed-off-by: Peter Bigot <[email protected]>
1 parent 4118ed1 commit 14e5e98

File tree

4 files changed

+673
-0
lines changed

4 files changed

+673
-0
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@
464464
/lib/gui/ @vanwinkeljan
465465
/lib/open-amp/ @arnopo
466466
/lib/os/ @dcpleung @nashif @andyross
467+
/lib/os/cbprintf_packaged.c @npitre
467468
/lib/posix/ @pfalcon
468469
/lib/cmsis_rtos_v2/ @nashif
469470
/lib/cmsis_rtos_v1/ @nashif

include/sys/cbprintf.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <stdarg.h>
1111
#include <stddef.h>
12+
#include <stdint.h>
1213
#include <toolchain.h>
1314

1415
#ifdef CONFIG_CBPRINTF_LIBC_SUBSTS
@@ -44,6 +45,102 @@ extern "C" {
4445
*/
4546
typedef int (*cbprintf_cb)(/* int c, void *ctx */);
4647

48+
/** @brief Capture state required to output formatted data later.
49+
*
50+
* Like cbprintf() but instead of processing the arguments and emitting the
51+
* formatted results immediately all arguments are captured so this can be
52+
* done in a different context, e.g. when the output function can block.
53+
*
54+
* In addition to the values extracted from arguments this will ensure that
55+
* copies are made of the necessary portions of any string parameters that are
56+
* not confirmed to be stored in read-only memory (hence assumed to be safe to
57+
* refer to directly later).
58+
*
59+
* @param packaged pointer to where the packaged data can be stored. Pass a
60+
* null pointer to store nothing but still calculate the total space required.
61+
* The data stored here is relocatable, that is it can be moved to another
62+
* contiguous block of memory. The pointer must be aligned to a multiple of
63+
* the largest element in the argument list.
64+
*
65+
* @param len this must be set to the number of bytes available at @p packaged.
66+
* Ignored if @p packaged is NULL.
67+
*
68+
* @param format a standard ISO C format string with characters and conversion
69+
* specifications.
70+
*
71+
* @param ... arguments corresponding to the conversion specifications found
72+
* within @p format.
73+
*
74+
* @retval nonegative the number of bytes successfully stored at @p packaged.
75+
* This will not exceed @p len.
76+
* @retval -EINVAL if @p format is not acceptable
77+
* @retval -ENOSPC if @p packaged was not null and the space required to store
78+
* exceed @p len.
79+
*/
80+
__printf_like(3, 4)
81+
int cbprintf_package(void *packaged,
82+
size_t len,
83+
const char *format,
84+
...);
85+
86+
/** @brief Capture state required to output formatted data later.
87+
*
88+
* Like cbprintf() but instead of processing the arguments and emitting the
89+
* formatted results immediately all arguments are captured so this can be
90+
* done in a different context, e.g. when the output function can block.
91+
*
92+
* In addition to the values extracted from arguments this will ensure that
93+
* copies are made of the necessary portions of any string parameters that are
94+
* not confirmed to be stored in read-only memory (hence assumed to be safe to
95+
* refer to directly later).
96+
*
97+
* @param packaged pointer to where the packaged data can be stored. Pass a
98+
* null pointer to store nothing but still calculate the total space required.
99+
* The data stored here is relocatable, that is it can be moved to another
100+
* contiguous block of memory. The pointer must be aligned to a multiple of
101+
* the largest element in the argument list.
102+
*
103+
* @param len this must be set to the number of bytes available at @p packaged.
104+
* Ignored if @p packaged is NULL.
105+
*
106+
* @param format a standard ISO C format string with characters and conversion
107+
* specifications.
108+
*
109+
* @param ap captured stack arguments corresponding to the conversion
110+
* specifications found within @p format.
111+
*
112+
* @retval nonegative the number of bytes successfully stored at @p packaged.
113+
* This will not exceed @p len.
114+
* @retval -EINVAL if @p format is not acceptable
115+
* @retval -ENOSPC if @p packaged was not null and the space required to store
116+
* exceed @p len.
117+
*/
118+
int cbvprintf_package(void *packaged,
119+
size_t len,
120+
const char *format,
121+
va_list ap);
122+
123+
/** @brief Generate the output for a previously captured format
124+
* operation.
125+
*
126+
* @param out the function used to emit each generated character.
127+
*
128+
* @param ctx context provided when invoking out
129+
*
130+
* @param packaged the data required to generate the formatted output, as
131+
* captured by cbprintf_package() or cbvprintf_package(). The alignment
132+
* requirement on this data is the same as when it was initially created.
133+
*
134+
* @note Memory indicated by @p packaged will be modified in a non-destructive
135+
* way, meaning that it could still be reused with this function again.
136+
*
137+
* @return the number of characters printed, or a negative error value
138+
* returned from invoking @p out.
139+
*/
140+
int cbpprintf(cbprintf_cb out,
141+
void *ctx,
142+
void *packaged);
143+
47144
/** @brief *printf-like output through a callback.
48145
*
49146
* This is essentially printf() except the output is generated

lib/os/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ zephyr_sources_ifdef(CONFIG_BASE64 base64.c)
44

55
zephyr_sources(
66
cbprintf.c
7+
cbprintf_packaged.c
78
crc32c_sw.c
89
crc32_sw.c
910
crc16_sw.c

0 commit comments

Comments
 (0)