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