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