Main Page Modules Data Structures File List Data Fields Globals Related Pages

# 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@*/
    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 }