runevsmprint.c 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #include <u.h>
  2. #include <libc.h>
  3. #include "fmtdef.h"
  4. static int
  5. runeFmtStrFlush(Fmt *f)
  6. {
  7. Rune *s;
  8. int n;
  9. if(f->start == nil)
  10. return 0;
  11. n = (int)(uintptr)f->farg;
  12. n *= 2;
  13. s = f->start;
  14. f->start = realloc(s, sizeof(Rune)*n);
  15. if(f->start == nil){
  16. f->farg = nil;
  17. f->to = nil;
  18. f->stop = nil;
  19. free(s);
  20. return 0;
  21. }
  22. f->farg = (void*)n;
  23. f->to = (Rune*)f->start + ((Rune*)f->to - s);
  24. f->stop = (Rune*)f->start + n - 1;
  25. return 1;
  26. }
  27. int
  28. runefmtstrinit(Fmt *f)
  29. {
  30. int n;
  31. memset(f, 0, sizeof *f);
  32. f->runes = 1;
  33. n = 32;
  34. f->start = malloc(sizeof(Rune)*n);
  35. if(f->start == nil)
  36. return -1;
  37. setmalloctag(f->start, getcallerpc(&f));
  38. f->to = f->start;
  39. f->stop = (Rune*)f->start + n - 1;
  40. f->flush = runeFmtStrFlush;
  41. f->farg = (void*)n;
  42. f->nfmt = 0;
  43. return 0;
  44. }
  45. /*
  46. * print into an allocated string buffer
  47. */
  48. Rune*
  49. runevsmprint(char *fmt, va_list args)
  50. {
  51. Fmt f;
  52. int n;
  53. if(runefmtstrinit(&f) < 0)
  54. return nil;
  55. f.args = args;
  56. n = dofmt(&f, fmt);
  57. if(f.start == nil) /* realloc failed? */
  58. return nil;
  59. if(n < 0){
  60. free(f.start);
  61. return nil;
  62. }
  63. setmalloctag(f.start, getcallerpc(&fmt));
  64. *(Rune*)f.to = '\0';
  65. return f.start;
  66. }