diff src/vbuf.c @ 182:b65e8d0a088a

more cleanup on external names in the shared object file
author Carl Byington <carl@five-ten-sg.com>
date Mon, 13 Apr 2009 11:39:33 -0700
parents ac6e22c8a9cf
children 320cfcba8058
line wrap: on
line diff
--- a/src/vbuf.c	Fri Apr 10 13:10:14 2009 -0700
+++ b/src/vbuf.c	Mon Apr 13 11:39:33 2009 -0700
@@ -1,88 +1,6 @@
 
 #include "define.h"
 
-static int    pst_skip_nl(char *s);         // returns the width of the newline at s[0]
-static int    pst_find_nl(vstr *vs);        // find newline of type type in b
-
-// vbuf functions
-static void   pst_vbfree(vbuf *vb);
-static void   pst_vbclear(vbuf *vb);        // ditch the data, keep the buffer
-static void   pst_vbresize(vbuf *vb, size_t len);
-static size_t pst_vbavail(vbuf *vb);
-static void   pst_vbdump(vbuf *vb);
-static void   pst_vbskipws(vbuf *vb);
-static void   pst_vbskip(vbuf *vb, size_t skip);
-static void   pst_vboverwrite(vbuf *vbdest, vbuf *vbsrc);
-
-// vstr functions
-static vstr  *pst_vsalloc(size_t len);
-static char  *pst_vsb(vstr *vs);
-static size_t pst_vslen(vstr *vs);                      //strlen
-static void   pst_vsfree(vstr *vs);
-static void   pst_vsset(vstr *vs, char *s);             // Store string s in vb
-static void   pst_vsnset(vstr *vs, char *s, size_t n);  // Store string s in vb
-static void   pst_vsgrow(vstr *vs, size_t len);         // grow buffer by len bytes, data are preserved
-static size_t pst_vsavail(vstr *vs);
-static void   pst_vscat(vstr *vs, char *str);
-static void   pst_vsncat(vstr *vs, char *str, size_t len);
-static void   pst_vsnprepend(vstr *vs, char *str, size_t len) ;
-static void   pst_vsskip(vstr *vs, size_t len);
-static int    pst_vscmp(vstr *vs, char *str);
-static void   pst_vsskipws(vstr *vs);
-static void   pst_vs_printf(vstr *vs, char *fmt, ...);
-static void   pst_vs_printfa(vstr *vs, char *fmt, ...);
-static void   pst_vshexdump(vstr *vs, const char *b, size_t start, size_t stop, int ascii);
-static int    pst_vscatprintf(vstr *vs, char *fmt, ...);
-static void   pst_vsvprintf(vstr *vs, char *fmt, va_list ap);
-static void   pst_vstrunc(vstr *vs, size_t off);    // Drop chars [off..dlen]
-static int    pst_vslast(vstr *vs);                 // returns the last character stored in a vstr string
-static void   pst_vscharcat(vstr *vs, int ch);
-
-static void   pst_unicode_close();
-
-static int    pst_vb_skipline(vbuf *vb);   // in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff"
-
-
-
-
-#define ASSERT(x,...) { if( !(x) ) DIE(( __VA_ARGS__)); }
-
-
-static int pst_skip_nl(char *s)
-{
-    if (s[0] == '\n')
-        return 1;
-    if (s[0] == '\r' && s[1] == '\n')
-        return 2;
-    if (s[0] == '\0')
-        return 0;
-    return -1;
-}
-
-
-static int pst_find_nl(vstr * vs)
-{
-    char *nextr, *nextn;
-
-    nextr = memchr(vs->b, '\r', vs->dlen);
-    nextn = memchr(vs->b, '\n', vs->dlen);
-
-    //case 1: UNIX, we find \n first
-    if (nextn && (!nextr || (nextr > nextn))) {
-        return nextn - vs->b;
-    }
-    //case 2: DOS, we find \r\n
-    if (nextr && nextn && (nextn-nextr == 1)) {
-        return nextr - vs->b;
-    }
-    //case 3: we find nothing
-
-    return -1;
-}
-
-
-//  UTF8 <-> UTF16 <-> ISO8859 Character set conversion functions and (ack) their globals
-
 static int unicode_up = 0;
 static iconv_t i16to8;
 static const char *target_charset = NULL;
@@ -92,18 +10,88 @@
 static iconv_t     target2i8  = (iconv_t)-1;
 
 
-void pst_unicode_init()
+#define ASSERT(x,...) { if( !(x) ) DIE(( __VA_ARGS__)); }
+
+
+/** DESTRUCTIVELY grow or shrink buffer
+ */
+static void   pst_vbresize(pst_vbuf *vb, size_t len);
+static void pst_vbresize(pst_vbuf *vb, size_t len)
 {
-    if (unicode_up) pst_unicode_close();
-    i16to8 = iconv_open("utf-8", "utf-16le");
-    if (i16to8 == (iconv_t)-1) {
-        WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n"));
-        exit(1);
+    vb->dlen = 0;
+
+    if (vb->blen >= len) {
+        vb->b = vb->buf;
+        return;
     }
-    unicode_up = 1;
+
+    vb->buf  = realloc(vb->buf, len);
+    vb->b    = vb->buf;
+    vb->blen = len;
+}
+
+
+static size_t pst_vbavail(pst_vbuf * vb);
+static size_t pst_vbavail(pst_vbuf * vb)
+{
+    return vb->blen  - vb->dlen - (size_t)(vb->b - vb->buf);
 }
 
 
+static void open_targets(const char* charset);
+static void open_targets(const char* charset)
+{
+    if (!target_charset || strcasecmp(target_charset, charset)) {
+        if (target_open_from) iconv_close(i8totarget);
+        if (target_open_to)   iconv_close(target2i8);
+        if (target_charset)   free((char *)target_charset);
+        target_charset   = strdup(charset);
+        target_open_from = 1;
+        target_open_to   = 1;
+        i8totarget = iconv_open(target_charset, "utf-8");
+        if (i8totarget == (iconv_t)-1) {
+            target_open_from = 0;
+            WARN(("Couldn't open iconv descriptor for utf-8 to %s.\n", target_charset));
+        }
+        target2i8 = iconv_open("utf-8", target_charset);
+        if (target2i8 == (iconv_t)-1) {
+            target_open_to = 0;
+            WARN(("Couldn't open iconv descriptor for %s to utf-8.\n", target_charset));
+        }
+    }
+}
+
+
+static size_t sbcs_conversion(pst_vbuf *dest, const char *inbuf, int iblen, iconv_t conversion);
+static size_t sbcs_conversion(pst_vbuf *dest, const char *inbuf, int iblen, iconv_t conversion)
+{
+    size_t inbytesleft  = iblen;
+    size_t icresult     = (size_t)-1;
+    size_t outbytesleft = 0;
+    char *outbuf        = NULL;
+    int   myerrno;
+
+    pst_vbresize(dest, 2*iblen);
+
+    do {
+        outbytesleft = dest->blen - dest->dlen;
+        outbuf = dest->b + dest->dlen;
+        icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft);
+        myerrno  = errno;
+        dest->dlen = outbuf - dest->b;
+        if (inbytesleft) pst_vbgrow(dest, 2*inbytesleft);
+    } while ((size_t)-1 == icresult && E2BIG == myerrno);
+
+    if (icresult == (size_t)-1) {
+        DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno)));
+        pst_unicode_init();
+        return (size_t)-1;
+    }
+    return (icresult) ? (size_t)-1 : 0;
+}
+
+
+static void pst_unicode_close();
 static void pst_unicode_close()
 {
     iconv_close(i16to8);
@@ -120,7 +108,6 @@
 static int utf16_is_terminated(const char *str, int length);
 static int utf16_is_terminated(const char *str, int length)
 {
-    VSTR_STATIC(errbuf, 100);
     int len = -1;
     int i;
     for (i = 0; i < length; i += 2) {
@@ -129,16 +116,99 @@
         }
     }
 
-    if (-1 == len) {
-        pst_vshexdump(errbuf, str, 0, length, 1);
-        DEBUG_WARN(("String is not zero terminated (probably broken data from registry) %s.\n", errbuf->b));
+    if (len == -1) {
+        DEBUG_WARN(("utf16 string is not zero terminated\n"));
     }
 
-    return (-1 == len) ? 0 : 1;
+    return (len == -1) ? 0 : 1;
+}
+
+
+pst_vbuf *pst_vballoc(size_t len)
+{
+    pst_vbuf *result = pst_malloc(sizeof(pst_vbuf));
+    if (result) {
+        result->dlen = 0;
+        result->blen = 0;
+        result->buf = NULL;
+        pst_vbresize(result, len);
+    }
+    else DIE(("malloc() failure"));
+    return result;
 }
 
 
-size_t pst_vb_utf16to8(vbuf *dest, const char *inbuf, int iblen)
+/** out: vbavail(vb) >= len, data are preserved
+ */
+void pst_vbgrow(pst_vbuf *vb, size_t len)
+{
+    if (0 == len)
+        return;
+
+    if (0 == vb->blen) {
+        pst_vbresize(vb, len);
+        return;
+    }
+
+    if (vb->dlen + len > vb->blen) {
+        if (vb->dlen + len < vb->blen * 1.5)
+            len = vb->blen * 1.5;
+        char *nb = pst_malloc(vb->blen + len);
+        if (!nb) DIE(("malloc() failure"));
+        vb->blen = vb->blen + len;
+        memcpy(nb, vb->b, vb->dlen);
+
+        free(vb->buf);
+        vb->buf = nb;
+        vb->b = vb->buf;
+    } else {
+        if (vb->b != vb->buf)
+            memcpy(vb->buf, vb->b, vb->dlen);
+    }
+
+    vb->b = vb->buf;
+
+    ASSERT(pst_vbavail(vb) >= len, "vbgrow(): I have failed in my mission.");
+}
+
+
+/** set vbuf b size=len, resize if necessary, relen = how much to over-allocate
+ */
+void pst_vbset(pst_vbuf * vb, void *b, size_t len)
+{
+    pst_vbresize(vb, len);
+    memcpy(vb->b, b, len);
+    vb->dlen = len;
+}
+
+
+/** append len bytes of b to vb, resize if necessary
+ */
+void pst_vbappend(pst_vbuf *vb, void *b, size_t len)
+{
+    if (0 == vb->dlen) {
+        pst_vbset(vb, b, len);
+        return;
+    }
+    pst_vbgrow(vb, len);
+    memcpy(vb->b + vb->dlen, b, len);
+    vb->dlen += len;
+}
+
+
+void pst_unicode_init()
+{
+    if (unicode_up) pst_unicode_close();
+    i16to8 = iconv_open("utf-8", "utf-16le");
+    if (i16to8 == (iconv_t)-1) {
+        WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n"));
+        exit(1);
+    }
+    unicode_up = 1;
+}
+
+
+size_t pst_vb_utf16to8(pst_vbuf *dest, const char *inbuf, int iblen)
 {
     size_t inbytesleft  = iblen;
     size_t icresult     = (size_t)-1;
@@ -171,60 +241,7 @@
 }
 
 
-static void open_targets(const char* charset);
-static void open_targets(const char* charset)
-{
-    if (!target_charset || strcasecmp(target_charset, charset)) {
-        if (target_open_from) iconv_close(i8totarget);
-        if (target_open_to)   iconv_close(target2i8);
-        if (target_charset)   free((char *)target_charset);
-        target_charset   = strdup(charset);
-        target_open_from = 1;
-        target_open_to   = 1;
-        i8totarget = iconv_open(target_charset, "utf-8");
-        if (i8totarget == (iconv_t)-1) {
-            target_open_from = 0;
-            WARN(("Couldn't open iconv descriptor for utf-8 to %s.\n", target_charset));
-        }
-        target2i8 = iconv_open("utf-8", target_charset);
-        if (target2i8 == (iconv_t)-1) {
-            target_open_to = 0;
-            WARN(("Couldn't open iconv descriptor for %s to utf-8.\n", target_charset));
-        }
-    }
-}
-
-
-static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion);
-static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion)
-{
-    size_t inbytesleft  = iblen;
-    size_t icresult     = (size_t)-1;
-    size_t outbytesleft = 0;
-    char *outbuf        = NULL;
-    int   myerrno;
-
-    pst_vbresize(dest, 2*iblen);
-
-    do {
-        outbytesleft = dest->blen - dest->dlen;
-        outbuf = dest->b + dest->dlen;
-        icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft);
-        myerrno  = errno;
-        dest->dlen = outbuf - dest->b;
-        if (inbytesleft) pst_vbgrow(dest, 2*inbytesleft);
-    } while ((size_t)-1 == icresult && E2BIG == myerrno);
-
-    if (icresult == (size_t)-1) {
-        DEBUG_WARN(("iconv failure: %s\n", strerror(myerrno)));
-        pst_unicode_init();
-        return (size_t)-1;
-    }
-    return (icresult) ? (size_t)-1 : 0;
-}
-
-
-size_t pst_vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset)
+size_t pst_vb_utf8to8bit(pst_vbuf *dest, const char *inbuf, int iblen, const char* charset)
 {
     open_targets(charset);
     if (!target_open_from) return (size_t)-1;   // failure to open the target
@@ -232,438 +249,10 @@
 }
 
 
-size_t pst_vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset)
+size_t pst_vb_8bit2utf8(pst_vbuf *dest, const char *inbuf, int iblen, const char* charset)
 {
     open_targets(charset);
     if (!target_open_to) return (size_t)-1;     // failure to open the target
     return sbcs_conversion(dest, inbuf, iblen, target2i8);
 }
 
-
-vbuf *pst_vballoc(size_t len)
-{
-    vbuf *result = malloc(sizeof(vbuf));
-    if (result) {
-        result->dlen = 0;
-        result->blen = 0;
-        result->buf = NULL;
-        pst_vbresize(result, len);
-    }
-    else DIE(("malloc() failure"));
-    return result;
-}
-
-
-static void pst_vbcheck(vbuf * vb)
-{
-    ASSERT(vb->b >= vb->buf, "vbcheck(): data not inside buffer");
-    ASSERT((size_t)(vb->b - vb->buf) <= vb->blen, "vbcheck(): vb->b outside of buffer range.");
-    ASSERT(vb->dlen <= vb->blen, "vbcheck(): data length > buffer length.");
-    ASSERT(vb->blen < 1024 * 1024, "vbcheck(): blen is a bit large...hmmm.");
-}
-
-
-static void pst_vbfree(vbuf * vb)
-{
-    free(vb->buf);
-    free(vb);
-}
-
-
-static void pst_vbclear(vbuf *vb) // ditch the data, keep the buffer
-{
-    pst_vbresize(vb, 0);
-}
-
-
-static void pst_vbresize(vbuf *vb, size_t len)    // DESTRUCTIVELY grow or shrink buffer
-{
-    vb->dlen = 0;
-
-    if (vb->blen >= len) {
-        vb->b = vb->buf;
-        return;
-    }
-
-    vb->buf  = realloc(vb->buf, len);
-    vb->b    = vb->buf;
-    vb->blen = len;
-}
-
-
-static size_t pst_vbavail(vbuf * vb)
-{
-    return vb->blen  - vb->dlen - (size_t)(vb->b - vb->buf);
-}
-
-
-void pst_vbgrow(vbuf *vb, size_t len)      // out: vbavail(vb) >= len, data are preserved
-{
-    if (0 == len)
-        return;
-
-    if (0 == vb->blen) {
-        pst_vbresize(vb, len);
-        return;
-    }
-
-    if (vb->dlen + len > vb->blen) {
-        if (vb->dlen + len < vb->blen * 1.5)
-            len = vb->blen * 1.5;
-        char *nb = pst_malloc(vb->blen + len);
-        if (!nb) DIE(("malloc() failure"));
-        vb->blen = vb->blen + len;
-        memcpy(nb, vb->b, vb->dlen);
-
-        free(vb->buf);
-        vb->buf = nb;
-        vb->b = vb->buf;
-    } else {
-        if (vb->b != vb->buf)
-            memcpy(vb->buf, vb->b, vb->dlen);
-    }
-
-    vb->b = vb->buf;
-
-    ASSERT(pst_vbavail(vb) >= len, "vbgrow(): I have failed in my mission.");
-}
-
-
-void pst_vbset(vbuf * vb, void *b, size_t len)      // set vbuf b size=len, resize if necessary, relen = how much to over-allocate
-{
-    pst_vbresize(vb, len);
-    memcpy(vb->b, b, len);
-    vb->dlen = len;
-}
-
-
-static void pst_vsskipws(vstr * vs)
-{
-    char *p = vs->b;
-    while ((size_t)(p - vs->b) < vs->dlen && isspace(p[0]))
-        p++;
-
-    pst_vbskip((vbuf *) vs, p - vs->b);
-}
-
-
-// append len bytes of b to vbuf, resize if necessary
-void pst_vbappend(vbuf *vb, void *b, size_t len)
-{
-    if (0 == vb->dlen) {
-        pst_vbset(vb, b, len);
-        return;
-    }
-    pst_vbgrow(vb, len);
-    memcpy(vb->b + vb->dlen, b, len);
-    vb->dlen += len;
-}
-
-
-// dumps the first skip bytes from vbuf
-static void pst_vbskip(vbuf *vb, size_t skip)
-{
-    ASSERT(skip <= vb->dlen, "vbskip(): Attempt to seek past end of buffer.");
-    vb->b += skip;
-    vb->dlen -= skip;
-}
-
-
-// overwrite vbdest with vbsrc
-static void pst_vboverwrite(vbuf *vbdest, vbuf *vbsrc)
-{
-    pst_vbresize(vbdest, vbsrc->blen);
-    memcpy(vbdest->b, vbsrc->b, vbsrc->dlen);
-    vbdest->blen = vbsrc->blen;
-    vbdest->dlen = vbsrc->dlen;
-}
-
-
-static vstr *pst_vsalloc(size_t len)
-{
-    vstr *result = (vstr *) pst_vballoc(len + 1);
-    pst_vsset(result, "");
-    return result;
-}
-
-
-static char *pst_vsstr(vstr * vs);
-static char *pst_vsstr(vstr * vs)
-{
-    return vs->b;
-}
-
-
-static size_t pst_vslen(vstr * vs)
-{
-    return strlen(pst_vsstr(vs));
-}
-
-
-static void pst_vsfree(vstr * vs)
-{
-    pst_vbfree((vbuf *) vs);
-}
-
-
-static void pst_vscharcat(vstr * vb, int ch)
-{
-    pst_vbgrow((vbuf *) vb, 1);
-    vb->b[vb->dlen - 1] = ch;
-    vb->b[vb->dlen] = '\0';
-    vb->dlen++;
-}
-
-
-// prependappend string str to vbuf, vbuf must already contain a valid string
-static void pst_vsnprepend(vstr * vb, char *str, size_t len)
-{
-    ASSERT(vb->b[vb->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string.");
-    size_t sl = strlen(str);
-    size_t n = (sl < len) ? sl : len;
-    pst_vbgrow((vbuf *) vb, n + 1);
-    memmove(vb->b + n, vb->b, vb->dlen - 1);
-    memcpy(vb->b, str, n);
-    vb->dlen += n;
-    vb->b[vb->dlen - 1] = '\0';
-}
-
-
-// len < dlen-1 -> skip len chars, else DIE
-static void pst_vsskip(vstr * vs, size_t len)
-{
-    ASSERT(len < vs->dlen - 1, "Attempt to skip past end of string");
-    pst_vbskip((vbuf *) vs, len);
-}
-
-
-// in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff"
-static int pst_vsskipline(vstr * vs)
-{
-    int nloff = pst_find_nl(vs);
-    int nll   = pst_skip_nl(vs->b + nloff);
-
-    if (nloff < 0) {
-        //TODO: error
-        printf("vb_skipline(): there seems to be no newline here.\n");
-        return -1;
-    }
-    if (nll < 0) {
-        //TODO: error
-        printf("vb_skipline(): there seems to be no newline here...except there should be. :P\n");
-        return -1;
-    }
-
-    memmove(vs->b, vs->b + nloff + nll, vs->dlen - nloff - nll);
-
-    vs->dlen -= nloff + nll;
-
-    return 0;
-}
-
-
-static int pst_vscatprintf(vstr * vs, char *fmt, ...)
-{
-    int size;
-    va_list ap;
-
-    /* Guess we need no more than 100 bytes. */
-    //vsresize( vb, 100 );
-    if (!vs->b || vs->dlen == 0) {
-        pst_vsset(vs, "");
-    }
-
-    while (1) {
-        /* Try to print in the allocated space. */
-        va_start(ap, fmt);
-        size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen, fmt, ap);
-        va_end(ap);
-
-        /* If that worked, return the string. */
-        if ((size > -1) && ((size_t)size < vs->blen - vs->dlen)) {
-            vs->dlen += size;
-            return size;
-        }
-        /* Else try again with more space. */
-        if (size >= 0)          /* glibc 2.1 */
-            pst_vbgrow((vbuf *) vs, size + 1);      /* precisely what is needed */
-        else                    /* glibc 2.0 */
-            pst_vbgrow((vbuf *) vs, vs->blen);
-    }
-}
-
-
-//  returns the last character stored in a vstr
-static int pst_vslast(vstr * vs)
-{
-    if (vs->dlen < 1)
-        return -1;
-    if (vs->b[vs->dlen - 1] != '\0')
-        return -1;
-    if (vs->dlen == 1)
-        return '\0';
-    return vs->b[vs->dlen - 2];
-}
-
-
-//  print over vb
-static void pst_vs_printf(vstr * vs, char *fmt, ...)
-{
-    int size;
-    va_list ap;
-
-    /* Guess we need no more than 100 bytes. */
-    pst_vbresize((vbuf *) vs, 100);
-
-    while (1) {
-        /* Try to print in the allocated space. */
-        va_start(ap, fmt);
-        size = vsnprintf(vs->b, vs->blen, fmt, ap);
-        va_end(ap);
-
-        /* If that worked, return the string. */
-        if ((size > -1) && ((size_t)size < vs->blen)) {
-            vs->dlen = size + 1;
-            return;
-        }
-        /* Else try again with more space. */
-        if (size >= 0)          /* glibc 2.1 */
-            pst_vbresize((vbuf *) vs, size + 1);    /* precisely what is needed */
-        else                    /* glibc 2.0 */
-            pst_vbresize((vbuf *) vs, vs->blen * 2);
-    }
-}
-
-
-// printf append to vs
-static void pst_vs_printfa(vstr * vs, char *fmt, ...)
-{
-    int size;
-    va_list ap;
-
-    if (vs->blen - vs->dlen < 50)
-        pst_vbgrow((vbuf *) vs, 100);
-
-    while (1) {
-        /* Try to print in the allocated space. */
-        va_start(ap, fmt);
-        size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen + 1, fmt, ap);
-        va_end(ap);
-
-        /* If that worked, return the string. */
-        if ((size > -1) && ((size_t)size < vs->blen)) {
-            vs->dlen += size;
-            return;
-        }
-        /* Else try again with more space. */
-        if (size >= 0)          /* glibc 2.1 */
-            pst_vbgrow((vbuf *) vs, size + 1 - vs->dlen);   /* precisely what is needed */
-        else                    /* glibc 2.0 */
-            pst_vbgrow((vbuf *) vs, size);
-    }
-}
-
-
-static void pst_vshexdump(vstr * vs, const char *b, size_t start, size_t stop, int ascii)
-{
-    char c;
-    int diff, i;
-
-    while (start < stop) {
-        diff = stop - start;
-        if (diff > 16)
-            diff = 16;
-
-        pst_vs_printfa(vs, ":%08X  ", start);
-
-        for (i = 0; i < diff; i++) {
-            if (8 == i)
-                pst_vs_printfa(vs, " ");
-            pst_vs_printfa(vs, "%02X ", (unsigned char) *(b + start + i));
-        }
-        if (ascii) {
-            for (i = diff; i < 16; i++)
-                pst_vs_printfa(vs, "   ");
-            for (i = 0; i < diff; i++) {
-                c = *(b + start + i);
-                pst_vs_printfa(vs, "%c", isprint(c) ? c : '.');
-            }
-        }
-        pst_vs_printfa(vs, "\n");
-        start += 16;
-    }
-}
-
-
-static void pst_vsset(vstr * vs, char *s)  // Store string s in vs
-{
-    pst_vsnset(vs, s, strlen(s));
-}
-
-
-static void pst_vsnset(vstr * vs, char *s, size_t n)       // Store string s in vs
-{
-    pst_vbresize((vbuf *) vs, n + 1);
-    memcpy(vs->b, s, n);
-    vs->b[n] = '\0';
-    vs->dlen = n + 1;
-}
-
-
-static void pst_vsgrow(vstr * vs, size_t len)      // grow buffer by len bytes, data are preserved
-{
-    pst_vbgrow((vbuf *) vs, len);
-}
-
-
-static size_t pst_vsavail(vstr * vs)
-{
-    return pst_vbavail((vbuf *) vs);
-}
-
-
-static void pst_vsnset16(vstr * vs, char *s, size_t len)   // Like vbstrnset, but for UTF16
-{
-    pst_vbresize((vbuf *) vs, len + 1);
-    memcpy(vs->b, s, len);
-
-    vs->b[len] = '\0';
-    vs->dlen = len + 1;
-    vs->b[len] = '\0';
-}
-
-
-static void pst_vscat(vstr * vs, char *str)
-{
-    pst_vsncat(vs, str, strlen(str));
-}
-
-
-static int pst_vscmp(vstr * vs, char *str)
-{
-    return strcmp(vs->b, str);
-}
-
-
-static void pst_vsncat(vstr * vs, char *str, size_t len)   // append string str to vstr, vstr must already contain a valid string
-{
-    ASSERT(vs->b[vs->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string.");
-    size_t sl = strlen(str);
-    size_t n = (sl < len) ? sl : len;
-    //string append
-    pst_vbgrow((vbuf *) vs, n + 1);
-    memcpy(vs->b + vs->dlen - 1, str, n);
-    vs->dlen += n;
-    vs->b[vs->dlen - 1] = '\0';
-}
-
-
-static void pst_vstrunc(vstr * v, size_t off) // Drop chars [off..dlen]
-{
-    if (off >= v->dlen - 1)
-        return;                 //nothing to do
-    v->b[off] = '\0';
-    v->dlen = off + 1;
-}
-
-