📄 stringline.cpp
字号:
#include "StdAfx.h"
#include "StringLine.h"
#define QUEUE_LINE(q) ((LineString *) ((ULONG)q - (ULONG)(&(((LineString *)NULL)->lineque))))
inline int queue_initialize(Queue *q)
{
if(q == NULL) return -1;
q->next = q->prev = q;
return 0;
}
//insert qnew before q
inline int queue_insert(Queue *q, Queue *qnew)
{
if(q == NULL || qnew == NULL) return -1;
if(q == qnew) return 0;
qnew->next = q;
qnew->prev = q->prev;
q->prev->next = qnew;
q->prev = qnew;
return 0;
}
inline int queue_delete(Queue *q)
{
if(q == NULL) return -1;
if(q == q->next || q == q->prev) return 0;
q->prev->next = q->next;
q->next->prev = q->prev;
q->next = q->prev = q;
return 0;
}
CStringLines::CStringLines()
{
m_tp_node = NULL;
m_sat_node = NULL;
m_prog_node = NULL;
m_tp_full_node = NULL;
m_sat_full_node = NULL;
m_prog_full_node = NULL;
m_def_prog_full_node = NULL;
m_def_prog_field_full_count = 0;
m_tp_field_count = m_sat_field_count = m_prog_field_count = 0;
m_tp_field_full_count = m_sat_field_full_count = m_prog_field_full_count = 0;
#ifdef _MY_DEBUG
debugfd = fopen("debug.log", "wb");
scriptfd = fopen("script_debug.log", "wb");
#endif
}
CStringLines::~CStringLines()
{
#ifdef _MY_DEBUG
fclose(debugfd);
fclose(scriptfd);
#endif
FreeNodeFieldInfo(SAT_NODE);
FreeNodeFieldInfo(TP_NODE);
FreeNodeFieldInfo(PROG_NODE);
FreeNodeFieldInfo(DEF_PROG_NODE);
}
CString CStringLines::FilterFileComment(CString filestr)
{
int pos;
const char *pbuf;
BOOL bInQuote;
BOOL bInComment;
CString newfile;
int length = filestr.GetLength();
pos = 0;
newfile = "";
bInQuote = FALSE;
bInComment = FALSE;
pbuf = (LPCSTR)filestr;
while(pbuf[pos])
{
if(pos == 0)
{
if(pbuf[pos] == '\"')
{
bInQuote = !bInQuote;
}
}
else
{
if((pbuf[pos] == '\"') && (pbuf[pos - 1] != '\\'))
{
bInQuote = !bInQuote;
}
}
if((pos + 2 < length) && (pbuf[pos] == '/') && (pbuf[pos + 1] == '*') && (pbuf[pos + 2] != '#') && (!bInQuote))
{
if(!bInComment)
{
bInComment = TRUE;
pos = pos + 2;
continue;
}
}
if((pos > 1) && (pbuf[pos - 1] != '@') && (pbuf[pos] == '*') && (pbuf[pos + 1] == '/') && (!bInQuote))
{
if(bInComment)
{
bInComment = FALSE;
pos = pos + 2;
continue;
}
}
if(!bInComment) newfile = newfile + pbuf[pos];
pos++;
}
return newfile;
}
CString CStringLines::FilterLineComment(CString linestr)
{
int pos;
const char *pbuf;
BOOL bInQuote;
CString tempstr;
BOOL bDefineStr = FALSE;
static BOOL bLineInComment = FALSE;
pos = 0;
bInQuote = FALSE;
pbuf = (LPCSTR)linestr;
while(pbuf[pos])
{
if(pos == 0)
{
if(pbuf[pos] == '\"')
{
bInQuote = !bInQuote;
}
}
else
{
if((pbuf[pos] == '\"') && (pbuf[pos - 1] != '\\'))
{
bInQuote = !bInQuote;
}
}
if((pbuf[pos] == '/') && (pbuf[pos + 1] == '*') && (!bInQuote) && (!bLineInComment)) bLineInComment = TRUE;
if((pbuf[pos] == '*') && (pbuf[pos + 1] == '/') && (!bInQuote) && bLineInComment) bLineInComment = FALSE;
if((pbuf[pos] == '/') && (pbuf[pos + 1] == '/') && (!bInQuote) && (!bLineInComment)) break;
pos++;
}
if(bDefineStr) return "//" + linestr.Left(pos);
else return linestr.Left(pos);
}
CString CStringLines::FilterBackChar(CString linestr, char ch)
{
char tab = 9;
if(ch == ' ') tab = 9;
else tab = -1;
for(int i = linestr.GetLength() - 1; i >= 0; i--)
{
if((linestr.GetAt(i) == ch) || (linestr.GetAt(i) == tab))
{
linestr = linestr.Left(i);
}
else break;
}
return linestr;
}
CString CStringLines::FilterFrontChar(CString linestr, char ch)
{
const char *pbuf;
char tab = 9;
pbuf = (LPCTSTR)linestr;
if(ch == ' ') tab = 9;
else tab = -1;
while(*pbuf == ch || *pbuf == tab) pbuf++;
CString word(pbuf);
return word;
}
BOOL CStringLines::IsKeyWord(CString linestr, char *keyword)
{
const char *pbuf = (LPCSTR)linestr;
while(*keyword && *keyword == *pbuf)
{
keyword++;
pbuf++;
};
if((*keyword == 0) && (*pbuf == ' ' || *pbuf == '=')) return TRUE;
return FALSE;
}
BOOL CStringLines::ParseLineTag(LineString *pLineStr)
{
int pos;
CString strline = *(pLineStr->plinestr);
strline = FilterFrontChar(strline, ' ');
//fisrt comment
pos = strline.Find("//", 0);
if(pos != -1)
{
if(pos == 0)
{
pLineStr->tag = COMMENT;
return TRUE;
}
strline.Delete(pos, strline.GetLength() - pos - 1);
}
//ScriptVersion
if(IsKeyWord(strline, "ScriptVersion"))
{
pLineStr->tag = SCRIPTVER;
return TRUE;
}
if(IsKeyWord(strline, "module"))
{
pLineStr->tag = MODULE;
return TRUE;
}
if(IsKeyWord(strline, "type"))
{
pLineStr->tag = TYPE;
return TRUE;
}
if(IsKeyWord(strline, "version"))
{
pLineStr->tag = VERSION;
return TRUE;
}
if(IsKeyWord(strline, "description"))
{
pLineStr->tag = DESCRIPTION;
return TRUE;
}
if(IsKeyWord(strline, "signature"))
{
pLineStr->tag = SIGNATURE;
return TRUE;
}
if(IsKeyWord(strline, "submodules"))
{
pLineStr->tag = SUBMODELS;
return TRUE;
}
if(IsKeyWord(strline, "codefiles"))
{
pLineStr->tag = CODEFILES;
return TRUE;
}
if(IsKeyWord(strline, "docfiles"))
{
pLineStr->tag = DOCFILES;
return TRUE;
}
if(IsKeyWord(strline, "macro"))
{
pLineStr->tag = MACRO;
return TRUE;
}
if(IsKeyWord(strline, "rules"))
{
pLineStr->tag = RULES;
return TRUE;
}
pos = strline.Find("{", 0);
if(pos != -1)
{
if(pos == 0)
{
pLineStr->tag = LBRACKET;
return TRUE;
}
}
pos = strline.Find("}", 0);
if(pos != -1)
{
if(pos == 0)
{
pLineStr->tag = RBRACKET;
return TRUE;
}
}
if((strline.GetLength()) == 1 && (strline.Find("\n", 0) != -1))
{
pLineStr->tag = EMPTY;
return TRUE;
}
pLineStr->tag = FIELDEXP;
return TRUE;
}
BOOL CStringLines::IsFieldLine(LineString *pLineStr)
{
if(pLineStr->tag != FIELDEXP) return FALSE;
return TRUE;
}
/*
void CStringLines::PrintCdlFile(LineString *pLineStr)
{
char TagBuf[19][20] = {
{"EMPTY"}, {"COMMENT"}, {"COMMA"}, {"SCRIPTVER"}, {"MODULE"}, {"LBRACKET"}, {"RBRACKET"},
{"TYPE"}, {"VERSION"}, {"DESCRIPTION"}, {"SIGNATURE"}, {"SUBMODELS"}, {"CODEFILES"}, {"DOCFILES"},
{"MACRO"}, {"RULES"}, {"EQUALSIGN"}, {"FIELDEXP"}, {"UNKOWN"}
};
if(!pLineStr) return;
LineString *pLine = pLineStr;
do
{
CString strline = *(pLine->plinestr);
strline.Remove('\r');
strline.Remove('\n');
strline = " " + strline + " ";
OutputMsg(strline.GetBuffer(0));
CString strline0(TagBuf[pLine->tag]);
strline0.Remove('\r');
strline0.Remove('\n');
strline0 = " " + strline0 + "\r\n";
OutputMsg(strline0.GetBuffer(0));
pLine = NextLineString(pLine);
}
while(pLine && pLine != pLineStr);
}
*/
int CStringLines::FindNextExpression(CString strline)
{
return FineNextPostionByKey(strline, ';');
}
LineString* CStringLines::ReadCdlFile(CString path)
{
int pos;
int lines;
BOOL bReadNewLine;
CString LineBuf, LineTmp;
LineString *pLine, *pRoot;
CStdioFile stdfd(path, CFile::modeRead | CFile::shareExclusive);
lines = 0;
pLine = pRoot = new LineString;
queue_initialize(&(pRoot->lineque));
bReadNewLine = TRUE;
while(1)
{
if(bReadNewLine)
{
if(!stdfd.ReadString(LineBuf))
{
delete pLine;
break;
}
}
LineTmp = "";
pos = FindNextExpression(LineBuf);
if(pos != -1)
{
if(pos == LineBuf.GetLength() - 1)
{
bReadNewLine = TRUE;
}
else
{
LineTmp = LineBuf.Right(LineBuf.GetLength() - pos - 1);
LineBuf = LineBuf.Left(pos + 1);
bReadNewLine = FALSE;
CString strline(LineTmp);
strline = FilterFrontChar(strline, ' ');
pos = strline.Find("//", 0);
if(!pos) bReadNewLine = TRUE;
}
}
else bReadNewLine = TRUE;
pLine->lineseq = lines;
pLine->plinestr = new CString(LineBuf);
queue_insert(&(pRoot->lineque), &(pLine->lineque));
ParseLineTag(pLine);
if(!bReadNewLine)
{
delete pLine->plinestr;
pLine->plinestr = new CString(LineBuf);
LineBuf = LineTmp;
}
pLine = new LineString;
lines++;
};
return pRoot;
}
LineString *CStringLines::NextLineString(LineString *pLinestr)
{
if(!pLinestr) return NULL;
return QUEUE_LINE(pLinestr->lineque.next);
}
LineString *CStringLines::PrevLineString(LineString *pLinestr)
{
if(!pLinestr) return NULL;
return QUEUE_LINE(pLinestr->lineque.prev);
}
BOOL CStringLines::WriteCdlFile(LineString *pCdlLine, CString path)
{
LineString *pLine, *pNext;
if(!pCdlLine) return FALSE;
FILE *pFile = fopen((LPCSTR)path, "wb");
if(!pFile)
{
// AfxMessageBox(path + " Read Only!");
return FALSE;
}
CStdioFile stdfd(pFile);
pLine = pCdlLine;
while(1)
{
stdfd.WriteString(*pLine->plinestr + "\n");
pNext = NextLineString(pLine);
if((!pNext) || (pNext == pCdlLine)) break;
pLine = pNext;
};
fclose(pFile);
return TRUE;
}
char cdltemplate[32][128] =
{
{"// this MDF template file is created by MdfEditor."},
{" "},
{"ScriptVersion = 1.0;// version of generator of this file"},
{" "},
{"module NoTitle"},
{"{"},
// {"\ttype = non_leaf;//{non_leaf|leaf};"},
{"\tversion = 1.0;"},
//{"\tdescription = \"\";"},
//{"\tsignature = \"\";"},
{"\tsubmodules = {};"},
{"\tcodefiles = {};"},
{"\tdocfiles = {};"},
//{"\tmacro _MACRO = _EXAMPLE;"},
{"\trules = {};"},
{"};"},
NULL
};
LineString* CStringLines::CreateCdlTemplateFile()
{
int lines;
LineString *pLine, *pRoot;
lines = 0;
pLine = pRoot = new LineString;
queue_initialize(&(pRoot->lineque));
while(cdltemplate[lines][0])
{
pLine->lineseq = lines;
pLine->plinestr = new CString(cdltemplate[lines]);
ParseLineTag(pLine);
queue_insert(&(pRoot->lineque), &(pLine->lineque));
pLine = new LineString;
lines++;
}
return pRoot;
}
int CStringLines::GetLineByTag(LineString *pCdlLine, enum TagType tag)
{
LineString *pLine = NULL;
pLine = pCdlLine;
do
{
if(pLine->tag == tag)
{
return pLine->lineseq;
}
pLine = NextLineString(pLine);
}
while(pLine != pCdlLine);
return -1;
}
LineString *CStringLines::GetExpressionByLine(LineString *pCdlLine, int lines)
{
LineString *pLine = NULL;
pLine = pCdlLine;
do
{
if(pLine->lineseq == lines)
{
return pLine;
}
pLine = NextLineString(pLine);
}
while(pLine != pCdlLine);
return NULL;
}
LineString *CStringLines::GetLineExpression(LineString *pCdlLine, enum TagType tag)
{
LineString *pLine = NULL;
pLine = pCdlLine;
do
{
if(pLine->tag == tag)
{
return pLine;
}
pLine = NextLineString(pLine);
}
while(pLine != pCdlLine);
return NULL;
}
LineString *CStringLines::DeleteExpressionByTag(LineString *pCdlLine, int lines, enum TagType tag)
{
int pos;
BOOL bDel, bDone;
LineString *pLine, *pNext;
bDone = FALSE;
pLine = GetExpressionByLine(pCdlLine, lines);
if(!pLine) return pCdlLine;
while(1)
{
bDel = FALSE;
if(tag == MODULE)
{
pos = pLine->plinestr->Find("{");
if(pos == -1)
{
bDel = TRUE;
}
else
{
if(pLine->tag == LBRACKET) bDone = TRUE;
else if(pLine->tag == FIELDEXP)
{
bDel = TRUE;
}
}
}
else
{
pos = pLine->plinestr->Find(";");
if(pos != -1)
{
if(pos == pLine->plinestr->GetLength() - 1) bDel = TRUE;
else
{
pLine->plinestr->Delete(0, pos + 1);
*(pLine->plinestr) = FilterFrontChar(*(pLine->plinestr), ' ');
pos = pLine->plinestr->Find("//");
if(pos == -1 || pos == 0) bDel = TRUE;
}
bDone = TRUE;
}
else
{
bDel = TRUE;
}
}
if(bDel)
{
pNext = NextLineString(pLine);
pCdlLine = DeleteLineStr(pCdlLine, pLine->lineseq);
pLine = pNext;
}
else
{
pLine = NextLineString(pLine);
}
if(bDone && tag == MACRO && pLine->tag == MACRO) bDone = FALSE;
if(bDone || !pNext || pNext->lineseq < lines) break;
};
return pCdlLine;
}
BOOL CStringLines::DestroyAllLine(LineString *pCdlLine)
{
LineString *pLine, *pNext;
if(!pCdlLine) return FALSE;
pLine = pCdlLine;
do
{
pNext = NextLineString(pLine);
queue_delete(&(pLine->lineque));
delete pLine->plinestr;
delete pLine;
if(pNext == pLine) break;
pLine = pNext;
}
while(1);
return FALSE;
}
LineString *CStringLines::DeleteLineStr(LineString *pCdlLine, int lines)
{
LineString *pLine, *pNext;
pLine = GetExpressionByLine(pCdlLine, lines);
if(!pLine) return pCdlLine;
pNext = NextLineString(pLine);
if(pNext == pLine)
{
delete pLine->plinestr;
delete pLine;
return NULL;
}
if(pLine == pCdlLine) pCdlLine = pNext;
queue_delete(&(pLine->lineque));
delete pLine->plinestr;
delete pLine;
lines = 0;
pLine = pCdlLine;
do
{
pLine->lineseq = lines++;
pLine = NextLineString(pLine);
}
while(pLine && pLine != pCdlLine);
return pCdlLine;
}
BOOL CStringLines::IsValidExpress(CString strline)
{
BOOL bInQuote;
if(strline.IsEmpty()) return TRUE;
bInQuote = FALSE;
const char *buf = (LPCSTR)strline;
for(int i = 0; i < strline.GetLength(); i++)
{
if(i == 0)
{
if(buf[i] == '\"')
{
bInQuote = !bInQuote;
}
}
else
{
if((buf[i] == '\"') && (buf[i - 1] != '\\'))
{
bInQuote = !bInQuote;
if(i != strline.GetLength() - 1) return FALSE;
}
}
}
return !bInQuote;
}
int CStringLines::FineNextPostionByKey(CString strline, char key)
{
BOOL bInQuote;
int bInBracket;
CString linestr = FilterFrontChar(strline, ' ');
int pos = linestr.Find("//", 0);
if(pos == 0) return -1;
bInQuote = FALSE;
bInBracket = 0;
const char *buf = (LPCSTR)strline;
for(int i = 0; i < linestr.GetLength(); i++)
{
if(pos != -1 && i == pos) break;
if(i == 0)
{
if(buf[i] == '\"')
{
bInQuote = !bInQuote;
}
}
else
{
if((buf[i] == '\"') && (buf[i - 1] != '\\'))
{
bInQuote = !bInQuote;
}
}
if((buf[i] == '{') && (!bInQuote) && (key != '{')) bInBracket++;
if((buf[i] == '}') && (!bInQuote) && (key != '}')) bInBracket--;
if((buf[i] == key) && (!bInQuote) && (!bInBracket))
{
if(pos == -1) return i;
else if(i < pos) return i;
}
}
return -1;
}
int CStringLines::FineNewMacroPos(CString strline)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -