From 12e09f9f85ac48ff891adf92f3b2c9a5fea27273 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sat, 4 Dec 2021 14:10:21 -0800 Subject: Chore(REMOVE): finished deprecation of old io functions. The old methods were simple wrappers of C standard library functions. We've moved (painfully) over to a new interface that allows for files to live on the stack. All users of the functionality are ported over. --- src/base/io/close.c | 7 ---- src/base/io/fd.c | 7 ---- src/base/io/flush.c | 33 +++++++++++++++- src/base/io/get.c | 7 ---- src/base/io/getc.c | 45 +++++++++++++++++++++ src/base/io/getr.c | 29 ++++++++++++++ src/base/io/init.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ src/base/io/interface.c | 70 --------------------------------- src/base/io/internal.h | 4 +- src/base/io/offset.c | 24 ++++++++++++ src/base/io/open.c | 27 +++++++++++-- src/base/io/openfd.c | 12 ++++++ src/base/io/print.c | 14 +++++++ src/base/io/putbyte.c | 7 ---- src/base/io/putc.c | 19 +++++++++ src/base/io/putstring.c | 7 ---- src/base/io/read.c | 53 +++++++++++++++++++++++-- src/base/io/readline.c | 11 ++++++ src/base/io/readln.c | 12 ------ src/base/io/readuntil.c | 65 ++++++++++++++++++++++++++++++ src/base/io/rules.mk | 21 +++++----- src/base/io/seek.c | 54 ++++++++++++++++++++++++- src/base/io/stat.c | 7 ---- src/base/io/tell.c | 7 ---- src/base/io/unget.c | 7 ---- src/base/io/ungetc.c | 13 ++++++ src/base/io/ungetr.c | 13 ++++++ src/base/io/vprint.c | 34 ++++++++++++++++ src/base/io/write.c | 39 ++++++++++++++++-- 29 files changed, 588 insertions(+), 162 deletions(-) delete mode 100644 src/base/io/close.c delete mode 100644 src/base/io/fd.c delete mode 100644 src/base/io/get.c create mode 100644 src/base/io/getc.c create mode 100644 src/base/io/getr.c create mode 100644 src/base/io/init.c delete mode 100644 src/base/io/interface.c create mode 100644 src/base/io/offset.c create mode 100644 src/base/io/openfd.c create mode 100644 src/base/io/print.c delete mode 100644 src/base/io/putbyte.c create mode 100644 src/base/io/putc.c delete mode 100644 src/base/io/putstring.c create mode 100644 src/base/io/readline.c delete mode 100644 src/base/io/readln.c create mode 100644 src/base/io/readuntil.c delete mode 100644 src/base/io/stat.c delete mode 100644 src/base/io/tell.c delete mode 100644 src/base/io/unget.c create mode 100644 src/base/io/ungetc.c create mode 100644 src/base/io/ungetr.c create mode 100644 src/base/io/vprint.c (limited to 'src/base/io') diff --git a/src/base/io/close.c b/src/base/io/close.c deleted file mode 100644 index 5a773cd..0000000 --- a/src/base/io/close.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -int -io·close(io·Stream *s) -{ - return fclose(s); -} diff --git a/src/base/io/fd.c b/src/base/io/fd.c deleted file mode 100644 index ded1b02..0000000 --- a/src/base/io/fd.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -int -io·fd(io·Stream *s) -{ - return fileno(s); -} diff --git a/src/base/io/flush.c b/src/base/io/flush.c index 0f1217a..ff970b4 100644 --- a/src/base/io/flush.c +++ b/src/base/io/flush.c @@ -1,7 +1,36 @@ #include "internal.h" int -io·flush(io·Stream *s) +io·flush(io·Header *io) { - return fflush(s); + 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/io/get.c b/src/base/io/get.c deleted file mode 100644 index d4e52f8..0000000 --- a/src/base/io/get.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -byte -io·getbyte(io·Stream *s) -{ - return fgetc(s); -} diff --git a/src/base/io/getc.c b/src/base/io/getc.c new file mode 100644 index 0000000..68e1772 --- /dev/null +++ b/src/base/io/getc.c @@ -0,0 +1,45 @@ +#include "internal.h" + +int +io·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/io/getr.c b/src/base/io/getr.c new file mode 100644 index 0000000..01b0f45 --- /dev/null +++ b/src/base/io/getr.c @@ -0,0 +1,29 @@ +#include "internal.h" + +rune +io·getr(io·Header *io) +{ + int c, i; + rune r; + char buf[UTFmax]; + + c = io·getc(io); + if(utf8·onebyte(c)){ + io->runesz = 1; + return c; + } + buf[0] = c; + + for(i=1;;){ + if((c = io·getc(io))<0) + return c; + + buf[i++] = c; + if(utf8·fullrune(buf, i)){ + io->runesz = utf8·decode(buf, &r); + while(i-- > io->runesz) + io·ungetc(io); + return r; + } + } +} diff --git a/src/base/io/init.c b/src/base/io/init.c new file mode 100644 index 0000000..81b26c2 --- /dev/null +++ b/src/base/io/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; + io·flush(it); + } + } +} + +static void +untrack(io·Header *io) +{ + int i; + + for(i=0; istate = 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->nread = 0; + return 0; +} + +int +io·init(io·Buffer *io, int fd, int mode) +{ + return io·initcap(header(io), fd, mode, io·BufLen + io·BufUngets, io->bytes); +} + +int +io·close(io·Header *io) +{ + int err; + + untrack(io); + + err = io·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/io/interface.c b/src/base/io/interface.c deleted file mode 100644 index 80469bf..0000000 --- a/src/base/io/interface.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "internal.h" - -static -int -·read(void *rdr, int size, int n, void *buf) -{ - return io·read((io·Stream *)rdr, size, n, buf); -} - -static -byte -·get(void *rdr) -{ - return io·getbyte((io·Stream *)rdr); -} - -static -int -·unget(void *rdr, byte c) -{ - return io·ungetbyte((io·Stream *)rdr, c); -} - -static -int -·write(void *wtr, int sz, int n, void *buf) -{ - return io·write((io·Stream *)wtr, sz, n, buf); -} - -static -int -·put(void *wtr, byte c) -{ - return io·putbyte((io·Stream *)wtr, c); -} - -static -int -·puts(void *wtr, string s) -{ - return io·putstring((io·Stream *)wtr, s); -} - -static -int -·seek(void *skr, long off, int whence) -{ - return io·seek((io·Stream *)skr, off, whence); -} - -static -long -·tell(void *skr) -{ - return io·tell((io·Stream *)skr); -} - -/* actual interfaces */ -io·Reader sys·Reader = (io·Reader){ ·read }; -io·Seeker sys·Seeker = (io·Seeker){ ·seek, ·tell }; -io·Peeker sys·Peeker = (io·Peeker){ ·get, ·unget }; -io·SeekReader sys·SeekReader = (io·SeekReader){ ·seek, ·tell, ·read }; -io·PeekReader sys·PeekReader = (io·PeekReader){ ·read, ·get, ·unget }; - -io·Writer sys·Writer = (io·Writer){ ·write }; -io·Putter sys·Putter = (io·Putter){ ·put, ·puts }; -io·PutWriter sys·PutWriter = (io·PutWriter){ ·write, ·put, ·puts }; - -io·ReadWriter sys·ReadWriter = (io·ReadWriter){ ·read, ·write }; diff --git a/src/base/io/internal.h b/src/base/io/internal.h index 302c035..a59e787 100644 --- a/src/base/io/internal.h +++ b/src/base/io/internal.h @@ -1,4 +1,4 @@ -#pragma once - #include #include + +#define header(io) ((io·Header*)(io)) diff --git a/src/base/io/offset.c b/src/base/io/offset.c new file mode 100644 index 0000000..81ef994 --- /dev/null +++ b/src/base/io/offset.c @@ -0,0 +1,24 @@ +#include "internal.h" + +intptr +io·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/io/open.c b/src/base/io/open.c index fe78255..ed0be92 100644 --- a/src/base/io/open.c +++ b/src/base/io/open.c @@ -1,7 +1,28 @@ #include "internal.h" -io·Stream* -io·open(byte *name, byte *mode) +int +io·open(char *path, int flag, io·Buffer *io) { - return fopen(name, mode); + int err,fd; + switch(flag & ~(sys·OCloseExec|sys·OTrunc)){ + default: + /* fmt·fprint(2, "open: unknown flag %d\n", flag); */ + return 1; + + case sys·ORead: + if((err=sys·open(path, flag, 0, &fd))) + return err; + break; + + case sys·OWrite: + if((err=sys·open(path, flag, 0666, &fd))) + return err; + break; + } + + if((err=io·openfd(fd, flag, io))){ + sys·close(fd); + return err; + } + return 0; } diff --git a/src/base/io/openfd.c b/src/base/io/openfd.c new file mode 100644 index 0000000..db13413 --- /dev/null +++ b/src/base/io/openfd.c @@ -0,0 +1,12 @@ +#include "internal.h" + +int +io·openfd(int fd, int flag, io·Buffer *io) +{ + int err; + if((err=io·init(io, fd, flag))) + return err; + + io->flag = io·BufMagic; + return 0; +} diff --git a/src/base/io/print.c b/src/base/io/print.c new file mode 100644 index 0000000..00d39d9 --- /dev/null +++ b/src/base/io/print.c @@ -0,0 +1,14 @@ +#include "internal.h" + +int +io·print(io·Header *io, char *fmt, ...) +{ + int n; + va_list args; + + va_start(args, fmt); + n = io·vprint(io, fmt, args); + va_end(args); + + return n; +} diff --git a/src/base/io/putbyte.c b/src/base/io/putbyte.c deleted file mode 100644 index 2350a8d..0000000 --- a/src/base/io/putbyte.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -int -io·putbyte(io·Stream *s, byte c) -{ - return fputc(c, s); -} diff --git a/src/base/io/putc.c b/src/base/io/putc.c new file mode 100644 index 0000000..167f10f --- /dev/null +++ b/src/base/io/putc.c @@ -0,0 +1,19 @@ +#include "internal.h" + +int +io·putc(io·Header *io, int c) +{ + intptr i; + + for(;;){ + i = io->olen; + if(i){ + io->e[i++] = c; + io->olen = i; + return 0; + } + if(io·flush(io) == io·BufEof) + break; + } + return io·BufEof; +} diff --git a/src/base/io/putstring.c b/src/base/io/putstring.c deleted file mode 100644 index 53fa993..0000000 --- a/src/base/io/putstring.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -int -io·putstring(io·Stream *s, string str) -{ - return fputs(str, s); -} diff --git a/src/base/io/read.c b/src/base/io/read.c index b0ed3d2..d4f7bd9 100644 --- a/src/base/io/read.c +++ b/src/base/io/read.c @@ -1,7 +1,54 @@ #include "internal.h" -int -io·read(io·Stream *s, int sz, int n, void *buf) +intptr +io·read(io·Header *io, intptr len, void *buf) { - return fread(buf, sz, n, s); + 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/io/readline.c b/src/base/io/readline.c new file mode 100644 index 0000000..2be19db --- /dev/null +++ b/src/base/io/readline.c @@ -0,0 +1,11 @@ +#include "internal.h" + +void * +io·readline(io·Header *io, int null) +{ + char *start = io·readuntil(io, '\n'); + if(null && start) + start[io->nread-1] = 0; + + return start; +} diff --git a/src/base/io/readln.c b/src/base/io/readln.c deleted file mode 100644 index 283472d..0000000 --- a/src/base/io/readln.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "internal.h" - -int -io·readln(io·Stream *s, int n, byte* buf) -{ - byte* b; - b = fgets(buf, n+1, s); - if(b == nil) - return -1; - - return strlen(buf); -} diff --git a/src/base/io/readuntil.c b/src/base/io/readuntil.c new file mode 100644 index 0000000..d5c2ed6 --- /dev/null +++ b/src/base/io/readuntil.c @@ -0,0 +1,65 @@ +#include "internal.h" + +void * +io·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->nread = 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->nread = 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) || j == 0){ + mem·move(io->e-i, io->b, i); + io->nread = +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->nread = j; + io->ilen = j - i; + return b; + } + b += j; + } + + io->nread = +io->cap; + io->ilen = -io->cap; + io->g = io->b; + return nil; +} diff --git a/src/base/io/rules.mk b/src/base/io/rules.mk index 124cd09..3a091be 100644 --- a/src/base/io/rules.mk +++ b/src/base/io/rules.mk @@ -1,15 +1,18 @@ SRCS_$(d)+=\ - $(d)/io/fd.c\ $(d)/io/flush.c\ - $(d)/io/interface.c\ + $(d)/io/getc.c\ + $(d)/io/getr.c\ + $(d)/io/init.c\ + $(d)/io/offset.c\ $(d)/io/open.c\ - $(d)/io/close.c\ - $(d)/io/putbyte.c\ - $(d)/io/putstring.c\ + $(d)/io/openfd.c\ + $(d)/io/print.c\ + $(d)/io/putc.c\ $(d)/io/read.c\ - $(d)/io/readln.c\ + $(d)/io/readline.c\ + $(d)/io/readuntil.c\ $(d)/io/seek.c\ - $(d)/io/stat.c\ - $(d)/io/tell.c\ - $(d)/io/unget.c\ + $(d)/io/ungetc.c\ + $(d)/io/ungetr.c\ + $(d)/io/vprint.c\ $(d)/io/write.c diff --git a/src/base/io/seek.c b/src/base/io/seek.c index 1be4ee7..4fa1aff 100644 --- a/src/base/io/seek.c +++ b/src/base/io/seek.c @@ -1,7 +1,57 @@ #include "internal.h" int -io·seek(io·Stream *s, long off, int whence) +io·seek(io·Header *io, intptr offset, int whence, intptr *pos) { - return fseek(s, off, whence); + 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 += io·offset(io); + whence = sys·SeekSet; + } + + /* can we seek inside our buffer */ + if(whence == sys·SeekSet){ + d = n - io·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: + io·flush(io); + sys·seek(io->fd, offset, whence, &n); + break; + } + io->pos = *pos = n; + return 0; } diff --git a/src/base/io/stat.c b/src/base/io/stat.c deleted file mode 100644 index 063ff8f..0000000 --- a/src/base/io/stat.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -int -io·stat(io·Stream *s, io·Stat *buf) -{ - return fstat(fileno(s), buf); -} diff --git a/src/base/io/tell.c b/src/base/io/tell.c deleted file mode 100644 index 1c50439..0000000 --- a/src/base/io/tell.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -long -io·tell(io·Stream *s) -{ - return ftell(s); -} diff --git a/src/base/io/unget.c b/src/base/io/unget.c deleted file mode 100644 index 5c37433..0000000 --- a/src/base/io/unget.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "internal.h" - -int -io·ungetbyte(io·Stream *s, byte c) -{ - return ungetc(c, s); -} diff --git a/src/base/io/ungetc.c b/src/base/io/ungetc.c new file mode 100644 index 0000000..201ffd6 --- /dev/null +++ b/src/base/io/ungetc.c @@ -0,0 +1,13 @@ +#include "internal.h" + +int +io·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/io/ungetr.c b/src/base/io/ungetr.c new file mode 100644 index 0000000..c0b8e9d --- /dev/null +++ b/src/base/io/ungetr.c @@ -0,0 +1,13 @@ +#include "internal.h" + +rune +io·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/io/vprint.c b/src/base/io/vprint.c new file mode 100644 index 0000000..6fa446e --- /dev/null +++ b/src/base/io/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(io·flush(io)) + return 0; + + fmt->buffer.end = (char*)io->e; + fmt->buffer.cur = fmt->buffer.beg = fmt->buffer.end + io->olen; + return 1; +} + +int +io·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/io/write.c b/src/base/io/write.c index 63df664..2f37200 100644 --- a/src/base/io/write.c +++ b/src/base/io/write.c @@ -1,7 +1,40 @@ #include "internal.h" -int -io·write(io·Stream *s, int sz, int n, void *buf) +intptr +io·write(io·Header *io, intptr len, void *buf) { - return fwrite(buf, sz, n, s); + 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; } -- cgit v1.2.1