io.c 3.7 KB

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