io.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include "rc.h"
  2. #include "exec.h"
  3. #include "io.h"
  4. #include "fns.h"
  5. enum { Stralloc = 100, };
  6. int pfmtnest = 0;
  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. errstr(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. void
  60. pchr(io *b, int c)
  61. {
  62. if(b->bufp==b->ebuf)
  63. fullbuf(b, c);
  64. else *b->bufp++=c;
  65. }
  66. int
  67. rchr(io *b)
  68. {
  69. if(b->bufp==b->ebuf)
  70. return emptybuf(b);
  71. return *b->bufp++;
  72. }
  73. void
  74. pquo(io *f, char *s)
  75. {
  76. pchr(f, '\'');
  77. for(;*s;s++)
  78. if(*s=='\'')
  79. pfmt(f, "''");
  80. else pchr(f, *s);
  81. pchr(f, '\'');
  82. }
  83. void
  84. pwrd(io *f, char *s)
  85. {
  86. char *t;
  87. for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break;
  88. if(t==s || *t)
  89. pquo(f, s);
  90. else pstr(f, s);
  91. }
  92. void
  93. pptr(io *f, void *v)
  94. {
  95. int n;
  96. uintptr p;
  97. p = (uintptr)v;
  98. if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
  99. for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
  100. for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
  101. }
  102. void
  103. pstr(io *f, char *s)
  104. {
  105. if(s==0)
  106. s="(null)";
  107. while(*s) pchr(f, *s++);
  108. }
  109. void
  110. pdec(io *f, int n)
  111. {
  112. if(n<0){
  113. n=-n;
  114. if(n>=0){
  115. pchr(f, '-');
  116. pdec(f, n);
  117. return;
  118. }
  119. /* n is two's complement minimum integer */
  120. n = 1-n;
  121. pchr(f, '-');
  122. pdec(f, n/10);
  123. pchr(f, n%10+'1');
  124. return;
  125. }
  126. if(n>9)
  127. pdec(f, n/10);
  128. pchr(f, n%10+'0');
  129. }
  130. void
  131. poct(io *f, unsigned n)
  132. {
  133. if(n>7)
  134. poct(f, n>>3);
  135. pchr(f, (n&7)+'0');
  136. }
  137. void
  138. pval(io *f, word *a)
  139. {
  140. if(a){
  141. while(a->next && a->next->word){
  142. pwrd(f, (char *)a->word);
  143. pchr(f, ' ');
  144. a = a->next;
  145. }
  146. pwrd(f, (char *)a->word);
  147. }
  148. }
  149. int
  150. fullbuf(io *f, int c)
  151. {
  152. flush(f);
  153. return *f->bufp++=c;
  154. }
  155. void
  156. flush(io *f)
  157. {
  158. int n;
  159. if(f->strp){
  160. n = f->ebuf - f->strp;
  161. f->strp = realloc(f->strp, n+Stralloc+1);
  162. if(f->strp==0)
  163. panic("Can't realloc %d bytes in flush!", n+Stralloc+1);
  164. f->bufp = f->strp + n;
  165. f->ebuf = f->bufp + Stralloc;
  166. memset(f->bufp, '\0', Stralloc+1);
  167. }
  168. else{
  169. n = f->bufp-f->buf;
  170. if(n && Write(f->fd, f->buf, n) != n){
  171. Write(2, "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. f->fd = -1;
  193. f->bufp = f->strp = emalloc(Stralloc+1);
  194. f->ebuf = f->bufp + Stralloc;
  195. memset(f->bufp, '\0', Stralloc+1);
  196. return f;
  197. }
  198. /*
  199. * Open a corebuffer to read. EOF occurs after reading len
  200. * characters from buf.
  201. */
  202. io*
  203. opencore(char *s, int len)
  204. {
  205. io *f = new(struct io);
  206. uchar *buf = emalloc(len);
  207. f->fd = -1 /*open("/dev/null", 0)*/;
  208. f->bufp = f->strp = buf;
  209. f->ebuf = buf+len;
  210. Memcpy(buf, s, len);
  211. return f;
  212. }
  213. void
  214. rewind(io *io)
  215. {
  216. if(io->fd==-1)
  217. io->bufp = io->strp;
  218. else{
  219. io->bufp = io->ebuf = io->buf;
  220. Seek(io->fd, 0L, 0);
  221. }
  222. }
  223. void
  224. closeio(io *io)
  225. {
  226. if(io->fd>=0)
  227. close(io->fd);
  228. if(io->strp)
  229. efree(io->strp);
  230. efree(io);
  231. }
  232. int
  233. emptybuf(io *f)
  234. {
  235. int n;
  236. if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
  237. f->bufp = f->buf;
  238. f->ebuf = f->buf + n;
  239. return *f->bufp++;
  240. }