Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FLAG_OUTPUT 1
#define FLAG_EVEN 2
#define NUMKEYWORDS 32
typedef struct {
size_t nLen;
char *sz;
} t_string;
const t_string c_keywords[NUMKEYWORDS] = { 4, "auto", 5, "break", 4, "case", 4, "char", 5, "const", 8, "continue", 7, "default", 2, "do",
6, "double", 4, "else", 4, "enum", 6, "extern", 5, "float", 3, "for", 4, "goto", 2, "if",
3, "int", 4, "long", 8, "register", 6, "return", 5, "short", 6, "signed", 6, "sizeof", 6, "static",
6, "struct", 6, "switch", 7, "typedef", 5, "union", 8, "unsigned", 4, "void", 8, "volatile", 5, "while" };
int main(int argc, char **argv)
{
char cEscape, cLast, *pBuffer, *pEnd, *pPtr;
int c;
unsigned int fFlags, n;
pBuffer = malloc(BUFSIZ);
if (!pBuffer)
return -1;
pPtr = pBuffer;
pEnd = pBuffer + ((BUFSIZ - 1) * sizeof(*pBuffer));
fFlags = FLAG_EVEN;
cEscape = '\0';
cLast = '\0';
printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\r\n \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\r\n<head>\r\n<link rel=\"stylesheet\" type=\"text/css\" href=\"source.css\"/>\r\n<title>Source code</title>\r\n</head>\r\n<body>\r\n<div>\r\n");
while ((c = getchar()) != EOF)
{
// HACK: if we ate a comment escape char, but haven't started a comment, put it back!
if ((cLast == '/' && c != '/' && c != '*') || (cLast == '*' && c != '/'))
putchar(cLast);
if (strchr("\t\n\r !\"&()*+,-./:;<=>?@[\\]^`{|}~", c) || cEscape != '\0')
{
if (pPtr > pBuffer)
{
*pPtr = '\0';
for (n=0;n<NUMKEYWORDS;n++)
{
if (!strncmp(pBuffer, c_keywords[n].sz, (c_keywords[n].nLen >= (size_t)(pPtr - pBuffer)) ? c_keywords[n].nLen : (pPtr - pBuffer)))
{
printf("<span class=\"keyword\">%s</span>", pBuffer);
break;
}
}
if (n == NUMKEYWORDS)
printf("%s", pBuffer);
pPtr = pBuffer;
fFlags |= FLAG_OUTPUT;
}
if (c == '\t')
printf(" ");
else if (c == '\n')
{
if (!(fFlags & FLAG_OUTPUT))
printf(" ");
printf((fFlags & FLAG_EVEN) ? "</div>\r\n<div class=\"evenline\">" : "</div>\r\n<div>");
fFlags &= ~FLAG_OUTPUT;
fFlags ^= FLAG_EVEN;
if (cEscape == '/')
cEscape = '\0';
}
else if (c == ' ' && cLast == c)
printf(" ");
else if (c == '&')
printf("&");
else if ((c == '*' || c == '/'))
{
if (cLast == '/' && cEscape == '\0')
{
printf("<span class=\"comment\">/");
cEscape = (char)c;
}
else if (c == '/' && cLast == '*' && cEscape != '\0')
{
printf("*/</span>");
cEscape = '\0';
}
}
else if (c == '<')
printf("<");
else if (c == '>')
printf(">");
else if (c >= ' ')
{
if (c == '\"' && cLast != '\\')
cEscape = (cEscape == '\0') ? (char)c : '\0';
putchar(c);
}
if (c != '\n')
fFlags |= FLAG_OUTPUT;
}
else if (pPtr < pEnd)
*(pPtr++) = (char)c;
cLast = (char)c;
}
if (cEscape == '/' || cEscape == '*')
printf("</span>");
printf("</div>\r\n</body>\r\n</html>");
free(pBuffer);
return 0;
}
Oh, and in case you run it and don't understand why it hangs -