Mercurial > hg > index.cgi
annotate lwcc/cpp-main.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 | a38542cf4cc6 |
rev | line source |
---|---|
295 | 1 /* |
2 lwcc/cpp-main.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 <errno.h> | |
23 #include <stdarg.h> | |
24 #include <stdio.h> | |
25 #include <stdlib.h> | |
26 #include <string.h> | |
313 | 27 #include <lw_alloc.h> |
295 | 28 #include <lw_stringlist.h> |
29 #include <lw_cmdline.h> | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
30 #include <lw_string.h> |
295 | 31 |
32 #include "cpp.h" | |
33 | |
34 int process_file(const char *); | |
35 static void do_error(const char *f, ...); | |
36 | |
37 /* command line option handling */ | |
38 #define PROGVER "lwcc-cpp from " PACKAGE_STRING | |
39 char *program_name; | |
40 | |
41 /* input files */ | |
42 lw_stringlist_t input_files; | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
43 lw_stringlist_t includedirs; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
44 lw_stringlist_t sysincludedirs; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
45 lw_stringlist_t macrolist; |
295 | 46 |
47 /* various flags */ | |
48 int trigraphs = 0; | |
49 char *output_file = NULL; | |
50 FILE *output_fp = NULL; | |
51 | |
52 static struct lw_cmdline_options options[] = | |
53 { | |
54 { "output", 'o', "FILE", 0, "Output to FILE"}, | |
55 { "include", 'i', "FILE", 0, "Pre-include FILE" }, | |
56 { "includedir", 'I', "PATH", 0, "Add entry to the user include path" }, | |
57 { "sincludedir", 'S', "PATH", 0, "Add entry to the system include path" }, | |
58 { "define", 'D', "SYM[=VAL]",0, "Automatically define SYM to be VAL (or 1)"}, | |
59 { "trigraphs", 0x100, NULL, 0, "Enable interpretation of trigraphs" }, | |
60 { 0 } | |
61 }; | |
62 | |
63 static int parse_opts(int key, char *arg, void *state) | |
64 { | |
65 switch (key) | |
66 { | |
67 case 'o': | |
68 if (output_file) | |
69 do_error("Output file specified more than once."); | |
70 output_file = arg; | |
71 break; | |
72 | |
73 case 0x100: | |
74 trigraphs = 1; | |
75 break; | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
76 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
77 case 'I': |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
78 lw_stringlist_addstring(includedirs, arg); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
79 break; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
80 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
81 case 'S': |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
82 lw_stringlist_addstring(sysincludedirs, arg); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
83 break; |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
84 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
85 case 'D': |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
86 lw_stringlist_addstring(macrolist, arg); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
87 break; |
295 | 88 |
89 case lw_cmdline_key_end: | |
90 break; | |
91 | |
92 case lw_cmdline_key_arg: | |
93 lw_stringlist_addstring(input_files, arg); | |
94 break; | |
95 | |
96 default: | |
97 return lw_cmdline_err_unknown; | |
98 } | |
99 return 0; | |
100 } | |
101 | |
102 static struct lw_cmdline_parser cmdline_parser = | |
103 { | |
104 options, | |
105 parse_opts, | |
106 "INPUTFILE", | |
107 "lwcc-cpp - C preprocessor for lwcc", | |
108 PROGVER | |
109 }; | |
110 | |
111 int main(int argc, char **argv) | |
112 { | |
113 program_name = argv[0]; | |
114 int retval = 0; | |
115 | |
116 input_files = lw_stringlist_create(); | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
117 includedirs = lw_stringlist_create(); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
118 sysincludedirs = lw_stringlist_create(); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
119 macrolist = lw_stringlist_create(); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
120 |
295 | 121 /* parse command line arguments */ |
122 lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, NULL); | |
123 | |
124 /* set up output file */ | |
125 if (output_file == NULL || strcmp(output_file, "-") == 0) | |
126 { | |
127 output_fp = stdout; | |
128 } | |
129 else | |
130 { | |
131 output_fp = fopen(output_file, "wb"); | |
132 if (output_fp == NULL) | |
133 { | |
134 do_error("Failed to create output file %s: %s", output_file, strerror(errno)); | |
135 } | |
136 } | |
137 | |
138 if (lw_stringlist_nstrings(input_files) == 0) | |
139 { | |
140 /* if no input files, work on stdin */ | |
141 retval = process_file("-"); | |
142 } | |
143 else | |
144 { | |
145 char *s; | |
146 lw_stringlist_reset(input_files); | |
147 for (s = lw_stringlist_current(input_files); s; s = lw_stringlist_next(input_files)) | |
148 { | |
149 retval = process_file(s); | |
150 if (retval != 0) | |
151 break; | |
152 } | |
153 } | |
154 lw_stringlist_destroy(input_files); | |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
155 lw_stringlist_destroy(includedirs); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
156 lw_stringlist_destroy(sysincludedirs); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
157 lw_stringlist_destroy(macrolist); |
295 | 158 exit(retval); |
159 } | |
160 | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
161 static void print_line_marker(FILE *fp, int line, const char *fn, int flag) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
162 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
163 fprintf(fp, "\n# %d \"", line); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
164 while (*fn) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
165 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
166 if (*fn < 32 || *fn == 34 || *fn > 126) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
167 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
168 fprintf(fp, "\\%03o", *fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
169 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
170 else |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
171 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
172 fprintf(fp, "%c", *fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
173 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
174 fn++; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
175 } |
307
9e342c4e4b66
Added support for __LINE__, __FILE__, __DATE__, and __TIME__
William Astle <lost@l-w.ca>
parents:
306
diff
changeset
|
176 fprintf(fp, "\" %d", flag); |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
177 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
178 |
295 | 179 int process_file(const char *fn) |
180 { | |
181 struct preproc_info *pp; | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
182 struct token *tok = NULL; |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
183 int last_line = 0; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
184 char *last_fn = NULL; |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
185 char *tstr; |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
186 |
295 | 187 pp = preproc_init(fn); |
188 if (!pp) | |
189 return -1; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
190 |
306
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
191 /* set up the include paths */ |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
192 lw_stringlist_reset(includedirs); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
193 for (tstr = lw_stringlist_current(includedirs); tstr; tstr = lw_stringlist_next(includedirs)) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
194 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
195 preproc_add_include(pp, tstr, 0); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
196 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
197 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
198 lw_stringlist_reset(sysincludedirs); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
199 for (tstr = lw_stringlist_current(sysincludedirs); tstr; tstr = lw_stringlist_next(sysincludedirs)) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
200 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
201 preproc_add_include(pp, tstr, 1); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
202 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
203 |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
204 /* set up pre-defined macros */ |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
205 lw_stringlist_reset(macrolist); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
206 for (tstr = lw_stringlist_current(macrolist); tstr; tstr = lw_stringlist_next(macrolist)) |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
207 { |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
208 preproc_add_macro(pp, tstr); |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
209 } |
b08787e5b9f3
Add include search paths and command line macro definitions
William Astle <lost@l-w.ca>
parents:
305
diff
changeset
|
210 |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
211 print_line_marker(output_fp, 1, fn, 1); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
212 last_fn = lw_strdup(fn); |
295 | 213 for (;;) |
214 { | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
215 tok = preproc_next(pp); |
295 | 216 if (tok -> ttype == TOK_EOF) |
217 break; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
218 if (strcmp(tok -> fn, last_fn) != 0) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
219 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
220 int lt = 1; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
221 if (tok -> lineno != 1) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
222 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
223 lt = 2; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
224 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
225 lw_free(last_fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
226 last_fn = lw_strdup(tok -> fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
227 last_line = tok -> lineno; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
228 print_line_marker(output_fp, last_line, last_fn, lt); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
229 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
230 else |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
231 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
232 while (tok -> lineno > last_line) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
233 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
234 fprintf(output_fp, "\n"); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
235 last_line++; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
236 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
237 } |
295 | 238 token_print(tok, output_fp); |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
239 if (tok -> ttype == TOK_EOL) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
240 last_line++; |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
241 token_free(tok); |
295 | 242 } |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
243 token_free(tok); |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
244 lw_free(last_fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
245 // symtab_dump(pp); |
295 | 246 preproc_finish(pp); |
247 return 0; | |
248 } | |
249 | |
250 static void do_error(const char *f, ...) | |
251 { | |
252 va_list args; | |
253 va_start(args, f); | |
254 fprintf(stderr, "ERROR: "); | |
255 vfprintf(stderr, f, args); | |
256 va_end(args); | |
257 fprintf(stderr, "\n"); | |
258 exit(1); | |
259 } |