|
|
1.1 ! root 1: #include "rc.h" ! 2: #include "exec.h" ! 3: #include "io.h" ! 4: #include "fns.h" ! 5: #include "stdarg.h" ! 6: int pfmtnest=0; ! 7: void pfmt(io *f, char *fmt, ...){ ! 8: va_list ap; ! 9: va_start(ap, fmt); ! 10: pfmtnest++; ! 11: for(;*fmt;fmt++) ! 12: if(*fmt!='%') pchr(f, *fmt); ! 13: else switch(*++fmt){ ! 14: case '\0': va_end(ap); return; ! 15: case 'c': pchr(f, va_arg(ap, int)); break; ! 16: case 'd': pdec(f, va_arg(ap, int)); break; ! 17: case 'o': poct(f, va_arg(ap, unsigned)); break; ! 18: case 'p': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/ ! 19: case 'Q': pquo(f, va_arg(ap, char *)); break; ! 20: case 'q': pwrd(f, va_arg(ap, char *)); break; ! 21: case 's': pstr(f, va_arg(ap, char *)); break; ! 22: case 't': pcmd(f, va_arg(ap, struct tree *)); break; ! 23: case 'v': pval(f, va_arg(ap, struct word *)); break; ! 24: default: pchr(f, *fmt); break; ! 25: } ! 26: va_end(ap); ! 27: if(--pfmtnest==0) flush(f); ! 28: } ! 29: void pquo(io *f, char *s) ! 30: { ! 31: pchr(f, '\''); ! 32: for(;*s;s++) ! 33: if(*s=='\'') pfmt(f, "''"); ! 34: else pchr(f, *s); ! 35: pchr(f, '\''); ! 36: } ! 37: void pwrd(io *f, char *s) ! 38: { ! 39: char *t; ! 40: for(t=s;*t;t++) if(!wordchr(*t)) break; ! 41: if(t==s || *t) pquo(f, s); ! 42: else pstr(f, s); ! 43: } ! 44: void phex(io *f, long p) ! 45: { ! 46: int n; ! 47: for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); ! 48: } ! 49: void pstr(io *f, char *s) ! 50: { ! 51: if(s==0) s="(null)"; ! 52: while(*s) pchr(f, *s++); ! 53: } ! 54: void pdec(io *f, long n) ! 55: { ! 56: if(n<0){ ! 57: n=-n; ! 58: if(n>=0){ ! 59: pchr(f, '-'); ! 60: pdec(f, n); ! 61: return; ! 62: } ! 63: /* n is two's complement minimum integer */ ! 64: n=1-n; ! 65: pchr(f, '-'); ! 66: pdec(f, n/10); ! 67: pchr(f, n%10+'1'); ! 68: return; ! 69: } ! 70: if(n>9) pdec(f, n/10); ! 71: pchr(f, n%10+'0'); ! 72: } ! 73: void poct(io *f, ulong n) ! 74: { ! 75: if(n>7) poct(f, n>>3); ! 76: pchr(f, (n&7)+'0'); ! 77: } ! 78: void pval(io *f, word *a) ! 79: { ! 80: if(a){ ! 81: while(a->next && a->next->word){ ! 82: pwrd(f, a->word); ! 83: pchr(f, ' '); ! 84: a=a->next; ! 85: } ! 86: pwrd(f, a->word); ! 87: } ! 88: } ! 89: int fullbuf(io *f, int c) ! 90: { ! 91: flush(f); ! 92: return *f->bufp++=c; ! 93: } ! 94: void flush(io *f) ! 95: { ! 96: int n; ! 97: char *s; ! 98: if(f->strp){ ! 99: n=f->ebuf-f->strp; ! 100: f->strp=realloc(f->strp, n+101); ! 101: if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101); ! 102: f->bufp=f->strp+n; ! 103: f->ebuf=f->bufp+100; ! 104: for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; ! 105: } ! 106: else{ ! 107: n=f->bufp-f->buf; ! 108: if(n && Write(f->fd, f->buf, n) < 0){ ! 109: Write(3, "Write error\n", 12); ! 110: if(ntrap) dotrap(); ! 111: } ! 112: f->bufp=f->buf; ! 113: f->ebuf=f->buf+NBUF; ! 114: } ! 115: } ! 116: io *openfd(int fd){ ! 117: io *f=new(struct io); ! 118: f->fd=fd; ! 119: f->bufp=f->ebuf=f->buf; ! 120: f->strp=0; ! 121: return f; ! 122: } ! 123: io *openstr(void){ ! 124: io *f=new(struct io); ! 125: char *s; ! 126: f->fd=-1; ! 127: f->bufp=f->strp=emalloc(101); ! 128: f->ebuf=f->bufp+100; ! 129: for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; ! 130: return f; ! 131: } ! 132: /* ! 133: * Open a corebuffer to read. EOF occurs after reading len ! 134: * characters from buf. ! 135: */ ! 136: io *opencore(char *s, int len) ! 137: { ! 138: io *f=new(struct io); ! 139: char *buf=emalloc(len); ! 140: f->fd= -1 /*open("/dev/null", 0)*/; ! 141: f->bufp=f->strp=buf; ! 142: f->ebuf=buf+len; ! 143: Memcpy(buf, s, len); ! 144: return f; ! 145: } ! 146: rewind(io *io) ! 147: { ! 148: if(io->fd==-1) io->bufp=io->strp; ! 149: else{ ! 150: io->bufp=io->ebuf=io->buf; ! 151: Seek(io->fd, 0L, 0); ! 152: } ! 153: } ! 154: void closeio(io *io) ! 155: { ! 156: if(io->fd>=0) close(io->fd); ! 157: if(io->strp) efree(io->strp); ! 158: efree((char *)io); ! 159: } ! 160: int emptybuf(io *f) ! 161: { ! 162: int n; ! 163: if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF; ! 164: f->bufp=f->buf; ! 165: f->ebuf=f->buf+n; ! 166: return *f->bufp++&0xff; ! 167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.