diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2021-12-31 15:27:10 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2021-12-31 15:27:10 +0000 |
commit | b90036a062ca330ac5f667cd1ee503686cbe0b80 (patch) | |
tree | ab9538715188d5017843c6d94e2ee4c5e155448a /sys/src/cmd/rc/io.c | |
parent | 855cf4326f5a07d7142c2d8918f5fa856d912b85 (diff) |
rc: fix everything
Untangle the lexer and interpreter thread state.
Fix the file and line number error reporting, getting rid of
Xsrcfile instruction, as the whole code block can only come
from a single file, stuff the source file in slot[1] of the
code block instead.
Remove limitations for globber (path element limits)
and be more intelligent about handling globbing by
inserting Xglob instruction only when needed and not
run it over every Xsimple argument list.
Remove fragile ndot magic and make it explicit by adding
the -q flag to . builtin command.
Add -b flag for full compilation.
Make exitnext() smart, so we can speculate thru rcmain and
avoid the fork().
Get rid of all print(2) format functions and use io
instead.
Improve the io library, adding rstr() to handle tokenization,
which allows us to look ahead in the already read buffer
for the terminators, avoiding alot of string copies.
Auto indent pcmd(), to make line number reporting more usefull.
Implement here documents properly, so they can work everywhere.
Diffstat (limited to 'sys/src/cmd/rc/io.c')
-rw-r--r-- | sys/src/cmd/rc/io.c | 221 |
1 files changed, 130 insertions, 91 deletions
diff --git a/sys/src/cmd/rc/io.c b/sys/src/cmd/rc/io.c index 2010e80ef..6c89b048f 100644 --- a/sys/src/cmd/rc/io.c +++ b/sys/src/cmd/rc/io.c @@ -3,18 +3,13 @@ #include "io.h" #include "fns.h" -enum { Stralloc = 100, }; - -int pfmtnest = 0; +enum { + NBUF = 8192, +}; void -pfmt(io *f, char *fmt, ...) +vpfmt(io *f, char *fmt, va_list ap) { - va_list ap; - char err[ERRMAX]; - - va_start(ap, fmt); - pfmtnest++; for(;*fmt;fmt++) { if(*fmt!='%') { pchr(f, *fmt); @@ -42,51 +37,103 @@ pfmt(io *f, char *fmt, ...) pwrd(f, va_arg(ap, char *)); break; case 'r': - errstr(err, sizeof err); pstr(f, err); + pstr(f, Errstr()); break; case 's': pstr(f, va_arg(ap, char *)); break; case 't': - pcmd(f, va_arg(ap, struct tree *)); + pcmd(f, va_arg(ap, tree *)); break; case 'v': - pval(f, va_arg(ap, struct word *)); + pval(f, va_arg(ap, word *)); break; default: pchr(f, *fmt); break; } } +} + +void +pfmt(io *f, char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vpfmt(f, fmt, ap); va_end(ap); - if(--pfmtnest==0) - flush(f); } void pchr(io *b, int c) { - if(b->bufp==b->ebuf) - fullbuf(b, c); - else *b->bufp++=c; + if(b->bufp>=b->ebuf) + flushio(b); + *b->bufp++=c; } int rchr(io *b) { - if(b->bufp==b->ebuf) - return emptybuf(b); + if(b->bufp>=b->ebuf) + return emptyiobuf(b); return *b->bufp++; } +char* +rstr(io *b, char *stop) +{ + char *s, *p; + int l, m, n; + + do { + l = rchr(b); + if(l == EOF) + return 0; + } while(strchr(stop, l)); + b->bufp--; + + s = 0; + l = 0; + for(;;){ + p = (char*)b->bufp; + n = (char*)b->ebuf - p; + if(n > 0){ + for(m = 0; m < n; m++){ + if(strchr(stop, p[m])==0) + continue; + + b->bufp += m+1; + if(m > 0 || s==0){ + s = erealloc(s, l+m+1); + memmove(s+l, p, m); + l += m; + } + s[l]='\0'; + return s; + } + s = erealloc(s, l+m+1); + memmove(s+l, p, m); + l += m; + b->bufp += m; + } + if(emptyiobuf(b) == EOF){ + if(s) s[l]='\0'; + return s; + } + b->bufp--; + } +} + void pquo(io *f, char *s) { pchr(f, '\''); - for(;*s;s++) + for(;*s;s++){ if(*s=='\'') - pfmt(f, "''"); - else pchr(f, *s); + pchr(f, *s); + pchr(f, *s); + } pchr(f, '\''); } @@ -154,112 +201,104 @@ poct(io *f, unsigned n) void pval(io *f, word *a) { - if(a){ - while(a->next && a->next->word){ - pwrd(f, (char *)a->word); - pchr(f, ' '); - a = a->next; - } + if(a==0) + return; + while(a->next && a->next->word){ pwrd(f, (char *)a->word); + pchr(f, ' '); + a = a->next; } + pwrd(f, (char *)a->word); } -int -fullbuf(io *f, int c) +io* +newio(uchar *buf, int len, int fd) { - flush(f); - return *f->bufp++=c; + io *f = new(io); + f->buf = buf; + f->bufp = buf; + f->ebuf = buf+len; + f->fd = fd; + return f; } -void -flush(io *f) +/* + * Open a string buffer for writing. + */ +io* +openiostr(void) { - int n; - - if(f->strp){ - n = f->ebuf - f->strp; - f->strp = erealloc(f->strp, n+Stralloc+1); - f->bufp = f->strp + n; - f->ebuf = f->bufp + Stralloc; - memset(f->bufp, '\0', Stralloc+1); - } - else{ - n = f->bufp-f->buf; - if(n && Write(f->fd, f->buf, n) != n){ - Write(2, "Write error\n", 12); - if(ntrap) - dotrap(); - } - f->bufp = f->buf; - f->ebuf = f->buf+NBUF; - } + uchar *buf = emalloc(100+1); + memset(buf, '\0', 100+1); + return newio(buf, 100, -1); } -io* -openfd(int fd) +/* + * Return the buf, free the io + */ +char* +closeiostr(io *f) { - io *f = new(struct io); - f->fd = fd; - f->bufp = f->ebuf = f->buf; - f->strp = 0; - return f; + void *buf = f->buf; + free(f); + return buf; } +/* + * Use a open file descriptor for reading. + */ io* -openstr(void) +openiofd(int fd) { - io *f = new(struct io); - - f->fd = -1; - f->bufp = f->strp = emalloc(Stralloc+1); - f->ebuf = f->bufp + Stralloc; - memset(f->bufp, '\0', Stralloc+1); - return f; + return newio(emalloc(NBUF), 0, fd); } + /* * Open a corebuffer to read. EOF occurs after reading len * characters from buf. */ - io* -opencore(char *s, int len) +openiocore(uchar *buf, int len) { - io *f = new(struct io); - uchar *buf = emalloc(len); - - f->fd = -1 /*open("/dev/null", 0)*/; - f->bufp = f->strp = buf; - f->ebuf = buf+len; - memmove(buf, s, len); - return f; + return newio(buf, len, -1); } void -rewind(io *io) +flushio(io *f) { - if(io->fd==-1) - io->bufp = io->strp; + int n; + + if(f->fd<0){ + n = f->ebuf - f->buf; + f->buf = erealloc(f->buf, n+n+1); + f->bufp = f->buf + n; + f->ebuf = f->bufp + n; + memset(f->bufp, '\0', n+1); + } else{ - io->bufp = io->ebuf = io->buf; - Seek(io->fd, 0L, 0); + n = f->bufp - f->buf; + if(n && Write(f->fd, f->buf, n) != n){ + Write(2, "Write error\n", 12); + if(ntrap) + dotrap(); + } + f->bufp = f->buf; + f->ebuf = f->buf+NBUF; } } void -closeio(io *io) +closeio(io *f) { - if(io->fd>=0) - close(io->fd); - if(io->strp) - free(io->strp); - free(io); + if(f->fd>=0) Close(f->fd); + free(closeiostr(f)); } int -emptybuf(io *f) +emptyiobuf(io *f) { int n; - if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; + if(f->fd<0 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; f->bufp = f->buf; f->ebuf = f->buf + n; return *f->bufp++; |