/* * Bugs: * * Comments are very sensitive to missing space: */ /* Also, note the colouring here: */ #ifdef NEVER char *simpletest = "fred"; char test2 = 'x'; CINEWORD/*CINEBYTE*/ register_P = 0; /* Page-Register (4 bits, shifts to * high short nibble for code, hight * byte nibble for ram) */ CINEWORD /*CINEBYTE*/acc_a0 = 0; /* bit0 of A-reg at last accumulator * access */ const char *do_it = "line1\n\"line2"; /* oops! */ const char *again = "line1\n\"line2"; int new = 0; const char *nullstr = ""; #define a_macro (i = \ i + 1) int that_is_better = '\''; int or_is_it = '\''; int last_test = '\\'; char *another_string_test = "hello\\\"world"; char *last_string_test = "hello\\nworld"; /* test *//* Here is one remaining bug I only just now noticed ... fixed! */ #endif /* * Probably a bug in the 'peek' logic. (read/ungetc can't be called twice) * \" in a string terminates the string colouring. * a variable name such as do_it does *not* contain the keyword 'do' - * someone is relying on isalnum() to identify variables. * #directive immediately following a comment line is not * coloured * #directives on multiple lines (ending each in in \) are not * coloured on the second and following lines * * Misfeatures: for my purposes, I don't want C++ keywords to be highlighted. */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #define QUOTE_COLOR "#ff0000" #define COMMENT_COLOR "#408080" #define PREPROC_COLOR "#008000" /* * C / C++ to HTML converter. Converts C and C++ code to HTML with syntax * hilighting... */ int peekchar = -1; char *Reserved_Words[] = { #ifdef CPLUSPLUS "asm", "catch", "double", "cgoto", "not", "return", "throw", "volatile", "and", "char", "else", "if", "not_eq", "short", "true", "while", "and_eq", "class", "enum", "inline", "operator", "signed", "try", "xor", "auto", "compl", "explicit", "int", "or", "sizeof", "typedef", "xor_eq", "bitand", "const", "extern", "long", "or_eq", "static", "typename", "bitor", "continue", "false", "mutable", "private", "struct", "union", "bool", "default", "float", "namespace", "protected", "switch", "unsigned", "break", "delete", "for", "new", "public", "template", "virtual", "case", "do", "friend", "not", "register", "this", "void", #else "double", "goto", "return", "volatile", "char", "else", "if", "short", "true", "while", "enum", "inline", "signed", "auto", "int", /*"or",*/ "sizeof", "typedef", "const", "extern", "long", "static", "continue", "false", "struct", "union", "bool", "default", "float", "switch", "unsigned", "break", "for", "case", "do", "register", "void", #endif NULL }; int IsReservedWord(char *word) { int i; for (i = 0;; ++i) { if (Reserved_Words[i] == NULL) return (0); if (!strcmp(word, Reserved_Words[i])) { return 1; } } } int fpeek(FILE * f) { int ch; ch = fgetc(f); ungetc(ch, f); return ch; } void printchar(char inchar, FILE * fstream) { if (inchar == '&') fprintf(fstream, "&"); else if (inchar == '>') fprintf(fstream, ">"); else if (inchar == '<') fprintf(fstream, "<"); else fputc(inchar, fstream); } int Print_HTML(FILE * fstream, char *Title) { FILE *InFile; int inchar, i, newline = 1, WordIdx = 0; char word[280]; for (i = 0; i < 280; ++i) word[i] = 0; /* Print out the HTML header. */ fprintf(fstream, "<HTML>\n<HEAD>\n<TITLE> %s </TITLE>\n</HEAD>\n", Title); fprintf(fstream, "<BODY bgcolor=ffffff><pre>\n"); /* Now we open the file for reading in text mode. */ InFile = fopen(Title, "r"); if (InFile == NULL) return -1; /* And start reading it in character by character. */ inchar = fgetc(InFile); peekchar = fpeek(InFile); while (!feof(InFile)) { if (inchar == '\n') { newline = 1; } else if (!isspace(inchar)) { /* Handle all preproccessor directives. */ if (inchar == '#') { if (newline == 1) { fprintf(fstream, "<font color=%s>", PREPROC_COLOR); for (;;) { if ((inchar != '\\') && (peekchar == '\n')) break; printchar(inchar, fstream); inchar = fgetc(InFile); peekchar = fpeek(InFile); } printchar(inchar, fstream); inchar = fgetc(InFile); peekchar = fpeek(InFile); fprintf(fstream, "</font>"); newline = 1; continue; } } /* Handle single line comments. */ else if ((inchar == '/') && (peekchar == '/')) { fprintf(fstream, "<font color=%s><i>", COMMENT_COLOR); while ((inchar != '\n') && (inchar > 0)) { printchar(inchar, fstream); inchar = fgetc(InFile); peekchar = fpeek(InFile); } fprintf(fstream, "</i></font>"); newline = 1; continue; } /* Handle Multi-line comments. */ else if ((inchar == '/') && (peekchar == '*')) { fprintf(fstream, "<font color=%s><i>/", COMMENT_COLOR); for (;;) { inchar = fgetc(InFile); peekchar = fpeek(InFile); if ((inchar == '*') && (peekchar == '/')) break; printchar(inchar, fstream); } inchar = fgetc(InFile); peekchar = fpeek(InFile); fprintf(fstream, "*/</i></font>"); inchar = fgetc(InFile); peekchar = fpeek(InFile); continue; /* Now process next char */ } /* Handle Double Quotes. */ else if (inchar == '"') { fprintf(fstream, "<font color=%s>\"", QUOTE_COLOR); if (peekchar == '"') { /* Null string bug fix */ inchar = fgetc(InFile); peekchar = fpeek(InFile); printchar(inchar, fstream); } else { inchar = fgetc(InFile); if (inchar == EOF) continue; peekchar = fpeek(InFile); for (;;) { if ((inchar != '\\') && (peekchar == '"')) break; printchar(inchar, fstream); inchar = fgetc(InFile); if (inchar == EOF) break; peekchar = fpeek(InFile); } printchar(inchar, fstream); inchar = fgetc(InFile); peekchar = fpeek(InFile); printchar(inchar, fstream); } inchar = fgetc(InFile); peekchar = fpeek(InFile); fprintf(fstream, "</font>"); newline = 0; continue; } /* Handle Single Quotes. */ else if (inchar == '\'') { fprintf(fstream, "<font color=%s>'", QUOTE_COLOR); inchar = fgetc(InFile); if (inchar == EOF) continue; peekchar = fpeek(InFile); for (;;) { if ((inchar != '\\') && (peekchar == '\'')) break; if ((inchar == '\\') && (peekchar == '\\')) { printchar(inchar, fstream); inchar = fgetc(InFile); if (inchar == EOF) break; peekchar = fpeek(InFile); if (peekchar == '\'') break; } printchar(inchar, fstream); inchar = fgetc(InFile); if (inchar == EOF) break; peekchar = fpeek(InFile); } printchar(inchar, fstream); inchar = fgetc(InFile); peekchar = fpeek(InFile); printchar(inchar, fstream); inchar = fgetc(InFile); peekchar = fpeek(InFile); fprintf(fstream, "</font>"); newline = 0; continue; } newline = 0; } /* Everything else. */ if (!(isalnum(inchar) || (inchar == '_'))) { if (IsReservedWord(word)) { fprintf(fstream, "<b>%s</b>%c", word, inchar); } else { for (i = 0; i < WordIdx; ++i) printchar(word[i], fstream); printchar(inchar, fstream); } for (i = 0; i < 280; ++i) word[i] = 0; WordIdx = 0; } else { word[WordIdx++] = inchar; } inchar = fgetc(InFile); peekchar = fpeek(InFile); } fprintf(fstream, "\n</pre></BODY></HTML>\n"); fclose(InFile); return 1; } int main(int argc, char *argv[]) { if (argc < 2) { printf("Usage: %s [Filename]\n\n", argv[0]); return -1; } Print_HTML(stdout, argv[1]); return 0; }