//ParseSection.cpp #include "stdafx.h" #include "edtparse.hpp" ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : CParseSection // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// CParseSection::CParseSection (CString csFinalMDFFileName/* = ""*/) { m_csFinalMDFFileName = csFinalMDFFileName; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : ParseFile // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::ParseFile (CString csInitialMDFFileName, CString csFinalMDFFileName/* = ""*/) { //the final MDF file name can be passed in constructor or here if (!csFinalMDFFileName.IsEmpty ()) m_csFinalMDFFileName = csFinalMDFFileName; CFileStatus status; BOOL bInitialMDFFileExists = CFile::GetStatus (csInitialMDFFileName, status); if (!bInitialMDFFileExists) //the file exists { AfxMessageBox ("Error, can't open the initial MDF file"); return 0; } else //normal behavior { if (FillListOfInitialMDFSections (csInitialMDFFileName)) { CreateTheFinalMDFFile (); //copy the unchanged sections while (!m_lstOfInitialUnchangeableMDFSections.IsEmpty ()) { CString csSectionName = m_lstOfInitialUnchangeableMDFSections.RemoveHead (); CopySectionAsItIs (csInitialMDFFileName, csSectionName); } //copy the normal sections while (!m_lstOfInitialMDFSections.IsEmpty ()) { CString csSectionName = m_lstOfInitialMDFSections.RemoveHead (); CopySectionWithAnalyze (csInitialMDFFileName, csSectionName); } } else ASSERT (FALSE); } return 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : CopySection // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::CopySection (CString csFileName, CString csSectionName, BOOL bCopyAsItIs/* = FALSE*/) { //if section is already included skip it if (IsSectionIncluded (csSectionName)) return 1; if (!IsFileNameAbsolute (csFileName)) //the absolute path is computed using different roots //we assume here that the relative path fit only one root(we can't compute two or more valid paths //using the same relative path and different roots) csFileName = ComputeAbsoluteFileName (csFileName); if (csFileName.IsEmpty ()) return 0; CStringList lstSection; if (!ReadSection (csFileName, csSectionName, lstSection)) return 0; if (!bCopyAsItIs) AnalyseSection (csFileName, lstSection); WriteSection (lstSection); return 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : ReadSection // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::ReadSection (CString csFileName, CString csSectionName, CStringList &rSection) { ASSERT (!csFileName.IsEmpty ()); UINT uOpenFlags = CFile::modeRead | CFile::typeText; CStdioFile file; if (!file.Open (csFileName, uOpenFlags)) return 0; BOOL bReadOK = 0; //read every line and when you find the section copy it in the rSection CString csEntry; while (file.ReadString (csEntry)) //not eof { csEntry.TrimLeft (); csEntry.TrimRight (); if (0 < csEntry.GetLength ()) //not a blank line { //find a section BOOL bBeginOfSection = cBeginBracket == csEntry [0]; if (bBeginOfSection) { int iOpenedBracketCount = 1; //remove the bracket CString csRedSectionName = csEntry.Mid (1); csRedSectionName = RemoveParameters (csRedSectionName); BOOL bSectionMatch = csRedSectionName == csSectionName; if (bSectionMatch) { ASSERT (rSection.IsEmpty ()); rSection.AddTail (csEntry); } //read the whole section do{ file.ReadString (csEntry); if (bSectionMatch) rSection.AddTail (csEntry); csEntry.TrimLeft (); csEntry.TrimRight (); if (csEntry.IsEmpty ()) continue; //end bracket if (cEndBracket == csEntry [0]) iOpenedBracketCount--; //begin bracket if (cBeginBracket == csEntry [0]) iOpenedBracketCount++; }while (0 < iOpenedBracketCount); if (bSectionMatch) { //store this as a treated section in order not to include this the second time m_lstOfIncludedExternalReferences.AddTail (csSectionName); bReadOK = 1; break; //no need to read more } } //else go to next line } } file.Close (); if (!bReadOK) { CString csWarningMsg = "Can't find the section: " + csSectionName + " in the file: " + csFileName; AfxMessageBox (csWarningMsg); } return bReadOK; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : AnalyseSection // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::AnalyseSection (CString csFileName, CStringList &rSection) { ASSERT (!rSection.IsEmpty ()); //look for external references POSITION pos = rSection.GetHeadPosition (); while (NULL != pos) { POSITION oldPos = pos; //check every entry(line) in the section CString csEntry = rSection.GetNext (pos); int iInx = csEntry.Find (cExternalReferencesIndicator); BOOL bExternalReferences = -1 != iInx; if (bExternalReferences) // external references { //assume there is only one referenced section in the entry ASSERT (0 < iInx); //always there is something at the left int iBeginStringInx = csEntry.Find (cStringDelimitator); ASSERT (-1 != iBeginStringInx); //copy the keyword CString csEntryStartPart = csEntry.Left (iBeginStringInx);//don't include the delimitator CString csTextToAnalyze = csEntry.Mid (iBeginStringInx); while (!csTextToAnalyze.IsEmpty ()) { int iFirstDelimitInx = csTextToAnalyze.Find (cStringDelimitator); BOOL bStringLeftForAnalyze = -1 != iFirstDelimitInx; if (!bStringLeftForAnalyze) { csEntryStartPart += csTextToAnalyze; break; //that's it } CString csLeftTrail = csTextToAnalyze.Left (iFirstDelimitInx + 1); //include the delimitator csTextToAnalyze = csTextToAnalyze.Mid (iFirstDelimitInx + 1); int iSubstringInx = csTextToAnalyze.Find (cStringDelimitator); ASSERT (-1 != iSubstringInx); //get the pair " CString csSubstring = csTextToAnalyze.Left (iSubstringInx); //don't include the delimitator //but keep count of it csTextToAnalyze = csTextToAnalyze.Mid (iSubstringInx + 1); //get the right part, that will be analyzed next time int iSplitInx = csSubstring.Find (cExternalReferencesIndicator); BOOL bExternalReferencesFound = -1 != iSplitInx; if (!bExternalReferencesFound) { csEntryStartPart += csLeftTrail + csSubstring + cStringDelimitator; continue; } //if ext reference found CString csSectionsFileName = csSubstring.Left (iSplitInx); BOOL bReferenceInThisFile = cThisFileReference == csSectionsFileName; if (bReferenceInThisFile) csSectionsFileName = csFileName; CString csSectionName = csSubstring.Mid (iSplitInx + 1); if (!IsSectionIncluded (csSectionName)) CopySectionWithAnalyze (csSectionsFileName, csSectionName); //recompute the entry and replace the file name by * CString csFullSectionName; if (bReferenceInThisFile) { csFullSectionName = csLeftTrail + csSubstring + cStringDelimitator; } else { csFullSectionName = csLeftTrail + cThisFileReference + cExternalReferencesIndicator + csSectionName + cStringDelimitator; } csEntryStartPart += csFullSectionName; } rSection.SetAt (oldPos, csEntryStartPart); } } return 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : WriteSection // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::WriteSection (CStringList &rSection) { ASSERT (!rSection.IsEmpty ()); ASSERT (!m_csFinalMDFFileName.IsEmpty ()); CStdioFile file; //assume the file exists UINT uOpenFlags = CFile::modeWrite | CFile::typeText; if (!file.Open (m_csFinalMDFFileName, uOpenFlags)) return 0; file.SeekToEnd (); while (!rSection.IsEmpty ()) { CString csEntry = rSection.RemoveHead (); if (!csEntry.IsEmpty()) { BOOL bOrdinaryEntryInSection = cBeginBracket != csEntry [0] || cEndBracket != csEntry [0]; if (bOrdinaryEntryInSection) csEntry = "\t" + csEntry + "\n"; else //begin and end section csEntry = csEntry + "\n"; file.WriteString (csEntry); } } file.WriteString ("\n\n"); file.Close (); return 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : FillListOfInitialMDFSections // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::FillListOfInitialMDFSections (CString csInitialMDFFileName) { ASSERT (!csInitialMDFFileName.IsEmpty ()); UINT uOpenFlags = CFile::modeRead | CFile::typeText; CStdioFile file; if (!file.Open (csInitialMDFFileName, uOpenFlags)) return 0; //empty the lists before a new fill m_lstOfInitialUnchangeableMDFSections.RemoveAll (); m_lstOfInitialMDFSections.RemoveAll (); //read every line and when you find the section copy it in the rSection CString csEntry; while (file.ReadString (csEntry)) //not eof { csEntry.TrimLeft (); if (0 < csEntry.GetLength ()) //not a blank line { //find a section BOOL bBeginOfSection = cBeginBracket == csEntry [0]; if (bBeginOfSection) { int iOpenedBracketCount = 1; //remove the bracket CString csRedSectionName = csEntry.Mid (1); csRedSectionName.TrimLeft (); csRedSectionName.TrimRight (); //read the whole section do{ file.ReadString (csEntry); csEntry.TrimLeft (); //end bracket if (cEndBracket == csEntry [0]) iOpenedBracketCount--; //begin bracket if (cBeginBracket == csEntry [0]) iOpenedBracketCount++; }while (0 < iOpenedBracketCount); //exceptions at the rule if (szEditModificationsKW == csRedSectionName) { m_lstOfInitialUnchangeableMDFSections.AddTail (csRedSectionName); continue; } m_lstOfInitialMDFSections.AddTail (csRedSectionName); } //else ignore it } //else go to next line } file.Close (); return 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : CreateTheFinalMDFFile // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::CreateTheFinalMDFFile () { ASSERT (!m_csFinalMDFFileName.IsEmpty ()); CStdioFile file; //assume the file exists UINT uOpenFlags = CFile::modeCreate | CFile::modeWrite | CFile::typeText; if (!file.Open (m_csFinalMDFFileName, uOpenFlags)) return 0; CString csMDFHeader (";MDF file\n\n"); file.WriteString (csMDFHeader); file.Close (); return 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : IsSectionIncluded // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::IsSectionIncluded (CString csSectionName) { POSITION pos = m_lstOfIncludedExternalReferences.GetHeadPosition (); while (NULL != pos) { CString csExternSectionName = m_lstOfIncludedExternalReferences.GetNext (pos); if (csSectionName == csExternSectionName) return 1; } return 0; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : ComputeAbsoluteFileName // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// CString CParseSection::ComputeAbsoluteFileName (CString csFileName) { ASSERT (!IsFileNameAbsolute (csFileName)); if (cBackslash == csFileName [0]) csFileName = csFileName.Mid (1); //remove the useless backslash //assume we can compute only one absolute path POSITION pos = m_lstOfRoots.GetHeadPosition (); while (NULL != pos) { CString csRoot = m_lstOfRoots.GetNext (pos); //assume the root ends with a backslash CString csFilePath = csRoot + csFileName; CFileStatus status; if (CFile::GetStatus (csFilePath, status)) //verify if the file exists return csFilePath; } ASSERT (FALSE); return ""; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : IsFileNameAbsolute // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// int CParseSection::IsFileNameAbsolute (CString csFileName) { csFileName.TrimLeft (); //make sure there are no pending blanks if (':' == csFileName [1]) //the path contains a drive { #ifdef _DEBUG CFileStatus status; ASSERT (CFile::GetStatus (csFileName, status)); //the file exists #endif //_DEBUG return 1; } return 0; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : RemoveParameters // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// CString CParseSection::RemoveParameters (CString csRedSectionName) { csRedSectionName.TrimLeft (); csRedSectionName.TrimRight (); int iInx = csRedSectionName.Find (cParameterBeginIndicator); BOOL bHasParameters = -1 != iInx; if (bHasParameters) csRedSectionName = csRedSectionName.Left (iInx); return csRedSectionName; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Method : AddRoot // Date : 98-03 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Author : Stegaru Cristian - CPA2 ////////////////////////////////////////////////////////////////////////////////////////////////////// // Modification : // Date : // By : ////////////////////////////////////////////////////////////////////////////////////////////////////// void CParseSection::AddRoot (CString csRoot) { csRoot.TrimRight (); //the roots have to end with a backslash if (cBackslash != csRoot [csRoot.GetLength () - 1]) csRoot += cBackslash; m_lstOfRoots.AddTail (csRoot); }