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 |
1.1 --- a/src/c2html.c Wed Jun 12 13:40:23 2013 +0200 1.2 +++ b/src/c2html.c Wed Jun 12 14:48:50 2013 +0200 1.3 @@ -35,6 +35,14 @@ 1.4 #include <ctype.h> 1.5 1.6 #define INPUTBUF_SIZE 2048 1.7 +#define WORDBUF_SIZE 16 1.8 + 1.9 +const char* keywords[] = { 1.10 + "auto", "break", "case", "char", "const", "continue", "default", "do", 1.11 + "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", 1.12 + "long", "register", "return", "short", "signed", "sizeof", "static", "struct", 1.13 + "switch", "typedef", "union", "unsigned", "void", "volatile", "while", NULL 1.14 +}; 1.15 1.16 1.17 typedef struct { 1.18 @@ -98,6 +106,7 @@ 1.19 } 1.20 1.21 if (buf[i] == '\n') { 1.22 + line[col++] = '\n'; 1.23 line[col] = 0; 1.24 addline(inputfile, line, col); 1.25 col = 0; 1.26 @@ -114,24 +123,80 @@ 1.27 return inputfile; 1.28 } 1.29 1.30 +size_t writeescapedchar(char *dest, size_t dp, char c) { 1.31 + if (c == '>') { 1.32 + dest[dp++] = '&'; dest[dp++] = 'g'; 1.33 + dest[dp++] = 't'; dest[dp++] = ';'; 1.34 + } else if (c == '<') { 1.35 + dest[dp++] = '&'; dest[dp++] = 'l'; 1.36 + dest[dp++] = 't'; dest[dp++] = ';'; 1.37 + } else { 1.38 + dest[dp++] = c; 1.39 + } 1.40 + 1.41 + return dp; 1.42 +} 1.43 + 1.44 +int iskeyword(char *word) { 1.45 + for (int i = 0 ; keywords[i] ; i++) { 1.46 + if (strncmp(keywords[i], word, WORDBUF_SIZE) == 0) { 1.47 + return 1; 1.48 + } 1.49 + } 1.50 + return 0; 1.51 +} 1.52 + 1.53 +#define istype(word, len) (word[len-2] == '_' && word[len-1] == 't') 1.54 + 1.55 void parseline(char *src, char *dest) { 1.56 size_t sp = 0, dp = 0; 1.57 /* indent */ 1.58 while (isspace(src[sp])) { 1.59 dest[dp++] = src[sp++]; 1.60 } 1.61 + char word[WORDBUF_SIZE]; 1.62 + memset(word, 0, WORDBUF_SIZE); 1.63 + size_t wp = 0; 1.64 + int closespan; 1.65 for (char c = src[sp] ; c ; c=src[++sp]) { 1.66 - switch (c) { 1.67 - case '<': 1.68 - memcpy(&(dest[dp]), "<", 4); 1.69 - dp += 4; 1.70 - break; 1.71 - case '>': 1.72 - memcpy(&(dest[dp]), ">", 4); 1.73 - dp += 4; 1.74 - break; 1.75 - default: 1.76 - dest[dp++] = c; 1.77 + if (!isalnum(c) && c != '_') { 1.78 + /* interpret word int_t */ 1.79 + if (wp > 0 && wp < WORDBUF_SIZE) { 1.80 + if (iskeyword(word)) { 1.81 + memcpy(&(dest[dp]), "<span class=\"c2html-keyword\">", 29); 1.82 + dp += 29; 1.83 + closespan = 1; 1.84 + } else if (istype(word, wp)) { 1.85 + memcpy(&(dest[dp]), "<span class=\"c2html-type\">", 26); 1.86 + dp += 26; 1.87 + closespan = 1; 1.88 + } else { 1.89 + closespan = 0; 1.90 + } 1.91 + for (int i = 0 ; i < wp ; i++) { 1.92 + dp = writeescapedchar(dest, dp, word[i]); 1.93 + } 1.94 + if (closespan) { 1.95 + memcpy(&(dest[dp]), "</span>", 7); 1.96 + dp += 7; 1.97 + } 1.98 + } 1.99 + memset(word, 0, WORDBUF_SIZE); 1.100 + wp = 0; 1.101 + dp = writeescapedchar(dest, dp, c); 1.102 + } else { 1.103 + /* read word */ 1.104 + if (wp < WORDBUF_SIZE) { 1.105 + word[wp++] = c; 1.106 + } else if (wp == WORDBUF_SIZE) { 1.107 + for (int i = 0 ; i < WORDBUF_SIZE ; i++) { 1.108 + dp = writeescapedchar(dest, dp, word[i]); 1.109 + } 1.110 + wp++; 1.111 + dp = writeescapedchar(dest, dp, c); 1.112 + } else { 1.113 + dp = writeescapedchar(dest, dp, c); 1.114 + } 1.115 } 1.116 } 1.117 dest[dp] = 0; 1.118 @@ -165,7 +230,7 @@ 1.119 int lnw = lnint(inputfile->count); 1.120 for (int i = 0 ; i < inputfile->count ; i++) { 1.121 parseline(inputfile->lines[i], line); 1.122 - printf("<span class=\"c2html-lineno\">%*d:</span> %s\n", 1.123 + printf("<span class=\"c2html-lineno\">%*d:</span> %s", 1.124 lnw, i, line); 1.125 } 1.126 free(line);
2.1 --- a/test/header.html Wed Jun 12 13:40:23 2013 +0200 2.2 +++ b/test/header.html Wed Jun 12 14:48:50 2013 +0200 2.3 @@ -7,6 +7,12 @@ 2.4 font-style: italic; 2.5 color: grey; 2.6 } 2.7 + span.c2html-keyword { 2.8 + color: blue; 2.9 + } 2.10 + span.c2html-type { 2.11 + color: cornflowerblue; 2.12 + } 2.13 </style> 2.14 </head> 2.15 <body>