|
|
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.