Wed, 12 Jun 2013 14:48:50 +0200
support for keywords and types
src/c2html.c | file | annotate | diff | comparison | revisions | |
test/header.html | file | annotate | diff | comparison | revisions |
--- a/src/c2html.c Wed Jun 12 13:40:23 2013 +0200 +++ b/src/c2html.c Wed Jun 12 14:48:50 2013 +0200 @@ -35,6 +35,14 @@ #include <ctype.h> #define INPUTBUF_SIZE 2048 +#define WORDBUF_SIZE 16 + +const char* keywords[] = { + "auto", "break", "case", "char", "const", "continue", "default", "do", + "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", + "long", "register", "return", "short", "signed", "sizeof", "static", "struct", + "switch", "typedef", "union", "unsigned", "void", "volatile", "while", NULL +}; typedef struct { @@ -98,6 +106,7 @@ } if (buf[i] == '\n') { + line[col++] = '\n'; line[col] = 0; addline(inputfile, line, col); col = 0; @@ -114,24 +123,80 @@ return inputfile; } +size_t writeescapedchar(char *dest, size_t dp, char c) { + if (c == '>') { + dest[dp++] = '&'; dest[dp++] = 'g'; + dest[dp++] = 't'; dest[dp++] = ';'; + } else if (c == '<') { + dest[dp++] = '&'; dest[dp++] = 'l'; + dest[dp++] = 't'; dest[dp++] = ';'; + } else { + dest[dp++] = c; + } + + return dp; +} + +int iskeyword(char *word) { + for (int i = 0 ; keywords[i] ; i++) { + if (strncmp(keywords[i], word, WORDBUF_SIZE) == 0) { + return 1; + } + } + return 0; +} + +#define istype(word, len) (word[len-2] == '_' && word[len-1] == 't') + void parseline(char *src, char *dest) { size_t sp = 0, dp = 0; /* indent */ while (isspace(src[sp])) { dest[dp++] = src[sp++]; } + char word[WORDBUF_SIZE]; + memset(word, 0, WORDBUF_SIZE); + size_t wp = 0; + int closespan; for (char c = src[sp] ; c ; c=src[++sp]) { - switch (c) { - case '<': - memcpy(&(dest[dp]), "<", 4); - dp += 4; - break; - case '>': - memcpy(&(dest[dp]), ">", 4); - dp += 4; - break; - default: - dest[dp++] = c; + 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; + } 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); + } } } dest[dp] = 0; @@ -165,7 +230,7 @@ int lnw = lnint(inputfile->count); for (int i = 0 ; i < inputfile->count ; i++) { parseline(inputfile->lines[i], line); - printf("<span class=\"c2html-lineno\">%*d:</span> %s\n", + printf("<span class=\"c2html-lineno\">%*d:</span> %s", lnw, i, line); } free(line);