Mercurial > hg > index.cgi
annotate lwcc/preproc.c @ 306:b08787e5b9f3 ccdev
Add include search paths and command line macro definitions
Added command line macro definitions. Also implemented include paths. There
is no default include path; that will be supplied by the driver program.
author | William Astle <lost@l-w.ca> |
---|---|
date | Wed, 18 Sep 2013 20:41:41 -0600 |
parents | 54f213c8fb81 |
children | 9e342c4e4b66 |
rev | line source |
---|---|
296 | 1 /* |
2 lwcc/preproc.c | |
3 | |
4 Copyright © 2013 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
300 | 22 #include <stdio.h> |
23 #include <stdlib.h> | |
296 | 24 #include <string.h> |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
25 #include <unistd.h> |
296 | 26 |
27 #include <lw_alloc.h> | |
28 #include <lw_string.h> | |
29 | |
30 #include "cpp.h" | |
31 #include "strbuf.h" | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
32 #include "strpool.h" |
296 | 33 #include "symbol.h" |
34 #include "token.h" | |
35 | |
36 static int expand_macro(struct preproc_info *, char *); | |
37 static void process_directive(struct preproc_info *); | |
38 static long eval_expr(struct preproc_info *); | |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
39 extern struct token *preproc_lex_next_token(struct preproc_info *); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
40 |
296 | 41 |
42 struct token *preproc_next_processed_token(struct preproc_info *pp) | |
43 { | |
44 struct token *ct; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
45 |
296 | 46 again: |
47 ct = preproc_next_token(pp); | |
48 if (ct -> ttype == TOK_EOF) | |
49 return ct; | |
50 if (ct -> ttype == TOK_EOL) | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
51 { |
296 | 52 pp -> ppeolseen = 1; |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
53 return ct; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
54 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
55 |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
56 if (ct -> ttype == TOK_HASH && pp -> ppeolseen == 1) |
296 | 57 { |
58 // preprocessor directive | |
59 process_directive(pp); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
60 goto again; |
296 | 61 } |
62 // if we're in a false section, don't return the token; keep scanning | |
63 if (pp -> skip_level) | |
64 goto again; | |
65 | |
66 if (ct -> ttype != TOK_WSPACE) | |
67 pp -> ppeolseen = 0; | |
68 | |
69 if (ct -> ttype == TOK_IDENT) | |
70 { | |
71 // possible macro expansion | |
72 if (expand_macro(pp, ct -> strval)) | |
73 goto again; | |
74 } | |
75 | |
76 return ct; | |
77 } | |
78 | |
79 static struct token *preproc_next_processed_token_nws(struct preproc_info *pp) | |
80 { | |
81 struct token *t; | |
82 | |
83 do | |
84 { | |
85 t = preproc_next_processed_token(pp); | |
86 } while (t -> ttype == TOK_WSPACE); | |
87 return t; | |
88 } | |
89 | |
90 static struct token *preproc_next_token_nws(struct preproc_info *pp) | |
91 { | |
92 struct token *t; | |
93 | |
94 do | |
95 { | |
96 t = preproc_next_token(pp); | |
97 } while (t -> ttype == TOK_WSPACE); | |
98 return t; | |
99 } | |
100 | |
101 static void skip_eol(struct preproc_info *pp) | |
102 { | |
103 struct token *t; | |
104 | |
105 if (pp -> curtok && pp -> curtok -> ttype == TOK_EOL) | |
106 return; | |
107 do | |
108 { | |
109 t = preproc_next_token(pp); | |
110 } while (t -> ttype != TOK_EOL); | |
111 } | |
112 | |
113 static void check_eol(struct preproc_info *pp) | |
114 { | |
115 struct token *t; | |
116 | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
117 t = preproc_next_token_nws(pp); |
296 | 118 if (t -> ttype != TOK_EOL) |
119 preproc_throw_warning(pp, "Extra text after preprocessor directive"); | |
120 skip_eol(pp); | |
121 } | |
122 | |
123 static void dir_ifdef(struct preproc_info *pp) | |
124 { | |
125 struct token *ct; | |
126 | |
127 if (pp -> skip_level) | |
128 { | |
129 pp -> skip_level++; | |
130 skip_eol(pp); | |
131 return; | |
132 } | |
133 | |
134 do | |
135 { | |
136 ct = preproc_next_token(pp); | |
137 } while (ct -> ttype == TOK_WSPACE); | |
138 | |
139 if (ct -> ttype != TOK_IDENT) | |
140 { | |
141 preproc_throw_error(pp, "Bad #ifdef"); | |
142 skip_eol(pp); | |
143 } | |
144 | |
145 if (symtab_find(pp, ct -> strval) == NULL) | |
146 { | |
147 pp -> skip_level++; | |
148 } | |
149 else | |
150 { | |
151 pp -> found_level++; | |
152 } | |
153 check_eol(pp); | |
154 } | |
155 | |
156 static void dir_ifndef(struct preproc_info *pp) | |
157 { | |
158 struct token *ct; | |
159 | |
160 if (pp -> skip_level) | |
161 { | |
162 pp -> skip_level++; | |
163 skip_eol(pp); | |
164 return; | |
165 } | |
166 | |
167 do | |
168 { | |
169 ct = preproc_next_token(pp); | |
170 } while (ct -> ttype == TOK_WSPACE); | |
171 | |
172 if (ct -> ttype != TOK_IDENT) | |
173 { | |
174 preproc_throw_error(pp, "Bad #ifdef"); | |
175 skip_eol(pp); | |
176 } | |
177 | |
178 if (symtab_find(pp, ct -> strval) != NULL) | |
179 { | |
180 pp -> skip_level++; | |
181 } | |
182 else | |
183 { | |
184 pp -> found_level++; | |
185 } | |
186 check_eol(pp); | |
187 } | |
188 | |
189 static void dir_if(struct preproc_info *pp) | |
190 { | |
191 if (pp -> skip_level || !eval_expr(pp)) | |
192 pp -> skip_level++; | |
193 else | |
194 pp -> found_level++; | |
195 } | |
196 | |
197 static void dir_elif(struct preproc_info *pp) | |
198 { | |
199 if (pp -> skip_level == 0) | |
200 pp -> else_skip_level = pp -> found_level; | |
201 if (pp -> skip_level) | |
202 { | |
203 if (pp -> else_skip_level > pp -> found_level) | |
204 ; | |
205 else if (--(pp -> skip_level) != 0) | |
206 pp -> skip_level++; | |
207 else if (eval_expr(pp)) | |
208 pp -> found_level++; | |
209 else | |
210 pp -> skip_level++; | |
211 } | |
212 else if (pp -> found_level) | |
213 { | |
214 pp -> skip_level++; | |
215 pp -> found_level--; | |
216 } | |
217 else | |
218 preproc_throw_error(pp, "#elif in non-conditional section"); | |
219 } | |
220 | |
221 static void dir_else(struct preproc_info *pp) | |
222 { | |
223 if (pp -> skip_level) | |
224 { | |
225 if (pp -> else_skip_level > pp -> found_level) | |
226 ; | |
227 else if (--(pp -> skip_level) != 0) | |
228 pp -> skip_level++; | |
229 else | |
230 pp -> found_level++; | |
231 } | |
232 else if (pp -> found_level) | |
233 { | |
234 pp -> skip_level++; | |
235 pp -> found_level--; | |
236 } | |
237 else | |
238 { | |
239 preproc_throw_error(pp, "#else in non-conditional section"); | |
240 } | |
241 if (pp -> else_level == pp -> found_level + pp -> skip_level) | |
242 { | |
243 preproc_throw_error(pp, "Too many #else"); | |
244 } | |
245 pp -> else_level = pp -> found_level + pp -> skip_level; | |
246 check_eol(pp); | |
247 } | |
248 | |
249 static void dir_endif(struct preproc_info *pp) | |
250 { | |
251 if (pp -> skip_level) | |
252 pp -> skip_level--; | |
253 else if (pp -> found_level) | |
254 pp -> found_level--; | |
255 else | |
256 preproc_throw_error(pp, "#endif in non-conditional section"); | |
257 if (pp -> skip_level == 0) | |
258 pp -> else_skip_level = 0; | |
259 pp -> else_level = 0; | |
260 check_eol(pp); | |
261 } | |
262 | |
263 static void dir_define(struct preproc_info *pp) | |
264 { | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
265 struct token_list *tl = NULL; |
296 | 266 struct token *ct; |
267 int nargs = -1; | |
268 int vargs = 0; | |
269 char *mname = NULL; | |
270 | |
271 char **arglist = NULL; | |
272 | |
273 if (pp -> skip_level) | |
274 { | |
275 skip_eol(pp); | |
276 return; | |
277 } | |
278 | |
279 ct = preproc_next_token_nws(pp); | |
280 if (ct -> ttype != TOK_IDENT) | |
281 goto baddefine; | |
282 | |
283 mname = lw_strdup(ct -> strval); | |
284 ct = preproc_next_token(pp); | |
285 if (ct -> ttype == TOK_WSPACE) | |
286 { | |
287 /* object like macro */ | |
288 } | |
289 else if (ct -> ttype == TOK_EOL) | |
290 { | |
291 /* object like macro - empty value */ | |
292 goto out; | |
293 } | |
294 else if (ct -> ttype == TOK_OPAREN) | |
295 { | |
296 /* function like macro - parse args */ | |
297 nargs = 0; | |
298 vargs = 0; | |
299 for (;;) | |
300 { | |
301 ct = preproc_next_token_nws(pp); | |
302 if (ct -> ttype == TOK_EOL) | |
303 { | |
304 goto baddefine; | |
305 } | |
306 if (ct -> ttype == TOK_CPAREN) | |
307 break; | |
308 | |
309 if (ct -> ttype == TOK_IDENT) | |
310 { | |
311 /* parameter name */ | |
312 nargs++; | |
313 /* record argument name */ | |
314 arglist = lw_realloc(arglist, sizeof(char *) * nargs); | |
315 arglist[nargs - 1] = lw_strdup(ct -> strval); | |
316 | |
317 /* check for end of args or comma */ | |
318 ct = preproc_next_token_nws(pp); | |
319 if (ct -> ttype == TOK_CPAREN) | |
320 break; | |
321 else if (ct -> ttype == TOK_COMMA) | |
322 continue; | |
323 else | |
324 goto baddefine; | |
325 } | |
326 else if (ct -> ttype == TOK_ELLIPSIS) | |
327 { | |
328 /* variadic macro */ | |
329 vargs = 1; | |
330 ct = preproc_next_token_nws(pp); | |
331 if (ct -> ttype != TOK_CPAREN) | |
332 goto baddefine; | |
333 break; | |
334 } | |
335 else | |
336 goto baddefine; | |
337 } | |
338 } | |
339 else | |
340 { | |
341 baddefine: | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
342 preproc_throw_error(pp, "bad #define", ct -> ttype); |
296 | 343 baddefine2: |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
344 token_list_destroy(tl); |
296 | 345 skip_eol(pp); |
346 lw_free(mname); | |
347 while (nargs > 0) | |
348 lw_free(arglist[--nargs]); | |
349 lw_free(arglist); | |
350 return; | |
351 } | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
352 |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
353 tl = token_list_create(); |
296 | 354 for (;;) |
355 { | |
356 ct = preproc_next_token(pp); | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
357 |
296 | 358 if (ct -> ttype == TOK_EOL) |
359 break; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
360 token_list_append(tl, token_dup(ct)); |
296 | 361 } |
362 out: | |
363 if (strcmp(mname, "defined") == 0) | |
364 { | |
365 preproc_throw_warning(pp, "attempt to define 'defined' as a macro not allowed"); | |
366 goto baddefine2; | |
367 } | |
368 else if (symtab_find(pp, mname) != NULL) | |
369 { | |
370 /* need to do a token compare between the old value and the new value | |
371 to decide whether to complain */ | |
372 preproc_throw_warning(pp, "%s previous defined", mname); | |
373 symtab_undef(pp, mname); | |
374 } | |
375 symtab_define(pp, mname, tl, nargs, arglist, vargs); | |
376 lw_free(mname); | |
377 while (nargs > 0) | |
378 lw_free(arglist[--nargs]); | |
379 lw_free(arglist); | |
380 /* no need to check for EOL here */ | |
381 } | |
382 | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
383 void preproc_add_macro(struct preproc_info *pp, char *str) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
384 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
385 char *s; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
386 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
387 pp -> lexstr = lw_strdup(str); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
388 pp -> lexstrloc = 0; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
389 s = strchr(pp -> lexstr, '='); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
390 if (s) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
391 *s = ' '; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
392 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
393 dir_define(pp); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
394 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
395 lw_free(pp -> lexstr); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
396 pp -> lexstr = NULL; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
397 pp -> lexstrloc = 0; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
398 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
399 |
296 | 400 static void dir_undef(struct preproc_info *pp) |
401 { | |
402 struct token *ct; | |
403 if (pp -> skip_level) | |
404 { | |
405 skip_eol(pp); | |
406 return; | |
407 } | |
408 | |
409 do | |
410 { | |
411 ct = preproc_next_token(pp); | |
412 } while (ct -> ttype == TOK_WSPACE); | |
413 | |
414 if (ct -> ttype != TOK_IDENT) | |
415 { | |
416 preproc_throw_error(pp, "Bad #undef"); | |
417 skip_eol(pp); | |
418 } | |
419 | |
420 symtab_undef(pp, ct -> strval); | |
421 check_eol(pp); | |
422 } | |
423 | |
424 char *streol(struct preproc_info *pp) | |
425 { | |
426 struct strbuf *s; | |
427 struct token *ct; | |
428 int i; | |
429 | |
430 s = strbuf_new(); | |
431 do | |
432 { | |
433 ct = preproc_next_token(pp); | |
434 } while (ct -> ttype == TOK_WSPACE); | |
435 | |
436 while (ct -> ttype != TOK_EOL) | |
437 { | |
438 for (i = 0; ct -> strval[i]; i++) | |
439 strbuf_add(s, ct -> strval[i]); | |
440 ct = preproc_next_token(pp); | |
441 } | |
442 return strbuf_end(s); | |
443 } | |
444 | |
445 static void dir_error(struct preproc_info *pp) | |
446 { | |
447 char *s; | |
448 | |
449 if (pp -> skip_level) | |
450 { | |
451 skip_eol(pp); | |
452 return; | |
453 } | |
454 | |
455 s = streol(pp); | |
456 preproc_throw_error(pp, "%s", s); | |
457 lw_free(s); | |
458 } | |
459 | |
460 static void dir_warning(struct preproc_info *pp) | |
461 { | |
462 char *s; | |
463 | |
464 if (pp -> skip_level) | |
465 { | |
466 skip_eol(pp); | |
467 return; | |
468 } | |
469 | |
470 s = streol(pp); | |
471 preproc_throw_warning(pp, "%s", s); | |
472 lw_free(s); | |
473 } | |
474 | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
475 static char *preproc_file_exists_in_dir(char *dir, char *fn) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
476 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
477 int l; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
478 char *f; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
479 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
480 l = snprintf(NULL, 0, "%s/%s", dir, fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
481 f = lw_alloc(l + 1); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
482 snprintf(f, l + 1, "%s/%s", dir, fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
483 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
484 if (access(f, R_OK) == 0) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
485 return f; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
486 lw_free(f); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
487 return NULL; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
488 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
489 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
490 static char *preproc_find_file(struct preproc_info *pp, char *fn, int sys) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
491 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
492 char *tstr; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
493 char *pref; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
494 char *rfn; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
495 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
496 /* pass through absolute paths, dumb as they are */ |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
497 if (fn[0] == '/') |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
498 return lw_strdup(fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
499 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
500 if (!sys) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
501 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
502 /* look in the directory with the current file */ |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
503 tstr = strchr(pp -> fn, '/'); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
504 if (!tstr) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
505 pref = lw_strdup("."); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
506 else |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
507 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
508 pref = lw_alloc(tstr - pp -> fn + 1); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
509 memcpy(pref, pp -> fn, tstr - pp -> fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
510 pref[tstr - pp -> fn] = 0; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
511 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
512 rfn = preproc_file_exists_in_dir(pref, fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
513 lw_free(pref); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
514 if (rfn) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
515 return rfn; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
516 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
517 /* look in the "quote" dir list */ |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
518 lw_stringlist_reset(pp -> quotelist); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
519 for (pref = lw_stringlist_current(pp -> quotelist); pref; pref = lw_stringlist_next(pp -> quotelist)) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
520 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
521 rfn = preproc_file_exists_in_dir(pref, fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
522 if (rfn) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
523 return rfn; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
524 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
525 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
526 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
527 /* look in the "include" dir list */ |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
528 lw_stringlist_reset(pp -> inclist); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
529 for (pref = lw_stringlist_current(pp -> inclist); pref; pref = lw_stringlist_next(pp -> inclist)) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
530 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
531 rfn = preproc_file_exists_in_dir(pref, fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
532 if (rfn) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
533 return rfn; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
534 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
535 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
536 /* the default search list is provided by the driver program */ |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
537 return NULL; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
538 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
539 |
296 | 540 static void dir_include(struct preproc_info *pp) |
541 { | |
300 | 542 FILE *fp; |
543 struct token *ct; | |
544 int sys = 0; | |
545 char *fn; | |
546 struct strbuf *strbuf; | |
547 int i; | |
548 struct preproc_info *fs; | |
549 | |
550 ct = preproc_next_token_nws(pp); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
551 if (ct -> ttype == TOK_STR_LIT) |
300 | 552 { |
553 usrinc: | |
554 sys = strlen(ct -> strval); | |
555 fn = lw_alloc(sys - 1); | |
556 memcpy(fn, ct -> strval + 1, sys - 2); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
557 fn[sys - 2] = 0; |
300 | 558 sys = 0; |
559 goto doinc; | |
560 } | |
561 else if (ct -> ttype == TOK_LT) | |
562 { | |
563 strbuf = strbuf_new(); | |
564 for (;;) | |
565 { | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
566 int c; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
567 c = preproc_lex_fetch_byte(pp); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
568 if (c == CPP_EOL) |
300 | 569 { |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
570 preproc_lex_unfetch_byte(pp, c); |
300 | 571 preproc_throw_error(pp, "Bad #include"); |
572 lw_free(strbuf_end(strbuf)); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
573 break; |
300 | 574 } |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
575 if (c == '>') |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
576 break; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
577 strbuf_add(strbuf, c); |
300 | 578 } |
579 ct = preproc_next_token_nws(pp); | |
580 if (ct -> ttype != TOK_EOL) | |
581 { | |
582 preproc_throw_error(pp, "Bad #include"); | |
583 skip_eol(pp); | |
584 lw_free(strbuf_end(strbuf)); | |
585 return; | |
586 } | |
587 sys = 1; | |
588 fn = strbuf_end(strbuf); | |
589 goto doinc; | |
590 } | |
591 else | |
592 { | |
593 preproc_unget_token(pp, ct); | |
594 // computed include | |
595 ct = preproc_next_processed_token_nws(pp); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
596 if (ct -> ttype == TOK_STR_LIT) |
300 | 597 goto usrinc; |
598 else if (ct -> ttype == TOK_LT) | |
599 { | |
600 strbuf = strbuf_new(); | |
601 for (;;) | |
602 { | |
603 ct = preproc_next_processed_token(pp); | |
604 if (ct -> ttype == TOK_GT) | |
605 break; | |
606 if (ct -> ttype == TOK_EOL) | |
607 { | |
608 preproc_throw_error(pp, "Bad #include"); | |
609 lw_free(strbuf_end(strbuf)); | |
610 return; | |
611 } | |
612 for (i = 0; ct -> strval[i]; ct++) | |
613 { | |
614 strbuf_add(strbuf, ct -> strval[i]); | |
615 } | |
616 } | |
617 ct = preproc_next_processed_token_nws(pp); | |
618 if (ct -> ttype != TOK_EOL) | |
619 { | |
620 preproc_throw_error(pp, "Bad #include"); | |
621 skip_eol(pp); | |
622 lw_free(strbuf_end(strbuf)); | |
623 return; | |
624 } | |
625 sys = 1; | |
626 fn = strbuf_end(strbuf); | |
627 goto doinc; | |
628 } | |
629 else | |
630 { | |
631 skip_eol(pp); | |
632 preproc_throw_error(pp, "Bad #include"); | |
633 return; | |
634 } | |
635 } | |
636 doinc: | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
637 fn = preproc_find_file(pp, fn, sys); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
638 if (!fn) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
639 goto badfile; |
300 | 640 fp = fopen(fn, "rb"); |
641 if (!fp) | |
642 { | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
643 lw_free(fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
644 badfile: |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
645 preproc_throw_error(pp, "Cannot open #include file %s - this is fatal", fn); |
300 | 646 exit(1); |
647 } | |
648 | |
649 /* save the current include file state, etc. */ | |
650 fs = lw_alloc(sizeof(struct preproc_info)); | |
651 *fs = *pp; | |
652 fs -> n = pp -> filestack; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
653 pp -> curtok = NULL; |
300 | 654 pp -> filestack = fs; |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
655 pp -> fn = strpool_strdup(pp -> strpool, fn); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
656 lw_free(fn); |
300 | 657 pp -> fp = fp; |
658 pp -> ra = CPP_NOUNG; | |
659 pp -> ppeolseen = 1; | |
660 pp -> eolstate = 0; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
661 pp -> lineno = 1; |
300 | 662 pp -> column = 0; |
663 pp -> qseen = 0; | |
664 pp -> ungetbufl = 0; | |
665 pp -> ungetbufs = 0; | |
666 pp -> ungetbuf = NULL; | |
667 pp -> unget = 0; | |
668 pp -> eolseen = 0; | |
669 pp -> nlseen = 0; | |
670 pp -> skip_level = 0; | |
671 pp -> found_level = 0; | |
672 pp -> else_level = 0; | |
673 pp -> else_skip_level = 0; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
674 pp -> tokqueue = NULL; |
300 | 675 // now get on with processing |
296 | 676 } |
677 | |
678 static void dir_line(struct preproc_info *pp) | |
679 { | |
300 | 680 struct token *ct; |
681 long lineno; | |
682 char *estr; | |
683 | |
684 lineno = -1; | |
685 | |
686 ct = preproc_next_processed_token_nws(pp); | |
687 if (ct -> ttype == TOK_NUMBER) | |
688 { | |
689 lineno = strtoul(ct -> strval, &estr, 10); | |
690 if (*estr) | |
691 { | |
692 preproc_throw_error(pp, "Bad #line"); | |
693 skip_eol(pp); | |
694 return; | |
695 } | |
696 } | |
697 else | |
698 { | |
699 preproc_throw_error(pp, "Bad #line"); | |
700 skip_eol(pp); | |
701 return; | |
702 } | |
703 ct = preproc_next_processed_token_nws(pp); | |
704 if (ct -> ttype == TOK_EOL) | |
705 { | |
706 pp -> lineno = lineno; | |
707 return; | |
708 } | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
709 if (ct -> ttype != TOK_STR_LIT) |
300 | 710 { |
711 preproc_throw_error(pp, "Bad #line"); | |
712 skip_eol(pp); | |
713 return; | |
714 } | |
715 estr = lw_strdup(ct -> strval); | |
716 ct = preproc_next_processed_token_nws(pp); | |
717 if (ct -> ttype != TOK_EOL) | |
718 { | |
719 preproc_throw_error(pp, "Bad #line"); | |
720 skip_eol(pp); | |
721 lw_free(estr); | |
722 return; | |
723 } | |
724 pp -> fn = estr; | |
725 pp -> lineno = lineno; | |
296 | 726 } |
727 | |
728 static void dir_pragma(struct preproc_info *pp) | |
729 { | |
730 if (pp -> skip_level) | |
731 { | |
732 skip_eol(pp); | |
733 return; | |
734 } | |
735 | |
736 preproc_throw_warning(pp, "Unsupported #pragma"); | |
737 skip_eol(pp); | |
738 } | |
739 | |
740 struct { char *name; void (*fn)(struct preproc_info *); } dirlist[] = | |
741 { | |
742 { "ifdef", dir_ifdef }, | |
743 { "ifndef", dir_ifndef }, | |
744 { "if", dir_if }, | |
745 { "else", dir_else }, | |
746 { "elif", dir_elif }, | |
747 { "endif", dir_endif }, | |
748 { "define", dir_define }, | |
749 { "undef", dir_undef }, | |
750 { "include", dir_include }, | |
751 { "error", dir_error }, | |
752 { "warning", dir_warning }, | |
753 { "line", dir_line }, | |
754 { "pragma", dir_pragma }, | |
755 { NULL, NULL } | |
756 }; | |
757 | |
758 static void process_directive(struct preproc_info *pp) | |
759 { | |
760 struct token *ct; | |
761 int i; | |
762 | |
763 do | |
764 { | |
765 ct = preproc_next_token(pp); | |
766 } while (ct -> ttype == TOK_WSPACE); | |
767 | |
768 // NULL directive | |
769 if (ct -> ttype == TOK_EOL) | |
770 return; | |
771 | |
772 if (ct -> ttype != TOK_IDENT) | |
773 goto baddir; | |
774 | |
775 for (i = 0; dirlist[i].name; i++) | |
776 { | |
777 if (strcmp(dirlist[i].name, ct -> strval) == 0) | |
778 { | |
779 (*(dirlist[i].fn))(pp); | |
780 return; | |
781 } | |
782 } | |
783 baddir: | |
784 preproc_throw_error(pp, "Bad preprocessor directive"); | |
785 while (ct -> ttype != TOK_EOL) | |
786 ct = preproc_next_token(pp); | |
787 return; | |
788 } | |
789 | |
790 /* | |
791 Evaluate a preprocessor expression | |
792 */ | |
793 | |
794 /* same as skip_eol() but the EOL token is not consumed */ | |
795 static void skip_eoe(struct preproc_info *pp) | |
796 { | |
797 skip_eol(pp); | |
798 preproc_unget_token(pp, pp -> curtok); | |
799 } | |
800 | |
801 static long eval_expr_real(struct preproc_info *, int); | |
301
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
802 static long preproc_numval(struct preproc_info *, struct token *); |
296 | 803 |
804 static long eval_term_real(struct preproc_info *pp) | |
805 { | |
806 long tval = 0; | |
807 struct token *ct; | |
808 | |
809 eval_next: | |
810 ct = preproc_next_processed_token_nws(pp); | |
811 if (ct -> ttype == TOK_EOL) | |
812 { | |
813 preproc_throw_error(pp, "Bad expression"); | |
814 return 0; | |
815 } | |
816 | |
817 switch (ct -> ttype) | |
818 { | |
819 case TOK_OPAREN: | |
820 tval = eval_expr_real(pp, 0); | |
821 ct = preproc_next_processed_token_nws(pp); | |
822 if (ct -> ttype != ')') | |
823 { | |
824 preproc_throw_error(pp, "Unbalanced () in expression"); | |
825 skip_eoe(pp); | |
826 return 0; | |
827 } | |
828 return tval; | |
829 | |
830 case TOK_ADD: // unary + | |
831 goto eval_next; | |
832 | |
833 case TOK_SUB: // unary - | |
834 tval = eval_expr_real(pp, 200); | |
835 return -tval; | |
836 | |
837 /* NOTE: we should only get "TOK_IDENT" from an undefined macro */ | |
838 case TOK_IDENT: // some sort of function, symbol, etc. | |
839 if (strcmp(ct -> strval, "defined")) | |
840 { | |
841 /* the defined operator */ | |
842 /* any number in the "defined" bit will be | |
843 treated as a defined symbol, even zero */ | |
844 ct = preproc_next_token_nws(pp); | |
845 if (ct -> ttype == TOK_OPAREN) | |
846 { | |
847 ct = preproc_next_token_nws(pp); | |
848 if (ct -> ttype != TOK_IDENT) | |
849 { | |
850 preproc_throw_error(pp, "Bad expression"); | |
851 skip_eoe(pp); | |
852 return 0; | |
853 } | |
854 if (symtab_find(pp, ct -> strval) == NULL) | |
855 tval = 0; | |
856 else | |
857 tval = 1; | |
858 ct = preproc_next_token_nws(pp); | |
859 if (ct -> ttype != TOK_CPAREN) | |
860 { | |
861 preproc_throw_error(pp, "Bad expression"); | |
862 skip_eoe(pp); | |
863 return 0; | |
864 } | |
865 return tval; | |
866 } | |
867 else if (ct -> ttype == TOK_IDENT) | |
868 { | |
869 return (symtab_find(pp, ct -> strval) != NULL) ? 1 : 0; | |
870 } | |
871 preproc_throw_error(pp, "Bad expression"); | |
872 skip_eoe(pp); | |
873 return 0; | |
874 } | |
875 /* unknown identifier - it's zero */ | |
876 return 0; | |
877 | |
878 /* numbers */ | |
879 case TOK_NUMBER: | |
301
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
880 return preproc_numval(pp, ct); |
296 | 881 |
882 default: | |
883 preproc_throw_error(pp, "Bad expression"); | |
884 skip_eoe(pp); | |
885 return 0; | |
886 } | |
887 return 0; | |
888 } | |
889 | |
890 static long eval_expr_real(struct preproc_info *pp, int p) | |
891 { | |
892 static const struct operinfo | |
893 { | |
894 int tok; | |
895 int prec; | |
896 } operators[] = | |
897 { | |
898 { TOK_ADD, 100 }, | |
899 { TOK_SUB, 100 }, | |
900 { TOK_STAR, 150 }, | |
901 { TOK_DIV, 150 }, | |
902 { TOK_MOD, 150 }, | |
903 { TOK_LT, 75 }, | |
904 { TOK_LE, 75 }, | |
905 { TOK_GT, 75 }, | |
906 { TOK_GE, 75 }, | |
907 { TOK_EQ, 70 }, | |
908 { TOK_NE, 70 }, | |
909 { TOK_BAND, 30 }, | |
910 { TOK_BOR, 25 }, | |
911 { TOK_NONE, 0 } | |
912 }; | |
913 | |
914 int op; | |
915 long term1, term2, term3; | |
916 struct token *ct; | |
917 | |
918 term1 = eval_term_real(pp); | |
919 eval_next: | |
920 ct = preproc_next_processed_token_nws(pp); | |
921 for (op = 0; operators[op].tok != TOK_NONE; op++) | |
922 { | |
923 if (operators[op].tok == ct -> ttype) | |
924 break; | |
925 } | |
926 /* if it isn't a recognized operator, assume end of expression */ | |
927 if (operators[op].tok == TOK_NONE) | |
928 { | |
929 preproc_unget_token(pp, ct); | |
930 return term1; | |
931 } | |
932 | |
933 /* if new operation is not higher than the current precedence, let the previous op finish */ | |
934 if (operators[op].prec <= p) | |
935 return term1; | |
936 | |
937 /* get the second term */ | |
938 term2 = eval_expr_real(pp, operators[op].prec); | |
939 | |
940 switch (operators[op].tok) | |
941 { | |
942 case TOK_ADD: | |
943 term3 = term1 + term2; | |
944 break; | |
945 | |
946 case TOK_SUB: | |
947 term3 = term1 - term2; | |
948 break; | |
949 | |
950 case TOK_STAR: | |
951 term3 = term1 * term2; | |
952 break; | |
953 | |
954 case TOK_DIV: | |
955 if (!term2) | |
956 { | |
957 preproc_throw_warning(pp, "Division by zero"); | |
958 term3 = 0; | |
959 break; | |
960 } | |
961 term3 = term1 / term2; | |
962 break; | |
963 | |
964 case TOK_MOD: | |
965 if (!term2) | |
966 { | |
967 preproc_throw_warning(pp, "Division by zero"); | |
968 term3 = 0; | |
969 break; | |
970 } | |
971 term3 = term1 % term2; | |
972 break; | |
973 | |
974 case TOK_BAND: | |
975 term3 = (term1 && term2); | |
976 break; | |
977 | |
978 case TOK_BOR: | |
979 term3 = (term1 || term2); | |
980 break; | |
981 | |
982 case TOK_EQ: | |
983 term3 = (term1 == term2); | |
984 break; | |
985 | |
986 case TOK_NE: | |
987 term3 = (term1 != term2); | |
988 break; | |
989 | |
990 case TOK_GT: | |
991 term3 = (term1 > term2); | |
992 break; | |
993 | |
994 case TOK_GE: | |
995 term3 = (term1 >= term2); | |
996 break; | |
997 | |
998 case TOK_LT: | |
999 term3 = (term1 < term2); | |
1000 break; | |
1001 | |
1002 case TOK_LE: | |
1003 term3 = (term1 <= term2); | |
1004 break; | |
1005 | |
1006 default: | |
1007 term3 = 0; | |
1008 break; | |
1009 } | |
1010 term1 = term3; | |
1011 goto eval_next; | |
1012 } | |
1013 | |
1014 static long eval_expr(struct preproc_info *pp) | |
1015 { | |
1016 long rv; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
1017 struct token *t; |
296 | 1018 |
1019 rv = eval_expr_real(pp, 0); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
1020 t = preproc_next_token_nws(pp); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
1021 if (t -> ttype != TOK_EOL) |
296 | 1022 { |
1023 preproc_throw_error(pp, "Bad expression"); | |
1024 skip_eol(pp); | |
1025 } | |
1026 return rv; | |
1027 } | |
1028 | |
301
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1029 static int eval_escape(char **t) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1030 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1031 int c; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1032 int c2; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1033 |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1034 if (**t == 0) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1035 return 0; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1036 c = *(*t)++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1037 int rv = 0; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1038 |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1039 switch (c) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1040 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1041 case 'n': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1042 return 10; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1043 case 'r': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1044 return 13; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1045 case 'b': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1046 return 8; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1047 case 'e': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1048 return 27; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1049 case 'f': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1050 return 12; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1051 case 't': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1052 return 9; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1053 case 'v': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1054 return 11; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1055 case 'a': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1056 return 7; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1057 case '0': case '1': case '2': case '3': case '4': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1058 case '5': case '6': case '7': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1059 // octal constant |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1060 rv = c - '0'; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1061 c2 = 1; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1062 for (; c2 < 3; c2++) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1063 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1064 c = *(*t)++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1065 if (c < '0' || c > '7') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1066 break; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1067 rv = (rv << 3) | (c - '0'); |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1068 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1069 return rv; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1070 case 'x': |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1071 // hex constant |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1072 for (;;) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1073 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1074 c = *(*t)++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1075 if (c < '0' || (c > '9' && c < 'A') || (c > 'F' && c < 'a') || c > 'f') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1076 break; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1077 c = c - '0'; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1078 if (c > 9) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1079 c -= 7; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1080 if (c > 15) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1081 c -= 32; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1082 rv = (rv << 4) | c; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1083 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1084 return rv & 0xff; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1085 default: |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1086 return c; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1087 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1088 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1089 |
296 | 1090 /* convert a numeric string to a number */ |
301
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1091 long preproc_numval(struct preproc_info *pp, struct token *t) |
296 | 1092 { |
301
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1093 unsigned long long rv = 0; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1094 unsigned long long rv2 = 0; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1095 char *tstr = t -> strval; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1096 int radix = 10; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1097 int c; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1098 int ovf = 0; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1099 union { long sv; unsigned long uv; } tv; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1100 |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1101 if (t -> ttype == TOK_CHR_LIT) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1102 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1103 tstr++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1104 while (*tstr && *tstr != '\'') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1105 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1106 if (*tstr == '\\') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1107 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1108 tstr++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1109 c = eval_escape(&tstr); |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1110 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1111 else |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1112 c = *tstr++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1113 rv = (rv << 8) | c; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1114 if (rv / radix < rv2) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1115 ovf = 1; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1116 rv2 = rv; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1117 |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1118 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1119 goto done; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1120 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1121 |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1122 |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1123 if (*tstr == '0') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1124 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1125 radix = 8; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1126 tstr++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1127 if (*tstr == 'x') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1128 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1129 radix = 16; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1130 tstr++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1131 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1132 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1133 while (*tstr) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1134 { |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1135 c = *tstr++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1136 if (c < '0' || (c > '9' && c < 'A') || (c > 'F' && c < 'a') || c > 'f') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1137 break; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1138 c -= '0'; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1139 if (c > 9) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1140 c -= 7; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1141 if (c > 15) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1142 c -= 32; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1143 if (c >= radix) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1144 break; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1145 rv = rv * radix + c; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1146 if (rv / radix < rv2) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1147 ovf = 1; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1148 rv2 = rv; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1149 } |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1150 tstr--; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1151 while (*tstr == 'l' || *tstr == 'L') |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1152 tstr++; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1153 tv.uv = rv; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1154 if (tv.sv < 0 && radix == 10) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1155 ovf = 1; |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1156 done: |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1157 if (ovf) |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1158 preproc_throw_error(pp, "Constant out of range: %s", t -> strval); |
6f7fe78bb868
Add string -> number conversion for preproc expression evaluator
William Astle <lost@l-w.ca>
parents:
300
diff
changeset
|
1159 return rv; |
296 | 1160 } |
1161 | |
1162 /* | |
1163 Below here is the logic for expanding a macro | |
1164 */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1165 static char *stringify(struct token_list *tli) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1166 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1167 struct strbuf *s; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1168 int ws = 0; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1169 struct token *tl = tli -> head; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1170 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1171 s = strbuf_new(); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1172 strbuf_add(s, '"'); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1173 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1174 while (tl && tl -> ttype == TOK_WSPACE) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1175 tl = tl -> next; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1176 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1177 for (; tl; tl = tl -> next) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1178 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1179 if (tl -> ttype == TOK_WSPACE) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1180 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1181 ws = 1; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1182 continue; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1183 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1184 if (ws) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1185 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1186 strbuf_add(s, ' '); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1187 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1188 for (ws = 0; tl -> strval[ws]; ws++) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1189 { |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
1190 if (tl -> ttype == TOK_STR_LIT || tl -> ttype == TOK_CHR_LIT) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1191 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1192 if (tl -> strval[ws] == '"' || tl -> strval[ws] == '\\') |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1193 strbuf_add(s, '\\'); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1194 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1195 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1196 ws = 0; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1197 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1198 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1199 strbuf_add(s, '"'); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1200 return strbuf_end(s); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1201 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1202 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1203 static int macro_arg(struct symtab_e *s, char *str) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1204 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1205 int i; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1206 if (strcmp(str, "__VA_ARGS__") == 0) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1207 i = s -> nargs; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1208 else |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1209 for (i = 0; i < s -> nargs; i++) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1210 if (strcmp(s -> params[i], str) == 0) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1211 break; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1212 if (i == s -> nargs) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1213 if (s -> vargs == 0) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1214 return -1; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1215 return i; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1216 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1217 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1218 /* return list to tokens as a result of ## expansion */ |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1219 static struct token_list *paste_tokens(struct preproc_info *pp, struct symtab_e *s, struct token_list **arglist, struct token *t1, struct token *t2) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1220 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1221 struct token_list *left; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1222 struct token_list *right; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1223 char *tstr; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1224 struct token *ttok; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1225 int i; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1226 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1227 if (t1 -> ttype == TOK_IDENT) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1228 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1229 i = macro_arg(s, t1 -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1230 if (i == -1) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1231 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1232 left = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1233 token_list_append(left, token_dup(t1)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1234 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1235 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1236 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1237 left = token_list_dup(arglist[i]); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1238 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1239 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1240 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1241 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1242 left = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1243 token_list_append(left, token_dup(t1)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1244 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1245 // munch trailing white space |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1246 while (left -> tail && left -> tail -> ttype == TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1247 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1248 token_list_remove(left -> tail); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1249 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1250 |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1251 if (t2 -> ttype == TOK_IDENT) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1252 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1253 i = macro_arg(s, t2 -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1254 if (i == -1) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1255 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1256 right = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1257 token_list_append(right, token_dup(t2)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1258 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1259 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1260 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1261 right = token_list_dup(arglist[i]); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1262 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1263 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1264 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1265 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1266 right = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1267 token_list_append(right, token_dup(t2)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1268 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1269 // munch leading white space |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1270 while (right -> head && right -> head -> ttype == TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1271 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1272 token_list_remove(right -> head); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1273 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1274 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1275 // nothing to append at all |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1276 if (left -> head != NULL && right -> head == NULL) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1277 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1278 // right arg is empty - use left |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1279 token_list_destroy(right); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1280 return left; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1281 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1282 if (left -> head == NULL && right -> head != NULL) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1283 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1284 // left arg is empty, use right |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1285 token_list_destroy(left); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1286 return right; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1287 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1288 if (left -> head == NULL && right -> head == NULL) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1289 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1290 // both empty, use left |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1291 token_list_destroy(right); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1292 return left; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1293 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1294 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1295 // both non-empty - past left tail with right head |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1296 // then past the right list onto the left |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1297 tstr = lw_alloc(strlen(left -> tail -> strval) + strlen(right -> head -> strval) + 1); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1298 strcpy(tstr, left -> tail -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1299 strcat(tstr, right -> head -> strval); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1300 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1301 pp -> lexstr = tstr; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1302 pp -> lexstrloc = 0; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1303 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1304 ttok = preproc_lex_next_token(pp); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1305 if (ttok -> ttype != TOK_ERROR && pp -> lexstr[pp -> lexstrloc] == 0) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1306 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1307 // we have a new token here |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1308 token_list_remove(left -> tail); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1309 token_list_remove(right -> head); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1310 token_list_append(left, token_dup(ttok)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1311 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1312 lw_free(tstr); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1313 pp -> lexstr = NULL; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1314 pp -> lexstrloc = 0; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1315 for (ttok = right -> head; ttok; ttok = ttok -> next) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1316 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1317 token_list_append(left, token_dup(ttok)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1318 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1319 token_list_destroy(right); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1320 return left; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1321 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1322 |
296 | 1323 static int expand_macro(struct preproc_info *pp, char *mname) |
1324 { | |
1325 struct symtab_e *s; | |
1326 struct token *t, *t2, *t3; | |
1327 int nargs = 0; | |
1328 struct expand_e *e; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1329 struct token_list **exparglist = NULL; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1330 struct token_list **arglist = NULL; |
296 | 1331 int i; |
297
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1332 int pcount; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1333 char *tstr; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1334 struct token_list *expand_list; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1335 int repl; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1336 struct token_list *rtl; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1337 |
296 | 1338 s = symtab_find(pp, mname); |
1339 if (!s) | |
1340 return 0; | |
1341 | |
1342 for (e = pp -> expand_list; e; e = e -> next) | |
1343 { | |
1344 /* don't expand if we're already expanding the same macro */ | |
1345 if (e -> s == s) | |
1346 return 0; | |
1347 } | |
1348 | |
1349 if (s -> nargs == -1) | |
1350 { | |
1351 /* short circuit NULL expansion */ | |
1352 if (s -> tl == NULL) | |
1353 return 1; | |
1354 | |
1355 goto expandmacro; | |
1356 } | |
1357 | |
1358 // look for opening paren after optional whitespace | |
1359 t2 = NULL; | |
1360 t = NULL; | |
1361 for (;;) | |
1362 { | |
1363 t = preproc_next_token(pp); | |
1364 if (t -> ttype != TOK_WSPACE && t -> ttype != TOK_EOL) | |
1365 break; | |
1366 t -> next = t2; | |
1367 t2 = t2; | |
1368 } | |
1369 if (t -> ttype != TOK_OPAREN) | |
1370 { | |
1371 // not a function-like invocation | |
1372 while (t2) | |
1373 { | |
1374 t = t2 -> next; | |
1375 preproc_unget_token(pp, t2); | |
1376 t2 = t; | |
1377 } | |
1378 return 0; | |
1379 } | |
1380 | |
1381 // parse parameters here | |
1382 t = preproc_next_token_nws(pp); | |
1383 nargs = 1; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1384 arglist = lw_alloc(sizeof(struct token_list *)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1385 arglist[0] = token_list_create(); |
296 | 1386 t2 = NULL; |
1387 | |
1388 while (t -> ttype != TOK_CPAREN) | |
1389 { | |
297
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1390 pcount = 0; |
296 | 1391 if (t -> ttype == TOK_EOF) |
1392 { | |
1393 preproc_throw_error(pp, "Unexpected EOF in macro call"); | |
1394 break; | |
1395 } | |
1396 if (t -> ttype == TOK_EOL) | |
1397 continue; | |
297
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1398 if (t -> ttype == TOK_OPAREN) |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1399 pcount++; |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1400 else if (t -> ttype == TOK_CPAREN && pcount) |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1401 pcount--; |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1402 if (t -> ttype == TOK_COMMA && pcount == 0) |
296 | 1403 { |
1404 if (!(s -> vargs) || (nargs > s -> nargs)) | |
1405 { | |
1406 nargs++; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1407 arglist = lw_realloc(arglist, sizeof(struct token_list *) * nargs); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1408 arglist[nargs - 1] = token_list_create(); |
296 | 1409 t2 = NULL; |
1410 continue; | |
1411 } | |
1412 } | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1413 token_list_append(arglist[nargs - 1], token_dup(t)); |
296 | 1414 } |
1415 | |
1416 if (s -> vargs) | |
1417 { | |
1418 if (nargs <= s -> nargs) | |
1419 { | |
1420 preproc_throw_error(pp, "Wrong number of arguments (%d) for variadic macro %s which takes %d arguments", nargs, mname, s -> nargs); | |
1421 } | |
1422 } | |
1423 else | |
1424 { | |
1425 if (s -> nargs != nargs && !(s -> nargs == 0 && nargs == 1 && arglist[nargs - 1])) | |
1426 { | |
1427 preproc_throw_error(pp, "Wrong number of arguments (%d) for macro %s which takes %d arguments", nargs, mname, s -> nargs); | |
1428 } | |
1429 } | |
1430 | |
1431 /* now calculate the pre-expansions of the arguments */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1432 exparglist = lw_alloc(nargs * sizeof(struct token_list *)); |
296 | 1433 for (i = 0; i < nargs; i++) |
1434 { | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1435 exparglist[i] = token_list_create(); |
296 | 1436 // NOTE: do nothing if empty argument |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1437 if (arglist[i] == NULL || arglist[i] -> head == NULL) |
296 | 1438 continue; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1439 pp -> sourcelist = arglist[i]->head; |
296 | 1440 for (;;) |
1441 { | |
1442 t = preproc_next_processed_token(pp); | |
1443 if (t -> ttype == TOK_EOF) | |
1444 break; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1445 token_list_append(exparglist[i], token_dup(t)); |
296 | 1446 } |
1447 } | |
1448 | |
1449 expandmacro: | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1450 expand_list = token_list_dup(s -> tl); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1451 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1452 // scan for stringification and handle it |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1453 repl = 0; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1454 while (repl == 0) |
296 | 1455 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1456 for (t = expand_list -> head; t; t = t -> next) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1457 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1458 if (t -> ttype == TOK_HASH && t -> next && t -> next -> ttype == TOK_IDENT) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1459 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1460 i = macro_arg(s, t -> next -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1461 if (i != -1) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1462 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1463 repl = 1; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1464 tstr = stringify(arglist[i]); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1465 token_list_remove(t -> next); |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
1466 token_list_insert(expand_list, t, token_create(TOK_STR_LIT, tstr, t -> lineno, t -> column, t -> fn)); |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1467 token_list_remove(t); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1468 lw_free(tstr); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1469 break; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1470 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1471 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1472 } |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
1473 repl = 1; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1474 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1475 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1476 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1477 // scan for concatenation and handle it |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1478 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1479 for (t = expand_list -> head; t; t = t -> next) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1480 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1481 if (t -> ttype == TOK_DBLHASH) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1482 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1483 // have a concatenation operator here |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1484 for (t2 = t -> prev; t2; t2 = t2 -> prev) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1485 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1486 if (t2 -> ttype != TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1487 break; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1488 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1489 for (t3 = t -> next; t3; t3 = t3 -> next); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1490 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1491 if (t3 -> ttype != TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1492 break; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1493 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1494 // if no non-whitespace before or after, ignore it |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1495 if (!t2 || !t3) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1496 continue; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1497 // eat the whitespace before and after |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1498 while (t -> prev != t2) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1499 token_list_remove(t -> prev); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1500 while (t -> next != t3) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1501 token_list_remove(t -> next); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1502 // now paste t -> prev with t -> next and replace t with the result |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1503 // continue scanning for ## at t -> next -> next |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1504 t3 = t -> next -> next; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1505 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1506 rtl = paste_tokens(pp, s, arglist, t -> prev, t -> next); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1507 token_list_remove(t -> next); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1508 token_list_remove(t -> prev); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1509 t2 = t -> prev; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1510 token_list_remove(t); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1511 for (t = rtl -> head; t; t = t -> next) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1512 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1513 token_list_insert(expand_list, t2, token_dup(t)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1514 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1515 t = t3 -> prev; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1516 token_list_destroy(rtl); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1517 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1518 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1519 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1520 // now scan for arguments and expand them |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1521 for (t = expand_list -> head; t; t = t -> next) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1522 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1523 again: |
296 | 1524 if (t -> ttype == TOK_IDENT) |
1525 { | |
1526 /* identifiers might need expansion to arguments */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1527 i = macro_arg(s, t -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1528 if (i != -1) |
296 | 1529 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1530 t3 = t -> next; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1531 for (t2 = exparglist[i] -> tail; t2; t2 = t2 -> prev) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1532 token_list_insert(expand_list, t, token_dup(t2)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1533 token_list_remove(t); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1534 t = t3; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1535 goto again; |
296 | 1536 } |
1537 } | |
1538 } | |
1539 | |
1540 /* put the new expansion in front of the input, if relevant; if we | |
1541 expanded to nothing, no need to create an expansion record or | |
1542 put anything into the input queue */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1543 if (expand_list -> head) |
296 | 1544 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1545 token_list_append(expand_list, token_create(TOK_ENDEXPAND, "", -1, -1, "")); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1546 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1547 // move the expanded list into the token queue |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1548 for (t = expand_list -> tail; t; t = t -> prev) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1549 preproc_unget_token(pp, token_dup(t)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1550 |
296 | 1551 /* set up expansion record */ |
1552 e = lw_alloc(sizeof(struct expand_e)); | |
1553 e -> next = pp -> expand_list; | |
1554 pp -> expand_list = e; | |
1555 e -> s = s; | |
1556 } | |
1557 | |
1558 /* now clean up */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1559 token_list_destroy(expand_list); |
296 | 1560 for (i = 0; i < nargs; i++) |
1561 { | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1562 token_list_destroy(arglist[i]); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1563 token_list_destroy(exparglist[i]); |
296 | 1564 } |
1565 lw_free(arglist); | |
1566 lw_free(exparglist); | |
1567 | |
1568 return 1; | |
1569 } | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1570 |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1571 struct token *preproc_next(struct preproc_info *pp) |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1572 { |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1573 struct token *t; |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1574 |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1575 t = preproc_next_processed_token(pp); |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1576 pp -> curtok = NULL; |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1577 return t; |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
301
diff
changeset
|
1578 } |