--- /dev/null
+#include <stdlib.h>
+#include "stringbuf.h"
+
+#define BUF_CHUNK 1024
+
+struct StringBufRec {
+ char *buf;
+ char *tail; /* Points to first "free" char (usually '\0') */
+ int allocated;
+ int free;
+};
+
+StringBuf newStringBuf(void)
+{
+ StringBuf sb = malloc(sizeof(struct StringBufRec));
+
+ sb->buf = malloc(BUF_CHUNK * sizeof(char));
+ sb->buf[0] = '\0';
+ sb->tail = sb->buf;
+ sb->allocated = BUF_CHUNK;
+ sb->free = BUF_CHUNK;
+
+ return sb;
+}
+
+void freeStringBuf(StringBuf sb)
+{
+ free(sb->buf);
+ free(sb);
+}
+
+void truncStringBuf(StringBuf sb)
+{
+ sb->buf[0] = '\0';
+ sb->tail = sb->buf;
+ sb->free = sb->allocated;
+}
+
+char *getStringBuf(StringBuf sb)
+{
+ return sb->buf;
+}
+
+void appendStringBufAux(StringBuf sb, char *s, int nl)
+{
+ int l;
+
+ l = strlen(s);
+ /* If free == l there is no room for NULL terminator! */
+ if ((l + nl) > sb->free) {
+ sb->allocated += BUF_CHUNK;
+ sb->free += BUF_CHUNK;
+ sb->buf = realloc(sb->buf, sb->allocated);
+ sb->tail = sb->buf + (sb->allocated - sb->free);
+ }
+
+ strcpy(sb->tail, s);
+ sb->tail += l;
+ sb->free -= l;
+ if (nl) {
+ sb->tail[0] = '\n';
+ sb->tail[1] = '\0';
+ sb->tail++;
+ sb->free--;
+ }
+}
--- /dev/null
+#ifndef _STRINGBUF_H_
+#define _STRINGBUF_H_
+
+typedef struct StringBufRec *StringBuf;
+
+StringBuf newStringBuf(void);
+void freeStringBuf(StringBuf sb);
+void truncStringBuf(StringBuf sb);
+char *getStringBuf(StringBuf sb);
+
+#define appendStringBuf(sb, s) appendStringBufAux(sb, s, 0)
+#define appendLineStringBuf(sb, s) appendStringBufAux(sb, s, 1)
+
+void appendStringBufAux(StringBuf sb, char *s, int nl);
+
+#endif _STRINGBUF_H_