# lib/stringbuf.c

Go to the documentation of this file.

    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 }