]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/rc/io.c
kernel: keep segment locked for data2txt
[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 = realloc(f->strp, n+Stralloc+1);
182                 if(f->strp==0)
183                         panic("Can't realloc %d bytes in flush!", n+Stralloc+1);
184                 f->bufp = f->strp + n;
185                 f->ebuf = f->bufp + Stralloc;
186                 memset(f->bufp, '\0', Stralloc+1);
187         }
188         else{
189                 n = f->bufp-f->buf;
190                 if(n && Write(f->fd, f->buf, n) != n){
191                         Write(2, "Write error\n", 12);
192                         if(ntrap)
193                                 dotrap();
194                 }
195                 f->bufp = f->buf;
196                 f->ebuf = f->buf+NBUF;
197         }
198 }
199
200 io*
201 openfd(int fd)
202 {
203         io *f = new(struct io);
204         f->fd = fd;
205         f->bufp = f->ebuf = f->buf;
206         f->strp = 0;
207         return f;
208 }
209
210 io*
211 openstr(void)
212 {
213         io *f = new(struct io);
214
215         f->fd = -1;
216         f->bufp = f->strp = emalloc(Stralloc+1);
217         f->ebuf = f->bufp + Stralloc;
218         memset(f->bufp, '\0', Stralloc+1);
219         return f;
220 }
221 /*
222  * Open a corebuffer to read.  EOF occurs after reading len
223  * characters from buf.
224  */
225
226 io*
227 opencore(char *s, int len)
228 {
229         io *f = new(struct io);
230         uchar *buf = emalloc(len);
231
232         f->fd = -1 /*open("/dev/null", 0)*/;
233         f->bufp = f->strp = buf;
234         f->ebuf = buf+len;
235         Memcpy(buf, s, len);
236         return f;
237 }
238
239 void
240 rewind(io *io)
241 {
242         if(io->fd==-1)
243                 io->bufp = io->strp;
244         else{
245                 io->bufp = io->ebuf = io->buf;
246                 Seek(io->fd, 0L, 0);
247         }
248 }
249
250 void
251 closeio(io *io)
252 {
253         if(io->fd>=0)
254                 close(io->fd);
255         if(io->strp)
256                 efree(io->strp);
257         efree(io);
258 }
259
260 int
261 emptybuf(io *f)
262 {
263         int n;
264         if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
265         f->bufp = f->buf;
266         f->ebuf = f->buf + n;
267         return *f->bufp++;
268 }