master
 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 k = MIN(c->n, f->wpos - f->wbase);
18	if (k) {
19		memcpy(c->s, f->wbase, k);
20		c->s += k;
21		c->n -= k;
22	}
23	k = MIN(c->n, l);
24	if (k) {
25		memcpy(c->s, s, k);
26		c->s += k;
27		c->n -= k;
28	}
29	*c->s = 0;
30	f->wpos = f->wbase = f->buf;
31	/* pretend to succeed, even if we discarded extra data */
32	return l;
33}
34
35int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
36{
37	unsigned char buf[1];
38	char dummy[1];
39	struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 };
40	FILE f = {
41		.lbf = EOF,
42		.write = sn_write,
43#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
44		.lock = -1,
45#endif
46		.buf = buf,
47		.cookie = &c,
48	};
49
50	*c.s = 0;
51	return vfprintf(&f, fmt, ap);
52}