/*
* 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;
}