Blame


1 c42a1d3d 2006-02-21 devnull /*
2 c42a1d3d 2006-02-21 devnull * Read input files.
3 c42a1d3d 2006-02-21 devnull */
4 c42a1d3d 2006-02-21 devnull #include "a.h"
5 c42a1d3d 2006-02-21 devnull
6 c42a1d3d 2006-02-21 devnull typedef struct Istack Istack;
7 c42a1d3d 2006-02-21 devnull struct Istack
8 c42a1d3d 2006-02-21 devnull {
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;
12 c42a1d3d 2006-02-21 devnull Rune *p;
13 c42a1d3d 2006-02-21 devnull Rune *ep;
14 c42a1d3d 2006-02-21 devnull Rune *s;
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);
19 c42a1d3d 2006-02-21 devnull };
20 c42a1d3d 2006-02-21 devnull
21 c42a1d3d 2006-02-21 devnull Istack *istack;
22 c42a1d3d 2006-02-21 devnull Istack *ibottom;
23 c42a1d3d 2006-02-21 devnull
24 c42a1d3d 2006-02-21 devnull static void
25 c42a1d3d 2006-02-21 devnull setname(void)
26 c42a1d3d 2006-02-21 devnull {
27 c42a1d3d 2006-02-21 devnull Rune *r, *p;
28 c42a1d3d 2006-02-21 devnull
29 c42a1d3d 2006-02-21 devnull if(istack == nil || istack->name == nil)
30 c42a1d3d 2006-02-21 devnull return;
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, '.');
34 c42a1d3d 2006-02-21 devnull if(p)
35 c42a1d3d 2006-02-21 devnull *p = 0;
36 c42a1d3d 2006-02-21 devnull _nr(L(".B"), r);
37 c42a1d3d 2006-02-21 devnull free(r);
38 c42a1d3d 2006-02-21 devnull }
39 c42a1d3d 2006-02-21 devnull
40 c42a1d3d 2006-02-21 devnull static void
41 c42a1d3d 2006-02-21 devnull ipush(Istack *is)
42 c42a1d3d 2006-02-21 devnull {
43 c42a1d3d 2006-02-21 devnull if(istack == nil)
44 c42a1d3d 2006-02-21 devnull ibottom = is;
45 c42a1d3d 2006-02-21 devnull else
46 c42a1d3d 2006-02-21 devnull is->next = istack;
47 c42a1d3d 2006-02-21 devnull istack = is;
48 c42a1d3d 2006-02-21 devnull setname();
49 c42a1d3d 2006-02-21 devnull }
50 c42a1d3d 2006-02-21 devnull
51 c42a1d3d 2006-02-21 devnull static void
52 c42a1d3d 2006-02-21 devnull iqueue(Istack *is)
53 c42a1d3d 2006-02-21 devnull {
54 c42a1d3d 2006-02-21 devnull if(ibottom == nil){
55 c42a1d3d 2006-02-21 devnull istack = is;
56 c42a1d3d 2006-02-21 devnull setname();
57 c42a1d3d 2006-02-21 devnull }else
58 c42a1d3d 2006-02-21 devnull ibottom->next = is;
59 c42a1d3d 2006-02-21 devnull ibottom = is;
60 c42a1d3d 2006-02-21 devnull }
61 c42a1d3d 2006-02-21 devnull
62 c42a1d3d 2006-02-21 devnull int
63 c42a1d3d 2006-02-21 devnull _inputfile(Rune *s, void (*push)(Istack*))
64 c42a1d3d 2006-02-21 devnull {
65 c42a1d3d 2006-02-21 devnull Istack *is;
66 c42a1d3d 2006-02-21 devnull Biobuf *b;
67 c42a1d3d 2006-02-21 devnull char *t;
68 fa325e9b 2020-01-10 cross
69 c42a1d3d 2006-02-21 devnull t = esmprint("%S", s);
70 c42a1d3d 2006-02-21 devnull if((b = Bopen(t, OREAD)) == nil){
71 c42a1d3d 2006-02-21 devnull free(t);
72 c42a1d3d 2006-02-21 devnull fprint(2, "%s: open %S: %r\n", argv0, s);
73 c42a1d3d 2006-02-21 devnull return -1;
74 c42a1d3d 2006-02-21 devnull }
75 c42a1d3d 2006-02-21 devnull free(t);
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;
82 c42a1d3d 2006-02-21 devnull }
83 c42a1d3d 2006-02-21 devnull
84 c42a1d3d 2006-02-21 devnull int
85 c42a1d3d 2006-02-21 devnull pushinputfile(Rune *s)
86 c42a1d3d 2006-02-21 devnull {
87 c42a1d3d 2006-02-21 devnull return _inputfile(s, ipush);
88 c42a1d3d 2006-02-21 devnull }
89 c42a1d3d 2006-02-21 devnull
90 c42a1d3d 2006-02-21 devnull int
91 c42a1d3d 2006-02-21 devnull queueinputfile(Rune *s)
92 c42a1d3d 2006-02-21 devnull {
93 c42a1d3d 2006-02-21 devnull return _inputfile(s, iqueue);
94 c42a1d3d 2006-02-21 devnull }
95 c42a1d3d 2006-02-21 devnull
96 c42a1d3d 2006-02-21 devnull int
97 c42a1d3d 2006-02-21 devnull _inputstdin(void (*push)(Istack*))
98 fa325e9b 2020-01-10 cross {
99 c42a1d3d 2006-02-21 devnull Biobuf *b;
100 c42a1d3d 2006-02-21 devnull Istack *is;
101 c42a1d3d 2006-02-21 devnull
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;
105 c42a1d3d 2006-02-21 devnull }
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;
113 c42a1d3d 2006-02-21 devnull }
114 c42a1d3d 2006-02-21 devnull
115 c42a1d3d 2006-02-21 devnull int
116 c42a1d3d 2006-02-21 devnull pushstdin(void)
117 c42a1d3d 2006-02-21 devnull {
118 c42a1d3d 2006-02-21 devnull return _inputstdin(ipush);
119 c42a1d3d 2006-02-21 devnull }
120 c42a1d3d 2006-02-21 devnull
121 c42a1d3d 2006-02-21 devnull int
122 c42a1d3d 2006-02-21 devnull queuestdin(void)
123 c42a1d3d 2006-02-21 devnull {
124 c42a1d3d 2006-02-21 devnull return _inputstdin(iqueue);
125 c42a1d3d 2006-02-21 devnull }
126 c42a1d3d 2006-02-21 devnull
127 c42a1d3d 2006-02-21 devnull void
128 c42a1d3d 2006-02-21 devnull _inputstring(Rune *s, void (*push)(Istack*))
129 c42a1d3d 2006-02-21 devnull {
130 c42a1d3d 2006-02-21 devnull Istack *is;
131 fa325e9b 2020-01-10 cross
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);
137 c42a1d3d 2006-02-21 devnull }
138 c42a1d3d 2006-02-21 devnull
139 c42a1d3d 2006-02-21 devnull void
140 c42a1d3d 2006-02-21 devnull pushinputstring(Rune *s)
141 c42a1d3d 2006-02-21 devnull {
142 c42a1d3d 2006-02-21 devnull _inputstring(s, ipush);
143 c42a1d3d 2006-02-21 devnull }
144 c42a1d3d 2006-02-21 devnull
145 c42a1d3d 2006-02-21 devnull
146 c42a1d3d 2006-02-21 devnull void
147 c42a1d3d 2006-02-21 devnull inputnotify(void (*fn)(void))
148 c42a1d3d 2006-02-21 devnull {
149 c42a1d3d 2006-02-21 devnull if(istack)
150 c42a1d3d 2006-02-21 devnull istack->fn = fn;
151 c42a1d3d 2006-02-21 devnull }
152 c42a1d3d 2006-02-21 devnull
153 c42a1d3d 2006-02-21 devnull int
154 c42a1d3d 2006-02-21 devnull popinput(void)
155 c42a1d3d 2006-02-21 devnull {
156 c42a1d3d 2006-02-21 devnull Istack *is;
157 c42a1d3d 2006-02-21 devnull
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;
161 c42a1d3d 2006-02-21 devnull
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;
172 c42a1d3d 2006-02-21 devnull }
173 c42a1d3d 2006-02-21 devnull
174 c42a1d3d 2006-02-21 devnull int
175 c42a1d3d 2006-02-21 devnull getrune(void)
176 c42a1d3d 2006-02-21 devnull {
177 c42a1d3d 2006-02-21 devnull Rune r;
178 c42a1d3d 2006-02-21 devnull int c;
179 fa325e9b 2020-01-10 cross
180 c42a1d3d 2006-02-21 devnull top:
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;
189 c42a1d3d 2006-02-21 devnull }
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;
195 c42a1d3d 2006-02-21 devnull }
196 c42a1d3d 2006-02-21 devnull r = c;
197 c42a1d3d 2006-02-21 devnull }else{
198 c42a1d3d 2006-02-21 devnull r = 0;
199 c42a1d3d 2006-02-21 devnull sysfatal("getrune - can't happen");
200 c42a1d3d 2006-02-21 devnull }
201 c42a1d3d 2006-02-21 devnull if(r == '\n')
202 fa325e9b 2020-01-10 cross istack->lineno++;
203 c42a1d3d 2006-02-21 devnull return r;
204 c42a1d3d 2006-02-21 devnull }
205 c42a1d3d 2006-02-21 devnull
206 c42a1d3d 2006-02-21 devnull void
207 c42a1d3d 2006-02-21 devnull ungetrune(Rune r)
208 c42a1d3d 2006-02-21 devnull {
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;
212 c42a1d3d 2006-02-21 devnull }
213 c42a1d3d 2006-02-21 devnull
214 c42a1d3d 2006-02-21 devnull int
215 c42a1d3d 2006-02-21 devnull linefmt(Fmt *f)
216 c42a1d3d 2006-02-21 devnull {
217 c42a1d3d 2006-02-21 devnull Istack *is;
218 fa325e9b 2020-01-10 cross
219 c42a1d3d 2006-02-21 devnull for(is=istack; is && !is->b; is=is->next)
220 c42a1d3d 2006-02-21 devnull ;
221 c42a1d3d 2006-02-21 devnull if(is)
222 c42a1d3d 2006-02-21 devnull return fmtprint(f, "%S:%d", is->name, is->lineno);
223 c42a1d3d 2006-02-21 devnull else
224 c42a1d3d 2006-02-21 devnull return fmtprint(f, "<no input>");
225 c42a1d3d 2006-02-21 devnull }
226 c42a1d3d 2006-02-21 devnull
227 c42a1d3d 2006-02-21 devnull void
228 c42a1d3d 2006-02-21 devnull setlinenumber(Rune *s, int n)
229 c42a1d3d 2006-02-21 devnull {
230 c42a1d3d 2006-02-21 devnull Istack *is;
231 fa325e9b 2020-01-10 cross
232 c42a1d3d 2006-02-21 devnull for(is=istack; is && !is->name; is=is->next)
233 c42a1d3d 2006-02-21 devnull ;
234 c42a1d3d 2006-02-21 devnull if(is){
235 c42a1d3d 2006-02-21 devnull if(s){
236 c42a1d3d 2006-02-21 devnull free(is->name);
237 c42a1d3d 2006-02-21 devnull is->name = erunestrdup(s);
238 c42a1d3d 2006-02-21 devnull }
239 c42a1d3d 2006-02-21 devnull is->lineno = n;
240 c42a1d3d 2006-02-21 devnull }
241 c42a1d3d 2006-02-21 devnull }