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