io.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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)&0xF]);
          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 }