#include <stdio.h>
#include <string.h>
#define STRLENGTH 262 /* room for massive name+ext or line */
/* All HTML tags used are here: */
#define HTMLSTR_HDGTOTITLE "<html>\n<head>\n<title>"
#define HTMLSTR_TITLE "Syntax coloring assignment \
by Laurie Sutherland"
#define HTMLSTR_CLOSEHDG "</title>\n</head>\n<body>\n<pre>\n"
#define HTMLSTR_CLOSEFILE "</pre>\n</body>\n</html>\n"
#define HTMLSTR_OPENSTR "<i>"
#define HTMLSTR_CLOSESTR "</i>"
#define HTMLSTR_OPENBOLD "<b>"
#define HTMLSTR_CLOSEBOLD "</b>"
/* ---------------------------------------
change_ext()
Takes in file name of C source file and
converts it to a .html
----------------------------------------- */
static int change_ext(char * inputname, char * inputname_html)
{
int i = 0;
if (strlen(inputname) > STRLENGTH-3)
return 1;
else {
while (inputname[i] != '.') {
inputname_html[i] = inputname[i];
i++;
}
inputname_html[i] = '\0';
strcat(inputname_html, ".html");
return 0;
}
}
/* ---------------------------------------
change_ltgtamp()
Takes in character streamed from file, and
pointer to destination file. Converts
<, >, and & for HTML legibility
----------------------------------------- */
static void change_ltgtamp(int c, FILE * outputfile) {
if (c == '<')
fputs("<", outputfile);
else if (c == '>')
fputs(">", outputfile);
else if (c == '&')
fputs("&", outputfile);
}
/* ---------------------------------------
output_word()
Takes in pointers to buffer and destination
file. Tests buffer word against C keywords;
outputs word as bold if there's a match,
or plain if there is not a match.
----------------------------------------- */
static void output_word(char * buffer, FILE * outputfile) {
char * * ptr_key;
char * keyword[] =
{ "auto", "break", "case", "char", "const",
"continue", "double", "default", "do", "else",
"enum", "extern", "float", "for", "goto",
"if", "int", "long", "register", "return",
"short", "signed", "sizeof", "static", "struct",
"switch", "typedef", "union", "unsigned", "void",
"volatile", "while", NULL };
ptr_key = &keyword[0];
while (*ptr_key != NULL) {
if (strcmp (*ptr_key, buffer) == 0) {
fputs(HTMLSTR_OPENBOLD, outputfile);
fputs(buffer, outputfile);
fputs(HTMLSTR_CLOSEBOLD, outputfile);
break;
}
ptr_key++;
}
if (*ptr_key == NULL)
fputs(buffer, outputfile);
}
/* ---------------------------------------
Syntax Coloring, Project 6, CIT593 Fall 04
by Laurie Sutherland
Converts a C source file to an HTML file,
with C keywords emboldened, and strings
italicized. Comments are set in "code"
formatting. Keywords in strings or comments
are ignored.
----------------------------------------- */
int main(int argc, char *argv[])
{
char * inputname_c; /* string name of input file */
char inputname_html[STRLENGTH]; /* for converted name */
FILE * inputfile; /* file pointer for input file */
FILE * outputfile; /* file pointer for ouput file */
char buffer[STRLENGTH]; /* holds words to be tested */
int c = 0; /* holds each input character */
int i = 1; /* loop increment */
/* Prepare input file - code adapted from Pat Palmer's
hexdump assignment */
if (argc > 1) { /* 1st arg should be filename */
inputname_c = argv[1];
/* Only allow .c */
if (strstr(inputname_c, ".c\0") == NULL) {
printf("The input argument must be a C source file (.c)\n");
return 0;
}
/* Create output filename, exit if error */
else {
if (change_ext(inputname_c, inputname_html) != 0) {
printf("Filename is too large\n");
return 0;
}
}/* close else */
} /* close filename if */
/* If no argument, exit */
else {
printf("filename argument required\n");
return 0; /* quit now if no argument */
}
/* Open the input file, to be read */
inputfile = fopen(inputname_c,"r");
if (inputfile == NULL) { /* file did not open */
printf("%s could not be opened\n", inputname_c);
return 0; /* quit now */
}
/* If file opened OK, create output file */
else {
outputfile = fopen(inputname_html, "w");
/* Start file with opening HTML tags */
fprintf(outputfile, "%s%s%s", HTMLSTR_HDGTOTITLE,
HTMLSTR_TITLE, HTMLSTR_CLOSEHDG);
while (1) {
/* Stream until end of file */
if ((c = fgetc(inputfile)) == EOF) {
break;
}
/* Store alpha and test when word is completed */
if (isalpha(c) != 0) {
for (i=0; i<STRLENGTH; i++) {
if (c == EOF) {
printf("\n***Error: Unclosed string\n");
return 1;
}
else if (isalpha(c) == 0)
break;
else
buffer[i] = c;
c = fgetc(inputfile);
} /* end for loop */
/* Add null character to word, test */
buffer[i] = '\0';
output_word(buffer, outputfile);
}
/* Stream comments without testing for
anything except <, >, & */
if (c == '/') {
fputc(c, outputfile);
c = fgetc(inputfile);
if (c == '*') {
while (1) {
if ((c=='<') || (c=='>') || (c=='&'))
change_ltgtamp(c, outputfile);
else
fputc(c, outputfile);
c = fgetc(inputfile);
if (c == '*') {
fputc(c, outputfile);
c = fgetc(inputfile);
if (c == '/')
break;
}
}
}
}
/* Convert <, >, or & */
if ((c=='<') || (c=='>') || (c=='&'))
change_ltgtamp(c, outputfile);
/* Stream what follows ', to ensure that
** " following ' is not considered beginning of string */
else if (c == '\'') {
fputc(c, outputfile);
i = 1;
while (1) {
c = fgetc(inputfile);
if (c=='<' || c=='>' || c=='&')
change_ltgtamp(c, outputfile);
else
fputc(c, outputfile);
/* Stop when second ' is reached, or after 4 char (max
** reference in single quotes) */
if (c == '\'' || i > 4)
break;
if (c == EOF) {
printf("\n***Error: Unclosed single quote\n");
return 1;
}
i++;
} /* end while */
} /* end else */
/* Italicize and stream strings */
else if (c == '"') {
fputs(HTMLSTR_OPENSTR, outputfile);
fputc(c, outputfile);
while (1) {
c = fgetc(inputfile);
if (c=='<' || c=='>' || c=='&')
change_ltgtamp(c, outputfile);
else
fputc(c, outputfile);
if (c == EOF) {
printf("\n***Error: Unclosed string\n");
return 1;
}
if (c == '"')
break;
}
fputs(HTMLSTR_CLOSESTR, outputfile);
} /* end else if " */
/* Any non-special characters can be output */
else
fputc(c, outputfile);
} /* close while */
fprintf(outputfile, "%s", HTMLSTR_CLOSEFILE);
fclose(outputfile);
} /* close else */
fclose(inputfile);
return 0;
} /* end main */