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 8struct cookie { 9 wchar_t* ws; 10 size_t l; 11}; 12 13static 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 29int 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