Mercurial > hg > index.cgi
comparison lwcc/cc-main.c @ 495:5b8871fd7503
Merged previous lwcc development branch into mainline.
author | William Astle <lost@l-w.ca> |
---|---|
date | Mon, 05 Aug 2019 21:27:09 -0600 |
parents | 41118fb0a8f2 |
children | a38542cf4cc6 |
comparison
equal
deleted
inserted
replaced
493:6073f4a33475 | 495:5b8871fd7503 |
---|---|
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> | |
27 | |
28 #include <lw_stringlist.h> | |
29 #include <lw_cmdline.h> | |
30 #include <lw_string.h> | |
31 | |
32 #include "cpp.h" | |
33 #include "tree.h" | |
34 | |
35 node_t *process_file(const char *); | |
36 static void do_error(const char *f, ...); | |
37 extern node_t *parse_program(struct preproc_info *pp); | |
38 | |
39 node_t *program_tree = NULL; | |
40 | |
41 /* command line option handling */ | |
42 #define PROGVER "lwcc-cc from " PACKAGE_STRING | |
43 char *program_name; | |
44 | |
45 /* input files */ | |
46 lw_stringlist_t input_files; | |
47 lw_stringlist_t includedirs; | |
48 lw_stringlist_t sysincludedirs; | |
49 lw_stringlist_t macrolist; | |
50 | |
51 /* various flags */ | |
52 int trigraphs = 0; | |
53 char *output_file = NULL; | |
54 FILE *output_fp = NULL; | |
55 | |
56 static struct lw_cmdline_options options[] = | |
57 { | |
58 { "output", 'o', "FILE", 0, "Output to FILE"}, | |
59 { "include", 'i', "FILE", 0, "Pre-include FILE" }, | |
60 { "includedir", 'I', "PATH", 0, "Add entry to the user include path" }, | |
61 { "sincludedir", 'S', "PATH", 0, "Add entry to the system include path" }, | |
62 { "define", 'D', "SYM[=VAL]",0, "Automatically define SYM to be VAL (or 1)"}, | |
63 { "trigraphs", 0x100, NULL, 0, "Enable interpretation of trigraphs" }, | |
64 { 0 } | |
65 }; | |
66 | |
67 static int parse_opts(int key, char *arg, void *state) | |
68 { | |
69 switch (key) | |
70 { | |
71 case 'o': | |
72 if (output_file) | |
73 do_error("Output file specified more than once."); | |
74 output_file = arg; | |
75 break; | |
76 | |
77 case 0x100: | |
78 trigraphs = 1; | |
79 break; | |
80 | |
81 case 'I': | |
82 lw_stringlist_addstring(includedirs, arg); | |
83 break; | |
84 | |
85 case 'S': | |
86 lw_stringlist_addstring(sysincludedirs, arg); | |
87 break; | |
88 | |
89 case 'D': | |
90 lw_stringlist_addstring(macrolist, arg); | |
91 break; | |
92 | |
93 case lw_cmdline_key_end: | |
94 break; | |
95 | |
96 case lw_cmdline_key_arg: | |
97 lw_stringlist_addstring(input_files, arg); | |
98 break; | |
99 | |
100 default: | |
101 return lw_cmdline_err_unknown; | |
102 } | |
103 return 0; | |
104 } | |
105 | |
106 static struct lw_cmdline_parser cmdline_parser = | |
107 { | |
108 options, | |
109 parse_opts, | |
110 "INPUTFILE", | |
111 "lwcc-cc - C compiler for lwcc", | |
112 PROGVER | |
113 }; | |
114 | |
115 int main(int argc, char **argv) | |
116 { | |
117 program_name = argv[0]; | |
118 int retval = 0; | |
119 node_t *n; | |
120 | |
121 input_files = lw_stringlist_create(); | |
122 includedirs = lw_stringlist_create(); | |
123 sysincludedirs = lw_stringlist_create(); | |
124 macrolist = lw_stringlist_create(); | |
125 | |
126 /* parse command line arguments */ | |
127 lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, NULL); | |
128 | |
129 /* set up output file */ | |
130 if (output_file == NULL || strcmp(output_file, "-") == 0) | |
131 { | |
132 output_fp = stdout; | |
133 } | |
134 else | |
135 { | |
136 output_fp = fopen(output_file, "wb"); | |
137 if (output_fp == NULL) | |
138 { | |
139 do_error("Failed to create output file %s: %s", output_file, strerror(errno)); | |
140 } | |
141 } | |
142 | |
143 program_tree = node_create(NODE_PROGRAM); | |
144 | |
145 if (lw_stringlist_nstrings(input_files) == 0) | |
146 { | |
147 /* if no input files, work on stdin */ | |
148 n = process_file("-"); | |
149 if (!n) | |
150 retval = 1; | |
151 else | |
152 node_addchild(program_tree, n); | |
153 } | |
154 else | |
155 { | |
156 char *s; | |
157 lw_stringlist_reset(input_files); | |
158 for (s = lw_stringlist_current(input_files); s; s = lw_stringlist_next(input_files)) | |
159 { | |
160 n = process_file(s); | |
161 if (!n) | |
162 retval = 1; | |
163 if (retval != 0) | |
164 break; | |
165 node_addchild(program_tree, n); | |
166 } | |
167 } | |
168 lw_stringlist_destroy(input_files); | |
169 lw_stringlist_destroy(includedirs); | |
170 lw_stringlist_destroy(sysincludedirs); | |
171 lw_stringlist_destroy(macrolist); | |
172 | |
173 node_display(program_tree, stdout); | |
174 node_destroy(program_tree); | |
175 exit(retval); | |
176 } | |
177 | |
178 node_t *process_file(const char *fn) | |
179 { | |
180 struct preproc_info *pp; | |
181 char *tstr; | |
182 node_t *n; | |
183 | |
184 pp = preproc_init(fn); | |
185 if (!pp) | |
186 return NULL; | |
187 | |
188 /* set up the include paths */ | |
189 lw_stringlist_reset(includedirs); | |
190 for (tstr = lw_stringlist_current(includedirs); tstr; tstr = lw_stringlist_next(includedirs)) | |
191 { | |
192 preproc_add_include(pp, tstr, 0); | |
193 } | |
194 | |
195 lw_stringlist_reset(sysincludedirs); | |
196 for (tstr = lw_stringlist_current(sysincludedirs); tstr; tstr = lw_stringlist_next(sysincludedirs)) | |
197 { | |
198 preproc_add_include(pp, tstr, 1); | |
199 } | |
200 | |
201 /* set up pre-defined macros */ | |
202 lw_stringlist_reset(macrolist); | |
203 for (tstr = lw_stringlist_current(macrolist); tstr; tstr = lw_stringlist_next(macrolist)) | |
204 { | |
205 preproc_add_macro(pp, tstr); | |
206 } | |
207 | |
208 n = parse_program(pp); | |
209 preproc_finish(pp); | |
210 return n; | |
211 } | |
212 | |
213 static void do_error(const char *f, ...) | |
214 { | |
215 va_list args; | |
216 va_start(args, f); | |
217 fprintf(stderr, "ERROR: "); | |
218 vfprintf(stderr, f, args); | |
219 va_end(args); | |
220 fprintf(stderr, "\n"); | |
221 exit(1); | |
222 } |