io.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "rc.h"
  2. #include "exec.h"
  3. #include "io.h"
  4. #include "fns.h"
  5. int pfmtnest=0;
  6. void pfmt(io *f, char *fmt, ...){
  7. va_list ap;
  8. char err[ERRMAX];
  9. va_start(ap, fmt);
  10. pfmtnest++;
  11. for(;*fmt;fmt++)
  12. if(*fmt!='%') pchr(f, *fmt);
  13. else switch(*++fmt){
  14. case '\0': va_end(ap); return;
  15. case 'c': pchr(f, va_arg(ap, int)); break;
  16. case 'd': pdec(f, va_arg(ap, int)); break;
  17. case 'o': poct(f, va_arg(ap, unsigned)); break;
  18. case 'p': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/
  19. case 'Q': pquo(f, va_arg(ap, char *)); break;
  20. case 'q': pwrd(f, va_arg(ap, char *)); break;
  21. case 'r': errstr(err, sizeof err); pstr(f, err); break;
  22. case 's': pstr(f, va_arg(ap, char *)); break;
  23. case 't': pcmd(f, va_arg(ap, struct tree *)); break;
  24. case 'v': pval(f, va_arg(ap, struct word *)); break;
  25. default: pchr(f, *fmt); break;
  26. }
  27. va_end(ap);
  28. if(--pfmtnest==0) flush(f);
  29. }
  30. void pchr(io *b, int c)
  31. {
  32. if(b->bufp==b->ebuf) fullbuf(b, c);
  33. else *b->bufp++=c;
  34. }
  35. int rchr(io *b)
  36. {
  37. if(b->bufp==b->ebuf) return emptybuf(b);
  38. return *b->bufp++ & 0xFF;
  39. }
  40. void pquo(io *f, char *s)
  41. {
  42. pchr(f, '\'');
  43. for(;*s;s++)
  44. if(*s=='\'') pfmt(f, "''");
  45. else pchr(f, *s);
  46. pchr(f, '\'');
  47. }
  48. void pwrd(io *f, char *s)
  49. {
  50. char *t;
  51. for(t=s;*t;t++) if(!wordchr(*t)) break;
  52. if(t==s || *t) pquo(f, s);
  53. else pstr(f, s);
  54. }
  55. void phex(io *f, long p)
  56. {
  57. int n;
  58. for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
  59. }
  60. void pstr(io *f, char *s)
  61. {
  62. if(s==0) s="(null)";
  63. while(*s) pchr(f, *s++);
  64. }
  65. void pdec(io *f, long n)
  66. {
  67. if(n<0){
  68. n=-n;
  69. if(n>=0){
  70. pchr(f, '-');
  71. pdec(f, n);
  72. return;
  73. }
  74. /* n is two's complement minimum integer */
  75. n=1-n;
  76. pchr(f, '-');
  77. pdec(f, n/10);
  78. pchr(f, n%10+'1');
  79. return;
  80. }
  81. if(n>9) pdec(f, n/10);
  82. pchr(f, n%10+'0');
  83. }
  84. void poct(io *f, ulong n)
  85. {
  86. if(n>7) poct(f, n>>3);
  87. pchr(f, (n&7)+'0');
  88. }
  89. void pval(io *f, word *a)
  90. {
  91. if(a){
  92. while(a->next && a->next->word){
  93. pwrd(f, a->word);
  94. pchr(f, ' ');
  95. a=a->next;
  96. }
  97. pwrd(f, a->word);
  98. }
  99. }
  100. int fullbuf(io *f, int c)
  101. {
  102. flush(f);
  103. return *f->bufp++=c;
  104. }
  105. void flush(io *f)
  106. {
  107. int n;
  108. char *s;
  109. if(f->strp){
  110. n=f->ebuf-f->strp;
  111. f->strp=realloc(f->strp, n+101);
  112. if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101);
  113. f->bufp=f->strp+n;
  114. f->ebuf=f->bufp+100;
  115. for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
  116. }
  117. else{
  118. n=f->bufp-f->buf;
  119. if(n && Write(f->fd, f->buf, n) < 0){
  120. Write(3, "Write error\n", 12);
  121. if(ntrap) dotrap();
  122. }
  123. f->bufp=f->buf;
  124. f->ebuf=f->buf+NBUF;
  125. }
  126. }
  127. io *openfd(int fd){
  128. io *f=new(struct io);
  129. f->fd=fd;
  130. f->bufp=f->ebuf=f->buf;
  131. f->strp=0;
  132. return f;
  133. }
  134. io *openstr(void){
  135. io *f=new(struct io);
  136. char *s;
  137. f->fd=-1;
  138. f->bufp=f->strp=emalloc(101);
  139. f->ebuf=f->bufp+100;
  140. for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
  141. return f;
  142. }
  143. /*
  144. * Open a corebuffer to read. EOF occurs after reading len
  145. * characters from buf.
  146. */
  147. io *opencore(char *s, int len)
  148. {
  149. io *f=new(struct io);
  150. char *buf=emalloc(len);
  151. f->fd= -1 /*open("/dev/null", 0)*/;
  152. f->bufp=f->strp=buf;
  153. f->ebuf=buf+len;
  154. Memcpy(buf, s, len);
  155. return f;
  156. }
  157. void rewind(io *io)
  158. {
  159. if(io->fd==-1) io->bufp=io->strp;
  160. else{
  161. io->bufp=io->ebuf=io->buf;
  162. Seek(io->fd, 0L, 0);
  163. }
  164. }
  165. void closeio(io *io)
  166. {
  167. if(io->fd>=0) close(io->fd);
  168. if(io->strp) efree(io->strp);
  169. efree((char *)io);
  170. }
  171. int emptybuf(io *f)
  172. {
  173. int n;
  174. if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF;
  175. f->bufp=f->buf;
  176. f->ebuf=f->buf+n;
  177. return *f->bufp++&0xff;
  178. }