1.1 --- a/src/c2html.c Fri Aug 30 11:23:44 2013 +0200 1.2 +++ b/src/c2html.c Thu Jan 23 09:19:37 2014 +0100 1.3 @@ -1,7 +1,7 @@ 1.4 /* 1.5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 * 1.7 - * Copyright 2013 Mike Becker. All rights reserved. 1.8 + * Copyright 2014 Mike Becker. All rights reserved. 1.9 * 1.10 * Redistribution and use in source and binary forms, with or without 1.11 * modification, are permitted provided that the following conditions are met: 1.12 @@ -34,56 +34,10 @@ 1.13 #include <unistd.h> 1.14 #include <ctype.h> 1.15 1.16 +#include "javacodegen.h" 1.17 +#include "ccodegen.h" 1.18 + 1.19 #define INPUTBUF_SIZE 2048 1.20 -#define WORDBUF_SIZE 64 1.21 - 1.22 -const char* ckeywords[] = { 1.23 - "auto", "break", "case", "char", "const", "continue", "default", "do", 1.24 - "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", 1.25 - "long", "register", "return", "short", "signed", "sizeof", "static", 1.26 - "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", 1.27 - "while", NULL 1.28 -}; 1.29 - 1.30 -const char* jkeywords[] = { 1.31 - "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", 1.32 - "package", "synchronized", "boolean", "do", "if", "private", "this", 1.33 - "break", "double", "implements", "protected", "throw", "byte", "else", 1.34 - "import", "public", "throws", "case", "enum", "instanceof", "return", 1.35 - "transient", "catch", "extends", "int", "short", "try", "char", "final", 1.36 - "interface", "static", "void", "class", "finally", "long", "strictfp", 1.37 - "volatile", "const", "float", "native", "super", "while", NULL 1.38 -}; 1.39 - 1.40 -#define iswordcharacter(c) (isalnum(c) || c=='_' || c=='#' || c=='@') 1.41 - 1.42 -int isctype(char *word, size_t len) { 1.43 - return (word[len-2] == '_' && word[len-1] == 't'); 1.44 -} 1.45 - 1.46 -int iscdirective(char *word) { 1.47 - return (word[0] == '#'); 1.48 -} 1.49 - 1.50 -int isjtype(char *word, size_t len) { 1.51 - return isupper(word[0]); 1.52 -} 1.53 - 1.54 -int isjdirective(char *word) { 1.55 - return word[0] == '@'; 1.56 -} 1.57 - 1.58 -typedef struct _highlighter_t highlighter_t; 1.59 - 1.60 -struct _highlighter_t { 1.61 - const char** keywords; 1.62 - int(*istype)(char*,size_t); 1.63 - int(*isdirective)(char*); 1.64 - void(*parser)(char*,char*,highlighter_t*); 1.65 - int iscommentml; 1.66 - char word[WORDBUF_SIZE]; 1.67 - char includefile[FILENAME_MAX]; 1.68 -}; 1.69 1.70 typedef struct { 1.71 char* outfilename; 1.72 @@ -169,190 +123,6 @@ 1.73 return inputfile; 1.74 } 1.75 1.76 -size_t writeescapedchar(char *dest, size_t dp, char c) { 1.77 - if (c == '>') { 1.78 - dest[dp++] = '&'; dest[dp++] = 'g'; dest[dp++] = 't'; dest[dp++] = ';'; 1.79 - } else if (c == '<') { 1.80 - dest[dp++] = '&'; dest[dp++] = 'l'; dest[dp++] = 't'; dest[dp++] = ';'; 1.81 - } else { 1.82 - dest[dp++] = c; 1.83 - } 1.84 - 1.85 - return dp; 1.86 -} 1.87 - 1.88 -int iskeyword(char *word, const char** keywords) { 1.89 - for (int i = 0 ; keywords[i] ; i++) { 1.90 - if (strncmp(keywords[i], word, WORDBUF_SIZE) == 0) { 1.91 - return 1; 1.92 - } 1.93 - } 1.94 - return 0; 1.95 -} 1.96 - 1.97 -int iscapsonly(char *word, size_t wp) { 1.98 - for (size_t i = 0 ; i < wp ; i++) { 1.99 - if (!isupper(word[i]) && word[i] != '_') { 1.100 - return 0; 1.101 - } 1.102 - } 1.103 - return 1; 1.104 -} 1.105 - 1.106 -void parseline(char *src, char *dest, highlighter_t *hltr) { 1.107 - hltr->parser(src, dest, hltr); 1.108 -} 1.109 - 1.110 -void cjparseline(char *src, char *dest, highlighter_t *hltr) { 1.111 - size_t sp = 0, dp = 0; 1.112 - /* indent */ 1.113 - while (isspace(src[sp])) { 1.114 - dest[dp++] = src[sp++]; 1.115 - } 1.116 - 1.117 - memset(hltr->word, 0, WORDBUF_SIZE); 1.118 - size_t wp = 0, ifp = 0; 1.119 - int isstring = 0, iscomment = 0, isinclude = 0, parseinclude = 0; 1.120 - int isescaping = 0; 1.121 - 1.122 - if (hltr->iscommentml) { 1.123 - iscomment = 1; 1.124 - memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); 1.125 - dp += 29; 1.126 - } 1.127 - 1.128 - for (char c = src[sp] ; c ; c=src[++sp]) { 1.129 - /* comments */ 1.130 - if (c == '/') { 1.131 - if (hltr->iscommentml && sp > 0 && src[sp-1] == '*') { 1.132 - iscomment = 0; 1.133 - hltr->iscommentml = 0; 1.134 - memcpy(&(dest[dp]), "/</span>", 8); 1.135 - dp += 8; 1.136 - continue; 1.137 - } else if (!iscomment && (src[sp+1] == '/' || src[sp+1] == '*')) { 1.138 - iscomment = 1; 1.139 - hltr->iscommentml = (src[sp+1] == '*'); 1.140 - memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); 1.141 - dp += 29; 1.142 - } 1.143 - } 1.144 - 1.145 - if (iscomment) { 1.146 - if (c == '\n') { 1.147 - memcpy(&(dest[dp]), "</span>", 7); 1.148 - dp += 7; 1.149 - } 1.150 - dp = writeescapedchar(dest, dp, c); 1.151 - } else if (isinclude) { 1.152 - if (c == '<') { 1.153 - memcpy(&(dest[dp]), "<span class=\"c2html-stdinclude\">", 32); 1.154 - dp += 32; 1.155 - dp = writeescapedchar(dest, dp, c); 1.156 - } else if (c == '\"') { 1.157 - if (parseinclude) { 1.158 - dest[dp++] = '\"'; 1.159 - dest[dp++] = '>'; 1.160 - memcpy(&(dest[dp]), hltr->includefile, ifp); 1.161 - dp += ifp; 1.162 - 1.163 - dp = writeescapedchar(dest, dp, c); 1.164 - memcpy(&(dest[dp]), "</a>", 4); 1.165 - dp += 4; 1.166 - parseinclude = 0; 1.167 - } else { 1.168 - memcpy(&(dest[dp]), 1.169 - "<a class=\"c2html-userinclude\" href=", 35); 1.170 - dp += 35; 1.171 - dp = writeescapedchar(dest, dp, c); 1.172 - ifp = 0; 1.173 - hltr->includefile[ifp++] = '\"'; 1.174 - parseinclude = 1; 1.175 - } 1.176 - } else if (c == '>') { 1.177 - dp = writeescapedchar(dest, dp, c); 1.178 - memcpy(&(dest[dp]), "</span>", 7); 1.179 - dp += 7; 1.180 - } else { 1.181 - if (parseinclude) { 1.182 - hltr->includefile[ifp++] = c; 1.183 - } 1.184 - dp = writeescapedchar(dest, dp, c); 1.185 - } 1.186 - } else { 1.187 - /* strings */ 1.188 - if (!isescaping && (c == '\'' || c == '\"')) { 1.189 - isstring ^= 1; 1.190 - if (isstring) { 1.191 - memcpy(&(dest[dp]), "<span class=\"c2html-string\">", 28); 1.192 - dp += 28; 1.193 - dp = writeescapedchar(dest, dp, c); 1.194 - } else { 1.195 - dp = writeescapedchar(dest, dp, c); 1.196 - memcpy(&(dest[dp]), "</span>", 7); 1.197 - dp += 7; 1.198 - } 1.199 - } else { 1.200 - if (isstring) { 1.201 - dp = writeescapedchar(dest, dp, c); 1.202 - } else if (!iswordcharacter(c)) { 1.203 - /* interpret word int_t */ 1.204 - if (wp > 0 && wp < WORDBUF_SIZE) { 1.205 - int closespan = 1; 1.206 - if (iskeyword(hltr->word, hltr->keywords)) { 1.207 - memcpy(&(dest[dp]), 1.208 - "<span class=\"c2html-keyword\">", 29); 1.209 - dp += 29; 1.210 - } else if (hltr->istype(hltr->word, wp)) { 1.211 - memcpy(&(dest[dp]), 1.212 - "<span class=\"c2html-type\">", 26); 1.213 - dp += 26; 1.214 - } else if (hltr->isdirective(hltr->word)) { 1.215 - isinclude = !strncmp( 1.216 - "#include", hltr->word, WORDBUF_SIZE); 1.217 - memcpy(&(dest[dp]), 1.218 - "<span class=\"c2html-directive\">", 31); 1.219 - dp += 31; 1.220 - } else if (iscapsonly(hltr->word, wp)) { 1.221 - memcpy(&(dest[dp]), 1.222 - "<span class=\"c2html-macroconst\">", 32); 1.223 - dp += 32; 1.224 - } else { 1.225 - closespan = 0; 1.226 - } 1.227 - for (int i = 0 ; i < wp ; i++) { 1.228 - dp = writeescapedchar(dest, dp, hltr->word[i]); 1.229 - } 1.230 - if (closespan) { 1.231 - memcpy(&(dest[dp]), "</span>", 7); 1.232 - dp += 7; 1.233 - } 1.234 - } 1.235 - memset(hltr->word, 0, WORDBUF_SIZE); 1.236 - wp = 0; 1.237 - dp = writeescapedchar(dest, dp, c); 1.238 - } else { 1.239 - /* read word */ 1.240 - if (wp < WORDBUF_SIZE) { 1.241 - hltr->word[wp++] = c; 1.242 - } else if (wp == WORDBUF_SIZE) { 1.243 - for (int i = 0 ; i < WORDBUF_SIZE ; i++) { 1.244 - dp = writeescapedchar(dest, dp, hltr->word[i]); 1.245 - } 1.246 - wp++; 1.247 - dp = writeescapedchar(dest, dp, c); 1.248 - } else { 1.249 - dp = writeescapedchar(dest, dp, c); 1.250 - } 1.251 - } 1.252 - } 1.253 - 1.254 - isescaping = !isescaping & (c == '\\'); 1.255 - } 1.256 - } 1.257 - dest[dp] = 0; 1.258 -} 1.259 - 1.260 void printhelp() { 1.261 printf("Formats source code using HTML.\n\nUsage:\n" 1.262 " c2html [Options] FILE\n\n" 1.263 @@ -382,7 +152,7 @@ 1.264 highlighter.isdirective = iscdirective; 1.265 highlighter.istype = isctype; 1.266 highlighter.keywords = ckeywords; 1.267 - highlighter.parser = cjparseline; 1.268 + highlighter.parser = cparseline; 1.269 1.270 char optc; 1.271 while ((optc = getopt(argc, argv, "hjo:p")) != -1) { 1.272 @@ -396,6 +166,7 @@ 1.273 highlighter.isdirective = isjdirective; 1.274 highlighter.istype = isjtype; 1.275 highlighter.keywords = jkeywords; 1.276 + highlighter.parser = jparseline; 1.277 break; 1.278 case 'p': 1.279 settings.highlight = 0; 1.280 @@ -432,7 +203,7 @@ 1.281 int lnw = lnint(inputfile->count); 1.282 for (int i = 0 ; i < inputfile->count ; i++) { 1.283 if (settings.highlight) { 1.284 - parseline(inputfile->lines[i], line, &highlighter); 1.285 + highlighter.parser(inputfile->lines[i], line, &highlighter); 1.286 } else { 1.287 line = inputfile->lines[i]; 1.288 }