reman3/Rayman_X/cpa/tempgrp/SCR/SCR_Anl.c

1734 lines
58 KiB
C

/*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
* SCR_Anl.c
* To analyse a section.
*
* Scripts, Beaudet Christophe
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*
*=================================================================================================
* Includes.
*=================================================================================================
*/
#include <memory.h>
#include "SCR.h"
/*
*=================================================================================================
* Global variables.
*=================================================================================================
*/
/*
* Array of all callbacks.
*/
SCR_tdst_DyAr_Description SCR_g_st_Anl_ArrayCallbacks;
/*
* For parser. To treat return values of callbacks.
*/
int g_iExitBeforeLevel = -1;
/*
*=================================================================================================
* Functions.
*=================================================================================================
*/
/*
*-------------------------------------------------------------------------------------------------
* Init.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_InitModule(void)
{
fn_v_DyAr_InitArray(&SCR_g_st_Anl_ArrayCallbacks);
}
/*
*-------------------------------------------------------------------------------------------------
* Close.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_CloseModule(void)
{
SCR_M_DyAr_DeleteAllElements(SCR_tdst_Anl_Callback, &SCR_g_st_Anl_ArrayCallbacks, ;);
}
/*===============================================================================================*/
/*
*-------------------------------------------------------------------------------------------------
* To add a callback for a file or a section.
* _p_szSectionName : Name of section or file.
* _pfn_eCallback : Address of function callback.
* _cForSection : 0 - It's a file callback.
* 1 - It's a section callback.
* Returns address of allocated structure.
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Anl_Callback *fnp_st_Anl_AddCallback
(
char *_p_szSectionName,
SCR_tdpfn_Anl_Callback _pfn_eCallback,
char _cForSection
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPos;
SCR_tdst_Anl_Callback *p_stCallback;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_P(_p_szSectionName != NULL);
SCR_M_Dbg_Assert_P(_pfn_eCallback != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Add element.
*/
SCR_M_DyAr_AddElement(SCR_tdst_Anl_Callback, uiPos, p_stCallback, SCR_g_st_Anl_ArrayCallbacks);
/*
* Initialize structure.
*/
strcpy(p_stCallback->a_szSectionName, _p_szSectionName);
p_stCallback->pfn_eCallback = _pfn_eCallback;
p_stCallback->cForSection = _cForSection;
/* Return structure */
return p_stCallback;
}
/*
*-------------------------------------------------------------------------------------------------
* To delete a callback.
* _p_szCallback : Callback to delete.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_DeleteCallback(SCR_tdst_Anl_Callback *_p_stCallback)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Anl_Callback, _p_stCallback);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_DyAr_DeleteElement
(
SCR_tdst_Anl_Callback,
_p_stCallback->stHeader.uiIndexInArray,
&SCR_g_st_Anl_ArrayCallbacks,
;
);
}
/*
*-------------------------------------------------------------------------------------------------
* To search a callback.
* _p_szSectionName : Name of section.
* _cForSection : 0 - It's a file callback.
* 1 - It's a section callback.
* Returns address of allocated structure.
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Anl_Callback *fnp_st_Anl_SearchCallback
(
char *_p_szSectionName,
char _cForSection
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPos;
SCR_tdst_Anl_Callback *p_stPointer = NULL;
char *p_szTemp;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_P(_p_szSectionName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_DyAr_SearchElement
(
SCR_tdst_Anl_Callback,
uiPos,
p_stPointer,
SCR_g_st_Anl_ArrayCallbacks,
(
(!strcmpi(p_stPointer->a_szSectionName, _p_szSectionName))
&& (p_stPointer->cForSection == _cForSection)
)
);
/*
* If we have not found the callback, and if it's for a file, we search a
* callback associated to the file extension (if one).
*/
if((p_stPointer == NULL) && (_cForSection == 0))
{
p_szTemp = strrchr(_p_szSectionName, '.');
if(p_szTemp)
{
SCR_M_DyAr_SearchElement
(
SCR_tdst_Anl_Callback,
uiPos,
p_stPointer,
SCR_g_st_Anl_ArrayCallbacks,
(
(!strcmpi(p_stPointer->a_szSectionName, p_szTemp))
&& (p_stPointer->cForSection == _cForSection)
)
);
}
}
return p_stPointer;
}
/*===============================================================================================*/
/*
*-------------------------------------------------------------------------------------------------
* To add a new section in list. Section description must be in current context.
* _p_stContext : Current context.
* _p_stParentSection : Address of parent section description (can be NULL).
* Returns address of allocated structure.
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Anl_SectionDes *fnp_st_Anl_AddSectionDes
(
SCR_tdst_Cxt_Description *_p_stContext,
SCR_tdst_Anl_SectionDes *_p_stParentSection
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPos;
SCR_tdst_Anl_SectionDes *p_stSection;
SCR_tdx_Hash_Key xHashKey;
unsigned int uiIndexOfHashValue;
unsigned char ucMemoLevel;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Force memory level to be equal to file one.
*/
ucMemoLevel = g_uc_Mem_CurrentMemLevel;
g_uc_Mem_CurrentMemLevel = _p_stContext->p_stOpenFile->stHeader.ucMemLevel;
/*
* Add element in dynamic array.
*/
SCR_M_DyAr_AddElement
(
SCR_tdst_Anl_SectionDes,
uiPos,
p_stSection,
_p_stContext->p_stOpenFile->stSectionsDes
);
/*
* Compute hash key of section complete name.
* Add the section description in the hash table.
*/
SCR_M_Sect_ComputeHashKey
(
xHashKey,
_p_stContext->stBuffers.a_szBufferCompleteName
);
fnp_st_Hash_AddValue
(
xHashKey,
_p_stContext->p_stOpenFile->a_stHashSectionsDes,
(unsigned long) p_stSection,
&uiIndexOfHashValue
);
/*
* Initialize structure.
*/
fn_v_Mem_SetMode(p_stSection->stHeader.ucMemLevel);
SCR_M_Cxt_CopyBuffersToDyn(&p_stSection->stBuffers, &_p_stContext->stBuffers);
memcpy(&p_stSection->stBeginPosition, &_p_stContext->stPosition, sizeof(SCR_tdst_Cxt_Position));
memset(&p_stSection->stEndPosition, 0, sizeof(SCR_tdst_Cxt_Position));
p_stSection->uwDynamicFlags = _p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags;
p_stSection->p_stParentSection = _p_stParentSection;
p_stSection->uiIndexOfHashValue = uiIndexOfHashValue;
p_stSection->p_stOpenSection = NULL;
/*
* Restore memory level.
*/
g_uc_Mem_CurrentMemLevel = ucMemoLevel;
return p_stSection;
}
/*
*-------------------------------------------------------------------------------------------------
* To search a section description in list.
* _p_stOpenFile : File to search the section description.
* _p_szSectionName : Name of section to add.
* _Line : Line to search (0 to ignore)
* Returns address of allocated structure.
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Anl_SectionDes *fnp_st_Anl_SearchSectionDes
(
SCR_tdst_File_Open *_p_stOpenFile,
char *_p_szSectionName,
unsigned int _uiLineInFile,
unsigned int _uiNum
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPos;
SCR_tdst_Hash_Value *p_stPointer = NULL;
SCR_tdx_Hash_Key xHashKey;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stOpenFile);
SCR_M_Dbg_Assert_P(_p_szSectionName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Compute hash key of section complete name.
*/
SCR_M_Sect_ComputeHashKey
(
xHashKey,
_p_szSectionName
);
/*
* We search the section in a_stHashSectionDes.
*/
SCR_M_DyAr_SearchElement
(
SCR_tdst_Hash_Value,
uiPos,
p_stPointer,
_p_stOpenFile->a_stHashSectionsDes[xHashKey],
(
(!strcmpi(((SCR_tdst_Anl_SectionDes *) (p_stPointer->ulValue))->stBuffers.p_szBufferCompleteName, _p_szSectionName))
&& (
(_uiLineInFile == 0)
|| (((SCR_tdst_Anl_SectionDes *) (p_stPointer->ulValue))->stBeginPosition.uiLineInFile == _uiLineInFile)
)
&& (!_uiNum || !_uiNum--)
)
);
/*
* Return address of structure.
*/
if(p_stPointer)
return (SCR_tdst_Anl_SectionDes *) p_stPointer->ulValue;
else
return NULL;
}
/*===============================================================================================*/
/*
*-------------------------------------------------------------------------------------------------
* We analyse a dynamic directive.
* _p_stContext : Current context.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_AnalyseDynamicDirective(SCR_tdst_Cxt_Description *_p_stContext)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
char *p_szDirective;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
p_szDirective = _p_stContext->stBuffers.a_szBufferName;
/*
* SCR_CD_sz_Cfg_BreakPoint. Only in debug mode.
*/
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_BreakPoint))
{
#if defined(_DEBUG) && !defined(SCR_DM_ProtectedVersion)
/*
* USER BREAKPOINT.
* A directive has been found in file.
*/
SCR_M_Dbg_BreakForDebug();
#else if defined(SCR_DM_ProtectedVersion)
printf("User breakpoint detected\n");
#endif /* _DEBUG */
}
/*
* SCR_CD_sz_Cfg_UpdateLog
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_UpdateLog))
{
sprintf
(
g_st_Err_GlobalError.a_szBufferTmp1,
"User update log in file \"%s\" at line \"%d\".\n",
_p_stContext->p_stOpenFile->stFile.a_szFileName,
_p_stContext->stPosition.uiLineInFile
);
sprintf
(
g_st_Err_GlobalError.a_szBufferTmp2,
"Section is \"%s\".",
_p_stContext->stBuffersCopy.a_szBufferCompleteName
);
strcpy(g_st_Err_GlobalError.a_szBufferOut, g_st_Err_GlobalError.a_szBufferTmp1);
strcat(g_st_Err_GlobalError.a_szBufferOut, g_st_Err_GlobalError.a_szBufferTmp2);
fn_v_Err_UpdateLogFile();
}
}
/*
*-------------------------------------------------------------------------------------------------
* Parser has found a directive in file.
* We analyse it and we update the stDirectives structure of current parsing infos in file.
* _p_stContext : Current context.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_AnalyseDirective(SCR_tdst_Cxt_Description *_p_stContext)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
char *p_szDirective;
char *ap_szParameters[SCR_CV_ui_Cfg_MaxNumPars];
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
p_szDirective = _p_stContext->stBuffers.a_szBufferName;
/*
* Test all directives.
*/
/*
* Dynamic directives that must be ignored.
*/
if
(
(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_BreakPoint))
|| (!strcmpi(p_szDirective, SCR_CD_sz_Cfg_UpdateLog))
)
{
}
/*
* SCR_CD_sz_Cfg_Comments.
* All next sections will never not be treated.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_Comments))
{
if(_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_Comments)
{
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", p_szDirective);
SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
}
else
_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags |= SCR_CDF_uw_Anl_Comments;
}
/*
* SCR_CD_sz_Cfg_EndComments.
* End of previous mode.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_EndComments))
{
if((_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_Comments) == 0)
{
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", p_szDirective);
SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
}
else
_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags &= ~SCR_CDF_uw_Anl_Comments;
}
/*
* SCR_CD_sz_Cfg_ForceAnalyse.
* All next sections will be analyse even if it was already done.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_ForceAnalyse))
{
if(_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_ForceAnalyse)
{
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", p_szDirective);
SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
}
else
_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags |= SCR_CDF_uw_Anl_ForceAnalyse;
}
/*
* SCR_CD_sz_Cfg_EndForceAnalyse.
* End of previous mode.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_EndForceAnalyse))
{
if((_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_ForceAnalyse) == 0)
{
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", p_szDirective);
SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
}
else
_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags &= ~SCR_CDF_uw_Anl_ForceAnalyse;
}
/*
* SCR_CD_sz_Cfg_NotSaveSection.
* All next sections will not be saved.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_NotSaveSection))
{
if(_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_NotSaveSection)
{
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", p_szDirective);
SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
}
else
_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags |= SCR_CDF_uw_Anl_NotSaveSection;
}
/*
* SCR_CD_sz_Cfg_EndNotSaveSection.
* End of previous mode.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_EndNotSaveSection))
{
if((_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_NotSaveSection) == 0)
{
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", p_szDirective);
SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
}
else
_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags &= ~SCR_CDF_uw_Anl_NotSaveSection;
}
/*
* SCR_CD_sz_Cfg_SetFileLong.
* To initialize a long file value of a relative context.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_SetCurrentFileLong))
{
fn_v_Pars_ConvertNormalParameters(_p_stContext->stBuffers.a_szBufferParams, ap_szParameters);
SCR_M_Dbg_Assert_D(SCR_fn_uc_RdL0_GetNumberOfParameters(ap_szParameters) == 2);
SCR_M_RdL0_SetFileLong(0, atol(ap_szParameters[0]), atol(ap_szParameters[1]));
SCR_M_Pars_FreeParameters(ap_szParameters);
}
/*
* SCR_CD_sz_Cfg_SetFileDouble.
* To initialize a double file value of a relative context.
*/
else
if(!strcmpi(p_szDirective, SCR_CD_sz_Cfg_SetCurrentFileDouble))
{
fn_v_Pars_ConvertNormalParameters(_p_stContext->stBuffers.a_szBufferParams, ap_szParameters);
SCR_M_Dbg_Assert_D(SCR_fn_uc_RdL0_GetNumberOfParameters(ap_szParameters) == 2);
SCR_M_RdL0_SetFileDouble(0, atol(ap_szParameters[0]), atof(ap_szParameters[1]));
SCR_M_Pars_FreeParameters(ap_szParameters);
}
/*
* Else unknown directive : Error.
*/
else
{
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Unknown directive is \"%s\".", p_szDirective);
SCR_M_Err_RaiseError(SCR_EI_Err_UnknownDirective);
}
}
/*
*-------------------------------------------------------------------------------------------------
* Update the a_szBufferCompleteName of current context.
* _p_stContext : Current context.
* Returns address of parent section (NULL if not).
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Anl_SectionDes *fnp_st_Anl_ComputeCompleteName
(
SCR_tdst_Cxt_Description *_p_stContext,
char _cUpdateParser
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Anl_SectionDes *p_stSection = NULL;
unsigned int uiSectionPos;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* If current level is 1, it's a main section without parent.
* Parent section returns is NULL.
* We add the file name before the section one.
* We add the id section name after it.
*/
if(_p_stContext->stPosition.uiLevel == 1)
{
strcpy(_p_stContext->stBuffers.a_szBufferCompleteName, _p_stContext->p_stOpenFile->stFile.a_szFileName);
p_stSection = NULL;
}
else
{
/*
* Else current section has a parent. We must found it and compute the complete section
* name of the current one.
*
* If we have not yet parsed this section :
* We began with the last section in array of sections.
*
* If we have already parsed this section :
* We are analysed it, so stBuffersCopy of current context contains the parent
* section name.
*/
if(_cUpdateParser)
{
uiSectionPos = _p_stContext->p_stOpenFile->stSectionsDes.uiNumValues;
do
{
uiSectionPos--;
SCR_M_DyAr_GetElement
(
SCR_tdst_Anl_SectionDes,
uiSectionPos,
p_stSection,
_p_stContext->p_stOpenFile->stSectionsDes
);
} while
(
(uiSectionPos)
&& (p_stSection->stBeginPosition.uiLevel >= _p_stContext->stPosition.uiLevel)
);
SCR_M_Dbg_Assert_P(p_stSection->stBeginPosition.uiLevel < _p_stContext->stPosition.uiLevel);
/* Parent complete section name is in section description found */
strcpy(_p_stContext->stBuffers.a_szBufferCompleteName, p_stSection->stBuffers.p_szBufferCompleteName);
}
else
{
/* Parent complete section name is in buffer copy of actual context */
strcpy(_p_stContext->stBuffers.a_szBufferCompleteName, _p_stContext->stBuffersCopy.a_szBufferCompleteName);
}
}
/*
* We add the separator, the actual section action name and the actual section id name.
*/
strcat(_p_stContext->stBuffers.a_szBufferCompleteName, SCR_CC_sz_Cfg_NameSeparator);
strcat(_p_stContext->stBuffers.a_szBufferCompleteName, _p_stContext->stBuffers.a_szBufferName);
if(*_p_stContext->stBuffers.a_szBufferNameExt)
{
strcat(_p_stContext->stBuffers.a_szBufferCompleteName, SCR_CC_sz_Cfg_SectionIdMark);
strcat(_p_stContext->stBuffers.a_szBufferCompleteName, _p_stContext->stBuffers.a_szBufferNameExt);
}
return p_stSection;
}
/*
*-------------------------------------------------------------------------------------------------
* To compute the seek just after a EndSection marker.
* Update p_stSectionDes in current context.
* _p_stContext : Current context.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_ComputeSeekEnd(SCR_tdst_Cxt_Description *_p_stContext)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Anl_SectionDes *p_stSection;
unsigned int uiSectionPos;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Anl_SectionDes, _p_stContext->p_stSectionDes);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Search the first section with the same level than the current one.
*/
/*MP: BINARY*/
if( _p_stContext->p_stSectionDes == NULL )
return;
uiSectionPos = _p_stContext->p_stSectionDes->stHeader.uiIndexInArray + 1;
do
{
uiSectionPos--;
SCR_M_DyAr_GetElement
(
SCR_tdst_Anl_SectionDes,
uiSectionPos,
p_stSection,
_p_stContext->p_stOpenFile->stSectionsDes
);
} while
(
(uiSectionPos)
&& (p_stSection->stBeginPosition.uiLevel != _p_stContext->stPosition.uiLevel)
);
SCR_M_Dbg_Assert_P(p_stSection->stBeginPosition.uiLevel == _p_stContext->stPosition.uiLevel);
/*
* Update lSeekEndSection of current section.
* Update uiCurrentSectionDescription of current context.
*/
memcpy(&p_stSection->stEndPosition, &_p_stContext->stPosition, sizeof(SCR_tdst_Cxt_Position));
_p_stContext->p_stSectionDes = p_stSection;
}
/*
*-------------------------------------------------------------------------------------------------
* Update parsing infos of current file.
* _p_stContext : Current context.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_UpdateInfos(SCR_tdst_Cxt_Description *_p_stContext)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Anl_SectionDes *p_stParentSection;
char cUpdateParser = 0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if( _p_stContext->eParseType== SCR_EPT_Cxt_Directive )
{
/*
* It's a directive.
* We analyse it and update stParsingInfos.stDirectives.
*/
if( _p_stContext->p_stOpenFile->stFile.bBinaryMode )
_p_stContext->stPosition.lAfterSeekInFile+=fn_l_Bin_AnalyseDirective(_p_stContext);
else
fn_v_Anl_AnalyseDirective(_p_stContext);
}
/*
* cUpdateParser is set to 0 if it's the first time we parsed that line.
* Else cUpdateParser is set to 0.
*/
if(_p_stContext->stPosition.uiLineInFile > _p_stContext->p_stOpenFile->stParsingInfos.stPosition.uiLineInFile)
{
cUpdateParser = 1;
if
(
(_p_stContext->p_stOpenFile->stSectionsDes.uiNumValues)
&& (_p_stContext->cForSection&~2)
)
{
SCR_M_DyAr_GetElement
(
SCR_tdst_Anl_SectionDes,
_p_stContext->p_stOpenFile->stSectionsDes.uiNumValues - 1,
_p_stContext->p_stSectionDes,
_p_stContext->p_stOpenFile->stSectionsDes
);
}
}
/*
* Position of parser is the one of context.
*/
if(cUpdateParser)
{
memcpy
(
&_p_stContext->p_stOpenFile->stParsingInfos.stPosition,
&_p_stContext->stPosition,
sizeof(SCR_tdst_Cxt_Position)
);
}
switch(_p_stContext->eParseType)
{
/*
* Is this an entry or a blank line ?
*/
case SCR_EPT_Cxt_Entry:
case SCR_EPT_Cxt_None:
break;
/*
* Is this a section name ?
* We update the current level.
* We compute its complete section name.
* We add this section to the array for file.
*/
case SCR_EPT_Cxt_BeginSection:
/* We update level of current context and of infos */
if(cUpdateParser)
_p_stContext->p_stOpenFile->stParsingInfos.stPosition.uiLevel++;
_p_stContext->stPosition.uiLevel++;
/* We compute complete section name */
p_stParentSection = fnp_st_Anl_ComputeCompleteName(_p_stContext, cUpdateParser);
/* We add the section to the array for the file and we update p_stSectionDes */
if(cUpdateParser)
{
_p_stContext->p_stSectionDes = fnp_st_Anl_AddSectionDes
(
_p_stContext,
p_stParentSection
);
}
/* We simply update p_stSectionDes */
else
{
_p_stContext->p_stSectionDes = fnp_st_Anl_SearchSectionDes
(
_p_stContext->p_stOpenFile,
_p_stContext->stBuffers.a_szBufferCompleteName,
_p_stContext->stPosition.uiLineInFile,
0
);
}
break;
/*
* Is this a end of section ?
* Update lSeekEndSection of corresponding section.
* Update current parsing level.
*/
case SCR_EPT_Cxt_EndSection:
/* End section without begin one */
if(_p_stContext->stPosition.uiLevel == 0)
{
SCR_M_Err_UpdateSyntaxError();
SCR_M_Err_RaiseError(SCR_EI_Err_EndSectionAlone);
}
if(cUpdateParser)
{
/* Compute seek end */
fn_v_Anl_ComputeSeekEnd(_p_stContext);
/* Update current level of parser */
_p_stContext->p_stOpenFile->stParsingInfos.stPosition.uiLevel--;
}
_p_stContext->stPosition.uiLevel--;
break;
}
}
/*
*-------------------------------------------------------------------------------------------------
* To parse a line to current context.
* _p_stContext : Current context.
*-------------------------------------------------------------------------------------------------
*/
int fn_i_Anl_LineToContext(SCR_tdst_Cxt_Description *_p_stContext)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int iRead;
unsigned int uiNbRead;
int iCpt;
char a_szTempBuffer[SCR_CV_ui_Cfg_MaxLenLine + 1];
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Parse one line of file.
*/
_p_stContext->stBuffers.a_szBufferCompleteName[0] = 0;
_p_stContext->stPosition.uiLineInFile++;
/* MP - BINARY mode START */
if( _p_stContext->p_stOpenFile->stFile.bBinaryMode )
{
short sLineLength;
fn_v_Bin_Line(
&_p_stContext->p_stOpenFile->stFile,
_p_stContext->stBuffers.a_szBufferName,
_p_stContext->stBuffers.a_szBufferNameExt,
_p_stContext->stBuffers.a_szBufferFormat,
_p_stContext->stBuffers.a_szBufferParams,
&_p_stContext->eParseType,
&uiNbRead
);
iRead='a'; /* for convenience...*/
if( _p_stContext->eParseType==SCR_EPT_Cxt_None )
{
char tmp[100];
sLineLength=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile ); /* get line length */
if( sLineLength==0 )
iRead=EOF;
else
iRead='0';
/* temp */
fn_v_Bin_Read( &_p_stContext->p_stOpenFile->stFile, sLineLength, (void *)tmp );
uiNbRead+=sLineLength+2;
}
}
else
/* MP - BINARY mode END */
/*
* If current parsing directive is ignore, we swap the line like a comment
* (except if it is the $EndComments directive).
*/
if(_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_Comments)
{
/*
* Get the current line.
*/
iCpt = 0;
SCR_g_ui_Pars_NbRead = 0;
SCR_M_Pars_GetNextNonSpaceChar(&_p_stContext->p_stOpenFile->stFile, iRead);
while((iRead != '\n') && (iRead != EOF))
{
if(!SCR_M_Pars_IsSpace(iRead))
a_szTempBuffer[iCpt++] = (char) iRead;
SCR_M_Pars_ReadChar(&_p_stContext->p_stOpenFile->stFile, iRead);
}
a_szTempBuffer[iCpt] = '\0';
uiNbRead = SCR_g_ui_Pars_NbRead;
/*
* Test for end of comment directive.
*/
if
(
(*a_szTempBuffer != SCR_CC_c_Cfg_DirectiveMark)
|| (strcmpi(a_szTempBuffer + 1, SCR_CD_sz_Cfg_EndComments))
)
{
_p_stContext->eParseType = SCR_EPT_Cxt_None;
_p_stContext->stBuffers.a_szBufferName[0] = '\0';
}
else
_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags &= ~SCR_CDF_uw_Anl_Comments;
}
else
{
iRead = (char) fn_i_Pars_Line
(
&_p_stContext->p_stOpenFile->stFile,
_p_stContext->stBuffers.a_szBufferName,
_p_stContext->stBuffers.a_szBufferNameExt,
_p_stContext->stBuffers.a_szBufferFormat,
_p_stContext->stBuffers.a_szBufferParams,
&_p_stContext->eParseType,
&uiNbRead
);
}
/*
* Update seek after reading.
*/
_p_stContext->stPosition.lAfterSeekInFile += uiNbRead;
/*
* Update parsing infos.
*/
fn_v_Anl_UpdateInfos(_p_stContext);
/* Return last character read */
return iRead;
}
/*===============================================================================================*/
/*
*-------------------------------------------------------------------------------------------------
* Initialize the current context with the section title of _p_szSectionName.
* _p_stContext : Current context.
* _p_szSectionName : Name of section.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_ContextToSection(SCR_tdst_Cxt_Description *_p_stContext, char *_p_szSectionName)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Anl_SectionDes *p_stSection;
char iRead;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
SCR_M_Dbg_Assert_P(_p_szSectionName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* We search the section in the array. The first section with the good name
* is took !
*/
_p_stContext->cForSection = 1;
if( _p_stContext->p_stOpenFile->stFile.bBinaryMode ) /* MP: BINARY */
_p_stContext->cForSection = 3;
p_stSection = fnp_st_Anl_SearchSectionDes(_p_stContext->p_stOpenFile, _p_szSectionName, 0, 0);
if(p_stSection)
{
/* Update position of context and file */
SCR_M_Anl_CxtFileToPos
(
_p_stContext,
p_stSection->stBeginPosition
);
/* Update buffers */
SCR_M_Cxt_CopyDynToBuffers(&_p_stContext->stBuffers, &p_stSection->stBuffers);
/* Update other fields */
_p_stContext->p_stSectionDes = p_stSection;
return;
}
/*
* Parser has not yet reached the section. We must parse to it.
* => Current context position is parsing infos of current file.
* => Parse file
*/
SCR_M_Anl_CxtFileToPos
(
_p_stContext,
_p_stContext->p_stOpenFile->stParsingInfos.stPosition
);
do
{
/* Read one line of file */
iRead = (char) fn_i_Anl_LineToContext(_p_stContext);
if(iRead == (char) EOF)
break;
/* If current line is a section, we test its complete name */
if(_p_stContext->eParseType == SCR_EPT_Cxt_BeginSection)
{
p_stSection = _p_stContext->p_stSectionDes;
if(!strcmpi(p_stSection->stBuffers.p_szBufferCompleteName, _p_szSectionName))
return;
else if( _p_stContext->p_stOpenFile->stFile.bBinaryMode ) /* MP: BINARY */
{
long l=fn_l_Bin_ToEndSection( _p_stContext );
_p_stContext->stPosition.lAfterSeekInFile+=l;
_p_stContext->p_stOpenFile->stFile.lToEndSection=0;
}
}
} while(iRead != (char) EOF);
/*
* We have reached the end of file : Unknown section.
*/
SCR_M_Err_UpdateSyntaxError();
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Unknown section is \"%s\".", _p_szSectionName);
SCR_M_Err_RaiseError(SCR_EI_Err_UnknownSection);
}
/*
*-------------------------------------------------------------------------------------------------
* Place the current context to the end of the current section.
* _p_stContext : Current context.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_ContextToEndSection(SCR_tdst_Cxt_Description *_p_stContext)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiFirstLevel;
int iRead;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if(_p_stContext->cForSection==2) /*MP: BINARY */
return;
if(_p_stContext->cForSection==3) /*MP: BINARY */
{
long l=fn_l_Bin_ToEndSection( _p_stContext );
_p_stContext->stPosition.lAfterSeekInFile+=l;
/*fn_i_Anl_LineToContext(_p_stContext);*/
/*return;*/
}
/*
* No section description, it's a file, we zap to the end (we parse).
*/
if(_p_stContext->p_stSectionDes == NULL)
{
do
{
iRead = fn_i_Anl_LineToContext(_p_stContext);
} while(iRead != EOF);
return;
}
/*
* The end of section seek has not been parsed : We must parse to it.
* We go to the last parsing position and we parse.
*/
if((_p_stContext->p_stSectionDes->stEndPosition.uiLineInFile == 0)||
( _p_stContext->p_stOpenFile->stFile.bBinaryMode )) /*MP: BINARY*/
{
uiFirstLevel = _p_stContext->stPosition.uiLevel;
if( !_p_stContext->p_stOpenFile->stFile.bBinaryMode ) /*MP: BINARY*/
SCR_M_Anl_CxtFileToPos
(
_p_stContext,
_p_stContext->p_stOpenFile->stParsingInfos.stPosition
);
do
{
/* Get one line of file */
iRead = fn_i_Anl_LineToContext(_p_stContext);
/* MP: BINARY */
if(_p_stContext->eParseType == SCR_EPT_Cxt_BeginSection)
{
if( _p_stContext->p_stOpenFile->stFile.bBinaryMode )
{
long l=fn_l_Bin_ToEndSection( _p_stContext );
_p_stContext->stPosition.lAfterSeekInFile+=l;
_p_stContext->p_stOpenFile->stFile.lToEndSection=0;
}
}
/* Until endsection */
if
(
(_p_stContext->eParseType == SCR_EPT_Cxt_EndSection)
&& (_p_stContext->stPosition.uiLevel == uiFirstLevel - 1)
)
{
return;
}
} while(iRead != EOF);
SCR_M_Err_UpdateSyntaxError();
SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndSection);
}
/*
* Else we go to the end of section.
*/
else
{
SCR_M_Anl_CxtFileToPos
(
_p_stContext,
_p_stContext->p_stSectionDes->stEndPosition
);
_p_stContext->stPosition.uiLevel--;
}
}
/*
*-------------------------------------------------------------------------------------------------
* To init the parser for a file.
* p_stOpenFile must be correct in current context.
* _p_stContext : Current context
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_ContextToFile(SCR_tdst_Cxt_Description *_p_stContext)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Cxt_Position stPosition;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_AssertStruct_P(SCR_tdst_Cxt_Description, _p_stContext);
SCR_M_Dbg_AssertStruct_P(SCR_tdst_File_Open, _p_stContext->p_stOpenFile);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Initialize position to 0.
*/
memset(&stPosition, 0, sizeof(SCR_tdst_Cxt_Position));
/* MP: BINARY */
if( _p_stContext->p_stOpenFile->stFile.bBinaryMode )
stPosition.lAfterSeekInFile=SCR_M_ftell(&_p_stContext->p_stOpenFile->stFile);
/*
* Position the file to its beginning.
*/
/* End BINARY */
/*
* a_szBufferCompleteName, a_szBufferName and a_szBufferNameExt are name of file
* (with path).
* No format and no parameters.
* Parse type is a file begin (that will be replace by a section begin later).
* No section description.
*/
strcpy
(
_p_stContext->stBuffers.a_szBufferCompleteName,
_p_stContext->p_stOpenFile->stFile.a_szFileName
);
strcpy
(
_p_stContext->stBuffers.a_szBufferName,
_p_stContext->p_stOpenFile->stFile.a_szFileName
);
strcpy
(
_p_stContext->stBuffers.a_szBufferNameExt,
_p_stContext->p_stOpenFile->stFile.a_szFileName
);
*_p_stContext->stBuffers.a_szBufferFormat = '\0';
*_p_stContext->stBuffers.a_szBufferParams = '\0';
_p_stContext->cForSection = 0;
/* MP: BINARY */
if( _p_stContext->p_stOpenFile->stFile.bBinaryMode )
_p_stContext->cForSection = 2;
_p_stContext->eParseType = SCR_EPT_Cxt_BeginSection;
_p_stContext->p_stSectionDes = NULL;
/*
* Position the file to its beginning.
*/
SCR_M_Anl_CxtFileToPos
(
_p_stContext,
stPosition
);
}
/*===============================================================================================*/
/*
*-------------------------------------------------------------------------------------------------
* A call to a callback.
* _p_stP : Parser values.
* _eAction : Action for callback.
* _p_iExitBeforeLevel : To treat call-back return values.
* Returns return value of callback.
*-------------------------------------------------------------------------------------------------
*/
char fn_c_Anl_CallToCallback
(
SCR_tdst_Anl_ParserValues *_p_stP,
SCR_tde_Anl_Action _eAction,
int *_p_iExitBeforeLevel
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
char cReturn;
char *ap_szParameters[SCR_CV_ui_Cfg_MaxNumPars];
SCR_tdst_Cxt_Description *p_stNextContext;
SCR_tdst_Cxt_Buffers *p_stBuffers;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_P(_p_stP != NULL);
SCR_M_Dbg_Assert_P(_p_iExitBeforeLevel != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Call the callback
*----------------------
*/
p_stNextContext = _p_stP->p_stContext;
p_stBuffers = &_p_stP->p_stContext->stBuffers;
ap_szParameters[0] = NULL;
switch(_eAction)
{
/*
* A begin of section, a end of section or an entry.
*/
case SCR_EA_Anl_BeginSection:
case SCR_EA_Anl_EndSection:
case SCR_EA_Anl_Entry:
/* Convert parameters */
fn_v_Pars_ConvertParameters
(
p_stBuffers->a_szBufferFormat,
p_stBuffers->a_szBufferParams,
ap_szParameters
);
/* Call the callback */
SCR_M_Dbg_Assert_P(_p_stP->p_stCallback != NULL);
SCR_M_Dbg_Assert_P(_p_stP->p_stCallback->pfn_eCallback != NULL);
_p_stP->eReturnValue = _p_stP->p_stCallback->pfn_eCallback
(
&_p_stP->p_stContext->p_stOpenFile->stFile,
p_stBuffers->a_szBufferNameExt,
ap_szParameters,
_eAction
);
/* Free parameters */
SCR_M_Pars_FreeParameters(ap_szParameters);
break;
/*
* A begin of a subsection.
* Current context contains in stBuffers all info about subsection.
* A end of a subsection.
* The next context contains infos (in stBuffersCopy) about subsection.
*
* stBuffersCopy of current context contains infos about current section.
*/
case SCR_EA_Anl_EndSubSection:
p_stNextContext = fnp_st_Cxt_Compute(1);
p_stBuffers = &p_stNextContext->stBuffersCopy;
case SCR_EA_Anl_BeginSubSection:
/* Prepare parameters with infos about subsection (the one in context) */
ap_szParameters[0] = p_stBuffers->a_szBufferName;
ap_szParameters[1] = p_stBuffers->a_szBufferNameExt;
ap_szParameters[2] = p_stBuffers->a_szBufferCompleteName;
ap_szParameters[3] = (char *) (&p_stNextContext->stSectionValues);
ap_szParameters[4] = NULL;
/* Call the callback */
_p_stP->eReturnValue = _p_stP->p_stCallback->pfn_eCallback
(
&_p_stP->p_stContext->p_stOpenFile->stFile,
_p_stP->p_stContext->stBuffersCopy.a_szBufferNameExt,
ap_szParameters,
_eAction
);
/* Erase array of parameters */
ap_szParameters[0] = NULL;
break;
/*
* Section already analysed.
* No parameters.
*/
case SCR_EA_Anl_AlreadyAnalysed:
ap_szParameters[0] = NULL;
_p_stP->eReturnValue = _p_stP->p_stCallback->pfn_eCallback
(
&_p_stP->p_stContext->p_stOpenFile->stFile,
p_stBuffers->a_szBufferNameExt,
ap_szParameters,
SCR_EA_Anl_AlreadyAnalysed
);
break;
}
/*
*
* Treat return value.
*
*/
cReturn = 0;
switch(_p_stP->eReturnValue)
{
/* Normal return : Continue */
case SCR_ERV_Anl_NormalReturn:
cReturn = 0;
break;
/* End of current section */
case SCR_ERV_Anl_TerminateCurrentSection:
*_p_iExitBeforeLevel = _p_stP->p_stContext->stPosition.uiLevel;
cReturn = 1;
break;
/* End of parent section */
case SCR_ERV_Anl_TerminateParentSection:
*_p_iExitBeforeLevel = _p_stP->p_stContext->stPosition.uiLevel - 1;
cReturn = 1;
break;
/* End of main section */
case SCR_ERV_Anl_TerminateMainSection:
*_p_iExitBeforeLevel = 1;
cReturn = 1;
break;
/* End of file */
case SCR_ERV_Anl_TerminateFile:
*_p_iExitBeforeLevel = 0;
cReturn = 1;
break;
/* Default : Error */
default:
SCR_M_Dbg_Assert_P(0);
}
/*
* Treat uiExitBeforeLevel.
* It is the level we want to pass below without parsing (and going to the end
* of sections while passing).
*/
if(*_p_iExitBeforeLevel >= 0)
{
/* We have reached the level */
if((int) (_p_stP->p_stContext->stPosition.uiLevel + 1) == *_p_iExitBeforeLevel)
{
*_p_iExitBeforeLevel = -1;
cReturn = 0;
}
/* We are above the level : We zap the current section */
else
{
fn_v_Anl_ContextToEndSection(_p_stP->p_stContext);
cReturn = 1;
}
}
return cReturn;
}
/*
*-------------------------------------------------------------------------------------------------
* To parse the current section of file.
* Context must be placed at the beginning of the section (title has been parsed).
* _uwDynamicFlags : Dynamic flags to modify parsing.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_ParseCurrentSection(unsigned short _uwDynamicFlags)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Anl_ParserValues stP;
SCR_tdst_Cxt_Description *p_stNewContext;
SCR_tdx_Hash_Key xHashKey;
int iRead = 0;
char cEndSection, cForceEnd, cFirst;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Update stBuffersCopy.
* It will always contain the first state of stBuffers structure (so the name
* of the section itself).
*/
stP.p_stContext = fnp_st_Cxt_Compute(0);
SCR_M_Cxt_CopyBuffers(&stP.p_stContext->stBuffersCopy, &stP.p_stContext->stBuffers);
stP.p_stContext->uwDynamicFlags = _uwDynamicFlags;
/*
* Current user callback return value is normal.
*/
stP.eReturnValue = SCR_ERV_Anl_NormalReturn;
if( stP.p_stContext->p_stOpenFile->stFile.bBinaryMode ) /* MP: BINARY */
stP.p_stContext->cForSection|=2;
/*
* Get callback.
*/
stP.p_stCallback = fnp_st_Anl_SearchCallback
(
stP.p_stContext->stBuffers.a_szBufferName,
stP.p_stContext->cForSection
);
/*
* If there's no section for that callback, we raise a warning except if we analyse
* a file.
* We exit for a real section (we never analyse subsections if a section has no
* callback).
*/
if((stP.p_stCallback == NULL) && (stP.p_stContext->cForSection&~2))
{
*g_st_Err_GlobalError.a_szBufferTmp1 = '\0';
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Section is \"%s\".", stP.p_stContext->stBuffers.a_szBufferName);
SCR_M_Err_RaiseWarning(SCR_EI_Err_SectionWithoutCallback);
fn_v_Anl_ContextToEndSection(stP.p_stContext);
return;
}
/*
* Compute hash key code of this section.
* Is section has already been parsed ?
* If it's the case (and if there's a callback), we initialize static results
*/
SCR_M_Sect_ComputeHashKey
(
xHashKey,
stP.p_stContext->stBuffers.a_szBufferCompleteName
);
if(stP.p_stContext->p_stSectionDes)
stP.p_stContext->p_stOpenSection = stP.p_stContext->p_stSectionDes->p_stOpenSection;
else
{
stP.p_stContext->p_stOpenSection = fnp_st_Sect_SearchOpen
(
stP.p_stContext->stBuffers.a_szBufferCompleteName,
stP.p_stContext->stPosition.uiLineInFile,
xHashKey
);
}
/*
* Here, we are sure that we want to analyse the section.
* If section has not already been analysed once (p_stOpenSection not NULL), we add
* it to the array of open sections if we can (_uwDynamicFlags &= SCR_CDF_uw_Anl_NotSave false
* and section flag false too).
*/
cFirst = 0;
if
(
(stP.p_stContext->p_stOpenSection == NULL)
&&
(
(stP.p_stContext->p_stSectionDes == NULL)
|| ((stP.p_stContext->p_stSectionDes->uwDynamicFlags & SCR_CDF_uw_Anl_NotSaveSection) == 0)
)
)
{
stP.p_stContext->p_stOpenSection = fnp_st_Sect_AddOpen(stP.p_stContext, xHashKey);
if(stP.p_stContext->p_stSectionDes)
stP.p_stContext->p_stSectionDes->p_stOpenSection = stP.p_stContext->p_stOpenSection;
cFirst = 1;
}
/*
* Update values.
*/
if(stP.p_stContext->cSectionValuesValid)
{
memcpy
(
&stP.p_stContext->p_stOpenSection->stSectionValues,
&stP.p_stContext->stSectionValues,
sizeof(SCR_tdst_Cxt_Values)
);
stP.p_stContext->cSectionValuesValid = 0;
}
else
{
memcpy
(
&stP.p_stContext->stSectionValues,
&stP.p_stContext->p_stOpenSection->stSectionValues,
sizeof(SCR_tdst_Cxt_Values)
);
}
/*
* Test open section.
* If section is not forced to be analyse (_uwDynamicFlags &= SCR_CDF_uw_Anl_ForceAnalyse or
* flag set by a directive), and if section has already been analysed (p_stOpenSection not NULL),
* we call the callback (if one) with SCR_EA_Anl_AlreadyAnalysed, and we exit after being to the
* end of section.
*/
if
(
(!cFirst)
&& (stP.p_stContext->p_stOpenSection)
&& ((_uwDynamicFlags & SCR_CDF_uw_Anl_ForceAnalyse) == 0)
&&
(
(stP.p_stContext->p_stSectionDes == NULL)
|| ((stP.p_stContext->p_stSectionDes->uwDynamicFlags & SCR_CDF_uw_Anl_ForceAnalyse) == 0)
)
)
{
if(stP.p_stCallback)
fn_c_Anl_CallToCallback(&stP, SCR_EA_Anl_AlreadyAnalysed, &g_iExitBeforeLevel);
fn_v_Anl_ContextToEndSection(stP.p_stContext);
/*
* Force end of special return if we are at level 0.
*/
if(stP.p_stContext->stPosition.uiLevel == 0)
g_iExitBeforeLevel = -1;
return;
}
/*
* We call the callback with SCR_EA_Anl_BeginSection.
* cForceEnd can be set to 1 to force the end of parsing for that section (cause of
* a callback return value).
* cEndSection is set to 1 if a endsection has been parsed. We must end parser too.
*/
cForceEnd = 0;
cEndSection = 0;
if(stP.p_stCallback)
cForceEnd = fn_c_Anl_CallToCallback(&stP, SCR_EA_Anl_BeginSection, &g_iExitBeforeLevel);
/*
* Parsing.
*/
while((!cEndSection) && (!cForceEnd))
{
/*
* Get one line of text.
* If last character read is EOF, we raise a warning for a real section (cause we
* have not found the endsection).
* We exit the parser (cause it's like a end section).
*/
iRead = fn_i_Anl_LineToContext(stP.p_stContext);
if(iRead == EOF)
{
cEndSection = 1;
if((stP.p_stContext->p_stSectionDes) && (stP.p_stContext->eParseType != SCR_EPT_Cxt_EndSection))
{
*g_st_Err_GlobalError.a_szBufferTmp1 = '\0';
sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Section is \"%s\".", stP.p_stContext->stBuffersCopy.a_szBufferCompleteName);
SCR_M_Err_RaiseWarning(SCR_EI_Err_MissingEndSection);
}
break;
}
switch(stP.p_stContext->eParseType)
{
/*
* Dummy values.
* We don't care about directives that has already been treat when reading the line.
*/
case SCR_EPT_Cxt_None:
break;
case SCR_EPT_Cxt_Directive:
fn_v_Anl_AnalyseDynamicDirective(stP.p_stContext);
break;
/*
* An entry.
* We call the callback (if one).
*/
case SCR_EPT_Cxt_Entry:
if(stP.p_stCallback)
cForceEnd = fn_c_Anl_CallToCallback(&stP, SCR_EA_Anl_Entry, &g_iExitBeforeLevel);
break;
/*
* A Sub Section.
*/
case SCR_EPT_Cxt_BeginSection:
/* Callback SCR_EA_Anl_BeginSubSection */
if(stP.p_stCallback)
{
cForceEnd = fn_c_Anl_CallToCallback(&stP, SCR_EA_Anl_BeginSubSection, &g_iExitBeforeLevel);
if(cForceEnd)
break;
}
/* Add one context */
p_stNewContext = fnp_st_Cxt_Add();
/* Copy old context to new one */
SCR_M_Cxt_CopyBuffers(&p_stNewContext->stBuffers, &stP.p_stContext->stBuffers);
memcpy(&p_stNewContext->stPosition, &stP.p_stContext->stPosition, sizeof(SCR_tdst_Cxt_Position));
p_stNewContext->p_stOpenFile = stP.p_stContext->p_stOpenFile;
p_stNewContext->p_stSectionDes = stP.p_stContext->p_stSectionDes;
p_stNewContext->cForSection = 1;
if( p_stNewContext->p_stOpenFile->stFile.bBinaryMode ) /* MP: BINARY */
p_stNewContext->cForSection=3;
/* Parse section */
fn_v_Anl_ParseCurrentSection(_uwDynamicFlags);
/* Copy new position to current context */
memcpy(&stP.p_stContext->stPosition, &p_stNewContext->stPosition, sizeof(SCR_tdst_Cxt_Position));
stP.p_stContext->p_stSectionDes = stP.p_stContext->p_stSectionDes->p_stParentSection;
/* Delete last context */
fn_v_Cxt_DeleteLast();
/* To treat eventual return of section analyse */
stP.eReturnValue = SCR_ERV_Anl_NormalReturn;
cForceEnd = fn_c_Anl_CallToCallback(&stP, SCR_EA_Anl_Invalid, &g_iExitBeforeLevel);
/* Callback SCR_EA_Anl_EndSubSection */
if((stP.p_stCallback) && (cForceEnd == 0))
cForceEnd = fn_c_Anl_CallToCallback(&stP, SCR_EA_Anl_EndSubSection, &g_iExitBeforeLevel);
break;
/*
* End of section or file.
*/
case SCR_EPT_Cxt_EndSection:
cEndSection = 1;
break;
}
}
/*
* Test if an end section is missing.
* We raise an error in that case.
*/
if((cEndSection == 0) && (iRead == EOF) && (stP.p_stContext->p_stSectionDes))
{
SCR_M_Err_UpdateSyntaxError();
SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndSection);
}
/*
* Call the callback with SCR_EA_Anl_EndSection only if the end of this section has not
* been forced.
*/
if((cEndSection) && (stP.p_stCallback))
{
/* To have the really good name of section (id part passed to the callback) */
strcpy(stP.p_stContext->stBuffers.a_szBufferNameExt, stP.p_stContext->stBuffersCopy.a_szBufferNameExt);
/* Call the callback */
fn_c_Anl_CallToCallback(&stP, SCR_EA_Anl_EndSection, &g_iExitBeforeLevel);
}
/*
* Force end of special return if we are at level 0.
*/
if(stP.p_stContext->stPosition.uiLevel == 0)
g_iExitBeforeLevel = -1;
}
/*
**************************************************************************************************
**************************************************************************************************
**************************************************************************************************
**************************************************************************************************
*/
/*
*-------------------------------------------------------------------------------------------------
* To reduce memory size.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_ReduceMemory(void)
{
/* Pack array of callbacks */
SCR_M_DyAr_PackArray(SCR_tdst_Anl_Callback, SCR_g_st_Anl_ArrayCallbacks, ;);
}
/*
*-------------------------------------------------------------------------------------------------
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Anl_DeleteWithMemLevel(unsigned char _ucMin, unsigned char _ucMax)
{
SCR_M_DyAr_DeleteElementWithMemLevel
(
SCR_tdst_Anl_Callback,
SCR_g_st_Anl_ArrayCallbacks,
;,
_ucMin,
_ucMax
);
}