Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2020 Nordic Semiconductor ASA
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0
5 : : */
6 : :
7 : : #include <stdarg.h>
8 : : #include <stddef.h>
9 : : #include <zephyr/sys/cbprintf.h>
10 : :
11 : 0 : int cbprintf(cbprintf_cb out, void *ctx, const char *format, ...)
12 : : {
13 : 0 : va_list ap;
14 : 0 : int rc;
15 : :
16 : 0 : va_start(ap, format);
17 : 0 : rc = cbvprintf(out, ctx, format, ap);
18 : 0 : va_end(ap);
19 : :
20 : 0 : return rc;
21 : : }
22 : :
23 : : #if defined(CONFIG_CBPRINTF_LIBC_SUBSTS)
24 : :
25 : : #include <stdio.h>
26 : : #include <zephyr/sys/__assert.h>
27 : :
28 : : /* Context for sn* variants is the next space in the buffer, and the buffer
29 : : * end.
30 : : */
31 : : struct str_ctx {
32 : : char *dp;
33 : : char *const dpe;
34 : : };
35 : :
36 : : static int str_out(int c,
37 : : void *ctx)
38 : : {
39 : : struct str_ctx *scp = ctx;
40 : :
41 : : /* s*printf must return the number of characters that would be
42 : : * output, even if they don't all fit, so conditionally store
43 : : * and unconditionally succeed.
44 : : */
45 : : if (scp->dp < scp->dpe) {
46 : : *(scp->dp++) = c;
47 : : }
48 : :
49 : : return c;
50 : : }
51 : :
52 : : int fprintfcb(FILE *stream, const char *format, ...)
53 : : {
54 : : va_list ap;
55 : : int rc;
56 : :
57 : : va_start(ap, format);
58 : : rc = vfprintfcb(stream, format, ap);
59 : : va_end(ap);
60 : :
61 : : return rc;
62 : : }
63 : :
64 : : int vfprintfcb(FILE *stream, const char *format, va_list ap)
65 : : {
66 : : return cbvprintf(fputc, stream, format, ap);
67 : : }
68 : :
69 : : int printfcb(const char *format, ...)
70 : : {
71 : : va_list ap;
72 : : int rc;
73 : :
74 : : va_start(ap, format);
75 : : rc = vprintfcb(format, ap);
76 : : va_end(ap);
77 : :
78 : : return rc;
79 : : }
80 : :
81 : : int vprintfcb(const char *format, va_list ap)
82 : : {
83 : : return cbvprintf(fputc, stdout, format, ap);
84 : : }
85 : :
86 : : int snprintfcb(char *str, size_t size, const char *format, ...)
87 : : {
88 : : va_list ap;
89 : : int rc;
90 : :
91 : : va_start(ap, format);
92 : : rc = vsnprintfcb(str, size, format, ap);
93 : : va_end(ap);
94 : :
95 : : return rc;
96 : : }
97 : :
98 : : int vsnprintfcb(char *str, size_t size, const char *format, va_list ap)
99 : : {
100 : : __ASSERT(str || !size, "str may only be NULL when size == 0");
101 : :
102 : : struct str_ctx ctx = {
103 : : .dp = str,
104 : : .dpe = str + size,
105 : : };
106 : : int rv = cbvprintf(str_out, &ctx, format, ap);
107 : :
108 : : if (!size) {
109 : : return rv;
110 : : }
111 : :
112 : : if (ctx.dp < ctx.dpe) {
113 : : ctx.dp[0] = 0;
114 : : } else {
115 : : ctx.dp[-1] = 0;
116 : : }
117 : :
118 : : return rv;
119 : : }
120 : :
121 : : #endif /* CONFIG_CBPRINTF_LIBC_SUBSTS */
|