/* CopyRight (C) 1999, Dmitry Obukhov, dso@usa.net mailto: dso@usa.net http://www.EmbeddedStuff.com ---------------------------------------------- Last modified 6 Apr 97 ---------------------------------------------- Converts C (C++) source to HTML code fragment with syntax highlighting. Since program written for personal purpose the tags generated. This is optional page format specific thing. Usage: CTHM . All output is done to STDOUTPUT, error messages to STDERR. For HTML fragment generation: CHTM file.c > file.htm - Some input convertion required to use this code as CGI module. Will be done soon. - Optimization required for blocks of EOL comments */ #include // ------------------- Decoding status values #define START 0 #define INLINE 1 #define DEFINE 2 // ------------------- Decoding Remark #define REM1 20 #define REM2 21 #define REM_END 22 #define REM_STAR 23 #define REM_STAR_1 24 #define STRING 25 // String is "like" remark // ------------------- HTML TAG Generation #define ON 1 #define OFF 0 // ------------------- HTML TAG type #define MODE_KEYWORD 0 #define MODE_REMARK 2 #define MODE_REMARK_EOL 4 #define MODE_DEFINE 6 #define MODE_STRING 8 int is_delimeter(char c) { int ii=0; char dlms[] = "\t\r\n (){}[]+-*/%\"'&|^~:;<>.,"; //-------------------------------- while (dlms[ii]) { if (c==dlms[ii++]) return 1; } return 0; } int is_keyword(char * str) { char * kwords[] = { "asm", "auto", "break", "case", "cdecl", "char", "class", "const", "continue", "default", "delete", "do", "double", "else", "enum", "extern", "far", "float", "for", "friend", "goto", "huge", "if", "inline", "int", "interrupt", "long", "near", "new", "operator", "pascal", "private", "protected", "public", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "template", "this", "typedef", "union", "unsigned", "virtual", "void", "volatile", "while", NULL }; int ii=0; int jj; int check; while (kwords[ii]) { jj = 0; check = 1; while (kwords[ii][jj] && check) { if (str[jj] != kwords[ii][jj]) { check = 0; } jj++; } if (check) return 1; ii++; } return 0; } void set_mode(int on_off, int mode) { char * tags[] = { //-------------------- KEYWORD "", "", //-------------------- Classic remarks "", "", //-------------------- EOL Remarks "", "", //-------------------- #DEFINE "", "", //-------------------- "string" "", "", NULL, NULL }; fprintf(stdout,tags[mode + 1 - on_off]); } void print_char_html(char c) { switch (c) { case '<': fprintf(stdout,"<"); break; case '>': fprintf(stdout,">"); break; case '"': fprintf(stdout,"""); break; case '&': fprintf(stdout,"&"); break; case '|': fprintf(stdout,"¦"); break; default: fprintf(stdout,"%c",c); } } int main(int _argc, char** _argv) { FILE *in, *out; char c; int mode; char buf[80]; int bufidx = 0; int progress = 1; int echo; int saved_mode; int kw; char tmpc; char prevc; if (_argc < 2) { fprintf(stderr, "USAGE: c2html \n"); return 1; } if ((in = fopen(_argv[1], "rt")) == NULL) { fprintf(stderr, "Cannot open input file.\n"); return 1; } fprintf(stdout, "
");
   mode = START;

   while (!feof(in) && progress)
   {
        echo = 1;
        prevc = c;
        c = fgetc(in);

        if (c=='/' && (mode < REM1))
        {
            saved_mode = mode;
            mode = REM1;
        }

        switch (mode)
        {
            case REM1:
                 echo = 0;
                 mode = REM2;
                 break;

            case REM2:
                 if (c=='/')
                 {
                    if (saved_mode == DEFINE)
                    {
                      set_mode(OFF, MODE_DEFINE);
                    }
                    mode = REM_END;
                    set_mode(ON, MODE_REMARK_EOL);
                 }
                 else if (c=='*')
                 {
                    if (saved_mode == DEFINE)
                    {
                      set_mode(OFF, MODE_DEFINE);
                    }
                    mode = REM_STAR;
                    set_mode(ON, MODE_REMARK);
                 }
                 else
                 {
                    mode = saved_mode;
                 }
                 printf("/");
                 break;

            case REM_END:
                 if (c=='\n')
                 {
                   set_mode(OFF, MODE_REMARK_EOL);
                 }
                 break;

            case REM_STAR:
                 if (c=='*')
                 {
                    mode = REM_STAR_1;
                 }
                 break;

            case REM_STAR_1:
                 if (c=='/')
                 {
                    mode = INLINE;
                    fprintf(stdout,"/");
                    echo = 0;
                    set_mode(OFF, MODE_REMARK);
                 }
                 else mode = REM_STAR;
                 break;

            case START:
                 if (c=='#')
                 {
                    mode = DEFINE;
                    set_mode(ON, MODE_DEFINE);
                    break;
                 }
                 else if (c==' ') break;

                 mode = INLINE;
                 // and continue in next case

            case INLINE:
                 if (c=='"' &&        //
                     prevc != 0x27 && //
                     prevc != '\\')   //
                 {
                    set_mode(ON, MODE_STRING);
                    mode = STRING;
                 }
                 break;

            case STRING:
                 if (c=='"' && prevc != '\\')
                 {
                    print_char_html('"');
                    set_mode(OFF, MODE_STRING);
                    echo = 0;
                    mode = INLINE;
                 }
                 break;

            case DEFINE:
                 if (c=='\n')
                 {
                    set_mode(OFF, MODE_DEFINE);
                 }
                 break;

        }

        if (echo && //
            (mode == INLINE || //
             (mode!=INLINE &&  //
              bufidx)))        //
        {
            buf[bufidx++] = c;
            buf[bufidx]   = 0;
            if (is_delimeter(c))
            {
                kw = 0;
                if (bufidx>2)
                {
                  kw = is_keyword(buf);
                }
                if (kw)
                {
                  set_mode(ON, MODE_KEYWORD);
                }
                tmpc = buf[bufidx-1];
                buf[bufidx-1] = 0;
                fprintf(stdout,"%s",buf);
                if (kw)
                {
                  set_mode(OFF, MODE_KEYWORD);
                }
                print_char_html(tmpc);
                bufidx = 0;
                buf[0] = 0;
            }
        }
        else if (echo) print_char_html(c);

        if (c=='\n' && mode != REM_STAR)
        {
            mode = START;
        }
   }

   fclose(in);
   fprintf(stdout,"
\n"); fprintf(stdout, "\n"); fprintf(stdout, "\n"); return 0; }