Продолжаем разговор
По мотивам предыдущих конвертеров набросал простенький ASM->HTML:
Хидер:
// ASMConv.h header file
//---------------------------------------------------------------------------
#ifndef ASMConvH
#define ASMConvH
//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//---------------------------------------------------------------------------
#define BUF_SIZE 1024 // размер буфера для чтения из файла
#define MAX_KWD_LEN 100 // максимальная длина ключевого слова
#define KEYWORDS_COUNT 170 // кол-во ключевых слов в языка
//---------------------------------------------------------------------------
class ASMConv
{
private:
FILE* fIn;
FILE* fOut;
char buffer[BUF_SIZE];
char kwd[MAX_KWD_LEN];
char tmp_kwd[MAX_KWD_LEN];
static char* Keywords[KEYWORDS_COUNT];
bool ReadString(FILE* fIn);
void ParseString(char* str);
void PutChar(FILE* outfile,char ch);
void PutString(FILE* outfile, const char* str, bool bConvert);
bool IsDelimiter(char ch);
void WriteSpaces(FILE* outfile,int Num);
bool IsKeyword(char* s);
bool IsDigit(char* s);
void Reset();
public:
bool Convert(const char* InputFileName, const char* OutputFileName);
public:
ASMConv();
~ASMConv();
};
//---------------------------------------------------------------------------
#endif
Сорц:
// ASMConv.cpp implementation file
//---------------------------------------------------------------------------
#include "ASMConv.h"
//---------------------------------------------------------------------------
char* ASMConv::Keywords[KEYWORDS_COUNT] =
{
"AAA","AAD","AAM","AAS","ADC","ADD",
"AND","ASSUME","BOUND","BYTE","CALL",
"CBW","CLC","CLD","CLI","CMC","CMP",
"CMPSB","CMPSW","CWD","DAA","DAS","DB",
"DD","DEC","DIV","DQ","DT","DUP","DW",
"DWORD","END","ENDP","ENDS","ENTER",
"ENTRY","EQU","ESC","EXIT","EXTRN",
"FAR","FCOMP","FDIV","FDIVP","FISTP",
"FLAT","FLD","FLDZ","FMUL","FMULP",
"FSTP","FSTSW","FSUBR","FXCH","HLT",
"IDIV","IMUL","IN","INC","INCLUDE",
"INSB","INSW","INT","INTO","IRET",
"JA","JAE","JB","JBE","JC","JCXZ",
"JE","JECXZ","JG","JGE","JL","JLE",
"JMP","JNA","JNAE","JNB","JNBE",
"JNC","JNE","JNG","JNGE","JNL","JNLE",
"JNO","JNP","JNS","JNZ","JO","JP","JPE",
"JPO","JS","JZ","LABEL","LAHF","LDS",
"LEA","LEAVE","LES","LOCALS","LOCK",
"LODSB","LODSW","LOOP","MODEL","MOV",
"MOVSB","MOVSW","MOVSX","MOVZX","MUL",
"NEAR","NEG","NOP","NOT","NULL","OFFSET",
"OR","OUT","OUTSB","OUTSW","POP","POPA",
"POPF","PROC","PTR","PUBLIC","PUSH","QWORD",
"RCL","RCR","REP","RET","RETF","RETN",
"ROL","ROR","SAHF","SAL","SAR","SBB",
"SCASB","SCASW","SEGMENT","SETAE","SHL",
"SHLD","SHR","SHRD","STC","STD","STI",
"STOSB","STOSW","STRUC","SUB","TBYTE",
"TEST","WAIT","WORD","XCHG","XLAT","XOR",
"POPFD","PUSHFD"
};
//---------------------------------------------------------------------------
ASMConv::ASMConv(): fIn(NULL),fOut(NULL)
{
}
//---------------------------------------------------------------------------
ASMConv::~ASMConv()
{
Reset();
}
//---------------------------------------------------------------------------
void ASMConv::Reset()
{
if(fIn) {
fclose(fIn);fIn = NULL;
}
if(fOut) {
fclose(fOut); fOut = NULL;
}
}
//---------------------------------------------------------------------------
bool ASMConv::ReadString(FILE* infile)
{
memset(buffer,0,BUF_SIZE);
if(!fgets(buffer, BUF_SIZE-1,infile))return false;
return true;
}
//---------------------------------------------------------------------------
bool ASMConv::Convert(const char* InputFileName, const char* OutputFileName)
{
Reset();
fIn = fopen(InputFileName, "r");
if(!fIn) return false;
fOut = fopen(OutputFileName,"w");
if(!fOut) return false;
PutString(fOut,"<DIV STYLE=\"background-color:#FFFFFF>",false);
PutString(fOut,"<FONT COLOR=#000000><FONT FACE=\"Courier New\" STYLE=\"font-size:14px;\">",false);
while( ReadString(fIn) ) ParseString(buffer);
PutString(fOut,"</FONT></FONT></DIV>",false);
fclose(fIn);
fclose(fOut);
return true;
}
//---------------------------------------------------------------------------
void ASMConv::PutChar(FILE* outfile,char ch)
{
if(ch=='<') PutString(outfile,"<",false);
else if(ch=='>') PutString(outfile,">",false);
else if(ch=='&') PutString(outfile,"&",false);
else fputc(ch,outfile);
}
//---------------------------------------------------------------------------
void ASMConv::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("<",outfile);
else if(str[i]=='>') fputs(">",outfile);
else if(str[i]=='&') fputs("&",outfile);
else fputc(str[i],outfile);
}
}
else fputs(str,outfile);
}
//---------------------------------------------------------------------------
void ASMConv::ParseString(char* str)
{
if(!str) return;
int cntr=0;
int NumSpaces=-1;
while(isspace(str[cntr]))
{
if(str[cntr]=='\t')NumSpaces+=4;
else NumSpaces+=1;
cntr++;
}
WriteSpaces(fOut,NumSpaces); // write beginning 's
int s_len = strlen(str);
unsigned int buff_offset=0;
memset(kwd,0,MAX_KWD_LEN);
for(int i=cntr;i<s_len;i++)
{
if(str[i]==';') //Begin Comment
{
PutString(fOut,"<FONT COLOR=#008000><I>",false);
int j=i;
for(;j<s_len;j++) PutChar(fOut,str[j]);
PutString(fOut,"<BR>",false);
PutString(fOut,"</I></FONT>",false);
return;
}
else if(str[i]=='\'') //Begin string
{
PutString(fOut,"<FONT COLOR=#000080>",false);
PutChar(fOut,str[i]);
int z=i+1;
for(;z<s_len;z++)
{
PutChar(fOut,str[z]);
if(str[z]=='\'')
{
PutChar(fOut,' ');
break;
}
}
PutString(fOut,"</FONT>",false);
i=z; continue;
} // Parse str
else
{
if(isspace(str[i]) ||IsDelimiter(str[i]))
{
if(IsKeyword(kwd))
{
PutString(fOut,"<FONT COLOR=#000000><B>",false);
PutString(fOut,kwd,true);
PutString(fOut,"</B></FONT>",false);
}
//else if is digit etc.
else if(IsDigit(kwd))
{
PutString(fOut,"<FONT COLOR=#808000>",false);
PutString(fOut,kwd,true);
PutString(fOut,"</FONT>",false);
}
else
{
PutString(fOut,kwd,true);
}
PutChar(fOut,str[i]);
buff_offset=0;
memset(kwd,0,MAX_KWD_LEN);
}
else // if(isspace(s[i]) ||is_delimiter(s[i]))
{
if(buff_offset<MAX_KWD_LEN)
{
kwd[buff_offset] = str[i];
buff_offset++;
}
}
}
}
PutString(fOut,"<BR>",false);
}
//---------------------------------------------------------------------------
bool ASMConv::IsDigit(char* s)
{
return ( atoi(s)!=0 );
}
//---------------------------------------------------------------------------
bool ASMConv::IsKeyword(char* s)
{
if(!s) return false;
int beginning=0;
while(isspace(*s) || IsDelimiter(*s))beginning++;
int ended = strlen(s);
while(isspace(s[ended]) || IsDelimiter(s[ended]))
{
s[ended]='\0';
ended--;
}
memset(tmp_kwd,'\0',MAX_KWD_LEN);
int cntr=0;
for(int i=beginning;i<(int)strlen(s);i++)
{
char ch = s[i];
tmp_kwd[cntr] = (char) toupper(ch);
cntr++;
}
for(int u=0;u<KEYWORDS_COUNT;u++)
{
if(strcmp(Keywords[u],tmp_kwd)==0)
return true;
}
return false;
}
//---------------------------------------------------------------------------
void ASMConv::WriteSpaces(FILE* outfile,int Num)
{
for(int i=0;i<Num;i++) {
fputs(" ",outfile);
}
}
//---------------------------------------------------------------------------
bool ASMConv::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;
}
}
//---------------------------------------------------------------------------
Пример использования:
#include "ASMConv.h"
ASMConv a;
a.Convert("C:\\test.asm","C:\\test.html");