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