2 c42a1d3d 2006-02-21 devnull * Read input files.
4 c42a1d3d 2006-02-21 devnull #include "a.h"
6 c42a1d3d 2006-02-21 devnull typedef struct Istack Istack;
7 c42a1d3d 2006-02-21 devnull struct Istack
9 c42a1d3d 2006-02-21 devnull Rune unget[3];
10 c42a1d3d 2006-02-21 devnull int nunget;
11 c42a1d3d 2006-02-21 devnull Biobuf *b;
13 c42a1d3d 2006-02-21 devnull Rune *ep;
15 c42a1d3d 2006-02-21 devnull int lineno;
16 c42a1d3d 2006-02-21 devnull Rune *name;
17 c42a1d3d 2006-02-21 devnull Istack *next;
18 c42a1d3d 2006-02-21 devnull void (*fn)(void);
21 c42a1d3d 2006-02-21 devnull Istack *istack;
22 c42a1d3d 2006-02-21 devnull Istack *ibottom;
24 c42a1d3d 2006-02-21 devnull static void
25 c42a1d3d 2006-02-21 devnull setname(void)
27 c42a1d3d 2006-02-21 devnull Rune *r, *p;
29 c42a1d3d 2006-02-21 devnull if(istack == nil || istack->name == nil)
31 c42a1d3d 2006-02-21 devnull _nr(L(".F"), istack->name);
32 c42a1d3d 2006-02-21 devnull r = erunestrdup(istack->name);
33 c42a1d3d 2006-02-21 devnull p = runestrchr(r, '.');
36 c42a1d3d 2006-02-21 devnull _nr(L(".B"), r);
40 c42a1d3d 2006-02-21 devnull static void
41 c42a1d3d 2006-02-21 devnull ipush(Istack *is)
43 c42a1d3d 2006-02-21 devnull if(istack == nil)
44 c42a1d3d 2006-02-21 devnull ibottom = is;
46 c42a1d3d 2006-02-21 devnull is->next = istack;
47 c42a1d3d 2006-02-21 devnull istack = is;
48 c42a1d3d 2006-02-21 devnull setname();
51 c42a1d3d 2006-02-21 devnull static void
52 c42a1d3d 2006-02-21 devnull iqueue(Istack *is)
54 c42a1d3d 2006-02-21 devnull if(ibottom == nil){
55 c42a1d3d 2006-02-21 devnull istack = is;
56 c42a1d3d 2006-02-21 devnull setname();
58 c42a1d3d 2006-02-21 devnull ibottom->next = is;
59 c42a1d3d 2006-02-21 devnull ibottom = is;
63 c42a1d3d 2006-02-21 devnull _inputfile(Rune *s, void (*push)(Istack*))
65 c42a1d3d 2006-02-21 devnull Istack *is;
66 c42a1d3d 2006-02-21 devnull Biobuf *b;
69 c42a1d3d 2006-02-21 devnull t = esmprint("%S", s);
70 c42a1d3d 2006-02-21 devnull if((b = Bopen(t, OREAD)) == nil){
72 c42a1d3d 2006-02-21 devnull fprint(2, "%s: open %S: %r\n", argv0, s);
73 c42a1d3d 2006-02-21 devnull return -1;
76 c42a1d3d 2006-02-21 devnull is = emalloc(sizeof *is);
77 c42a1d3d 2006-02-21 devnull is->b = b;
78 c42a1d3d 2006-02-21 devnull is->name = erunestrdup(s);
79 c42a1d3d 2006-02-21 devnull is->lineno = 1;
80 c42a1d3d 2006-02-21 devnull push(is);
81 c42a1d3d 2006-02-21 devnull return 0;
85 c42a1d3d 2006-02-21 devnull pushinputfile(Rune *s)
87 c42a1d3d 2006-02-21 devnull return _inputfile(s, ipush);
91 c42a1d3d 2006-02-21 devnull queueinputfile(Rune *s)
93 c42a1d3d 2006-02-21 devnull return _inputfile(s, iqueue);
97 c42a1d3d 2006-02-21 devnull _inputstdin(void (*push)(Istack*))
99 c42a1d3d 2006-02-21 devnull Biobuf *b;
100 c42a1d3d 2006-02-21 devnull Istack *is;
102 c42a1d3d 2006-02-21 devnull if((b = Bopen("/dev/null", OREAD)) == nil){
103 c42a1d3d 2006-02-21 devnull fprint(2, "%s: open /dev/null: %r\n", argv0);
104 c42a1d3d 2006-02-21 devnull return -1;
106 c42a1d3d 2006-02-21 devnull dup(0, b->fid);
107 c42a1d3d 2006-02-21 devnull is = emalloc(sizeof *is);
108 c42a1d3d 2006-02-21 devnull is->b = b;
109 c42a1d3d 2006-02-21 devnull is->name = erunestrdup(L("stdin"));
110 c42a1d3d 2006-02-21 devnull is->lineno = 1;
111 c42a1d3d 2006-02-21 devnull push(is);
112 c42a1d3d 2006-02-21 devnull return 0;
116 c42a1d3d 2006-02-21 devnull pushstdin(void)
118 c42a1d3d 2006-02-21 devnull return _inputstdin(ipush);
122 c42a1d3d 2006-02-21 devnull queuestdin(void)
124 c42a1d3d 2006-02-21 devnull return _inputstdin(iqueue);
128 c42a1d3d 2006-02-21 devnull _inputstring(Rune *s, void (*push)(Istack*))
130 c42a1d3d 2006-02-21 devnull Istack *is;
132 c42a1d3d 2006-02-21 devnull is = emalloc(sizeof *is);
133 c42a1d3d 2006-02-21 devnull is->s = erunestrdup(s);
134 c42a1d3d 2006-02-21 devnull is->p = is->s;
135 c42a1d3d 2006-02-21 devnull is->ep = is->p+runestrlen(is->p);
136 c42a1d3d 2006-02-21 devnull push(is);
140 c42a1d3d 2006-02-21 devnull pushinputstring(Rune *s)
142 c42a1d3d 2006-02-21 devnull _inputstring(s, ipush);
147 c42a1d3d 2006-02-21 devnull inputnotify(void (*fn)(void))
149 c42a1d3d 2006-02-21 devnull if(istack)
150 c42a1d3d 2006-02-21 devnull istack->fn = fn;
154 c42a1d3d 2006-02-21 devnull popinput(void)
156 c42a1d3d 2006-02-21 devnull Istack *is;
158 c42a1d3d 2006-02-21 devnull is = istack;
159 c42a1d3d 2006-02-21 devnull if(is == nil)
160 c42a1d3d 2006-02-21 devnull return 0;
162 c42a1d3d 2006-02-21 devnull istack = istack->next;
163 c42a1d3d 2006-02-21 devnull if(is->b)
164 c42a1d3d 2006-02-21 devnull Bterm(is->b);
165 c42a1d3d 2006-02-21 devnull free(is->s);
166 c42a1d3d 2006-02-21 devnull free(is->name);
167 c42a1d3d 2006-02-21 devnull if(is->fn)
168 c42a1d3d 2006-02-21 devnull is->fn();
169 c42a1d3d 2006-02-21 devnull free(is);
170 c42a1d3d 2006-02-21 devnull setname();
171 c42a1d3d 2006-02-21 devnull return 1;
175 c42a1d3d 2006-02-21 devnull getrune(void)
181 c42a1d3d 2006-02-21 devnull if(istack == nil)
182 c42a1d3d 2006-02-21 devnull return -1;
183 c42a1d3d 2006-02-21 devnull if(istack->nunget)
184 c42a1d3d 2006-02-21 devnull return istack->unget[--istack->nunget];
185 c42a1d3d 2006-02-21 devnull else if(istack->p){
186 c42a1d3d 2006-02-21 devnull if(istack->p >= istack->ep){
187 c42a1d3d 2006-02-21 devnull popinput();
188 c42a1d3d 2006-02-21 devnull goto top;
190 c42a1d3d 2006-02-21 devnull r = *istack->p++;
191 c42a1d3d 2006-02-21 devnull }else if(istack->b){
192 c42a1d3d 2006-02-21 devnull if((c = Bgetrune(istack->b)) < 0){
193 c42a1d3d 2006-02-21 devnull popinput();
194 c42a1d3d 2006-02-21 devnull goto top;
199 c42a1d3d 2006-02-21 devnull sysfatal("getrune - can't happen");
201 c42a1d3d 2006-02-21 devnull if(r == '\n')
202 c42a1d3d 2006-02-21 devnull istack->lineno++;
203 c42a1d3d 2006-02-21 devnull return r;
207 c42a1d3d 2006-02-21 devnull ungetrune(Rune r)
209 c42a1d3d 2006-02-21 devnull if(istack == nil || istack->nunget >= nelem(istack->unget))
210 c42a1d3d 2006-02-21 devnull pushinputstring(L(""));
211 c42a1d3d 2006-02-21 devnull istack->unget[istack->nunget++] = r;
215 c42a1d3d 2006-02-21 devnull linefmt(Fmt *f)
217 c42a1d3d 2006-02-21 devnull Istack *is;
219 c42a1d3d 2006-02-21 devnull for(is=istack; is && !is->b; is=is->next)
222 c42a1d3d 2006-02-21 devnull return fmtprint(f, "%S:%d", is->name, is->lineno);
224 c42a1d3d 2006-02-21 devnull return fmtprint(f, "<no input>");
228 c42a1d3d 2006-02-21 devnull setlinenumber(Rune *s, int n)
230 c42a1d3d 2006-02-21 devnull Istack *is;
232 c42a1d3d 2006-02-21 devnull for(is=istack; is && !is->name; is=is->next)
236 c42a1d3d 2006-02-21 devnull free(is->name);
237 c42a1d3d 2006-02-21 devnull is->name = erunestrdup(s);
239 c42a1d3d 2006-02-21 devnull is->lineno = n;