/* This is a hack of a hack - a VERY QUICK mod to ctohtml */
/* "included *"s in strings" */
/* Does BCPL use '''' or '*'' ? */
/* Probably need to fix '**' */
/* - I haven't handled either as my program doesn't use them */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define QUOTE_COLOR "#ff0000"
#define COMMENT_COLOR "#408080"
#define PREPROC_COLOR "#008000"
#define NUMBER_COLOR "#000080"
#ifndef FALSE
#define TRUE (0==0)
#define FALSE (0!=0)
#endif
/*
* BCPL to HTML converter. Converts BCPL code to HTML with syntax hilighting...
* Assumes any words in UPPER CASE must be keywords to print in bold.
* Works for my programs, probably no-one elses...
*/
int peekchar = -1;
int
IsReservedWord(char *word)
{
char c;
char *s=word;
int isword = TRUE;
if (word[1] == '\0') return(FALSE);
for (;;) {
c = *word++;
if (c == '\0') break;
if (isalpha(c) && islower(c)) return(FALSE); /* Not */
if (!isalpha(c)) isword = FALSE;
}
if (isword) { /* HACK!!! reduce to lower-case */
for (;;) {
if (*s == '\0') break;
if ((isalpha(*s)) && (isupper(*s))) *s = tolower(*s);
s += 1;
}
}
return(isword); /* It's a word, and there's no lower-case in it */
}
int
fpeek(FILE * f)
{
int ch;
ch = fgetc(f);
ungetc(ch, f);
return ch;
}
void
printchar(char inchar, FILE * fstream)
{
static int lastch = '\n', lineno = 1;
if (lastch == '\n') fprintf(fstream, "<a name=\"%0d\"><font color=black><em>%05d</em></font> ", lineno, lineno);
if (inchar == '&')
fprintf(fstream, "&");
else if (inchar == '>')
fprintf(fstream, ">");
else if (inchar == '<')
fprintf(fstream, "<");
else
if (inchar != 0) fputc(inchar, fstream);
if (inchar == '\n') lineno += 1;
lastch = inchar;
}
int
Print_HTML(FILE * fstream, char *Title)
{
FILE *InFile;
int inchar, i, newline = 1, WordIdx = 0; // currntly newline is NOT USED.
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)) {
/* identifiers */
if (isalpha(inchar) || (inchar == '_')) {
for (i = 0; i < 280; ++i) word[i] = 0;
WordIdx = 0;
for (;;) {
word[WordIdx++] = inchar;
if (isdigit(peekchar) || isalnum(peekchar) || (peekchar == '_') || (peekchar == '.')) {
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
} else break;
}
if (IsReservedWord(word)) {
printchar('\0', fstream); fprintf(fstream, "<b>%s</b>", word);
} else {
for (i = 0; i < WordIdx; ++i)
printchar(word[i], fstream);
}
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
continue;
}
if (isdigit(inchar)) {
printchar('\0', fstream); fprintf(fstream, "<font color=%s>", NUMBER_COLOR);
for (;;) {
printchar(inchar, fstream);
if (isdigit(peekchar)) {
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
} else break;
}
fprintf(fstream, "</font>");
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
continue;
}
/* numbers */
if (inchar == '#') {
printchar('\0', fstream); fprintf(fstream, "<font color=%s>", NUMBER_COLOR);
printchar(inchar, fstream); // #
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
if (inchar == 'X') {
printchar(inchar, fstream); // #X
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
}
for (;;) { // assert first char must be a digit
if (!isdigit(inchar)) break;
printchar(inchar, fstream); // #X0000000
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
}
fprintf(fstream, "</font>");
continue;
/* Handle single line comments. */
}
else if (((inchar == '/') && (peekchar == '/'))
|| ((inchar == '|') && (peekchar == '|'))) {
printchar('\0', fstream); 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 == '*')) {
printchar('\0', fstream); 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>", COMMENT_COLOR);
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
continue; /* Now process next char */
}
else if (((inchar == '/') && (peekchar == '\\'))
|| ((inchar == '\\') && (peekchar == '/'))) {
printchar('\0', fstream);
if (inchar == '/') {
// not well supported - fprintf(fstream, "<b>∧</b>");
//fprintf(fstream, "<b>∩</b>");// poor approximation
fprintf(fstream, "<b>%c%c</b>", inchar, peekchar);
} else { // ditto
//fprintf(fstream, "<b>∨</b>");
//fprintf(fstream, "<b>∪</b>");
fprintf(fstream, "<b>%c%c</b>", inchar, peekchar);
}
(void)fgetc(InFile); // skip second char
inchar = fgetc(InFile); // preload for next time around main loop
peekchar = fpeek(InFile);
continue;
}
/* Handle Blocks. */
else if ((inchar == '$') &&
((peekchar == '(') || (peekchar == ')'))) {
printchar('\0', fstream);
fprintf(fstream, "<b>");
printchar(inchar, fstream);
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
printchar(inchar, fstream);
fprintf(fstream, "</b>");
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
}
/* Handle Double Quotes. */
else if (inchar == '"') {
printchar('\0', fstream); 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;
if ((inchar == '*') && (peekchar == '*')) {
printchar(inchar, fstream);
inchar = fgetc(InFile);
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;
}
/* Handle Single Quotes. */
else if (inchar == '\'') {
printchar('\0', fstream); fprintf(fstream, "<font color=%s>'", QUOTE_COLOR);
inchar = fgetc(InFile);
if (inchar == EOF) continue;
peekchar = fpeek(InFile);
printchar(inchar, fstream);
if (inchar == '*') {
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
printchar(inchar, fstream);
}
/* inchar should be closing ' */
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
printchar(inchar, fstream);
fprintf(fstream, "</font>");
inchar = fgetc(InFile);
peekchar = fpeek(InFile);
newline = 0;
continue;
}
newline = 0;
} else {
// it was a space...
}
// all drop through cases are single characters to be printed
printchar(inchar, fstream);
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;
}