/* *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * SCR_Anl.c * To analyse a section. * * Scripts, Beaudet Christophe *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ /* *================================================================================================= * Includes. *================================================================================================= */ #include #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 ); }