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