From 4abab5ad6c8465a7528ccdd5f49367da05f78bbd Mon Sep 17 00:00:00 2001 From: Vladimir Azarov Date: Tue, 1 Oct 2024 15:47:05 +0200 Subject: Initial version --- src/stdio/vsnprintf.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/stdio/vsnprintf.c (limited to 'src/stdio/vsnprintf.c') diff --git a/src/stdio/vsnprintf.c b/src/stdio/vsnprintf.c new file mode 100644 index 0000000..409b9c8 --- /dev/null +++ b/src/stdio/vsnprintf.c @@ -0,0 +1,50 @@ +#include "stdio_impl.h" +#include +#include +#include +#include + +struct cookie { + char *s; + size_t n; +}; + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static size_t sn_write(FILE *f, const unsigned char *s, size_t l) +{ + struct cookie *c = f->cookie; + size_t k = MIN(c->n, f->wpos - f->wbase); + if (k) { + memcpy(c->s, f->wbase, k); + c->s += k; + c->n -= k; + } + k = MIN(c->n, l); + if (k) { + memcpy(c->s, s, k); + c->s += k; + c->n -= k; + } + *c->s = 0; + f->wpos = f->wbase = f->buf; + /* pretend to succeed, even if we discarded extra data */ + return l; +} + +int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) +{ + unsigned char buf[1]; + char dummy[1]; + struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 }; + FILE f = { + .lbf = EOF, + .write = sn_write, + .lock = -1, + .buf = buf, + .cookie = &c, + }; + + *c.s = 0; + return vfprintf(&f, fmt, ap); +} -- cgit v1.2.3