71 |
71 |
72 int isjdirective(char *word) { |
72 int isjdirective(char *word) { |
73 return word[0] == '@'; |
73 return word[0] == '@'; |
74 } |
74 } |
75 |
75 |
76 typedef struct { |
76 typedef struct _highlighter_t highlighter_t; |
|
77 |
|
78 struct _highlighter_t { |
77 const char** keywords; |
79 const char** keywords; |
78 int(*istype)(char*,size_t); |
80 int(*istype)(char*,size_t); |
79 int(*isdirective)(char*); |
81 int(*isdirective)(char*); |
80 } highlighter_t; |
82 void(*parser)(char*,char*,highlighter_t*); |
|
83 int iscommentml; |
|
84 char word[WORDBUF_SIZE]; |
|
85 char includefile[FILENAME_MAX]; |
|
86 }; |
81 |
87 |
82 typedef struct { |
88 typedef struct { |
83 char* outfilename; |
89 char* outfilename; |
84 char* infilename; |
90 char* infilename; |
85 int highlight; |
91 int highlight; |
191 } |
197 } |
192 } |
198 } |
193 return 1; |
199 return 1; |
194 } |
200 } |
195 |
201 |
196 void parseline(char *src, char *dest, highlighter_t *highlighter) { |
202 void parseline(char *src, char *dest, highlighter_t *hltr) { |
|
203 hltr->parser(src, dest, hltr); |
|
204 } |
|
205 |
|
206 void cjparseline(char *src, char *dest, highlighter_t *hltr) { |
197 size_t sp = 0, dp = 0; |
207 size_t sp = 0, dp = 0; |
198 /* indent */ |
208 /* indent */ |
199 while (isspace(src[sp])) { |
209 while (isspace(src[sp])) { |
200 dest[dp++] = src[sp++]; |
210 dest[dp++] = src[sp++]; |
201 } |
211 } |
202 |
212 |
203 static char word[WORDBUF_SIZE]; |
213 memset(hltr->word, 0, WORDBUF_SIZE); |
204 static char includefile[FILENAME_MAX]; |
|
205 |
|
206 memset(word, 0, WORDBUF_SIZE); |
|
207 size_t wp = 0, ifp = 0; |
214 size_t wp = 0, ifp = 0; |
208 int isstring = 0, iscomment = 0, isinclude = 0, parseinclude = 0; |
215 int isstring = 0, iscomment = 0, isinclude = 0, parseinclude = 0; |
209 static int iscommentml; |
|
210 int isescaping = 0; |
216 int isescaping = 0; |
211 |
217 |
212 if (iscommentml) { |
218 if (hltr->iscommentml) { |
213 iscomment = 1; |
219 iscomment = 1; |
214 memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); |
220 memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); |
215 dp += 29; |
221 dp += 29; |
216 } |
222 } |
217 |
223 |
218 for (char c = src[sp] ; c ; c=src[++sp]) { |
224 for (char c = src[sp] ; c ; c=src[++sp]) { |
219 /* comments */ |
225 /* comments */ |
220 if (c == '/') { |
226 if (c == '/') { |
221 if (iscommentml && sp > 0 && src[sp-1] == '*') { |
227 if (hltr->iscommentml && sp > 0 && src[sp-1] == '*') { |
222 iscomment = 0; |
228 iscomment = 0; |
223 iscommentml = 0; |
229 hltr->iscommentml = 0; |
224 memcpy(&(dest[dp]), "/</span>", 8); |
230 memcpy(&(dest[dp]), "/</span>", 8); |
225 dp += 8; |
231 dp += 8; |
226 continue; |
232 continue; |
227 } else if (!iscomment && (src[sp+1] == '/' || src[sp+1] == '*')) { |
233 } else if (!iscomment && (src[sp+1] == '/' || src[sp+1] == '*')) { |
228 iscomment = 1; |
234 iscomment = 1; |
229 iscommentml = (src[sp+1] == '*'); |
235 hltr->iscommentml = (src[sp+1] == '*'); |
230 memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); |
236 memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); |
231 dp += 29; |
237 dp += 29; |
232 } |
238 } |
233 } |
239 } |
234 |
240 |
245 dp = writeescapedchar(dest, dp, c); |
251 dp = writeescapedchar(dest, dp, c); |
246 } else if (c == '\"') { |
252 } else if (c == '\"') { |
247 if (parseinclude) { |
253 if (parseinclude) { |
248 dest[dp++] = '\"'; |
254 dest[dp++] = '\"'; |
249 dest[dp++] = '>'; |
255 dest[dp++] = '>'; |
250 memcpy(&(dest[dp]), includefile, ifp); |
256 memcpy(&(dest[dp]), hltr->includefile, ifp); |
251 dp += ifp; |
257 dp += ifp; |
252 |
258 |
253 dp = writeescapedchar(dest, dp, c); |
259 dp = writeescapedchar(dest, dp, c); |
254 memcpy(&(dest[dp]), "</a>", 4); |
260 memcpy(&(dest[dp]), "</a>", 4); |
255 dp += 4; |
261 dp += 4; |
258 memcpy(&(dest[dp]), |
264 memcpy(&(dest[dp]), |
259 "<a class=\"c2html-userinclude\" href=", 35); |
265 "<a class=\"c2html-userinclude\" href=", 35); |
260 dp += 35; |
266 dp += 35; |
261 dp = writeescapedchar(dest, dp, c); |
267 dp = writeescapedchar(dest, dp, c); |
262 ifp = 0; |
268 ifp = 0; |
263 includefile[ifp++] = '\"'; |
269 hltr->includefile[ifp++] = '\"'; |
264 parseinclude = 1; |
270 parseinclude = 1; |
265 } |
271 } |
266 } else if (c == '>') { |
272 } else if (c == '>') { |
267 dp = writeescapedchar(dest, dp, c); |
273 dp = writeescapedchar(dest, dp, c); |
268 memcpy(&(dest[dp]), "</span>", 7); |
274 memcpy(&(dest[dp]), "</span>", 7); |
269 dp += 7; |
275 dp += 7; |
270 } else { |
276 } else { |
271 if (parseinclude) { |
277 if (parseinclude) { |
272 includefile[ifp++] = c; |
278 hltr->includefile[ifp++] = c; |
273 } |
279 } |
274 dp = writeescapedchar(dest, dp, c); |
280 dp = writeescapedchar(dest, dp, c); |
275 } |
281 } |
276 } else { |
282 } else { |
277 /* strings */ |
283 /* strings */ |
291 dp = writeescapedchar(dest, dp, c); |
297 dp = writeescapedchar(dest, dp, c); |
292 } else if (!iswordcharacter(c)) { |
298 } else if (!iswordcharacter(c)) { |
293 /* interpret word int_t */ |
299 /* interpret word int_t */ |
294 if (wp > 0 && wp < WORDBUF_SIZE) { |
300 if (wp > 0 && wp < WORDBUF_SIZE) { |
295 int closespan = 1; |
301 int closespan = 1; |
296 if (iskeyword(word, highlighter->keywords)) { |
302 if (iskeyword(hltr->word, hltr->keywords)) { |
297 memcpy(&(dest[dp]), |
303 memcpy(&(dest[dp]), |
298 "<span class=\"c2html-keyword\">", 29); |
304 "<span class=\"c2html-keyword\">", 29); |
299 dp += 29; |
305 dp += 29; |
300 } else if (highlighter->istype(word, wp)) { |
306 } else if (hltr->istype(hltr->word, wp)) { |
301 memcpy(&(dest[dp]), |
307 memcpy(&(dest[dp]), |
302 "<span class=\"c2html-type\">", 26); |
308 "<span class=\"c2html-type\">", 26); |
303 dp += 26; |
309 dp += 26; |
304 } else if (highlighter->isdirective(word)) { |
310 } else if (hltr->isdirective(hltr->word)) { |
305 isinclude = !strncmp( |
311 isinclude = !strncmp( |
306 "#include", word, WORDBUF_SIZE); |
312 "#include", hltr->word, WORDBUF_SIZE); |
307 memcpy(&(dest[dp]), |
313 memcpy(&(dest[dp]), |
308 "<span class=\"c2html-directive\">", 31); |
314 "<span class=\"c2html-directive\">", 31); |
309 dp += 31; |
315 dp += 31; |
310 } else if (iscapsonly(word, wp)) { |
316 } else if (iscapsonly(hltr->word, wp)) { |
311 memcpy(&(dest[dp]), |
317 memcpy(&(dest[dp]), |
312 "<span class=\"c2html-macroconst\">", 32); |
318 "<span class=\"c2html-macroconst\">", 32); |
313 dp += 32; |
319 dp += 32; |
314 } else { |
320 } else { |
315 closespan = 0; |
321 closespan = 0; |
316 } |
322 } |
317 for (int i = 0 ; i < wp ; i++) { |
323 for (int i = 0 ; i < wp ; i++) { |
318 dp = writeescapedchar(dest, dp, word[i]); |
324 dp = writeescapedchar(dest, dp, hltr->word[i]); |
319 } |
325 } |
320 if (closespan) { |
326 if (closespan) { |
321 memcpy(&(dest[dp]), "</span>", 7); |
327 memcpy(&(dest[dp]), "</span>", 7); |
322 dp += 7; |
328 dp += 7; |
323 } |
329 } |
324 } |
330 } |
325 memset(word, 0, WORDBUF_SIZE); |
331 memset(hltr->word, 0, WORDBUF_SIZE); |
326 wp = 0; |
332 wp = 0; |
327 dp = writeescapedchar(dest, dp, c); |
333 dp = writeescapedchar(dest, dp, c); |
328 } else { |
334 } else { |
329 /* read word */ |
335 /* read word */ |
330 if (wp < WORDBUF_SIZE) { |
336 if (wp < WORDBUF_SIZE) { |
331 word[wp++] = c; |
337 hltr->word[wp++] = c; |
332 } else if (wp == WORDBUF_SIZE) { |
338 } else if (wp == WORDBUF_SIZE) { |
333 for (int i = 0 ; i < WORDBUF_SIZE ; i++) { |
339 for (int i = 0 ; i < WORDBUF_SIZE ; i++) { |
334 dp = writeescapedchar(dest, dp, word[i]); |
340 dp = writeescapedchar(dest, dp, hltr->word[i]); |
335 } |
341 } |
336 wp++; |
342 wp++; |
337 dp = writeescapedchar(dest, dp, c); |
343 dp = writeescapedchar(dest, dp, c); |
338 } else { |
344 } else { |
339 dp = writeescapedchar(dest, dp, c); |
345 dp = writeescapedchar(dest, dp, c); |
365 while ((p*=10) < lnc) w++; |
371 while ((p*=10) < lnc) w++; |
366 return w; |
372 return w; |
367 } |
373 } |
368 |
374 |
369 int main(int argc, char** argv) { |
375 int main(int argc, char** argv) { |
370 |
|
371 settings_t settings; |
376 settings_t settings; |
372 settings.outfilename = NULL; |
377 settings.outfilename = NULL; |
373 settings.highlight = 1; |
378 settings.highlight = 1; |
374 |
379 |
375 highlighter_t highlighter; |
380 highlighter_t highlighter; |
|
381 memset(&highlighter, 0, sizeof(highlighter)); |
376 highlighter.isdirective = iscdirective; |
382 highlighter.isdirective = iscdirective; |
377 highlighter.istype = isctype; |
383 highlighter.istype = isctype; |
378 highlighter.keywords = ckeywords; |
384 highlighter.keywords = ckeywords; |
|
385 highlighter.parser = cjparseline; |
379 |
386 |
380 char optc; |
387 char optc; |
381 while ((optc = getopt(argc, argv, "hjo:p")) != -1) { |
388 while ((optc = getopt(argc, argv, "hjo:p")) != -1) { |
382 switch (optc) { |
389 switch (optc) { |
383 case 'o': |
390 case 'o': |