/* * Copyright (c) 2020 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include int cbprintf(cbprintf_cb out, void *ctx, const char *format, ...) { va_list ap; int rc; va_start(ap, format); rc = cbvprintf(out, ctx, format, ap); va_end(ap); return rc; } #if defined(CONFIG_CBPRINTF_LIBC_SUBSTS) #include /* Context for sn* variants is the next space in the buffer, and the buffer * end. */ struct str_ctx { char *dp; char *const dpe; }; static int str_out(int c, void *ctx) { struct str_ctx *scp = ctx; /* s*printf must return the number of characters that would be * output, even if they don't all fit, so conditionally store * and unconditionally succeed. */ if (scp->dp < scp->dpe) { *(scp->dp++) = c; } return c; } int fprintfcb(FILE *stream, const char *format, ...) { va_list ap; int rc; va_start(ap, format); rc = vfprintfcb(stream, format, ap); va_end(ap); return rc; } int vfprintfcb(FILE *stream, const char *format, va_list ap) { return cbvprintf(fputc, stream, format, ap); } int printfcb(const char *format, ...) { va_list ap; int rc; va_start(ap, format); rc = vprintfcb(format, ap); va_end(ap); return rc; } int vprintfcb(const char *format, va_list ap) { return cbvprintf(fputc, stdout, format, ap); } int snprintfcb(char *str, size_t size, const char *format, ...) { va_list ap; int rc; va_start(ap, format); rc = vsnprintfcb(str, size, format, ap); va_end(ap); return rc; } int vsnprintfcb(char *str, size_t size, const char *format, va_list ap) { struct str_ctx ctx = { .dp = str, .dpe = str + size, }; int rv = cbvprintf(str_out, &ctx, format, ap); if (ctx.dp < ctx.dpe) { ctx.dp[0] = 0; } else { ctx.dp[-1] = 0; } return rv; } #endif /* CONFIG_CBPRINTF_LIBC_SUBSTS */