1734 lines
58 KiB
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
|
|
);
|
|
}
|