Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "config.h"
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017
00018 #if HAVE_STDARG_H
00019 # include <stdarg.h>
00020 #else
00021 # error Not enough var arg support!
00022 #endif
00023
00024 #include "bits.h"
00025 #include "debug.h"
00026 #include "printbuf.h"
00027
00028 struct printbuf* printbuf_new()
00029 {
00030 struct printbuf *p;
00031
00032 if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL;
00033 p->size = 32;
00034 p->bpos = 0;
00035 if(!(p->buf = malloc( (size_t) p->size))) {
00036 free(p);
00037 return NULL;
00038 }
00039 return p;
00040 }
00041
00042
00043 int printbuf_memappend(struct printbuf *p, const char *buf, int size)
00044 {
00045 char *t;
00046 if(p->size - p->bpos <= size) {
00047 int new_size = max(p->size * 2, p->bpos + size + 8);
00048 #ifdef PRINTBUF_DEBUG
00049 mc_debug("printbuf_memappend: realloc "
00050 "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
00051 p->bpos, size, p->size, new_size);
00052 #endif
00053 if(!(t = realloc(p->buf, (size_t) new_size))) return -1;
00054 p->size = new_size;
00055 p->buf = t;
00056 }
00057 memcpy(p->buf + p->bpos, buf, (size_t) size);
00058 p->bpos += size;
00059 p->buf[p->bpos]= '\0';
00060 return size;
00061 }
00062
00063 #if !HAVE_VSNPRINTF && defined(WIN32)
00064 # define vsnprintf _vsnprintf
00065 #elif !HAVE_VSNPRINTF
00066 # error Need vsnprintf!
00067 #endif
00068
00069 #if !HAVE_VASPRINTF
00070
00071 static int vasprintf(char **buf, const char *fmt, va_list ap)
00072 {
00073 #ifndef WIN32
00074 static char _T_emptybuffer = '\0';
00075 #endif
00076 int chars;
00077 char *b;
00078
00079 if(!buf) { return -1; }
00080
00081 #ifdef WIN32
00082 chars = _vscprintf(fmt, ap)+1;
00083 #else
00084
00085
00086 chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
00087 if(chars < 0) { chars *= -1; }
00088 #endif
00089
00090 b = (char*)malloc(sizeof(char)*chars);
00091 if(!b) { return -1; }
00092
00093 if((chars = vsprintf(b, fmt, ap)) < 0)
00094 {
00095 free(b);
00096 } else {
00097 *buf = b;
00098 }
00099
00100 return chars;
00101 }
00102 #endif
00103
00104 int sprintbuf(struct printbuf *p, const char *msg, ...)
00105 {
00106 va_list ap;
00107 char *t;
00108 int size;
00109 char buf[128];
00110
00111
00112 va_start(ap, msg);
00113 size = vsnprintf(buf, 128, msg, ap);
00114 va_end(ap);
00115
00116
00117
00118
00119 if(size == -1 || size > 127) {
00120 int ret;
00121 va_start(ap, msg);
00122 if((size = vasprintf(&t, msg, ap)) == -1) return -1;
00123 va_end(ap);
00124 ret = printbuf_memappend(p, t, size);
00125 free(t);
00126 return ret;
00127 } else {
00128 return printbuf_memappend(p, buf, size);
00129 }
00130 }
00131
00132 void printbuf_reset(struct printbuf *p)
00133 {
00134 p->buf[0] = '\0';
00135 p->bpos = 0;
00136 }
00137
00138 void printbuf_free(struct printbuf *p)
00139 {
00140 if(p) {
00141 free(p->buf);
00142 free(p);
00143 }
00144 }