xref: /third_party/musl/src/stdio/vsnprintf.c (revision 570af302)
1#include "stdio_impl.h"
2#include <limits.h>
3#include <string.h>
4#include <errno.h>
5#include <stdint.h>
6
7struct cookie {
8	char *s;
9	size_t n;
10};
11
12#define MIN(a, b) ((a) < (b) ? (a) : (b))
13
14static size_t sn_write(FILE *f, const unsigned char *s, size_t l)
15{
16	struct cookie *c = f->cookie;
17	size_t already_size = f->wpos - f->wbase;
18	if (already_size <= c->n) {
19		size_t k = MIN(l, c->n - already_size);
20		memcpy(f->wpos, s, k);
21		f->wpos += k;
22	}
23	/* pretend to succeed, even if we discarded extra data */
24	return l;
25}
26
27int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
28{
29	unsigned char dummy[1];
30	struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 };
31	FILE f = {
32		.lbf = EOF,
33		.lock = -1,
34		.buf = (unsigned char *)(n ? s: dummy),
35		.buf_size = n ? n - 1 : 0,
36		.flags = F_PBUF,
37		.cookie = &c,
38		.write = sn_write,
39	};
40
41	return vfprintf(&f, fmt, ap);
42}
43