Mercurial > hg-old > index.cgi
comparison lwasm/input.c @ 330:81c005b82775
More tinkering with input subsystem
author | lost |
---|---|
date | Sun, 28 Feb 2010 05:35:50 +0000 |
parents | c15cca3ae6a2 |
children | 67224d8d1024 |
comparison
equal
deleted
inserted
replaced
329:c15cca3ae6a2 | 330:81c005b82775 |
---|---|
56 void *data; | 56 void *data; |
57 int data2; | 57 int data2; |
58 char *filespec; | 58 char *filespec; |
59 }; | 59 }; |
60 | 60 |
61 static struct input_stack *is = NULL; | 61 #define IS ((struct input_stack *)(as -> input_data)) |
62 | 62 |
63 void input_init(asmstate_t *as) | 63 void input_init(asmstate_t *as) |
64 { | 64 { |
65 struct input_stack *t; | 65 struct input_stack *t; |
66 | 66 |
67 if (as -> file_dir) | |
68 lw_stack_destroy(as -> file_dir); | |
69 as -> file_dir = lw_stack_create(lw_free); | |
67 lw_stringlist_reset(as -> input_files); | 70 lw_stringlist_reset(as -> input_files); |
68 while (is) | 71 while (IS) |
69 { | 72 { |
70 t = is; | 73 t = IS; |
71 is = is -> next; | 74 as -> input_data = IS -> next; |
72 lw_free(t); | 75 lw_free(t); |
73 } | 76 } |
74 } | 77 } |
75 | 78 |
76 void input_pushpath(asmstate_t *as, char *fn) | 79 void input_pushpath(asmstate_t *as, char *fn) |
111 t -> filespec = lw_strdup(s); | 114 t -> filespec = lw_strdup(s); |
112 | 115 |
113 t -> type = input_type_string; | 116 t -> type = input_type_string; |
114 t -> data = lw_strdup(str); | 117 t -> data = lw_strdup(str); |
115 t -> data2 = 0; | 118 t -> data2 = 0; |
116 t -> next = is; | 119 t -> next = IS; |
117 is = t; | 120 as -> input_data = t; |
118 t -> filespec = lw_strdup(s); | 121 t -> filespec = lw_strdup(s); |
119 } | 122 } |
120 | 123 |
121 void input_open(asmstate_t *as, char *s) | 124 void input_open(asmstate_t *as, char *s) |
122 { | 125 { |
146 t -> type = input_type_file; | 149 t -> type = input_type_file; |
147 else | 150 else |
148 t -> type = input_type_error; | 151 t -> type = input_type_error; |
149 } | 152 } |
150 | 153 |
151 t -> next = is; | 154 t -> next = IS; |
152 is = t; | 155 as -> input_data = t; |
153 | 156 |
154 switch (is -> type) | 157 switch (IS -> type) |
155 { | 158 { |
156 case input_type_include: | 159 case input_type_include: |
157 /* first check for absolute path and if so, skip path */ | 160 /* first check for absolute path and if so, skip path */ |
158 if (*s == '/') | 161 if (*s == '/') |
159 { | 162 { |
160 /* absolute path */ | 163 /* absolute path */ |
161 is -> data = fopen(s, "rb"); | 164 IS -> data = fopen(s, "rb"); |
162 if (!is -> data) | 165 if (!IS -> data) |
163 { | 166 { |
164 lw_error("Cannot open file '%s': %s", s, strerror(errno)); | 167 lw_error("Cannot open file '%s': %s", s, strerror(errno)); |
165 } | 168 } |
166 input_pushpath(as, s); | 169 input_pushpath(as, s); |
167 break; | 170 break; |
168 } | 171 } |
169 | 172 |
170 /* relative path, check relative to "current file" directory */ | 173 /* relative path, check relative to "current file" directory */ |
171 p = lw_stack_top(as -> file_dir); | 174 p = lw_stack_top(as -> file_dir); |
172 0 == asprintf(&p2, "%s/%s", p, s); | 175 0 == asprintf(&p2, "%s/%s", p, s); |
173 is -> data = fopen(p2, "rb"); | 176 IS -> data = fopen(p2, "rb"); |
174 if (is -> data) | 177 if (IS -> data) |
175 { | 178 { |
176 input_pushpath(as, p2); | 179 input_pushpath(as, p2); |
177 lw_free(p2); | 180 lw_free(p2); |
178 break; | 181 break; |
179 } | 182 } |
182 /* now check relative to entries in the search path */ | 185 /* now check relative to entries in the search path */ |
183 lw_stringlist_reset(as -> include_list); | 186 lw_stringlist_reset(as -> include_list); |
184 while (p = lw_stringlist_current(as -> include_list)) | 187 while (p = lw_stringlist_current(as -> include_list)) |
185 { | 188 { |
186 0 == asprintf(&p2, "%s/%s", p, s); | 189 0 == asprintf(&p2, "%s/%s", p, s); |
187 is -> data = fopen(p2, "rb"); | 190 IS -> data = fopen(p2, "rb"); |
188 if (is -> data) | 191 if (IS -> data) |
189 { | 192 { |
190 input_pushpath(as, p2); | 193 input_pushpath(as, p2); |
191 lw_free(p2); | 194 lw_free(p2); |
192 return; | 195 return; |
193 } | 196 } |
195 lw_stringlist_next(as -> include_list); | 198 lw_stringlist_next(as -> include_list); |
196 } | 199 } |
197 lw_error("Cannot open include file '%s': %s", s, strerror(errno)); | 200 lw_error("Cannot open include file '%s': %s", s, strerror(errno)); |
198 | 201 |
199 case input_type_file: | 202 case input_type_file: |
200 is -> data = fopen(s, "rb"); | 203 IS -> data = fopen(s, "rb"); |
201 | 204 |
202 if (!is -> data) | 205 if (!IS -> data) |
203 { | 206 { |
204 lw_error("Cannot open file '%s': %s", s, strerror(errno)); | 207 lw_error("Cannot open file '%s': %s", s, strerror(errno)); |
205 } | 208 } |
206 input_pushpath(as, s); | 209 input_pushpath(as, s); |
207 return; | 210 return; |
217 int lbloc; | 220 int lbloc; |
218 int eol = 0; | 221 int eol = 0; |
219 | 222 |
220 /* if no file is open, open one */ | 223 /* if no file is open, open one */ |
221 nextfile: | 224 nextfile: |
222 if (!is) { | 225 if (!IS) { |
223 s = lw_stringlist_current(as -> input_files); | 226 s = lw_stringlist_current(as -> input_files); |
224 if (!s) | 227 if (!s) |
225 return NULL; | 228 return NULL; |
226 lw_stringlist_next(as -> input_files); | 229 lw_stringlist_next(as -> input_files); |
227 input_open(as, s); | 230 input_open(as, s); |
228 } | 231 } |
229 | 232 |
230 switch (is -> type) | 233 switch (IS -> type) |
231 { | 234 { |
232 case input_type_file: | 235 case input_type_file: |
233 case input_type_include: | 236 case input_type_include: |
234 /* read from a file */ | 237 /* read from a file */ |
235 for (;;) | 238 for (;;) |
236 { | 239 { |
237 int c, c2; | 240 int c, c2; |
238 c = fgetc(is -> data); | 241 c = fgetc(IS -> data); |
239 lbloc = 0; | 242 lbloc = 0; |
240 if (c == EOF) | 243 if (c == EOF) |
241 { | 244 { |
242 if (lbloc == 0) | 245 if (lbloc == 0) |
243 { | 246 { |
244 struct input_stack *t; | 247 struct input_stack *t; |
245 fclose(is -> data); | 248 fclose(IS -> data); |
246 lw_free(lw_stack_pop(as -> file_dir)); | 249 lw_free(lw_stack_pop(as -> file_dir)); |
247 lw_free(is -> filespec); | 250 lw_free(IS -> filespec); |
248 t = is -> next; | 251 t = IS -> next; |
249 lw_free(is); | 252 lw_free(IS); |
250 is = t; | 253 as -> input_data = t; |
251 goto nextfile; | 254 goto nextfile; |
252 } | 255 } |
253 linebuff[lbloc] = '\0'; | 256 linebuff[lbloc] = '\0'; |
254 eol = 1; | 257 eol = 1; |
255 } | 258 } |
256 else if (c == '\r') | 259 else if (c == '\r') |
257 { | 260 { |
258 linebuff[lbloc] = '\0'; | 261 linebuff[lbloc] = '\0'; |
259 eol = 1; | 262 eol = 1; |
260 c2 = fgetc(is -> data); | 263 c2 = fgetc(IS -> data); |
261 if (c2 == EOF) | 264 if (c2 == EOF) |
262 c = EOF; | 265 c = EOF; |
263 else if (c2 != '\n') | 266 else if (c2 != '\n') |
264 ungetc(c2, is -> data); | 267 ungetc(c2, IS -> data); |
265 } | 268 } |
266 else if (c == '\n') | 269 else if (c == '\n') |
267 { | 270 { |
268 linebuff[lbloc] = '\0'; | 271 linebuff[lbloc] = '\0'; |
269 eol = 1; | 272 eol = 1; |
270 c2 = fgetc(is -> data); | 273 c2 = fgetc(IS -> data); |
271 if (c2 == EOF) | 274 if (c2 == EOF) |
272 c = EOF; | 275 c = EOF; |
273 else if (c2 != '\r') | 276 else if (c2 != '\r') |
274 ungetc(c2, is -> data); | 277 ungetc(c2, IS -> data); |
275 } | 278 } |
276 else | 279 else |
277 { | 280 { |
278 if (lbloc < 2048) | 281 if (lbloc < 2048) |
279 linebuff[lbloc++] = c; | 282 linebuff[lbloc++] = c; |
285 } | 288 } |
286 } | 289 } |
287 | 290 |
288 case input_type_string: | 291 case input_type_string: |
289 /* read from a string */ | 292 /* read from a string */ |
290 if (((char *)(is -> data))[is -> data2] == '\0') | 293 if (((char *)(IS -> data))[IS -> data2] == '\0') |
291 { | 294 { |
292 struct input_stack *t; | 295 struct input_stack *t; |
293 lw_free(is -> data); | 296 lw_free(IS -> data); |
294 lw_free(is -> filespec); | 297 lw_free(IS -> filespec); |
295 t = is -> next; | 298 t = IS -> next; |
296 lw_free(is); | 299 lw_free(IS); |
297 is = t; | 300 as -> input_data = t; |
298 goto nextfile; | 301 goto nextfile; |
299 } | 302 } |
300 s = (char *)(is -> data); | 303 s = (char *)(IS -> data); |
301 lbloc = 0; | 304 lbloc = 0; |
302 for (;;) | 305 for (;;) |
303 { | 306 { |
304 int c; | 307 int c; |
305 c = s[is -> data2]; | 308 c = s[IS -> data2]; |
306 if (c) | 309 if (c) |
307 is -> data2++; | 310 IS -> data2++; |
308 if (c == '\0') | 311 if (c == '\0') |
309 { | 312 { |
310 linebuff[lbloc] = '\0'; | 313 linebuff[lbloc] = '\0'; |
311 eol = 1; | 314 eol = 1; |
312 } | 315 } |
313 else if (c == '\r') | 316 else if (c == '\r') |
314 { | 317 { |
315 linebuff[lbloc] = '\0'; | 318 linebuff[lbloc] = '\0'; |
316 eol = 1; | 319 eol = 1; |
317 if (s[is -> data2] == '\n') | 320 if (s[IS -> data2] == '\n') |
318 is -> data2++; | 321 IS -> data2++; |
319 } | 322 } |
320 else if (c == '\n') | 323 else if (c == '\n') |
321 { | 324 { |
322 linebuff[lbloc] = '\0'; | 325 linebuff[lbloc] = '\0'; |
323 eol = 1; | 326 eol = 1; |
324 if (s[is -> data2] == '\r') | 327 if (s[IS -> data2] == '\r') |
325 is -> data2++; | 328 IS -> data2++; |
326 } | 329 } |
327 else | 330 else |
328 { | 331 { |
329 if (lbloc < 2048) | 332 if (lbloc < 2048) |
330 linebuff[lbloc++] = c; | 333 linebuff[lbloc++] = c; |
338 | 341 |
339 default: | 342 default: |
340 lw_error("Problem reading from unknown input type"); | 343 lw_error("Problem reading from unknown input type"); |
341 } | 344 } |
342 } | 345 } |
346 | |
347 char *input_curspec(asmstate_t *as) | |
348 { | |
349 if (IS) | |
350 return IS -> filespec; | |
351 return NULL; | |
352 } |