«
* C / C++ to HTML converter
*
* Converts C and C++ code to HTML with syntax hilighting
* and folding by use of embedded comments.
*
* If you are viewing this file on a web page, it has already been
* processed using itself, so you can click on the darker colored comments
* to unfold the source code behind them. Click on the comment again
* (or the following source code) to re-fold it to the summary text.
*
* This comment is a fold, and clicking here will display an extended
* comment section.
»
« Declaration section »
« Support procedure section »
« Symbol table management »
int IsReservedWord (char *word)
« Is a token an identifier or a reserved keyword?»{
static char *Reserved_Words[] = {
« List of C and C++ keywords »#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",
"sizeof", "typedef", "const", "extern",
"long", "static", "continue",
"false", "struct", "union", "bool", "default",
"float", "switch", "unsigned", "break",
"for", "case",
"do", "register", "void",
#endif
NULL };
int i;
for (i = 0;; ++i) {
if (Reserved_Words[i] == NULL)
return (0);
if (!strcmp (word, Reserved_Words[i])) {
return 1;
}
}
}
« I/O support »
void PrintHeader (void)
« Output Javascript and CSS to the header section »{
« First the Javascript - comes from http://www.netlobo.com/div_hiding.html » fprintf (stdout, "<script type=\"text/javascript\">\n");
fprintf (stdout, "<!--\n");
fprintf (stdout, "function toggleLayer( whichLayer, summary )\n");
fprintf (stdout, "{\n");
fprintf (stdout, " var elem, vis;\n");
fprintf (stdout, " if( document.getElementById ) // this is the way the standards work\n");
fprintf (stdout, " elem = document.getElementById( whichLayer );\n");
fprintf (stdout, " else if( document.all ) // this is the way old msie versions work\n");
fprintf (stdout, " elem = document.all[whichLayer];\n");
fprintf (stdout, " else if( document.layers ) // this is the way nn4 works\n");
fprintf (stdout, " elem = document.layers[whichLayer];\n");
fprintf (stdout, " vis = elem.style;\n");
fprintf (stdout, " // if the style.display value is blank we try to figure it out here\n");
fprintf (stdout, " if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)\n");
fprintf (stdout, " vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';\n");
fprintf (stdout, " vis.display = (vis.display==''||vis.display=='block')?'none':'block';\n");
fprintf (stdout, "\n");
fprintf (stdout, " if( document.getElementById ) // this is the way the standards work\n");
fprintf (stdout, " elem = document.getElementById( summary );\n");
fprintf (stdout, " else if( document.all ) // this is the way old msie versions work\n");
fprintf (stdout, " elem = document.all[summary];\n");
fprintf (stdout, " else if( document.layers ) // this is the way nn4 works\n");
fprintf (stdout, " elem = document.layers[summary];\n");
fprintf (stdout, " vis = elem.style;\n");
fprintf (stdout, " // if the style.display value is blank we try to figure it out here\n");
fprintf (stdout, " if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)\n");
fprintf (stdout, " vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';\n");
fprintf (stdout, " vis.display = (vis.display==''||vis.display=='block')?'none':'block';\n");
fprintf (stdout, "}\n");
fprintf (stdout, "// -->\n");
fprintf (stdout, "</script>\n");
fprintf (stdout, "\n");
« And then the CSS - derived from Tim Wakeham's page » fprintf (stdout, "<style>\n");
fprintf (stdout, ".hidecode {\n");
fprintf (stdout, " z-index:99;\n");
fprintf (stdout, " visibility:hidden;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".file {\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".file div {\n");
fprintf (stdout, " margin: auto;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, "div p {\n");
fprintf (stdout, " margin-left: 15px;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, "body {\n");
fprintf (stdout, " font-family: Calibri, Arial, Georgia, \"Times New Roman\", Times, serif;\n");
fprintf (stdout, " color: #000000;\n");
fprintf (stdout, "}\n\n");
fprintf (stdout, "h2, h3 {\n");
fprintf (stdout, " margin-bottom: 0px;\n color: #000000;\n");
fprintf (stdout, " }\n");
fprintf (stdout, "\n");
fprintf (stdout, "p {\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, "h2 {\n color: #000000;\n");
fprintf (stdout, " }\n");
fprintf (stdout, "\n");
fprintf (stdout, "h2 .link {\n");
fprintf (stdout, " font-size: small;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".link a {\n");
fprintf (stdout, " text-decoration: none;\n outline: none;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, "h2 .link a:hover {\n");
fprintf (stdout, " text-decoration: none;\n");
fprintf (stdout, " }\n");
fprintf (stdout, "\n");
fprintf (stdout, ".data {\n");
fprintf (stdout, " display: none;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".data pre {\n");
fprintf (stdout, " overflow: auto;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".data p {\n");
fprintf (stdout, " margin-top: 0px;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".summary {\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".summary pre {\n");
fprintf (stdout, " overflow: auto;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".summary p {\n");
fprintf (stdout, " margin-top: 0px;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".summary a {\n"); /* not sure... */
fprintf (stdout, " text-decoration: none;\n outline: none;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".show {\n");
fprintf (stdout, " text-decoration: none;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".show:hover {\n");
fprintf (stdout, " text-decoration: none;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".flinks {\n");
fprintf (stdout, " text-decoration: none;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, ".flinks:hover {\n");
fprintf (stdout, " text-decoration: none;\n color: #000000;\n");
fprintf (stdout, "}\n");
fprintf (stdout, "\n");
fprintf (stdout, "\n");
fprintf (stdout, "\n");
fprintf (stdout, "</style>\n");
}
« Four procedures to output DHTML <div>s to hide/display the nested layers »void UnexpandedStart (int seq)
{
stack[++top] = seq;
if (top > 0) fprintf (stdout, /* terminate link from previous block because nested links are bad! */
"</a>");
fprintf (stdout,
"<a href=\"javascript:toggleLayer('expanded_%d','unexpanded_%d')\" class=\"show\">",
seq, seq);
}
void UnexpandedFinish (void)
{
fprintf (stdout,
"<div class=\"show\" id=\"unexpanded_%d\"></div>",
stack[top]);
fprintf (stdout, "</a>");
}
void ExpandedStart (void)
{
int seq = stack[top];
if (top > 0) fprintf (stdout, /* terminate link from previous block because nested links are bad! */
"</a>"
"</font>");
fprintf (stdout,
"<div class=\"data\" id=\"expanded_%d\">"
"<font color=\"#000000\">"
"<a href=\"javascript:toggleLayer('expanded_%d','unexpanded_%d')\" class=\"show\">",
seq, seq, seq);
}
void ExpandedFinish (void)
{
--top;
fprintf (stdout, "</a>"
"</font>"
"</div>");
if (top >= 0) {
int seq = stack[top];
fprintf (stdout, /* re-instate link to allow collapse of previous block */
"<font color=\"#000000\">"
"<a href=\"javascript:toggleLayer('expanded_%d','unexpanded_%d')\" class=\"show\">",
seq, seq);
} else {
fprintf (stdout, "<font color=\"#000000\">");
}
}
int Print_HTML (FILE * fstream, char *Title)
« This is the main filter which loops over input C source and outputs HTML »{
FILE *InFile;
static int peekchar = -1;
int inchar, i, newline = 1, WordIdx = 0, savecol;
char word[280];
word[0] = '\0';
« Print out the HTML header. » « Open the file for reading in text mode. » /* Start reading it in, character by character. */
inchar = freadchar (InFile);
peekchar = fpeek (InFile);
while (!feof (InFile)) {
« Check for keywords (& print in bold), and simple tags (not bold) »
if (inchar == '\n') {
newline = 1;
}
if (!isspace (inchar)) {
savecol = col; /* note column position. this is to
re-indent <div>s which seem to be forced
to start on the next line */
« Handle all '#' preprocessor directives. » « Handle single line C++ style comments ('//'), and continue » « Handle traditional C-style comments and folding directives, and continue »
« Handle double-quotes, and continue »#ifdef NEVER
else if (inchar == '"') {
fprintf (fstream, "<font color=\"%s\">\"", QUOTE_COLOR);
if (peekchar == '"') {
/* Null string bug fix */
inchar = freadchar (InFile);
peekchar = fpeek (InFile);
printchar (inchar, fstream);
} else {
inchar = freadchar (InFile);
if (inchar == EOF)
continue;
peekchar = fpeek (InFile);
for (;;) {
if ((inchar != '\\') && (peekchar == '"'))
break;
printchar (inchar, fstream);
inchar = freadchar (InFile);
if (inchar == EOF)
break;
peekchar = fpeek (InFile);
}
printchar (inchar, fstream);
inchar = freadchar (InFile);
peekchar = fpeek (InFile);
printchar (inchar, fstream);
}
inchar = freadchar (InFile);
peekchar = fpeek (InFile);
fprintf (fstream, "</font>");
newline = 0;
continue;
}
#endif
/* Handle Double Quotes, and continue (fixed!). */
else if (inchar == '"') {
fprintf(fstream, "<font color=\"%s\">\"", QUOTE_COLOR);
for (;;) { // fix by simplifying
inchar = fgetc(InFile);
if (inchar == EOF) break;
if (inchar == '"') break;
if (inchar == '\\') {
printchar(inchar, fstream);
inchar = fgetc(InFile);
if (inchar == EOF) break;
}
printchar(inchar, fstream);
}
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
fprintf(fstream, "\"</font>");
newline = 0;
continue;
}
« Handle single-quotes, and continue » /* Any other characters drop through */
newline = 0;
}
/* Including white space. I think I made an exception for it as a quick
hack to remove initial spaces before a #define etc */
printchar (inchar, fstream); // print normal text here.
// move on to next character
inchar = freadchar (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;
}