URI:
       tio.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tio.c (3932B)
       ---
            1 #include <limits.h>
            2 #include <errno.h>
            3 #include "rc.h"
            4 #include "exec.h"
            5 #include "io.h"
            6 #include "fns.h"
            7 int pfmtnest = 0;
            8 
            9 void
           10 pfmt(io *f, char *fmt, ...)
           11 {
           12         va_list ap;
           13         char err[ERRMAX];
           14         va_start(ap, fmt);
           15         pfmtnest++;
           16         for(;*fmt;fmt++)
           17                 if(*fmt!='%')
           18                         pchr(f, *fmt);
           19                 else switch(*++fmt){
           20                 case '\0':
           21                         va_end(ap);
           22                         return;
           23                 case 'c':
           24                         pchr(f, va_arg(ap, int));
           25                         break;
           26                 case 'd':
           27                         pdec(f, va_arg(ap, int));
           28                         break;
           29                 case 'o':
           30                         poct(f, va_arg(ap, unsigned));
           31                         break;
           32                 case 'p':
           33                         pptr(f, va_arg(ap, void*));
           34                         break;
           35                 case 'Q':
           36                         pquo(f, va_arg(ap, char *));
           37                         break;
           38                 case 'q':
           39                         pwrd(f, va_arg(ap, char *));
           40                         break;
           41                 case 'r':
           42                         rerrstr(err, sizeof err); pstr(f, err);
           43                         break;
           44                 case 's':
           45                         pstr(f, va_arg(ap, char *));
           46                         break;
           47                 case 't':
           48                         pcmd(f, va_arg(ap, tree *));
           49                         break;
           50                 case 'u':
           51                         pcmdu(f, va_arg(ap, 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         va_end(ap);
           61         if(--pfmtnest==0)
           62                 flush(f);
           63 }
           64 
           65 void
           66 pchr(io *b, int c)
           67 {
           68         if(b->bufp==b->ebuf)
           69                 fullbuf(b, c);
           70         else *b->bufp++=c;
           71 }
           72 
           73 int
           74 rchr(io *b)
           75 {
           76         if(b->bufp==b->ebuf)
           77                 return emptybuf(b);
           78         return *b->bufp++ & 0xFF;
           79 }
           80 
           81 void
           82 pquo(io *f, char *s)
           83 {
           84         pchr(f, '\'');
           85         for(;*s;s++)
           86                 if(*s=='\'')
           87                         pfmt(f, "''");
           88                 else pchr(f, *s);
           89         pchr(f, '\'');
           90 }
           91 
           92 void
           93 pwrd(io *f, char *s)
           94 {
           95         char *t;
           96         for(t = s;*t;t++) if(!wordchr(*t)) break;
           97         if(t==s || *t)
           98                 pquo(f, s);
           99         else pstr(f, s);
          100 }
          101 
          102 void
          103 pptr(io *f, void *v)
          104 {
          105         int n;
          106         uintptr p;
          107 
          108         p = (uintptr)v;
          109         if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
          110                 for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
          111 
          112         for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
          113 }
          114 
          115 void
          116 pstr(io *f, char *s)
          117 {
          118         if(s==0)
          119                 s="(null)";
          120         while(*s) pchr(f, *s++);
          121 }
          122 
          123 void
          124 pdec(io *f, int n)
          125 {
          126         if(n<0){
          127                 if(n!=INT_MIN){
          128                         pchr(f, '-');
          129                         pdec(f, -n);
          130                         return;
          131                 }
          132                 /* n is two's complement minimum integer */
          133                 n = -(INT_MIN+1);
          134                 pchr(f, '-');
          135                 pdec(f, n/10);
          136                 pchr(f, n%10+'1');
          137                 return;
          138         }
          139         if(n>9)
          140                 pdec(f, n/10);
          141         pchr(f, n%10+'0');
          142 }
          143 
          144 void
          145 poct(io *f, unsigned n)
          146 {
          147         if(n>7)
          148                 poct(f, n>>3);
          149         pchr(f, (n&7)+'0');
          150 }
          151 
          152 void
          153 pval(io *f, word *a)
          154 {
          155         if(a){
          156                 while(a->next && a->next->word){
          157                         pwrd(f, a->word);
          158                         pchr(f, ' ');
          159                         a = a->next;
          160                 }
          161                 pwrd(f, a->word);
          162         }
          163 }
          164 
          165 int
          166 fullbuf(io *f, int c)
          167 {
          168         flush(f);
          169         return *f->bufp++=c;
          170 }
          171 
          172 void
          173 flush(io *f)
          174 {
          175         int n;
          176         char *s;
          177         if(f->strp){
          178                 n = f->ebuf-f->strp;
          179                 f->strp = realloc(f->strp, n+101);
          180                 if(f->strp==0)
          181                         panic("Can't realloc %d bytes in flush!", n+101);
          182                 f->bufp = f->strp+n;
          183                 f->ebuf = f->bufp+100;
          184                 for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
          185         }
          186         else{
          187                 n = f->bufp-f->buf;
          188                 if(n && Write(f->fd, f->buf, n) < 0){
          189                         Write(3, "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         char *s;
          213         f->fd=-1;
          214         f->bufp = f->strp = emalloc(101);
          215         f->ebuf = f->bufp+100;
          216         for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
          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         char *buf = emalloc(len);
          229         f->fd= -1 /*open("/dev/null", 0)*/;
          230         f->bufp = f->strp = buf;
          231         f->ebuf = buf+len;
          232         Memcpy(buf, s, len);
          233         return f;
          234 }
          235 
          236 void
          237 iorewind(io *io)
          238 {
          239         if(io->fd==-1)
          240                 io->bufp = io->strp;
          241         else{
          242                 io->bufp = io->ebuf = io->buf;
          243                 Seek(io->fd, 0L, 0);
          244         }
          245 }
          246 
          247 void
          248 closeio(io *io)
          249 {
          250         if(io->fd>=0)
          251                 close(io->fd);
          252         if(io->strp)
          253                 efree(io->strp);
          254         efree((char *)io);
          255 }
          256 
          257 int
          258 emptybuf(io *f)
          259 {
          260         int n;
          261         if(f->fd==-1)
          262                 return EOF;
          263 Loop:
          264         errno = 0;
          265         n = Read(f->fd, f->buf, NBUF);
          266         if(n < 0 && errno == EINTR)
          267                 goto Loop;
          268         if(n <= 0)
          269                 return EOF;
          270         f->bufp = f->buf;
          271         f->ebuf = f->buf+n;
          272         return *f->bufp++&0xff;
          273 }