1 #include "stdio_impl.h"
2 #include <errno.h>
3 #include <limits.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <wchar.h>
7
8 struct cookie {
9 wchar_t* ws;
10 size_t l;
11 };
12
sw_write(FILE * f,const unsigned char * s,size_t l)13 static size_t sw_write(FILE* f, const unsigned char* s, size_t l) {
14 size_t l0 = l;
15 int i = 0;
16 struct cookie* c = f->cookie;
17 if (s != f->wbase && sw_write(f, f->wbase, f->wpos - f->wbase) == -1)
18 return -1;
19 while (c->l && l && (i = mbtowc(c->ws, (void*)s, l)) >= 0) {
20 s += i;
21 l -= i;
22 c->l--;
23 c->ws++;
24 }
25 *c->ws = 0;
26 return i < 0 ? i : l0;
27 }
28
vswprintf(wchar_t * restrict s,size_t n,const wchar_t * restrict fmt,va_list ap)29 int vswprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict fmt, va_list ap) {
30 int r;
31 FILE f;
32 unsigned char buf[256];
33 struct cookie c = {s, n - 1};
34
35 memset(&f, 0, sizeof(FILE));
36 f.lbf = EOF;
37 f.write = sw_write;
38 f.buf_size = sizeof buf;
39 f.buf = buf;
40 f.lock = -1;
41 f.cookie = &c;
42 if (!n) {
43 return -1;
44 } else if (n > INT_MAX) {
45 errno = EOVERFLOW;
46 return -1;
47 }
48 r = vfwprintf(&f, fmt, ap);
49 sw_write(&f, 0, 0);
50 return r >= n ? -1 : r;
51 }
52