30 #include <stdio.h> |
30 #include <stdio.h> |
31 #include <stdlib.h> |
31 #include <stdlib.h> |
32 #include <string.h> |
32 #include <string.h> |
33 #include <fcntl.h> |
33 #include <fcntl.h> |
34 #include <unistd.h> |
34 #include <unistd.h> |
35 #include "c2html.h" |
35 #include <ctype.h> |
|
36 |
|
37 #define INPUTBUF_SIZE 2048 |
|
38 |
|
39 |
|
40 typedef struct { |
|
41 size_t count; |
|
42 size_t capacity; |
|
43 size_t maxlinewidth; |
|
44 char** lines; |
|
45 } inputfile_t; |
36 |
46 |
37 inputfile_t *inputfilebuffer(size_t capacity) { |
47 inputfile_t *inputfilebuffer(size_t capacity) { |
38 inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t)); |
48 inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t)); |
39 inputfile->lines = (char**) malloc(capacity * sizeof(char*)); |
49 inputfile->lines = (char**) malloc(capacity * sizeof(char*)); |
40 inputfile->capacity = capacity; |
50 inputfile->capacity = capacity; |
41 inputfile->count = 0; |
51 inputfile->count = 0; |
|
52 inputfile->maxlinewidth = 0; |
42 |
53 |
43 return inputfile; |
54 return inputfile; |
44 } |
55 } |
45 |
56 |
46 void addline(inputfile_t *inputfile, char* line, size_t width) { |
57 void addline(inputfile_t *inputfile, char* line, size_t width) { |
50 if (inputfile->count >= inputfile->capacity) { |
61 if (inputfile->count >= inputfile->capacity) { |
51 inputfile->capacity <<= 1; |
62 inputfile->capacity <<= 1; |
52 inputfile->lines = realloc(inputfile->lines, inputfile->capacity); |
63 inputfile->lines = realloc(inputfile->lines, inputfile->capacity); |
53 } |
64 } |
54 inputfile->lines[inputfile->count] = l; |
65 inputfile->lines[inputfile->count] = l; |
|
66 inputfile->maxlinewidth = |
|
67 width > inputfile->maxlinewidth ? width : inputfile->maxlinewidth; |
55 inputfile->count++; |
68 inputfile->count++; |
56 } |
69 } |
57 |
70 |
58 void freeinputfilebuffer(inputfile_t *inputfile) { |
71 void freeinputfilebuffer(inputfile_t *inputfile) { |
59 for (int i = 0 ; i < inputfile->count ; i++) { |
72 for (int i = 0 ; i < inputfile->count ; i++) { |
68 int fd = open(filename, O_RDONLY); |
81 int fd = open(filename, O_RDONLY); |
69 if (fd == -1) return NULL; |
82 if (fd == -1) return NULL; |
70 |
83 |
71 inputfile_t *inputfile = inputfilebuffer(512); |
84 inputfile_t *inputfile = inputfilebuffer(512); |
72 |
85 |
73 const size_t bufsize = 1024; |
86 char buf[INPUTBUF_SIZE]; |
74 char buf[bufsize]; |
|
75 ssize_t r; |
87 ssize_t r; |
76 |
88 |
77 size_t maxlinewidth = 80; |
89 size_t maxlinewidth = 256; |
78 char *line = (char*) malloc(maxlinewidth); |
90 char *line = (char*) malloc(maxlinewidth); |
79 size_t col = 0; |
91 size_t col = 0; |
80 |
92 |
81 while ((r = read(fd, buf, bufsize)) > 0) { |
93 while ((r = read(fd, buf, INPUTBUF_SIZE)) > 0) { |
82 for (size_t i = 0 ; i < r ; i++) { |
94 for (size_t i = 0 ; i < r ; i++) { |
83 if (col >= maxlinewidth-4) { |
95 if (col >= maxlinewidth-4) { |
84 maxlinewidth <<= 1; |
96 maxlinewidth <<= 1; |
85 line = realloc(line, maxlinewidth); |
97 line = realloc(line, maxlinewidth); |
86 } |
98 } |
87 |
99 |
88 if (buf[i] == '\n') { |
100 if (buf[i] == '\n') { |
89 line[col] = 0; |
101 line[col] = 0; |
90 addline(inputfile, line, col); |
102 addline(inputfile, line, col); |
91 col = 0; |
103 col = 0; |
92 } else if (buf[i] == '<') { |
|
93 line[col++] = '&'; line[col++] = 'l'; |
|
94 line[col++] = 't'; line[col++] = ';'; |
|
95 } else if (buf[i] == '>') { |
|
96 line[col++] = '&'; line[col++] = 'g'; |
|
97 line[col++] = 't'; line[col++] = ';'; |
|
98 } else { |
104 } else { |
99 line[col++] = buf[i]; |
105 line[col++] = buf[i]; |
100 } |
106 } |
101 } |
107 } |
102 } |
108 } |
106 close(fd); |
112 close(fd); |
107 |
113 |
108 return inputfile; |
114 return inputfile; |
109 } |
115 } |
110 |
116 |
|
117 void parseline(char *src, char *dest) { |
|
118 size_t sp = 0, dp = 0; |
|
119 /* indent */ |
|
120 while (isspace(src[sp])) { |
|
121 dest[dp++] = src[sp++]; |
|
122 } |
|
123 for (char c = src[sp] ; c ; c=src[++sp]) { |
|
124 switch (c) { |
|
125 case '<': |
|
126 memcpy(&(dest[dp]), "<", 4); |
|
127 dp += 4; |
|
128 break; |
|
129 case '>': |
|
130 memcpy(&(dest[dp]), ">", 4); |
|
131 dp += 4; |
|
132 break; |
|
133 default: |
|
134 dest[dp++] = c; |
|
135 } |
|
136 } |
|
137 dest[dp] = 0; |
|
138 } |
|
139 |
111 void printhelp() { |
140 void printhelp() { |
112 printf("Formats source code using HTML.\n\nUsage:\n" |
141 printf("Formats source code using HTML.\n\nUsage:\n" |
113 " c2html [FILE...]" |
142 " c2html [FILE...]" |
114 "\n"); |
143 "\n"); |
115 |
144 |
116 |
145 |
117 } |
146 } |
118 |
147 |
119 int lnw(size_t lnc) { |
148 int lnint(size_t lnc) { |
120 int w = 1, p = 1; |
149 int w = 1, p = 1; |
121 while ((p*=10) < lnc) w++; |
150 while ((p*=10) < lnc) w++; |
122 return w; |
151 return w; |
123 } |
152 } |
124 |
153 |
130 } else { |
159 } else { |
131 |
160 |
132 inputfile_t *inputfile = readinput(argv[1]); |
161 inputfile_t *inputfile = readinput(argv[1]); |
133 if (inputfile) { |
162 if (inputfile) { |
134 printf("<pre>\n"); |
163 printf("<pre>\n"); |
|
164 char *line = (char*) malloc(inputfile->maxlinewidth*64); |
|
165 int lnw = lnint(inputfile->count); |
135 for (int i = 0 ; i < inputfile->count ; i++) { |
166 for (int i = 0 ; i < inputfile->count ; i++) { |
|
167 parseline(inputfile->lines[i], line); |
136 printf("<span class=\"c2html-lineno\">%*d:</span> %s\n", |
168 printf("<span class=\"c2html-lineno\">%*d:</span> %s\n", |
137 lnw(inputfile->count), i, inputfile->lines[i]); |
169 lnw, i, line); |
138 } |
170 } |
|
171 free(line); |
139 printf("</pre>\n"); |
172 printf("</pre>\n"); |
140 freeinputfilebuffer(inputfile); |
173 freeinputfilebuffer(inputfile); |
141 } |
174 } |
142 |
175 |
143 return 0; |
176 return 0; |