Mercurial > hg > index.cgi
annotate lwcc/cpp-main.c @ 305:54f213c8fb81 ccdev
Various bugfixes and output tuning
Tuned output of preprocessor to include line markers similar to the ones
added by the gcc preprocessor.
Also, many fixes for various bits of dumbosity leading to misbehaviour and
crashing.
author | William Astle <lost@l-w.ca> |
---|---|
date | Wed, 18 Sep 2013 19:17:52 -0600 |
parents | d85d173ba120 |
children | b08787e5b9f3 |
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> | |
27 | |
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; | |
43 | |
44 /* various flags */ | |
45 int trigraphs = 0; | |
46 char *output_file = NULL; | |
47 FILE *output_fp = NULL; | |
48 | |
49 static struct lw_cmdline_options options[] = | |
50 { | |
51 { "output", 'o', "FILE", 0, "Output to FILE"}, | |
52 { "include", 'i', "FILE", 0, "Pre-include FILE" }, | |
53 { "includedir", 'I', "PATH", 0, "Add entry to the user include path" }, | |
54 { "sincludedir", 'S', "PATH", 0, "Add entry to the system include path" }, | |
55 { "define", 'D', "SYM[=VAL]",0, "Automatically define SYM to be VAL (or 1)"}, | |
56 { "trigraphs", 0x100, NULL, 0, "Enable interpretation of trigraphs" }, | |
57 { 0 } | |
58 }; | |
59 | |
60 static int parse_opts(int key, char *arg, void *state) | |
61 { | |
62 switch (key) | |
63 { | |
64 case 'o': | |
65 if (output_file) | |
66 do_error("Output file specified more than once."); | |
67 output_file = arg; | |
68 break; | |
69 | |
70 case 0x100: | |
71 trigraphs = 1; | |
72 break; | |
73 | |
74 case lw_cmdline_key_end: | |
75 break; | |
76 | |
77 case lw_cmdline_key_arg: | |
78 lw_stringlist_addstring(input_files, arg); | |
79 break; | |
80 | |
81 default: | |
82 return lw_cmdline_err_unknown; | |
83 } | |
84 return 0; | |
85 } | |
86 | |
87 static struct lw_cmdline_parser cmdline_parser = | |
88 { | |
89 options, | |
90 parse_opts, | |
91 "INPUTFILE", | |
92 "lwcc-cpp - C preprocessor for lwcc", | |
93 PROGVER | |
94 }; | |
95 | |
96 int main(int argc, char **argv) | |
97 { | |
98 program_name = argv[0]; | |
99 int retval = 0; | |
100 | |
101 input_files = lw_stringlist_create(); | |
102 | |
103 /* parse command line arguments */ | |
104 lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, NULL); | |
105 | |
106 /* set up output file */ | |
107 if (output_file == NULL || strcmp(output_file, "-") == 0) | |
108 { | |
109 output_fp = stdout; | |
110 } | |
111 else | |
112 { | |
113 output_fp = fopen(output_file, "wb"); | |
114 if (output_fp == NULL) | |
115 { | |
116 do_error("Failed to create output file %s: %s", output_file, strerror(errno)); | |
117 } | |
118 } | |
119 | |
120 if (lw_stringlist_nstrings(input_files) == 0) | |
121 { | |
122 /* if no input files, work on stdin */ | |
123 retval = process_file("-"); | |
124 } | |
125 else | |
126 { | |
127 char *s; | |
128 lw_stringlist_reset(input_files); | |
129 for (s = lw_stringlist_current(input_files); s; s = lw_stringlist_next(input_files)) | |
130 { | |
131 retval = process_file(s); | |
132 if (retval != 0) | |
133 break; | |
134 } | |
135 } | |
136 lw_stringlist_destroy(input_files); | |
137 | |
138 exit(retval); | |
139 } | |
140 | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
141 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
|
142 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
143 fprintf(fp, "\n# %d \"", line); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
144 while (*fn) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
145 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
146 if (*fn < 32 || *fn == 34 || *fn > 126) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
147 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
148 fprintf(fp, "\\%03o", *fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
149 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
150 else |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
151 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
152 fprintf(fp, "%c", *fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
153 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
154 fn++; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
155 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
156 fprintf(fp, "\" %d\n", flag); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
157 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
158 |
295 | 159 int process_file(const char *fn) |
160 { | |
161 struct preproc_info *pp; | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
162 struct token *tok = NULL; |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
163 int last_line = 0; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
164 char *last_fn = NULL; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
165 |
295 | 166 pp = preproc_init(fn); |
167 if (!pp) | |
168 return -1; | |
305
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 print_line_marker(output_fp, 1, fn, 1); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
171 last_fn = lw_strdup(fn); |
295 | 172 for (;;) |
173 { | |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
174 tok = preproc_next(pp); |
295 | 175 if (tok -> ttype == TOK_EOF) |
176 break; | |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
177 if (strcmp(tok -> fn, last_fn) != 0) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
178 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
179 int lt = 1; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
180 if (tok -> lineno != 1) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
181 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
182 lt = 2; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
183 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
184 lw_free(last_fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
185 last_fn = lw_strdup(tok -> fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
186 last_line = tok -> lineno; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
187 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
|
188 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
189 else |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
190 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
191 while (tok -> lineno > last_line) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
192 { |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
193 fprintf(output_fp, "\n"); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
194 last_line++; |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
195 } |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
196 } |
295 | 197 token_print(tok, output_fp); |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
198 if (tok -> ttype == TOK_EOL) |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
199 last_line++; |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
200 token_free(tok); |
295 | 201 } |
304
d85d173ba120
Checkpoint lwcc development - preprocessor is runnable but nonfunctional
William Astle <lost@l-w.ca>
parents:
295
diff
changeset
|
202 token_free(tok); |
305
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
203 lw_free(last_fn); |
54f213c8fb81
Various bugfixes and output tuning
William Astle <lost@l-w.ca>
parents:
304
diff
changeset
|
204 // symtab_dump(pp); |
295 | 205 preproc_finish(pp); |
206 return 0; | |
207 } | |
208 | |
209 static void do_error(const char *f, ...) | |
210 { | |
211 va_list args; | |
212 va_start(args, f); | |
213 fprintf(stderr, "ERROR: "); | |
214 vfprintf(stderr, f, args); | |
215 va_end(args); | |
216 fprintf(stderr, "\n"); | |
217 exit(1); | |
218 } |