reman3/Rayman_X/cpa/tempgrp/Edt/src/parsesection.cpp

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);
}