SRC: C/C++ to HTML source code converter
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 02.09.02 07:44
Оценка:
Сабж, в общем...

Для работы класса нужен класс, который приведен здесь:

SRC: Hash function (based on CRC-32)
Автор: Flamer
Дата: 29.08.02



Хидер:


// CPPConv.h header file
//---------------------------------------------------------------------------
#ifndef CPPConvH
#define CPPConvH
//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//---------------------------------------------------------------------------
#include "Hash.h"
//---------------------------------------------------------------------------
#define BUF_SIZE 1024       // размер приемного буфера
#define MAX_KWD_LEN 50      // максимальная длина ключевого слова
#define KEYWORDS_COUNT 95   // количество клчевых слов
//---------------------------------------------------------------------------
typedef enum {      // состояния автомата

psEmpty,            // пустое
psMultiLineDefine,  // обработка многострочного #define
psMultiLineComment // обработка многострочного комментария

}enParseState;
//---------------------------------------------------------------------------
class CPPConv
{
private:
    unsigned int HashTable[KEYWORDS_COUNT];
        static char* Keywords[KEYWORDS_COUNT];
    FILE* fIn;
    FILE* fOut;
        char* buffer;
    enParseState ParseState;

private:

    void CloseHandles();
    void Reset();
    bool MakeHashTable();
    void PutString(FILE* outfile, const char* str, bool bConvert);
    inline bool IsSingleLineComment(char ch){return (ch=='/');};
    inline bool IsMultiLineComment(char ch){return (ch=='*');};
    void WriteSpaces(FILE* outfile,int Num);
    void ParseString(FILE* outfile, const char* s);
    bool IsDelimiter(char ch);
    bool IsKeyword(char* s);
    bool IsDigit(char* s);
    void PutChar(FILE* outfile,char ch);

public:

bool Convert(const char* InputFileName, const char* OutputFileName);


public:
  CPPConv();
  ~CPPConv();

};
//---------------------------------------------------------------------------
#endif


Сорц:

//CPPConv.cpp implementation file
//---------------------------------------------------------------------------
#include "CPPConv.h"
//---------------------------------------------------------------------------
char* CPPConv::Keywords[] = {

"__asm", "__automated","__cdecl","__classid",
"__closure","__declspec","__dispid","__explicit",
"__export","__fastcall","__finally","__import",
"__int16","__int32","__int64","__int8","__pascal",
"__property","__published","__rtti","__stdcall",
"__thread","__try","_asm","_cdecl","_export",
"_fastcall","_import","_pascal","_stdcall","asm",
"auto","bool","break","case","catch","cdecl","char",
"class","const","const_cast","continue","default",
"delete","do","double","dynamic_cast","else","enum",
"explicit","extern","false","float","for","friend",
"goto","if","inline","int","long","mutable","namespace",
"new","operator","pascal","private","protected","public",
"register","reinterpret_cast","return","short","signed",
"sizeof","static","static_cast","struct","switch","template",
"this","throw","true","try","typedef","typeid","typename",
"union","unsigned","using","virtual","void","volatile",
"wchar_t","while","while2"

};
//---------------------------------------------------------------------------
CPPConv::CPPConv(): fIn(NULL),fOut(NULL),buffer(NULL),ParseState(psEmpty)
{
}    
//---------------------------------------------------------------------------
CPPConv::~CPPConv()
{
 CloseHandles();
 Reset();
}
//---------------------------------------------------------------------------
void CPPConv::CloseHandles()
{
 if(fIn)
  {
   fclose(fIn);
   fIn=NULL;
  }

  if(fOut)
  {
   fclose(fOut);
   fOut=NULL;
  }

}
//---------------------------------------------------------------------------
void CPPConv::Reset()
{

  if(buffer)
   {
    delete [] buffer;
    buffer=NULL;
   }


ParseState=psEmpty;
}
//---------------------------------------------------------------------------
void CPPConv::WriteSpaces(FILE* outfile,int Num)
{
 if(Num) for(int i=0;i<Num;i++)
     fputs("&nbsp;",outfile);
} 
//---------------------------------------------------------------------------
bool CPPConv::Convert(const char* InputFileName, const char* OutputFileName)
{
if(!InputFileName || !OutputFileName) return false;

 CloseHandles();
 Reset();


 buffer = new char[BUF_SIZE];
 if(!buffer) return false;

 fIn = fopen(InputFileName, "r");
 if(!fIn) return false;

 fOut = fopen(OutputFileName,"w");
 if(!fOut) return false;

 if(!MakeHashTable()) return false;

 bool EmptyStr;

 PutString(fOut,"<DIV STYLE=\"background-color:#FFFFFF\">",false);
 PutString(fOut,"<FONT COLOR=\"#000000\">",false);
 PutString(fOut,"<FONT FACE=\"Courier New\" STYLE=\"font-size:14px;\">",false);

  while(true)
  {
   if(!fgets(buffer,BUF_SIZE-1,fIn)) break;

   int cntr=0;
   EmptyStr=false;

  int NumSpaces=-1;

   while(isspace(buffer[cntr]))
    {
     if(buffer[cntr]=='\t')NumSpaces+=4;
     else NumSpaces+=1;
     cntr++;
    }

     int ended = strlen(buffer);

     while(isspace(buffer[ended]))
        {
       buffer[ended]='\0';
       ended--;
      }

  unsigned cur_buf_len = strlen(buffer);
  if((unsigned)cntr == cur_buf_len || !cur_buf_len) EmptyStr=true;

    WriteSpaces(fOut,NumSpaces); // write beginning &nbsp;'s

    if((unsigned)cntr<cur_buf_len)
     {
       switch(buffer[cntr])
        {
         case'#':
            {
             if(ParseState==psMultiLineDefine)
              {
               ParseState=psEmpty;
               PutString(fOut,"</FONT>",false);
              }

             if(ParseState!=psMultiLineComment)
                 PutString(fOut,"<FONT COLOR=#008000>",false);

             int ended = strlen(buffer);
             while(isspace(buffer[ended])) ended--;
             if(ended>=2)// not empty string
              {

                bool bStringFound=false;
                bool bCommentFound=false;
                int i;
                for(i=cntr;i<ended;i++)
                    {

                    if(buffer[i]=='"')
                        {
                        if(i>0 && buffer[i-1]!='\\' && !bStringFound) bStringFound=true;
                        if(i>0 && buffer[i-1]!='\\' && bStringFound)  bStringFound=false;
                        }

                    if(buffer[i]=='/')
                        {
                            if((buffer[i+1]=='*' && !bStringFound) || (buffer[i+1]=='/' && !bStringFound))
                                {
                                 bCommentFound=true;
                                 if(ParseState!=psEmpty)
                                   {
                                    PutString(fOut,"</FONT>",false);
                                    ParseState=psEmpty;
                                   }
                                 break;
                            }

                        }
                    }//for


               if(bCommentFound)
                {
                char ch = buffer[i-1];
                buffer[i-1]='\0';
                                PutString(fOut,buffer,true);
                PutString(fOut,"</FONT>",false);

                buffer[i-1]=ch;
                char* ptr = &buffer[i-1];
                ParseString(fOut,ptr);

                }


               if(buffer[ended-2]=='\\' && !bCommentFound) // multiline define
                 {
                 buffer[i-1]='\0';
                                 PutString(fOut,buffer,true);
                 ParseState=psMultiLineDefine;
                 }
                else if(!bCommentFound) // singleline define
                 {
                 buffer[i-1]='\0';
                                 PutString(fOut,buffer,true);
                 if(ParseState !=psMultiLineComment) PutString(fOut,"</FONT>",false);
                 }
              }

            }
         break;

         case '/': // possible single- or multiline comment
           {

           if((unsigned)cntr+1<(unsigned)strlen(buffer))
               {
                if(IsSingleLineComment(buffer[cntr+1]))
                  {
                   if(ParseState != psMultiLineComment)
                     {
                      if(ParseState==psMultiLineDefine)
                        {
                         PutString(fOut,"</FONT>",false);
                         ParseState = psEmpty;
                        }

                     PutString(fOut,"<FONT COLOR=#008000>",false);
                     }
                   PutString(fOut,buffer,true);
                   if(ParseState != psMultiLineComment)    PutString(fOut,"</FONT>",false);

                  }
                  else if(IsMultiLineComment(buffer[cntr+1])) // begin multiline comment
                  {
                     if(ParseState != psMultiLineComment)
                      {
                      ParseState = psMultiLineComment;
                      PutString(fOut,"<FONT COLOR=#008000>",false);

                      ParseString(fOut,buffer);
                      }
                  }
                 else ParseString(fOut,buffer);
               }
              else PutString(fOut,buffer,true);

           }
         break;

         case '*':
          {
              if((unsigned)cntr+1<(unsigned)strlen(buffer)) // end of multiline comment
                    ParseString(fOut,buffer);

          }
         break;


         default:
         // default string processing


        if(ParseState!=psMultiLineDefine)ParseString(fOut,buffer);
        else PutString(fOut,buffer,true);

         if(ParseState==psMultiLineDefine && buffer[strlen(buffer)-2]!='\\')
              {
               ParseState=psEmpty;
               PutString(fOut,"</FONT>",false);
              }

         if(ParseState==psMultiLineDefine && EmptyStr)  ParseState=psEmpty;


         break;
        }
     }//if(cntr<strlen(buffer))
     else
      {
         if(ParseState==psMultiLineDefine)
              {
               ParseState=psEmpty;
               PutString(fOut,"</FONT>",false);
              }
      }

   memset(buffer,0,BUF_SIZE);
   PutString(fOut,"<BR>",false);
  }

PutString(fOut,"</FONT></FONT></DIV>",false);

return true;
}
//---------------------------------------------------------------------------
void CPPConv::PutChar(FILE* outfile,char ch)
{
if(ch=='<') PutString(outfile,"&lt;",false);
else if(ch=='>') PutString(outfile,"&gt;",false);
else if(ch=='&') PutString(outfile,"&amp;",false);
else fputc(ch,outfile);
}
//---------------------------------------------------------------------------
void CPPConv::ParseString(FILE* outfile, const char* s)
{
if(!s) return;
static char kwd_buff[MAX_KWD_LEN] = {0};
memset(kwd_buff,0,MAX_KWD_LEN);

int s_len = strlen(s);
if(!s_len) return;


  int cntr=0;
  bool EmptyStr=false;

  while(isspace(s[cntr])) cntr++;

 if(cntr == s_len) EmptyStr=true;
 if(EmptyStr) return;


int buff_offset=0;

bool bStringFound=false;

if(ParseState==psMultiLineComment)
 {
  bool bEndOfMLFound=false; // end of multiline comment flag

   for(int i=cntr;i<s_len;i++)
    {
     if(s[i]=='"')
       {
        if(i>0 && s[i-1]!='\\' && !bStringFound) bStringFound=true;
        if(i>0 && s[i-1]!='\\' && bStringFound)  bStringFound=false;
       }
     if(s[i]=='*')
      {
       if(s[i+1]=='/' && !bStringFound)
         {
          // found end of multiline comment
          // copy portion of string (cntr, i+1) to buffer
          bEndOfMLFound=true;
            for(int y=cntr;y<i+2;y++)
              {
               PutChar(outfile,s[y]);
              }
            PutString(outfile,"</FONT>",false);
            ParseState=psEmpty;
          cntr = i+2; break;
         }
      }
    }//for
    if(!bEndOfMLFound)
     {
     PutString(outfile,s,true);
     return;
     }
 }

for(int i=cntr;i<s_len;i++)
 {

 if(s[i]=='"' /*&& i>0*/ && s[i-1]!='\\' && s[i-1]!='\'') // string begin
  {

   PutString(outfile,"<FONT COLOR=#000080><B>",false);
   PutChar(outfile,s[i]);

    int j;
     for(j=i+1;j<s_len;j++)
      {

       if(s[j]=='"') // end string
         {
         if((s[j-1] =='\\' && s[j-2] =='\\') || s[j-1] !='\\')
           {
            fputc(s[j],outfile);
            break;
           }
         }
         

         PutChar(outfile,s[j]);
      }
   PutString(outfile,"</B></FONT>",false);
   i=j; continue;
}


 if(IsSingleLineComment(s[i]) && IsSingleLineComment(s[i+1]))
  {
  //beginning single-line comment
  PutString(outfile,kwd_buff,true);
  PutString(outfile,"<FONT COLOR=#008000>",false);

   for(int j=i;j<s_len;j++)PutChar(outfile,s[j]);
   PutString(outfile,"</FONT>",false);

   return;
  }

  if(IsSingleLineComment(s[i]) && IsMultiLineComment(s[i+1])) //begin multi-line comment
  {
  PutString(outfile,kwd_buff,true);
  PutString(outfile,"<FONT COLOR=#008000>",false);
    bool bToEnd=true;
    int j;
    for(j=i;j<s_len;j++)
     {
     if(IsMultiLineComment(s[j]) && IsSingleLineComment(s[j+1]))
       {
       PutChar(outfile,s[j]);
       PutChar(outfile,s[j+1]);
       PutString(outfile,"</FONT>",false);
       bToEnd=false;
       break;
       }
      else      PutChar(outfile,s[j]);

     }
      if(bToEnd)
       {
       ParseState = psMultiLineComment;
       return;
       }
      else
      {
       buff_offset=0;
       memset(kwd_buff,0,MAX_KWD_LEN);
       i=j+1;continue;
      }
  }

  if(IsMultiLineComment(s[i]) && IsSingleLineComment(s[i+1])) // End of multiline comment
   {
   PutString(outfile,kwd_buff,true);
   PutChar(outfile,s[i]);
   PutChar(outfile,s[i+1]);
   PutString(outfile,"</FONT>",false);
   ParseState = psEmpty;
   buff_offset=0;
   memset(kwd_buff,0,MAX_KWD_LEN);
   i++; continue;
   }

  if(isspace(s[i]) ||/* ispunct(s[i]) || */IsDelimiter(s[i]))
   {
   if(IsKeyword(kwd_buff))
    {
     PutString(outfile,"<FONT COLOR=#0000FF>",false);
        PutString(outfile,kwd_buff,true);
     PutString(outfile,"</FONT>",false);
    }
    else if(IsDigit(kwd_buff))
    {
     PutString(outfile,"<FONT COLOR=#D00000><B>",false);
       PutString(outfile,kwd_buff,true);
     PutString(outfile,"</B></FONT>",false);
    }
    else // simple put !!!
       PutString(outfile,kwd_buff,true);

   buff_offset=0;
   memset(kwd_buff,0,MAX_KWD_LEN);

   PutChar(outfile,s[i]);

   } //if(isspace(s[i]) || ispunct(s[i]) || is_delimiter(s[i]))
   else
   {
   kwd_buff[buff_offset] = s[i];
   buff_offset++;
   }

 }


}
//---------------------------------------------------------------------------
bool CPPConv::IsDigit(char* s)
{
if(!s) return false;
while(isspace(*s) || IsDelimiter(*s))s++;

int ended = strlen(s);
 while(isspace(s[ended]) || IsDelimiter(s[ended]))
  {
   s[ended]='\0';
   ended--;
  }
 int s_len = strlen(s);
 bool bRet=false;
 if(s_len==1 && s[0]=='0') bRet=true;
 else
  {
   int result = atoi(s);
    if(result!=0) bRet=true;
    else
     {
          if(s_len>2 &&  s[0]=='0' && s[1]=='x' ) bRet=true;
         if(s_len>1 && s[0]=='0' && (s[s_len-1]=='L' || s[s_len-1]=='l')) bRet=true;
     }

  }
return bRet;
}
//---------------------------------------------------------------------------
bool CPPConv::IsKeyword(char* s)
{
 if(!s) return false;
 while(isspace(*s) || IsDelimiter(*s))s++;
 int ended = strlen(s);
 while(isspace(s[ended]) || IsDelimiter(s[ended]))
  {
   s[ended]='\0';
   ended--;
  }

 unsigned int hash = GetHash(s);

  for(int i=0;i<KEYWORDS_COUNT;i++)
    if(HashTable[i]==hash) return true;


 return false;
}
//---------------------------------------------------------------------------
bool CPPConv::IsDelimiter(char ch)
{
 switch(ch)
  {
  case '|':
  case '(':
  case ')':
  case '&':
  case '*':
  case '[':
  case ']':
  case ':':
  case ';':
  case '/':
  case '^':
  case '%':
  case '!':
  case '~':
  case '=':
  case '+':
  case '<':
  case '>':
  case '\t':
  case ' ':
  case '.':
  case ',':
  case '{':
  case '}':
  case '-':
  return true;

  default:
   return false;
  }
}
//---------------------------------------------------------------------------
void CPPConv::PutString(FILE* outfile, const char* str, bool bConvert)
{
 if(!str) return;
 if(bConvert)
 {
  for(unsigned int i=0;i<(unsigned)strlen(str);i++)
   {
   if(str[i]=='<') fputs("&lt;",outfile);
   else if(str[i]=='>') fputs("&gt;",outfile);
   else if(str[i]=='&') fputs("&amp;",outfile);
   else PutChar(outfile,str[i]);
   }
 }
 else fputs(str,outfile);
}
//---------------------------------------------------------------------------
bool CPPConv::MakeHashTable()
{
for(int i=0;i<KEYWORDS_COUNT;i++)
     HashTable[i] = GetHash(Keywords[i]);

return true;
}
//---------------------------------------------------------------------------



Пример использования:

#include "CPPConv.h"

CPPConv c;
c.Convert("C:\\test.cpp", "C:\\test.html");
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.