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 /*@owned@*/ char *buf; 00014 /*@dependent@*/ char *tail; /* Points to first "free" char */ 00015 int allocated; 00016 int free; 00017 }; 00018 00022 /*@unused@*/ static inline int xisspace(int c) { 00023 return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'); 00024 } 00025 00031 /*@unused@*/ static inline /*@null@*/ void * 00032 _free(/*@only@*/ /*@null@*/ const void * p) /*@modifies *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 /* If free == l there is no room for NULL terminator! */ 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 /*@-mayaliasunique@*/ 00097 strcpy(sb->tail, s); 00098 /*@=mayaliasunique@*/ 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 }