io.c 3.5 KB

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