123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #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;
- }
|