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 }