chiark / gitweb /
Fix memory and type management bugs.
[chiark-tcl.git] / base / hook.c
index 7f889fbdc6077632ada45be5e5a6adca703df142..cdcb246d2c742b945ad8444faad1cd1705529b01 100644 (file)
@@ -61,10 +61,10 @@ int do_hbytes_rep_info(ClientData cd, Tcl_Interp *ip,
 }
 
 static void hbytes_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
-  objfreeir(dup);
   hbytes_array(OBJ_HBYTES(dup),
               hbytes_data(OBJ_HBYTES(src)),
               hbytes_len(OBJ_HBYTES(src)));
+  dup->typePtr= &hbytes_type;
 }
 
 static void hbytes_t_free(Tcl_Obj *o) {
@@ -197,6 +197,50 @@ int do_hbytes_random(ClientData cd, Tcl_Interp *ip,
   return TCL_OK;
 }  
   
+int do_hbytes_overwrite(ClientData cd, Tcl_Interp *ip,
+                       HBytes_Var v, int start, HBytes_Value sub) {
+  int sub_l;
+
+  sub_l= hbytes_len(&sub);
+  if (start < 0)
+    return staticerr(ip, "hbytes overwrite start -ve");
+  if (start + sub_l > hbytes_len(v.hb))
+    return staticerr(ip, "hbytes overwrite out of range");
+  memcpy(hbytes_data(v.hb) + start, hbytes_data(&sub), sub_l);
+  return TCL_OK;
+}
+
+int do_hbytes_trimleft(ClientData cd, Tcl_Interp *ip, HBytes_Var v) {
+  const Byte *o, *p, *e;
+  o= p= hbytes_data(v.hb);
+  e= p + hbytes_len(v.hb);
+
+  while (p<e && !*p) p++;
+  if (p != o)
+    hbytes_unprepend(v.hb, p-o);
+
+  return TCL_OK;
+}
+
+int do_hbytes_repeat(ClientData cd, Tcl_Interp *ip,
+                    HBytes_Value sub, int count, HBytes_Value *result) {
+  int sub_l;
+  Byte *data;
+  const Byte *sub_d;
+
+  sub_l= hbytes_len(&sub);
+  if (count < 0) return staticerr(ip, "hbytes repeat count -ve");
+  if (count > INT_MAX/sub_l) return staticerr(ip, "hbytes repeat too long");
+
+  data= hbytes_arrayspace(result, sub_l*count);
+  sub_d= hbytes_data(&sub);
+  while (count) {
+    memcpy(data, sub_d, sub_l);
+    count--; data += sub_l;
+  }
+  return TCL_OK;
+}  
+
 int do_hbytes_zeroes(ClientData cd, Tcl_Interp *ip,
                     int length, HBytes_Value *result) {
   Byte *space;