annotate lwcc/preproc.c @ 314:a3e277c58df9 ccdev

Checkpoint parser development for lwcc Beginning of lemon based parser for C including all the infrastructure for calling the lemon generated parser. This requires a translation layer from the preprocessor token numbers to the lemon parser token numbers due to the fact that lemon wants to control the token numbers. Eventually when the lemon parser gets replaced with a hand crafted recursive descent parser, this translation will no longer be required. However, in the interest of getting things working sooner rather than later, using something like lemon is beneficial.
author William Astle <lost@l-w.ca>
date Sun, 17 Nov 2013 11:59:36 -0700
parents 73b2bfa17ab0
children 836dc5371980
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 }
856caf91ffaa Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents: 298
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 }