Wed, 10 Jul 2013 13:54:15 +0200
changes merged
src/c2html.c | file | annotate | diff | comparison | revisions |
--- a/src/c2html.c Wed Jul 10 13:45:26 2013 +0200 +++ b/src/c2html.c Wed Jul 10 13:54:15 2013 +0200 @@ -37,6 +37,9 @@ #define INPUTBUF_SIZE 2048 #define WORDBUF_SIZE 16 +#define istype(word, len) (word[len-2] == '_' && word[len-1] == 't') +#define isdirective(word) (word[0] == '#') + const char* keywords[] = { "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", @@ -151,7 +154,14 @@ return 0; } -#define istype(word, len) (word[len-2] == '_' && word[len-1] == 't') +int iscapsonly(char *word, size_t wp) { + for (size_t i = 0 ; i < wp ; i++) { + if (!isupper(word[i]) && word[i] != '_') { + return 0; + } + } + return 1; +} void parseline(char *src, char *dest) { size_t sp = 0, dp = 0; @@ -159,49 +169,143 @@ while (isspace(src[sp])) { dest[dp++] = src[sp++]; } - char word[WORDBUF_SIZE]; + + static char word[WORDBUF_SIZE]; + static char includefile[FILENAME_MAX]; + memset(word, 0, WORDBUF_SIZE); - size_t wp = 0; - int closespan; + size_t wp = 0, ifp = 0; + int isstring = 0, iscomment = 0, isinclude = 0, parseinclude = 0; + static int iscommentml; + int isescaping = 0; + + if (iscommentml) { + iscomment = 1; + memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); + dp += 29; + } + for (char c = src[sp] ; c ; c=src[++sp]) { - if (!isalnum(c) && c != '_') { - /* interpret word int_t */ - if (wp > 0 && wp < WORDBUF_SIZE) { - if (iskeyword(word)) { - memcpy(&(dest[dp]), "<span class=\"c2html-keyword\">", 29); - dp += 29; - closespan = 1; - } else if (istype(word, wp)) { - memcpy(&(dest[dp]), "<span class=\"c2html-type\">", 26); - dp += 26; - closespan = 1; + /* comments */ + if (c == '/') { + if (iscommentml && sp > 0 && src[sp-1] == '*') { + iscomment = 0; + iscommentml = 0; + memcpy(&(dest[dp]), "/</span>", 8); + dp += 8; + continue; + } else if (!iscomment && (src[sp+1] == '/' || src[sp+1] == '*')) { + iscomment = 1; + iscommentml = (src[sp+1] == '*'); + memcpy(&(dest[dp]), "<span class=\"c2html-comment\">", 29); + dp += 29; + } + } + + if (iscomment) { + if (c == '\n') { + memcpy(&(dest[dp]), "</span>", 7); + dp += 7; + } + dp = writeescapedchar(dest, dp, c); + } else if (isinclude) { + if (c == '<') { + memcpy(&(dest[dp]), "<span class=\"c2html-stdinclude\">", 32); + dp += 32; + dp = writeescapedchar(dest, dp, c); + } else if (c == '\"') { + if (parseinclude) { + dest[dp++] = '\"'; + dest[dp++] = '>'; + memcpy(&(dest[dp]), includefile, ifp); + dp += ifp; + + dp = writeescapedchar(dest, dp, c); + memcpy(&(dest[dp]), "</a>", 4); + dp += 4; + parseinclude = 0; } else { - closespan = 0; + memcpy(&(dest[dp]), "<a class=\"c2html-userinclude\" href=", 35); + dp += 35; + dp = writeescapedchar(dest, dp, c); + ifp = 0; + includefile[ifp++] = '\"'; + parseinclude = 1; } - for (int i = 0 ; i < wp ; i++) { - dp = writeescapedchar(dest, dp, word[i]); + } else if (c == '>') { + dp = writeescapedchar(dest, dp, c); + memcpy(&(dest[dp]), "</span>", 7); + dp += 7; + } else { + if (parseinclude) { + includefile[ifp++] = c; } - if (closespan) { + dp = writeescapedchar(dest, dp, c); + } + } else { + /* strings */ + if (!isescaping && (c == '\'' || c == '\"')) { + isstring ^= 1; + if (isstring) { + memcpy(&(dest[dp]), "<span class=\"c2html-string\">", 28); + dp += 28; + dp = writeescapedchar(dest, dp, c); + } else { + dp = writeescapedchar(dest, dp, c); memcpy(&(dest[dp]), "</span>", 7); dp += 7; } - memset(word, 0, WORDBUF_SIZE); - wp = 0; + } else { + if (isstring) { + dp = writeescapedchar(dest, dp, c); + } else if (!isalnum(c) && c != '_' && c != '#' && c != '.') { + /* interpret word int_t */ + if (wp > 0 && wp < WORDBUF_SIZE) { + int closespan = 1; + if (iskeyword(word)) { + memcpy(&(dest[dp]), "<span class=\"c2html-keyword\">", 29); + dp += 29; + } else if (istype(word, wp)) { + memcpy(&(dest[dp]), "<span class=\"c2html-type\">", 26); + dp += 26; + } else if (isdirective(word)) { + isinclude = !strncmp("#include", word, WORDBUF_SIZE); + memcpy(&(dest[dp]), "<span class=\"c2html-directive\">", 31); + dp += 31; + } else if (iscapsonly(word, wp)) { + memcpy(&(dest[dp]), "<span class=\"c2html-macroconst\">", 32); + dp += 32; + } else { + closespan = 0; + } + for (int i = 0 ; i < wp ; i++) { + dp = writeescapedchar(dest, dp, word[i]); + } + if (closespan) { + memcpy(&(dest[dp]), "</span>", 7); + dp += 7; + } + } + memset(word, 0, WORDBUF_SIZE); + wp = 0; + dp = writeescapedchar(dest, dp, c); + } else { + /* read word */ + if (wp < WORDBUF_SIZE) { + word[wp++] = c; + } else if (wp == WORDBUF_SIZE) { + for (int i = 0 ; i < WORDBUF_SIZE ; i++) { + dp = writeescapedchar(dest, dp, word[i]); + } + wp++; + dp = writeescapedchar(dest, dp, c); + } else { + dp = writeescapedchar(dest, dp, c); + } + } } - dp = writeescapedchar(dest, dp, c); - } else { - /* read word */ - if (wp < WORDBUF_SIZE) { - word[wp++] = c; - } else if (wp == WORDBUF_SIZE) { - for (int i = 0 ; i < WORDBUF_SIZE ; i++) { - dp = writeescapedchar(dest, dp, word[i]); - } - wp++; - dp = writeescapedchar(dest, dp, c); - } else { - dp = writeescapedchar(dest, dp, c); - } + + isescaping = !isescaping & (c == '\\'); } } dest[dp] = 0; @@ -274,7 +378,7 @@ line = inputfile->lines[i]; } fprintf(fout, "<span class=\"c2html-lineno\">%*d:</span> %s", - lnw, i, line); + lnw, i+1, line); } free(line); fprintf(fout, "</pre>\n");
--- a/test/header.html Wed Jul 10 13:45:26 2013 +0200 +++ b/test/header.html Wed Jul 10 13:54:15 2013 +0200 @@ -10,9 +10,31 @@ span.c2html-keyword { color: blue; } + span.c2html-macroconst { + color: cornflowerblue; + } span.c2html-type { color: cornflowerblue; } + span.c2html-directive { + color: green; + } + span.c2html-string { + color: darkorange; + } + span.c2html-comment { + color: grey; + } + span.c2html-stdinclude { + color: darkorange; + } + span.c2html-userinclude { + color: darkorange; + } + a.c2html-userinclude { + color: darkorange; + text-decoration: underline; + } </style> </head> <body>