Skip to content

Commit c899cd0

Browse files
Johan HedbergAnas Nashif
authored andcommitted
printk: Add APIs to print into strings instead of default output
These correspond to the libc snprintf and vsnprintf APIs. Change-Id: If3944972ed95934a4967756593bb2932c3359b72 Signed-off-by: Johan Hedberg <[email protected]>
1 parent 3ab6046 commit c899cd0

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

include/misc/printk.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#define _PRINTK_H_
2020

2121
#include <toolchain.h>
22+
#include <stddef.h>
23+
#include <stdarg.h>
2224

2325
#ifdef __cplusplus
2426
extern "C" {
@@ -50,12 +52,33 @@ extern "C" {
5052
*/
5153
#ifdef CONFIG_PRINTK
5254
extern __printf_like(1, 2) int printk(const char *fmt, ...);
55+
extern __printf_like(3, 4) int snprintk(char *str, size_t size,
56+
const char *fmt, ...);
57+
extern int vsnprintk(char *str, size_t size, const char *fmt, va_list ap);
5358
#else
5459
static inline __printf_like(1, 2) int printk(const char *fmt, ...)
5560
{
5661
ARG_UNUSED(fmt);
5762
return 0;
5863
}
64+
65+
static inline __printf_like(3, 4) int snprintk(char *str, size_t size,
66+
const char *fmt, ...)
67+
{
68+
ARG_UNUSED(str);
69+
ARG_UNUSED(size);
70+
ARG_UNUSED(fmt);
71+
return 0;
72+
}
73+
74+
static inline int vsnprintk(char *str, size_t size, const char *fmt,
75+
va_list ap)
76+
{
77+
ARG_UNUSED(str);
78+
ARG_UNUSED(size);
79+
ARG_UNUSED(fmt);
80+
return 0;
81+
}
5982
#endif
6083

6184
#ifdef __cplusplus

misc/printk.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,53 @@ static void _printk_dec_ulong(out_func_t out, void *ctx,
287287
out((int)(remainder + 48), ctx);
288288
}
289289

290+
struct str_context {
291+
char *str;
292+
int max;
293+
int count;
294+
};
295+
296+
static int str_out(int c, struct str_context *ctx)
297+
{
298+
if (!ctx->str || ctx->count >= ctx->max) {
299+
ctx->count++;
300+
return c;
301+
}
302+
303+
if (ctx->count == ctx->max - 1) {
304+
ctx->str[ctx->count++] = '\0';
305+
} else {
306+
ctx->str[ctx->count++] = c;
307+
}
308+
309+
return c;
310+
}
311+
312+
int snprintk(char *str, size_t size, const char *fmt, ...)
313+
{
314+
struct str_context ctx = { str, size, 0 };
315+
va_list ap;
316+
317+
va_start(ap, fmt);
318+
_vprintk((out_func_t)str_out, &ctx, fmt, ap);
319+
va_end(ap);
320+
321+
if (ctx.count < ctx.max) {
322+
str[ctx.count] = '\0';
323+
}
324+
325+
return ctx.count;
326+
}
327+
328+
int vsnprintk(char *str, size_t size, const char *fmt, va_list ap)
329+
{
330+
struct str_context ctx = { str, size, 0 };
331+
332+
_vprintk((out_func_t)str_out, &ctx, fmt, ap);
333+
334+
if (ctx.count < ctx.max) {
335+
str[ctx.count] = '\0';
336+
}
337+
338+
return ctx.count;
339+
}

tests/kernel/test_common/src/printk.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ static int ram_console_out(int character)
6767

6868
void printk_test(void)
6969
{
70+
int count;
71+
7072
_old_char_out = _char_out;
7173
_char_out = ram_console_out;
7274

@@ -82,4 +84,30 @@ void printk_test(void)
8284

8385
ram_console[pos] = '\0';
8486
assert_true((strcmp(ram_console, expected) == 0), "printk failed");
87+
88+
memset(ram_console, 0, sizeof(ram_console));
89+
count = 0;
90+
91+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
92+
"%zu %hhu %hu %u %lu %llu\n",
93+
stv, uc, usi, ui, ul, ull);
94+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
95+
"%c %hhd %hd %d %ld %lld\n", c, c, ssi, si, sl, sll);
96+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
97+
"0x%x %p\n", hex, ptr);
98+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
99+
"0x%x 0x%02x 0x%04x 0x%08x\n", 1, 1, 1, 1);
100+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
101+
"0x%x 0x%2x 0x%4x 0x%8x\n", 1, 1, 1, 1);
102+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
103+
"%d %02d %04d %08d\n", 42, 42, 42, 42);
104+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
105+
"%d %02d %04d %08d\n", -42, -42, -42, -42);
106+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
107+
"%u %2u %4u %8u\n", 42, 42, 42, 42);
108+
count += snprintk(ram_console + count, sizeof(ram_console) - count,
109+
"%u %02u %04u %08u\n", 42, 42, 42, 42);
110+
111+
ram_console[count] = '\0';
112+
assert_true((strcmp(ram_console, expected) == 0), "snprintk failed");
85113
}

0 commit comments

Comments
 (0)