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@*/ 00014 char *buf; 00015 /*@dependent@*/ 00016 char *tail; /* Points to first "free" char */ 00017 int allocated; 00018 int free; 00019 }; 00020 00024 /*@unused@*/ static inline int xisspace(int c) /*@*/ { 00025 return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'); 00026 } 00027 00033 /*@unused@*/ static inline /*@null@*/ void * 00034 _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p) /*@modifies *p @*/ 00035 { 00036 if (p != NULL) free((void *)p); 00037 return NULL; 00038 } 00039 00040 StringBuf newStringBuf(void) 00041 { 00042 StringBuf sb = xmalloc(sizeof(*sb)); 00043 00044 sb->free = sb->allocated = BUF_CHUNK; 00045 sb->buf = xcalloc(sb->allocated, sizeof(*sb->buf)); 00046 sb->buf[0] = '\0'; 00047 sb->tail = sb->buf; 00048 00049 return sb; 00050 } 00051 00052 StringBuf freeStringBuf(StringBuf sb) 00053 { 00054 if (sb) { 00055 sb->buf = _free(sb->buf); 00056 sb = _free(sb); 00057 } 00058 return sb; 00059 } 00060 00061 void truncStringBuf(StringBuf sb) 00062 { 00063 /*@-boundswrite@*/ 00064 sb->buf[0] = '\0'; 00065 /*@=boundswrite@*/ 00066 sb->tail = sb->buf; 00067 sb->free = sb->allocated; 00068 } 00069 00070 void stripTrailingBlanksStringBuf(StringBuf sb) 00071 { 00072 /*@-bounds@*/ 00073 while (sb->free != sb->allocated) { 00074 if (! xisspace(*(sb->tail - 1))) 00075 break; 00076 sb->free++; 00077 sb->tail--; 00078 } 00079 sb->tail[0] = '\0'; 00080 /*@=bounds@*/ 00081 } 00082 00083 char * getStringBuf(StringBuf sb) 00084 { 00085 return sb->buf; 00086 } 00087 00088 void appendStringBufAux(StringBuf sb, const char *s, int nl) 00089 { 00090 int l; 00091 00092 l = strlen(s); 00093 /* If free == l there is no room for NULL terminator! */ 00094 while ((l + nl + 1) > sb->free) { 00095 sb->allocated += BUF_CHUNK; 00096 sb->free += BUF_CHUNK; 00097 sb->buf = xrealloc(sb->buf, sb->allocated); 00098 sb->tail = sb->buf + (sb->allocated - sb->free); 00099 } 00100 00101 /*@-boundswrite@*/ 00102 /*@-mayaliasunique@*/ /* FIX: shrug */ 00103 strcpy(sb->tail, s); 00104 /*@=mayaliasunique@*/ 00105 sb->tail += l; 00106 sb->free -= l; 00107 if (nl) { 00108 sb->tail[0] = '\n'; 00109 sb->tail[1] = '\0'; 00110 sb->tail++; 00111 sb->free--; 00112 } 00113 /*@=boundswrite@*/ 00114 }