diff options
Diffstat (limited to 'src/cmd/rc/io.c')
-rw-r--r-- | src/cmd/rc/io.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/src/cmd/rc/io.c b/src/cmd/rc/io.c new file mode 100644 index 00000000..cf143b0f --- /dev/null +++ b/src/cmd/rc/io.c @@ -0,0 +1,179 @@ +#include "rc.h" +#include "exec.h" +#include "io.h" +#include "fns.h" +int pfmtnest=0; +void pfmt(io *f, char *fmt, ...){ + va_list ap; + char err[ERRMAX]; + va_start(ap, fmt); + pfmtnest++; + for(;*fmt;fmt++) + if(*fmt!='%') pchr(f, *fmt); + else switch(*++fmt){ + case '\0': va_end(ap); return; + case 'c': pchr(f, va_arg(ap, int)); break; + case 'd': pdec(f, va_arg(ap, int)); break; + case 'o': poct(f, va_arg(ap, unsigned)); break; + case 'p': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/ + case 'Q': pquo(f, va_arg(ap, char *)); break; + case 'q': pwrd(f, va_arg(ap, char *)); break; + case 'r': errstr(err, sizeof err); pstr(f, err); break; + case 's': pstr(f, va_arg(ap, char *)); break; + case 't': pcmd(f, va_arg(ap, struct tree *)); break; + case 'v': pval(f, va_arg(ap, struct word *)); break; + default: pchr(f, *fmt); break; + } + 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; +} +int rchr(io *b) +{ + if(b->bufp==b->ebuf) return emptybuf(b); + return *b->bufp++ & 0xFF; +} + +void pquo(io *f, char *s) +{ + pchr(f, '\''); + for(;*s;s++) + if(*s=='\'') pfmt(f, "''"); + else pchr(f, *s); + pchr(f, '\''); +} +void pwrd(io *f, char *s) +{ + char *t; + for(t=s;*t;t++) if(!wordchr(*t)) break; + if(t==s || *t) pquo(f, s); + else pstr(f, s); +} +void phex(io *f, long p) +{ + int n; + for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); +} +void pstr(io *f, char *s) +{ + if(s==0) s="(null)"; + while(*s) pchr(f, *s++); +} +void pdec(io *f, long n) +{ + if(n<0){ + n=-n; + if(n>=0){ + pchr(f, '-'); + pdec(f, n); + return; + } + /* n is two's complement minimum integer */ + n=1-n; + pchr(f, '-'); + pdec(f, n/10); + pchr(f, n%10+'1'); + return; + } + if(n>9) pdec(f, n/10); + pchr(f, n%10+'0'); +} +void poct(io *f, ulong n) +{ + if(n>7) poct(f, n>>3); + pchr(f, (n&7)+'0'); +} +void pval(io *f, word *a) +{ + if(a){ + while(a->next && a->next->word){ + pwrd(f, a->word); + pchr(f, ' '); + a=a->next; + } + pwrd(f, a->word); + } +} +int fullbuf(io *f, int c) +{ + flush(f); + return *f->bufp++=c; +} +void flush(io *f) +{ + int n; + char *s; + if(f->strp){ + n=f->ebuf-f->strp; + f->strp=realloc(f->strp, n+101); + if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101); + f->bufp=f->strp+n; + f->ebuf=f->bufp+100; + for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; + } + else{ + n=f->bufp-f->buf; + if(n && Write(f->fd, f->buf, n) < 0){ + Write(3, "Write error\n", 12); + if(ntrap) dotrap(); + } + f->bufp=f->buf; + f->ebuf=f->buf+NBUF; + } +} +io *openfd(int fd){ + io *f=new(struct io); + f->fd=fd; + f->bufp=f->ebuf=f->buf; + f->strp=0; + return f; +} +io *openstr(void){ + io *f=new(struct io); + char *s; + f->fd=-1; + f->bufp=f->strp=emalloc(101); + f->ebuf=f->bufp+100; + for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; + return f; +} +/* + * Open a corebuffer to read. EOF occurs after reading len + * characters from buf. + */ +io *opencore(char *s, int len) +{ + io *f=new(struct io); + char *buf=emalloc(len); + f->fd= -1 /*open("/dev/null", 0)*/; + f->bufp=f->strp=buf; + f->ebuf=buf+len; + Memcpy(buf, s, len); + return f; +} +void rewind(io *io) +{ + if(io->fd==-1) io->bufp=io->strp; + else{ + io->bufp=io->ebuf=io->buf; + Seek(io->fd, 0L, 0); + } +} +void closeio(io *io) +{ + if(io->fd>=0) close(io->fd); + if(io->strp) efree(io->strp); + efree((char *)io); +} +int emptybuf(io *f) +{ + int n; + if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF; + f->bufp=f->buf; + f->ebuf=f->buf+n; + return *f->bufp++&0xff; +} |