vswprintf.c 872 B

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