support for keywords and types

Wed, 12 Jun 2013 14:48:50 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 12 Jun 2013 14:48:50 +0200
changeset 5
412f1896874b
parent 4
323f674931fe
child 6
d10f7570add4

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]), "&lt;", 4);
-        dp += 4;
-        break;
-      case '>':
-        memcpy(&(dest[dp]), "&gt;", 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);
--- a/test/header.html	Wed Jun 12 13:40:23 2013 +0200
+++ b/test/header.html	Wed Jun 12 14:48:50 2013 +0200
@@ -7,6 +7,12 @@
         font-style: italic;
         color: grey;
       }
+      span.c2html-keyword {
+        color: blue;
+      }
+      span.c2html-type {
+        color: cornflowerblue;
+      }
     </style>
   </head>
   <body>

mercurial