You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1583 lines
39 KiB
C++

// XTPSyntaxEditLexCfgFileReader.cpp: implementation of the CXTPSyntaxEditLexCfgFileReader class.
//
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME SYNTAX EDIT LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
// common includes
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPResourceManager.h"
#include "Common/XTPVC80Helpers.h"
// syntax editor includes
#include "XTPSyntaxEditDefines.h"
#include "XTPSyntaxEditLexPtrs.h"
#include "XTPSyntaxEditLexCfgFileReader.h"
#include "XTPSyntaxEditLexColorFileReader.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifndef DBG_READ_TRACE
#define DBG_READ_TRACE
#endif
namespace XTPSyntaxEditLexAnalyser
{
//===========================================================================
// XTP_EDIT_LEXPROPINFO
//===========================================================================
XTP_EDIT_LEXPROPINFO::XTP_EDIT_LEXPROPINFO()
{
nLine = 0;
nOffset = 0;
nPropertyLen = 0;
}
XTP_EDIT_LEXPROPINFO::XTP_EDIT_LEXPROPINFO(const XTP_EDIT_LEXPROPINFO& rSrc)
{
arPropName.RemoveAll();
int i;
for (i = 0; i < rSrc.arPropName.GetSize(); ++i) {
arPropName.Add(rSrc.arPropName[i]);
}
arPropValue.RemoveAll();
for (i = 0; i < rSrc.arPropValue.GetSize(); ++i) {
arPropValue.Add(rSrc.arPropValue[i]);
}
nLine = rSrc.nLine;
nOffset = rSrc.nOffset;
nPropertyLen = rSrc.nPropertyLen;
}
const XTP_EDIT_LEXPROPINFO& XTP_EDIT_LEXPROPINFO::operator = (const XTP_EDIT_LEXPROPINFO& rSrc)
{
arPropName.RemoveAll();
int i;
for (i = 0; i < rSrc.arPropName.GetSize(); ++i) {
arPropName.Add(rSrc.arPropName[i]);
}
arPropValue.RemoveAll();
for (i = 0; i < rSrc.arPropValue.GetSize(); ++i) {
arPropValue.Add(rSrc.arPropValue[i]);
}
nLine = rSrc.nLine;
nOffset = rSrc.nOffset;
nPropertyLen = rSrc.nPropertyLen;
return *this;
}
//===========================================================================
// CXTPSyntaxEditLexPropInfoArray
//===========================================================================
CXTPSyntaxEditLexPropInfoArray::CXTPSyntaxEditLexPropInfoArray()
{
}
CXTPSyntaxEditLexPropInfoArray::CXTPSyntaxEditLexPropInfoArray(const CXTPSyntaxEditLexPropInfoArray& rSrc)
{
RemoveAll();
for (int i = 0; i < rSrc.GetSize(); ++i)
{
XTP_EDIT_LEXPROPINFO info(rSrc[i]);
Add(info);
}
}
const CXTPSyntaxEditLexPropInfoArray& CXTPSyntaxEditLexPropInfoArray::operator = (const CXTPSyntaxEditLexPropInfoArray& rSrc)
{
RemoveAll();
for (int i = 0; i < rSrc.GetSize(); ++i)
{
XTP_EDIT_LEXPROPINFO info(rSrc[i]);
Add(info);
}
return *this;
}
//===========================================================================
// XTP_EDIT_LEXCLASSINFO
//===========================================================================
XTP_EDIT_LEXCLASSINFO::XTP_EDIT_LEXCLASSINFO()
{
nEndLine = 0;
nStartLine = 0;
}
XTP_EDIT_LEXCLASSINFO::XTP_EDIT_LEXCLASSINFO(const XTP_EDIT_LEXCLASSINFO& rSrc)
{
arPropertyDesc.RemoveAll();
for (int i = 0; i < rSrc.arPropertyDesc.GetSize(); ++i)
{
XTP_EDIT_LEXPROPINFO info(rSrc.arPropertyDesc[i]);
arPropertyDesc.Add(info);
}
nEndLine = rSrc.nEndLine;
nStartLine = rSrc.nStartLine;
csClassName = rSrc.csClassName;
}
const XTP_EDIT_LEXCLASSINFO& XTP_EDIT_LEXCLASSINFO::operator = (const XTP_EDIT_LEXCLASSINFO& rSrc)
{
arPropertyDesc.RemoveAll();
for (int i = 0; i < rSrc.arPropertyDesc.GetSize(); ++i)
{
XTP_EDIT_LEXPROPINFO info(rSrc.arPropertyDesc[i]);
arPropertyDesc.Add(info);
}
nEndLine = rSrc.nEndLine;
nStartLine = rSrc.nStartLine;
csClassName = rSrc.csClassName;
return *this;
}
//===========================================================================
// CXTPSyntaxEditLexClassInfoArray
//===========================================================================
CXTPSyntaxEditLexClassInfoArray::CXTPSyntaxEditLexClassInfoArray()
{
m_bModified = FALSE;
}
CXTPSyntaxEditLexClassInfoArray::CXTPSyntaxEditLexClassInfoArray(const CXTPSyntaxEditLexClassInfoArray& rSrc)
{
RemoveAll();
m_bModified = rSrc.m_bModified;
for (int i = 0; i < rSrc.GetSize(); ++i)
{
XTP_EDIT_LEXCLASSINFO info(rSrc[i]);
Add(info);
}
}
const CXTPSyntaxEditLexClassInfoArray& CXTPSyntaxEditLexClassInfoArray::operator = (const CXTPSyntaxEditLexClassInfoArray& rSrc)
{
RemoveAll();
m_bModified = rSrc.m_bModified;
for (int i = 0; i < rSrc.GetSize(); ++i)
{
XTP_EDIT_LEXCLASSINFO info(rSrc[i]);
Add(info);
}
return *this;
}
extern CString MakeStr(const CStringArray& rArProps, LPCTSTR strSplitter);
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace XTPSyntaxEditLexAnalyser;
const CString cstrDelims(_T(" \t,"));
const CString cstrEOL(_T("\r\n"));
const CString cstrHex(_T("0123456789ABCDEFGabcdefg"));
AFX_STATIC BOOL AFX_CDECL AfxCompareTime(const FILETIME& ft1, const FILETIME& ft2, DWORD dwTimeDiff = 500)
{
ULARGE_INTEGER uFT1, uFT2;
uFT1.LowPart = ft1.dwLowDateTime;
uFT1.HighPart = ft1.dwHighDateTime;
uFT2.LowPart = ft2.dwLowDateTime;
uFT2.HighPart = ft2.dwHighDateTime;
ULONGLONG ullDiff = uFT1.QuadPart > uFT2.QuadPart ? uFT1.QuadPart - uFT2.QuadPart : uFT2.QuadPart - uFT1.QuadPart;
//ullDiff = the number of 100-nanosecond intervals since January 1, 1601.
if (ullDiff <= (dwTimeDiff*1000*1000/100))
{
return TRUE;
}
return FALSE;
}
AFX_STATIC BOOL AFX_CDECL AfxOpenFile(CFile& file, LPCTSTR lpszFileName, UINT nOpenFlags)
{
if (nOpenFlags == CFile::modeRead)
{
if (!FILEEXISTS_S(lpszFileName))
{
return FALSE;
}
}
CFileException e;
if (!file.Open(lpszFileName, nOpenFlags, &e))
{
AfxThrowFileException(e.m_cause, e.m_lOsError, e.m_strFileName);
}
return TRUE;
}
AFX_STATIC CString AFX_CDECL AfxMakeStrES(const CStringArray& rArProps, LPCTSTR strSplitter)
{
CString strResult;
int nCount = (int)rArProps.GetSize();
for (int i = 0; i < nCount; i++)
{
CString csProp = XTPSyntaxEditLexConfig()->ESToStr(rArProps[i], TRUE);
if (i)
{
strResult += strSplitter;
}
CString strI = csProp;
strResult += strI;
}
return strResult;
}
////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditLexCfgFileReader& AFX_CDECL CXTPSyntaxEditLexCfgFileReader::Instance()
{
static CXTPSyntaxEditLexCfgFileReader instance;
return instance;
}
CXTPSyntaxEditLexCfgFileReader::CXTPSyntaxEditLexCfgFileReader()
{
m_csDataBuffer = XTP_EDIT_LEXCLASS_EMPTYSTR;
m_nCurrLine = 0;
m_nCurrLine_pos = 0;
m_nCurrPos = 0;
m_nEOFPos = 0;
m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
m_nTokenType = xtpEditTokType_Unknown;
m_bReadNames = TRUE;
m_bES = FALSE;
p_sSyntaxScheme = NULL;
p_sColorScheme = NULL;
}
CXTPSyntaxEditLexCfgFileReader::~CXTPSyntaxEditLexCfgFileReader()
{
CleanInfoMap(m_mapLexClassInfo);
}
void CXTPSyntaxEditLexCfgFileReader::CleanInfoMap(CMapStringToPtr& mapInfo)
{
for (POSITION pos = mapInfo.GetStartPosition(); pos;)
{
CString csFileName;
CXTPSyntaxEditLexClassInfoArray* pInfoArray = NULL;
mapInfo.GetNextAssoc(pos, csFileName, (void*&)pInfoArray);
SAFE_DELETE(pInfoArray);
}
mapInfo.RemoveAll();
}
void CXTPSyntaxEditLexCfgFileReader::CopyInfoMap(CMapStringToPtr& mapInfo)
{
CleanInfoMap(mapInfo);
for (POSITION pos = m_mapLexClassInfo.GetStartPosition(); pos;)
{
// get the source data.
CString csFileName;
CXTPSyntaxEditLexClassInfoArray* pSource = NULL;
m_mapLexClassInfo.GetNextAssoc(pos, csFileName, (void*&)pSource);
// instantiate a new data pointer.
CXTPSyntaxEditLexClassInfoArray* pDest =
new CXTPSyntaxEditLexClassInfoArray(*pSource);
// set the data.
mapInfo[csFileName] = pDest;
}
}
void CXTPSyntaxEditLexCfgFileReader::ReadSource2(const CString& csFileName, CStringArray& arBuffer)
{
try
{
arBuffer.RemoveAll();
CStdioFile file;
if (AfxOpenFile(file, csFileName, CFile::modeRead))
{
arBuffer.Add(_T(""));
CString csBuffer;
while(file.ReadString(csBuffer))
{
int nLen = csBuffer.GetLength();
if (nLen && csBuffer[nLen - 1] == _T('\r'))
csBuffer.Delete(nLen - 1);
arBuffer.Add(csBuffer);
}
}
}
catch(CFileException* expFile)
{
#ifdef _DEBUG
ProcessFileException(expFile);
#endif
expFile->Delete();
}
}
void CXTPSyntaxEditLexCfgFileReader::ReadSource(const CString& csFileName, BOOL bSaveInfo)
{
try
{
CFile file;
if (AfxOpenFile(file, csFileName, CFile::modeRead))
{
int iLen = (int)file.GetLength();
char* pszBuffer = new char[iLen + 2];
int iBytes = (int)file.Read(pszBuffer, iLen);
ASSERT(iLen == iBytes);
pszBuffer[iLen] = '\0';
m_csDataBuffer = pszBuffer;
SAFE_DELETE_AR(pszBuffer);
file.Close();
Parse(m_arLexClassInfo);
if (bSaveInfo)
{
CString csKey = csFileName;
csKey.MakeLower();
CXTPSyntaxEditLexClassInfoArray* pInfo = NULL;
if (!m_mapLexClassInfo.Lookup(csKey, (void*&)pInfo))
m_mapLexClassInfo[csKey] = new CXTPSyntaxEditLexClassInfoArray(m_arLexClassInfo);
else
*pInfo = m_arLexClassInfo;
}
}
}
catch(CFileException* expFile)
{
#ifdef _DEBUG
ProcessFileException(expFile);
#endif
expFile->Delete();
}
}
void CXTPSyntaxEditLexCfgFileReader::ReadStringSource(BOOL bSaveInfo, CString sPassedString,
CString* pSyntaxScheme)
{
if (pSyntaxScheme == NULL)
return;
p_sSyntaxScheme = pSyntaxScheme;
m_csDataBuffer = *pSyntaxScheme;
Parse(m_arLexClassInfo);
if (bSaveInfo)
{
CString csKey = _T("InternalSyntaxSet");
//CString csKey = sPassedString ;
csKey.MakeLower();
CXTPSyntaxEditLexClassInfoArray* pInfo = NULL;
if (!m_mapLexClassInfo.Lookup(csKey, (void*&)pInfo))
m_mapLexClassInfo[csKey] = new CXTPSyntaxEditLexClassInfoArray(m_arLexClassInfo);
else
*pInfo = m_arLexClassInfo;
}
}
void CXTPSyntaxEditLexCfgFileReader::ReadSource(UINT nResourceID)
{
CXTPResourceManager::AssertValid(XTPResourceManager()->LoadHTML(&m_csDataBuffer, nResourceID));
}
void CXTPSyntaxEditLexCfgFileReader::Parse(CXTPSyntaxEditLexClassInfoArray& arLexClassDesc)
{
arLexClassDesc.RemoveAll();
m_nEOFPos = m_csDataBuffer.GetLength() - 1;
m_nPrevPos = 0;
if (m_nEOFPos < 0)
return;
m_nCurrLine = 1;
m_nCurrLine_pos = 0;
m_nCurrPos = 0;
m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
int nTokenType = 0;
while(m_nEOFPos > m_nCurrPos
&& m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0)
{
nTokenType = GetLexToken();
}
if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) == 0)
{
while(m_nEOFPos > m_nCurrPos)
{
XTP_EDIT_LEXCLASSINFO infoClass;
ParseLexClass(infoClass);
if (!infoClass.csClassName.IsEmpty())
arLexClassDesc.Add(infoClass);
}
}
}
void CXTPSyntaxEditLexCfgFileReader::ParseLexClass(XTP_EDIT_LEXCLASSINFO& infoClass)
{
if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) == 0)
{
infoClass.nStartLine = m_nCurrLine;
infoClass.nEndLine = 0;
}
int nTokenType = GetLexToken();
int nPrevToken = 0;
while(m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0
&& m_nEOFPos > m_nCurrPos )
{
XTP_EDIT_LEXPROPINFO infoProp;
if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_ENDTOKEN) == 0)
infoClass.nEndLine = m_nCurrLine;
infoProp.nLine = 0;
infoProp.nPropertyLen = 0;
infoProp.nOffset = 0;
int nValBeginPos = 0;
while(m_strToken != _T('=')
&& m_nEOFPos > m_nCurrPos
&& m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0)
{
if (nTokenType != xtpEditTokType_EOL && m_nEOFPos > m_nCurrPos)
{
if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_PROPNAME) == 0)
infoClass.csClassName = m_strToken;
else
infoProp.arPropName.Add(m_strToken);
infoProp.nLine = m_nCurrLine;
}
nTokenType = GetLexToken();
}
if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0
&& nTokenType != xtpEditTokType_EOL)
{
// get value's chain
nTokenType = GetLexToken();
infoProp.nOffset = m_nCurrPos - m_nPrevPos - m_strToken.GetLength();
nValBeginPos = m_nCurrPos - m_strToken.GetLength();
if (nPrevToken == xtpEditTokType_Quoted)
{
infoProp.nOffset += 1;
}
if (nTokenType == xtpEditTokType_Quoted )
{
infoProp.nOffset -= 1;
nValBeginPos -= 1;
}
while(nTokenType != xtpEditTokType_EOL
&& m_nEOFPos > m_nCurrPos)
{
if (nTokenType != xtpEditTokType_EOL)
{
if (infoClass.csClassName.CompareNoCase(XTP_EDIT_LEXCLASS_PROPNAME) == 0)
{
infoClass.csClassName = m_strToken;
DBG_READ_TRACE(_T("\nClass name = %s "), m_strToken);
}
else
{
m_nPrevPos = m_nCurrPos;
CString str = StrToES(m_strToken, TRUE);
infoProp.arPropValue.Add(str);
str = ESToStr(str, TRUE);
}
}
nPrevToken = nTokenType;
nTokenType = GetLexToken();
}
if (infoProp.arPropValue.GetSize() > 0)
{
infoProp.nPropertyLen += m_nPrevPos - nValBeginPos;
if (nPrevToken == xtpEditTokType_Quoted)
infoProp.nPropertyLen -= 1;
infoClass.arPropertyDesc.Add(infoProp);
}
nTokenType = GetLexToken();
}
}
if (infoClass.nEndLine == 0)
{
int nCount = (int)infoClass.arPropertyDesc.GetSize();
if (nCount)
{
infoClass.nEndLine = infoClass.arPropertyDesc[nCount-1].nLine;
}
else
{
infoClass.nEndLine = infoClass.nStartLine;
}
}
}
int CXTPSyntaxEditLexCfgFileReader::GetLexToken()
{
int nIgnoredTokensMask = xtpEditTokType_Unknown;
nIgnoredTokensMask |= xtpEditTokType_Delim;
nIgnoredTokensMask |= xtpEditTokType_Comment;
m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
int nTokenType = GetToken();
if (m_strToken == _T(":"))
nTokenType = xtpEditTokType_Unknown;
while((nTokenType == xtpEditTokType_Unknown ||
nTokenType == xtpEditTokType_Delim||
nTokenType == xtpEditTokType_Comment)
&& m_nEOFPos > m_nCurrPos)
{
m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
nTokenType = GetToken();
}
if (m_strToken == _T("lexClass"))
{
GetToken();
}
return nTokenType;
}
int CXTPSyntaxEditLexCfgFileReader::GetToken()
{
TCHAR tchCurrSymbol = _T('\0');
int nFoundedToken = 0;
if (m_nCurrPos >= m_nEOFPos)
{
return xtpEditTokType_Unknown;
}
TCHAR tchCurr_0 = m_csDataBuffer.GetAt(m_nCurrPos);
if (tchCurr_0 == _T('\x0A') && m_nCurrPos > m_nCurrLine_pos)
{
m_nCurrLine++;
m_nCurrLine_pos = m_nCurrPos;
}
tchCurrSymbol = m_csDataBuffer.GetAt(m_nCurrPos++);
switch (m_nTokenType)
{
case xtpEditTokType_Unknown :
nFoundedToken = ProcessUnknowToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_Unknown)
{
GetToken();
}
break;
case xtpEditTokType_Delim :
nFoundedToken = ProcessDelimToken(tchCurrSymbol);
break;
case xtpEditTokType_Name :
nFoundedToken = ProcessNameToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_Name)
{
m_strToken += tchCurrSymbol;
GetToken();
}
break;
case xtpEditTokType_Value :
nFoundedToken = ProcessValueToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_Value)
{
m_strToken += tchCurrSymbol;
GetToken();
}
break;
case xtpEditTokType_Quoted :
nFoundedToken = ProcessQuotedToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_Quoted)
{
m_strToken += tchCurrSymbol;
GetToken();
}
break;
case xtpEditTokType_Comment :
nFoundedToken = ProcessCommentToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_Comment)
{
m_strToken += tchCurrSymbol;
GetToken();
}
break;
case xtpEditTokType_EOL :
nFoundedToken = ProcessEOLToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_EOL)
{
m_strToken += tchCurrSymbol;
GetToken();
}
break;
case xtpEditTokType_Control :
nFoundedToken = ProcessControlToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_Control)
{
m_strToken += tchCurrSymbol;
GetToken();
}
break;
default :
nFoundedToken = ProcessUnknowToken(tchCurrSymbol);
if (m_nTokenType == xtpEditTokType_Unknown)
{
GetToken();
}
}
return nFoundedToken;
}
int CXTPSyntaxEditLexCfgFileReader::ProcessUnknowToken(TCHAR tchCurrSymbol)
{
int nFoundedToken = m_nTokenType;
if (_istalpha(tchCurrSymbol))
m_nTokenType = xtpEditTokType_Name;
else if (tchCurrSymbol == _T('\''))
m_nTokenType = xtpEditTokType_Quoted;
else if (tchCurrSymbol == _T('/'))
m_nTokenType = xtpEditTokType_Comment;
else if (cstrDelims.Find(tchCurrSymbol) > -1)
m_nTokenType = xtpEditTokType_Delim;
else if (cstrEOL.Find(tchCurrSymbol) > -1)
m_nTokenType = xtpEditTokType_EOL;
else if (tchCurrSymbol == _T('='))
m_nTokenType = xtpEditTokType_Control;
else if (tchCurrSymbol == _T(':'))
m_nTokenType = xtpEditTokType_Control;
else
m_nTokenType = xtpEditTokType_Value;
if (nFoundedToken != m_nTokenType)
m_nCurrPos--;
return nFoundedToken;
}
int CXTPSyntaxEditLexCfgFileReader::ProcessDelimToken(TCHAR tchCurrSymbol)
{
return ProcessUnknowToken(tchCurrSymbol);
}
int CXTPSyntaxEditLexCfgFileReader::ProcessNameToken(TCHAR tchCurrSymbol)
{
int nFoundedToken = m_nTokenType;
if (tchCurrSymbol == _T('\''))
m_nTokenType = xtpEditTokType_Quoted;
else if (tchCurrSymbol == _T('/'))
m_nTokenType = xtpEditTokType_Comment;
else if (cstrDelims.Find(tchCurrSymbol) > -1)
m_nTokenType = xtpEditTokType_Delim;
else if (cstrEOL.Find(tchCurrSymbol) > -1)
m_nTokenType = xtpEditTokType_EOL;
else if (tchCurrSymbol == _T('='))
m_nTokenType = xtpEditTokType_Control;
else if (tchCurrSymbol == _T(':'))
m_nTokenType = xtpEditTokType_Control;
if (nFoundedToken != m_nTokenType)
m_nCurrPos--;
return nFoundedToken;
}
int CXTPSyntaxEditLexCfgFileReader::ProcessValueToken(TCHAR tchCurrSymbol)
{
int nFoundedToken = m_nTokenType;
if (cstrDelims.Find(tchCurrSymbol) > -1)
m_nTokenType = xtpEditTokType_Delim;
else if (cstrEOL.Find(tchCurrSymbol) > -1)
m_nTokenType = xtpEditTokType_EOL;
else if (tchCurrSymbol == _T('/'))
m_nTokenType = xtpEditTokType_Comment;
if (nFoundedToken != m_nTokenType)
m_nCurrPos--;
return nFoundedToken;
}
int CXTPSyntaxEditLexCfgFileReader::ProcessQuotedToken(TCHAR tchCurrSymbol)
{
int nFoundedToken = m_nTokenType;
int nLen = m_strToken.GetLength();
if (cstrEOL.Find(tchCurrSymbol) > -1)
m_nTokenType = xtpEditTokType_EOL;
else if (m_nCurrPos == m_nEOFPos)
m_nTokenType = xtpEditTokType_Unknown;
else if (nLen == 0)
return nFoundedToken;
else if (m_strToken.GetAt(max(0, m_strToken.GetLength() - 1)) == _T('\\'))
{
return nFoundedToken;
}
else if (tchCurrSymbol == _T('\''))
{
if (m_strToken == _T('\''))
{
nFoundedToken = GetToken();
}
else
{
m_nTokenType = xtpEditTokType_Unknown;
m_strToken += tchCurrSymbol;
m_nCurrPos++;
}
}
return nFoundedToken;
}
int CXTPSyntaxEditLexCfgFileReader::ProcessCommentToken(TCHAR tchCurrSymbol)
{
int nFoundedToken = m_nTokenType;
if (cstrEOL.Find(tchCurrSymbol) > -1)
{
m_nTokenType = xtpEditTokType_EOL;
m_nCurrPos--;
}
return nFoundedToken;
}
int CXTPSyntaxEditLexCfgFileReader::ProcessEOLToken(TCHAR tchCurrSymbol)
{
return ProcessUnknowToken(tchCurrSymbol);
}
int CXTPSyntaxEditLexCfgFileReader::ProcessControlToken(TCHAR tchCurrSymbol)
{
return ProcessUnknowToken(tchCurrSymbol);
}
CXTPSyntaxEditLexClassInfoArray& CXTPSyntaxEditLexCfgFileReader::GetLexClassInfoArray()
{
return m_arLexClassInfo;
}
BOOL CXTPSyntaxEditLexCfgFileReader::WriteCfgFile(const CString& csFileName, CXTPSyntaxEditLexClassInfoArray& arLexClassDesc)
{
if (!arLexClassDesc.m_bModified)
return FALSE;
CStringArray arBuffer;
CMapPtrToBool mapSavedClass;
ReadSource(csFileName, FALSE);
ReadSource2(csFileName, arBuffer);
try
{
CString csTmpFileName = csFileName + _T(".tmp");
::SetFileAttributes(csTmpFileName, FILE_ATTRIBUTE_NORMAL);
::DeleteFile(csTmpFileName);
CFile file;
if (!AfxOpenFile(file, csTmpFileName, CFile::modeWrite | CFile::shareExclusive | CFile::modeCreate))
return FALSE;
int nLastWrittenLine = 0;
// (1) Update Existing and deleted Classes
int nCount = (int)m_arLexClassInfo.GetSize();
int i;
for (i = 0; i < nCount; i++)
{
XTP_EDIT_LEXCLASSINFO& oldClassInfo = m_arLexClassInfo[i];
XTP_EDIT_LEXCLASSINFO* pNewClassInfo = FindClassDesc(arLexClassDesc, oldClassInfo.csClassName);
// class was deleted;
if (!pNewClassInfo)
{
WriteStrings(file, arBuffer, nLastWrittenLine+1, oldClassInfo.nStartLine-1);
nLastWrittenLine = oldClassInfo.nEndLine;
continue;
}
mapSavedClass[pNewClassInfo] = TRUE;
CMapPtrToBool mapSavedProps;
CString csOffset(_T("\t"));
// (1.a) Update Existing and deleted properties
int nPropsCount = (int)oldClassInfo.arPropertyDesc.GetSize();
int k;
for (k = 0; k < nPropsCount; k++)
{
XTP_EDIT_LEXPROPINFO& oldInfoProp = oldClassInfo.arPropertyDesc[k];
WriteStrings(file, arBuffer, nLastWrittenLine+1, oldInfoProp.nLine-1);
nLastWrittenLine = oldInfoProp.nLine;
XTP_EDIT_LEXPROPINFO* pNewInfoProp = FindPropDesc(pNewClassInfo, &oldInfoProp, mapSavedProps);
if (pNewInfoProp)
{
WriteProp(file, csOffset, oldInfoProp, *pNewInfoProp, arBuffer);
mapSavedProps[pNewInfoProp] = TRUE;
}
}
// (1.b) Insert new properties
nPropsCount = (int)pNewClassInfo->arPropertyDesc.GetSize();
for (k = 0; k < nPropsCount; k++)
{
XTP_EDIT_LEXPROPINFO& newInfoProp = pNewClassInfo->arPropertyDesc[k];
bool bSaved = false;
if (!mapSavedProps.Lookup((void*)&newInfoProp, bSaved) || !bSaved)
{
WriteProp(file, csOffset, newInfoProp);
}
}
}
//------------------------------------------------------------------------
WriteStrings(file, arBuffer, nLastWrittenLine + 1, m_nCurrLine);
nLastWrittenLine = m_nCurrLine;
//===========================================================================
// (2) Insert new Classes
nCount = (int)arLexClassDesc.GetSize();
for (i = 0; i < nCount; i++)
{
XTP_EDIT_LEXCLASSINFO& newClassInfo = arLexClassDesc[i];
bool bSaved = false;
if (!mapSavedClass.Lookup((void*)&newClassInfo, bSaved) || !bSaved)
{
WriteString(file, _T(""));
WriteString(file, XTP_EDIT_LEXCLASS_STARTTOKEN);
// Insert properties
int nPropsCount = (int)newClassInfo.arPropertyDesc.GetSize();
for (int k = 0; k < nPropsCount; k++)
{
const XTP_EDIT_LEXPROPINFO& newInfoProp = newClassInfo.arPropertyDesc[k];
CString csOffset(_T("\t"));
WriteProp(file, csOffset, newInfoProp);
}
WriteString(file, XTP_EDIT_LEXCLASS_ENDTOKEN);
}
}
//===========================================================================
file.Close();
CString strFileName_prev = csFileName + _T(".old");
::SetFileAttributes(strFileName_prev, FILE_ATTRIBUTE_NORMAL);
::DeleteFile(strFileName_prev);
#ifdef _DEBUG
//CFile::Rename(csFileName, strFileName_prev);
#endif
::SetFileAttributes(csFileName, FILE_ATTRIBUTE_NORMAL);
::DeleteFile(csFileName);
CFile::Rename(csTmpFileName, csFileName);
m_arLexClassInfo.RemoveAll();
return TRUE;
}
catch(CFileException* expFile)
{
#ifdef _DEBUG
expFile->ReportError();
//ProcessFileException(expFile);
#endif
expFile->Delete();
}
m_arLexClassInfo.RemoveAll();
arLexClassDesc.m_bModified = FALSE;
return FALSE;
}
BOOL CXTPSyntaxEditLexCfgFileReader::WriteCfg2String(CXTPSyntaxEditLexClassInfoArray& arLexClassDesc)
{
if (!arLexClassDesc.m_bModified)
return FALSE;
CStringArray arBuffer;
CMapPtrToBool mapSavedClass;
//ReadSource(csFileName, FALSE);
//ReadSource2(csFileName, arBuffer);
//try
//{
// int nLastWrittenLine = 0;
// // (1) Update Existing and deleted Classes
// int nCount = (int)m_arLexClassInfo.GetSize();
// int i;
// for (i = 0; i < nCount; i++)
// {
// XTP_EDIT_LEXCLASSINFO& oldClassInfo = m_arLexClassInfo[i];
// XTP_EDIT_LEXCLASSINFO* pNewClassInfo = FindClassDesc(arLexClassDesc, oldClassInfo.csClassName);
// // class was deleted;
// if (!pNewClassInfo)
// {
// WriteStrings(file, arBuffer, nLastWrittenLine+1, oldClassInfo.nStartLine-1);
// nLastWrittenLine = oldClassInfo.nEndLine;
// continue;
// }
// mapSavedClass[pNewClassInfo] = TRUE;
// CMapPtrToBool mapSavedProps;
// CString csOffset(_T("\t"));
// // (1.a) Update Existing and deleted properties
// int nPropsCount = (int)oldClassInfo.arPropertyDesc.GetSize();
// int k;
// for (k = 0; k < nPropsCount; k++)
// {
// XTP_EDIT_LEXPROPINFO& oldInfoProp = oldClassInfo.arPropertyDesc[k];
// WriteStrings(file, arBuffer, nLastWrittenLine+1, oldInfoProp.nLine-1);
// nLastWrittenLine = oldInfoProp.nLine;
// XTP_EDIT_LEXPROPINFO* pNewInfoProp = FindPropDesc(pNewClassInfo, &oldInfoProp, mapSavedProps);
// if (pNewInfoProp)
// {
// WriteProp(file, csOffset, oldInfoProp, *pNewInfoProp, arBuffer);
// mapSavedProps[pNewInfoProp] = TRUE;
// }
// }
// // (1.b) Insert new properties
// nPropsCount = (int)pNewClassInfo->arPropertyDesc.GetSize();
// for (k = 0; k < nPropsCount; k++)
// {
// XTP_EDIT_LEXPROPINFO& newInfoProp = pNewClassInfo->arPropertyDesc[k];
// bool bSaved = false;
// if (!mapSavedProps.Lookup((void*)&newInfoProp, bSaved) || !bSaved)
// {
// WriteProp(file, csOffset, newInfoProp);
// }
// }
// }
// //------------------------------------------------------------------------
// WriteStrings(file, arBuffer, nLastWrittenLine + 1, m_nCurrLine);
// nLastWrittenLine = m_nCurrLine;
// //===========================================================================
// // (2) Insert new Classes
// nCount = (int)arLexClassDesc.GetSize();
// for (i = 0; i < nCount; i++)
// {
// XTP_EDIT_LEXCLASSINFO& newClassInfo = arLexClassDesc[i];
// bool bSaved = false;
// if (!mapSavedClass.Lookup((void*)&newClassInfo, bSaved) || !bSaved)
// {
// WriteString(file, _T(""));
// WriteString(file, XTP_EDIT_LEXCLASS_STARTTOKEN);
// // Insert properties
// int nPropsCount = (int)newClassInfo.arPropertyDesc.GetSize();
// for (int k = 0; k < nPropsCount; k++)
// {
// const XTP_EDIT_LEXPROPINFO& newInfoProp = newClassInfo.arPropertyDesc[k];
// CString csOffset(_T("\t"));
// WriteProp(file, csOffset, newInfoProp);
// }
// WriteString(file, XTP_EDIT_LEXCLASS_ENDTOKEN);
// }
// }
m_arLexClassInfo.RemoveAll();
return TRUE;
}
XTP_EDIT_LEXCLASSINFO* CXTPSyntaxEditLexCfgFileReader::FindClassDesc(CXTPSyntaxEditLexClassInfoArray& arInfoClass, const CString& csClassName)
{
if (csClassName.IsEmpty())
{
ASSERT(FALSE);
return NULL;
}
for (int i = 0; i < arInfoClass.GetSize(); i++)
{
if (arInfoClass[i].csClassName.CompareNoCase(csClassName) == 0)
{
return &arInfoClass[i];
}
}
return NULL;
}
XTP_EDIT_LEXPROPINFO* CXTPSyntaxEditLexCfgFileReader::FindPropDesc(XTP_EDIT_LEXCLASSINFO* pInfoClass, XTP_EDIT_LEXPROPINFO* pInfoProp, CMapPtrToBool& mapUsed)
{
if (!pInfoClass || !pInfoProp)
{
ASSERT(FALSE);
return NULL;
}
int nPNameSize = (int)pInfoProp->arPropName.GetSize();
CString strPropName_src = MakeStr(pInfoProp->arPropName, _T(":"));
int nCount = (int)pInfoClass->arPropertyDesc.GetSize();
for (int i = 0; i < nCount; i++)
{
XTP_EDIT_LEXPROPINFO* pNewInfoProp = &(*pInfoClass).arPropertyDesc[i];
ASSERT(pNewInfoProp);
if (pNewInfoProp && pNewInfoProp->arPropName.GetSize() == nPNameSize)
{
CString strPName = MakeStr(pNewInfoProp->arPropName, _T(":"));
if (strPropName_src.CompareNoCase(strPName) == 0)
{
bool bUsed = false;
if (mapUsed.Lookup(pNewInfoProp, bUsed) && bUsed)
{
continue;
}
return pNewInfoProp;
}
}
}
return NULL;
}
void CXTPSyntaxEditLexCfgFileReader::WriteString(CFile& file, LPCTSTR pcszString)
{
int nStrLen = (int)_tcslen(pcszString);
#ifdef _UNICODE
CByteArray arBufferMBCS;
arBufferMBCS.SetSize(nStrLen*2+4);
char* pTextMBCS = (char*)arBufferMBCS.GetData();
int nNewLen = WideCharToMultiByte(CP_ACP, 0,
pcszString, -1, pTextMBCS, nStrLen*2+1, NULL, NULL);
nStrLen = nNewLen ? nNewLen-1 : 0;
#else
char* pTextMBCS = (char*)pcszString;
#endif
file.Write(pTextMBCS, nStrLen);
file.Write("\r\n", 2);
}
void CXTPSyntaxEditLexCfgFileReader::WriteStrings(CFile& file, CStringArray& arBuffer, int nFrom, int nTo)
{
int nCount = (int)arBuffer.GetSize();
if (nFrom >= nCount || nFrom > nTo)
{
return;
}
if (nTo >= nCount)
{
nTo = nCount-1;
}
for (int nLine = nFrom; nLine <= nTo; nLine++)
{
CString csBuffer = arBuffer[nLine];
WriteString(file, csBuffer);
}
}
void CXTPSyntaxEditLexCfgFileReader::WriteProp(CFile& file, CString& csOffset, const XTP_EDIT_LEXPROPINFO& newInfoProp)
{
CString csPropName = MakeStr(newInfoProp.arPropName, _T(":"));
CString csPropValue = AfxMakeStrES(newInfoProp.arPropValue, _T(", "));
CString csPropString = csOffset + csPropName + _T(" = ") + csPropValue;
WriteString(file, csPropString);
}
void CXTPSyntaxEditLexCfgFileReader::WriteProp(CFile& file, CString& csOffset, const XTP_EDIT_LEXPROPINFO& oldInfoProp, const XTP_EDIT_LEXPROPINFO& newInfoProp, const CStringArray& arBuffer)
{
if (oldInfoProp.nLine < arBuffer.GetSize())
{
CString csBuffer = arBuffer[oldInfoProp.nLine];
int iIndex = csBuffer.Find(_T("="));
ASSERT(iIndex > 0);
if (iIndex > 0)
{
csOffset = csBuffer.SpanIncluding(_T(" \t"));
CString csSep = csBuffer.Mid(iIndex+1);
csSep = csSep.SpanIncluding(_T(" \t"));
iIndex += csSep.GetLength();
CString csNewBuffer = csBuffer;
csNewBuffer.Delete(iIndex+1, oldInfoProp.nPropertyLen);
CString csPropValue = AfxMakeStrES(newInfoProp.arPropValue, _T(", "));
csNewBuffer.Insert(iIndex+1, csPropValue);
WriteString(file, csNewBuffer);
return;
}
}
else
{
ASSERT(FALSE);
}
WriteProp(file, csOffset, newInfoProp);
}
#ifdef _DEBUG
void CXTPSyntaxEditLexCfgFileReader::ProcessFileException(CFileException* pExc)
{
CString strErrorMsg(_T(" "));
switch (pExc->m_cause)
{
#if (_MSC_VER > 1310) // VS2005
case CFileException::genericException :
#else
case CFileException::generic :
#endif
strErrorMsg = _T("An unspecified error occurred.");
break;
case CFileException::fileNotFound :
strErrorMsg = _T("The file could not be located.");
break;
case CFileException::badPath :
strErrorMsg = _T("All or part of the path is invalid.");
break;
case CFileException::tooManyOpenFiles :
strErrorMsg = _T("The permitted number of open files was exceeded.");
break;
case CFileException::accessDenied :
strErrorMsg = _T("The file could not be accessed.");
break;
case CFileException::invalidFile :
strErrorMsg = _T("There was an attempt to use an invalid file handle.");
break;
case CFileException::removeCurrentDir :
strErrorMsg = _T("The current working directory cannot be removed.");
break;
case CFileException::directoryFull :
strErrorMsg = _T("There are no more directory entries.");
break;
case CFileException::badSeek :
strErrorMsg = _T("There was an error trying to set the file pointer.");
break;
case CFileException::hardIO :
strErrorMsg = _T("There was a hardware error.");
break;
case CFileException::sharingViolation :
strErrorMsg = _T("SHARE.EXE was not loaded, or a shared region was locked.");
break;
case CFileException::lockViolation :
strErrorMsg = _T("There was an attempt to lock a region that was already locked.");
break;
case CFileException::diskFull :
strErrorMsg = _T("The disk is full.");
break;
case CFileException::endOfFile :
strErrorMsg = _T("The end of file was reached.");
break;
default :
strErrorMsg = _T("Unknown error.");
}
TRACE(_T("ERROR: %s File Name: %s \n"), (LPCTSTR)strErrorMsg, (LPCTSTR)pExc->m_strFileName);
}
#endif
CString CXTPSyntaxEditLexCfgFileReader::StrToES(CString strSrc, BOOL bQuoted)
{
CString strRez(strSrc);
strRez.TrimLeft(); strRez.TrimRight();
int nLen = strRez.GetLength();
if (nLen < 1)
{
return strRez;
}
if (bQuoted && strRez.GetAt(0) == _T('\'') && strRez.GetAt(nLen - 1) == _T('\''))
{
strRez.SetAt(0, _T('\x1'));
strRez.SetAt(nLen-1, _T('\x1'));
}
strRez.Replace(_T("\\\\"), _T("\x2"));
strRez.Replace(_T("\\a"), _T("\a"));
strRez.Replace(_T("\\b"), _T("\b"));
strRez.Replace(_T("\\f"), _T("\f"));
strRez.Replace(_T("\\n"), _T("\n"));
strRez.Replace(_T("\\r"), _T("\r"));
strRez.Replace(_T("\\t"), _T("\t"));
strRez.Replace(_T("\\v"), _T("\v"));
strRez.Replace(_T("\\'"), _T("\'"));
strRez.Replace(_T("\x2"), _T("\\"));
strRez.Replace(_T("\x1"), _T("\'"));
return strRez;
}
CString CXTPSyntaxEditLexCfgFileReader::ESToStr(CString strSrc, BOOL bQuoted)
{
CString strRez(strSrc);
strRez.TrimLeft(); strRez.TrimRight();
int nLen = strRez.GetLength();
if (nLen < 1)
{
return strRez;
}
if (bQuoted && strRez.GetAt(0) == _T('\'') && strRez.GetAt(nLen - 1) == _T('\''))
{
strRez.SetAt(0, _T('\x1'));
strRez.SetAt(nLen-1, _T('\x1'));
}
strRez.Replace(_T("\\"), _T("\x2"));
strRez.Replace(_T("\a"), _T("\\a"));
strRez.Replace(_T("\b"), _T("\\b"));
strRez.Replace(_T("\f"), _T("\\f"));
strRez.Replace(_T("\n"), _T("\\n"));
strRez.Replace(_T("\r"), _T("\\r"));
strRez.Replace(_T("\t"), _T("\\t"));
strRez.Replace(_T("\v"), _T("\\v"));
strRez.Replace(_T("\'"), _T("\\'"));
strRez.Replace(_T("\x2"), _T("\\\\"));
strRez.Replace(_T("\x1"), _T("\'"));
return strRez;
}
/////////////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditFileChangesMonitor
//
CXTPSyntaxEditFileChangesMonitor::CXTPSyntaxEditFileChangesMonitor()
{
m_pThread = NULL;
m_evExitThread = NULL;
m_pConfigMgr = NULL;
}
CXTPSyntaxEditFileChangesMonitor::~CXTPSyntaxEditFileChangesMonitor()
{
StopMonitoring();
}
void CXTPSyntaxEditFileChangesMonitor::SetDefaultFolder(const CString& strPath)
{
m_strPath = strPath;
}
void CXTPSyntaxEditFileChangesMonitor::RemoveAll()
{
m_arFiles.RemoveAll();
}
BOOL CXTPSyntaxEditFileChangesMonitor::AddMonitorFile(CString& strFilename,
DWORD dwOwnerFlags)
{
// try open file
BY_HANDLE_FILE_INFORMATION sysFileInfo;
BOOL bRes = GetFileInfo(strFilename, &sysFileInfo);
if (!bRes)
{
// try again in the default folder
CString strFullFilename = m_strPath + strFilename;
bRes = GetFileInfo(strFullFilename, &sysFileInfo);
if (bRes)
strFilename = strFullFilename;
}
// get complete file name
if (bRes)
{
// get the directory for the file
TCHAR szPath[_MAX_PATH];
LPTSTR lpszName;
if (::GetFullPathName(strFilename, _MAX_PATH, szPath, &lpszName))
strFilename = szPath;
}
// Prepare file info structure
CFMFileInfo fmFileInfo;
fmFileInfo.m_strFileName = strFilename;
fmFileInfo.m_bExists = bRes;
fmFileInfo.m_dwOwnerFlags = dwOwnerFlags;
if (bRes)
fmFileInfo.m_sysFileInfo = sysFileInfo;
// add file to the monitoring array
m_arFiles.Add(fmFileInfo);
return bRes;
}
void CXTPSyntaxEditFileChangesMonitor::StartMonitoring()
{
if (m_pThread)
{
ASSERT(FALSE);
return;
}
ASSERT(m_evExitThread == NULL);
m_evExitThread = CreateEvent(NULL, TRUE, FALSE, NULL);
ASSERT(m_evExitThread);
m_pThread = AfxBeginThread(ThreadMonitorProc, (LPVOID)this,
THREAD_PRIORITY_LOWEST);
//, 0, CREATE_SUSPENDED, NULL);
if (!m_pThread)
{
ASSERT(FALSE);
return;
}
}
void CXTPSyntaxEditFileChangesMonitor::StopMonitoring()
{
if (m_pThread)
{
HANDLE hThread = m_pThread->m_hThread;
::SetEvent(m_evExitThread);
DWORD dwThreadRes = ::WaitForSingleObject(hThread, 20*1000);
if (dwThreadRes == WAIT_TIMEOUT)
{
::TerminateThread(hThread, 0);
//ASSERT(FALSE);
TRACE(_T("ERROR! FileChangesMonitor thread was not ended by normal way. It was terminated. \n"));
}
::CloseHandle(m_evExitThread);
m_evExitThread = NULL;
m_pThread = NULL;
}
RemoveAll();
}
UINT CXTPSyntaxEditFileChangesMonitor::ThreadMonitorProc(LPVOID p)
{
try
{
CXTPSyntaxEditFileChangesMonitor* pFolderMonitor = (CXTPSyntaxEditFileChangesMonitor*)p;
if (!pFolderMonitor)
return 1;
for (;;)
{
// Wait for notification.
DWORD dwWaitStatus = WaitForSingleObject(pFolderMonitor->m_evExitThread, 3000);
if (WAIT_OBJECT_0 == dwWaitStatus)
{
::Sleep(100);
break;
}
if (WAIT_TIMEOUT == dwWaitStatus)
{
pFolderMonitor->RefreshFiles();
}
}
}
catch(...)
{
TRACE(_T("EXCEPTION in CXTPSyntaxEditFileChangesMonitor::ThreadMonitorProc\n"));
}
return 0;
}
void CXTPSyntaxEditFileChangesMonitor::RefreshFiles()
{
// Iterate all stored filenames
int nCount = (int)m_arFiles.GetSize();
for (int i = 0; i < nCount; i++)
{
//CString strFilename;
CFMFileInfo& rFMFileInfo = m_arFiles.ElementAt(i);
// get new info for this file
BY_HANDLE_FILE_INFORMATION sysFileInfo;
if (GetFileInfo(rFMFileInfo.m_strFileName, &sysFileInfo) )
{
// check whether file status is changed
if (!AfxCompareTime(sysFileInfo.ftLastWriteTime,
rFMFileInfo.m_sysFileInfo.ftLastWriteTime) ||
sysFileInfo.nFileSizeLow != rFMFileInfo.m_sysFileInfo.nFileSizeLow ||
sysFileInfo.nFileSizeHigh != rFMFileInfo.m_sysFileInfo.nFileSizeHigh
|| !rFMFileInfo.m_bExists)
{
int nCfgFlags = rFMFileInfo.m_bExists ? 0 : xtpEditCfgFileAdd;
rFMFileInfo.m_sysFileInfo = sysFileInfo;
rFMFileInfo.m_bExists = TRUE;
// reload this file
m_pConfigMgr->ReloadFile(rFMFileInfo.m_strFileName,
rFMFileInfo.m_dwOwnerFlags, nCfgFlags);
}
}
else
{
if (rFMFileInfo.m_bExists)
{
rFMFileInfo.m_bExists = FALSE;
// remove this file from the collection
m_pConfigMgr->ReloadFile(rFMFileInfo.m_strFileName,
rFMFileInfo.m_dwOwnerFlags, xtpEditCfgFileRemove);
}
// try again in the default folder
CString strFullFilename = m_strPath + rFMFileInfo.m_strFileName;
if (GetFileInfo(strFullFilename, &sysFileInfo))
{
rFMFileInfo.m_strFileName = strFullFilename;
i--;
}
}
}
}
BOOL CXTPSyntaxEditFileChangesMonitor::GetFileInfo(LPCTSTR pcszFilePath,
BY_HANDLE_FILE_INFORMATION* pInfo)
{
const DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
HANDLE hFile = ::CreateFile(pcszFilePath, GENERIC_READ, dwShareMode, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
if (!pInfo)
{
return TRUE;
}
ZeroMemory(pInfo, sizeof(*pInfo));
BOOL bRes = GetFileInformationByHandle(hFile, pInfo);
CloseHandle(hFile);
return bRes;
}
////////////////////////////////////////////////////////////////////////////
//class CFMFileInfo
CXTPSyntaxEditFileChangesMonitor::CFMFileInfo::CFMFileInfo()
{
ZeroMemory(&m_sysFileInfo, sizeof(m_sysFileInfo));
m_bExists = FALSE;
m_dwOwnerFlags = 0;
}
const CXTPSyntaxEditFileChangesMonitor::CFMFileInfo&
CXTPSyntaxEditFileChangesMonitor::CFMFileInfo::operator=(
const CXTPSyntaxEditFileChangesMonitor::CFMFileInfo& rSrc)
{
m_strFileName = rSrc.m_strFileName;
m_sysFileInfo = rSrc.m_sysFileInfo;
m_bExists = rSrc.m_bExists;
m_dwOwnerFlags = rSrc.m_dwOwnerFlags;
return *this;
}