Blob


1 #include "rc.h"
2 #include "exec.h"
3 #include "io.h"
4 #include "fns.h"
5 int pfmtnest=0;
6 void pfmt(io *f, char *fmt, ...){
7 va_list ap;
8 char err[ERRMAX];
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 'r': errstr(err, sizeof err); pstr(f, err); break;
22 case 's': pstr(f, va_arg(ap, char *)); break;
23 case 't': pcmd(f, va_arg(ap, struct tree *)); break;
24 case 'v': pval(f, va_arg(ap, struct word *)); break;
25 default: pchr(f, *fmt); break;
26 }
27 va_end(ap);
28 if(--pfmtnest==0) flush(f);
29 }
30 void pchr(io *b, int c)
31 {
32 if(b->bufp==b->ebuf) fullbuf(b, c);
33 else *b->bufp++=c;
34 }
35 int rchr(io *b)
36 {
37 if(b->bufp==b->ebuf) return emptybuf(b);
38 return *b->bufp++ & 0xFF;
39 }
41 void pquo(io *f, char *s)
42 {
43 pchr(f, '\'');
44 for(;*s;s++)
45 if(*s=='\'') pfmt(f, "''");
46 else pchr(f, *s);
47 pchr(f, '\'');
48 }
49 void pwrd(io *f, char *s)
50 {
51 char *t;
52 for(t=s;*t;t++) if(!wordchr(*t)) break;
53 if(t==s || *t) pquo(f, s);
54 else pstr(f, s);
55 }
56 void phex(io *f, long p)
57 {
58 int n;
59 for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
60 }
61 void pstr(io *f, char *s)
62 {
63 if(s==0) s="(null)";
64 while(*s) pchr(f, *s++);
65 }
66 void pdec(io *f, long n)
67 {
68 if(n<0){
69 n=-n;
70 if(n>=0){
71 pchr(f, '-');
72 pdec(f, n);
73 return;
74 }
75 /* n is two's complement minimum integer */
76 n=1-n;
77 pchr(f, '-');
78 pdec(f, n/10);
79 pchr(f, n%10+'1');
80 return;
81 }
82 if(n>9) pdec(f, n/10);
83 pchr(f, n%10+'0');
84 }
85 void poct(io *f, ulong n)
86 {
87 if(n>7) poct(f, n>>3);
88 pchr(f, (n&7)+'0');
89 }
90 void pval(io *f, word *a)
91 {
92 if(a){
93 while(a->next && a->next->word){
94 pwrd(f, a->word);
95 pchr(f, ' ');
96 a=a->next;
97 }
98 pwrd(f, a->word);
99 }
101 int fullbuf(io *f, int c)
103 flush(f);
104 return *f->bufp++=c;
106 void flush(io *f)
108 int n;
109 char *s;
110 if(f->strp){
111 n=f->ebuf-f->strp;
112 f->strp=realloc(f->strp, n+101);
113 if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101);
114 f->bufp=f->strp+n;
115 f->ebuf=f->bufp+100;
116 for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
118 else{
119 n=f->bufp-f->buf;
120 if(n && Write(f->fd, f->buf, n) < 0){
121 Write(3, "Write error\n", 12);
122 if(ntrap) dotrap();
124 f->bufp=f->buf;
125 f->ebuf=f->buf+NBUF;
128 io *openfd(int fd){
129 io *f;
130 f=new(struct io);
131 f->fd=fd;
132 f->bufp=f->ebuf=f->buf;
133 f->strp=0;
134 return f;
136 io *openstr(void){
137 io *f=new(struct io);
138 char *s;
139 f->fd=-1;
140 f->bufp=f->strp=emalloc(101);
141 f->ebuf=f->bufp+100;
142 for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
143 return f;
145 /*
146 * Open a corebuffer to read. EOF occurs after reading len
147 * characters from buf.
148 */
149 io *opencore(char *s, int len)
151 io *f=new(struct io);
152 char *buf=emalloc(len);
153 f->fd= -1 /*open("/dev/null", 0)*/;
154 f->bufp=f->strp=buf;
155 f->ebuf=buf+len;
156 Memcpy(buf, s, len);
157 return f;
159 /*
160 void rewind(io *io)
162 if(io->fd==-1) io->bufp=io->strp;
163 else{
164 io->bufp=io->ebuf=io->buf;
165 Seek(io->fd, 0L, 0);
168 */
169 void closeio(io *io)
171 if(io->fd>=0) close(io->fd);
172 if(io->strp) efree(io->strp);
173 efree((char *)io);
175 int emptybuf(io *f)
177 int n;
178 if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF;
179 f->bufp=f->buf;
180 f->ebuf=f->buf+n;
181 return *f->bufp++&0xff;