annotate lwcc/preproc.c @ 308:670ea8f90212 ccdev

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