]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/rc/io.c
audiohda: fix syntax error
[plan9front.git] / sys / src / cmd / rc / io.c
1 #include "rc.h"
2 #include "exec.h"
3 #include "io.h"
4 #include "fns.h"
5
6 enum { Stralloc = 100, };
7
8 int pfmtnest = 0;
9
10 void
11 pfmt(io *f, char *fmt, ...)
12 {
13         va_list ap;
14         char err[ERRMAX];
15
16         va_start(ap, fmt);
17         pfmtnest++;
18         for(;*fmt;fmt++) {
19                 if(*fmt!='%') {
20                         pchr(f, *fmt);
21                         continue;
22                 }
23                 if(*++fmt == '\0')              /* "blah%"? */
24                         break;
25                 switch(*fmt){
26                 case 'c':
27                         pchr(f, va_arg(ap, int));
28                         break;
29                 case 'd':
30                         pdec(f, va_arg(ap, int));
31                         break;
32                 case 'o':
33                         poct(f, va_arg(ap, unsigned));
34                         break;
35                 case 'p':
36                         pptr(f, va_arg(ap, void*));
37                         break;
38                 case 'Q':
39                         pquo(f, va_arg(ap, char *));
40                         break;
41                 case 'q':
42                         pwrd(f, va_arg(ap, char *));
43                         break;
44                 case 'r':
45                         errstr(err, sizeof err); pstr(f, err);
46                         break;
47                 case 's':
48                         pstr(f, va_arg(ap, char *));
49                         break;
50                 case 't':
51                         pcmd(f, va_arg(ap, struct tree *));
52                         break;
53                 case 'v':
54                         pval(f, va_arg(ap, struct word *));
55                         break;
56                 default:
57                         pchr(f, *fmt);
58                         break;
59                 }
60         }
61         va_end(ap);
62         if(--pfmtnest==0)
63                 flush(f);
64 }
65
66 void
67 pchr(io *b, int c)
68 {
69         if(b->bufp==b->ebuf)
70                 fullbuf(b, c);
71         else *b->bufp++=c;
72 }
73
74 int
75 rchr(io *b)
76 {
77         if(b->bufp==b->ebuf)
78                 return emptybuf(b);
79         return *b->bufp++;
80 }
81
82 void
83 pquo(io *f, char *s)
84 {
85         pchr(f, '\'');
86         for(;*s;s++)
87                 if(*s=='\'')
88                         pfmt(f, "''");
89                 else pchr(f, *s);
90         pchr(f, '\'');
91 }
92
93 void
94 pwrd(io *f, char *s)
95 {
96         char *t;
97         for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break;
98         if(t==s || *t)
99                 pquo(f, s);
100         else pstr(f, s);
101 }
102
103 void
104 pptr(io *f, void *v)
105 {
106         int n;
107         uintptr p;
108
109         p = (uintptr)v;
110         if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
111                 for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
112
113         for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
114 }
115
116 void
117 pstr(io *f, char *s)
118 {
119         if(s==0)
120                 s="(null)";
121         while(*s) pchr(f, *s++);
122 }
123
124 void
125 pdec(io *f, int n)
126 {
127         if(n<0){
128                 n=-n;
129                 if(n>=0){
130                         pchr(f, '-');
131                         pdec(f, n);
132                         return;
133                 }
134                 /* n is two's complement minimum integer */
135                 n = 1-n;
136                 pchr(f, '-');
137                 pdec(f, n/10);
138                 pchr(f, n%10+'1');
139                 return;
140         }
141         if(n>9)
142                 pdec(f, n/10);
143         pchr(f, n%10+'0');
144 }
145
146 void
147 poct(io *f, unsigned n)
148 {
149         if(n>7)
150                 poct(f, n>>3);
151         pchr(f, (n&7)+'0');
152 }
153
154 void
155 pval(io *f, word *a)
156 {
157         if(a){
158                 while(a->next && a->next->word){
159                         pwrd(f, (char *)a->word);
160                         pchr(f, ' ');
161                         a = a->next;
162                 }
163                 pwrd(f, (char *)a->word);
164         }
165 }
166
167 int
168 fullbuf(io *f, int c)
169 {
170         flush(f);
171         return *f->bufp++=c;
172 }
173
174 void
175 flush(io *f)
176 {
177         int n;
178
179         if(f->strp){
180                 n = f->ebuf - f->strp;
181                 f->strp = erealloc(f->strp, n+Stralloc+1);
182                 f->bufp = f->strp + n;
183                 f->ebuf = f->bufp + Stralloc;
184                 memset(f->bufp, '\0', Stralloc+1);
185         }
186         else{
187                 n = f->bufp-f->buf;
188                 if(n && Write(f->fd, f->buf, n) != n){
189                         Write(2, "Write error\n", 12);
190                         if(ntrap)
191                                 dotrap();
192                 }
193                 f->bufp = f->buf;
194                 f->ebuf = f->buf+NBUF;
195         }
196 }
197
198 io*
199 openfd(int fd)
200 {
201         io *f = new(struct io);
202         f->fd = fd;
203         f->bufp = f->ebuf = f->buf;
204         f->strp = 0;
205         return f;
206 }
207
208 io*
209 openstr(void)
210 {
211         io *f = new(struct io);
212
213         f->fd = -1;
214         f->bufp = f->strp = emalloc(Stralloc+1);
215         f->ebuf = f->bufp + Stralloc;
216         memset(f->bufp, '\0', Stralloc+1);
217         return f;
218 }
219 /*
220  * Open a corebuffer to read.  EOF occurs after reading len
221  * characters from buf.
222  */
223
224 io*
225 opencore(char *s, int len)
226 {
227         io *f = new(struct io);
228         uchar *buf = emalloc(len);
229
230         f->fd = -1 /*open("/dev/null", 0)*/;
231         f->bufp = f->strp = buf;
232         f->ebuf = buf+len;
233         memmove(buf, s, len);
234         return f;
235 }
236
237 void
238 rewind(io *io)
239 {
240         if(io->fd==-1)
241                 io->bufp = io->strp;
242         else{
243                 io->bufp = io->ebuf = io->buf;
244                 Seek(io->fd, 0L, 0);
245         }
246 }
247
248 void
249 closeio(io *io)
250 {
251         if(io->fd>=0)
252                 close(io->fd);
253         if(io->strp)
254                 free(io->strp);
255         free(io);
256 }
257
258 int
259 emptybuf(io *f)
260 {
261         int n;
262         if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
263         f->bufp = f->buf;
264         f->ebuf = f->buf + n;
265         return *f->bufp++;
266 }