input.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * Read input files.
  3. */
  4. #include "a.h"
  5. typedef struct Istack Istack;
  6. struct Istack
  7. {
  8. Rune unget[3];
  9. int nunget;
  10. Biobuf *b;
  11. Rune *p;
  12. Rune *ep;
  13. Rune *s;
  14. int lineno;
  15. Rune *name;
  16. Istack *next;
  17. void (*fn)(void);
  18. };
  19. Istack *istack;
  20. Istack *ibottom;
  21. static void
  22. setname(void)
  23. {
  24. Rune *r, *p;
  25. if(istack == nil || istack->name == nil)
  26. return;
  27. _nr(L(".F"), istack->name);
  28. r = erunestrdup(istack->name);
  29. p = runestrchr(r, '.');
  30. if(p)
  31. *p = 0;
  32. _nr(L(".B"), r);
  33. free(r);
  34. }
  35. static void
  36. ipush(Istack *is)
  37. {
  38. if(istack == nil)
  39. ibottom = is;
  40. else
  41. is->next = istack;
  42. istack = is;
  43. setname();
  44. }
  45. static void
  46. iqueue(Istack *is)
  47. {
  48. if(ibottom == nil){
  49. istack = is;
  50. setname();
  51. }else
  52. ibottom->next = is;
  53. ibottom = is;
  54. }
  55. int
  56. _inputfile(Rune *s, void (*push)(Istack*))
  57. {
  58. Istack *is;
  59. Biobuf *b;
  60. char *t;
  61. t = esmprint("%S", s);
  62. if((b = Bopen(t, OREAD)) == nil){
  63. free(t);
  64. fprint(2, "%s: open %S: %r\n", argv0, s);
  65. return -1;
  66. }
  67. free(t);
  68. is = emalloc(sizeof *is);
  69. is->b = b;
  70. is->name = erunestrdup(s);
  71. is->lineno = 1;
  72. push(is);
  73. return 0;
  74. }
  75. int
  76. pushinputfile(Rune *s)
  77. {
  78. return _inputfile(s, ipush);
  79. }
  80. int
  81. queueinputfile(Rune *s)
  82. {
  83. return _inputfile(s, iqueue);
  84. }
  85. int
  86. _inputstdin(void (*push)(Istack*))
  87. {
  88. Biobuf *b;
  89. Istack *is;
  90. if((b = Bopen("/dev/null", OREAD)) == nil){
  91. fprint(2, "%s: open /dev/null: %r\n", argv0);
  92. return -1;
  93. }
  94. dup(0, b->fid);
  95. is = emalloc(sizeof *is);
  96. is->b = b;
  97. is->name = erunestrdup(L("stdin"));
  98. is->lineno = 1;
  99. push(is);
  100. return 0;
  101. }
  102. int
  103. pushstdin(void)
  104. {
  105. return _inputstdin(ipush);
  106. }
  107. int
  108. queuestdin(void)
  109. {
  110. return _inputstdin(iqueue);
  111. }
  112. void
  113. _inputstring(Rune *s, void (*push)(Istack*))
  114. {
  115. Istack *is;
  116. is = emalloc(sizeof *is);
  117. is->s = erunestrdup(s);
  118. is->p = is->s;
  119. is->ep = is->p+runestrlen(is->p);
  120. push(is);
  121. }
  122. void
  123. pushinputstring(Rune *s)
  124. {
  125. _inputstring(s, ipush);
  126. }
  127. void
  128. inputnotify(void (*fn)(void))
  129. {
  130. if(istack)
  131. istack->fn = fn;
  132. }
  133. int
  134. popinput(void)
  135. {
  136. Istack *is;
  137. is = istack;
  138. if(is == nil)
  139. return 0;
  140. istack = istack->next;
  141. if(is->b)
  142. Bterm(is->b);
  143. free(is->s);
  144. free(is->name);
  145. if(is->fn)
  146. is->fn();
  147. free(is);
  148. setname();
  149. return 1;
  150. }
  151. int
  152. getrune(void)
  153. {
  154. Rune r;
  155. int c;
  156. top:
  157. if(istack == nil)
  158. return -1;
  159. if(istack->nunget)
  160. return istack->unget[--istack->nunget];
  161. else if(istack->p){
  162. if(istack->p >= istack->ep){
  163. popinput();
  164. goto top;
  165. }
  166. r = *istack->p++;
  167. }else if(istack->b){
  168. if((c = Bgetrune(istack->b)) < 0){
  169. popinput();
  170. goto top;
  171. }
  172. r = c;
  173. }else{
  174. r = 0;
  175. sysfatal("getrune - can't happen");
  176. }
  177. if(r == '\n')
  178. istack->lineno++;
  179. return r;
  180. }
  181. void
  182. ungetrune(Rune r)
  183. {
  184. if(istack == nil || istack->nunget >= nelem(istack->unget))
  185. pushinputstring(L(""));
  186. istack->unget[istack->nunget++] = r;
  187. }
  188. int
  189. linefmt(Fmt *f)
  190. {
  191. Istack *is;
  192. for(is=istack; is && !is->b; is=is->next)
  193. ;
  194. if(is)
  195. return fmtprint(f, "%S:%d", is->name, is->lineno);
  196. else
  197. return fmtprint(f, "<no input>");
  198. }
  199. void
  200. setlinenumber(Rune *s, int n)
  201. {
  202. Istack *is;
  203. for(is=istack; is && !is->name; is=is->next)
  204. ;
  205. if(is){
  206. if(s){
  207. free(is->name);
  208. is->name = erunestrdup(s);
  209. }
  210. is->lineno = n;
  211. }
  212. }