py: Change vstr so that it doesn't null terminate buffer by default.

This cleans up vstr so that it's a pure "variable buffer", and the user
can decide whether they need to add a terminating null byte.  In most
places where vstr is used, the vstr did not need to be null terminated
and so this patch saves code size, a tiny bit of RAM, and makes vstr
usage more efficient.  When null termination is needed it must be
done explicitly using vstr_null_terminate.
diff --git a/py/vstr.c b/py/vstr.c
index e71a6b7..ccd54d5 100644
--- a/py/vstr.c
+++ b/py/vstr.c
@@ -35,12 +35,10 @@
 // returned value is always at least 1 greater than argument
 #define ROUND_ALLOC(a) (((a) & ((~0) - 7)) + 8)
 
-// Init the vstr so it allocs exactly given number of bytes.
-// Length is set to zero, and null byte written in first position.
+// Init the vstr so it allocs exactly given number of bytes.  Set length to zero.
 void vstr_init(vstr_t *vstr, size_t alloc) {
-    if (alloc < 2) {
-        // need at least 1 byte for the null byte at the end
-        alloc = 2;
+    if (alloc < 1) {
+        alloc = 1;
     }
     vstr->alloc = alloc;
     vstr->len = 0;
@@ -49,24 +47,20 @@
         vstr->had_error = true;
         return;
     }
-    vstr->buf[0] = 0;
     vstr->had_error = false;
     vstr->fixed_buf = false;
 }
 
-// Init the vstr so it allocs exactly enough ram to hold given length (plus the
-// null terminating byte), set the length, and write the null byte at the end.
+// Init the vstr so it allocs exactly enough ram to hold given length, and set the length.
 void vstr_init_len(vstr_t *vstr, size_t len) {
-    vstr_init(vstr, len + 1);
-    vstr_add_len(vstr, len);
+    vstr_init(vstr, len);
+    vstr->len = len;
 }
 
 void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf) {
-    assert(alloc > 0); // need at least room for the null byte
     vstr->alloc = alloc;
     vstr->len = 0;
     vstr->buf = buf;
-    vstr->buf[0] = 0;
     vstr->had_error = false;
     vstr->fixed_buf = true;
 }
@@ -79,16 +73,16 @@
 }
 
 vstr_t *vstr_new(void) {
-    vstr_t *vstr = m_new(vstr_t, 1);
+    vstr_t *vstr = m_new_obj(vstr_t);
     if (vstr == NULL) {
         return NULL;
     }
-    vstr_init(vstr, 32);
+    vstr_init(vstr, 16);
     return vstr;
 }
 
 vstr_t *vstr_new_size(size_t alloc) {
-    vstr_t *vstr = m_new(vstr_t, 1);
+    vstr_t *vstr = m_new_obj(vstr_t);
     if (vstr == NULL) {
         return NULL;
     }
@@ -107,7 +101,6 @@
 
 void vstr_reset(vstr_t *vstr) {
     vstr->len = 0;
-    vstr->buf[0] = 0;
     vstr->had_error = false;
 }
 
@@ -129,7 +122,7 @@
     return vstr->len;
 }
 
-// Extend vstr strictly by requested size, return pointer to newly added chunk
+// Extend vstr strictly by requested size, return pointer to newly added chunk.
 char *vstr_extend(vstr_t *vstr, size_t size) {
     if (vstr->fixed_buf) {
         return NULL;
@@ -146,11 +139,11 @@
 }
 
 STATIC bool vstr_ensure_extra(vstr_t *vstr, size_t size) {
-    if (vstr->len + size + 1 > vstr->alloc) {
+    if (vstr->len + size > vstr->alloc) {
         if (vstr->fixed_buf) {
             return false;
         }
-        size_t new_alloc = ROUND_ALLOC((vstr->len + size + 1) * 2);
+        size_t new_alloc = ROUND_ALLOC((vstr->len + size) * 2);
         char *new_buf = m_renew(char, vstr->buf, vstr->alloc, new_alloc);
         if (new_buf == NULL) {
             vstr->had_error = true;
@@ -175,10 +168,17 @@
     }
     char *buf = vstr->buf + vstr->len;
     vstr->len += len;
-    vstr->buf[vstr->len] = 0;
     return buf;
 }
 
+// Doesn't increase len, just makes sure there is a null byte at the end
+void vstr_null_terminate(vstr_t *vstr) {
+    if (vstr->had_error || !vstr_ensure_extra(vstr, 1)) {
+        return;
+    }
+    vstr->buf[vstr->len] = '\0';
+}
+
 void vstr_add_byte(vstr_t *vstr, byte b) {
     byte *buf = (byte*)vstr_add_len(vstr, 1);
     if (buf == NULL) {
@@ -224,11 +224,7 @@
         buf[3] = (c & 0x3F) | 0x80;
     }
 #else
-    byte *buf = (byte*)vstr_add_len(vstr, 1);
-    if (buf == NULL) {
-        return;
-    }
-    buf[0] = c;
+    vstr_add_byte(vstr, c);
 #endif
 }
 
@@ -239,7 +235,7 @@
 void vstr_add_strn(vstr_t *vstr, const char *str, size_t len) {
     if (vstr->had_error || !vstr_ensure_extra(vstr, len)) {
         // if buf is fixed, we got here because there isn't enough room left
-        // so just try to copy as much as we can, with room for null byte
+        // so just try to copy as much as we can, with room for a possible null byte
         if (vstr->fixed_buf && vstr->len + 1 < vstr->alloc) {
             len = vstr->alloc - vstr->len - 1;
             goto copy;
@@ -249,7 +245,6 @@
 copy:
     memmove(vstr->buf + vstr->len, str, len);
     vstr->len += len;
-    vstr->buf[vstr->len] = 0;
 }
 
 STATIC char *vstr_ins_blank_bytes(vstr_t *vstr, size_t byte_pos, size_t byte_len) {
@@ -265,8 +260,8 @@
         if (!vstr_ensure_extra(vstr, byte_len)) {
             return NULL;
         }
-        // copy up the string to make room for the new bytes; +1 for the null byte
-        memmove(vstr->buf + byte_pos + byte_len, vstr->buf + byte_pos, l - byte_pos + 1);
+        // copy up the string to make room for the new bytes
+        memmove(vstr->buf + byte_pos + byte_len, vstr->buf + byte_pos, l - byte_pos);
         // increase the length
         vstr->len += byte_len;
     }
@@ -301,7 +296,6 @@
     } else {
         vstr->len -= len;
     }
-    vstr->buf[vstr->len] = 0;
 }
 
 void vstr_cut_out_bytes(vstr_t *vstr, size_t byte_pos, size_t bytes_to_cut) {
@@ -309,10 +303,8 @@
         return;
     } else if (byte_pos + bytes_to_cut >= vstr->len) {
         vstr->len = byte_pos;
-        vstr->buf[vstr->len] = 0;
     } else {
-        // move includes +1 for null byte at the end
-        memmove(vstr->buf + byte_pos, vstr->buf + byte_pos + bytes_to_cut, vstr->len - byte_pos - bytes_to_cut + 1);
+        memmove(vstr->buf + byte_pos, vstr->buf + byte_pos + bytes_to_cut, vstr->len - byte_pos - bytes_to_cut);
         vstr->len -= bytes_to_cut;
     }
 }