559 lines
18 KiB
C++
559 lines
18 KiB
C++
//ParseSection.cpp
|
|
|
|
#include "stdafx.h"
|
|
#include "ParseSection.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);
|
|
}
|
|
|
|
|