aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicholas <nbnoll@eml.cc>2021-11-20 20:12:21 -0800
committerNicholas <nbnoll@eml.cc>2021-11-20 20:12:21 -0800
commit138fb272fae79587de3469493b55e4d18eadc722 (patch)
tree447d2af80b8c2ea080253e76d33e128c9b27d3f6 /src
parentc9a32c1a43d2bdded07eaa45732c3a6e195a5442 (diff)
Feat: added buffered io from plan9
As we no longer have the FILE type, we need to buffer our reading and writing so that we don't have to make so many syscalls. The API is nice so that we can buffer other readers. We will update it so that it eats io·Readers/io·Writers.
Diffstat (limited to 'src')
-rw-r--r--src/base/bufio/flush.c36
-rw-r--r--src/base/bufio/getc.c45
-rw-r--r--src/base/bufio/getr.c29
-rw-r--r--src/base/bufio/init.c102
-rw-r--r--src/base/bufio/offset.c24
-rw-r--r--src/base/bufio/open.c27
-rw-r--r--src/base/bufio/openfd.c12
-rw-r--r--src/base/bufio/print.c14
-rw-r--r--src/base/bufio/putc.c19
-rw-r--r--src/base/bufio/read.c54
-rw-r--r--src/base/bufio/readuntil.c64
-rw-r--r--src/base/bufio/rules.mk22
-rw-r--r--src/base/bufio/seek.c57
-rw-r--r--src/base/bufio/ungetc.c13
-rw-r--r--src/base/bufio/ungetr.c13
-rw-r--r--src/base/bufio/vprint.c34
-rw-r--r--src/base/bufio/write.c40
-rw-r--r--src/base/fmt/do.c2
-rw-r--r--src/base/mem/arena.c9
-rw-r--r--src/base/mem/copy.c14
-rw-r--r--src/base/mem/findc.c14
-rw-r--r--src/base/mem/move.c22
-rw-r--r--src/base/mem/rules.mk3
-rw-r--r--src/base/mem/set.c12
-rw-r--r--src/base/mem/set64.c4
-rw-r--r--src/base/utf/canfit.c3
26 files changed, 673 insertions, 15 deletions
diff --git a/src/base/bufio/flush.c b/src/base/bufio/flush.c
new file mode 100644
index 0000000..0974766
--- /dev/null
+++ b/src/base/bufio/flush.c
@@ -0,0 +1,36 @@
+#include "internal.h"
+
+int
+bio·flush(io·Header *io)
+{
+ intptr ni, no;
+
+ switch(io->state){
+ case io·BufWtr:
+ if((ni = io->cap + io->olen))
+ return 0;
+
+ sys·write(io->fd, ni, io->b, &no);
+
+ if(no!=ni){
+ io->pos += ni;
+ io->olen = -io->cap;
+ return 0;
+ }
+
+ io->state = io·BufNil;
+ io->olen = 0;
+ break;
+
+ case io·BufEof:
+ io->state = io·BufRdr;
+ /* fallthrough */
+ case io·BufRdr:
+ io->ilen = 0;
+ io->g = io->e;
+ return 0;
+ default:
+ ;
+ }
+ return io·BufEof;
+}
diff --git a/src/base/bufio/getc.c b/src/base/bufio/getc.c
new file mode 100644
index 0000000..264e01d
--- /dev/null
+++ b/src/base/bufio/getc.c
@@ -0,0 +1,45 @@
+#include "internal.h"
+
+int
+bio·getc(io·Header *io)
+{
+ int i;
+ intptr nr;
+
+loop:
+ i = io->ilen;
+ if(i != 0){
+ io->ilen = i+1;
+ return io->e[i];
+ }
+
+ if(io->state != io·BufRdr){
+ if(io->state == io·BufEnd)
+ io->state = io·BufRdr;
+ return io·BufEof;
+ }
+
+ /*
+ * get next buffer, try to keep io·BufUngets bytes
+ * pre-catenated from the previous read to allow for ungets
+ */
+ mem·move(io->b-io·BufUngets, io->e-io·BufUngets, io·BufUngets);
+ if(sys·read(io->fd, io->cap, io->b, &nr)){
+ io->state = io·BufNil;
+ return io·BufEof;
+ }
+ if(nr == 0){
+ io->state = io·BufEnd;
+ return io·BufEof;
+ }
+
+ if(nr < io->cap){
+ mem·move(io->e-i-io·BufUngets, io->b-io·BufUngets, i+io·BufUngets);
+ io->g = io->e-i;
+ }
+
+ io->ilen = -i;
+ io->pos += +i;
+
+ goto loop;
+}
diff --git a/src/base/bufio/getr.c b/src/base/bufio/getr.c
new file mode 100644
index 0000000..579a387
--- /dev/null
+++ b/src/base/bufio/getr.c
@@ -0,0 +1,29 @@
+#include "internal.h"
+
+rune
+bio·getr(io·Header *io)
+{
+ int c, i;
+ rune r;
+ char buf[UTFmax];
+
+ c = bio·getc(io);
+ if(utf8·onebyte(c)){
+ io->runesz = 1;
+ return c;
+ }
+ buf[0] = c;
+
+ for(i=1;;){
+ if((c = bio·getc(io))<0)
+ return c;
+
+ buf[i++] = c;
+ if(utf8·fullrune(buf, i)){
+ io->runesz = utf8·decode(buf, &r);
+ while(i-- > io->runesz)
+ bio·ungetc(io);
+ return r;
+ }
+ }
+}
diff --git a/src/base/bufio/init.c b/src/base/bufio/init.c
new file mode 100644
index 0000000..7e6dcee
--- /dev/null
+++ b/src/base/bufio/init.c
@@ -0,0 +1,102 @@
+#include "internal.h"
+
+#define MAXHEADERS 20
+static io·Header *tracked[MAXHEADERS];
+static int doexit;
+
+static void
+untrackall(void *arg)
+{
+ int i;
+ io·Header *it;
+
+ for(i=0; i < MAXHEADERS; i++){
+ it = tracked[i];
+ if(it){
+ tracked[i] = nil;
+ bio·flush(it);
+ }
+ }
+}
+
+static void
+untrack(io·Header *io)
+{
+ int i;
+
+ for(i=0; i<arrlen(tracked); i++){
+ if(tracked[i] == io)
+ tracked[i] = nil;
+ }
+}
+
+static void
+track(io·Header *io)
+{
+ int i;
+
+ untrack(io);
+ for(i=0; i<arrlen(tracked); i++){
+ if(!tracked[i]){
+ tracked[i] = io;
+ break;
+ }
+ }
+
+ if(!doexit){
+ doexit = 1;
+ rt·atexit(untrackall, nil);
+ }
+}
+
+int
+bio·initcap(io·Header *io, int fd, int mode, int cap, uchar *buf)
+{
+ buf += io·BufUngets;
+ cap += io·BufUngets;
+
+ switch(mode & ~(sys·OCloseExec|sys·OTrunc)){
+ default:
+ fmt·fprint(2, "initcap: unknown mode %d\n" , mode);
+ return io·BufErr;
+ case sys·ORead:
+ io->state = io·BufRdr;
+ io->olen = 0;
+ break;
+ case sys·OWrite:
+ track(io);
+ io->state = io·BufWtr;
+ io->olen = -cap;
+ break;
+ }
+
+ io->b = buf;
+ io->e = buf+cap;
+ io->g = io->e;
+ io->fd = fd;
+ io->cap = cap;
+ io->pos = io->runesz = io->flag = io->ilen = io->line = 0;
+ return 0;
+}
+
+int
+bio·init(io·Buffer *io, int fd, int mode)
+{
+ return bio·initcap(header(io), fd, mode, io·BufLen + io·BufUngets, io->b);
+}
+
+int
+bio·close(io·Header *io)
+{
+ int err;
+
+ untrack(io);
+
+ err = bio·flush(io);
+ if(io->flag == io·BufMagic){
+ io->flag = 0;
+ if((err=sys·close(io->fd)))
+ return err;
+ }
+ return 0;
+}
diff --git a/src/base/bufio/offset.c b/src/base/bufio/offset.c
new file mode 100644
index 0000000..15579c4
--- /dev/null
+++ b/src/base/bufio/offset.c
@@ -0,0 +1,24 @@
+#include "internal.h"
+
+intptr
+bio·offset(io·Header *io)
+{
+ intptr n;
+ switch(io->state){
+ default:
+ fmt·fprint(2, "offset: unknown state %d\n", io->state);
+ n = io·BufEof;
+ break;
+
+ case io·BufEnd:
+ case io·BufRdr:
+ n = io->pos + io->ilen;
+ break;
+
+ case io·BufWtr:
+ n = io->pos + (io->cap + io->olen);
+ break;
+ }
+
+ return n;
+}
diff --git a/src/base/bufio/open.c b/src/base/bufio/open.c
new file mode 100644
index 0000000..29ccae1
--- /dev/null
+++ b/src/base/bufio/open.c
@@ -0,0 +1,27 @@
+#include "internal.h"
+
+int
+bio·open(char *path, int flag, io·Buffer *io)
+{
+ int fd;
+ switch(flag & ~(sys·OCloseExec|sys·OTrunc)){
+ default:
+ fmt·fprint(2, "open: unknown flag %d\n", flag);
+ return 1;
+
+ case sys·ORead:
+ if(sys·open(path, flag, 0, &fd))
+ return 1;
+ break;
+
+ case sys·OWrite:
+ if(sys·open(path, flag, 0666, &fd))
+ return 1;
+ break;
+ }
+ if(bio·openfd(fd, flag, io)){
+ sys·close(fd);
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/base/bufio/openfd.c b/src/base/bufio/openfd.c
new file mode 100644
index 0000000..66ca967
--- /dev/null
+++ b/src/base/bufio/openfd.c
@@ -0,0 +1,12 @@
+#include "internal.h"
+
+int
+bio·openfd(int fd, int flag, io·Buffer *io)
+{
+ int err;
+ if((err=bio·init(io, fd, flag)))
+ return err;
+
+ io->flag = io·BufMagic;
+ return 0;
+}
diff --git a/src/base/bufio/print.c b/src/base/bufio/print.c
new file mode 100644
index 0000000..04a85f9
--- /dev/null
+++ b/src/base/bufio/print.c
@@ -0,0 +1,14 @@
+#include "internal.h"
+
+int
+bio·print(io·Header *io, char *fmt, ...)
+{
+ int n;
+ va_list args;
+
+ va_start(args, fmt);
+ n = bio·vprint(io, fmt, args);
+ va_end(args);
+
+ return n;
+}
diff --git a/src/base/bufio/putc.c b/src/base/bufio/putc.c
new file mode 100644
index 0000000..e91a1f1
--- /dev/null
+++ b/src/base/bufio/putc.c
@@ -0,0 +1,19 @@
+#include "internal.h"
+
+int
+bio·putc(io·Header *io, int c)
+{
+ intptr i;
+
+ for(;;){
+ i = io->olen;
+ if(i){
+ io->e[i++] = c;
+ io->olen = i;
+ return 0;
+ }
+ if(bio·flush(io) == io·BufEof)
+ break;
+ }
+ return io·BufEof;
+}
diff --git a/src/base/bufio/read.c b/src/base/bufio/read.c
new file mode 100644
index 0000000..ad0275c
--- /dev/null
+++ b/src/base/bufio/read.c
@@ -0,0 +1,54 @@
+#include "internal.h"
+
+intptr
+bio·read(io·Header *io, intptr len, void *buf)
+{
+ uchar *b;
+ intptr c0, c, nr, n, ic;
+
+ b = buf;
+ c = len;
+ ic = io->ilen; // how many bytes we've read and not flushed
+
+ while(c > 0){
+ n = -ic;
+ if(n > c)
+ n = c;
+ if(n == 0){
+ /* only continue if we are a file reader */
+ if(io->state != io·BufRdr)
+ break;
+
+ /* get more bytes */
+ if(sys·read(io->fd, io->cap, io->b, &nr)){
+ io->state = io·BufNil;
+ break;
+ }
+
+ if(nr == 0){
+ io->state = io·BufEnd;
+ break;
+ }
+
+ /* shift bytes within buffer so they end at terminal */
+ io->g = io->b;
+ io->pos += nr;
+ if(nr < io->cap){
+ io->g = io->e-nr;
+ mem·move(io->g, io->b, nr);
+ }
+ ic -= nr;
+ continue;
+ }
+ /* move our read bytes into the caller's buffer */
+ mem·move(b, io->e+ic, n);
+ c -= n;
+ ic += n;
+ b += n;
+ }
+ io->ilen = ic;
+ if(c == len && io->state == io·BufNil)
+ return -1;
+
+ return len-c;
+}
diff --git a/src/base/bufio/readuntil.c b/src/base/bufio/readuntil.c
new file mode 100644
index 0000000..8084cca
--- /dev/null
+++ b/src/base/bufio/readuntil.c
@@ -0,0 +1,64 @@
+#include "internal.h"
+
+void *
+bio·readuntil(io·Header *io, int delim)
+{
+ char *b, *e;
+ intptr i, j;
+
+ i = -io->ilen;
+ if(i==0){
+ if(io->state != io·BufRdr){
+ if(io->state == io·BufEnd)
+ io->state = io·BufRdr;
+ io->line = 0;
+ io->g = io->e;
+ return nil;
+ }
+ }
+
+ /* best case, we find it in the remaining bytes */
+ b = (char*)io->e - i;
+ if((e = mem·findc(b, i, delim)) != nil){
+ j = (e - b)+1;
+ io->line = j;
+ io->ilen += j;
+ return b;
+ }
+ /* ok no luck, shift over the data and get more */
+ if(i < io->cap)
+ mem·move(io->b, b, i);
+ io->g = io->b;
+ /* write to the buffer while we search for delim */
+ b = (char *)io->b + i;
+ while(i < io->cap){
+ if(sys·read(io->fd, io->cap-i, b, &j)){
+ mem·move(io->e-i, io->b, i);
+ io->line = +i;
+ io->ilen = -i;
+ io->g = io->e - i;
+ return 0;
+ }
+ io->pos += j;
+ i += j;
+ e = mem·findc(b, j, delim);
+ if(e!=nil){
+ /* finally have a hit. reset the world */
+ b = (char*)io->e - i;
+ if(i < io->cap){
+ mem·move(b, io->b, i);
+ io->g = (uchar *)b;
+ }
+ j = (e - (char*)io->b) + 1;
+ io->line = j;
+ io->ilen = j - i;
+ return b;
+ }
+ b += j;
+ }
+
+ io->line = +io->cap;
+ io->ilen = -io->cap;
+ io->g = io->b;
+ return 0;
+}
diff --git a/src/base/bufio/rules.mk b/src/base/bufio/rules.mk
index 8089e77..4546aeb 100644
--- a/src/base/bufio/rules.mk
+++ b/src/base/bufio/rules.mk
@@ -1,5 +1,17 @@
-# SRCS_$(d)+=\
-# $(d)/bufio/get.c\
-# $(d)/bufio/read.c\
-# $(d)/bufio/reader.c\
-# $(d)/bufio/unget.c\
+SRCS_$(d)+=\
+ $(d)/bufio/flush.c\
+ $(d)/bufio/getc.c\
+ $(d)/bufio/getr.c\
+ $(d)/bufio/init.c\
+ $(d)/bufio/offset.c\
+ $(d)/bufio/open.c\
+ $(d)/bufio/openfd.c\
+ $(d)/bufio/print.c\
+ $(d)/bufio/putc.c\
+ $(d)/bufio/read.c\
+ $(d)/bufio/readuntil.c\
+ $(d)/bufio/seek.c\
+ $(d)/bufio/ungetc.c\
+ $(d)/bufio/ungetr.c\
+ $(d)/bufio/vprint.c\
+ $(d)/bufio/write.c
diff --git a/src/base/bufio/seek.c b/src/base/bufio/seek.c
new file mode 100644
index 0000000..5d25173
--- /dev/null
+++ b/src/base/bufio/seek.c
@@ -0,0 +1,57 @@
+#include "internal.h"
+
+int
+bio·seek(io·Header *io, intptr offset, int whence, intptr *pos)
+{
+ intptr n,d,cap;
+
+ switch(io->state){
+ default:
+ fmt·fprint(2, "seek: unknown state %d\n", io->state);
+ return io·BufEof;
+ case io·BufEnd:
+ io->state = io·BufRdr;
+ io->ilen = 0;
+ io->g = io->e;
+ /* fallthrough */
+ case io·BufRdr:
+ n = offset;
+ if(whence == sys·SeekCur){
+ n += bio·offset(io);
+ whence = sys·SeekSet;
+ }
+
+ /* can we seek inside our buffer */
+ if(whence == sys·SeekSet){
+ d = n - bio·offset(io);
+ cap = io->e - io->g;
+ if(-cap <= d && d <= cap){
+ io->ilen += d;
+ if(d >= 0){
+ if(io->ilen <= 0){
+ *pos = n;
+ return 0;
+ }
+ }else{
+ if(io->e - io->g >= -io->ilen){
+ *pos = n;
+ return 0;
+ }
+ }
+ }
+ }
+
+ /* nope, call the kernel to do it for us */
+ sys·seek(io->fd, offset, whence, &n);
+ io->ilen = 0;
+ io->g = io->e;
+ break;
+
+ case io·BufWtr:
+ bio·flush(io);
+ sys·seek(io->fd, offset, whence, &n);
+ break;
+ }
+ io->pos = *pos = n;
+ return 0;
+}
diff --git a/src/base/bufio/ungetc.c b/src/base/bufio/ungetc.c
new file mode 100644
index 0000000..70abbab
--- /dev/null
+++ b/src/base/bufio/ungetc.c
@@ -0,0 +1,13 @@
+#include "internal.h"
+
+int
+bio·ungetc(io·Header *io)
+{
+ if(io->state == io·BufEnd)
+ io->state = io·BufRdr;
+ if(io->state != io·BufRdr)
+ return io·BufEof;
+
+ io->ilen--;
+ return 0;
+}
diff --git a/src/base/bufio/ungetr.c b/src/base/bufio/ungetr.c
new file mode 100644
index 0000000..8abdc39
--- /dev/null
+++ b/src/base/bufio/ungetr.c
@@ -0,0 +1,13 @@
+#include "internal.h"
+
+rune
+bio·ungetr(io·Header *io)
+{
+ if(io->state == io·BufEnd)
+ io->state = io·BufRdr;
+ if(io->state != io·BufRdr)
+ return io·BufEof;
+ io->ilen -= io->runesz;
+ io->runesz = 0;
+ return 0;
+}
diff --git a/src/base/bufio/vprint.c b/src/base/bufio/vprint.c
new file mode 100644
index 0000000..70be6bf
--- /dev/null
+++ b/src/base/bufio/vprint.c
@@ -0,0 +1,34 @@
+#include "internal.h"
+
+static int
+flush(fmt·State *fmt)
+{
+ io·Header *io = fmt->file;
+ io->olen = fmt->buffer.cur - fmt->buffer.end;
+ if(bio·flush(io))
+ return 0;
+
+ fmt->buffer.end = (char*)io->e;
+ fmt->buffer.cur = fmt->buffer.beg = fmt->buffer.end + io->olen;
+ return 1;
+}
+
+int
+bio·vprint(io·Header *io, char *fmt, va_list args)
+{
+ int n;
+ fmt·State f;
+
+ f.buffer.end = (char*)io->e;
+ f.buffer.beg = f.buffer.cur = (char*)(io->e + io->olen);
+ f.n = 0;
+ f.file = io;
+ f.flush = flush;
+
+ va_copy(f.args,args);
+ n = fmt·do(&f, fmt);
+ va_end(f.args);
+
+ io->olen = f.buffer.cur - f.buffer.beg;
+ return n;
+}
diff --git a/src/base/bufio/write.c b/src/base/bufio/write.c
new file mode 100644
index 0000000..8b64055
--- /dev/null
+++ b/src/base/bufio/write.c
@@ -0,0 +1,40 @@
+#include "internal.h"
+
+intptr
+bio·write(io·Header *io, intptr len, void *buf)
+{
+ char *b;
+ intptr c, o, nw, n;
+
+ b = buf;
+ c = len;
+ o = io->olen;
+
+ while(c > 0){
+ n = -o;
+ if(n > c)
+ n = c;
+ if(n == 0){
+ if(io->state != io·BufWtr)
+ return io·BufEof;
+ switch(sys·write(io->fd, io->cap, io->b, &nw)){
+ case 0:
+ if(nw != io->cap) goto error;
+ io->pos += nw;
+ o = -io->cap;
+ continue;
+ case sys·ErrorInterrupt:
+ io->state = io·BufNil;
+ /* fallthrough */
+ default: error:
+ return io·BufEof;
+ }
+ }
+ mem·move(io->e+o, b, n);
+ o += n;
+ c -= n;
+ b += n;
+ }
+ io->olen = o;
+ return len-c;
+}
diff --git a/src/base/fmt/do.c b/src/base/fmt/do.c
index 71b005e..3825fc8 100644
--- a/src/base/fmt/do.c
+++ b/src/base/fmt/do.c
@@ -212,7 +212,7 @@ copy(fmt·State *io, char *m, int sz, int n)
if(utf8·onebyte(r)){
nb=1;
m++;
- }else if((me-m) >= UTFmax || utf8·canfit(m, me-m)){
+ }else if((me-m) >= UTFmax || utf8·fullrune(m, me-m)){
nb=utf8·decode(m, &r);
m+=n;
}else
diff --git a/src/base/mem/arena.c b/src/base/mem/arena.c
index b2ce044..37e7b56 100644
--- a/src/base/mem/arena.c
+++ b/src/base/mem/arena.c
@@ -25,15 +25,13 @@ struct mem·Arena
struct Block first;
};
-static
-void*
+static void*
·arenaalloc(void *heap, uint n, ulong size)
{
return mem·arenaalloc(heap, n, size);
}
-static
-void
+static void
·arenafree(void *heap, void *ptr)
{
/* no-op */
@@ -45,8 +43,7 @@ mem·Allocator mem·ArenaAllocator = {
};
-static
-void
+static void
grow(mem·Arena *a, vlong min)
{
uintptr size;
diff --git a/src/base/mem/copy.c b/src/base/mem/copy.c
new file mode 100644
index 0000000..5ce4f90
--- /dev/null
+++ b/src/base/mem/copy.c
@@ -0,0 +1,14 @@
+#include "internal.h"
+
+int
+mem·copy(void *dst, void *src, uintptr len)
+{
+ char *d, *s;
+ if((long)len < 0)
+ return 1;
+
+ d=dst, s=src;
+ while(len-- > 0)
+ *d++ = *s++;
+ return 0;
+}
diff --git a/src/base/mem/findc.c b/src/base/mem/findc.c
new file mode 100644
index 0000000..d3215c5
--- /dev/null
+++ b/src/base/mem/findc.c
@@ -0,0 +1,14 @@
+#include "internal.h"
+
+void *
+mem·findc(void *addr, uintptr len, int c)
+{
+ uchar *a = addr;
+
+ c &= 0xFF;
+ while(len-- > 0){
+ if(*a++ == c)
+ return a-1;
+ }
+ return nil;
+}
diff --git a/src/base/mem/move.c b/src/base/mem/move.c
new file mode 100644
index 0000000..5ad4074
--- /dev/null
+++ b/src/base/mem/move.c
@@ -0,0 +1,22 @@
+#include "internal.h"
+
+int
+mem·move(void *dst, void *src, uintptr len)
+{
+ char *d, *s;
+ if((long)len < 0)
+ return 1;
+
+ d=dst, s=src;
+ if((s < d) && (s+len > d))
+ goto aliased;
+ while(len-- > 0)
+ *d++ = *s++;
+ return 0;
+
+aliased:
+ d+=len, s+=len;
+ while(len-- > 0)
+ *--d = *--s;
+ return 0;
+}
diff --git a/src/base/mem/rules.mk b/src/base/mem/rules.mk
index b912d0c..fda54e1 100644
--- a/src/base/mem/rules.mk
+++ b/src/base/mem/rules.mk
@@ -2,4 +2,7 @@ SRCS_$(d)+=\
$(d)/mem/arena.c\
$(d)/mem/buffer.c\
$(d)/mem/interface.c\
+ $(d)/mem/set.c\
$(d)/mem/set64.c\
+ $(d)/mem/copy.c\
+ $(d)/mem/move.c
diff --git a/src/base/mem/set.c b/src/base/mem/set.c
new file mode 100644
index 0000000..2e296be
--- /dev/null
+++ b/src/base/mem/set.c
@@ -0,0 +1,12 @@
+#include "internal.h"
+
+int
+mem·set(void *addr, int c, uintptr len)
+{
+ char *a = addr;
+
+ while(len-- > 0)
+ *a++ = c;
+
+ return 0;
+}
diff --git a/src/base/mem/set64.c b/src/base/mem/set64.c
index 464b3ad..7000866 100644
--- a/src/base/mem/set64.c
+++ b/src/base/mem/set64.c
@@ -1,6 +1,6 @@
#include "internal.h"
-void
+int
mem·set64(void *dst, uint64 val, uintptr size)
{
intptr i;
@@ -10,4 +10,6 @@ mem·set64(void *dst, uint64 val, uintptr size)
for(; i < size; i++)
((byte*)dst)[i] = ((byte*)&val)[i&7];
+
+ return 0;
}
diff --git a/src/base/utf/canfit.c b/src/base/utf/canfit.c
index 4579ab3..fddf580 100644
--- a/src/base/utf/canfit.c
+++ b/src/base/utf/canfit.c
@@ -2,7 +2,7 @@
/* returns 1 if string of length n is long enough to be decoded */
int
-utf8·canfit(byte* s, int n)
+utf8·fullrune(byte* s, int n)
{
int i;
rune c;
@@ -13,7 +13,6 @@ utf8·canfit(byte* s, int n)
c = *(ubyte*)s;
if(c < TByte1)
return 1;
-
if(c < TByte3)
return n >= 2;
if(c < TByte4)