You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

printbuf.c 2.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * $Id: printbuf.c,v 1.3 2004/08/07 03:12:21 mclark Exp $
  3. *
  4. * Copyright Metaparadigm Pte. Ltd. 2004.
  5. * Michael Clark <michael@metaparadigm.com>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public (LGPL)
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details: http://www.gnu.org/
  16. *
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stdarg.h>
  21. #include <string.h>
  22. #include "bits.h"
  23. #include "debug.h"
  24. #include "printbuf.h"
  25. struct printbuf* printbuf_new()
  26. {
  27. struct printbuf *p;
  28. if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL;
  29. p->size = 32;
  30. p->bpos = 0;
  31. if(!(p->buf = malloc(p->size))) {
  32. free(p);
  33. return NULL;
  34. }
  35. return p;
  36. }
  37. int printbuf_memappend(struct printbuf *p, char *buf, int size)
  38. {
  39. char *t;
  40. if(p->size - p->bpos <= size) {
  41. int new_size = max(p->size * 2, p->bpos + size + 8);
  42. #if 0
  43. mc_debug("printbuf_memappend: realloc "
  44. "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
  45. p->bpos, size, p->size, new_size);
  46. #endif
  47. if(!(t = realloc(p->buf, new_size))) return -1;
  48. p->size = new_size;
  49. p->buf = t;
  50. }
  51. memcpy(p->buf + p->bpos, buf, size);
  52. p->bpos += size;
  53. p->buf[p->bpos]= '\0';
  54. return size;
  55. }
  56. int sprintbuf(struct printbuf *p, const char *msg, ...)
  57. {
  58. va_list ap;
  59. char *t;
  60. int size;
  61. char buf[128];
  62. /* user stack buffer first */
  63. va_start(ap, msg);
  64. size = vsnprintf(buf, 128, msg, ap);
  65. va_end(ap);
  66. /* if string is greater than stack buffer, then use dynamic string
  67. with vasprintf. Note: some implementation of vsnprintf return -1
  68. if output is truncated whereas some return the number of bytes that
  69. would have been writeen - this code handles both cases. */
  70. if(size == -1 || size > 127) {
  71. int ret;
  72. va_start(ap, msg);
  73. if((size = vasprintf(&t, msg, ap)) == -1) return -1;
  74. va_end(ap);
  75. ret = printbuf_memappend(p, t, size);
  76. free(t);
  77. return ret;
  78. } else {
  79. return printbuf_memappend(p, buf, size);
  80. }
  81. }
  82. void printbuf_reset(struct printbuf *p)
  83. {
  84. p->buf[0] = '\0';
  85. p->bpos = 0;
  86. }
  87. void printbuf_free(struct printbuf *p)
  88. {
  89. if(p) {
  90. free(p->buf);
  91. free(p);
  92. }
  93. }

No Description

Contributors (1)