io.c 3.7 KB

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