src/c2html.c

changeset 24
e43dee5892f4
parent 23
f44a185b678b
child 25
f82aa7afe872
equal deleted inserted replaced
23:f44a185b678b 24:e43dee5892f4
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*));
109 " -j Highlight Java instead of C source code\n" 107 " -j Highlight Java instead of C source code\n"
110 " -o <output> Output file (stdout, if not specified)\n" 108 " -o <output> Output file (stdout, if not specified)\n"
111 " -H <header> Prepend header file\n" 109 " -H <header> Prepend header file\n"
112 " -F <footer> Append footer file\n" 110 " -F <footer> Append footer file\n"
113 " -p Disable highlighting (plain text)\n" 111 " -p Disable highlighting (plain text)\n"
112 " -l Disable line numbers\n"
114 "\n"); 113 "\n");
115 114
116 115
117 } 116 }
118 117
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 }
168 break; 221 break;
169 case 'H': 222 case 'H':
170 settings.headerfile = optarg; 223 settings.headerfile = optarg;
171 break; 224 break;
172 case 'j': 225 case 'j':
173 highlighter.isdirective = isjdirective; 226 lang = C2HTML_JAVA;
174 highlighter.istype = isjtype;
175 highlighter.keywords = jkeywords;
176 highlighter.parser = jparseline;
177 break; 227 break;
178 case 'p': 228 case 'p':
179 settings.highlight = 0; 229 settings.highlight = 0;
230 break;
231 case 'l':
232 settings.showlinenumbers = 0;
180 break; 233 break;
181 case 'h': 234 case 'h':
182 printhelp(); 235 printhelp();
183 return 0; 236 return 0;
184 default: 237 default:
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);

mercurial