00001
00005 #include "system.h"
00006
00007 #include "stringbuf.h"
00008 #include "debug.h"
00009
00010 #define BUF_CHUNK 1024
00011
00012 struct StringBufRec {
00013 char *buf;
00014 char *tail;
00015 int allocated;
00016 int free;
00017 };
00018
00022 static inline int xisspace(int c) {
00023 return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v');
00024 }
00025
00031 static inline void *
00032 _free( const void * p)
00033 {
00034 if (p != NULL) free((void *)p);
00035 return NULL;
00036 }
00037
00038 StringBuf newStringBuf(void)
00039 {
00040 StringBuf sb = xmalloc(sizeof(struct StringBufRec));
00041
00042 sb->free = sb->allocated = BUF_CHUNK;
00043 sb->buf = xcalloc(sb->allocated, sizeof(*sb->buf));
00044 sb->buf[0] = '\0';
00045 sb->tail = sb->buf;
00046
00047 return sb;
00048 }
00049
00050 StringBuf freeStringBuf(StringBuf sb)
00051 {
00052 if (sb) {
00053 sb->buf = _free(sb->buf);
00054 sb = _free(sb);
00055 }
00056 return sb;
00057 }
00058
00059 void truncStringBuf(StringBuf sb)
00060 {
00061 sb->buf[0] = '\0';
00062 sb->tail = sb->buf;
00063 sb->free = sb->allocated;
00064 }
00065
00066 void stripTrailingBlanksStringBuf(StringBuf sb)
00067 {
00068 while (sb->free != sb->allocated) {
00069 if (! xisspace(*(sb->tail - 1))) {
00070 break;
00071 }
00072 sb->free++;
00073 sb->tail--;
00074 }
00075 sb->tail[0] = '\0';
00076 }
00077
00078 char * getStringBuf(StringBuf sb)
00079 {
00080 return sb->buf;
00081 }
00082
00083 void appendStringBufAux(StringBuf sb, const char *s, int nl)
00084 {
00085 int l;
00086
00087 l = strlen(s);
00088
00089 while ((l + nl + 1) > sb->free) {
00090 sb->allocated += BUF_CHUNK;
00091 sb->free += BUF_CHUNK;
00092 sb->buf = xrealloc(sb->buf, sb->allocated);
00093 sb->tail = sb->buf + (sb->allocated - sb->free);
00094 }
00095
00096
00097 strcpy(sb->tail, s);
00098
00099 sb->tail += l;
00100 sb->free -= l;
00101 if (nl) {
00102 sb->tail[0] = '\n';
00103 sb->tail[1] = '\0';
00104 sb->tail++;
00105 sb->free--;
00106 }
00107 }