You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
1.8 KiB
114 lines
1.8 KiB
/* |
|
* Copyright (c) 2020 Nordic Semiconductor ASA |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include <stdarg.h> |
|
#include <stddef.h> |
|
#include <zephyr/sys/cbprintf.h> |
|
|
|
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 <stdio.h> |
|
|
|
/* 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 */
|
|
|