io.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "rc.h"
  10. #include "exec.h"
  11. #include "io.h"
  12. #include "fns.h"
  13. enum { Stralloc = 100, };
  14. int pfmtnest = 0;
  15. void
  16. pfmt(io *f, char *fmt, ...)
  17. {
  18. va_list ap;
  19. char err[ERRMAX];
  20. va_start(ap, fmt);
  21. pfmtnest++;
  22. for(;*fmt;fmt++) {
  23. if(*fmt!='%') {
  24. pchr(f, *fmt);
  25. continue;
  26. }
  27. if(*++fmt == '\0') /* "blah%"? */
  28. break;
  29. switch(*fmt){
  30. case 'c':
  31. pchr(f, va_arg(ap, int));
  32. break;
  33. case 'd':
  34. pdec(f, va_arg(ap, int));
  35. break;
  36. case 'o':
  37. poct(f, va_arg(ap, unsigned));
  38. break;
  39. case 'p':
  40. pptr(f, va_arg(ap, void*));
  41. break;
  42. case 'Q':
  43. pquo(f, va_arg(ap, char *));
  44. break;
  45. case 'q':
  46. pwrd(f, va_arg(ap, char *));
  47. break;
  48. case 'r':
  49. errstr(err, sizeof err); pstr(f, err);
  50. break;
  51. case 's':
  52. pstr(f, va_arg(ap, char *));
  53. break;
  54. case 't':
  55. pcmd(f, va_arg(ap, struct tree *));
  56. break;
  57. case 'v':
  58. pval(f, va_arg(ap, struct word *));
  59. break;
  60. default:
  61. pchr(f, *fmt);
  62. break;
  63. }
  64. }
  65. va_end(ap);
  66. if(--pfmtnest==0)
  67. flush(f);
  68. }
  69. void
  70. pchr(io *b, int c)
  71. {
  72. if(b->bufp==b->ebuf)
  73. fullbuf(b, c);
  74. else *b->bufp++=c;
  75. }
  76. int
  77. rchr(io *b)
  78. {
  79. if(b->bufp==b->ebuf)
  80. return emptybuf(b);
  81. return *b->bufp++;
  82. }
  83. int
  84. rutf(io *b, char *buf, Rune *r)
  85. {
  86. int n, i, c;
  87. c = rchr(b);
  88. if(c == EOF)
  89. return EOF;
  90. *buf = c;
  91. if(c < Runesync){
  92. *r = c;
  93. return 1;
  94. }
  95. for(i = 1; (c = rchr(b)) != EOF; ){
  96. buf[i++] = c;
  97. buf[i] = 0;
  98. if(fullrune(buf, i)){
  99. n = chartorune(r, buf);
  100. b->bufp -= i - n; /* push back unconsumed bytes */
  101. assert(b->fd == -1 || b->bufp > b->buf);
  102. return n;
  103. }
  104. }
  105. /* at eof */
  106. b->bufp -= i - 1; /* consume 1 byte */
  107. *r = Runeerror;
  108. return runetochar(buf, r);
  109. }
  110. void
  111. pquo(io *f, char *s)
  112. {
  113. pchr(f, '\'');
  114. for(;*s;s++)
  115. if(*s=='\'')
  116. pfmt(f, "''");
  117. else pchr(f, *s);
  118. pchr(f, '\'');
  119. }
  120. void
  121. pwrd(io *f, char *s)
  122. {
  123. char *t;
  124. for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break;
  125. if(t==s || *t)
  126. pquo(f, s);
  127. else pstr(f, s);
  128. }
  129. void
  130. pptr(io *f, void *v)
  131. {
  132. int n;
  133. uintptr p;
  134. p = (uintptr)v;
  135. if(sizeof(uintptr) == sizeof(uint64_t) && p>>32)
  136. for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
  137. for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
  138. }
  139. void
  140. pstr(io *f, char *s)
  141. {
  142. if(s==0)
  143. s="(null)";
  144. while(*s) pchr(f, *s++);
  145. }
  146. void
  147. pdec(io *f, int n)
  148. {
  149. if(n<0){
  150. n=-n;
  151. if(n>=0){
  152. pchr(f, '-');
  153. pdec(f, n);
  154. return;
  155. }
  156. /* n is two's complement minimum integer */
  157. n = 1-n;
  158. pchr(f, '-');
  159. pdec(f, n/10);
  160. pchr(f, n%10+'1');
  161. return;
  162. }
  163. if(n>9)
  164. pdec(f, n/10);
  165. pchr(f, n%10+'0');
  166. }
  167. void
  168. poct(io *f, unsigned n)
  169. {
  170. if(n>7)
  171. poct(f, n>>3);
  172. pchr(f, (n&7)+'0');
  173. }
  174. void
  175. pval(io *f, word *a)
  176. {
  177. if(a){
  178. while(a->next && a->next->word){
  179. pwrd(f, (char *)a->word);
  180. pchr(f, ' ');
  181. a = a->next;
  182. }
  183. pwrd(f, (char *)a->word);
  184. }
  185. }
  186. int
  187. fullbuf(io *f, int c)
  188. {
  189. flush(f);
  190. return *f->bufp++=c;
  191. }
  192. void
  193. flush(io *f)
  194. {
  195. int n;
  196. if(f->strp){
  197. n = f->ebuf - f->strp;
  198. f->strp = realloc(f->strp, n+Stralloc+1);
  199. if(f->strp==0)
  200. panic("Can't realloc %d bytes in flush!", n+Stralloc+1);
  201. f->bufp = f->strp + n;
  202. f->ebuf = f->bufp + Stralloc;
  203. memset(f->bufp, '\0', Stralloc+1);
  204. }
  205. else{
  206. n = f->bufp-f->buf;
  207. if(n && Write(f->fd, f->buf, n) != n){
  208. Write(2, "Write error\n", 12);
  209. if(ntrap)
  210. dotrap();
  211. }
  212. f->bufp = f->buf;
  213. f->ebuf = f->buf+NBUF;
  214. }
  215. }
  216. io*
  217. openfd(int fd)
  218. {
  219. io *f = new(struct io);
  220. f->fd = fd;
  221. f->bufp = f->ebuf = f->buf;
  222. f->strp = 0;
  223. return f;
  224. }
  225. io*
  226. openstr(void)
  227. {
  228. io *f = new(struct io);
  229. f->fd = -1;
  230. f->bufp = f->strp = emalloc(Stralloc+1);
  231. f->ebuf = f->bufp + Stralloc;
  232. memset(f->bufp, '\0', Stralloc+1);
  233. return f;
  234. }
  235. /*
  236. * Open a corebuffer to read. EOF occurs after reading len
  237. * characters from buf.
  238. */
  239. io*
  240. opencore(char *s, int len)
  241. {
  242. io *f = new(struct io);
  243. uint8_t *buf = emalloc(len);
  244. f->fd = -1 /*open("/dev/null", 0)*/;
  245. f->bufp = f->strp = buf;
  246. f->ebuf = buf+len;
  247. Memcpy(buf, s, len);
  248. return f;
  249. }
  250. void
  251. rewind(io *io)
  252. {
  253. if(io->fd==-1)
  254. io->bufp = io->strp;
  255. else{
  256. io->bufp = io->ebuf = io->buf;
  257. Seek(io->fd, 0L, 0);
  258. }
  259. }
  260. void
  261. closeio(io *io)
  262. {
  263. if(io->fd>=0)
  264. close(io->fd);
  265. if(io->strp)
  266. efree(io->strp);
  267. efree(io);
  268. }
  269. int
  270. emptybuf(io *f)
  271. {
  272. int n;
  273. if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
  274. f->bufp = f->buf;
  275. f->ebuf = f->buf + n;
  276. return *f->bufp++;
  277. }