annotate lwcc/preproc.c @ 494:836dc5371980 ccdev

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