vsmprint.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * The authors of this software are Rob Pike and Ken Thompson.
  3. * Copyright (c) 2002 by Lucent Technologies.
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose without fee is hereby granted, provided that this entire notice
  6. * is included in all copies of any software which is or includes a copy
  7. * or modification of this software and in all copies of the supporting
  8. * documentation for such software.
  9. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
  10. * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
  11. * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
  12. * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
  13. */
  14. #include "lib9.h"
  15. #include "fmtdef.h"
  16. static int
  17. fmtStrFlush(Fmt *f)
  18. {
  19. char *s;
  20. int n;
  21. if(f->start == nil)
  22. return 0;
  23. n = (int)f->farg;
  24. n += 256;
  25. f->farg = (void*)n;
  26. s = f->start;
  27. f->start = realloc(s, n);
  28. if(f->start == nil){
  29. free(s);
  30. f->to = nil;
  31. f->stop = nil;
  32. return 0;
  33. }
  34. f->to = (char*)f->start + ((char*)f->to - s);
  35. f->stop = (char*)f->start + n - 1;
  36. return 1;
  37. }
  38. int
  39. fmtstrinit(Fmt *f)
  40. {
  41. int n;
  42. memset(f, 0, sizeof(*f));
  43. n = 32;
  44. f->start = malloc(n);
  45. if(f->start == nil)
  46. return -1;
  47. f->to = f->start;
  48. f->stop = (char*)f->start + n - 1;
  49. f->flush = fmtStrFlush;
  50. f->farg = (void*)n;
  51. f->nfmt = 0;
  52. return 0;
  53. }
  54. /*
  55. * print into an allocated string buffer
  56. */
  57. char*
  58. vsmprint(char *fmt, va_list args)
  59. {
  60. Fmt f;
  61. int n;
  62. if(fmtstrinit(&f) < 0)
  63. return nil;
  64. va_copy(f.args, args);
  65. n = dofmt(&f, fmt);
  66. va_end(f.args);
  67. if(n < 0){
  68. free(f.start);
  69. f.start = nil;
  70. return nil;
  71. }
  72. return fmtstrflush(&f);
  73. }