1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2014 Mike Becker. All rights reserved. |
4 * Copyright 2015 Mike Becker. All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 * |
27 * |
28 */ |
28 */ |
29 #include <errno.h> |
|
30 |
|
31 #include "c2html.h" |
29 #include "c2html.h" |
32 |
30 |
33 inputfile_t *inputfilebuffer(size_t capacity) { |
31 inputfile_t *inputfilebuffer(size_t capacity) { |
34 inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t)); |
32 inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t)); |
35 inputfile->lines = (char**) malloc(capacity * sizeof(char*)); |
33 inputfile->lines = (char**) malloc(capacity * sizeof(char*)); |
135 fwrite(buf, 1, r, dest); |
134 fwrite(buf, 1, r, dest); |
136 } |
135 } |
137 fclose(src); |
136 fclose(src); |
138 return 0; |
137 return 0; |
139 } else { |
138 } else { |
140 return errno; |
139 return -1; |
141 } |
140 } |
|
141 } |
|
142 |
|
143 #define WRITECONST(stream, out, cstr) out(cstr, 1, sizeof(cstr)-1, stream) |
|
144 int formatfile( |
|
145 highlighter_t *highlighter, |
|
146 inputfile_t *in, |
|
147 fmt_write_func out, |
|
148 void *stream, |
|
149 _Bool showln) { |
|
150 // formats an input file and writes the result to out |
|
151 |
|
152 char *line = malloc(in->maxlinewidth*64); |
|
153 if(!line) { |
|
154 return 1; |
|
155 } |
|
156 WRITECONST(stream, out, "<pre>\n"); |
|
157 |
|
158 int lnw = lnint(in->count); |
|
159 for (int i = 0 ; i < in->count ; i++) { |
|
160 char *ln = line; |
|
161 if (highlighter) { |
|
162 highlighter->parser(in->lines[i], line, highlighter); |
|
163 } else { |
|
164 ln = in->lines[i]; |
|
165 } |
|
166 |
|
167 // write line number |
|
168 if (showln) { |
|
169 WRITECONST(stream, out, "<span class=\"c2html-lineno\">"); |
|
170 char lnbuf[16]; |
|
171 int len = snprintf(lnbuf, 16, "%*d ", lnw, i+1); |
|
172 out(lnbuf, 1, len, stream); |
|
173 WRITECONST(stream, out, "</span> "); |
|
174 } |
|
175 |
|
176 // write formated (or plain) code line |
|
177 out(ln, 1, strlen(ln), stream); |
|
178 } |
|
179 |
|
180 WRITECONST(stream, out, "</pre>\n"); |
|
181 free(line); |
|
182 return 0; |
|
183 } |
|
184 |
|
185 void init_c_highlighter(highlighter_t *highlighter) { |
|
186 memset(highlighter, 0, sizeof(highlighter_t)); |
|
187 highlighter->isdirective = iscdirective; |
|
188 highlighter->istype = isctype; |
|
189 highlighter->keywords = ckeywords; |
|
190 highlighter->parser = cparseline; |
|
191 } |
|
192 |
|
193 void init_java_highlighter(highlighter_t *highlighter) { |
|
194 memset(highlighter, 0, sizeof(highlighter_t)); |
|
195 highlighter->isdirective = isjdirective; |
|
196 highlighter->istype = isjtype; |
|
197 highlighter->keywords = jkeywords; |
|
198 highlighter->parser = jparseline; |
142 } |
199 } |
143 |
200 |
144 int main(int argc, char** argv) { |
201 int main(int argc, char** argv) { |
145 int retcode = EXIT_SUCCESS; |
202 int retcode = EXIT_SUCCESS; |
146 |
203 |
147 settings_t settings; |
204 settings_t settings; |
148 memset(&settings, 0, sizeof(settings)); |
205 memset(&settings, 0, sizeof(settings)); |
149 settings.highlight = 1; |
206 settings.highlight = 1; |
150 |
207 settings.showlinenumbers = 1; |
151 highlighter_t highlighter; |
208 |
152 memset(&highlighter, 0, sizeof(highlighter)); |
209 int lang = C2HTML_C; |
153 highlighter.isdirective = iscdirective; |
|
154 highlighter.istype = isctype; |
|
155 highlighter.keywords = ckeywords; |
|
156 highlighter.parser = cparseline; |
|
157 |
210 |
158 char optc; |
211 char optc; |
159 while ((optc = getopt(argc, argv, "hjo:pH:F:")) != -1) { |
212 while ((optc = getopt(argc, argv, "hljo:pH:F:")) != -1) { |
160 switch (optc) { |
213 switch (optc) { |
161 case 'o': |
214 case 'o': |
162 if (!(optarg[0] == '-' && optarg[1] == 0)) { |
215 if (!(optarg[0] == '-' && optarg[1] == 0)) { |
163 settings.outfilename = optarg; |
216 settings.outfilename = optarg; |
164 } |
217 } |
194 FILE *fout; |
247 FILE *fout; |
195 if (settings.outfilename) { |
248 if (settings.outfilename) { |
196 fout = fopen(settings.outfilename, "w"); |
249 fout = fopen(settings.outfilename, "w"); |
197 if (!fout) { |
250 if (!fout) { |
198 perror("Error opening output file"); |
251 perror("Error opening output file"); |
199 return errno; |
252 return -1; |
200 } |
253 } |
201 } else { |
254 } else { |
202 fout = stdout; |
255 fout = stdout; |
203 } |
256 } |
204 |
257 |
205 if (copyfile(settings.headerfile, fout)) { |
258 if (copyfile(settings.headerfile, fout)) { |
206 perror("Error opening header file"); |
259 perror("Error opening header file"); |
207 retcode = errno; |
260 retcode = -1; |
208 goto prog_end; |
261 goto prog_end; |
|
262 } |
|
263 |
|
264 highlighter_t highlighter; |
|
265 highlighter_t *hptr = &highlighter; |
|
266 switch (lang) { |
|
267 case C2HTML_C: |
|
268 init_c_highlighter(&highlighter); |
|
269 break; |
|
270 case C2HTML_JAVA: |
|
271 init_java_highlighter(&highlighter); |
|
272 break; |
|
273 default: |
|
274 hptr = NULL; |
|
275 break; |
|
276 } |
|
277 if (!settings.highlight) { |
|
278 hptr = NULL; |
209 } |
279 } |
210 |
280 |
211 inputfile_t *inputfile = readinput(settings.infilename); |
281 inputfile_t *inputfile = readinput(settings.infilename); |
212 if (inputfile) { |
282 if (inputfile) { |
213 char *line; |
283 formatfile( |
214 if (settings.highlight) { |
284 hptr, |
215 line = (char*) malloc(inputfile->maxlinewidth*64); |
285 inputfile, |
216 } else { |
286 (fmt_write_func)fwrite, |
217 line = NULL; |
287 fout, |
218 } |
288 settings.showlinenumbers); |
219 fprintf(fout, "<pre>\n"); |
|
220 int lnw = lnint(inputfile->count); |
|
221 for (int i = 0 ; i < inputfile->count ; i++) { |
|
222 if (settings.highlight) { |
|
223 highlighter.parser(inputfile->lines[i], line, &highlighter); |
|
224 } else { |
|
225 line = inputfile->lines[i]; |
|
226 } |
|
227 fprintf(fout, "<span class=\"c2html-lineno\">%*d:</span> %s", |
|
228 lnw, i+1, line); |
|
229 } |
|
230 if (settings.highlight) { |
|
231 free(line); |
|
232 } |
|
233 fprintf(fout, "</pre>\n"); |
|
234 |
|
235 freeinputfilebuffer(inputfile); |
|
236 |
|
237 if (copyfile(settings.footerfile, fout)) { |
|
238 perror("Error opening footer file"); |
|
239 retcode = errno; |
|
240 } |
|
241 } else { |
289 } else { |
242 perror("Error opening input file"); |
290 perror("Error opening input file"); |
243 retcode = errno; |
291 retcode = -1; |
|
292 } |
|
293 |
|
294 if (copyfile(settings.footerfile, fout)) { |
|
295 perror("Error opening footer file"); |
|
296 retcode = -1; |
244 } |
297 } |
245 |
298 |
246 prog_end: |
299 prog_end: |
247 if (fout != stdout) { |
300 if (fout != stdout) { |
248 fclose(fout); |
301 fclose(fout); |