io.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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. int
  76. rutf(io *b, char *buf, Rune *r)
  77. {
  78. int n, i, c;
  79. c = rchr(b);
  80. if(c == EOF)
  81. return EOF;
  82. *buf = c;
  83. if(c < Runesync){
  84. *r = c;
  85. return 1;
  86. }
  87. for(i = 1; (c = rchr(b)) != EOF; ){
  88. buf[i++] = c;
  89. buf[i] = 0;
  90. if(fullrune(buf, i)){
  91. n = chartorune(r, buf);
  92. b->bufp -= i - n; /* push back unconsumed bytes */
  93. assert(b->fd == -1 || b->bufp > b->buf);
  94. return n;
  95. }
  96. }
  97. /* at eof */
  98. b->bufp -= i - 1; /* consume 1 byte */
  99. *r = Runeerror;
  100. return runetochar(buf, r);
  101. }
  102. void
  103. pquo(io *f, char *s)
  104. {
  105. pchr(f, '\'');
  106. for(;*s;s++)
  107. if(*s=='\'')
  108. pfmt(f, "''");
  109. else pchr(f, *s);
  110. pchr(f, '\'');
  111. }
  112. void
  113. pwrd(io *f, char *s)
  114. {
  115. char *t;
  116. for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break;
  117. if(t==s || *t)
  118. pquo(f, s);
  119. else pstr(f, s);
  120. }
  121. void
  122. pptr(io *f, void *v)
  123. {
  124. int n;
  125. uintptr p;
  126. p = (uintptr)v;
  127. if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
  128. for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
  129. for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
  130. }
  131. void
  132. pstr(io *f, char *s)
  133. {
  134. if(s==0)
  135. s="(null)";
  136. while(*s) pchr(f, *s++);
  137. }
  138. void
  139. pdec(io *f, int n)
  140. {
  141. if(n<0){
  142. n=-n;
  143. if(n>=0){
  144. pchr(f, '-');
  145. pdec(f, n);
  146. return;
  147. }
  148. /* n is two's complement minimum integer */
  149. n = 1-n;
  150. pchr(f, '-');
  151. pdec(f, n/10);
  152. pchr(f, n%10+'1');
  153. return;
  154. }
  155. if(n>9)
  156. pdec(f, n/10);
  157. pchr(f, n%10+'0');
  158. }
  159. void
  160. poct(io *f, unsigned n)
  161. {
  162. if(n>7)
  163. poct(f, n>>3);
  164. pchr(f, (n&7)+'0');
  165. }
  166. void
  167. pval(io *f, word *a)
  168. {
  169. if(a){
  170. while(a->next && a->next->word){
  171. pwrd(f, (char *)a->word);
  172. pchr(f, ' ');
  173. a = a->next;
  174. }
  175. pwrd(f, (char *)a->word);
  176. }
  177. }
  178. int
  179. fullbuf(io *f, int c)
  180. {
  181. flush(f);
  182. return *f->bufp++=c;
  183. }
  184. void
  185. flush(io *f)
  186. {
  187. int n;
  188. if(f->strp){
  189. n = f->ebuf - f->strp;
  190. f->strp = realloc(f->strp, n+Stralloc+1);
  191. if(f->strp==0)
  192. panic("Can't realloc %d bytes in flush!", n+Stralloc+1);
  193. f->bufp = f->strp + n;
  194. f->ebuf = f->bufp + Stralloc;
  195. memset(f->bufp, '\0', Stralloc+1);
  196. }
  197. else{
  198. n = f->bufp-f->buf;
  199. if(n && Write(f->fd, f->buf, n) != n){
  200. Write(2, "Write error\n", 12);
  201. if(ntrap)
  202. dotrap();
  203. }
  204. f->bufp = f->buf;
  205. f->ebuf = f->buf+NBUF;
  206. }
  207. }
  208. io*
  209. openfd(int fd)
  210. {
  211. io *f = new(struct io);
  212. f->fd = fd;
  213. f->bufp = f->ebuf = f->buf;
  214. f->strp = 0;
  215. return f;
  216. }
  217. io*
  218. openstr(void)
  219. {
  220. io *f = new(struct io);
  221. f->fd = -1;
  222. f->bufp = f->strp = emalloc(Stralloc+1);
  223. f->ebuf = f->bufp + Stralloc;
  224. memset(f->bufp, '\0', Stralloc+1);
  225. return f;
  226. }
  227. /*
  228. * Open a corebuffer to read. EOF occurs after reading len
  229. * characters from buf.
  230. */
  231. io*
  232. opencore(char *s, int len)
  233. {
  234. io *f = new(struct io);
  235. uchar *buf = emalloc(len);
  236. f->fd = -1 /*open("/dev/null", 0)*/;
  237. f->bufp = f->strp = buf;
  238. f->ebuf = buf+len;
  239. Memcpy(buf, s, len);
  240. return f;
  241. }
  242. void
  243. rewind(io *io)
  244. {
  245. if(io->fd==-1)
  246. io->bufp = io->strp;
  247. else{
  248. io->bufp = io->ebuf = io->buf;
  249. Seek(io->fd, 0L, 0);
  250. }
  251. }
  252. void
  253. closeio(io *io)
  254. {
  255. if(io->fd>=0)
  256. close(io->fd);
  257. if(io->strp)
  258. efree(io->strp);
  259. efree(io);
  260. }
  261. int
  262. emptybuf(io *f)
  263. {
  264. int n;
  265. if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
  266. f->bufp = f->buf;
  267. f->ebuf = f->buf + n;
  268. return *f->bufp++;
  269. }