1
0

vswprintf.c 1.1 KB

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