XTPSyntaxEditLexCfgFileReader.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:38k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPSyntaxEditLexCfgFileReader.cpp: implementation of the CXTPSyntaxEditLexCfgFileReader class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME SYNTAX EDIT LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. //////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. // common includes
  22. #include "Common/XTPColorManager.h"
  23. #include "Common/XTPNotifyConnection.h"
  24. #include "Common/XTPSmartPtrInternalT.h"
  25. #include "Common/XTPResourceManager.h"
  26. #include "Common/XTPVC80Helpers.h"
  27. #include "Common/XTPVC50Helpers.h"
  28. // syntax editor includes
  29. #include "XTPSyntaxEditDefines.h"
  30. #include "XTPSyntaxEditStruct.h"
  31. #include "XTPSyntaxEditLexPtrs.h"
  32. #include "XTPSyntaxEditLexClassSubObjT.h"
  33. #include "XTPSyntaxEditTextIterator.h"
  34. #include "XTPSyntaxEditSectionManager.h"
  35. #include "XTPSyntaxEditLexCfgFileReader.h"
  36. #include "XTPSyntaxEditLexClassSubObjDef.h"
  37. #include "XTPSyntaxEditLexClass.h"
  38. #include "XTPSyntaxEditLexParser.h"
  39. #include "XTPSyntaxEditLexColorFileReader.h"
  40. #include "XTPSyntaxEditCtrl.h"
  41. #ifdef _DEBUG
  42. #define new DEBUG_NEW
  43. #undef THIS_FILE
  44. static char THIS_FILE[] = __FILE__;
  45. #endif
  46. #ifndef DBG_READ_TRACE
  47. #define DBG_READ_TRACE
  48. #endif
  49. namespace XTPSyntaxEditLexAnalyser
  50. {
  51. //===========================================================================
  52. // XTP_EDIT_LEXPROPINFO
  53. //===========================================================================
  54. XTP_EDIT_LEXPROPINFO::XTP_EDIT_LEXPROPINFO()
  55. {
  56. nLine           = 0;
  57. nOffset         = 0;
  58. nPropertyLen    = 0;
  59. }
  60. XTP_EDIT_LEXPROPINFO::XTP_EDIT_LEXPROPINFO(const XTP_EDIT_LEXPROPINFO& rSrc)
  61. {
  62. arPropName.RemoveAll();
  63. int i;
  64. for (i = 0; i < rSrc.arPropName.GetSize(); ++i) {
  65. arPropName.Add(rSrc.arPropName[i]);
  66. }
  67. arPropValue.RemoveAll();
  68. for (i = 0; i < rSrc.arPropValue.GetSize(); ++i) {
  69. arPropValue.Add(rSrc.arPropValue[i]);
  70. }
  71. nLine           = rSrc.nLine;
  72. nOffset         = rSrc.nOffset;
  73. nPropertyLen    = rSrc.nPropertyLen;
  74. }
  75. const XTP_EDIT_LEXPROPINFO& XTP_EDIT_LEXPROPINFO::operator = (const XTP_EDIT_LEXPROPINFO& rSrc)
  76. {
  77. arPropName.RemoveAll();
  78. int i;
  79. for (i = 0; i < rSrc.arPropName.GetSize(); ++i) {
  80. arPropName.Add(rSrc.arPropName[i]);
  81. }
  82. arPropValue.RemoveAll();
  83. for (i = 0; i < rSrc.arPropValue.GetSize(); ++i) {
  84. arPropValue.Add(rSrc.arPropValue[i]);
  85. }
  86. nLine           = rSrc.nLine;
  87. nOffset         = rSrc.nOffset;
  88. nPropertyLen    = rSrc.nPropertyLen;
  89. return *this;
  90. }
  91. //===========================================================================
  92. // CXTPSyntaxEditLexPropInfoArray
  93. //===========================================================================
  94. CXTPSyntaxEditLexPropInfoArray::CXTPSyntaxEditLexPropInfoArray()
  95. {
  96. }
  97. CXTPSyntaxEditLexPropInfoArray::CXTPSyntaxEditLexPropInfoArray(const CXTPSyntaxEditLexPropInfoArray& rSrc)
  98. {
  99. RemoveAll();
  100. for (int i = 0; i < rSrc.GetSize(); ++i)
  101. {
  102. XTP_EDIT_LEXPROPINFO info(rSrc[i]);
  103. Add(info);
  104. }
  105. }
  106. const CXTPSyntaxEditLexPropInfoArray& CXTPSyntaxEditLexPropInfoArray::operator = (const CXTPSyntaxEditLexPropInfoArray& rSrc)
  107. {
  108. RemoveAll();
  109. for (int i = 0; i < rSrc.GetSize(); ++i)
  110. {
  111. XTP_EDIT_LEXPROPINFO info(rSrc[i]);
  112. Add(info);
  113. }
  114. return *this;
  115. }
  116. //===========================================================================
  117. // XTP_EDIT_LEXCLASSINFO
  118. //===========================================================================
  119. XTP_EDIT_LEXCLASSINFO::XTP_EDIT_LEXCLASSINFO()
  120. {
  121. nEndLine    = 0;
  122. nStartLine  = 0;
  123. }
  124. XTP_EDIT_LEXCLASSINFO::XTP_EDIT_LEXCLASSINFO(const XTP_EDIT_LEXCLASSINFO& rSrc)
  125. {
  126. arPropertyDesc.RemoveAll();
  127. for (int i = 0; i < rSrc.arPropertyDesc.GetSize(); ++i)
  128. {
  129. XTP_EDIT_LEXPROPINFO info(rSrc.arPropertyDesc[i]);
  130. arPropertyDesc.Add(info);
  131. }
  132. nEndLine    = rSrc.nEndLine;
  133. nStartLine  = rSrc.nStartLine;
  134. csClassName = rSrc.csClassName;
  135. }
  136. const XTP_EDIT_LEXCLASSINFO& XTP_EDIT_LEXCLASSINFO::operator = (const XTP_EDIT_LEXCLASSINFO& rSrc)
  137. {
  138. arPropertyDesc.RemoveAll();
  139. for (int i = 0; i < rSrc.arPropertyDesc.GetSize(); ++i)
  140. {
  141. XTP_EDIT_LEXPROPINFO info(rSrc.arPropertyDesc[i]);
  142. arPropertyDesc.Add(info);
  143. }
  144. nEndLine    = rSrc.nEndLine;
  145. nStartLine  = rSrc.nStartLine;
  146. csClassName = rSrc.csClassName;
  147. return *this;
  148. }
  149. //===========================================================================
  150. // CXTPSyntaxEditLexClassInfoArray
  151. //===========================================================================
  152. CXTPSyntaxEditLexClassInfoArray::CXTPSyntaxEditLexClassInfoArray()
  153. {
  154. m_bModified = FALSE;
  155. }
  156. CXTPSyntaxEditLexClassInfoArray::CXTPSyntaxEditLexClassInfoArray(const CXTPSyntaxEditLexClassInfoArray& rSrc)
  157. {
  158. RemoveAll();
  159. m_bModified = rSrc.m_bModified;
  160. for (int i = 0; i < rSrc.GetSize(); ++i)
  161. {
  162. XTP_EDIT_LEXCLASSINFO info(rSrc[i]);
  163. Add(info);
  164. }
  165. }
  166. const CXTPSyntaxEditLexClassInfoArray& CXTPSyntaxEditLexClassInfoArray::operator = (const CXTPSyntaxEditLexClassInfoArray& rSrc)
  167. {
  168. RemoveAll();
  169. m_bModified = rSrc.m_bModified;
  170. for (int i = 0; i < rSrc.GetSize(); ++i)
  171. {
  172. XTP_EDIT_LEXCLASSINFO info(rSrc[i]);
  173. Add(info);
  174. }
  175. return *this;
  176. }
  177. extern CString MakeStr(const CStringArray& rArProps, LPCTSTR strSplitter);
  178. }
  179. //////////////////////////////////////////////////////////////////////
  180. // Construction/Destruction
  181. //////////////////////////////////////////////////////////////////////
  182. using namespace XTPSyntaxEditLexAnalyser;
  183. const CString cstrDelims(_T(" t,"));
  184. const CString cstrEOL(_T("rn"));
  185. const CString cstrHex(_T("0123456789ABCDEFGabcdefg"));
  186. AFX_STATIC BOOL AFX_CDECL AfxCompareTime(const FILETIME& ft1, const FILETIME& ft2, DWORD dwTimeDiff = 500)
  187. {
  188. ULARGE_INTEGER uFT1, uFT2;
  189. uFT1.LowPart = ft1.dwLowDateTime;
  190. uFT1.HighPart = ft1.dwHighDateTime;
  191. uFT2.LowPart = ft2.dwLowDateTime;
  192. uFT2.HighPart = ft2.dwHighDateTime;
  193. ULONGLONG ullDiff = uFT1.QuadPart > uFT2.QuadPart ? uFT1.QuadPart - uFT2.QuadPart : uFT2.QuadPart - uFT1.QuadPart;
  194. //ullDiff = the number of 100-nanosecond intervals since January 1, 1601.
  195. if (ullDiff <= (dwTimeDiff*1000*1000/100))
  196. {
  197. return TRUE;
  198. }
  199. return FALSE;
  200. }
  201. AFX_STATIC BOOL AFX_CDECL AfxOpenFile(CFile& file, LPCTSTR lpszFileName, UINT nOpenFlags)
  202. {
  203. if (nOpenFlags == CFile::modeRead)
  204. {
  205. if (!FILEEXISTS_S(lpszFileName))
  206. {
  207. return FALSE;
  208. }
  209. }
  210. CFileException e;
  211. if (!file.Open(lpszFileName, nOpenFlags, &e))
  212. {
  213. AfxThrowFileException(e.m_cause,e.m_lOsError, e.m_strFileName);
  214. }
  215. return TRUE;
  216. }
  217. AFX_STATIC CString AFX_CDECL AfxMakeStrES(const CStringArray& rArProps, LPCTSTR strSplitter)
  218. {
  219. CString strResult;
  220. int nCount = (int)rArProps.GetSize();
  221. for (int i = 0; i < nCount; i++)
  222. {
  223. CString csProp = XTPSyntaxEditLexConfig()->ESToStr(rArProps[i], TRUE);
  224. if (i)
  225. {
  226. strResult += strSplitter;
  227. }
  228. CString strI = csProp;
  229. strResult += strI;
  230. }
  231. return strResult;
  232. }
  233. ////////////////////////////////////////////////////////////////////////////
  234. CXTPSyntaxEditLexCfgFileReader& AFX_CDECL CXTPSyntaxEditLexCfgFileReader::Instance()
  235. {
  236. static CXTPSyntaxEditLexCfgFileReader instance;
  237. return instance;
  238. }
  239. CXTPSyntaxEditLexCfgFileReader::CXTPSyntaxEditLexCfgFileReader()
  240. {
  241. m_csDataBuffer = XTP_EDIT_LEXCLASS_EMPTYSTR;
  242. m_nCurrLine = 0;
  243. m_nCurrLine_pos = 0;
  244. m_nCurrPos = 0;
  245. m_nEOFPos = 0;
  246. m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
  247. m_nTokenType = xtpEditTokType_Unknown;
  248. m_bReadNames = TRUE;
  249. m_bES = FALSE;
  250. }
  251. CXTPSyntaxEditLexCfgFileReader::~CXTPSyntaxEditLexCfgFileReader()
  252. {
  253. CleanInfoMap(m_mapLexClassInfo);
  254. }
  255. void CXTPSyntaxEditLexCfgFileReader::CleanInfoMap(CMapStringToPtr& mapInfo)
  256. {
  257. for (POSITION pos = mapInfo.GetStartPosition(); pos;)
  258. {
  259. CString csFileName;
  260. CXTPSyntaxEditLexClassInfoArray* pInfoArray = NULL;
  261. mapInfo.GetNextAssoc(pos, csFileName, (void*&)pInfoArray);
  262. SAFE_DELETE(pInfoArray);
  263. }
  264. mapInfo.RemoveAll();
  265. }
  266. void CXTPSyntaxEditLexCfgFileReader::CopyInfoMap(CMapStringToPtr& mapInfo)
  267. {
  268. CleanInfoMap(mapInfo);
  269. for (POSITION pos = m_mapLexClassInfo.GetStartPosition(); pos;)
  270. {
  271. // get the source data.
  272. CString csFileName;
  273. CXTPSyntaxEditLexClassInfoArray* pSource = NULL;
  274. m_mapLexClassInfo.GetNextAssoc(pos, csFileName, (void*&)pSource);
  275. // instantiate a new data pointer.
  276. CXTPSyntaxEditLexClassInfoArray* pDest =
  277. new CXTPSyntaxEditLexClassInfoArray(*pSource);
  278. // set the data.
  279. mapInfo[csFileName] = pDest;
  280. }
  281. }
  282. void CXTPSyntaxEditLexCfgFileReader::ReadSource2(const CString& csFileName, CStringArray& arBuffer)
  283. {
  284. try
  285. {
  286. arBuffer.RemoveAll();
  287. CStdioFile file;
  288. if (AfxOpenFile(file, csFileName, CFile::modeRead))
  289. {
  290. arBuffer.Add(_T(""));
  291. CString csBuffer;
  292. while (file.ReadString(csBuffer))
  293. {
  294. int nLen = csBuffer.GetLength();
  295. if (nLen && csBuffer[nLen-1] == _T('r'))
  296. {
  297. DELETE_S(csBuffer, nLen-1);
  298. }
  299. arBuffer.Add(csBuffer);
  300. }
  301. }
  302. }
  303. catch(CFileException* expFile)
  304. {
  305. #ifdef _DEBUG
  306. ProcessFileException(expFile);
  307. #endif
  308. expFile->Delete();
  309. }
  310. }
  311. void CXTPSyntaxEditLexCfgFileReader::ReadSource(const CString& csFileName, BOOL bSaveInfo)
  312. {
  313. try
  314. {
  315. CFile file;
  316. if (AfxOpenFile(file, csFileName, CFile::modeRead))
  317. {
  318. int iLen = (int)file.GetLength();
  319. char* pszBuffer = new char[iLen+2];
  320. int iBytes = (int)file.Read(pszBuffer, iLen);
  321. ASSERT(iLen == iBytes);
  322. pszBuffer[iLen] = '';
  323. m_csDataBuffer = pszBuffer;
  324. SAFE_DELETE_AR(pszBuffer);
  325. file.Close();
  326. Parse(m_arLexClassInfo);
  327. if (bSaveInfo)
  328. {
  329. CString csKey = csFileName;
  330. csKey.MakeLower();
  331. CXTPSyntaxEditLexClassInfoArray* pInfo = NULL;
  332. if (!m_mapLexClassInfo.Lookup(csKey, (void*&)pInfo))
  333. {
  334. m_mapLexClassInfo[csKey] = new CXTPSyntaxEditLexClassInfoArray(m_arLexClassInfo);
  335. }
  336. else
  337. {
  338. *pInfo = m_arLexClassInfo;
  339. }
  340. }
  341. }
  342. }
  343. catch(CFileException* expFile)
  344. {
  345. #ifdef _DEBUG
  346. ProcessFileException(expFile);
  347. #endif
  348. expFile->Delete();
  349. }
  350. }
  351. void CXTPSyntaxEditLexCfgFileReader::ReadSource(UINT nResourceID)
  352. {
  353. VERIFY(XTPResourceManager()->LoadHTML(&m_csDataBuffer, nResourceID));
  354. }
  355. void CXTPSyntaxEditLexCfgFileReader::Parse(CXTPSyntaxEditLexClassInfoArray& arLexClassDesc)
  356. {
  357. arLexClassDesc.RemoveAll();
  358. m_nEOFPos = m_csDataBuffer.GetLength() - 1;
  359. m_nPrevPos = 0;
  360. if (m_nEOFPos < 0)
  361. {
  362. return;
  363. }
  364. m_nCurrLine = 1;
  365. m_nCurrLine_pos = 0;
  366. m_nCurrPos = 0;
  367. m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
  368. int nTokenType = 0;
  369. while (m_nEOFPos > m_nCurrPos && m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0)
  370. {
  371. nTokenType = GetLexToken();
  372. }
  373. if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) == 0)
  374. {
  375. while (m_nEOFPos > m_nCurrPos)
  376. {
  377. XTP_EDIT_LEXCLASSINFO infoClass;
  378. ParseLexClass(infoClass);
  379. if (!infoClass.csClassName.IsEmpty())
  380. {
  381. arLexClassDesc.Add(infoClass);
  382. }
  383. }
  384. }
  385. }
  386. void CXTPSyntaxEditLexCfgFileReader::ParseLexClass(XTP_EDIT_LEXCLASSINFO& infoClass)
  387. {
  388. if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) == 0)
  389. {
  390. infoClass.nStartLine = m_nCurrLine;
  391. infoClass.nEndLine = 0;
  392. }
  393. int nTokenType = GetLexToken();
  394. int nPrevToken = 0;
  395. while (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0 && m_nEOFPos > m_nCurrPos )
  396. {
  397. XTP_EDIT_LEXPROPINFO infoProp;
  398. if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_ENDTOKEN) == 0)
  399. {
  400. infoClass.nEndLine = m_nCurrLine;
  401. }
  402. infoProp.nLine = 0;
  403. infoProp.nPropertyLen = 0;
  404. infoProp.nOffset = 0;
  405. int nValBeginPos = 0;
  406. while (m_strToken != _T('=') && m_nEOFPos > m_nCurrPos && m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0)
  407. {
  408. if (nTokenType != xtpEditTokType_EOL && m_nEOFPos > m_nCurrPos)
  409. {
  410. if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_PROPNAME) == 0)
  411. {
  412. infoClass.csClassName = m_strToken;
  413. //TRACE(_T("nName = %s"), m_strToken);
  414. }
  415. else
  416. {
  417. infoProp.arPropName.Add(m_strToken);
  418. DBG_READ_TRACE(_T("%s$"),m_strToken);
  419. }
  420. infoProp.nLine = m_nCurrLine;
  421. }
  422. nTokenType = GetLexToken();
  423. }
  424. if (m_strToken.CompareNoCase(XTP_EDIT_LEXCLASS_STARTTOKEN) != 0 &&
  425. nTokenType != xtpEditTokType_EOL)
  426. { // get value's chain
  427. nTokenType = GetLexToken();
  428. infoProp.nOffset = m_nCurrPos - m_nPrevPos - m_strToken.GetLength();
  429. nValBeginPos = m_nCurrPos - m_strToken.GetLength();
  430. if (nPrevToken == xtpEditTokType_Quoted)
  431. {
  432. infoProp.nOffset += 1;
  433. }
  434. if (nTokenType == xtpEditTokType_Quoted )
  435. {
  436. infoProp.nOffset -= 1;
  437. nValBeginPos -= 1;
  438. }
  439. while (nTokenType != xtpEditTokType_EOL && m_nEOFPos > m_nCurrPos)
  440. {
  441. if (nTokenType != xtpEditTokType_EOL)
  442. {
  443. if (infoClass.csClassName.CompareNoCase(XTP_EDIT_LEXCLASS_PROPNAME) == 0)
  444. {
  445. infoClass.csClassName = m_strToken;
  446. DBG_READ_TRACE(_T("nClass name = %s "),m_strToken);
  447. }
  448. else
  449. {
  450. m_nPrevPos = m_nCurrPos;
  451. CString str = StrToES(m_strToken, TRUE);
  452. infoProp.arPropValue.Add(str);
  453. str = ESToStr(str, TRUE);
  454. DBG_READ_TRACE(_T("|%sn"),str);
  455. }
  456. }
  457. nPrevToken = nTokenType;
  458. nTokenType = GetLexToken();
  459. }
  460. if (infoProp.arPropValue.GetSize() > 0)
  461. {
  462. infoProp.nPropertyLen +=  m_nPrevPos - nValBeginPos;
  463. if (nPrevToken == xtpEditTokType_Quoted)
  464. {
  465. infoProp.nPropertyLen -= 1;
  466. }
  467. infoClass.arPropertyDesc.Add(infoProp);
  468. }
  469. nTokenType = GetLexToken();
  470. }
  471. }
  472. DBG_READ_TRACE(_T("n ---------------- %s -----------------n"), infoClass.csClassName);
  473. if (infoClass.nEndLine == 0)
  474. {
  475. int nCount = (int)infoClass.arPropertyDesc.GetSize();
  476. if (nCount)
  477. {
  478. infoClass.nEndLine = infoClass.arPropertyDesc[nCount-1].nLine;
  479. }
  480. else
  481. {
  482. infoClass.nEndLine = infoClass.nStartLine;
  483. }
  484. }
  485. }
  486. int CXTPSyntaxEditLexCfgFileReader::GetLexToken()
  487. {
  488. int nIgnoredTokensMask = xtpEditTokType_Unknown;
  489. nIgnoredTokensMask |= xtpEditTokType_Delim;
  490. nIgnoredTokensMask |= xtpEditTokType_Comment;
  491. m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
  492. int nTokenType = GetToken();
  493. if (m_strToken == _T(":"))
  494. nTokenType = xtpEditTokType_Unknown;
  495. while ((nTokenType == xtpEditTokType_Unknown ||
  496.    nTokenType == xtpEditTokType_Delim||
  497.    nTokenType == xtpEditTokType_Comment
  498.    ) && m_nEOFPos > m_nCurrPos
  499.    )
  500. {
  501. m_strToken = XTP_EDIT_LEXCLASS_EMPTYSTR;
  502. nTokenType = GetToken();
  503. }
  504. if (m_strToken == _T("lexClass"))
  505. {
  506. GetToken();
  507. }
  508. return nTokenType;
  509. }
  510. int CXTPSyntaxEditLexCfgFileReader::GetToken()
  511. {
  512. TCHAR tchCurrSymbol = _T('');
  513. int nFoundedToken = 0;
  514. if (m_nCurrPos >= m_nEOFPos)
  515. {
  516. return xtpEditTokType_Unknown;
  517. }
  518. //------------------------------------------------------------------------
  519. TCHAR tchCurr_0 = m_csDataBuffer.GetAt(m_nCurrPos);
  520. if (tchCurr_0 == _T('x0A') && m_nCurrPos > m_nCurrLine_pos)
  521. {
  522. m_nCurrLine++;
  523. m_nCurrLine_pos = m_nCurrPos;
  524. }
  525. //------------------------------------------------------------------------
  526. tchCurrSymbol = m_csDataBuffer.GetAt(m_nCurrPos++);
  527. switch (m_nTokenType)
  528. {
  529. case xtpEditTokType_Unknown :
  530. nFoundedToken = ProcessUnknowToken(tchCurrSymbol);
  531. if (m_nTokenType == xtpEditTokType_Unknown)
  532. {
  533. GetToken();
  534. }
  535. break;
  536. case xtpEditTokType_Delim :
  537. nFoundedToken = ProcessDelimToken(tchCurrSymbol);
  538. break;
  539. case xtpEditTokType_Name :
  540. nFoundedToken = ProcessNameToken(tchCurrSymbol);
  541. if (m_nTokenType == xtpEditTokType_Name)
  542. {
  543. m_strToken += tchCurrSymbol;
  544. GetToken();
  545. }
  546. break;
  547. case xtpEditTokType_Value :
  548. nFoundedToken = ProcessValueToken(tchCurrSymbol);
  549. if (m_nTokenType == xtpEditTokType_Value)
  550. {
  551. m_strToken += tchCurrSymbol;
  552. GetToken();
  553. }
  554. break;
  555. case xtpEditTokType_Quoted :
  556. nFoundedToken = ProcessQuotedToken(tchCurrSymbol);
  557. if (m_nTokenType == xtpEditTokType_Quoted)
  558. {
  559. m_strToken += tchCurrSymbol;
  560. GetToken();
  561. }
  562. break;
  563. case xtpEditTokType_Comment :
  564. nFoundedToken = ProcessCommentToken(tchCurrSymbol);
  565. if (m_nTokenType == xtpEditTokType_Comment)
  566. {
  567. m_strToken += tchCurrSymbol;
  568. GetToken();
  569. }
  570. break;
  571. case xtpEditTokType_EOL :
  572. nFoundedToken = ProcessEOLToken(tchCurrSymbol);
  573. if (m_nTokenType == xtpEditTokType_EOL)
  574. {
  575. m_strToken += tchCurrSymbol;
  576. GetToken();
  577. }
  578. break;
  579. case xtpEditTokType_Control :
  580. nFoundedToken = ProcessControlToken(tchCurrSymbol);
  581. if (m_nTokenType == xtpEditTokType_Control)
  582. {
  583. m_strToken += tchCurrSymbol;
  584. GetToken();
  585. }
  586. break;
  587. default :
  588. nFoundedToken = ProcessUnknowToken(tchCurrSymbol);
  589. if (m_nTokenType == xtpEditTokType_Unknown)
  590. {
  591. GetToken();
  592. }
  593. }
  594. return nFoundedToken;
  595. }
  596. int CXTPSyntaxEditLexCfgFileReader::ProcessUnknowToken(TCHAR tchCurrSymbol)
  597. {
  598. int nFoundedToken = m_nTokenType;
  599. if (_istalpha(tchCurrSymbol))
  600. {
  601. m_nTokenType = xtpEditTokType_Name;
  602. }
  603. else if (tchCurrSymbol == _T('''))
  604. {
  605. m_nTokenType = xtpEditTokType_Quoted;
  606. }
  607. else if (tchCurrSymbol == _T('/'))
  608. {
  609. m_nTokenType = xtpEditTokType_Comment;
  610. }
  611. else if (cstrDelims.Find(tchCurrSymbol) > -1)
  612. {
  613. m_nTokenType = xtpEditTokType_Delim;
  614. }
  615. else if (cstrEOL.Find(tchCurrSymbol) > -1)
  616. {
  617. m_nTokenType = xtpEditTokType_EOL;
  618. }
  619. else if (tchCurrSymbol == _T('='))
  620. {
  621. m_nTokenType = xtpEditTokType_Control;
  622. }
  623. else if (tchCurrSymbol == _T(':'))
  624. {
  625. m_nTokenType = xtpEditTokType_Control;
  626. }
  627. else
  628. {
  629. m_nTokenType = xtpEditTokType_Value;
  630. }
  631. if (nFoundedToken != m_nTokenType)
  632. {
  633. m_nCurrPos--;
  634. }
  635. return nFoundedToken;
  636. }
  637. int CXTPSyntaxEditLexCfgFileReader::ProcessDelimToken(TCHAR tchCurrSymbol)
  638. {
  639. return ProcessUnknowToken(tchCurrSymbol);
  640. }
  641. int CXTPSyntaxEditLexCfgFileReader::ProcessNameToken(TCHAR tchCurrSymbol)
  642. {
  643. int nFoundedToken = m_nTokenType;
  644. if (tchCurrSymbol == _T('''))
  645. {
  646. m_nTokenType = xtpEditTokType_Quoted;
  647. }
  648. else if (tchCurrSymbol == _T('/'))
  649. {
  650. m_nTokenType = xtpEditTokType_Comment;
  651. }
  652. else if (cstrDelims.Find(tchCurrSymbol) > -1)
  653. {
  654. m_nTokenType = xtpEditTokType_Delim;
  655. }
  656. else if (cstrEOL.Find(tchCurrSymbol) > -1)
  657. {
  658. m_nTokenType = xtpEditTokType_EOL;
  659. }
  660. else if (tchCurrSymbol == _T('='))
  661. {
  662. m_nTokenType = xtpEditTokType_Control;
  663. }
  664. else if (tchCurrSymbol == _T(':'))
  665. {
  666. m_nTokenType = xtpEditTokType_Control;
  667. }
  668. if (nFoundedToken != m_nTokenType)
  669. {
  670. m_nCurrPos--;
  671. }
  672. return nFoundedToken;
  673. }
  674. int CXTPSyntaxEditLexCfgFileReader::ProcessValueToken(TCHAR tchCurrSymbol)
  675. {
  676. int nFoundedToken = m_nTokenType;
  677. if (cstrDelims.Find(tchCurrSymbol) > -1)
  678. {
  679. m_nTokenType = xtpEditTokType_Delim;
  680. }
  681. else if (cstrEOL.Find(tchCurrSymbol) > -1)
  682. {
  683. m_nTokenType = xtpEditTokType_EOL;
  684. }
  685. else if (tchCurrSymbol == _T('/'))
  686. {
  687. m_nTokenType = xtpEditTokType_Comment;
  688. }
  689. if (nFoundedToken != m_nTokenType)
  690. {
  691. m_nCurrPos--;
  692. }
  693. return nFoundedToken;
  694. }
  695. int CXTPSyntaxEditLexCfgFileReader::ProcessQuotedToken(TCHAR tchCurrSymbol)
  696. {
  697. int nFoundedToken = m_nTokenType;
  698. int nLen = m_strToken.GetLength();
  699. if (cstrEOL.Find(tchCurrSymbol) > -1)
  700. m_nTokenType = xtpEditTokType_EOL;
  701. else if (m_nCurrPos == m_nEOFPos)
  702. m_nTokenType = xtpEditTokType_Unknown;
  703. else if (nLen == 0)
  704. return nFoundedToken;
  705. else if (m_strToken.GetAt(max(0, m_strToken.GetLength() - 1)) == _T('\'))
  706. {
  707. return nFoundedToken;
  708. }
  709. else if (tchCurrSymbol == _T('''))
  710. {
  711. if (m_strToken == _T('''))
  712. {
  713. nFoundedToken = GetToken();
  714. }
  715. else
  716. {
  717. m_nTokenType = xtpEditTokType_Unknown;
  718. m_strToken += tchCurrSymbol;
  719. m_nCurrPos++;
  720. }
  721. }
  722. return nFoundedToken;
  723. }
  724. int CXTPSyntaxEditLexCfgFileReader::ProcessCommentToken(TCHAR tchCurrSymbol)
  725. {
  726. int nFoundedToken = m_nTokenType;
  727. if (cstrEOL.Find(tchCurrSymbol) > -1)
  728. {
  729. m_nTokenType = xtpEditTokType_EOL;
  730. m_nCurrPos--;
  731. }
  732. return nFoundedToken;
  733. }
  734. int CXTPSyntaxEditLexCfgFileReader::ProcessEOLToken(TCHAR tchCurrSymbol)
  735. {
  736. return ProcessUnknowToken(tchCurrSymbol);
  737. }
  738. int CXTPSyntaxEditLexCfgFileReader::ProcessControlToken(TCHAR tchCurrSymbol)
  739. {
  740. return ProcessUnknowToken(tchCurrSymbol);
  741. }
  742. CXTPSyntaxEditLexClassInfoArray& CXTPSyntaxEditLexCfgFileReader::GetLexClassInfoArray()
  743. {
  744. return m_arLexClassInfo;
  745. }
  746. BOOL CXTPSyntaxEditLexCfgFileReader::WriteCfgFile(const CString& csFileName, CXTPSyntaxEditLexClassInfoArray& arLexClassDesc)
  747. {
  748. if (!arLexClassDesc.m_bModified)
  749. return FALSE;
  750. CStringArray arBuffer;
  751. CMapPtrToBool mapSavedClass;
  752. ReadSource(csFileName, FALSE);
  753. ReadSource2(csFileName, arBuffer);
  754. try
  755. {
  756. CString csTmpFileName = csFileName + _T(".tmp");
  757. ::SetFileAttributes(csTmpFileName, FILE_ATTRIBUTE_NORMAL);
  758. ::DeleteFile(csTmpFileName);
  759. CFile file;
  760. if (!AfxOpenFile(file, csTmpFileName, CFile::modeWrite | CFile::shareExclusive | CFile::modeCreate))
  761. return FALSE;
  762. int nLastWrittenLine = 0;
  763. // (1) Update Existing and deleted Classes
  764. int nCount = (int)m_arLexClassInfo.GetSize();
  765. int i;
  766. for (i = 0; i < nCount; i++)
  767. {
  768. XTP_EDIT_LEXCLASSINFO& oldClassInfo = m_arLexClassInfo[i];
  769. XTP_EDIT_LEXCLASSINFO* pNewClassInfo = FindClassDesc(arLexClassDesc, oldClassInfo.csClassName);
  770. // class was deleted;
  771. if (!pNewClassInfo)
  772. {
  773. WriteStrings(file, arBuffer, nLastWrittenLine+1, oldClassInfo.nStartLine-1);
  774. nLastWrittenLine = oldClassInfo.nEndLine;
  775. continue;
  776. }
  777. mapSavedClass[pNewClassInfo] = TRUE;
  778. CMapPtrToBool mapSavedProps;
  779. CString csOffset(_T("t"));
  780. // (1.a) Update Existing and deleted properties
  781. int nPropsCount = (int)oldClassInfo.arPropertyDesc.GetSize();
  782. int k;
  783. for (k = 0; k < nPropsCount; k++)
  784. {
  785. XTP_EDIT_LEXPROPINFO& oldInfoProp = oldClassInfo.arPropertyDesc[k];
  786. WriteStrings(file, arBuffer, nLastWrittenLine+1, oldInfoProp.nLine-1);
  787. nLastWrittenLine = oldInfoProp.nLine;
  788. XTP_EDIT_LEXPROPINFO* pNewInfoProp = FindPropDesc(pNewClassInfo, &oldInfoProp, mapSavedProps);
  789. if (pNewInfoProp)
  790. {
  791. WriteProp(file, csOffset, oldInfoProp, *pNewInfoProp, arBuffer);
  792. mapSavedProps[pNewInfoProp] = TRUE;
  793. }
  794. }
  795. // (1.b) Insert new properties
  796. nPropsCount = (int)pNewClassInfo->arPropertyDesc.GetSize();
  797. for (k = 0; k < nPropsCount; k++)
  798. {
  799. XTP_EDIT_LEXPROPINFO& newInfoProp = pNewClassInfo->arPropertyDesc[k];
  800. bool bSaved = false;
  801. if (!mapSavedProps.Lookup((void*)&newInfoProp, bSaved) || !bSaved)
  802. {
  803. WriteProp(file, csOffset, newInfoProp);
  804. }
  805. }
  806. }
  807. //------------------------------------------------------------------------
  808. WriteStrings(file, arBuffer, nLastWrittenLine+1, m_nCurrLine);
  809. nLastWrittenLine = m_nCurrLine;
  810. //===========================================================================
  811. // (2) Insert new Classes
  812. nCount = (int)arLexClassDesc.GetSize();
  813. for (i = 0; i < nCount; i++)
  814. {
  815. XTP_EDIT_LEXCLASSINFO& newClassInfo = arLexClassDesc[i];
  816. bool bSaved = false;
  817. if (!mapSavedClass.Lookup((void*)&newClassInfo, bSaved) || !bSaved)
  818. {
  819. WriteString(file, _T(""));
  820. WriteString(file, XTP_EDIT_LEXCLASS_STARTTOKEN);
  821. // Insert properties
  822. int nPropsCount = (int)newClassInfo.arPropertyDesc.GetSize();
  823. for (int k = 0; k < nPropsCount; k++)
  824. {
  825. const XTP_EDIT_LEXPROPINFO& newInfoProp = newClassInfo.arPropertyDesc[k];
  826. CString csOffset(_T("t"));
  827. WriteProp(file, csOffset, newInfoProp);
  828. }
  829. WriteString(file, XTP_EDIT_LEXCLASS_ENDTOKEN);
  830. }
  831. }
  832. //===========================================================================
  833. file.Close();
  834. CString strFileName_prev = csFileName + _T(".old");
  835. ::SetFileAttributes(strFileName_prev, FILE_ATTRIBUTE_NORMAL);
  836. ::DeleteFile(strFileName_prev);
  837. #ifdef _DEBUG
  838. //CFile::Rename(csFileName, strFileName_prev);
  839. #endif
  840. ::SetFileAttributes(csFileName, FILE_ATTRIBUTE_NORMAL);
  841. ::DeleteFile(csFileName);
  842. CFile::Rename(csTmpFileName, csFileName);
  843. m_arLexClassInfo.RemoveAll();
  844. return TRUE;
  845. }
  846. catch(CFileException* expFile)
  847. {
  848. #ifdef _DEBUG
  849. expFile->ReportError();
  850. //ProcessFileException(expFile);
  851. #endif
  852. expFile->Delete();
  853. }
  854. m_arLexClassInfo.RemoveAll();
  855. arLexClassDesc.m_bModified = FALSE;
  856. return FALSE;
  857. }
  858. XTP_EDIT_LEXCLASSINFO* CXTPSyntaxEditLexCfgFileReader::FindClassDesc(CXTPSyntaxEditLexClassInfoArray& arInfoClass, const CString& csClassName)
  859. {
  860. if (csClassName.IsEmpty())
  861. {
  862. ASSERT(FALSE);
  863. return NULL;
  864. }
  865. for (int i = 0; i < arInfoClass.GetSize(); i++)
  866. {
  867. if (arInfoClass[i].csClassName.CompareNoCase(csClassName) == 0)
  868. {
  869. return &arInfoClass[i];
  870. }
  871. }
  872. return NULL;
  873. }
  874. XTP_EDIT_LEXPROPINFO* CXTPSyntaxEditLexCfgFileReader::FindPropDesc(XTP_EDIT_LEXCLASSINFO* pInfoClass, XTP_EDIT_LEXPROPINFO* pInfoProp, CMapPtrToBool& mapUsed)
  875. {
  876. if (!pInfoClass || !pInfoProp)
  877. {
  878. ASSERT(FALSE);
  879. return NULL;
  880. }
  881. int nPNameSize = (int)pInfoProp->arPropName.GetSize();
  882. CString strPropName_src = MakeStr(pInfoProp->arPropName, _T(":"));
  883. int nCount = (int)pInfoClass->arPropertyDesc.GetSize();
  884. for (int i = 0; i < nCount; i++)
  885. {
  886. XTP_EDIT_LEXPROPINFO* pNewInfoProp = &(*pInfoClass).arPropertyDesc[i];
  887. ASSERT(pNewInfoProp);
  888. if (pNewInfoProp && pNewInfoProp->arPropName.GetSize() == nPNameSize)
  889. {
  890. CString strPName = MakeStr(pNewInfoProp->arPropName, _T(":"));
  891. if (strPropName_src.CompareNoCase(strPName) == 0)
  892. {
  893. bool bUsed = false;
  894. if (mapUsed.Lookup(pNewInfoProp, bUsed) && bUsed)
  895. {
  896. continue;
  897. }
  898. return pNewInfoProp;
  899. }
  900. }
  901. }
  902. return NULL;
  903. }
  904. void CXTPSyntaxEditLexCfgFileReader::WriteString(CFile& file, LPCTSTR pcszString)
  905. {
  906. int nStrLen = (int)_tcslen(pcszString);
  907. #ifdef _UNICODE
  908. CByteArray arBufferMBCS;
  909. arBufferMBCS.SetSize(nStrLen*2+4);
  910. char* pTextMBCS = (char*)arBufferMBCS.GetData();
  911. int nNewLen = WideCharToMultiByte(CP_ACP, 0,
  912. pcszString, -1, pTextMBCS, nStrLen*2+1, NULL, NULL);
  913. nStrLen = nNewLen ? nNewLen-1 : 0;
  914. #else
  915. char* pTextMBCS = (char*)pcszString;
  916. #endif
  917. file.Write(pTextMBCS, nStrLen);
  918. file.Write("rn", 2);
  919. }
  920. void CXTPSyntaxEditLexCfgFileReader::WriteStrings(CFile& file, CStringArray& arBuffer, int nFrom, int nTo)
  921. {
  922. int nCount = (int)arBuffer.GetSize();
  923. if (nFrom >= nCount || nFrom > nTo)
  924. {
  925. return;
  926. }
  927. if (nTo >= nCount)
  928. {
  929. nTo = nCount-1;
  930. }
  931. for (int nLine = nFrom; nLine <= nTo; nLine++)
  932. {
  933. CString csBuffer = arBuffer[nLine];
  934. WriteString(file, csBuffer);
  935. }
  936. }
  937. void CXTPSyntaxEditLexCfgFileReader::WriteProp(CFile& file, CString& csOffset, const XTP_EDIT_LEXPROPINFO& newInfoProp)
  938. {
  939. CString csPropName = MakeStr(newInfoProp.arPropName, _T(":"));
  940. CString csPropValue = AfxMakeStrES(newInfoProp.arPropValue, _T(", "));
  941. CString csPropString = csOffset + csPropName + _T(" = ") + csPropValue;
  942. WriteString(file, csPropString);
  943. }
  944. void CXTPSyntaxEditLexCfgFileReader::WriteProp(CFile& file, CString& csOffset, const XTP_EDIT_LEXPROPINFO& oldInfoProp, const XTP_EDIT_LEXPROPINFO& newInfoProp, const CStringArray& arBuffer)
  945. {
  946. if (oldInfoProp.nLine < arBuffer.GetSize())
  947. {
  948. CString csBuffer = arBuffer[oldInfoProp.nLine];
  949. int iIndex = csBuffer.Find(_T("="));
  950. ASSERT(iIndex > 0);
  951. if (iIndex > 0)
  952. {
  953. csOffset = csBuffer.SpanIncluding(_T(" t"));
  954. CString csSep = csBuffer.Mid(iIndex+1);
  955. csSep = csSep.SpanIncluding(_T(" t"));
  956. iIndex += csSep.GetLength();
  957. CString csNewBuffer = csBuffer;
  958. DELETE_S(csNewBuffer, iIndex+1, oldInfoProp.nPropertyLen);
  959. CString csPropValue = AfxMakeStrES(newInfoProp.arPropValue, _T(", "));
  960. INSERT_S(csNewBuffer, iIndex+1, csPropValue);
  961. WriteString(file, csNewBuffer);
  962. return;
  963. }
  964. }
  965. else
  966. {
  967. ASSERT(FALSE);
  968. }
  969. WriteProp(file, csOffset, newInfoProp);
  970. }
  971. #ifdef _DEBUG
  972. void CXTPSyntaxEditLexCfgFileReader::ProcessFileException(CFileException* pExc)
  973. {
  974. CString strErrorMsg(_T(" "));
  975. switch (pExc->m_cause)
  976. {
  977. #if (_MSC_VER > 1310) // VS2005
  978. case CFileException::genericException :
  979. #else
  980. case CFileException::generic :
  981. #endif
  982. strErrorMsg = _T("An unspecified error occurred.");
  983. break;
  984. case CFileException::fileNotFound :
  985. strErrorMsg = _T("The file could not be located.");
  986. break;
  987. case CFileException::badPath :
  988. strErrorMsg = _T("All or part of the path is invalid.");
  989. break;
  990. case CFileException::tooManyOpenFiles :
  991. strErrorMsg = _T("The permitted number of open files was exceeded.");
  992. break;
  993. case CFileException::accessDenied :
  994. strErrorMsg = _T("The file could not be accessed.");
  995. break;
  996. case CFileException::invalidFile :
  997. strErrorMsg = _T("There was an attempt to use an invalid file handle.");
  998. break;
  999. case CFileException::removeCurrentDir :
  1000. strErrorMsg = _T("The current working directory cannot be removed.");
  1001. break;
  1002. case CFileException::directoryFull :
  1003. strErrorMsg = _T("There are no more directory entries.");
  1004. break;
  1005. case CFileException::badSeek :
  1006. strErrorMsg = _T("There was an error trying to set the file pointer.");
  1007. break;
  1008. case CFileException::hardIO :
  1009. strErrorMsg = _T("There was a hardware error.");
  1010. break;
  1011. case CFileException::sharingViolation :
  1012. strErrorMsg = _T("SHARE.EXE was not loaded, or a shared region was locked.");
  1013. break;
  1014. case CFileException::lockViolation :
  1015. strErrorMsg = _T("There was an attempt to lock a region that was already locked.");
  1016. break;
  1017. case CFileException::diskFull :
  1018. strErrorMsg = _T("The disk is full.");
  1019. break;
  1020. case CFileException::endOfFile :
  1021. strErrorMsg = _T("The end of file was reached.");
  1022. break;
  1023. default :
  1024. strErrorMsg = _T("Unknown error.");
  1025. }
  1026. TRACE(_T("ERROR: %s File Name: %s n"), (LPCTSTR)strErrorMsg, (LPCTSTR)pExc->m_strFileName);
  1027. }
  1028. #endif
  1029. CString CXTPSyntaxEditLexCfgFileReader::StrToES(CString strSrc, BOOL bQuoted)
  1030. {
  1031. CString strRez(strSrc);
  1032. strRez.TrimLeft(); strRez.TrimRight();
  1033. int nLen = strRez.GetLength();
  1034. if (nLen < 1)
  1035. {
  1036. return strRez;
  1037. }
  1038. if (bQuoted && strRez.GetAt(0) == _T(''') && strRez.GetAt(nLen - 1) == _T('''))
  1039. {
  1040. strRez.SetAt(0,      _T('x1'));
  1041. strRez.SetAt(nLen-1, _T('x1'));
  1042. }
  1043. REPLACE_S(strRez, _T("\\"), _T("x2"));
  1044. REPLACE_S(strRez, _T("\a"), _T("a"));
  1045. REPLACE_S(strRez, _T("\b"), _T("b"));
  1046. REPLACE_S(strRez, _T("\f"), _T("f"));
  1047. REPLACE_S(strRez, _T("\n"), _T("n"));
  1048. REPLACE_S(strRez, _T("\r"), _T("r"));
  1049. REPLACE_S(strRez, _T("\t"), _T("t"));
  1050. REPLACE_S(strRez, _T("\v"), _T("v"));
  1051. REPLACE_S(strRez, _T("\'"), _T("'"));
  1052. REPLACE_S(strRez, _T("x2"), _T("\"));
  1053. REPLACE_S(strRez, _T("x1"), _T("'"));
  1054. return strRez;
  1055. }
  1056. CString CXTPSyntaxEditLexCfgFileReader::ESToStr(CString strSrc, BOOL bQuoted)
  1057. {
  1058. CString strRez(strSrc);
  1059. strRez.TrimLeft(); strRez.TrimRight();
  1060. int nLen = strRez.GetLength();
  1061. if (nLen < 1)
  1062. {
  1063. return strRez;
  1064. }
  1065. if (bQuoted && strRez.GetAt(0) == _T(''') && strRez.GetAt(nLen - 1) == _T('''))
  1066. {
  1067. strRez.SetAt(0,      _T('x1'));
  1068. strRez.SetAt(nLen-1, _T('x1'));
  1069. }
  1070. REPLACE_S(strRez, _T("\"), _T("x2"));
  1071. REPLACE_S(strRez, _T("a"), _T("\a"));
  1072. REPLACE_S(strRez, _T("b"), _T("\b"));
  1073. REPLACE_S(strRez, _T("f"), _T("\f"));
  1074. REPLACE_S(strRez, _T("n"), _T("\n"));
  1075. REPLACE_S(strRez, _T("r"), _T("\r"));
  1076. REPLACE_S(strRez, _T("t"), _T("\t"));
  1077. REPLACE_S(strRez, _T("v"), _T("\v"));
  1078. REPLACE_S(strRez, _T("'"), _T("\'"));
  1079. REPLACE_S(strRez, _T("x2"), _T("\\"));
  1080. REPLACE_S(strRez, _T("x1"), _T("'"));
  1081. return strRez;
  1082. }
  1083. /////////////////////////////////////////////////////////////////////////////
  1084. // CXTPSyntaxEditFileChangesMonitor
  1085. //
  1086. CXTPSyntaxEditFileChangesMonitor::CXTPSyntaxEditFileChangesMonitor()
  1087. {
  1088. m_pThread = NULL;
  1089. m_evExitThread = NULL;
  1090. m_pConfigMgr = NULL;
  1091. }
  1092. CXTPSyntaxEditFileChangesMonitor::~CXTPSyntaxEditFileChangesMonitor()
  1093. {
  1094. StopMonitoring();
  1095. }
  1096. void CXTPSyntaxEditFileChangesMonitor::SetDefaultFolder(const CString& strPath)
  1097. {
  1098. m_strPath = strPath;
  1099. }
  1100. void CXTPSyntaxEditFileChangesMonitor::RemoveAll()
  1101. {
  1102. m_arFiles.RemoveAll();
  1103. }
  1104. BOOL CXTPSyntaxEditFileChangesMonitor::AddMonitorFile(CString& strFilename,
  1105.  DWORD dwOwnerFlags)
  1106. {
  1107. // try open file
  1108. BY_HANDLE_FILE_INFORMATION sysFileInfo;
  1109. BOOL bRes = GetFileInfo(strFilename, &sysFileInfo);
  1110. if (!bRes)
  1111. {
  1112. // try again in the default folder
  1113. CString strFullFilename = m_strPath + strFilename;
  1114. bRes = GetFileInfo(strFullFilename, &sysFileInfo);
  1115. if (bRes)
  1116. {
  1117. strFilename = strFullFilename;
  1118. }
  1119. }
  1120. // get complete file name
  1121. if (bRes)
  1122. {
  1123. // get the directory for the file
  1124. TCHAR szPath[_MAX_PATH];
  1125. LPTSTR lpszName;
  1126. if (::GetFullPathName(strFilename, _MAX_PATH, szPath, &lpszName))
  1127. {
  1128. strFilename = szPath;
  1129. }
  1130. }
  1131. // Prepare file info structure
  1132. CFMFileInfo fmFileInfo;
  1133. fmFileInfo.m_strFileName = strFilename;
  1134. fmFileInfo.m_bExists = bRes;
  1135. fmFileInfo.m_dwOwnerFlags = dwOwnerFlags;
  1136. if (bRes)
  1137. {
  1138. fmFileInfo.m_sysFileInfo = sysFileInfo;
  1139. }
  1140. // add file to the monitoring array
  1141. m_arFiles.Add(fmFileInfo);
  1142. return bRes;
  1143. }
  1144. void CXTPSyntaxEditFileChangesMonitor::StartMonitoring()
  1145. {
  1146. if (m_pThread)
  1147. {
  1148. ASSERT(FALSE);
  1149. return;
  1150. }
  1151. ASSERT(m_evExitThread == NULL);
  1152. m_evExitThread = CreateEvent(NULL,TRUE,FALSE,NULL);
  1153. ASSERT(m_evExitThread);
  1154. m_pThread = AfxBeginThread(ThreadMonitorProc, (LPVOID)this,
  1155. THREAD_PRIORITY_LOWEST);
  1156. //, 0, CREATE_SUSPENDED, NULL);
  1157. if (!m_pThread)
  1158. {
  1159. ASSERT(FALSE);
  1160. return;
  1161. }
  1162. }
  1163. void CXTPSyntaxEditFileChangesMonitor::StopMonitoring()
  1164. {
  1165. if (m_pThread)
  1166. {
  1167. HANDLE hThread = m_pThread->m_hThread;
  1168. ::SetEvent(m_evExitThread);
  1169. DWORD dwThreadRes = ::WaitForSingleObject(hThread, 20*1000);
  1170. if (dwThreadRes == WAIT_TIMEOUT)
  1171. {
  1172. ::TerminateThread(hThread, 0);
  1173. //ASSERT(FALSE);
  1174. TRACE(_T("ERROR! FileChangesMonitor thread was not ended by normal way. It was terminated. n"));
  1175. }
  1176. ::CloseHandle(m_evExitThread);
  1177. m_evExitThread = NULL;
  1178. m_pThread = NULL;
  1179. }
  1180. RemoveAll();
  1181. }
  1182. UINT CXTPSyntaxEditFileChangesMonitor::ThreadMonitorProc(LPVOID p)
  1183. {
  1184. try
  1185. {
  1186. CXTPSyntaxEditFileChangesMonitor* pFolderMonitor = (CXTPSyntaxEditFileChangesMonitor*)p;
  1187. if (!pFolderMonitor)
  1188. return 1;
  1189. for (;;)
  1190. {
  1191. // Wait for notification.
  1192. DWORD dwWaitStatus = WaitForSingleObject(pFolderMonitor->m_evExitThread, 3000);
  1193. if (WAIT_OBJECT_0 == dwWaitStatus)
  1194. {
  1195. ::Sleep(100);
  1196. break;
  1197. }
  1198. if (WAIT_TIMEOUT == dwWaitStatus)
  1199. {
  1200. pFolderMonitor->RefreshFiles();
  1201. }
  1202. }
  1203. }
  1204. catch(...) {
  1205. TRACE(_T("EXCEPTION in CXTPSyntaxEditFileChangesMonitor::ThreadMonitorProcn"));
  1206. }
  1207. return 0;
  1208. }
  1209. void CXTPSyntaxEditFileChangesMonitor::RefreshFiles()
  1210. {
  1211. // Iterate all stored filenames
  1212. int nCount = (int)m_arFiles.GetSize();
  1213. for (int i = 0; i < nCount; i++)
  1214. {
  1215. //CString strFilename;
  1216. CFMFileInfo& rFMFileInfo = m_arFiles.ElementAt(i);
  1217. // get new info for this file
  1218. BY_HANDLE_FILE_INFORMATION sysFileInfo;
  1219. if (GetFileInfo(rFMFileInfo.m_strFileName, &sysFileInfo) )
  1220. {
  1221. // check whether file status is changed
  1222. if (!AfxCompareTime(sysFileInfo.ftLastWriteTime,
  1223. rFMFileInfo.m_sysFileInfo.ftLastWriteTime) ||
  1224. sysFileInfo.nFileSizeLow != rFMFileInfo.m_sysFileInfo.nFileSizeLow ||
  1225. sysFileInfo.nFileSizeHigh != rFMFileInfo.m_sysFileInfo.nFileSizeHigh
  1226. || !rFMFileInfo.m_bExists)
  1227. {
  1228. int nCfgFlags = rFMFileInfo.m_bExists ? 0 : xtpEditCfgFileAdd;
  1229. rFMFileInfo.m_sysFileInfo = sysFileInfo;
  1230. rFMFileInfo.m_bExists = TRUE;
  1231. // reload this file
  1232. m_pConfigMgr->ReloadFile(rFMFileInfo.m_strFileName,
  1233. rFMFileInfo.m_dwOwnerFlags, nCfgFlags);
  1234. }
  1235. }
  1236. else
  1237. {
  1238. if (rFMFileInfo.m_bExists)
  1239. {
  1240. rFMFileInfo.m_bExists = FALSE;
  1241. // remove this file from the collection
  1242. m_pConfigMgr->ReloadFile(rFMFileInfo.m_strFileName,
  1243.  rFMFileInfo.m_dwOwnerFlags, xtpEditCfgFileRemove);
  1244. }
  1245. // try again in the default folder
  1246. CString strFullFilename = m_strPath + rFMFileInfo.m_strFileName;
  1247. if (GetFileInfo(strFullFilename, &sysFileInfo))
  1248. {
  1249. rFMFileInfo.m_strFileName = strFullFilename;
  1250. i--;
  1251. }
  1252. }
  1253. }
  1254. }
  1255. BOOL CXTPSyntaxEditFileChangesMonitor::GetFileInfo(LPCTSTR pcszFilePath,
  1256.   BY_HANDLE_FILE_INFORMATION* pInfo)
  1257. {
  1258. const DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
  1259. HANDLE hFile = ::CreateFile(pcszFilePath, GENERIC_READ, dwShareMode, NULL,
  1260.  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  1261. if (hFile == INVALID_HANDLE_VALUE)
  1262. {
  1263. return FALSE;
  1264. }
  1265. if (!pInfo)
  1266. {
  1267. return TRUE;
  1268. }
  1269. ZeroMemory(pInfo, sizeof(*pInfo));
  1270. BOOL bRes = GetFileInformationByHandle(hFile, pInfo);
  1271. CloseHandle(hFile);
  1272. return bRes;
  1273. }
  1274. ////////////////////////////////////////////////////////////////////////////
  1275. //class CFMFileInfo
  1276. CXTPSyntaxEditFileChangesMonitor::CFMFileInfo::CFMFileInfo()
  1277. {
  1278. ZeroMemory(&m_sysFileInfo, sizeof(m_sysFileInfo));
  1279. m_bExists = FALSE;
  1280. m_dwOwnerFlags = 0;
  1281. }
  1282. const CXTPSyntaxEditFileChangesMonitor::CFMFileInfo&
  1283. CXTPSyntaxEditFileChangesMonitor::CFMFileInfo::operator=(
  1284. const CXTPSyntaxEditFileChangesMonitor::CFMFileInfo& rSrc)
  1285. {
  1286. m_strFileName   = rSrc.m_strFileName;
  1287. m_sysFileInfo   = rSrc.m_sysFileInfo;
  1288. m_bExists       = rSrc.m_bExists;
  1289. m_dwOwnerFlags  = rSrc.m_dwOwnerFlags;
  1290. return *this;
  1291. }