Mercurial > hg > index.cgi
annotate lwcc/cpp.c @ 306:b08787e5b9f3 ccdev
Add include search paths and command line macro definitions
Added command line macro definitions. Also implemented include paths. There
is no default include path; that will be supplied by the driver program.
author | William Astle <lost@l-w.ca> |
---|---|
date | Wed, 18 Sep 2013 20:41:41 -0600 |
parents | 54f213c8fb81 |
children | 670ea8f90212 |
rev | line source |
---|---|
295 | 1 /* |
2 lwcc/cpp.c | |
3 | |
4 Copyright © 2013 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <stdarg.h> | |
23 #include <stdio.h> | |
24 #include <stdlib.h> | |
25 #include <string.h> | |
26 | |
27 #include <lw_alloc.h> | |
28 #include <lw_string.h> | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
29 #include <lw_stringlist.h> |
295 | 30 |
31 #include "cpp.h" | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
32 #include "strpool.h" |
295 | 33 |
34 struct token *preproc_lex_next_token(struct preproc_info *); | |
35 | |
36 struct preproc_info *preproc_init(const char *fn) | |
37 { | |
38 FILE *fp; | |
39 struct preproc_info *pp; | |
40 | |
41 if (!fn || (fn[0] == '-' && fn[1] == '0')) | |
42 { | |
43 fp = stdin; | |
44 } | |
45 else | |
46 { | |
47 fp = fopen(fn, "rb"); | |
48 } | |
49 if (!fp) | |
50 return NULL; | |
51 | |
52 pp = lw_alloc(sizeof(struct preproc_info)); | |
53 memset(pp, 0, sizeof(struct preproc_info)); | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
54 pp -> strpool = strpool_create(); |
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
55 pp -> fn = strpool_strdup(pp -> strpool, fn); |
295 | 56 pp -> fp = fp; |
57 pp -> ra = CPP_NOUNG; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
58 pp -> unget = CPP_NOUNG; |
296 | 59 pp -> ppeolseen = 1; |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
60 pp -> lineno = 1; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
61 pp -> n = NULL; |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
62 pp -> quotelist = lw_stringlist_create(); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
63 pp -> inclist = lw_stringlist_create(); |
295 | 64 return pp; |
65 } | |
66 | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
67 void preproc_add_include(struct preproc_info *pp, char *dir, int sys) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
68 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
69 if (sys) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
70 lw_stringlist_addstring(pp -> inclist, dir); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
71 else |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
72 lw_stringlist_addstring(pp -> quotelist, dir); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
73 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
74 |
295 | 75 struct token *preproc_next_token(struct preproc_info *pp) |
76 { | |
77 struct token *t; | |
78 | |
296 | 79 if (pp -> curtok) |
80 token_free(pp -> curtok); | |
81 | |
82 /* | |
83 If there is a list of tokens to process, move it to the "unget" queue | |
84 with an EOF marker at the end of it. | |
85 */ | |
86 if (pp -> sourcelist) | |
87 { | |
88 for (t = pp -> sourcelist; t -> next; t = t -> next) | |
89 /* do nothing */ ; | |
90 t -> next = token_create(TOK_EOF, NULL, -1, -1, ""); | |
91 t -> next -> next = pp -> tokqueue; | |
92 pp -> tokqueue = pp -> sourcelist; | |
93 pp -> sourcelist = NULL; | |
94 } | |
95 again: | |
295 | 96 if (pp -> tokqueue) |
97 { | |
98 t = pp -> tokqueue; | |
99 pp -> tokqueue = t -> next; | |
100 if (pp -> tokqueue) | |
101 pp -> tokqueue -> prev = NULL; | |
102 t -> next = NULL; | |
103 t -> prev = NULL; | |
296 | 104 pp -> curtok = t; |
105 goto ret; | |
295 | 106 } |
296 | 107 pp -> curtok = preproc_lex_next_token(pp); |
108 t = pp -> curtok; | |
109 ret: | |
110 if (t -> ttype == TOK_ENDEXPAND) | |
111 { | |
112 struct expand_e *e; | |
113 e = pp -> expand_list; | |
114 pp -> expand_list = e -> next; | |
115 lw_free(e); | |
116 goto again; | |
117 } | |
118 return t; | |
119 } | |
120 | |
121 void preproc_unget_token(struct preproc_info *pp, struct token *t) | |
122 { | |
123 t -> next = pp -> tokqueue; | |
124 pp -> tokqueue = t; | |
125 if (pp -> curtok == t) | |
126 pp -> curtok = NULL; | |
295 | 127 } |
128 | |
129 void preproc_finish(struct preproc_info *pp) | |
130 { | |
131 fclose(pp -> fp); | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
132 lw_stringlist_destroy(pp -> inclist); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
133 lw_stringlist_destroy(pp -> quotelist); |
296 | 134 if (pp -> curtok) |
135 token_free(pp -> curtok); | |
136 while (pp -> tokqueue) | |
137 { | |
138 preproc_next_token(pp); | |
139 token_free(pp -> curtok); | |
140 } | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
141 strpool_free(pp -> strpool); |
295 | 142 lw_free(pp); |
143 } | |
144 | |
145 void preproc_register_error_callback(struct preproc_info *pp, void (*cb)(const char *)) | |
146 { | |
147 pp -> errorcb = cb; | |
148 } | |
149 | |
150 void preproc_register_warning_callback(struct preproc_info *pp, void (*cb)(const char *)) | |
151 { | |
152 pp -> warningcb = cb; | |
153 } | |
154 | |
155 static void preproc_throw_error_default(const char *m) | |
156 { | |
157 fprintf(stderr, "ERROR: %s\n", m); | |
158 } | |
159 | |
160 static void preproc_throw_warning_default(const char *m) | |
161 { | |
162 fprintf(stderr, "WARNING: %s\n", m); | |
163 } | |
164 | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
165 static void preproc_throw_message(struct preproc_info *pp, void (*cb)(const char *), const char *m, va_list args) |
295 | 166 { |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
167 int s, s2; |
295 | 168 char *b; |
169 | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
170 s2 = snprintf(NULL, 0, "(%s:%d:%d) ", pp -> fn, pp -> lineno, pp -> column); |
295 | 171 s = vsnprintf(NULL, 0, m, args); |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
172 b = lw_alloc(s + s2 + 1); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
173 snprintf(b, s2 + 1, "(%s:%d:%d) ", pp -> fn, pp -> lineno, pp -> column); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
174 vsnprintf(b + s2, s + 1, m, args); |
295 | 175 (*cb)(b); |
176 lw_free(b); | |
177 } | |
178 | |
179 void preproc_throw_error(struct preproc_info *pp, const char *m, ...) | |
180 { | |
181 va_list args; | |
182 va_start(args, m); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
183 preproc_throw_message(pp, pp -> errorcb ? pp -> errorcb : preproc_throw_error_default, m, args); |
295 | 184 va_end(args); |
185 exit(1); | |
186 } | |
187 | |
188 void preproc_throw_warning(struct preproc_info *pp, const char *m, ...) | |
189 { | |
190 va_list args; | |
191 va_start(args, m); | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
192 preproc_throw_message(pp, pp -> warningcb ? pp -> warningcb : preproc_throw_warning_default, m, args); |
295 | 193 va_end(args); |
194 } |