runevsmprint.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include "fmtdef.h"
  12. static int
  13. runeFmtStrFlush(Fmt *f)
  14. {
  15. Rune *s;
  16. int n;
  17. if(f->start == nil)
  18. return 0;
  19. n = (int)(uintptr)f->farg;
  20. n *= 2;
  21. s = f->start;
  22. f->start = realloc(s, sizeof(Rune)*n);
  23. if(f->start == nil){
  24. f->farg = nil;
  25. f->to = nil;
  26. f->stop = nil;
  27. free(s);
  28. return 0;
  29. }
  30. f->farg = (void*)(uintptr_t)n;
  31. f->to = (Rune*)f->start + ((Rune*)f->to - s);
  32. f->stop = (Rune*)f->start + n - 1;
  33. return 1;
  34. }
  35. int
  36. runefmtstrinit(Fmt *f)
  37. {
  38. int n;
  39. memset(f, 0, sizeof *f);
  40. f->runes = 1;
  41. n = 32;
  42. f->start = malloc(sizeof(Rune)*n);
  43. if(f->start == nil)
  44. return -1;
  45. setmalloctag(f->start, getcallerpc(&f));
  46. f->to = f->start;
  47. f->stop = (Rune*)f->start + n - 1;
  48. f->flush = runeFmtStrFlush;
  49. f->farg = (void*)(uintptr_t)n;
  50. f->nfmt = 0;
  51. return 0;
  52. }
  53. /*
  54. * print into an allocated string buffer
  55. */
  56. Rune*
  57. runevsmprint(char *fmt, va_list args)
  58. {
  59. Fmt f;
  60. int n;
  61. if(runefmtstrinit(&f) < 0)
  62. return nil;
  63. //f.args = args;
  64. va_copy(f.args,args);
  65. n = dofmt(&f, fmt);
  66. va_end(f.args);
  67. if(f.start == nil) /* realloc failed? */
  68. return nil;
  69. if(n < 0){
  70. free(f.start);
  71. return nil;
  72. }
  73. setmalloctag(f.start, getcallerpc(&fmt));
  74. *(Rune*)f.to = '\0';
  75. return f.start;
  76. }