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