Thu, 23 Jan 2014 14:17:06 +0100
added command line parameters for header and footer file
1 #include <errno.h>
3 #include "c2html.h"
5 inputfile_t *inputfilebuffer(size_t capacity) {
6 inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t));
7 inputfile->lines = (char**) malloc(capacity * sizeof(char*));
8 inputfile->capacity = capacity;
9 inputfile->count = 0;
10 inputfile->maxlinewidth = 0;
12 return inputfile;
13 }
15 void addline(inputfile_t *inputfile, char* line, size_t width) {
16 char *l = (char*) malloc(width+1);
17 memcpy(l, line, width);
18 l[width] = 0;
19 if (inputfile->count >= inputfile->capacity) {
20 inputfile->capacity <<= 1;
21 inputfile->lines = realloc(inputfile->lines, inputfile->capacity);
22 }
23 inputfile->lines[inputfile->count] = l;
24 inputfile->maxlinewidth =
25 width > inputfile->maxlinewidth ? width : inputfile->maxlinewidth;
26 inputfile->count++;
27 }
29 void freeinputfilebuffer(inputfile_t *inputfile) {
30 for (int i = 0 ; i < inputfile->count ; i++) {
31 free(inputfile->lines[i]);
32 }
33 free(inputfile->lines);
34 free(inputfile);
35 }
37 inputfile_t *readinput(char *filename) {
39 int fd = open(filename, O_RDONLY);
40 if (fd == -1) return NULL;
42 inputfile_t *inputfile = inputfilebuffer(512);
44 char buf[INPUTBUF_SIZE];
45 ssize_t r;
47 size_t maxlinewidth = 256;
48 char *line = (char*) malloc(maxlinewidth);
49 size_t col = 0;
51 while ((r = read(fd, buf, INPUTBUF_SIZE)) > 0) {
52 for (size_t i = 0 ; i < r ; i++) {
53 if (col >= maxlinewidth-4) {
54 maxlinewidth <<= 1;
55 line = realloc(line, maxlinewidth);
56 }
58 if (buf[i] == '\n') {
59 line[col++] = '\n';
60 line[col] = 0;
61 addline(inputfile, line, col);
62 col = 0;
63 } else {
64 line[col++] = buf[i];
65 }
66 }
67 }
69 free(line);
71 close(fd);
73 return inputfile;
74 }
76 void printhelp() {
77 printf("Formats source code using HTML.\n\nUsage:\n"
78 " c2html [Options] FILE\n\n"
79 " Options:\n"
80 " -h Prints this help message\n"
81 " -j Highlight Java instead of C source code\n"
82 " -o <output> Output file (stdout, if not specified)\n"
83 " -H <header> Prepend header file\n"
84 " -F <footer> Append footer file\n"
85 " -p Disable highlighting (plain text)\n"
86 "\n");
89 }
91 int lnint(size_t lnc) {
92 int w = 1, p = 1;
93 while ((p*=10) < lnc) w++;
94 return w;
95 }
97 int copyfile(char *filename, FILE *dest) {
98 if (!filename) {
99 return 0;
100 }
102 FILE *src = fopen(filename, "r");
103 if (src) {
104 char buf[4096];
105 int r;
106 while ((r = fread(buf, 1, 4096, src)) > 0) {
107 fwrite(buf, 1, r, dest);
108 }
109 fclose(src);
110 return 0;
111 } else {
112 return errno;
113 }
114 }
116 int main(int argc, char** argv) {
117 int retcode = EXIT_SUCCESS;
119 settings_t settings;
120 memset(&settings, 0, sizeof(settings));
121 settings.highlight = 1;
123 highlighter_t highlighter;
124 memset(&highlighter, 0, sizeof(highlighter));
125 highlighter.isdirective = iscdirective;
126 highlighter.istype = isctype;
127 highlighter.keywords = ckeywords;
128 highlighter.parser = cparseline;
130 char optc;
131 while ((optc = getopt(argc, argv, "hjo:pH:F:")) != -1) {
132 switch (optc) {
133 case 'o':
134 if (!(optarg[0] == '-' && optarg[1] == 0)) {
135 settings.outfilename = optarg;
136 }
137 break;
138 case 'F':
139 settings.footerfile = optarg;
140 break;
141 case 'H':
142 settings.headerfile = optarg;
143 break;
144 case 'j':
145 highlighter.isdirective = isjdirective;
146 highlighter.istype = isjtype;
147 highlighter.keywords = jkeywords;
148 highlighter.parser = jparseline;
149 break;
150 case 'p':
151 settings.highlight = 0;
152 break;
153 case 'h':
154 printhelp();
155 return 0;
156 default:
157 return 1;
158 }
159 }
161 if (optind != argc-1) {
162 printhelp();
163 return 1;
164 } else {
165 settings.infilename = argv[optind];
166 FILE *fout;
167 if (settings.outfilename) {
168 fout = fopen(settings.outfilename, "w");
169 if (!fout) {
170 perror("Error opening output file");
171 return errno;
172 }
173 } else {
174 fout = stdout;
175 }
177 if (copyfile(settings.headerfile, fout)) {
178 perror("Error opening header file");
179 retcode = errno;
180 goto prog_end;
181 }
183 inputfile_t *inputfile = readinput(settings.infilename);
184 if (inputfile) {
185 char *line;
186 if (settings.highlight) {
187 line = (char*) malloc(inputfile->maxlinewidth*64);
188 } else {
189 line = NULL;
190 }
191 fprintf(fout, "<pre>\n");
192 int lnw = lnint(inputfile->count);
193 for (int i = 0 ; i < inputfile->count ; i++) {
194 if (settings.highlight) {
195 highlighter.parser(inputfile->lines[i], line, &highlighter);
196 } else {
197 line = inputfile->lines[i];
198 }
199 fprintf(fout, "<span class=\"c2html-lineno\">%*d:</span> %s",
200 lnw, i+1, line);
201 }
202 if (settings.highlight) {
203 free(line);
204 }
205 fprintf(fout, "</pre>\n");
207 freeinputfilebuffer(inputfile);
209 if (copyfile(settings.footerfile, fout)) {
210 perror("Error opening footer file");
211 retcode = errno;
212 }
213 } else {
214 perror("Error opening input file");
215 retcode = errno;
216 }
218 prog_end:
219 if (fout != stdout) {
220 fclose(fout);
221 }
223 return retcode;
224 }
225 }