text: #undef NDEBUG
  #include <stdio.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <stdarg.h>
  #include <limits.h>
  #include <ctype.h>
  #include <lcthw/dbg.h>
  #include <lcthw/bstrlib.h>
  
  /*
   * This source file is part of the bstring string library.  This code was
   * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause 
   * BSD open source license or GPL v2.0. Refer to the accompanying documentation 
   * for details on usage and license.
   */ 
  static bstring dumpOut[16];
  static int rot = 0;
  static char *dumpBstring(const struct tagbstring *b)
  {
      rot = (rot + 1) % (unsigned)16;
      if (dumpOut[rot] == NULL) {
          dumpOut[rot] = bfromcstr("");
          if (dumpOut[rot] == NULL)
              return "FATAL INTERNAL ERROR";
      }
      dumpOut[rot]->slen = 0;
      if (b == NULL) {
          bcatcstr(dumpOut[rot], "NULL");
      } else {
          static char msg[256];
          sprintf(msg, "%p", (void *)b);
          bcatcstr(dumpOut[rot], msg);
          if (b->slen < 0) {
              sprintf(msg, ":[err:slen=%d<0]", b->slen);
              bcatcstr(dumpOut[rot], msg);
          } else {
              if (b->mlen > 0 && b->mlen < b->slen) {
                  sprintf(msg, ":[err:mlen=%d<slen=%d]", b->mlen,
                          b->slen);
                  bcatcstr(dumpOut[rot], msg);
              } else {
                  if (b->mlen == -1) {
                      bcatcstr(dumpOut[rot], "[p]");
                  } else if (b->mlen < 0) {
                      bcatcstr(dumpOut[rot], "[c]");
                  }
                  bcatcstr(dumpOut[rot], ":");
                  if (b->data == NULL) {
                      bcatcstr(dumpOut[rot], "[err:data=NULL]");
                  } else {
                      bcatcstr(dumpOut[rot], "\"");
                      bcatcstr(dumpOut[rot], (const char *)b->data);
                      bcatcstr(dumpOut[rot], "\"");
                  } } } } return (char *)dumpOut[rot]->data;
  }  static int test0_0(const char *s, const char *res)
  {
      bstring b0 = bfromcstr(s);
      int ret = 0;
      if (s == NULL) {
          if (res != NULL)
              ret++;
          debug(".\tbfromcstr (NULL) = %s", dumpBstring(b0));
          return ret;
      }
      ret += (res == NULL) || ((int)strlen(res) != b0->slen) 
          ||(0 != memcmp(res, b0->data, b0->slen));
      ret += b0->data[b0->slen] != '\0';
      debug(".\tbfromcstr (\"%s\") = %s", s, dumpBstring(b0));
      bdestroy(b0);
      return ret;
  }
  
  static int test0_1(const char *s, int len, const char *res)
  {
      bstring b0 = bfromcstralloc(len, s);
      int ret = 0;
      if (s == NULL) {
          if (res != NULL)
              ret++;
          debug(".\tbfromcstralloc (*, NULL) = %s", dumpBstring(b0));
          return ret;
      }
      ret += (res == NULL) || ((int)strlen(res) != b0->slen) 
          ||(0 != memcmp(res, b0->data, b0->slen));
      ret += b0->data[b0->slen] != '\0';
      ret += len > b0->mlen;
      debug(".\tbfromcstralloc (%d, \"%s\") = %s", len, s,
              dumpBstring(b0));
      bdestroy(b0);
      return ret;
  }
  
  
  #define EMPTY_STRING ""
  #define SHORT_STRING "bogus"
  #define LONG_STRING  "This is a bogus but reasonably long string.  Just long enough to cause some mallocing."
  static int test0(void)
  {
      int ret = 0;
      debug("TEST: bstring bfromcstr (const char * str);");
  
      /* tests with NULL */ 
      ret += test0_0(NULL, NULL);
  
      /* normal operation tests */ 
      ret += test0_0(EMPTY_STRING, EMPTY_STRING);
      ret += test0_0(SHORT_STRING, SHORT_STRING);
      ret += test0_0(LONG_STRING, LONG_STRING);
      debug("\t# failures: %d", ret);
      debug
          ("TEST: bstring bfromcstralloc (int len, const char * str);");
  
      /* tests with NULL */ 
      ret += test0_1(NULL, 0, NULL);
      ret += test0_1(NULL, 30, NULL);
  
      /* normal operation tests */ 
      ret += test0_1(EMPTY_STRING, 0, EMPTY_STRING);
      ret += test0_1(EMPTY_STRING, 30, EMPTY_STRING);
      ret += test0_1(SHORT_STRING, 0, SHORT_STRING);
      ret += test0_1(SHORT_STRING, 30, SHORT_STRING);
      ret += test0_1(LONG_STRING, 0, LONG_STRING);
      ret += test0_1(LONG_STRING, 30, LONG_STRING);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test1_0(const void *blk, int len, const char *res)
  {
      bstring b0 = blk2bstr(blk, len);
      int ret = 0;
      if (b0 == NULL) {
          if (res != NULL)
              ret++;
          debug(".\tblk2bstr (NULL, len=%d) = %s", len, dumpBstring(b0));
      } else {
          ret += (res == NULL) || (len != b0->slen) 
              ||(0 != memcmp(res, b0->data, len));
          ret += b0->data[b0->slen] != '\0';
          debug(".\tblk2bstr (blk=%p, len=%d) = %s", blk, len,
                  dumpBstring(b0));
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      bdestroy(b0);
      return ret;
  }
  
  static int test1(void)
  {
      int ret = 0;
      debug("TEST: bstring blk2bstr (const void * blk, int len);");
  
      /* tests with NULL */ 
      ret += test1_0(NULL, 10, NULL);
      ret += test1_0(NULL, 0, NULL);
      ret += test1_0(NULL, -1, NULL);
  
      /* normal operation tests */ 
      ret +=
          test1_0(SHORT_STRING, sizeof(SHORT_STRING) - 1, SHORT_STRING);
      ret += test1_0(LONG_STRING, sizeof(LONG_STRING) - 1, LONG_STRING);
      ret += test1_0(LONG_STRING, 5, "This ");
      ret += test1_0(LONG_STRING, 0, "");
      ret += test1_0(LONG_STRING, -1, NULL);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test2_0(const_bstring b, char z, const unsigned char *res)
  {
      char *s = bstr2cstr(b, z);
      int ret = 0;
      if (s == NULL) {
          if (res != NULL)
              ret++;
          debug(".\tbstr2cstr (%s, %02X) = NULL", dumpBstring(b), z);
          bcstrfree(s);
          return ret;
      }
      if (res == NULL)
          ret++;
  
      else {
          if (z != '\0')
              if ((int)strlen(s) != b->slen)
                  ret++;
          if (!ret) {
              ret += (0 != memcmp(res, b->data, b->slen));
          }
      }
      debug(".\tbstr2cstr (%s, %02X) = \"%s\"", dumpBstring(b), z, s);
      bcstrfree(s);
      return ret;
  }
  
  struct tagbstring emptyBstring = bsStatic("");
  struct tagbstring shortBstring = bsStatic("bogus");
  struct tagbstring longBstring =
  bsStatic
  ("This is a bogus but reasonably long string.  Just long enough to cause some mallocing.");
  struct tagbstring badBstring1 = { 8, 4, NULL };
  struct tagbstring badBstring2 = { 2, -5, (unsigned char *)"bogus" };
  struct tagbstring badBstring3 = { 2, 5, (unsigned char *)"bogus" };
  
  struct tagbstring xxxxxBstring = bsStatic("xxxxx");
  static int test2(void)
  {
      int ret = 0;
      debug("TEST: char * bstr2cstr (const_bstring s, char z);");
  
      /* tests with NULL */ 
      ret += test2_0(NULL, (char)'?', NULL);
  
      /* normal operation tests */ 
      ret += test2_0(&emptyBstring, (char)'?', emptyBstring.data);
      ret += test2_0(&shortBstring, (char)'?', shortBstring.data);
      ret += test2_0(&longBstring, (char)'?', longBstring.data);
      ret += test2_0(&badBstring1, (char)'?', NULL);
      ret += test2_0(&badBstring2, (char)'?', NULL);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test3_0(const_bstring b)
  {
      bstring b0 = bstrcpy(b);
      int ret = 0;
      debug(".\tbstrcpy (%s) = %s", dumpBstring(b), dumpBstring(b0));
      if (b0 == NULL) {
          if (b != NULL && b->data != NULL && b->slen >= 0)
              ret++;
      } else {
          ret += (b == NULL) || (b->slen != b0->slen) 
              ||(0 != memcmp(b->data, b0->data, b->slen));
          ret += b0->data[b0->slen] != '\0';
      }
      bdestroy(b0);
      return ret;
  }
  
  static int test3(void)
  {
      int ret = 0;
      debug("TEST: bstring bstrcpy (const_bstring b1);");
  
      /* tests with NULL to make sure that there is NULL propogation */ 
      ret += test3_0(NULL);
      ret += test3_0(&badBstring1);
      ret += test3_0(&badBstring2);
  
      /* normal operation tests */ 
      ret += test3_0(&emptyBstring);
      ret += test3_0(&shortBstring);
      ret += test3_0(&longBstring);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test4_0(const_bstring b, int left, int len,
          const char *res)
  {
      bstring b0 = bmidstr(b, left, len);
      int ret = 0;
      debug(".\tbmidstr (%s, %d, %d) = %s", dumpBstring(b), left, len,
              dumpBstring(b0));
      if (b0 == NULL) {
          if (b != NULL && b->data != NULL && b->slen >= 0 && len >= 0)
              ret++;
      } else {
          ret += (b == NULL) || (res == NULL) || (b0->slen > len
                  && len >=
                  0)  ||(b0->slen !=
                      (int)
                      strlen(res)) 
                  ||(b0->slen > 0 && 0 != memcmp(res, b0->data, b0->slen));
          ret += b0->data[b0->slen] != '\0';
      } if (ret) {
          debug("(b == NULL)                  = %d", (b == NULL));
          debug("(res == NULL)                = %d", (res == NULL));
          debug("(b0->slen > len && len >= 0) = %d",
                  (b0->slen > len && len >= 0));
          if (res)
              debug("(b0->slen != strlen (res))   = %d",
                      (b0->slen != (int)strlen(res)));
          debug
              ("(b0->slen > 0 && 0 != memcmp (res, b0->data, b0->slen) = %d",
               (b0->slen > 0 && 0 != memcmp(res, b0->data, b0->slen)));
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      bdestroy(b0);
      return ret;
  }
  
  static int test4(void)
  {
      int ret = 0;
      debug
          ("TEST: bstring bmidstr (const_bstring b, int left, int len);");
  
      /* tests with NULL to make sure that there is NULL propogation */ 
      ret += test4_0(NULL, 0, 0, NULL);
      ret += test4_0(NULL, 0, 2, NULL);
      ret += test4_0(NULL, 0, -2, NULL);
      ret += test4_0(NULL, -5, 2, NULL);
      ret += test4_0(NULL, -5, -2, NULL);
      ret += test4_0(&badBstring1, 1, 3, NULL);
      ret += test4_0(&badBstring2, 1, 3, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test4_0(&emptyBstring, 0, 0, "");
      ret += test4_0(&emptyBstring, 0, -1, "");
      ret += test4_0(&emptyBstring, 1, 3, "");
      ret += test4_0(&shortBstring, 0, 0, "");
      ret += test4_0(&shortBstring, 0, -1, "");
      ret += test4_0(&shortBstring, 1, 3, "ogu");
      ret += test4_0(&shortBstring, -1, 3, "bo");
      ret += test4_0(&shortBstring, -1, 9, "bogus");
      ret += test4_0(&shortBstring, 3, -1, "");
      ret += test4_0(&shortBstring, 9, 3, "");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test5_0(bstring b0, const_bstring b1, const char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && b1 != NULL && b1->data != NULL && b1->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbconcat (%s, ", dumpBstring(b2));
          rv = bconcat(b2, b1);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%s) = %s", dumpBstring(b1), dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbconcat (%s, ", dumpBstring(b2));
          rv = bconcat(b2, b1);
          debug("%s) = %s", dumpBstring(b1), dumpBstring(b2));
          if (b1)
              ret += (b2->slen != b0->slen + b1->slen);
          ret += ((0 != rv) && (b1 != NULL)) || ((0 == rv)
                  && (b1 == NULL));
          ret += (res == NULL)
              || ((int)strlen(res) > b2->slen)  ||(0 !=
                      memcmp(b2->data, res,
                          b2->slen));
          ret += b2->data[b2->slen] != '\0';
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = bconcat(b0, b1)));
          debug(".\tbconcat (%s, %s) = %d", dumpBstring(b0),
                  dumpBstring(b1), rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test5_1(void)
  {
      bstring b, c;
      struct tagbstring t;
      int i, ret;
      debug("TEST: bconcat aliasing");
      for (ret = i = 0; i < longBstring.slen; i++) {
          b = bstrcpy(&longBstring);
          c = bstrcpy(&longBstring);
          bmid2tbstr(t, b, i, longBstring.slen);
          ret += 0 != bconcat(c, &t);
          ret += 0 != bconcat(b, &t);
          ret += !biseq(b, c);
          bdestroy(b);
          bdestroy(c);
      }
      b = bfromcstr("abcd");
      c = bfromcstr("abcd");
      for (ret = i = 0; i < 100; i++) {
          bmid2tbstr(t, b, 0, 3);
          ret += 0 != bcatcstr(c, "abc");
          ret += 0 != bconcat(b, &t);
          ret += !biseq(b, c);
      }
      bdestroy(b);
      bdestroy(c);
      if (ret) {
          debug("\t\talias failures(%d) = %d", __LINE__, ret);
      }
      return ret;
  }
  
  static int test5(void)
  {
      int ret = 0;
      debug("TEST: int bconcat (bstring b0, const_bstring b1);");
  
      /* tests with NULL */ 
      ret += test5_0(NULL, NULL, NULL);
      ret += test5_0(NULL, &emptyBstring, NULL);
      ret += test5_0(&emptyBstring, NULL, "");
      ret += test5_0(&emptyBstring, &badBstring1, NULL);
      ret += test5_0(&emptyBstring, &badBstring2, NULL);
      ret += test5_0(&badBstring1, &emptyBstring, NULL);
      ret += test5_0(&badBstring2, &emptyBstring, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test5_0(&emptyBstring, &emptyBstring, "");
      ret += test5_0(&emptyBstring, &shortBstring, "bogus");
      ret += test5_0(&shortBstring, &emptyBstring, "bogus");
      ret += test5_0(&shortBstring, &shortBstring, "bogusbogus");
      ret += test5_1();
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test6_0(bstring b, char c, const char *res)
  {
      bstring b0;
      int rv, ret = 0;
      if (b != NULL && b->data != NULL && b->slen >= 0) {
          b0 = bstrcpy(b);
          bwriteprotect(*b0);
          rv = bconchar(b0, c);
          ret += (rv == 0);
          if (!biseq(b0, b))
              ret++;
          debug(".\tbconchar (%s, %c) = %s", dumpBstring(b), c,
                  dumpBstring(b0));
          bwriteallow(*b0);
          rv = bconchar(b0, c);
          ret += (0 != rv);
          ret += (b0->slen != b->slen + 1);
          ret += (res == NULL) || ((int)strlen(res) > b0->slen) 
              ||(0 != memcmp(b0->data, res, b0->slen));
          ret += b0->data[b0->slen] != '\0';
          debug(".\tbconchar (%s, %c) = %s", dumpBstring(b), c,
                  dumpBstring(b0));
          bdestroy(b0);
      } else {
          ret += (BSTR_ERR != (rv = bconchar(b, c)));
          debug(".\tbconchar (%s, %c) = %d", dumpBstring(b), c, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test6(void)
  {
      int ret = 0;
      debug("TEST: int bconchar (bstring b, char c);");
  
      /* tests with NULL */ 
      ret += test6_0(NULL, (char)'x', NULL);
      ret += test6_0(&badBstring1, (char)'x', NULL);
      ret += test6_0(&badBstring2, (char)'x', NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test6_0(&emptyBstring, (char)'x', "x");
      ret += test6_0(&shortBstring, (char)'x', "bogusx");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test7x8_0(char *fnname,
          int (*fnptr) (const struct tagbstring *,
              const struct tagbstring *),
          const struct tagbstring *b0,
          const struct tagbstring *b1, int res)
  {
      int rv, ret = 0;
      ret += (res != (rv = fnptr(b0, b1)));
      debug(".\t%s (%s, %s) = %d", fnname, dumpBstring(b0),
              dumpBstring(b1), rv);
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %d)", __LINE__, ret, res);
      }
      return ret;
  }
  
  static int test7x8(char *fnname,
          int (*fnptr) (const struct tagbstring *,
              const struct tagbstring *),
          int retFail, int retLT, int retGT, int retEQ)
  {
      int ret = 0;
      debug("TEST: int %s (const_bstring b0, const_bstring b1);",
              fnname);
  
      /* tests with NULL */ 
      ret += test7x8_0(fnname, fnptr, NULL, NULL, retFail);
      ret += test7x8_0(fnname, fnptr, &emptyBstring, NULL, retFail);
      ret += test7x8_0(fnname, fnptr, NULL, &emptyBstring, retFail);
      ret += test7x8_0(fnname, fnptr, &shortBstring, NULL, retFail);
      ret += test7x8_0(fnname, fnptr, NULL, &shortBstring, retFail);
      ret +=
          test7x8_0(fnname, fnptr, &badBstring1, &badBstring1, retFail);
      ret +=
          test7x8_0(fnname, fnptr, &badBstring2, &badBstring2, retFail);
      ret +=
          test7x8_0(fnname, fnptr, &shortBstring, &badBstring2, retFail);
      ret +=
          test7x8_0(fnname, fnptr, &badBstring2, &shortBstring, retFail);
  
      /* normal operation tests on all sorts of subranges */ 
      ret +=
          test7x8_0(fnname, fnptr, &emptyBstring, &emptyBstring, retEQ);
      ret +=
          test7x8_0(fnname, fnptr, &shortBstring, &emptyBstring, retGT);
      ret +=
          test7x8_0(fnname, fnptr, &emptyBstring, &shortBstring, retLT);
      ret +=
          test7x8_0(fnname, fnptr, &shortBstring, &shortBstring, retEQ);
      {
          bstring b = bstrcpy(&shortBstring);
          b->data[1]++;
          ret += test7x8_0(fnname, fnptr, b, &shortBstring, retGT);
          bdestroy(b);
      }  if (fnptr == biseq) {
          ret +=
              test7x8_0(fnname, fnptr, &shortBstring, &longBstring,
                      retGT);
          ret +=
              test7x8_0(fnname, fnptr, &longBstring, &shortBstring,
                      retLT);
      } else {
          ret +=
              test7x8_0(fnname, fnptr, &shortBstring, &longBstring,
                      'b' - 'T');
          ret +=
              test7x8_0(fnname, fnptr, &longBstring, &shortBstring,
                      'T' - 'b');
      }
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  
  #define test7() test7x8 ("biseq", biseq, -1, 0, 0, 1)
  #define test8() test7x8 ("bstrcmp", bstrcmp, SHRT_MIN, -1, 1, 0)
  static int test9_0(const_bstring b0, const_bstring b1, int n, int res)
  {
      int rv, ret = 0;
      ret += (res != (rv = bstrncmp(b0, b1, n)));
      debug(".\tbstrncmp (%s, %s, %d) = %d", dumpBstring(b0),
              dumpBstring(b1), n, rv);
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %d)", __LINE__, ret, res);
      }
      return ret;
  }
  
  static int test9(void)
  {
      int ret = 0;
      debug
          ("TEST: int bstrncmp (const_bstring b0, const_bstring b1, int n);");
  
      /* tests with NULL */ 
      ret += test9_0(NULL, NULL, 0, SHRT_MIN);
      ret += test9_0(NULL, NULL, -1, SHRT_MIN);
      ret += test9_0(NULL, NULL, 1, SHRT_MIN);
      ret += test9_0(&emptyBstring, NULL, 0, SHRT_MIN);
      ret += test9_0(NULL, &emptyBstring, 0, SHRT_MIN);
      ret += test9_0(&emptyBstring, NULL, 1, SHRT_MIN);
      ret += test9_0(NULL, &emptyBstring, 1, SHRT_MIN);
      ret += test9_0(&badBstring1, &badBstring1, 1, SHRT_MIN);
      ret += test9_0(&badBstring2, &badBstring2, 1, SHRT_MIN);
      ret += test9_0(&emptyBstring, &badBstring1, 1, SHRT_MIN);
      ret += test9_0(&emptyBstring, &badBstring2, 1, SHRT_MIN);
      ret += test9_0(&badBstring1, &emptyBstring, 1, SHRT_MIN);
      ret += test9_0(&badBstring2, &emptyBstring, 1, SHRT_MIN);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test9_0(&emptyBstring, &emptyBstring, -1, 0);
      ret += test9_0(&emptyBstring, &emptyBstring, 0, 0);
      ret += test9_0(&emptyBstring, &emptyBstring, 1, 0);
      ret += test9_0(&shortBstring, &shortBstring, -1, 0);
      ret += test9_0(&shortBstring, &shortBstring, 0, 0);
      ret += test9_0(&shortBstring, &shortBstring, 1, 0);
      ret += test9_0(&shortBstring, &shortBstring, 9, 0);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test10_0(bstring b, int res, int nochange)
  {
      struct tagbstring sb = bsStatic("<NULL>");
      int rv, x, ret = 0;
      if (b)
          sb = *b;
      debug(".\tbdestroy (%s) = ", dumpBstring(b));
      rv = bdestroy(b);
      debug("%d", rv);
      if (b != NULL) {
          if (rv >= 0)
  
              /* If the bdestroy was successful we have to assume
                 the contents were "changed" */ 
              x = 1;
  
          else
              x = memcmp(&sb, b, sizeof sb);
      } else
          x = !nochange;
      ret += (rv != res);
      ret += (!nochange) == (!x);
      if (ret) {
          debug
              ("\t\tfailure(%d) res = %d nochange = %d, x = %d, sb.slen = %d, sb.mlen = %d, sb.data = %p",
               __LINE__, res, nochange, x, sb.slen, sb.mlen, sb.data);
      }
      return ret;
  }
  
  static int test10(void)
  {
      bstring c = bstrcpy(&shortBstring);
      bstring b = bstrcpy(&emptyBstring);
      int ret = 0;
      debug("TEST: int bdestroy (const_bstring b);");
  
      /* tests with NULL */ 
      ret += test10_0(NULL, BSTR_ERR, 1);
  
      /* protected, constant and regular instantiations on empty or not */ 
      bwriteprotect(*b);
      bwriteprotect(*c);
      ret += test10_0(b, BSTR_ERR, 1);
      ret += test10_0(c, BSTR_ERR, 1);
      bwriteallow(*b);
      bwriteallow(*c);
      ret += test10_0(b, BSTR_OK, 0);
      ret += test10_0(c, BSTR_OK, 0);
      ret += test10_0(&emptyBstring, BSTR_ERR, 1);
      bwriteallow(emptyBstring);
      ret += test10_0(&emptyBstring, BSTR_ERR, 1);
      ret += test10_0(&shortBstring, BSTR_ERR, 1);
      bwriteallow(emptyBstring);
      ret += test10_0(&shortBstring, BSTR_ERR, 1);
      ret += test10_0(&badBstring1, BSTR_ERR, 1);
      ret += test10_0(&badBstring2, BSTR_ERR, 1);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test11_0(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbinstr (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = binstr(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test11_1(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbinstrcaseless (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = binstrcaseless(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test11(void)
  {
      bstring b, c;
      int ret = 0;
      debug
          ("TEST: int binstr (const_bstring s1, int pos, const_bstring s2);");
      ret += test11_0(NULL, 0, NULL, BSTR_ERR);
      ret += test11_0(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test11_0(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test11_0(&emptyBstring, 0, &badBstring1, BSTR_ERR);
      ret += test11_0(&emptyBstring, 0, &badBstring2, BSTR_ERR);
      ret += test11_0(&badBstring1, 0, &emptyBstring, BSTR_ERR);
      ret += test11_0(&badBstring2, 0, &emptyBstring, BSTR_ERR);
      ret += test11_0(&badBstring1, 0, &badBstring2, BSTR_ERR);
      ret += test11_0(&badBstring2, 0, &badBstring1, BSTR_ERR);
      ret += test11_0(&emptyBstring, 0, &emptyBstring, 0);
      ret += test11_0(&emptyBstring, 1, &emptyBstring, BSTR_ERR);
      ret += test11_0(&shortBstring, 1, &shortBstring, BSTR_ERR);
      ret += test11_0(&shortBstring, 5, &emptyBstring, 5);
      ret += test11_0(&shortBstring, -1, &shortBstring, BSTR_ERR);
      ret += test11_0(&shortBstring, 0, &shortBstring, 0);
      ret += test11_0(&shortBstring, 0, b = bstrcpy(&shortBstring), 0);
      bdestroy(b);
      ret += test11_0(&shortBstring, 0, b =
              bfromcstr("BOGUS"), BSTR_ERR);
      bdestroy(b);
      ret += test11_0(&longBstring, 0, &shortBstring, 10);
      ret += test11_0(&longBstring, 20, &shortBstring, BSTR_ERR);
      ret += test11_0(c = bfromcstr("sssssssssap"), 0, b =
              bfromcstr("sap"), 8);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("sssssssssap"), 3, b =
              bfromcstr("sap"), 8);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("ssssssssssap"), 3, b =
              bfromcstr("sap"), 9);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("sssssssssap"), 0, b =
              bfromcstr("s"), 0);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("sssssssssap"), 3, b =
              bfromcstr("s"), 3);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("sssssssssap"), 0, b =
              bfromcstr("a"), 9);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("sssssssssap"), 5, b =
              bfromcstr("a"), 9);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("sasasasasap"), 0, b =
              bfromcstr("sap"), 8);
      bdestroy(c);
      bdestroy(b);
      ret += test11_0(c = bfromcstr("ssasasasasap"), 0, b =
              bfromcstr("sap"), 9);
      bdestroy(c);
      bdestroy(b);
      debug
          ("TEST: int binstrcaseless (const_bstring s1, int pos, const_bstring s2);");
      ret += test11_1(NULL, 0, NULL, BSTR_ERR);
      ret += test11_1(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test11_1(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test11_1(&emptyBstring, 0, &badBstring1, BSTR_ERR);
      ret += test11_1(&emptyBstring, 0, &badBstring2, BSTR_ERR);
      ret += test11_1(&badBstring1, 0, &emptyBstring, BSTR_ERR);
      ret += test11_1(&badBstring2, 0, &emptyBstring, BSTR_ERR);
      ret += test11_1(&badBstring1, 0, &badBstring2, BSTR_ERR);
      ret += test11_1(&badBstring2, 0, &badBstring1, BSTR_ERR);
      ret += test11_1(&emptyBstring, 0, &emptyBstring, 0);
      ret += test11_1(&emptyBstring, 1, &emptyBstring, BSTR_ERR);
      ret += test11_1(&shortBstring, 1, &shortBstring, BSTR_ERR);
      ret += test11_1(&shortBstring, 5, &emptyBstring, 5);
      ret += test11_1(&shortBstring, -1, &shortBstring, BSTR_ERR);
      ret += test11_1(&shortBstring, 0, &shortBstring, 0);
      ret += test11_1(&shortBstring, 0, b = bstrcpy(&shortBstring), 0);
      bdestroy(b);
      ret += test11_1(&shortBstring, 0, b = bfromcstr("BOGUS"), 0);
      bdestroy(b);
      ret += test11_1(&longBstring, 0, &shortBstring, 10);
      ret += test11_1(&longBstring, 20, &shortBstring, BSTR_ERR);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test12_0(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbinstrr (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = binstrr(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test12_1(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbinstrrcaseless (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = binstrrcaseless(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test12(void)
  {
      bstring b;
      int ret = 0;
      debug
          ("TEST: int binstrr (const_bstring s1, int pos, const_bstring s2);");
      ret += test12_0(NULL, 0, NULL, BSTR_ERR);
      ret += test12_0(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test12_0(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test12_0(&emptyBstring, 0, &badBstring1, BSTR_ERR);
      ret += test12_0(&emptyBstring, 0, &badBstring2, BSTR_ERR);
      ret += test12_0(&badBstring1, 0, &emptyBstring, BSTR_ERR);
      ret += test12_0(&badBstring2, 0, &emptyBstring, BSTR_ERR);
      ret += test12_0(&badBstring1, 0, &badBstring2, BSTR_ERR);
      ret += test12_0(&badBstring2, 0, &badBstring1, BSTR_ERR);
      ret += test12_0(&emptyBstring, 0, &emptyBstring, 0);
      ret += test12_0(&emptyBstring, 1, &emptyBstring, BSTR_ERR);
      ret += test12_0(&shortBstring, 1, &shortBstring, 0);
      ret += test12_0(&shortBstring, 5, &emptyBstring, 5);
      ret += test12_0(&shortBstring, -1, &shortBstring, BSTR_ERR);
      ret += test12_0(&shortBstring, 0, &shortBstring, 0);
      ret += test12_0(&shortBstring, 0, b = bstrcpy(&shortBstring), 0);
      bdestroy(b);
      ret += test12_0(&shortBstring, 0, b =
              bfromcstr("BOGUS"), BSTR_ERR);
      bdestroy(b);
      ret += test12_0(&longBstring, 0, &shortBstring, BSTR_ERR);
      ret += test12_0(&longBstring, 20, &shortBstring, 10);
      debug
          ("TEST: int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);");
      ret += test12_1(NULL, 0, NULL, BSTR_ERR);
      ret += test12_1(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test12_1(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test12_1(&emptyBstring, 0, &badBstring1, BSTR_ERR);
      ret += test12_1(&emptyBstring, 0, &badBstring2, BSTR_ERR);
      ret += test12_1(&badBstring1, 0, &emptyBstring, BSTR_ERR);
      ret += test12_1(&badBstring2, 0, &emptyBstring, BSTR_ERR);
      ret += test12_1(&badBstring1, 0, &badBstring2, BSTR_ERR);
      ret += test12_1(&badBstring2, 0, &badBstring1, BSTR_ERR);
      ret += test12_1(&emptyBstring, 0, &emptyBstring, 0);
      ret += test12_1(&emptyBstring, 1, &emptyBstring, BSTR_ERR);
      ret += test12_1(&shortBstring, 1, &shortBstring, 0);
      ret += test12_1(&shortBstring, 5, &emptyBstring, 5);
      ret += test12_1(&shortBstring, -1, &shortBstring, BSTR_ERR);
      ret += test12_1(&shortBstring, 0, &shortBstring, 0);
      ret += test12_1(&shortBstring, 0, b = bstrcpy(&shortBstring), 0);
      bdestroy(b);
      ret += test12_1(&shortBstring, 0, b = bfromcstr("BOGUS"), 0);
      bdestroy(b);
      ret += test12_1(&longBstring, 0, &shortBstring, BSTR_ERR);
      ret += test12_1(&longBstring, 20, &shortBstring, 10);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test13_0(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbinchr (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = binchr(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test13(void)
  {
      bstring b;
      int ret = 0;
      struct tagbstring multipleOs = bsStatic("ooooo");
      debug
          ("TEST: int binchr (const_bstring s1, int pos, const_bstring s2);");
      ret += test13_0(NULL, 0, NULL, BSTR_ERR);
      ret += test13_0(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test13_0(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test13_0(&emptyBstring, 0, &badBstring1, BSTR_ERR);
      ret += test13_0(&emptyBstring, 0, &badBstring2, BSTR_ERR);
      ret += test13_0(&badBstring1, 0, &emptyBstring, BSTR_ERR);
      ret += test13_0(&badBstring2, 0, &emptyBstring, BSTR_ERR);
      ret += test13_0(&badBstring2, 0, &badBstring1, BSTR_ERR);
      ret += test13_0(&badBstring1, 0, &badBstring2, BSTR_ERR);
      ret += test13_0(&emptyBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test13_0(&shortBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test13_0(&shortBstring, 0, &shortBstring, 0);
      ret += test13_0(&shortBstring, 0, &multipleOs, 1);
      ret += test13_0(&shortBstring, 0, b = bstrcpy(&shortBstring), 0);
      bdestroy(b);
      ret += test13_0(&shortBstring, -1, &shortBstring, BSTR_ERR);
      ret += test13_0(&shortBstring, 10, &shortBstring, BSTR_ERR);
      ret += test13_0(&shortBstring, 1, &shortBstring, 1);
      ret += test13_0(&emptyBstring, 0, &shortBstring, BSTR_ERR);
      ret += test13_0(&xxxxxBstring, 0, &shortBstring, BSTR_ERR);
      ret += test13_0(&longBstring, 0, &shortBstring, 3);
      ret += test13_0(&longBstring, 10, &shortBstring, 10);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test14_0(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbinchrr (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = binchrr(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test14(void)
  {
      bstring b;
      int ret = 0;
      debug
          ("TEST: int binchrr (const_bstring s1, int pos, const_bstring s2);");
      ret += test14_0(NULL, 0, NULL, BSTR_ERR);
      ret += test14_0(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test14_0(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test14_0(&emptyBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test14_0(&shortBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test14_0(&emptyBstring, 0, &badBstring1, BSTR_ERR);
      ret += test14_0(&emptyBstring, 0, &badBstring2, BSTR_ERR);
      ret += test14_0(&badBstring1, 0, &emptyBstring, BSTR_ERR);
      ret += test14_0(&badBstring2, 0, &emptyBstring, BSTR_ERR);
      ret += test14_0(&badBstring2, 0, &badBstring1, BSTR_ERR);
      ret += test14_0(&badBstring1, 0, &badBstring2, BSTR_ERR);
      ret += test14_0(&shortBstring, 0, &shortBstring, 0);
      ret += test14_0(&shortBstring, 0, b = bstrcpy(&shortBstring), 0);
      bdestroy(b);
      ret += test14_0(&shortBstring, -1, &shortBstring, BSTR_ERR);
      ret += test14_0(&shortBstring, 5, &shortBstring, 4);
      ret += test14_0(&shortBstring, 4, &shortBstring, 4);
      ret += test14_0(&shortBstring, 1, &shortBstring, 1);
      ret += test14_0(&emptyBstring, 0, &shortBstring, BSTR_ERR);
      ret += test14_0(&xxxxxBstring, 4, &shortBstring, BSTR_ERR);
      ret += test14_0(&longBstring, 0, &shortBstring, BSTR_ERR);
      ret += test14_0(&longBstring, 10, &shortBstring, 10);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test15_0(bstring b0, int pos, const_bstring b1,
          unsigned char fill, char *res)
  {
      bstring b2;
      int rv, ret = 0, linenum = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && b1 != NULL && b1->data != NULL && b1->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbsetstr (%s, ", dumpBstring(b2));
          rv = bsetstr(b2, pos, b1, fill);
          ret += (rv == 0);
          if (ret && 0 == linenum)
              linenum = __LINE__;
          if (!biseq(b0, b2))
              ret++;
          if (ret && 0 == linenum)
              linenum = __LINE__;
          debug("%d, %s, %02X) = %s", pos, dumpBstring(b1), fill,
                  dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbsetstr (%s, ", dumpBstring(b2));
          rv = bsetstr(b2, pos, b1, fill);
          if (b1) {
              ret += (pos >= 0) && (b2->slen != b0->slen + b1->slen)
                  && (b2->slen != pos + b1->slen);
              if (ret && 0 == linenum)
                  linenum = __LINE__;
              ret += (pos < 0) && (b2->slen != b0->slen);
              if (ret && 0 == linenum)
                  linenum = __LINE__;
          }
          ret += ((rv == 0) != (pos >= 0));
          if (ret && 0 == linenum)
              linenum = __LINE__;
          ret += (res == NULL);
          if (ret && 0 == linenum)
              linenum = __LINE__;
          ret += ((int)strlen(res) > b2->slen);
          if (ret && 0 == linenum)
              linenum = __LINE__;
          ret += (0 != memcmp(b2->data, res, b2->slen));
          if (ret && 0 == linenum)
              linenum = __LINE__;
          ret += b2->data[b2->slen] != '\0';
          if (ret && 0 == linenum)
              linenum = __LINE__;
          debug("%d, %s, %02X) = %s", pos, dumpBstring(b1), fill,
                  dumpBstring(b2));
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = bsetstr(b0, pos, b1, fill)));
          if (ret && 0 == linenum)
              linenum = __LINE__;
          debug(".\tbsetstr (%s, %d, %s, %02X) = %d", dumpBstring(b0),
                  pos, dumpBstring(b1), fill, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", linenum, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test15(void)
  {
      int ret = 0;
      debug
          ("TEST: int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);");
  
      /* tests with NULL */ 
      ret += test15_0(NULL, 0, NULL, (unsigned char)'?', NULL);
      ret += test15_0(NULL, 0, &emptyBstring, (unsigned char)'?', NULL);
      ret += test15_0(&badBstring1, 0, NULL, (unsigned char)'?', NULL);
      ret +=
          test15_0(&badBstring1, 0, &badBstring1, (unsigned char)'?',
                  NULL);
      ret +=
          test15_0(&emptyBstring, 0, &badBstring1, (unsigned char)'?',
                  NULL);
      ret +=
          test15_0(&badBstring1, 0, &emptyBstring, (unsigned char)'?',
                  NULL);
      ret += test15_0(&badBstring2, 0, NULL, (unsigned char)'?', NULL);
      ret +=
          test15_0(&badBstring2, 0, &badBstring2, (unsigned char)'?',
                  NULL);
      ret +=
          test15_0(&emptyBstring, 0, &badBstring2, (unsigned char)'?',
                  NULL);
      ret +=
          test15_0(&badBstring2, 0, &emptyBstring, (unsigned char)'?',
                  NULL);
  
      /* normal operation tests */ 
      ret +=
          test15_0(&emptyBstring, 0, &emptyBstring, (unsigned char)'?',
                  "");
      ret +=
          test15_0(&emptyBstring, 5, &emptyBstring, (unsigned char)'?',
                  "?????");
      ret +=
          test15_0(&emptyBstring, 5, &shortBstring, (unsigned char)'?',
                  "?????bogus");
      ret +=
          test15_0(&shortBstring, 0, &emptyBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test15_0(&emptyBstring, 0, &shortBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test15_0(&shortBstring, 0, &shortBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test15_0(&shortBstring, -1, &shortBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test15_0(&shortBstring, 2, &shortBstring, (unsigned char)'?',
                  "bobogus");
      ret +=
          test15_0(&shortBstring, 6, &shortBstring, (unsigned char)'?',
                  "bogus?bogus");
      ret +=
          test15_0(&shortBstring, 6, NULL, (unsigned char)'?', "bogus?");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test16_0(bstring b0, int pos, const_bstring b1,
          unsigned char fill, char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && b1 != NULL && b1->data != NULL && b1->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbinsert (%s, ", dumpBstring(b2));
          rv = binsert(b2, pos, b1, fill);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%d, %s, %02X) = %s", pos, dumpBstring(b1), fill,
                  dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbinsert (%s, ", dumpBstring(b2));
          rv = binsert(b2, pos, b1, fill);
          if (b1) {
              ret += (pos >= 0) && (b2->slen != b0->slen + b1->slen)
                  && (b2->slen != pos + b1->slen);
              ret += (pos < 0) && (b2->slen != b0->slen);
              ret += ((rv == 0) != (pos >= 0 && pos <= b2->slen));
          }
          ret += (res == NULL) || ((int)strlen(res) > b2->slen) 
              ||(0 != memcmp(b2->data, res, b2->slen));
          ret += b2->data[b2->slen] != '\0';
          debug("%d, %s, %02X) = %s", pos, dumpBstring(b1), fill,
                  dumpBstring(b2));
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = binsert(b0, pos, b1, fill)));
          debug(".\tbinsert (%s, %d, %s, %02X) = %d", dumpBstring(b0),
                  pos, dumpBstring(b1), fill, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test16(void)
  {
      int ret = 0;
      debug
          ("TEST: int binsert (bstring b0, int pos, const_bstring b1, unsigned char fill);");
  
      /* tests with NULL */ 
      ret += test16_0(NULL, 0, NULL, (unsigned char)'?', NULL);
      ret += test16_0(NULL, 0, &emptyBstring, (unsigned char)'?', NULL);
      ret += test16_0(&badBstring1, 0, NULL, (unsigned char)'?', NULL);
      ret +=
          test16_0(&badBstring1, 0, &badBstring1, (unsigned char)'?',
                  NULL);
      ret +=
          test16_0(&emptyBstring, 0, &badBstring1, (unsigned char)'?',
                  NULL);
      ret +=
          test16_0(&badBstring1, 0, &emptyBstring, (unsigned char)'?',
                  NULL);
      ret += test16_0(&badBstring2, 0, NULL, (unsigned char)'?', NULL);
      ret +=
          test16_0(&badBstring2, 0, &badBstring2, (unsigned char)'?',
                  NULL);
      ret +=
          test16_0(&emptyBstring, 0, &badBstring2, (unsigned char)'?',
                  NULL);
      ret +=
          test16_0(&badBstring2, 0, &emptyBstring, (unsigned char)'?',
                  NULL);
  
      /* normal operation tests */ 
      ret +=
          test16_0(&emptyBstring, 0, &emptyBstring, (unsigned char)'?',
                  "");
      ret +=
          test16_0(&emptyBstring, 5, &emptyBstring, (unsigned char)'?',
                  "?????");
      ret +=
          test16_0(&emptyBstring, 5, &shortBstring, (unsigned char)'?',
                  "?????bogus");
      ret +=
          test16_0(&shortBstring, 0, &emptyBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test16_0(&emptyBstring, 0, &shortBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test16_0(&shortBstring, 0, &shortBstring, (unsigned char)'?',
                  "bogusbogus");
      ret +=
          test16_0(&shortBstring, -1, &shortBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test16_0(&shortBstring, 2, &shortBstring, (unsigned char)'?',
                  "bobogusgus");
      ret +=
          test16_0(&shortBstring, 6, &shortBstring, (unsigned char)'?',
                  "bogus?bogus");
      ret +=
          test16_0(&shortBstring, 6, NULL, (unsigned char)'?', "bogus");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test17_0(bstring s1, int pos, int len, char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (s1 != NULL && s1->data != NULL && s1->slen >= 0) {
          b2 = bstrcpy(s1);
          bwriteprotect(*b2);
          debug(".\tbdelete (%s, ", dumpBstring(b2));
          rv = bdelete(b2, pos, len);
          ret += (rv == 0);
          if (!biseq(s1, b2))
              ret++;
          debug("%d, %d) = %s", pos, len, dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbdelete (%s, ", dumpBstring(b2));
          rv = bdelete(b2, pos, len);
          ret += (len >= 0) != (rv == 0);
          ret += (b2->slen > s1->slen) || (b2->slen < pos
                  && s1->slen >= pos);
          ret += (res == NULL)
              || ((int)strlen(res) > b2->slen)  ||(0 !=
                      memcmp(b2->data, res,
                          b2->slen));
          ret += b2->data[b2->slen] != '\0';
          debug("%d, %d) = %s", pos, len, dumpBstring(b2));
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = bdelete(s1, pos, len)));
          debug(".\tbdelete (%s, %d, %d) = %d", dumpBstring(s1), pos,
                  len, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test17(void)
  {
      int ret = 0;
      debug("TEST: int bdelete (bstring s1, int pos, int len);");
  
      /* tests with NULL */ 
      ret += test17_0(NULL, 0, 0, NULL);
      ret += test17_0(&badBstring1, 0, 0, NULL);
      ret += test17_0(&badBstring2, 0, 0, NULL);
  
      /* normal operation tests */ 
      ret += test17_0(&emptyBstring, 0, 0, "");
      ret += test17_0(&shortBstring, 1, 3, "bs");
      ret += test17_0(&shortBstring, -1, 3, "gus");
      ret += test17_0(&shortBstring, 1, -3, "bogus");
      ret += test17_0(&shortBstring, 3, 9, "bog");
      ret += test17_0(&shortBstring, 3, 1, "bogs");
      ret += test17_0(&longBstring, 4, 300, "This");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test18_0(bstring b, int len, int res, int mlen)
  {
      int ret = 0;
      int rv;
      int ol = 0;
      debug(".\tballoc (%s, %d) = ", dumpBstring(b), len);
      if (b)
          ol = b->mlen;
      rv = balloc(b, len);
      debug("%d", rv);
      if (b != NULL && b->data != NULL && b->slen >= 0 && ol > b->mlen) {
          debug("\t\tfailure(%d) oldmlen = %d, newmlen %d", __LINE__, ol,
                  b->mlen);
          ret++;
      }
      if (rv != res) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
          ret++;
      }
      if (b != NULL && (mlen > b->mlen || b->mlen == 0)) {
          debug("\t\tfailure(%d) b->mlen = %d mlen = %d", __LINE__,
                  b->mlen, mlen);
          ret++;
      }
      return ret;
  }
  
  static int test18_1_int(bstring b, int len, int res, int mlen,
          int __line__)
  {
      int ret = 0;
      int rv;
      int ol = 0;
      debug(".\tballocmin (%s, %d) = ", dumpBstring(b), len);
      if (b)
          ol = b->mlen;
      rv = ballocmin(b, len);
      debug("[%d] %d", __LINE__, rv);
      if (b != NULL && b->data != NULL && b->mlen != mlen) {
          debug
              ("\t\t[%d] failure(%d) oldmlen = %d, newmlen = %d, mlen = %d len = %d",
               __line__, __LINE__, ol, b->mlen, mlen, b->slen);
          ret++;
      }
      if (rv != res) {
          debug("\t\t[%d] failure(%d) res = %d", __line__, __LINE__,
                  res);
          ret++;
      }
      return ret;
  }
  
  
  #define test18_1(b, len, res, mlen) test18_1_int (b, len, res, mlen, __LINE__)
  static int test18(void)
  {
      int ret = 0, reto;
      bstring b = bfromcstr("test");
      debug("TEST: int balloc (bstring s, int len);");
  
      /* tests with NULL */ 
      ret += test18_0(NULL, 2, BSTR_ERR, 0);
      ret += test18_0(&badBstring1, 2, BSTR_ERR, 0);
      ret += test18_0(&badBstring2, 2, BSTR_ERR, 0);
  
      /* normal operation tests */ 
      ret += test18_0(b, 2, 0, b->mlen);
      ret += test18_0(b, -1, BSTR_ERR, b->mlen);
      ret += test18_0(b, 9, 0, 9);
      ret += test18_0(b, 2, 0, 9);
      bwriteprotect(*b);
      ret += test18_0(b, 4, BSTR_ERR, b->mlen);
      bwriteallow(*b);
      ret += test18_0(b, 2, 0, b->mlen);
      ret += test18_0(&emptyBstring, 9, BSTR_ERR, emptyBstring.mlen);
      bdestroy(b);
      debug("\t# failures: %d", ret);
      reto = ret;
      ret = 0;
      b = bfromcstr("test");
      debug("TEST: int ballocmin (bstring s, int len);");
  
      /* tests with NULL */ 
      ret += test18_1(NULL, 2, BSTR_ERR, 0);
      ret += test18_1(&badBstring1, 2, BSTR_ERR, 0);
      ret += test18_1(&badBstring2, 2, BSTR_ERR, 2);
  
      /* normal operation tests */ 
      ret += test18_1(b, 2, 0, b->slen + 1);
      ret += test18_1(b, -1, BSTR_ERR, b->mlen);
      ret += test18_1(b, 9, 0, 9);
      ret += test18_1(b, 2, 0, b->slen + 1);
      ret += test18_1(b, 9, 0, 9);
      bwriteprotect(*b);
      ret += test18_1(b, 4, BSTR_ERR, -1);
      bwriteallow(*b);
      ret += test18_1(b, 2, 0, b->slen + 1);
      ret += test18_1(&emptyBstring, 9, BSTR_ERR, emptyBstring.mlen);
      bdestroy(b);
      debug("\t# failures: %d", ret);
      return reto + ret;
  }
  
  static int test19_0(bstring b, int len, const char *res, int erv)
  {
      int rv, ret = 0;
      bstring b1;
      if (b != NULL && b->data != NULL && b->slen >= 0) {
          b1 = bstrcpy(b);
          bwriteprotect(*b1);
          ret += bpattern(b1, len) != BSTR_ERR;
          ret += !biseq(b1, b);
          bwriteallow(*b1);
          debug(".\tbpattern (%s, %d) = ", dumpBstring(b1), len);
          rv = bpattern(b1, len);
          debug("%s", dumpBstring(b1));
          ret += (rv != erv);
          ret += (res == NULL) || ((int)strlen(res) > b1->slen) 
              ||(0 != memcmp(b1->data, res, b1->slen));
          ret += b1->data[b1->slen] != '\0';
          bdestroy(b1);
      } else {
          ret += BSTR_ERR != (rv = bpattern(b, len));
          debug(".\tbpattern (%s, %d) = %d", dumpBstring(b), len, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) rv = %d erv = %d (res = %p", __LINE__,
                  rv, erv, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test19(void)
  {
      int ret = 0;
      debug("TEST: int bpattern (bstring b, int len);");
  
      /* tests with NULL */ 
      ret += test19_0(NULL, 0, NULL, BSTR_ERR);
      ret += test19_0(NULL, 5, NULL, BSTR_ERR);
      ret += test19_0(NULL, -5, NULL, BSTR_ERR);
      ret += test19_0(&badBstring1, 5, NULL, BSTR_ERR);
      ret += test19_0(&badBstring2, 5, NULL, BSTR_ERR);
  
      /* normal operation tests */ 
      ret += test19_0(&emptyBstring, 0, "", BSTR_ERR);
      ret += test19_0(&emptyBstring, 10, "", BSTR_ERR);
      ret += test19_0(&emptyBstring, -1, "", BSTR_ERR);
      ret += test19_0(&shortBstring, 0, "", 0);
      ret += test19_0(&shortBstring, 12, "bogusbogusbo", 0);
      ret += test19_0(&shortBstring, -1, "bogus", BSTR_ERR);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test20(void)
  {
      int ret = 0;
  
  #if !defined (BSTRLIB_NOVSNP)
      int rv;
      bstring b, c;
      debug("TEST: bstring bformat (const char * fmt, ...);");
  
      /* tests with NULL */ 
      debug(".\tbformat (NULL, 1, 2) = ");
      b = bformat(NULL, 1, 2);
      debug("%s", dumpBstring(b));
      ret += b != NULL;
  
      /* normal operation tests */ 
      debug(".\tbformat (\"%%d %%s\", 1, \"xy\") = ");
      b = bformat("%d %s", 1, "xy");
      debug("%s", dumpBstring(b));
      ret += !biseq(c = bfromcstr("1 xy"), b);
      bdestroy(b);
      debug(".\tbformat (\"%%d %%s(%%s)\", 6, %s, %s) = ",
              dumpBstring(c), dumpBstring(&shortBstring));
      b = bformat("%d %s(%s)", 6, c->data, shortBstring.data);
      debug("%s", dumpBstring(b));
      bdestroy(c);
      ret += !biseq(c = bfromcstr("6 1 xy(bogus)"), b);
      bdestroy(c);
      bdestroy(b);
      debug(".\tbformat (\"%%s%%s%%s%%s%%s%%s%%s%%s\", ...) ...");
      b = bformat("%s%s%s%s%s%s%s%s", longBstring.data,
              longBstring.data , longBstring.data,
              longBstring.data , longBstring.data,
              longBstring.data , longBstring.data,
              longBstring.data);
      c = bstrcpy(&longBstring);
      bconcat(c, c);
      bconcat(c, c);
      bconcat(c, c);
      ret += !biseq(c, b);
      bdestroy(c);
      bdestroy(b);
      debug("\t# failures: %d", ret);
      b = bfromcstr("");
      debug("TEST: int bformata (bstring b, const char * fmt, ...);");
  
      /* tests with NULL */ 
      debug(".\tbformata (%s, NULL, 1, 2) = ", dumpBstring(b));
      rv = bformata(b, NULL, 1, 2);
      debug("%d", rv);
      ret += rv != BSTR_ERR;
      debug(".\tbformata (%s, \"%%d %%d\", 1, 2) = ",
              dumpBstring(&badBstring1));
      rv = bformata(&badBstring1, "%d %d", 1, 2);
      debug("%d", rv);
      ret += rv != BSTR_ERR;
      debug(".\tbformata (%s, \"%%d %%d\", 1, 2) = ", dumpBstring(b));
      rv = bformata(b, "%d %d", 1, 2);
      debug("%s", dumpBstring(b));
      ret += !biseq(c = bfromcstr("1 2"), b);
      bdestroy(c);
      bdestroy(b);
      debug
          (".\tbformata (\"x\", \"%%s%%s%%s%%s%%s%%s%%s%%s\", ...) ...");
      rv = bformata(b =
              bfromcstr("x"), "%s%s%s%s%s%s%s%s",
              longBstring.data, longBstring.data,
              longBstring.data, longBstring.data,
              longBstring.data, longBstring.data,
              longBstring.data, longBstring.data);
      ret += rv == BSTR_ERR;
      c = bstrcpy(&longBstring);
      bconcat(c, c);
      bconcat(c, c);
      bconcat(c, c);
      binsertch(c, 0, 1, (char)'x');
      ret += !biseq(c, b);
      bdestroy(c);
      bdestroy(b);
      debug("\t# failures: %d", ret);
      b = bfromcstr("Initial");
      debug
          ("TEST: int bassignformat (bstring b, const char * fmt, ...);");
  
      /* tests with NULL */ 
      debug(".\tbassignformat (%s, NULL, 1, 2) = ", dumpBstring(b));
      rv = bassignformat(b, NULL, 1, 2);
      debug("%d", rv);
      ret += rv != BSTR_ERR;
      debug(".\tbassignformat (%s, \"%%d %%d\", 1, 2) = ",
              dumpBstring(&badBstring1));
      rv = bassignformat(&badBstring1, "%d %d", 1, 2);
      debug("%d", rv);
      ret += rv != BSTR_ERR;
      debug(".\tbassignformat (%s, \"%%d %%d\", 1, 2) = ",
              dumpBstring(b));
      rv = bassignformat(b, "%d %d", 1, 2);
      debug("%s", dumpBstring(b));
      ret += !biseq(c = bfromcstr("1 2"), b);
      bdestroy(c);
      bdestroy(b);
      debug
          (".\tbassignformat (\"x\", \"%%s%%s%%s%%s%%s%%s%%s%%s\", ...) ...");
      rv = bassignformat(b =
              bfromcstr("x"), "%s%s%s%s%s%s%s%s",
              longBstring.data, longBstring.data,
              longBstring.data, longBstring.data,
              longBstring.data, longBstring.data,
              longBstring.data, longBstring.data);
      ret += rv == BSTR_ERR;
      c = bstrcpy(&longBstring);
      bconcat(c, c);
      bconcat(c, c);
      bconcat(c, c);
      ret += !biseq(c, b);
      bdestroy(c);
      bdestroy(b);
      debug("\t# failures: %d", ret);
  
  #endif	/*  */
      return ret;
  }
  
  static int test21_0(bstring b, char sc, int ns)
  {
      struct bstrList *l;
      int ret = 0;
      debug(".\tbsplit (%s, '%c') = ", dumpBstring(b), sc);
      if (b != NULL && b->data != NULL && b->slen >= 0) {
          bstring c;
          struct tagbstring t;
          blk2tbstr(t, &sc, 1);
          debug("{");
          l = bsplit(b, sc);
          if (l) {
              int i;
              for (i = 0; i < l->qty; i++) {
                  if (i != 0)
                      debug(", ");
                  debug("%s", dumpBstring(l->entry[i]));
              }
              debug(":<%d>", l->qty);
              if (ns != l->qty)
                  ret++;
          } else {
              debug("NULL");
              ret++;
          }
          debug("}");
          c = bjoin(l, &t);
          ret += !biseq(c, b);
          bdestroy(c);
          ret += 0 != bstrListDestroy(l);
      } else {
          l = bsplit(b, sc);
          ret += (l != NULL);
          debug("%p", (void *)l);
      }  if (ret) {
          debug("\t\tfailure(%d) ns = %d", __LINE__, ns);
      }
      return ret;
  }
  
  static int test21_1(bstring b, const_bstring sc, int ns)
  {
      struct bstrList *l;
      int ret = 0;
      debug(".\tbsplitstr (%s, %s) = ", dumpBstring(b),
              dumpBstring(sc));
      if (b != NULL && b->data != NULL && b->slen >= 0) {
          bstring c;
          debug("{");
          l = bsplitstr(b, sc);
          if (l) {
              int i;
              for (i = 0; i < l->qty; i++) {
                  if (i != 0)
                      debug(", ");
                  debug("%s", dumpBstring(l->entry[i]));
              }
              debug(":<%d>", l->qty);
              if (ns != l->qty)
                  ret++;
          } else {
              debug("NULL");
              ret++;
          }
          debug("}");
          c = bjoin(l, sc);
          ret += !biseq(c, b);
          bdestroy(c);
          ret += 0 != bstrListDestroy(l);
      } else {
          l = bsplitstr(b, sc);
          ret += (l != NULL);
          debug("%p", (void *)l);
      }  if (ret) {
          debug("\t\tfailure(%d) ns = %d", __LINE__, ns);
      }
      return ret;
  }
  
  static int test21(void)
  {
      struct tagbstring is = bsStatic("is");
      struct tagbstring ng = bsStatic("ng");
      int ret = 0;
      debug
          ("TEST: struct bstrList * bsplit (const_bstring str, unsigned char splitChar);");
  
      /* tests with NULL */ 
      ret += test21_0(NULL, (char)'?', 0);
      ret += test21_0(&badBstring1, (char)'?', 0);
      ret += test21_0(&badBstring2, (char)'?', 0);
  
      /* normal operation tests */ 
      ret += test21_0(&emptyBstring, (char)'?', 1);
      ret += test21_0(&shortBstring, (char)'o', 2);
      ret += test21_0(&shortBstring, (char)'s', 2);
      ret += test21_0(&shortBstring, (char)'b', 2);
      ret += test21_0(&longBstring, (char)'o', 9);
      debug
          ("TEST: struct bstrList * bsplitstr (bstring str, const_bstring splitStr);");
      ret += test21_1(NULL, NULL, 0);
      ret += test21_1(&badBstring1, &emptyBstring, 0);
      ret += test21_1(&badBstring2, &emptyBstring, 0);
  
      /* normal operation tests */ 
      ret += test21_1(&shortBstring, &emptyBstring, 5);
      ret += test21_1(&longBstring, &is, 3);
      ret += test21_1(&longBstring, &ng, 5);
      if (0 == ret) {
          struct bstrList *l;
          unsigned char c;
          struct tagbstring t;
          bstring b;
          bstring list[3] = {
              &emptyBstring, &shortBstring, &longBstring};
          int i;
          blk2tbstr(t, &c, 1);
          for (i = 0; i < 3; i++) {
              c = (unsigned char)'\0';
              for (;;) {
                  b = bjoin(l = bsplit(list[i], c), &t);
                  if (!biseq(b, list[i])) {
                      debug("\t\tfailure(%d) ", __LINE__);
                      debug("join (bsplit (%s, x%02X), {x%02X}) = %s",
                              dumpBstring(list[i]), c, c, dumpBstring(b));
                      ret++;
                  }
                  bdestroy(b);
                  bstrListDestroy(l);
                  if (ret)
                      break;
                  b = bjoin(l = bsplitstr(list[i], &t), &t);
                  if (!biseq(b, list[i])) {
                      debug("\t\tfailure(%d) ", __LINE__);
                      debug
                          ("join (bsplitstr (%s, {x%02X}), {x%02X}) = %s",
                           dumpBstring(list[i]), c, c, dumpBstring(b));
                      ret++;
                  }
                  bdestroy(b);
                  bstrListDestroy(l);
                  if (ret)
                      break;
                  if (UCHAR_MAX == c)
                      break;
                  c++;
              }
              if (ret)
                  break;
          }
      }
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test22_0(const_bstring b, const_bstring sep, int ns, ...)
  {
      va_list arglist;
      struct bstrList *l;
      int ret = 0;
      debug(".\tbsplits (%s, %s)", dumpBstring(b), dumpBstring(sep));
      if (b != NULL && b->data != NULL && b->slen >= 0 && sep != NULL
              && sep->data != NULL && sep->slen >= 0) {
          debug(" {");
          l = bsplits(b, sep);
          if (l) {
              int i;
              va_start(arglist, ns);
              for (i = 0; i < l->qty; i++) {
                  char *res;
                  res = va_arg(arglist, char *);
                  if (i != 0)
                      debug(", ");
                  debug("%s", dumpBstring(l->entry[i]));
                  ret += (res == NULL)
                      || ((int)strlen(res) > l->entry[i]->slen)  ||(0 !=
                              memcmp
                              (l->
                               entry
                               [i]->
                               data,
                               res,
                               l->
                               entry
                               [i]->
                               slen));
                  ret += l->entry[i]->data[l->entry[i]->slen] != '\0';
              }  va_end(arglist);
              debug(":<%d>", l->qty);
              if (ns != l->qty)
                  ret++;
          } else {
              debug("NULL");
              ret += (ns != 0);
          }
          debug("}");
          ret += (0 != bstrListDestroy(l) && l != NULL);
      } else {
          l = bsplits(b, sep);
          ret += (l != NULL);
          debug(" = %p", (void *)l);
      }  if (ret) {
          debug("\t\tfailure(%d) ns = %d", __LINE__, ns);
      }
      return ret;
  }
  
  static int test22(void)
  {
      int ret = 0;
      struct tagbstring o = bsStatic("o");
      struct tagbstring s = bsStatic("s");
      struct tagbstring b = bsStatic("b");
      struct tagbstring bs = bsStatic("bs");
      struct tagbstring uo = bsStatic("uo");
      debug
          ("TEST: extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);");
  
      /* tests with NULL */ 
      ret += test22_0(NULL, &o, 0);
      ret += test22_0(&o, NULL, 0);
  
      /* normal operation tests */ 
      ret += test22_0(&emptyBstring, &o, 1, "");
      ret += test22_0(&emptyBstring, &uo, 1, "");
      ret += test22_0(&shortBstring, &emptyBstring, 1, "bogus");
      ret += test22_0(&shortBstring, &o, 2, "b", "gus");
      ret += test22_0(&shortBstring, &s, 2, "bogu", "");
      ret += test22_0(&shortBstring, &b, 2, "", "ogus");
      ret += test22_0(&shortBstring, &bs, 3, "", "ogu", "");
      ret +=
          test22_0(&longBstring, &o, 9, "This is a b", "gus but reas",
                  "nably l", "ng string.  Just l", "ng en", "ugh t",
                  " cause s", "me mall", "cing.");
      ret += test22_0(&shortBstring, &uo, 3, "b", "g", "s");
      if (0 == ret) {
          struct bstrList *l;
          unsigned char c;
          struct tagbstring t;
          bstring bb;
          bstring list[3] = {
              &emptyBstring, &shortBstring, &longBstring};
          int i;
          blk2tbstr(t, &c, 1);
          for (i = 0; i < 3; i++) {
              c = (unsigned char)'\0';
              for (;;) {
                  bb = bjoin(l = bsplits(list[i], &t), &t);
                  if (!biseq(bb, list[i])) {
                      debug("\t\tfailure(%d) ", __LINE__);
                      debug("join (bsplits (%s, {x%02X}), {x%02X}) = %s",
                              dumpBstring(list[i]), c, c, dumpBstring(bb));
                      ret++;
                  }
                  bdestroy(bb);
                  bstrListDestroy(l);
                  if (ret)
                      break;
                  if (UCHAR_MAX == c)
                      break;
                  c++;
              }
              if (ret)
                  break;
          }
      }
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  struct sbstr {
      int ofs;
      bstring b;
  };
  static size_t test23_aux_read(void *buff, size_t elsize,
          size_t nelem, void *parm)
  {
      struct sbstr *sb = (struct sbstr *)parm;
      int els, len;
      if (parm == NULL || elsize == 0 || nelem == 0)
          return 0;
      len = (int)(nelem * elsize);
      if (len <= 0)
          return 0;
      if (len + sb->ofs > sb->b->slen)
          len = sb->b->slen - sb->ofs;
      els = (int)(len / elsize);
      len = (int)(els * elsize);
      if (len > 0) {
          memcpy(buff, sb->b->data + sb->ofs, len);
          sb->ofs += len;
      }
      return els;
  }
  
  static int test23_aux_open(struct sbstr *sb, bstring b)
  {
      if (!sb || b == NULL || b->data == NULL)
          return -__LINE__;
      sb->ofs = 0;
      sb->b = b;
      return 0;
  }
  
  static int test23_aux_splitcb(void *parm, int ofs,
          const struct tagbstring *entry)
  {
      bstring b = (bstring) parm;
      ofs = ofs;
      if (b->slen > 0)
          bconchar(b, (char)'|');
      bconcat(b, entry);
      return 0;
  }
  
  struct tagBss {
      int first;
      unsigned char sc;
      bstring b;
  };
  static int test23_aux_splitcbx(void *parm, int ofs,
          const struct tagbstring *entry)
  {
      struct tagBss *p = (struct tagBss *)parm;
      ofs = ofs;
      if (!p->first) {
          bconchar(p->b, (char)p->sc);
      } else
          p->first = 0;
      bconcat(p->b, entry);
      return 0;
  }
  
  static int test23(void)
  {
      struct tagbstring space = bsStatic(" ");
      struct sbstr sb;
      struct bStream *bs;
      bstring b;
      int l, ret = 0;
      debug("TEST: bstream integrated test");
      test23_aux_open(&sb, &longBstring);
      ret += NULL != (bs = bsopen((bNread) NULL, &sb));
      ret += NULL == (bs = bsopen((bNread) test23_aux_read, &sb));
      ret += (bseof(bs) != 0);
      ret += BSTR_ERR != bsbufflength(NULL, -1);
      ret += BSTR_ERR != bsbufflength(NULL, 1);
      ret += BSTR_ERR != bsbufflength(bs, -1);
      debug(".\tbsbufflength (bs, 0) -> %d", bsbufflength(bs, 0));
      ret += BSTR_ERR == bsbufflength(bs, 1);
      ret += BSTR_ERR != bspeek(NULL, bs);
      ret += BSTR_ERR != bsreadln(NULL, bs, (char)'?');
      ret += BSTR_ERR != bsreadln(&emptyBstring, bs, (char)'?');
      ret += BSTR_ERR != bspeek(&emptyBstring, bs);
      ret += BSTR_ERR == bspeek(b = bfromcstr(""), bs);
      debug(".\tbspeek () -> %s", dumpBstring(b));
      ret += BSTR_ERR != bsreadln(b, NULL, (char)'?');
      b->slen = 0;
      ret += BSTR_ERR == bsreadln(b, bs, (char)'?');
      ret += (bseof(bs) <= 0);
      ret += biseq(b, &longBstring) < 0;
      debug(".\tbsreadln ('?') -> %s", dumpBstring(b));
      ret += BSTR_ERR == bsunread(bs, b);
      ret += (bseof(bs) != 0);
      debug(".\tbsunread (%s)", dumpBstring(b));
      b->slen = 0;
      ret += BSTR_ERR == bspeek(b, bs);
      ret += biseq(b, &longBstring) < 0;
      debug(".\tbspeek () -> %s", dumpBstring(b));
      b->slen = 0;
      ret += BSTR_ERR == bsreadln(b, bs, (char)'?');
      ret += (bseof(bs) <= 0);
      ret += biseq(b, &longBstring) < 0;
      debug(".\tbsreadln ('?') -> %s", dumpBstring(b));
      ret += NULL == bsclose(bs);
      sb.ofs = 0;
      ret += NULL == (bs = bsopen((bNread) test23_aux_read, &sb));
      b->slen = 0;
      ret += BSTR_ERR == bsreadln(b, bs, (char)'.');
      l = b->slen;
      ret += (0 != bstrncmp(b, &longBstring, l))
          || (longBstring.data[l - 1] != '.');
      debug(".\tbsreadln ('.') -> %s", dumpBstring(b));
      ret += BSTR_ERR == bsunread(bs, b);
      debug(".\tbsunread (%s)", dumpBstring(b));
      b->slen = 0;
      ret += BSTR_ERR == bspeek(b, bs);
      ret += biseq(b, &longBstring) < 0;
      debug(".\tbspeek () -> %s", dumpBstring(b));
      b->slen = 0;
      ret += BSTR_ERR == bsreadln(b, bs, (char)'.');
      ret += b->slen != l || (0 != bstrncmp(b, &longBstring, l))
          || (longBstring.data[l - 1] != '.');
      debug(".\tbsreadln ('.') -> %s", dumpBstring(b));
      ret += NULL == bsclose(bs);
      test23_aux_open(&sb, &longBstring);
      ret += NULL == (bs = bsopen((bNread) test23_aux_read, &sb));
      ret += (bseof(bs) != 0);
      b->slen = 0;
      l = bssplitscb(bs, &space, test23_aux_splitcb, b);
      ret += (bseof(bs) <= 0);
      ret += NULL == bsclose(bs);
      debug(".\tbssplitscb (' ') -> %s", dumpBstring(b));
      for (l = 1; l < 4; l++) {
          char *str;
          for (str = (char *)longBstring.data; *str; str++) {
              test23_aux_open(&sb, &longBstring);
              ret += NULL == (bs =
                      bsopen((bNread) test23_aux_read, &sb));
              ret += bseof(bs) != 0;
              ret += 0 > bsbufflength(bs, l);
              b->slen = 0;
              while (0 == bsreadlna(b, bs, *str)) ;
              ret += 0 == biseq(b, &longBstring);
              ret += bseof(bs) <= 0;
              ret += NULL == bsclose(bs);
              if (ret)
                  break;
          }
          if (ret)
              break;
      }
      bdestroy(b);
      if (0 == ret) {
          unsigned char c;
          struct tagbstring t;
          bstring list[3] = {
              &emptyBstring, &shortBstring, &longBstring};
          int i;
          blk2tbstr(t, &c, 1);
          for (i = 0; i < 3; i++) {
              c = (unsigned char)'\0';
              for (;;) {
                  struct tagBss bss;
                  bss.sc = c;
                  bss.b = bfromcstr("");
                  bss.first = 1;
                  test23_aux_open(&sb, list[i]);
                  bs = bsopen((bNread) test23_aux_read, &sb);
                  bssplitscb(bs, &t, test23_aux_splitcbx, &bss);
                  bsclose(bs);
                  if (!biseq(bss.b, list[i])) {
                      debug("\t\tfailure(%d) ", __LINE__);
                      debug
                          ("join (bssplitscb (%s, {x%02X}), {x%02X}) = %s",
                           dumpBstring(list[i]), c, c,
                           dumpBstring(bss.b));
                      ret++;
                  }
                  bdestroy(bss.b);
                  if (ret)
                      break;
                  if (UCHAR_MAX == c)
                      break;
                  c++;
              }
              if (ret)
                  break;
              for (;;) {
                  struct tagBss bss;
                  bss.sc = c;
                  bss.b = bfromcstr("");
                  bss.first = 1;
                  test23_aux_open(&sb, list[i]);
                  bs = bsopen((bNread) test23_aux_read, &sb);
                  bssplitstrcb(bs, &t, test23_aux_splitcbx, &bss);
                  bsclose(bs);
                  if (!biseq(bss.b, list[i])) {
                      debug("\t\tfailure(%d) ", __LINE__);
                      debug
                          ("join (bssplitstrcb (%s, {x%02X}), {x%02X}) = %s",
                           dumpBstring(list[i]), c, c,
                           dumpBstring(bss.b));
                      ret++;
                  }
                  bdestroy(bss.b);
                  if (ret)
                      break;
                  if (UCHAR_MAX == c)
                      break;
                  c++;
              }
              if (ret)
                  break;
          }
      }
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test24_0(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbninchr (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = bninchr(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test24(void)
  {
      bstring b;
      int ret = 0;
      debug
          ("TEST: int bninchr (const_bstring s1, int pos, const_bstring s2);");
      ret += test24_0(NULL, 0, NULL, BSTR_ERR);
      ret += test24_0(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test24_0(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test24_0(&shortBstring, 3, &badBstring1, BSTR_ERR);
      ret += test24_0(&badBstring1, 3, &shortBstring, BSTR_ERR);
      ret += test24_0(&emptyBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test24_0(&shortBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test24_0(&shortBstring, 0, &shortBstring, BSTR_ERR);
      ret += test24_0(&shortBstring, 1, &shortBstring, BSTR_ERR);
      ret += test24_0(&longBstring, 3, &shortBstring, 4);
      ret += test24_0(&longBstring, 3, b = bstrcpy(&shortBstring), 4);
      bdestroy(b);
      ret += test24_0(&longBstring, -1, &shortBstring, BSTR_ERR);
      ret += test24_0(&longBstring, 1000, &shortBstring, BSTR_ERR);
      ret += test24_0(&xxxxxBstring, 0, &shortBstring, 0);
      ret += test24_0(&xxxxxBstring, 1, &shortBstring, 1);
      ret += test24_0(&emptyBstring, 0, &shortBstring, BSTR_ERR);
      ret += test24_0(&longBstring, 0, &shortBstring, 0);
      ret += test24_0(&longBstring, 10, &shortBstring, 15);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test25_0(bstring s1, int pos, const_bstring s2, int res)
  {
      int rv, ret = 0;
      debug(".\tbninchrr (%s, %d, %s) = ", dumpBstring(s1), pos,
              dumpBstring(s2));
      rv = bninchrr(s1, pos, s2);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test25(void)
  {
      bstring b;
      int ret = 0;
      debug
          ("TEST: int bninchrr (const_bstring s1, int pos, const_bstring s2);");
      ret += test25_0(NULL, 0, NULL, BSTR_ERR);
      ret += test25_0(&emptyBstring, 0, NULL, BSTR_ERR);
      ret += test25_0(NULL, 0, &emptyBstring, BSTR_ERR);
      ret += test25_0(&emptyBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test25_0(&shortBstring, 0, &emptyBstring, BSTR_ERR);
      ret += test25_0(&shortBstring, 0, &badBstring1, BSTR_ERR);
      ret += test25_0(&badBstring1, 0, &shortBstring, BSTR_ERR);
      ret += test25_0(&shortBstring, 0, &shortBstring, BSTR_ERR);
      ret += test25_0(&shortBstring, 4, &shortBstring, BSTR_ERR);
      ret += test25_0(&longBstring, 10, &shortBstring, 9);
      ret += test25_0(&longBstring, 10, b = bstrcpy(&shortBstring), 9);
      bdestroy(b);
      ret += test25_0(&xxxxxBstring, 4, &shortBstring, 4);
      ret += test25_0(&emptyBstring, 0, &shortBstring, BSTR_ERR);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test26_0(bstring b0, int pos, int len, const_bstring b1,
          unsigned char fill, char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && b1 != NULL && b1->data != NULL && b1->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbreplace (%s, ", dumpBstring(b2));
          rv = breplace(b2, pos, len, b1, fill);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%d, %d, %s, %02X) = %s", pos, len, dumpBstring(b1),
                  fill, dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbreplace (%s, ", dumpBstring(b2));
          rv = breplace(b2, pos, len, b1, fill);
          if (b1) {
              ret += (pos < 0) && (b2->slen != b0->slen);
              ret += ((rv == 0) != (pos >= 0 && pos <= b2->slen));
          }
          ret += (res == NULL) || ((int)strlen(res) > b2->slen) 
              ||(0 != memcmp(b2->data, res, b2->slen));
          ret += b2->data[b2->slen] != '\0';
          debug("%d, %d, %s, %02X) = %s", pos, len, dumpBstring(b1),
                  fill, dumpBstring(b2));
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = breplace(b0, pos, len, b1, fill)));
          debug(".\tbreplace (%s, %d, %d, %s, %02X) = %d",
                  dumpBstring(b0), pos, len, dumpBstring(b1), fill, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test26(void)
  {
      int ret = 0;
      debug
          ("TEST: int breplace (bstring b0, int pos, int len, const_bstring b1, unsigned char fill);");
  
      /* tests with NULL */ 
      ret += test26_0(NULL, 0, 0, NULL, (unsigned char)'?', NULL);
      ret +=
          test26_0(NULL, 0, 0, &emptyBstring, (unsigned char)'?', NULL);
      ret +=
          test26_0(&badBstring1, 1, 3, &shortBstring, (unsigned char)'?',
                  NULL);
      ret +=
          test26_0(&shortBstring, 1, 3, &badBstring1, (unsigned char)'?',
                  NULL);
  
      /* normal operation tests */ 
      ret +=
          test26_0(&emptyBstring, 0, 0, &emptyBstring, (unsigned char)'?',
                  "");
      ret +=
          test26_0(&emptyBstring, 5, 0, &emptyBstring, (unsigned char)'?',
                  "?????");
      ret +=
          test26_0(&emptyBstring, 5, 0, &shortBstring, (unsigned char)'?',
                  "?????bogus");
      ret +=
          test26_0(&shortBstring, 0, 0, &emptyBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test26_0(&emptyBstring, 0, 0, &shortBstring, (unsigned char)'?',
                  "bogus");
      ret +=
          test26_0(&shortBstring, 0, 0, &shortBstring, (unsigned char)'?',
                  "bogusbogus");
      ret +=
          test26_0(&shortBstring, 1, 3, &shortBstring, (unsigned char)'?',
                  "bboguss");
      ret +=
          test26_0(&shortBstring, 3, 8, &shortBstring, (unsigned char)'?',
                  "bogbogus");
      ret +=
          test26_0(&shortBstring, -1, 0, &shortBstring,
                  (unsigned char)'?', "bogus");
      ret +=
          test26_0(&shortBstring, 2, 0, &shortBstring, (unsigned char)'?',
                  "bobogusgus");
      ret +=
          test26_0(&shortBstring, 6, 0, &shortBstring, (unsigned char)'?',
                  "bogus?bogus");
      ret +=
          test26_0(&shortBstring, 6, 0, NULL, (unsigned char)'?',
                  "bogus");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test27_0(bstring b0, const_bstring b1, const char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && b1 != NULL && b1->data != NULL && b1->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbassign (%s, ", dumpBstring(b2));
          rv = bassign(b2, b1);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%s) = %s", dumpBstring(b1), dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbassign (%s, ", dumpBstring(b2));
          rv = bassign(b2, b1);
          debug("%s) = %s", dumpBstring(b1), dumpBstring(b2));
          if (b1)
              ret += (b2->slen != b1->slen);
          ret += ((0 != rv) && (b1 != NULL)) || ((0 == rv)
                  && (b1 == NULL));
          ret += (res == NULL)
              || ((int)strlen(res) != b2->slen)  ||(0 !=
                      memcmp(b2->data, res,
                          b2->slen));
          ret += b2->data[b2->slen] != '\0';
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = bassign(b0, b1)));
          debug(".\tbassign (%s, %s) = %d", dumpBstring(b0),
                  dumpBstring(b1), rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test27(void)
  {
      int ret = 0;
      debug("TEST: int bassign (bstring b0, const_bstring b1);");
  
      /* tests with NULL */ 
      ret += test27_0(NULL, NULL, NULL);
      ret += test27_0(NULL, &emptyBstring, NULL);
      ret += test27_0(&emptyBstring, NULL, "");
      ret += test27_0(&badBstring1, &emptyBstring, NULL);
      ret += test27_0(&badBstring2, &emptyBstring, NULL);
      ret += test27_0(&emptyBstring, &badBstring1, NULL);
      ret += test27_0(&emptyBstring, &badBstring2, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test27_0(&emptyBstring, &emptyBstring, "");
      ret += test27_0(&emptyBstring, &shortBstring, "bogus");
      ret += test27_0(&shortBstring, &emptyBstring, "");
      ret += test27_0(&shortBstring, &shortBstring, "bogus");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test28_0(bstring s1, int c, int res)
  {
      int rv, ret = 0;
      debug(".\tbstrchr (%s, %d) = ", dumpBstring(s1), c);
      rv = bstrchr(s1, c);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test28_1(bstring s1, int c, int res)
  {
      int rv, ret = 0;
      debug(".\tbstrrchr (%s, %d) = ", dumpBstring(s1), c);
      rv = bstrrchr(s1, c);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d rv = %d", __LINE__, res, rv);
      }
      return ret;
  }
  
  static int test28_2(bstring s1, int c, int pos, int res)
  {
      int rv, ret = 0;
      debug(".\tbstrchrp (%s, %d, %d) = ", dumpBstring(s1), c, pos);
      rv = bstrchrp(s1, c, pos);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d", __LINE__, res);
      }
      return ret;
  }
  
  static int test28_3(bstring s1, int c, int pos, int res)
  {
      int rv, ret = 0;
      debug(".\tbstrrchrp (%s, %d, %d) = ", dumpBstring(s1), c, pos);
      rv = bstrrchrp(s1, c, pos);
      debug("%d", rv);
      ret += (rv != res);
      if (ret) {
          debug("\t\tfailure(%d) res = %d rv = %d", __LINE__, res, rv);
      }
      return ret;
  }
  
  static int test28(void)
  {
      int ret = 0;
      debug("TEST: int bstrchr (const_bstring s1, int c);");
      ret += test28_0(NULL, 0, BSTR_ERR);
      ret += test28_0(&badBstring1, 'b', BSTR_ERR);
      ret += test28_0(&badBstring2, 's', BSTR_ERR);
      ret += test28_0(&emptyBstring, 0, BSTR_ERR);
      ret += test28_0(&shortBstring, 0, BSTR_ERR);
      ret += test28_0(&shortBstring, 'b', 0);
      ret += test28_0(&shortBstring, 's', 4);
      ret += test28_0(&shortBstring, 'q', BSTR_ERR);
      ret += test28_0(&xxxxxBstring, 0, BSTR_ERR);
      ret += test28_0(&xxxxxBstring, 'b', BSTR_ERR);
      ret += test28_0(&longBstring, 'i', 2);
      debug("TEST: int bstrrchr (const_bstring s1, int c);");
      ret += test28_1(NULL, 0, BSTR_ERR);
      ret += test28_1(&badBstring1, 'b', BSTR_ERR);
      ret += test28_1(&badBstring2, 's', BSTR_ERR);
      ret += test28_1(&emptyBstring, 0, BSTR_ERR);
      ret += test28_1(&shortBstring, 0, BSTR_ERR);
      ret += test28_1(&shortBstring, 'b', 0);
      ret += test28_1(&shortBstring, 's', 4);
      ret += test28_1(&shortBstring, 'q', BSTR_ERR);
      ret += test28_1(&xxxxxBstring, 0, BSTR_ERR);
      ret += test28_1(&xxxxxBstring, 'b', BSTR_ERR);
      ret += test28_1(&longBstring, 'i', 82);
      debug("TEST: int bstrchrp (const_bstring s1, int c, int pos);");
      ret += test28_2(NULL, 0, 0, BSTR_ERR);
      ret += test28_2(&badBstring1, 'b', 0, BSTR_ERR);
      ret += test28_2(&badBstring2, 's', 0, BSTR_ERR);
      ret += test28_2(&shortBstring, 'b', -1, BSTR_ERR);
      ret += test28_2(&shortBstring, 'b', shortBstring.slen, BSTR_ERR);
      ret += test28_2(&emptyBstring, 0, 0, BSTR_ERR);
      ret += test28_2(&shortBstring, 0, 0, BSTR_ERR);
      ret += test28_2(&shortBstring, 'b', 0, 0);
      ret += test28_2(&shortBstring, 'b', 1, BSTR_ERR);
      ret += test28_2(&shortBstring, 's', 0, 4);
      ret += test28_2(&shortBstring, 'q', 0, BSTR_ERR);
      debug("TEST: int bstrrchrp (const_bstring s1, int c, int pos);");
      ret += test28_3(NULL, 0, 0, BSTR_ERR);
      ret += test28_3(&badBstring1, 'b', 0, BSTR_ERR);
      ret += test28_3(&badBstring2, 's', 0, BSTR_ERR);
      ret += test28_3(&shortBstring, 'b', -1, BSTR_ERR);
      ret += test28_3(&shortBstring, 'b', shortBstring.slen, BSTR_ERR);
      ret += test28_3(&emptyBstring, 0, 0, BSTR_ERR);
      ret += test28_3(&shortBstring, 0, 0, BSTR_ERR);
      ret += test28_3(&shortBstring, 'b', 0, 0);
      ret += test28_3(&shortBstring, 'b', shortBstring.slen - 1, 0);
      ret += test28_3(&shortBstring, 's', shortBstring.slen - 1, 4);
      ret += test28_3(&shortBstring, 's', 0, BSTR_ERR);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test29_0(bstring b0, char *s, const char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbcatcstr (%s, ", dumpBstring(b2));
          rv = bcatcstr(b2, s);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%p) = %s", s, dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbcatcstr (%s, ", dumpBstring(b2));
          rv = bcatcstr(b2, s);
          debug("%p) = %s", s, dumpBstring(b2));
          if (s)
              ret += (b2->slen != b0->slen + (int)strlen(s));
          ret += ((0 != rv) && (s != NULL)) || ((0 == rv)
                  && (s == NULL));
          ret += (res == NULL)
              || ((int)strlen(res) != b2->slen)  ||(0 !=
                      memcmp(b2->data, res,
                          b2->slen));
          ret += b2->data[b2->slen] != '\0';
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = bcatcstr(b0, s)));
          debug(".\tbcatcstr (%s, %p) = %d", dumpBstring(b0), s, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test29(void)
  {
      int ret = 0;
      debug("TEST: int bcatcstr (bstring b0, const char * s);");
  
      /* tests with NULL */ 
      ret += test29_0(NULL, NULL, NULL);
      ret += test29_0(NULL, "", NULL);
      ret += test29_0(&emptyBstring, NULL, "");
      ret += test29_0(&badBstring1, "bogus", NULL);
      ret += test29_0(&badBstring2, "bogus", NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test29_0(&emptyBstring, "", "");
      ret += test29_0(&emptyBstring, "bogus", "bogus");
      ret += test29_0(&shortBstring, "", "bogus");
      ret += test29_0(&shortBstring, "bogus", "bogusbogus");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test30_0(bstring b0, const unsigned char *s, int len,
          const char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbcatblk (%s, ", dumpBstring(b2));
          rv = bcatblk(b2, s, len);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%p) = %s", s, dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbcatblk (%s, ", dumpBstring(b2));
          rv = bcatblk(b2, s, len);
          debug("%p) = %s", s, dumpBstring(b2));
          if (s) {
              if (len >= 0)
                  ret += (b2->slen != b0->slen + len);
  
              else
                  ret += (b2->slen != b0->slen);
          }
          ret += ((0 != rv) && (s != NULL && len >= 0)) || ((0 == rv)
                  && (s == NULL
                      || len <
                      0));
          ret += (res == NULL)
              || ((int)strlen(res) != b2->slen)  ||(0 !=
                      memcmp(b2->data, res,
                          b2->slen));
          ret += b2->data[b2->slen] != '\0';
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = bcatblk(b0, s, len)));
          debug(".\tbcatblk (%s, %p, %d) = %d", dumpBstring(b0), s, len,
                  rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test30(void)
  {
      int ret = 0;
      debug("TEST: int bcatblk (bstring b0, const char * s);");
  
      /* tests with NULL */ 
      ret += test30_0(NULL, NULL, 0, NULL);
      ret += test30_0(NULL, (unsigned char *)"", 0, NULL);
      ret += test30_0(&emptyBstring, NULL, 0, "");
      ret += test30_0(&emptyBstring, NULL, -1, "");
      ret += test30_0(&badBstring1, NULL, 0, NULL);
      ret += test30_0(&badBstring2, NULL, 0, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test30_0(&emptyBstring, (unsigned char *)"", -1, "");
      ret += test30_0(&emptyBstring, (unsigned char *)"", 0, "");
      ret +=
          test30_0(&emptyBstring, (unsigned char *)"bogus", 5, "bogus");
      ret += test30_0(&shortBstring, (unsigned char *)"", 0, "bogus");
      ret +=
          test30_0(&shortBstring, (unsigned char *)"bogus", 5,
                  "bogusbogus");
      ret +=
          test30_0(&shortBstring, (unsigned char *)"bogus", -1, "bogus");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test31_0(bstring b0, const_bstring find,
          const_bstring replace, int pos, char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && find != NULL && find->data != NULL && find->slen >= 0
              && replace != NULL && replace->data != NULL
              && replace->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbfindreplace (%s, %s, %s, %d) = ", dumpBstring(b2),
                  dumpBstring(find), dumpBstring(replace), pos);
          rv = bfindreplace(b2, find, replace, pos);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%d", rv);
          bwriteallow(*b2);
          debug(".\tbfindreplace (%s, %s, %s, %d)", dumpBstring(b2),
                  dumpBstring(find), dumpBstring(replace), pos);
          rv = bfindreplace(b2, find, replace, pos);
          ret += (res == NULL) || ((int)strlen(res) > b2->slen) 
              ||(0 != memcmp(b2->data, res, b2->slen));
          ret += b2->data[b2->slen] != '\0';
          debug(" -> %s", dumpBstring(b2));
          bdestroy(b2);
      } else {
          ret +=
              (BSTR_ERR != (rv = bfindreplace(b0, find, replace, pos)));
          debug(".\tbfindreplace (%s, %s, %s, %d) = %d", dumpBstring(b0),
                  dumpBstring(find), dumpBstring(replace), pos, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test31_1(bstring b0, const_bstring find,
          const_bstring replace, int pos, char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && find != NULL && find->data != NULL && find->slen >= 0
              && replace != NULL && replace->data != NULL
              && replace->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbfindreplacecaseless (%s, %s, %s, %d) = ",
                  dumpBstring(b2), dumpBstring(find),
                  dumpBstring(replace), pos);
          rv = bfindreplacecaseless(b2, find, replace, pos);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%d", rv);
          bwriteallow(*b2);
          debug(".\tbfindreplacecaseless (%s, %s, %s, %d)",
                  dumpBstring(b2), dumpBstring(find),
                  dumpBstring(replace), pos);
          rv = bfindreplacecaseless(b2, find, replace, pos);
          ret += (res == NULL) || ((int)strlen(res) > b2->slen) 
              ||(0 != memcmp(b2->data, res, b2->slen));
          ret += b2->data[b2->slen] != '\0';
          debug(" -> %s", dumpBstring(b2));
          bdestroy(b2);
      } else {
          ret +=
              (BSTR_ERR !=
               (rv = bfindreplacecaseless(b0, find, replace, pos)));
          debug(".\tbfindreplacecaseless (%s, %s, %s, %d) = %d",
                  dumpBstring(b0), dumpBstring(find), dumpBstring(replace),
                  pos, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  
  #define LOTS_OF_S "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
  static int test31(void)
  {
      int ret = 0;
      struct tagbstring t0 = bsStatic("funny");
      struct tagbstring t1 = bsStatic("weird");
      struct tagbstring t2 = bsStatic("s");
      struct tagbstring t3 = bsStatic("long");
      struct tagbstring t4 = bsStatic("big");
      struct tagbstring t5 = bsStatic("ss");
      struct tagbstring t6 = bsStatic("sstsst");
      struct tagbstring t7 = bsStatic("xx" LOTS_OF_S "xx");
      struct tagbstring t8 = bsStatic("S");
      struct tagbstring t9 = bsStatic("LONG");
      debug
          ("TEST: int bfindreplace (bstring b, const_bstring f, const_bstring r, int pos);");
  
      /* tests with NULL */ 
      ret += test31_0(NULL, NULL, NULL, 0, NULL);
      ret +=
          test31_0(&shortBstring, NULL, &t1, 0,
                  (char *)shortBstring.data);
      ret +=
          test31_0(&shortBstring, &t2, NULL, 0,
                  (char *)shortBstring.data);
      ret += test31_0(&badBstring1, &t2, &t1, 0, NULL);
      ret += test31_0(&badBstring2, &t2, &t1, 0, NULL);
  
      /* normal operation tests */ 
      ret +=
          test31_0(&longBstring, &shortBstring, &t0, 0,
                  "This is a funny but reasonably long string.  Just long enough to cause some mallocing.");
      ret +=
          test31_0(&longBstring, &t2, &t1, 0,
                  "Thiweird iweird a boguweird but reaweirdonably long weirdtring.  Juweirdt long enough to cauweirde weirdome mallocing.");
      ret += test31_0(&shortBstring, &t2, &t1, 0, "boguweird");
      ret += test31_0(&shortBstring, &t8, &t1, 0, "bogus");
      ret +=
          test31_0(&longBstring, &t2, &t1, 27,
                  "This is a bogus but reasonably long weirdtring.  Juweirdt long enough to cauweirde weirdome mallocing.");
      ret +=
          test31_0(&longBstring, &t3, &t4, 0,
                  "This is a bogus but reasonably big string.  Just big enough to cause some mallocing.");
      ret +=
          test31_0(&longBstring, &t9, &t4, 0,
                  "This is a bogus but reasonably long string.  Just long enough to cause some mallocing.");
      ret += test31_0(&t6, &t2, &t5, 0, "sssstsssst");
      ret += test31_0(&t7, &t2, &t5, 0, "xx" LOTS_OF_S LOTS_OF_S "xx");
      debug
          ("TEST: int bfindreplacecaseless (bstring b, const_bstring f, const_bstring r, int pos);");
  
      /* tests with NULL */ 
      ret += test31_1(NULL, NULL, NULL, 0, NULL);
      ret +=
          test31_1(&shortBstring, NULL, &t1, 0,
                  (char *)shortBstring.data);
      ret +=
          test31_1(&shortBstring, &t2, NULL, 0,
                  (char *)shortBstring.data);
      ret += test31_1(&badBstring1, &t2, &t1, 0, NULL);
      ret += test31_1(&badBstring2, &t2, &t1, 0, NULL);
  
      /* normal operation tests */ 
      ret +=
          test31_1(&longBstring, &shortBstring, &t0, 0,
                  "This is a funny but reasonably long string.  Just long enough to cause some mallocing.");
      ret +=
          test31_1(&longBstring, &t2, &t1, 0,
                  "Thiweird iweird a boguweird but reaweirdonably long weirdtring.  Juweirdt long enough to cauweirde weirdome mallocing.");
      ret += test31_1(&shortBstring, &t2, &t1, 0, "boguweird");
      ret += test31_1(&shortBstring, &t8, &t1, 0, "boguweird");
      ret +=
          test31_1(&longBstring, &t2, &t1, 27,
                  "This is a bogus but reasonably long weirdtring.  Juweirdt long enough to cauweirde weirdome mallocing.");
      ret +=
          test31_1(&longBstring, &t3, &t4, 0,
                  "This is a bogus but reasonably big string.  Just big enough to cause some mallocing.");
      ret +=
          test31_1(&longBstring, &t9, &t4, 0,
                  "This is a bogus but reasonably big string.  Just big enough to cause some mallocing.");
      ret += test31_1(&t6, &t2, &t5, 0, "sssstsssst");
      ret += test31_1(&t6, &t8, &t5, 0, "sssstsssst");
      ret += test31_1(&t7, &t2, &t5, 0, "xx" LOTS_OF_S LOTS_OF_S "xx");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test32_0(const_bstring b, const char *s, int res)
  {
      int rv, ret = 0;
      ret += (res != (rv = biseqcstr(b, s)));
      debug(".\tbiseqcstr (%s, %p:<%s>) = %d", dumpBstring(b), s,
              (s ? s : NULL), rv);
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %d)", __LINE__, ret, res);
      }
      return ret;
  }
  
  static int test32_1(const_bstring b, const char *s, int res)
  {
      int rv, ret = 0;
      ret += (res != (rv = biseqcstrcaseless(b, s)));
      debug(".\tbiseqcstrcaseless (%s, %p:<%s>) = %d", dumpBstring(b), s,
              (s ? s : NULL), rv);
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %d)", __LINE__, ret, res);
      }
      return ret;
  }
  
  static int test32(void)
  {
      int ret = 0;
      debug("TEST: int biseqcstr (const_bstring b, const char * s);");
  
      /* tests with NULL */ 
      ret += test32_0(NULL, NULL, BSTR_ERR);
      ret += test32_0(&emptyBstring, NULL, BSTR_ERR);
      ret += test32_0(NULL, "", BSTR_ERR);
      ret += test32_0(&badBstring1, "", BSTR_ERR);
      ret += test32_0(&badBstring2, "bogus", BSTR_ERR);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test32_0(&emptyBstring, "", 1);
      ret += test32_0(&shortBstring, "bogus", 1);
      ret += test32_0(&emptyBstring, "bogus", 0);
      ret += test32_0(&shortBstring, "", 0);
      {
          bstring b = bstrcpy(&shortBstring);
          b->data[1]++;
          ret += test32_0(b, (char *)shortBstring.data, 0);
          bdestroy(b);
      }  debug
      ("TEST: int biseqcstrcaseless (const_bstring b, const char * s);");
  
      /* tests with NULL */ 
      ret += test32_1(NULL, NULL, BSTR_ERR);
      ret += test32_1(&emptyBstring, NULL, BSTR_ERR);
      ret += test32_1(NULL, "", BSTR_ERR);
      ret += test32_1(&badBstring1, "", BSTR_ERR);
      ret += test32_1(&badBstring2, "bogus", BSTR_ERR);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test32_1(&emptyBstring, "", 1);
      ret += test32_1(&shortBstring, "bogus", 1);
      ret += test32_1(&shortBstring, "BOGUS", 1);
      ret += test32_1(&emptyBstring, "bogus", 0);
      ret += test32_1(&shortBstring, "", 0);
      {
          bstring b = bstrcpy(&shortBstring);
          b->data[1]++;
          ret += test32_1(b, (char *)shortBstring.data, 0);
          bdestroy(b);
      }  if (ret)
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test33_0(bstring b0, const char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbtoupper (%s)", dumpBstring(b2));
          rv = btoupper(b2);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug(" = %s", dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbtoupper (%s)", dumpBstring(b2));
          rv = btoupper(b2);
          debug(" = %s", dumpBstring(b2));
          ret += (b2->slen != b0->slen);
          ret += (0 != rv);
          ret += (res == NULL) || ((int)strlen(res) != b2->slen) 
              ||(0 != memcmp(b2->data, res, b2->slen));
          ret += b2->data[b2->slen] != '\0';
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = btoupper(b0)));
          debug(".\tbtoupper (%s) = %d", dumpBstring(b0), rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test33(void)
  {
      int ret = 0;
      debug("TEST: int btoupper (bstring b);");
  
      /* tests with NULL */ 
      ret += test33_0(NULL, NULL);
      ret += test33_0(&badBstring1, NULL);
      ret += test33_0(&badBstring2, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test33_0(&emptyBstring, "");
      ret += test33_0(&shortBstring, "BOGUS");
      ret +=
          test33_0(&longBstring,
                  "THIS IS A BOGUS BUT REASONABLY LONG STRING.  JUST LONG ENOUGH TO CAUSE SOME MALLOCING.");
      if (ret)
          debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test34_0(bstring b0, const char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbtolower (%s)", dumpBstring(b2));
          rv = btolower(b2);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug(" = %s", dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbtolower (%s)", dumpBstring(b2));
          rv = btolower(b2);
          debug(" = %s", dumpBstring(b2));
          ret += (b2->slen != b0->slen);
          ret += (0 != rv);
          ret += (res == NULL) || ((int)strlen(res) != b2->slen) 
              ||(0 != memcmp(b2->data, res, b2->slen));
          ret += b2->data[b2->slen] != '\0';
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = btolower(b0)));
          debug(".\tbtolower (%s) = %d", dumpBstring(b0), rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test34(void)
  {
      int ret = 0;
      debug("TEST: int btolower (bstring b);");
  
      /* tests with NULL */ 
      ret += test34_0(NULL, NULL);
      ret += test34_0(&badBstring1, NULL);
      ret += test34_0(&badBstring2, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test34_0(&emptyBstring, "");
      ret += test34_0(&shortBstring, "bogus");
      ret +=
          test34_0(&longBstring,
                  "this is a bogus but reasonably long string.  just long enough to cause some mallocing.");
      if (ret)
          debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test35_0(const_bstring b0, const_bstring b1, int res)
  {
      int rv, ret = 0;
      ret += (res != (rv = bstricmp(b0, b1)));
      debug(".\tbstricmp (%s, %s) = %d", dumpBstring(b0),
              dumpBstring(b1), rv);
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %d)", __LINE__, ret, res);
      }
      return ret;
  }
  
  static int test35(void)
  {
      int ret = 0;
      struct tagbstring t0 = bsStatic("bOgUs");
      struct tagbstring t1 = bsStatic("bOgUR");
      struct tagbstring t2 = bsStatic("bOgUt");
      debug
          ("TEST: int bstricmp (const_bstring b0, const_bstring b1);");
  
      /* tests with NULL */ 
      ret += test35_0(NULL, NULL, SHRT_MIN);
      ret += test35_0(&emptyBstring, NULL, SHRT_MIN);
      ret += test35_0(NULL, &emptyBstring, SHRT_MIN);
      ret += test35_0(&emptyBstring, &badBstring1, SHRT_MIN);
      ret += test35_0(&badBstring1, &emptyBstring, SHRT_MIN);
      ret += test35_0(&shortBstring, &badBstring2, SHRT_MIN);
      ret += test35_0(&badBstring2, &shortBstring, SHRT_MIN);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test35_0(&emptyBstring, &emptyBstring, 0);
      ret += test35_0(&shortBstring, &t0, 0);
      ret +=
          test35_0(&shortBstring, &t1,
                  tolower(shortBstring.data[4]) - tolower(t1.data[4]));
      ret +=
          test35_0(&shortBstring, &t2,
                  tolower(shortBstring.data[4]) - tolower(t2.data[4]));
      t0.slen++;
      ret += test35_0(&shortBstring, &t0, -(UCHAR_MAX + 1));
      ret += test35_0(&t0, &shortBstring, (UCHAR_MAX + 1));
      if (ret)
          debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test36_0(const_bstring b0, const_bstring b1, int n,
          int res)
  {
      int rv, ret = 0;
      ret += (res != (rv = bstrnicmp(b0, b1, n)));
      debug(".\tbstrnicmp (%s, %s, %d) = %d", dumpBstring(b0),
              dumpBstring(b1), n, rv);
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %d)", __LINE__, ret, res);
      }
      return ret;
  }
  
  static int test36(void)
  {
      int ret = 0;
      struct tagbstring t0 = bsStatic("bOgUs");
      struct tagbstring t1 = bsStatic("bOgUR");
      struct tagbstring t2 = bsStatic("bOgUt");
      debug
          ("TEST: int bstrnicmp (const_bstring b0, const_bstring b1);");
  
      /* tests with NULL */ 
      ret += test36_0(NULL, NULL, 0, SHRT_MIN);
      ret += test36_0(&emptyBstring, NULL, 0, SHRT_MIN);
      ret += test36_0(NULL, &emptyBstring, 0, SHRT_MIN);
      ret += test36_0(&emptyBstring, &badBstring1, 0, SHRT_MIN);
      ret += test36_0(&badBstring1, &emptyBstring, 0, SHRT_MIN);
      ret += test36_0(&shortBstring, &badBstring2, 5, SHRT_MIN);
      ret += test36_0(&badBstring2, &shortBstring, 5, SHRT_MIN);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test36_0(&emptyBstring, &emptyBstring, 0, 0);
      ret += test36_0(&shortBstring, &t0, 0, 0);
      ret += test36_0(&shortBstring, &t0, 5, 0);
      ret += test36_0(&shortBstring, &t0, 4, 0);
      ret += test36_0(&shortBstring, &t0, 6, 0);
      ret +=
          test36_0(&shortBstring, &t1, 5,
                  shortBstring.data[4] - t1.data[4]);
      ret += test36_0(&shortBstring, &t1, 4, 0);
      ret +=
          test36_0(&shortBstring, &t1, 6,
                  shortBstring.data[4] - t1.data[4]);
      ret +=
          test36_0(&shortBstring, &t2, 5,
                  shortBstring.data[4] - t2.data[4]);
      ret += test36_0(&shortBstring, &t2, 4, 0);
      ret +=
          test36_0(&shortBstring, &t2, 6,
                  shortBstring.data[4] - t2.data[4]);
      t0.slen++;
      ret += test36_0(&shortBstring, &t0, 5, 0);
      ret += test36_0(&shortBstring, &t0, 6, -(UCHAR_MAX + 1));
      ret += test36_0(&t0, &shortBstring, 6, (UCHAR_MAX + 1));
      if (ret)
          debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test37_0(const_bstring b0, const_bstring b1, int res)
  {
      int rv, ret = 0;
      ret += (res != (rv = biseqcaseless(b0, b1)));
      debug(".\tbiseqcaseless (%s, %s) = %d", dumpBstring(b0),
              dumpBstring(b1), rv);
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %d)", __LINE__, ret, res);
      }
      return ret;
  }
  
  static int test37(void)
  {
      int ret = 0;
      struct tagbstring t0 = bsStatic("bOgUs");
      struct tagbstring t1 = bsStatic("bOgUR");
      struct tagbstring t2 = bsStatic("bOgUt");
      debug
          ("TEST: int biseqcaseless (const_bstring b0, const_bstring b1);");
  
      /* tests with NULL */ 
      ret += test37_0(NULL, NULL, BSTR_ERR);
      ret += test37_0(&emptyBstring, NULL, BSTR_ERR);
      ret += test37_0(NULL, &emptyBstring, BSTR_ERR);
      ret += test37_0(&emptyBstring, &badBstring1, BSTR_ERR);
      ret += test37_0(&badBstring1, &emptyBstring, BSTR_ERR);
      ret += test37_0(&shortBstring, &badBstring2, BSTR_ERR);
      ret += test37_0(&badBstring2, &shortBstring, BSTR_ERR);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test37_0(&emptyBstring, &emptyBstring, 1);
      ret += test37_0(&shortBstring, &t0, 1);
      ret += test37_0(&shortBstring, &t1, 0);
      ret += test37_0(&shortBstring, &t2, 0);
      if (ret)
          debug("\t# failures: %d", ret);
      return ret;
  }
  
  struct emuFile {
      int ofs;
      bstring contents;
  };
  static int test38_aux_bNgetc(struct emuFile *f)
  {
      int v = EOF;
      if (NULL != f && EOF != (v = bchare(f->contents, f->ofs, EOF)))
          f->ofs++;
      return v;
  }
  
  static size_t test38_aux_bNread(void *buff, size_t elsize,
          size_t nelem, struct emuFile *f)
  {
      char *b = (char *)buff;
      int v;
      size_t i, j, c = 0;
      if (NULL == f || NULL == b)
          return c;
      for (i = 0; i < nelem; i++)
          for (j = 0; j < elsize; j++) {
              v = test38_aux_bNgetc(f);
              if (EOF == v) {
                  *b = (char)'\0';
                  return c;
              } else {
                  *b = (char)v;
                  b++;
                  c++;
              } }  return c;
  }
  
  static int test38_aux_bNopen(struct emuFile *f, bstring b)
  {
      if (NULL == f || NULL == b)
          return -__LINE__;
      f->ofs = 0;
      f->contents = b;
      return 0;
  }
  
  static int test38(void)
  {
      struct emuFile f;
      bstring b0, b1, b2, b3;
      int ret = 0;
      debug("TEST: bgets/breads test");
      test38_aux_bNopen(&f, &shortBstring);
  
      /* Creation/reads */ 
      b0 = bgets((bNgetc) test38_aux_bNgetc, &f, (char)'b');
      b1 = bread((bNread) test38_aux_bNread, &f);
      b2 = bgets((bNgetc) test38_aux_bNgetc, &f, (char)'\0');
      b3 = bread((bNread) test38_aux_bNread, &f);
      ret += 1 != biseqcstr(b0, "b");
      ret += 1 != biseqcstr(b1, "ogus");
      ret += NULL != b2;
      ret += 1 != biseqcstr(b3, "");
  
      /* Bogus accumulations */ 
      f.ofs = 0;
      ret +=
          0 <= bgetsa(NULL, (bNgetc) test38_aux_bNgetc, &f, (char)'o');
      ret += 0 <= breada(NULL, (bNread) test38_aux_bNread, &f);
      ret +=
          0 <= bgetsa(&shortBstring, (bNgetc) test38_aux_bNgetc, &f,
                  (char)'o');
      ret += 0 <= breada(&shortBstring, (bNread) test38_aux_bNread, &f);
  
      /* Normal accumulations */ 
      ret +=
          0 > bgetsa(b0, (bNgetc) test38_aux_bNgetc, &f, (char)'o');
      ret += 0 > breada(b1, (bNread) test38_aux_bNread, &f);
      ret += 1 != biseqcstr(b0, "bbo");
      ret += 1 != biseqcstr(b1, "ogusgus");
  
      /* Attempt to append past end should do nothing */ 
      ret +=
          0 > bgetsa(b0, (bNgetc) test38_aux_bNgetc, &f, (char)'o');
      ret += 0 > breada(b1, (bNread) test38_aux_bNread, &f);
      ret += 1 != biseqcstr(b0, "bbo");
      ret += 1 != biseqcstr(b1, "ogusgus");
      bdestroy(b0);
      bdestroy(b1);
      bdestroy(b2);
      bdestroy(b3);
      if (ret)
          debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test39_0(const_bstring b, const_bstring lt,
          const_bstring rt, const_bstring t)
  {
      bstring r;
      int ret = 0;
      ret += 0 <= bltrimws(NULL);
      ret += 0 <= brtrimws(NULL);
      ret += 0 <= btrimws(NULL);
      r = bstrcpy(b);
      bwriteprotect(*r);
      ret += 0 <= bltrimws(r);
      ret += 0 <= brtrimws(r);
      ret += 0 <= btrimws(r);
      bwriteallow(*r);
      ret += 0 != bltrimws(r);
      debug(".\tbltrim (%s) = %s", dumpBstring(b), dumpBstring(r));
      ret += !biseq(r, lt);
      bdestroy(r);
      r = bstrcpy(b);
      ret += 0 != brtrimws(r);
      debug(".\tbrtrim (%s) = %s", dumpBstring(b), dumpBstring(r));
      ret += !biseq(r, rt);
      bdestroy(r);
      r = bstrcpy(b);
      ret += 0 != btrimws(r);
      debug(".\tbtrim  (%s) = %s", dumpBstring(b), dumpBstring(r));
      ret += !biseq(r, t);
      bdestroy(r);
      return ret;
  }
  
  static int test39(void)
  {
      int ret = 0;
      struct tagbstring t0 = bsStatic("   bogus string   ");
      struct tagbstring t1 = bsStatic("bogus string   ");
      struct tagbstring t2 = bsStatic("   bogus string");
      struct tagbstring t3 = bsStatic("bogus string");
      struct tagbstring t4 = bsStatic("     ");
      struct tagbstring t5 = bsStatic("");
      debug("TEST: trim functions");
      ret += test39_0(&t0, &t1, &t2, &t3);
      ret += test39_0(&t1, &t1, &t3, &t3);
      ret += test39_0(&t2, &t3, &t2, &t3);
      ret += test39_0(&t3, &t3, &t3, &t3);
      ret += test39_0(&t4, &t5, &t5, &t5);
      ret += test39_0(&t5, &t5, &t5, &t5);
      if (ret)
          debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test40_0(bstring b0, const_bstring b1, int left, int len,
          const char *res)
  {
      bstring b2;
      int rv, ret = 0;
      if (b0 != NULL && b0->data != NULL && b0->slen >= 0
              && b1 != NULL && b1->data != NULL && b1->slen >= 0) {
          b2 = bstrcpy(b0);
          bwriteprotect(*b2);
          debug(".\tbassignmidstr (%s, ", dumpBstring(b2));
          rv = bassignmidstr(b2, b1, left, len);
          ret += (rv == 0);
          if (!biseq(b0, b2))
              ret++;
          debug("%s, %d, %d) = %s", dumpBstring(b1), left, len,
                  dumpBstring(b2));
          bwriteallow(*b2);
          debug(".\tbassignmidstr (%s, ", dumpBstring(b2));
          rv = bassignmidstr(b2, b1, left, len);
          debug("%s, %d, %d) = %s", dumpBstring(b1), left, len,
                  dumpBstring(b2));
          if (b1)
              ret += (b2->slen > len) | (b2->slen < 0);
          ret += ((0 != rv) && (b1 != NULL)) || ((0 == rv)
                  && (b1 == NULL));
          ret += (res == NULL)
              || ((int)strlen(res) != b2->slen)  ||(0 !=
                      memcmp(b2->data, res,
                          b2->slen));
          ret += b2->data[b2->slen] != '\0';
          bdestroy(b2);
      } else {
          ret += (BSTR_ERR != (rv = bassignmidstr(b0, b1, left, len)));
          debug(".\tbassignmidstr (%s, %s, %d, %d) = %d",
                  dumpBstring(b0), dumpBstring(b1), left, len, rv);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test40(void)
  {
      int ret = 0;
      debug
          ("TEST: int bassignmidstr (bstring b0, const_bstring b1, int left, int len);");
  
      /* tests with NULL */ 
      ret += test40_0(NULL, NULL, 0, 1, NULL);
      ret += test40_0(NULL, &emptyBstring, 0, 1, NULL);
      ret += test40_0(&emptyBstring, NULL, 0, 1, "");
      ret += test40_0(&badBstring1, &emptyBstring, 0, 1, NULL);
      ret += test40_0(&badBstring2, &emptyBstring, 0, 1, NULL);
      ret += test40_0(&emptyBstring, &badBstring1, 0, 1, NULL);
      ret += test40_0(&emptyBstring, &badBstring2, 0, 1, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test40_0(&emptyBstring, &emptyBstring, 0, 1, "");
      ret += test40_0(&emptyBstring, &shortBstring, 1, 3, "ogu");
      ret += test40_0(&shortBstring, &emptyBstring, 0, 1, "");
      ret += test40_0(&shortBstring, &shortBstring, 1, 3, "ogu");
      ret += test40_0(&shortBstring, &shortBstring, -1, 4, "bog");
      ret += test40_0(&shortBstring, &shortBstring, 1, 9, "ogus");
      ret += test40_0(&shortBstring, &shortBstring, 9, 1, "");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test41_0(bstring b1, int left, int len, const char *res)
  {
      struct tagbstring t;
      bstring b2, b3;
      int ret = 0;
      if (b1 != NULL && b1->data != NULL && b1->slen >= 0) {
          b2 = bfromcstr("");
          bassignmidstr(b2, b1, left, len);
          bmid2tbstr(t, b1, left, len);
          b3 = bstrcpy(&t);
          debug(".\tbmid2tbstr (%s, %d, %d) = %s", dumpBstring(b1),
                  left, len, dumpBstring(b3));
          ret += !biseq(&t, b2);
          bdestroy(b2);
          bdestroy(b3);
      } else {
          bmid2tbstr(t, b1, left, len);
          b3 = bstrcpy(&t);
          ret += t.slen != 0;
          debug(".\tbmid2tbstr (%s, %d, %d) = %s", dumpBstring(b1),
                  left, len, dumpBstring(b3));
          bdestroy(b3);
      }
      if (ret) {
          debug("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res);
          if (res)
              debug(" = \"%s\"", res);
          debug(")");
      }
      return ret;
  }
  
  static int test41(void)
  {
      int ret = 0;
      debug
          ("TEST: int bmid2tbstr (struct tagbstring &t, const_bstring b1, int left, int len);");
  
      /* tests with NULL */ 
      ret += test41_0(NULL, 0, 1, NULL);
      ret += test41_0(&emptyBstring, 0, 1, NULL);
      ret += test41_0(NULL, 0, 1, "");
      ret += test41_0(&emptyBstring, 0, 1, NULL);
      ret += test41_0(&emptyBstring, 0, 1, NULL);
      ret += test41_0(&badBstring1, 0, 1, NULL);
      ret += test41_0(&badBstring2, 0, 1, NULL);
  
      /* normal operation tests on all sorts of subranges */ 
      ret += test41_0(&emptyBstring, 0, 1, "");
      ret += test41_0(&shortBstring, 1, 3, "ogu");
      ret += test41_0(&emptyBstring, 0, 1, "");
      ret += test41_0(&shortBstring, 1, 3, "ogu");
      ret += test41_0(&shortBstring, -1, 4, "bog");
      ret += test41_0(&shortBstring, 1, 9, "ogus");
      ret += test41_0(&shortBstring, 9, 1, "");
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test42_0(const_bstring bi, int len, const char *res)
  {
      bstring b;
      int rv, ret = 0;
      rv = btrunc(b = bstrcpy(bi), len);
      ret += (len >= 0) ? (rv < 0) : (rv >= 0);
      if (res)
          ret += (0 == biseqcstr(b, res));
      debug(".\tbtrunc (%s, %d) = %s", dumpBstring(bi), len,
              dumpBstring(b));
      bdestroy(b);
      return ret;
  }
  
  static int test42(void)
  {
      int ret = 0;
      debug("TEST: int btrunc (bstring b, int n);");
  
      /* tests with NULL */ 
      ret += 0 <= btrunc(NULL, 2);
      ret += 0 <= btrunc(NULL, 0);
      ret += 0 <= btrunc(NULL, -1);
  
      /* write protected */ 
      ret += 0 <= btrunc(&shortBstring, 2);
      ret += 0 <= btrunc(&shortBstring, 0);
      ret += 0 <= btrunc(&shortBstring, -1);
      ret += test42_0(&emptyBstring, 10, "");
      ret += test42_0(&emptyBstring, 0, "");
      ret += test42_0(&emptyBstring, -1, NULL);
      ret += test42_0(&shortBstring, 10, "bogus");
      ret += test42_0(&shortBstring, 3, "bog");
      ret += test42_0(&shortBstring, 0, "");
      ret += test42_0(&shortBstring, -1, NULL);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test43(void)
  {
      static struct tagbstring ts0 = bsStatic("");
      static struct tagbstring ts1 = bsStatic("    ");
      static struct tagbstring ts2 = bsStatic(" abc");
      static struct tagbstring ts3 = bsStatic("abc ");
      static struct tagbstring ts4 = bsStatic(" abc ");
      static struct tagbstring ts5 = bsStatic("abc");
      bstring tstrs[6] = {
          &ts0, &ts1, &ts2, &ts3, &ts4, &ts5};
      int ret = 0;
      int i;
      debug
          ("TEST: int btfromblk*trim (struct tagbstring t, void * s, int l);");
      for (i = 0; i < 6; i++) {
          struct tagbstring t;
          bstring b;
          btfromblkltrimws(t, tstrs[i]->data, tstrs[i]->slen);
          bltrimws(b = bstrcpy(tstrs[i]));
          if (!biseq(b, &t)) {
              ret++;
              bassign(b, &t);
              debug("btfromblkltrimws failure: <%s> -> <%s>",
                      tstrs[i]->data, b->data);
          }
          debug(".\tbtfromblkltrimws (\"%s\", \"%s\", %d)",
                  (char *)bdatae(b, NULL), tstrs[i]->data, tstrs[i]->slen);
          bdestroy(b);
          btfromblkrtrimws(t, tstrs[i]->data, tstrs[i]->slen);
          brtrimws(b = bstrcpy(tstrs[i]));
          if (!biseq(b, &t)) {
              ret++;
              bassign(b, &t);
              debug("btfromblkrtrimws failure: <%s> -> <%s>",
                      tstrs[i]->data, b->data);
          }
          debug(".\tbtfromblkrtrimws (\"%s\", \"%s\", %d)",
                  (char *)bdatae(b, NULL), tstrs[i]->data, tstrs[i]->slen);
          bdestroy(b);
          btfromblktrimws(t, tstrs[i]->data, tstrs[i]->slen);
          btrimws(b = bstrcpy(tstrs[i]));
          if (!biseq(b, &t)) {
              ret++;
              bassign(b, &t);
              debug("btfromblktrimws failure: <%s> -> <%s>",
                      tstrs[i]->data, b->data);
          }
          debug(".\tbtfromblktrimws (\"%s\", \"%s\", %d)",
                  (char *)bdatae(b, NULL), tstrs[i]->data, tstrs[i]->slen);
          bdestroy(b);
      }  debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test44_0(const char *str)
  {
      int ret = 0, v;
      bstring b = bfromcstr("");
      if (NULL == str) {
          ret += 0 <= bassigncstr(NULL, "test");
          debug(".\tbassigncstr (b = %s, NULL)",
                  dumpBstring(b = bfromcstr("")));
          ret += 0 <= (v = bassigncstr(b, NULL));
          debug(" = %d; b -> %s", v, dumpBstring(b));
          ret += 0 <= bassigncstr(&shortBstring, NULL);
          bdestroy(b);
          return ret;
      }
      ret += 0 <= bassigncstr(NULL, str);
      debug(".\tbassigncstr (b = %s, \"%s\")",
              dumpBstring(b = bfromcstr("")), str);
      ret += 0 > (v = bassigncstr(b, str));
      debug(" = %d; b -> %s", v, dumpBstring(b));
      ret += 0 != strcmp(bdatae(b, ""), str);
      ret += ((size_t) b->slen) != strlen(str);
      ret += 0 > bassigncstr(b, "xxxxx");
      bwriteprotect(*b) 
          log_info(".\tbassigncstr (b = %s, \"%s\")", dumpBstring(b),
                  str);
      ret += 0 <= (v = bassigncstr(b, str));
      debug(" = %d; b -> %s", v, dumpBstring(b));
      ret += 0 != strcmp(bdatae(b, ""), "xxxxx");
      ret += ((size_t) b->slen) != strlen("xxxxx");
      bwriteallow(*b)  ret += 0 <= bassigncstr(&shortBstring, str);
      bdestroy(b);
      debug(".\tbassigncstr (a = %s, \"%s\")",
              dumpBstring(&shortBstring), str);
      ret += 0 <= (v = bassigncstr(&shortBstring, str));
      debug(" = %d; a -> %s", v, dumpBstring(&shortBstring));
      return ret;
  }
  
  static int test44(void)
  {
      int ret = 0;
      debug("TEST: int bassigncstr (bstring a, char * str);");
  
      /* tests with NULL */ 
      ret += test44_0(NULL);
      ret += test44_0(EMPTY_STRING);
      ret += test44_0(SHORT_STRING);
      ret += test44_0(LONG_STRING);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test45_0(const char *str)
  {
      int ret = 0, v, len;
      bstring b = bfromcstr("");
      if (NULL == str) {
          ret += 0 <= bassignblk(NULL, "test", 4);
          debug(".\tbassignblk (b = %s, NULL, 1)",
                  dumpBstring(b = bfromcstr("")));
          ret += 0 <= (v = bassignblk(b, NULL, 1));
          debug(" = %d; b -> %s", v, dumpBstring(b));
          ret += 0 <= bassignblk(&shortBstring, NULL, 1);
          bdestroy(b);
          return ret;
      }
      len = (int)strlen(str);
      ret += 0 <= bassignblk(NULL, str, len);
      debug(".\tbassignblk (b = %s, \"%s\", %d)",
              dumpBstring(b = bfromcstr("")), str, len);
      ret += 0 > (v = bassignblk(b, str, len));
      debug(" = %d; b -> %s", v, dumpBstring(b));
      ret += 0 != strcmp(bdatae(b, ""), str);
      ret += b->slen != len;
      ret += 0 > bassigncstr(b, "xxxxx");
      bwriteprotect(*b) 
          debug(".\tbassignblk (b = %s, \"%s\", %d)", dumpBstring(b), str,
                  len);
      ret += 0 <= (v = bassignblk(b, str, len));
      debug(" = %d; b -> %s", v, dumpBstring(b));
      ret += 0 != strcmp(bdatae(b, ""), "xxxxx");
      ret += ((size_t) b->slen) != strlen("xxxxx");
      bwriteallow(*b)  ret += 0 <= bassignblk(&shortBstring, str, len);
      bdestroy(b);
      debug(".\tbassignblk (a = %s, \"%s\", %d)",
              dumpBstring(&shortBstring), str, len);
      ret += 0 <= (v = bassignblk(&shortBstring, str, len));
      debug(" = %d; a -> %s", v, dumpBstring(&shortBstring));
      return ret;
  }
  
  static int test45(void)
  {
      int ret = 0;
      debug
          ("TEST: int bassignblk (bstring a, const void * s, int len);");
  
      /* tests with NULL */ 
      ret += test45_0(NULL);
      ret += test45_0(EMPTY_STRING);
      ret += test45_0(SHORT_STRING);
      ret += test45_0(LONG_STRING);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  static int test46_0(const_bstring r, bstring b, int count,
          const char *fmt, ...)
  {
      int ret;
      va_list arglist;
      debug(".\tbvcformata (%s, %d, \"%s\", ...) -> ", dumpBstring(b),
              count, fmt);
      va_start(arglist, fmt);
      ret = bvcformata(b, count, fmt, arglist);
      va_end(arglist);
      debug("%d, %s (%s)", ret, dumpBstring(b), dumpBstring(r));
      if (ret < 0)
          return (NULL != r);
      ret += 1 != biseq(r, b);
      if (0 != ret)
          debug("\t->failed");
      return ret;
  }
  
  static int test46_1(bstring b, const char *fmt, const_bstring r, ...)
  {
      int ret;
      debug(".\tbvformata (&, %s, \"%s\", ...) -> ", dumpBstring(b),
              fmt);
      bvformata(ret, b, fmt, r);
      debug("%d, %s (%s)", ret, dumpBstring(b), dumpBstring(r));
      if (ret < 0)
          return (NULL != r);
      ret += 1 != biseq(r, b);
      if (0 != ret)
          debug("\t->failed");
      return ret;
  }
  
  static int test46(void)
  {
      bstring b;
      int ret = 0;
      debug
          ("TEST: int bvcformata (bstring b, int count, const char * fmt, va_list arg);");
      ret += test46_0(NULL, NULL, 8, "[%d]", 15);
      ret += test46_0(NULL, &shortBstring, 8, "[%d]", 15);
      ret += test46_0(NULL, &badBstring1, 8, "[%d]", 15);
      ret += test46_0(NULL, &badBstring2, 8, "[%d]", 15);
      ret += test46_0(NULL, &badBstring3, 8, "[%d]", 15);
      b = bfromcstr("");
      ret +=
          test46_0(&shortBstring, b, shortBstring.slen, "%s",
                  (char *)shortBstring.data);
      b->slen = 0;
      ret +=
          test46_0(&shortBstring, b, shortBstring.slen + 1, "%s",
                  (char *)shortBstring.data);
      b->slen = 0;
      ret +=
          test46_0(NULL, b, shortBstring.slen - 1, "%s",
                  (char *)shortBstring.data);
      debug
          ("TEST: bvformata (int &ret, bstring b, const char * fmt, <type> lastarg);");
      ret += test46_1(NULL, "[%d]", NULL, 15);
      ret += test46_1(&shortBstring, "[%d]", NULL, 15);
      ret += test46_1(&badBstring1, "[%d]", NULL, 15);
      ret += test46_1(&badBstring2, "[%d]", NULL, 15);
      ret += test46_1(&badBstring3, "[%d]", NULL, 15);
      b->slen = 0;
      ret += test46_1(b, "%s", &shortBstring, (char *)shortBstring.data);
      b->slen = 0;
      ret += test46_1(b, "%s", &longBstring, (char *)longBstring.data);
      bdestroy(b);
      debug("\t# failures: %d", ret);
      return ret;
  }
  
  int main(int argc, char *argv[]) 
  {
      FILE * log_file = fopen("tests/bstr_tests.c", "a+");
      setbuf(log_file, NULL);
      int ret = 0;
      argc = argc;
      argv = argv;
      debug("Direct case testing of bstring core functions");
      ret += test0();
      ret += test1();
      ret += test2();
      ret += test3();
      ret += test4();
      ret += test5();
      ret += test6();
      ret += test7();
      ret += test8();
      ret += test9();
      ret += test10();
      ret += test11();
      ret += test12();
      ret += test13();
      ret += test14();
      ret += test15();
      ret += test16();
      ret += test17();
      ret += test18();
      ret += test19();
      ret += test20();
      ret += test21();
      ret += test22();
      ret += test23();
      ret += test24();
      ret += test25();
      ret += test26();
      ret += test27();
      ret += test28();
      ret += test29();
      ret += test30();
      ret += test31();
      ret += test32();
      ret += test33();
      ret += test34();
      ret += test35();
      ret += test36();
      ret += test37();
      ret += test38();
      ret += test39();
      ret += test40();
      ret += test41();
      ret += test42();
      ret += test43();
      ret += test44();
      ret += test45();
      ret += test46();
      debug("# test bstr failures: %d", ret);
      if (ret > 0) {
          printf("FAILED: %d failures in bstrlib", ret);
      }
      debug("# test aux failures: %d", ret);
      return ret;
  }
  
  
  