00001 00005 #include "system.h" 00006 00007 #include <rpmio.h> /* XXX xisspace, _free */ 00008 #include "stringbuf.h" 00009 #include "debug.h" 00010 00011 #define BUF_CHUNK 1024 00012 00013 struct StringBufRec { 00014 /*@owned@*/ 00015 char * buf; 00016 /*@dependent@*/ 00017 char * tail; /* Points to first "free" char */ 00018 size_t allocated; 00019 size_t free; 00020 }; 00021 00022 StringBuf newStringBuf(void) 00023 { 00024 StringBuf sb = xmalloc(sizeof(*sb)); 00025 00026 sb->free = sb->allocated = BUF_CHUNK; 00027 sb->buf = xcalloc(sb->allocated, sizeof(*sb->buf)); 00028 sb->buf[0] = '\0'; 00029 sb->tail = sb->buf; 00030 00031 return sb; 00032 } 00033 00034 StringBuf freeStringBuf(StringBuf sb) 00035 { 00036 if (sb) { 00037 sb->buf = _free(sb->buf); 00038 sb = _free(sb); 00039 } 00040 return sb; 00041 } 00042 00043 void truncStringBuf(StringBuf sb) 00044 { 00045 sb->buf[0] = '\0'; 00046 sb->tail = sb->buf; 00047 sb->free = sb->allocated; 00048 } 00049 00050 void stripTrailingBlanksStringBuf(StringBuf sb) 00051 { 00052 while (sb->free != sb->allocated) { 00053 if (!xisspace((int)*(sb->tail - 1))) 00054 break; 00055 sb->free++; 00056 sb->tail--; 00057 } 00058 sb->tail[0] = '\0'; 00059 } 00060 00061 char * getStringBuf(StringBuf sb) 00062 { 00063 return sb->buf; 00064 } 00065 00066 void appendStringBufAux(StringBuf sb, const char *s, size_t nl) 00067 { 00068 size_t l = strlen(s); 00069 00070 /* If free == l there is no room for NULL terminator! */ 00071 while ((l + nl) >= sb->free) { 00072 sb->allocated += BUF_CHUNK; 00073 sb->free += BUF_CHUNK; 00074 sb->buf = xrealloc(sb->buf, sb->allocated); 00075 sb->tail = sb->buf + (sb->allocated - sb->free); 00076 } 00077 00078 /*@-mayaliasunique@*/ /* FIX: shrug */ 00079 strcpy(sb->tail, s); 00080 /*@=mayaliasunique@*/ 00081 sb->tail += l; 00082 sb->free -= l; 00083 if (nl) { 00084 *sb->tail++ = '\n'; 00085 sb->free--; 00086 *sb->tail = '\0'; 00087 } 00088 }