/********************************************************************************/
/* */
/* File: c2html.cpp */
/* Auth: Ben Kenwright */
/* Email: bkenwright@xbdev.net */
/* Url: www.xbdev.net */
/* Date: 01/01/06 */
/* */
/********************************************************************************/
/*
About?
Well its such a simple program, and I'm sure everyone has wrote one, one time
or another.
Convert our code, c/c++ so that its colour coded! This code takes it a bit
further and generates a html file, so you can take your c/c++ text file
and output a html file which will have all the great colour coding!
I've kept it simple, as you can mix the html so it uses styles and .css files
but I like to use the font color html tag....but its very easy to convert
to the alternative method if you prefair.
To use?
Open a dos prompt, and do:
C:>c2html.exe test.cpp test.html
Which will take test.cpp and create test.html as your output html file :)
Note:
Because, fopen was depreciated by ms! To compile under visual studio we
have to include the '_CRT_SECURE_NO_DEPRECATE' macro
Further work / Thinking:
o Bit of modification a simple notepad c/c++ colour coding app can be done.
o Put the dos app in your C directory, and then you can convert any code
to colour coded html whenever you want :)
*/
/********************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
//--------------------------------------------------------------------------------
#define ZCOMMENT "<font color=\"navy\">"
#define ZSTRING "<font color=\"green\">"
#define ZMACRO "<font color=\"violet\">"
#define ZKEYWORDS "<font color=\"maroon\">"
#define ZDECLARATIONS "<font color=\"maroon\">"
#define ZUNIQUE "<font color=\"red\">"
//--------------------------------------------------------------------------------
void Parse(FILE *fd);
bool IsMacro(char *buffer);
void IsToken(char *buffer);
void PutChar(int c);
//--------------------------------------------------------------------------------
void PageHead(void);
void PageFoot(void);
void FileStart(char *file);
void FileEnd(void);
//--------------------------------------------------------------------------------
//#define DEBUGME
/********************************************************************************/
/* */
/* Program Entry Point */
/* */
/********************************************************************************/
int main(int argc, char **argv)
{
FILE *fd;
#ifdef DEBUGME
fd = fopen("c2html.cpp", "r");
PageHead();
FileStart(*argv);
Parse(fd);
FileEnd();
PageFoot();
fclose(fd);
return 0;
#endif // DEBUGME
if (argc < 2)
{
fprintf(stderr, "./c2html file1, file2, ..\n");
return 0;
}
PageHead();
// This is so we can parse multiple files
while (--argc > 0)
{
if ((fd = fopen(*++argv, "r")) == NULL)
{
fprintf(stderr, "Error: Unable to open file\n");
return -1;
}
FileStart(*argv);
Parse(fd);
FileEnd();
fclose(fd);
}
PageFoot();
return 0;
}// End main(..)
//--------------------------------------------------------------------------------
void Parse(FILE *fd)
{
// temp character
int c;
while (true)
{
// Reached the end of the file
if ((c = getc(fd)) == EOF)
return;
// Start of a comment
if (c == '/')
{
// Reached end of the file
if ((c = getc(fd)) == EOF)
return;
if (c == '/' || c == '*')
{
// Its a comment
int ch[2];
int comment;
ch[0] = c;
// This is so we know what type of comment where looking at
// Either /* or //, so we know to look for the */ or /n to end
// the comment
comment = c;
printf(ZCOMMENT "/");
PutChar(c);
for (;;)
{
if ((ch[1] = getc(fd)) == EOF)
return;
PutChar(ch[1]);
if (comment == '/' && ch[1] == '\n')
{
// End of the comment
break;
}
else if (comment == '*' && ch[0] == '*' && ch[1] == '/')
{
// End of comment
break;
}
ch[0] = ch[1];
}
printf("</font>");
}
else
{
ungetc(c, fd);
printf("/");
}
}
else if (c == '\'' || c == '"')
{
// Quotation
int quote;
int back_slash;
printf(ZSTRING);
quote = c;
back_slash = 0;
PutChar(c);
for (;;)
{
if ((c = getc(fd)) == EOF)
{
return;
}
PutChar(c);
if (c == quote && !back_slash)
{
break;
}
if (c == '\\' && !back_slash)
{
back_slash = 1;
}
else
{
back_slash = 0;
}
}
printf("</font>");
}
else if (c == '#')
{
// Start of a macro
printf(ZMACRO);
PutChar(c);
for (;;)
{
if ((c = getc(fd)) == EOF)
{
return;
}
if (isspace(c))
{
PutChar(c);
}
else
{
break;
}
}
char buffer[32];
memset(buffer, 0, 32);
buffer[0] = c;
for (int i = 1; i < 32; i++)
{
if ((c = getc(fd)) == EOF)
return;
if (isalpha(c))
buffer[i] = c;
else
break;
}
if (IsMacro(buffer))
{
// Is End Macro
printf("%s</font>", buffer);
}
else
{
// Is Start Macro
printf("</font>%s", buffer);
}
PutChar(c);
}
else
{
if (islower(c) || isalnum(c) || c == '_')
{
int i;
char buffer[32];
memset(buffer, 0, 32);
buffer[0] = c;
for (i = 1; i < 32; i++)
{
if ((c = getc(fd)) == EOF)
return;
if (islower(c) || isalnum(c) ||
c == '_')
buffer[i] = c;
else
break;
}
IsToken(buffer);
PutChar(c);
}
else
{
PutChar(c);
}
}
}
return;
}// End Parse(..)
//--------------------------------------------------------------------------------
bool IsKeyword(char *buffer)
{
const char *keywords[] =
{
"break", "case", "continue", "default", "do", "else", "for",
"goto", "if", "return", "sizeof", "switch", "while"
};
for (int i = 0; i < sizeof(keywords) / sizeof(*keywords); i++)
{
if (!strcmp(keywords[i], buffer))
{
return true;
}
}
return false;
}// End IsKeyword(..)
//--------------------------------------------------------------------------------
bool IsDecl(char *buffer)
{
const char *declarations[] =
{
"auto", "char", "const", "DIR", "double", "enum", "extern",
"FILE", "float", "fpos_t", "int", "int8_t", "int16_t",
"int32_t", "int64_t", "long", "mode_t", "pid_t", "register",
"short", "signed", "size_t", "ssize_t", "static", "struct",
"typedef", "union", "unsigned", "va_list", "void", "volatile",
"class", "public", "protected", "private"
};
for (int i = 0; i < sizeof(declarations) / sizeof(*declarations); i++)
{
if (!strcmp(declarations[i], buffer))
{
return true;
}
}
return false;
}// End IsDecl(..)
//--------------------------------------------------------------------------------
bool IsUniq(char *buffer)
{
const char *unique[] =
{
"__DATE__", "__TIME__", "EACCES", "EAGAIN", "EBADF",
"EBUSY", "EOF", "ECHILD", "EDEADLK", "EDOM",
"EFAULT", "EINVAL", "EILSEQ", "EINTR", "EFBIG",
"EISDIR", "stdin", "EMFILE", "EMLINK", "EMSGSIZE",
"ENFILE", "ENODEV", "ENOENT", "ENOLCK", "stdout",
"ENOMEM", "ENOTDIR", "ENOSPC", "ENOSYS", "ENOTEMPTY",
"ENOTSUP", "ENOTTY", "ENOEXEC", "ENXIO", "ECANCELED"
"EPIPE", "ERANGE", "EROFS", "ESPIPE", "ESRCH",
"EXDEV", "__FILE__", "__LINE__", "NULL", "SEEK_SET",
"SEEK_CUR", "SEEK_END", "SIGABRT", "SIGALRM", "SIGCHLD",
"SIGCONT", "SIG_DFL", "SIG_ERR", "SIGHUP", "SIG_IGN",
"SIGINT", "SIGFPE", "SIGKILL", "SIGQUIT", "SIGSEGV",
"SIGSTP", "SIGTERM", "SIGTRAP", "SIGTTIN", "SIGTTOU",
"SIGUSR1", "SIGUSR2", "__STDC__", "stderr", "EINPROGRESS",
"E2BIG" "EBADMSG", "EEXIST", "EIO", "ENAMETOOLONG",
"SIGILL", "EPERM", "SIGSTOP", "ETIMEDOUT",
};
for (int i = 0; i < sizeof(unique) / sizeof(*unique); i++)
{
if (!strcmp(unique[i], buffer))
{
return true;
}
}
return false;
}// End IsUniq(..)
//--------------------------------------------------------------------------------
bool IsNumber(char *buffer)
{
int i = 1, hex = 0;
while (*buffer)
{
if (isdigit(*buffer))
{
;
}
else if ((*buffer == 'x' || *buffer == 'X') && i == 2)
{
hex = 1;
}
else if (hex &&
(*buffer == 'a' || *buffer == 'A' ||
*buffer == 'b' || *buffer == 'B' ||
*buffer == 'c' || *buffer == 'C' ||
*buffer == 'd' || *buffer == 'D' ||
*buffer == 'e' || *buffer == 'E' ||
*buffer == 'f' || *buffer == 'F'))
{
;
}
else
{
return false;
}
buffer++;
i++;
}
return true;
}// End IsNumber(..)
//--------------------------------------------------------------------------------
bool IsMacro(char *buffer)
{
const char *macros[] =
{
"define", "elif", "else", "endif", "error", "if",
"ifdef", "ifndef", "include", "line", "pragma"
};
for (int i = 0; i < sizeof(macros) / sizeof(*macros); i++)
{
if (!strcmp(macros[i], buffer))
{
return true;
}
}
return false;
}// End IsMacro(..)
//--------------------------------------------------------------------------------
void IsToken(char *buffer)
{
if (IsKeyword(buffer))
{
printf(ZKEYWORDS "%s</font>", buffer);
}
else if (IsDecl(buffer))
{
printf(ZDECLARATIONS "%s</font>", buffer);
}
else if (IsUniq(buffer) || IsNumber(buffer))
{
printf(ZUNIQUE "%s</font>", buffer);
}
else
{
printf(buffer);
}
}// End IsToken(..)
//--------------------------------------------------------------------------------
void PutChar(int c)
{
switch (c)
{
case '<':
{
printf("<");
}
break;
case '>':
{
printf(">");
}
break;
case '&':
{
printf("&");
}
break;
default:
{
printf("%c", c);
}
break;
}
}// End PutChar(..)
//--------------------------------------------------------------------------------
void PageHead(void)
{
printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
printf("<html>\n");
printf("<head>\n");
printf("<title>www.xbdev.net c2html demo</title>\n");
printf("</head>\n");
printf("<body>\n\n");
}// End PageHead(..)
//--------------------------------------------------------------------------------
void PageFoot(void)
{
printf("\n\n</body>\n");
printf("</html>\n");
}// End PageFoot(..)
//--------------------------------------------------------------------------------
void FileStart(char *file)
{
printf("<h2>%s</h2>\n", file);
printf("<pre>\n");
}// End FileStart(..)
//--------------------------------------------------------------------------------
void FileEnd(void)
{
printf("</pre>\n");
printf("<hr />\n");
}// End FileEnd(..)
//--------------------------------------------------------------------------------
|