/*
 =======================================================================================
  Name        : Scr_Fct.cpp
 
  Author      : vincent lhullier            Date :08/09/97
 
  Description : script function to parse a file
 =======================================================================================
 */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "inidata.h"
#include "SCR_Fct.h"
#include "SpecRef.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
	Globals 
 =======================================================================================
 */


SCR_tdst_Link_Table	g_stSectionTypeLinkTable;	/* link table for section type */
SCR_tdst_Link_Table	g_stSectionLinkTable;		/* link table for section */
SCR_tdst_Link_Table g_stRefLinkTable;			/* link table for references */
SCR_tdst_Link_Table g_stFileLinkTable;			/* Link table for files */

/*
 =======================================================================================
	load/save functions
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : save all entry to describe all section entry
  _p_stFileDes        -> file
  _p_stSection        -> section
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vSaveSectionEntry( SCR_tdst_File_Description *_p_stFileDes, SCR_tdst_DyAr_Description *_p_stSectionEntryDyAr )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	tdstEntry					*p_stEntry;
	unsigned int				uiEntry;
	char						szParamString[21], szText[1024], *p_szText;
	char						cParam, cParamState;
	char						*a_szParam[3] = { NULL, szParamString, szText };
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	
	/*
	 * for each entry
	 */
	for (uiEntry = 0; uiEntry < _p_stSectionEntryDyAr->uiNumValues; uiEntry ++)
	{
		SCR_M_DyAr_GetElement( tdstEntry, uiEntry, p_stEntry, (*_p_stSectionEntryDyAr) );

		/*
		 * save entry name
		 */
		SCR_M_SvL0_SaveEntry( _p_stFileDes, "Entry", SCR_CC_C_Cfg_NoChar );

		/*
		 * compute first parameter : entry name
		 */
		a_szParam[0] = p_stEntry->szName;
		/*
		 * compute second parameter : perameter states
		 */
		for (cParam = 0; cParam < p_stEntry->cNumberOfParams; cParam++)
		{
			cParamState = p_stEntry->a_cIsRef[cParam];
			szParamString[cParam] = (cParamState == 0) ? '_' : (cParamState == 1) ? 'R' : 'S';
		}
		szParamString[cParam] = 0;

		/*
		 * compute third param : entry sample
		 */
		strcpy( szText, p_stEntry->szSample );
		p_szText = szText;
		while( *p_szText != 0)
		{
			if (*p_szText == '"') *p_szText = 39;
			p_szText++;
		}
		/*
		 * save parameters
		 */
		SCR_fn_v_SvL0_SaveParameters_AP( _p_stFileDes, SCR_EF_SvL0_Normal, 3, a_szParam );
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : save all section types in a script file
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vSaveSectionTypes( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	SCR_FILE					xFile;
	SCR_tdst_File_Description	stFileDes;
	SCR_tdst_DyAr_Description	*p_stDyAr;
	SCR_tdst_Link_Value			*p_stValue;
	unsigned int				uiSection;
	char						szText[256];
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	
	/*
	 * Open file and init file des
	 */
	xFile = SCR_M_p_x_File_OpenWrite( g_stIniData.szSectionFile );
	SCR_fn_v_File_InitFileDes( &stFileDes, g_stIniData.szSectionFile, xFile );

	/*
	 * save script header
	 */
	SCR_M_SvL0_SaveScriptFileHeader( &stFileDes );

	/* 
	 * save each section
	 */
	p_stDyAr = &g_stSectionTypeLinkTable.stLinkArray;
	for (uiSection = 0; uiSection < p_stDyAr->uiNumValues; uiSection ++)
	{
		SCR_M_DyAr_GetElement( SCR_tdst_Link_Value, uiSection, p_stValue, g_stSectionTypeLinkTable.stLinkArray );

		/*
		 * save section beginning
		 */
		sprintf( szText, "SectionType:%s", p_stValue->p_szKey );
		SCR_M_SvL0_SaveBeginSection( &stFileDes, szText, SCR_CC_C_Cfg_EOL );

		/*
		 * save all entries in section
		 */
		fn_Scr_vSaveSectionEntry( &stFileDes, (SCR_tdst_DyAr_Description *) p_stValue->ulValue );
			
		/*
		 * save end of section
		 */
		SCR_M_SvL0_SaveEndSection( &stFileDes, SCR_CC_C_Cfg_EOL );
	}


	/*
	 * Close file
	 */
	SCR_fn_v_File_CloseFileDes( &stFileDes );
}


/*
 ----------------------------------------------------------------------------------------
4  Description   : Callback to analyse a SectionType section
 ----------------------------------------------------------------------------------------
 */
SCR_tde_Anl_ReturnValue fn_Scr_eCallbackForSectionType(SCR_tdst_File_Description *_p_stFile, char *_szAction, char *_szParams[], SCR_tde_Anl_Action _eType)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/	
	SCR_tdst_Link_Value			*p_stLinkValue;
	SCR_tdst_DyAr_Description	*p_stSectionEntryDyAr;
	tdstEntry					*p_stEntry;
	char						cParam;
	unsigned int				uiPos;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	switch ( _eType )
	{
		case SCR_EA_Anl_BeginSection:
			p_stLinkValue = SCR_fnp_st_Link_CreateOrGetLinkFromKey( &g_stSectionTypeLinkTable, _szAction );
			if (p_stLinkValue->eState == SCR_ELS_Link_NotInitialized)
			{
				p_stSectionEntryDyAr = (SCR_tdst_DyAr_Description *) malloc (sizeof( SCR_tdst_DyAr_Description ) );
				fn_v_DyAr_InitArray( p_stSectionEntryDyAr );
				p_stLinkValue->eState = SCR_ELS_Link_Initialized;
				p_stLinkValue->ulValue = (unsigned long) p_stSectionEntryDyAr;
				p_stLinkValue->stInfos.ulLong1 = 0;
				p_stLinkValue->stInfos.ulLong2 = 0;
			}
			else
			{
				p_stSectionEntryDyAr = (SCR_tdst_DyAr_Description *) p_stLinkValue->ulValue;
			}
			SCR_M_RdL0_SetContextLong(0,0, p_stSectionEntryDyAr);
			break;

		case SCR_EA_Anl_Entry:
			
			SCR_M_RdL0_GetContextLong(0,0, SCR_tdst_DyAr_Description *, p_stSectionEntryDyAr);
			p_stEntry = fn_Scr_p_stFindEntry( p_stSectionEntryDyAr, _szParams[0] );
			if (p_stEntry == NULL)
			{
				/*
				 * add entry in entry array of section
				 */
				SCR_M_DyAr_AddElement( tdstEntry, uiPos, p_stEntry, (*p_stSectionEntryDyAr) );
				/*
				 * set entry data member
				 */
				p_stEntry->szName = (char *) malloc (strlen( _szParams[0] ) + 1);
				strcpy( p_stEntry->szName, _szParams[0] );
				p_stEntry->szSample = (char *) malloc (strlen( _szParams[2] ) + 1);
				strcpy( p_stEntry->szSample, _szParams[2] );
				p_stEntry->cNumberOfParams = strlen( _szParams[1] );
				p_stEntry->cNumberOfRefs = 0;
				for (cParam = 0; cParam < p_stEntry->cNumberOfParams; cParam++)
				{
					if ( _szParams[1][ cParam ] != '_' )
					{
						p_stEntry->cNumberOfRefs++;
						p_stEntry->a_cIsRef[ cParam ] = (_szParams[1][cParam] == 'R') ? 1 : 2;
					}
					else
					{
						p_stEntry->a_cIsRef[ cParam ] = 0;
					}
				}
			}
			break;
	}
	return  R_SCRIPT_NormalReturn;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : load all section types from a script file
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vLoadSectionTypes( void )
{
	/*
	 * Register callback for "SectionType" script section
	 */
	SCR_fn_v_RdL0_RegisterCallback( "SectionType", fn_Scr_eCallbackForSectionType, SCR_CRC_c_RdL0_ForSection);

	/*
	 * analyse section type file
	 */
	SCR_fnp_st_RdL0_AnalyseSection( g_stIniData.szSectionFile, SCR_CDF_uw_Anl_Normal );

	/*
	 * delete callback
	 */
	SCR_fn_v_RdL0_DeleteRegisterCallback( "SectionType", SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match );
}


/*
 =======================================================================================
	data functions
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : load an find an entry in a section type
  _p_stSection        -> pointer on a section type structure
  _szEntryName        -> name of entry to find
  Returns (tdstEntry) pointer on entry if found, otherwise NULL
 ----------------------------------------------------------------------------------------
 */
tdstEntry *fn_Scr_p_stFindEntry( SCR_tdst_DyAr_Description *_p_stSectionEntryDyAr, char *_szEntryName )
{
	tdstEntry		*p_stEntry;
	unsigned int	uiPos;
	
	SCR_M_DyAr_SearchElement( tdstEntry, uiPos, p_stEntry, (*_p_stSectionEntryDyAr), strcmp( _szEntryName, p_stEntry->szName) == 0 );
	
	return p_stEntry;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : Add an entry to a section
  _p_stSection        -> section
  _p_stContext        -> context that describe entry
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vAddEntryToSection( SCR_tdst_DyAr_Description *_p_stSectionEntryDyAr, SCR_tdst_Cxt_Description *_p_stContext )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	tdstEntry		*p_stEntry;
	char			szSample[512], *p_szSample;
	char			*szParam;
	size_t			xLenght;
	unsigned int	uiPos;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	p_stEntry = fn_Scr_p_stFindEntry( _p_stSectionEntryDyAr, _p_stContext->stBuffers.a_szBufferNameExt );
	if (p_stEntry == NULL)
	{
		/*
		 * add and init entry
		 */
		SCR_M_DyAr_AddElement( tdstEntry, uiPos, p_stEntry, (*_p_stSectionEntryDyAr) );
		memset( p_stEntry, 0, sizeof( tdstEntry) );

		/*
		 * allocate and set name
		 */
		p_stEntry->szName = (char *) malloc ( strlen(_p_stContext->stBuffers.a_szBufferNameExt) + 1 );
		strcpy( p_stEntry->szName, _p_stContext->stBuffers.a_szBufferNameExt );

		/*
		 * build sample and count parameters
		 */
		p_szSample = szSample + sprintf( szSample, "%s", p_stEntry->szName );

		if ( *_p_stContext->stBuffers.a_szBufferFormat != 0) 
			p_szSample += sprintf( p_szSample, "%c%s%c", SCR_CC_c_Cfg_FormatBegMark, _p_stContext->stBuffers.a_szBufferFormat, SCR_CC_c_Cfg_FormatEndMark );
		
		if ( *(szParam = _p_stContext->stBuffers.a_szBufferParams) != 0)
		{
			*p_szSample++ = SCR_CC_c_Cfg_ParamBegMark;
			*p_szSample++ = ' ';
			while ( 1 )
			{
				xLenght = strlen( szParam );

				/* detect a reference ? */
				if ( strcspn( szParam, "^\\") < xLenght)
				{
					p_stEntry->cNumberOfRefs++;
					p_stEntry->a_cIsRef[ p_stEntry->cNumberOfParams ] = 1;		
				}

				p_stEntry->cNumberOfParams++;

				memcpy( p_szSample, szParam, xLenght );
				p_szSample += xLenght;
				szParam += xLenght + 1;
				
				if (*szParam == 0)
					break;

				*p_szSample++ = SCR_CC_c_Cfg_ParamSeparator;
				*p_szSample++ = ' ';
			}
			*p_szSample++ = SCR_CC_c_Cfg_ParamEndMark;
			*p_szSample = 0;
		}

		p_stEntry->szSample = (char *) malloc ( p_szSample - szSample + 1 );
		memcpy( p_stEntry->szSample, szSample, p_szSample - szSample + 1 );
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : set to 0 all used value
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vResetUsedCounters( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	SCR_tdst_DyAr_Description	*p_stDyAr;
	SCR_tdst_Link_Value			*p_stValue;
	unsigned int				uiSection;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	p_stDyAr = &g_stSectionTypeLinkTable.stLinkArray;
	for (uiSection = 0; uiSection < p_stDyAr->uiNumValues; uiSection ++)
	{
		SCR_M_DyAr_GetElement( SCR_tdst_Link_Value, uiSection, p_stValue, g_stSectionTypeLinkTable.stLinkArray );
		SCR_M_v_Link_SetAdditionalLong( p_stValue, 1, 0 );
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : compute all section has ref flag. this flag is set if a section
				can have at least one entry with one ref.
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vComputeSectionTypeHasRef( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	SCR_tdst_DyAr_Description	*p_stDyAr;
	SCR_tdst_Link_Value			*p_stValue;
	SCR_tdst_DyAr_Description	*p_stSectionEntryDyAr;
	tdstEntry					*p_stEntry;
	unsigned int				uiSection;
	unsigned int				uiPos;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	p_stDyAr = &g_stSectionTypeLinkTable.stLinkArray;
	for (uiSection = 0; uiSection < p_stDyAr->uiNumValues; uiSection ++)
	{
		SCR_M_DyAr_GetElement( SCR_tdst_Link_Value, uiSection, p_stValue, g_stSectionTypeLinkTable.stLinkArray );

		p_stSectionEntryDyAr = (SCR_tdst_DyAr_Description *) SCR_M_ul_Link_GetValue( p_stValue );
		SCR_M_DyAr_SearchElement( tdstEntry, uiPos, p_stEntry, (*p_stSectionEntryDyAr), p_stEntry->cNumberOfRefs != 0 );
		
		SCR_M_v_Link_SetAdditionalLong( p_stValue, 2, (p_stEntry == NULL) ? 0 : 1 );
		
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : free section type list
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vFreeSectionTypeList( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	SCR_tdst_Link_Value			*p_stValue;
	unsigned int				uiSection;
	SCR_tdst_DyAr_Description	*p_stSectionEntryDyAr;
	tdstEntry					*p_stEntry;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	for (uiSection = 0; uiSection < g_stSectionTypeLinkTable.stLinkArray.uiNumValues; uiSection ++)
	{
		SCR_M_DyAr_GetElement( SCR_tdst_Link_Value, uiSection, p_stValue, g_stSectionTypeLinkTable.stLinkArray );

		p_stSectionEntryDyAr =  (SCR_tdst_DyAr_Description *) p_stValue->ulValue;
		SCR_M_DyAr_DeleteAllElements( tdstEntry, p_stSectionEntryDyAr, p_stEntry = (tdstEntry *) _p_stElement_->d_vElement; free( p_stEntry->szName ); free( p_stEntry->szSample); );
		free ( p_stSectionEntryDyAr );
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : free section type list
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vFreeSectionList( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	SCR_tdst_DyAr_Description	*p_stRefDyAr;
	SCR_tdst_Link_Value			*p_stValue;
	unsigned int				uiSection;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	for (uiSection = 0; uiSection < g_stSectionLinkTable.stLinkArray.uiNumValues; uiSection ++)
	{
		SCR_M_DyAr_GetElement( SCR_tdst_Link_Value, uiSection, p_stValue, g_stSectionLinkTable.stLinkArray );
		
		if ( p_stValue->ulValue )
		{
			p_stRefDyAr = (SCR_tdst_DyAr_Description *) p_stValue->ulValue;
			SCR_M_DyAr_DeleteAllElements( tdstReference, p_stRefDyAr, ; );
			free ( p_stRefDyAr );
		}
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : free file list
 ----------------------------------------------------------------------------------------
 */
void fn_Scr_vFreeLTFile( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	SCR_tdst_Link_Value			*p_stLVFile;
	unsigned int				uiFile;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	for (uiFile = 0; uiFile < g_stFileLinkTable.stLinkArray.uiNumValues; uiFile++)
	{
		SCR_M_DyAr_GetElement( SCR_tdst_Link_Value, uiFile, p_stLVFile, g_stFileLinkTable.stLinkArray );
		
		if (p_stLVFile->ulValue)
		{
			SCR_fn_v_Link_CloseTable( (SCR_tdst_Link_Table *) p_stLVFile->ulValue );
		}
	}
}


/*
 =======================================================================================
	Parsing functions
 =======================================================================================
 */

/*
 *-------------------------------------------------------------------------------------------------
 *  To parse a line to current context.
 *  _p_stContext    :   Current context.
 *-------------------------------------------------------------------------------------------------
 */
int fn_Scr_iLineToContext(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++;

    /*
     *  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;

    /* Return last character read */
    return iRead;
}


/*
 *-------------------------------------------------------------------------------------------------
 *  parse a file to get the section type
 *  _p_szFileName   :   file name
 *-------------------------------------------------------------------------------------------------
 */
void fn_Scr_vParseFileToBuildListOfSectionTypes(char *_p_szFileName)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_tdst_Cxt_Description    *p_stContext;
    int                         iRead;
	int							cIndent = -1;
	SCR_tdst_DyAr_Description	*a_p_stSectionEntryDyAr[ 16 ];
	SCR_tdst_Link_Value			*p_stLinkValue;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_D(_p_szFileName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
     *  One more context.
     */
    p_stContext = fnp_st_Cxt_Add();

    /*
     *  Open the file.
     */
    p_stContext->p_stOpenFile = fnp_st_File_OpenFile(_p_szFileName);
	
    /*
     *  Place file to its SCR_BEGINing.
     *  Parse to the end.
     */
    fn_v_Anl_ContextToFile(p_stContext);
    do
    {
		iRead = fn_Scr_iLineToContext( p_stContext );

		if ( p_stContext->eParseType == SCR_EPT_Cxt_BeginSection )
		{
			cIndent++;
			p_stLinkValue = SCR_fnp_st_Link_CreateOrGetLinkFromKey( &g_stSectionTypeLinkTable, p_stContext->stBuffers.a_szBufferName );
			if (p_stLinkValue->eState == SCR_ELS_Link_NotInitialized)
			{
				a_p_stSectionEntryDyAr[ cIndent ] = ( SCR_tdst_DyAr_Description *) malloc (sizeof( SCR_tdst_DyAr_Description ) );
				fn_v_DyAr_InitArray( a_p_stSectionEntryDyAr[ cIndent ] );
				p_stLinkValue->eState = SCR_ELS_Link_Initialized;
				p_stLinkValue->ulValue = (unsigned long) a_p_stSectionEntryDyAr[ cIndent ];
				p_stLinkValue->stInfos.ulLong1 = 1;
				p_stLinkValue->stInfos.ulLong2 = 0;
			}
			else
			{
				a_p_stSectionEntryDyAr[ cIndent ] = ( SCR_tdst_DyAr_Description *) p_stLinkValue->ulValue;
				p_stLinkValue->stInfos.ulLong1++;
			}
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_EndSection )
		{
			cIndent--;
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_Entry )
		{
			if (cIndent >= 0)
				fn_Scr_vAddEntryToSection( a_p_stSectionEntryDyAr[ cIndent ], p_stContext );
		}

	} while(iRead != EOF);

	SCR_fn_v_RdL0_DeleteOpenFile( _p_szFileName, SCR_CDR_c_RdL0_Match );

    /*
     *  Delete context. It's finish...
     */
    fn_v_Cxt_DeleteLast();
}


/*
 *-------------------------------------------------------------------------------------------------
 *  parse a file to get all sections and references
 *  _p_szFileName   :   file name
 *-------------------------------------------------------------------------------------------------
 */
void fn_Scr_vParseFileToBuildListOfSectionsAndRefs(char *_p_szFileName)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_tdst_Cxt_Description    *p_stContext;
    int                         iRead;
	int							cIndent = -1;
	char						*a_szSectionName[ 16 ];
	char						szSectionName[ SCR_CV_ui_Cfg_MaxLenName ];
	SCR_tdst_Link_Value			*a_p_stSection[ 16 ];
	SCR_tdst_Link_Value			*p_stSectionType;
	SCR_tdst_Link_Value			*p_stRefValue;
	SCR_tdst_DyAr_Description	*p_stSectionEntryDyAr;
	tdstEntry					*p_stEntry;
	SCR_tdst_DyAr_Description	*p_stDyAr;
	unsigned int				uiPos;
	tdstReference				*p_stRef;
	char						cRef, cIndex;
	char						*szParam;
	char						*szRefFileName;
	char						szRefName[ SCR_CV_ui_Cfg_MaxLenName ], *p_szRefName, *p_szEndRefFileName;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//    SCR_M_Dbg_Assert_D(_p_szFileName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
     *  One more context.
     */
    p_stContext = fnp_st_Cxt_Add();

    /*
     *  Open the file.
     */
    p_stContext->p_stOpenFile = fnp_st_File_OpenFile(_p_szFileName);

	cIndent = -1;

	szRefFileName = _p_szFileName + g_stIniData.lRootForSectionLength;
	p_szEndRefFileName = szRefFileName + strlen( szRefFileName );
	strcpy( szSectionName, szRefFileName );
	a_szSectionName[ 0 ] = szSectionName + ( p_szEndRefFileName - szRefFileName );
	
    /*
     *  Place file to its SCR_BEGINing.
     *  Parse to the end.
     */
    fn_v_Anl_ContextToFile(p_stContext);
    do
    {
		iRead = fn_Scr_iLineToContext( p_stContext );

		if ( p_stContext->eParseType == SCR_EPT_Cxt_BeginSection )
		{
			cIndent++;
			/*
			 * get section type
			 */
			p_stSectionType = SCR_fnp_st_Link_SearchKey( &g_stSectionTypeLinkTable, p_stContext->stBuffers.a_szBufferName );

			/*
			 * build full section name
			 */
			*a_szSectionName[ cIndent ] = SCR_CC_c_Cfg_NameSeparator;
			strcpy( a_szSectionName[ cIndent ] + 1, p_stContext->stBuffers.a_szBufferName );
			a_szSectionName[ cIndent + 1 ] = a_szSectionName[ cIndent ] + strlen( a_szSectionName[ cIndent ] );
			if ( *p_stContext->stBuffers.a_szBufferNameExt)
			{
				*a_szSectionName[cIndent + 1]++ = SCR_CC_c_Cfg_SectionIdMark;
				strcpy (a_szSectionName[cIndent + 1], p_stContext->stBuffers.a_szBufferNameExt );
				a_szSectionName[ cIndent + 1 ] += strlen( a_szSectionName[ cIndent + 1 ] );
			}

			/*
			 * get or create section link value
			 */
			a_p_stSection[ cIndent ] = SCR_fnp_st_Link_CreateOrGetLinkFromKey( &g_stSectionLinkTable, szSectionName );
			if (a_p_stSection[ cIndent ]->eState == SCR_ELS_Link_NotInitialized)
			{
				a_p_stSection[ cIndent ]->eState = SCR_ELS_Link_Initialized;
				a_p_stSection[ cIndent ]->stInfos.ulLong1 = p_stContext->stPosition.uiLineInFile;
				a_p_stSection[ cIndent ]->stInfos.ulLong2 = 0;

				if (p_stSectionType->stInfos.ulLong2)
				{
					a_p_stSection[ cIndent ]->stInfos.ulLong3 = (unsigned long) p_stSectionType;
					p_stDyAr = (SCR_tdst_DyAr_Description *) malloc( sizeof(SCR_tdst_DyAr_Description) );
					fn_v_DyAr_InitArray( p_stDyAr );
					a_p_stSection[ cIndent ]->ulValue = (unsigned long) p_stDyAr;
				}
				else
					a_p_stSection[ cIndent ]->ulValue = 0;
			}
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_EndSection )
		{
			*a_szSectionName[ cIndent ] = 0;
			cIndent--;
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_Entry )
		{
			if ( (cIndent >= 0) && (a_p_stSection[ cIndent ]->ulValue ) )
			{
				p_stSectionType = (SCR_tdst_Link_Value *) a_p_stSection[ cIndent ]->stInfos.ulLong3;
				p_stSectionEntryDyAr = (SCR_tdst_DyAr_Description *) p_stSectionType->ulValue;
				if ( (p_stEntry = fn_Scr_p_stFindEntry( p_stSectionEntryDyAr, p_stContext->stBuffers.a_szBufferNameExt )) != NULL)
				{
					p_stDyAr = (SCR_tdst_DyAr_Description *) a_p_stSection[ cIndent ]->ulValue;
					cRef = p_stEntry->cNumberOfRefs;
					cIndex = 0;
					szParam = p_stContext->stBuffers.a_szBufferParams;
					while (cRef)
					{
						if ( p_stEntry->a_cIsRef[ cIndex ] )
						{
							cRef--;
							
							if ( p_stEntry->a_cIsRef[cIndex] == 1)
							{
								if (*szParam == '*')
								{
									p_szRefName = szRefFileName;
									strcpy( p_szEndRefFileName, szParam + 1);
								}
								else
								{	
									p_szRefName = szParam;
								}
							}
							else
							{
								p_szRefName = strcpy( szRefName, szParam );
								fn_SpRef_vTransformSpecialRef( p_stSectionType->p_szKey, p_stEntry->szName, cIndex, szRefName );							
							}

							p_stRefValue = SCR_fnp_st_Link_CreateOrGetLinkFromKey( &g_stRefLinkTable, p_szRefName );
							if (p_stRefValue->eState == SCR_ELS_Link_NotInitialized)
							{
								p_stRefValue->eState = SCR_ELS_Link_Initialized;
								p_stRefValue->stInfos.ulLong1 = 1;
							}
							else
							{
								p_stRefValue->stInfos.ulLong1++;
							}
							SCR_M_DyAr_AddElement( tdstReference, uiPos, p_stRef, (*p_stDyAr) );
							p_stRef->uiLine = p_stContext->stPosition.uiLineInFile;
							p_stRef->p_stRef = p_stRefValue;
						}
						cIndex ++;
						szParam += strlen( szParam ) + 1;
					}
				}
			}
		}
	} while(iRead != EOF);

	SCR_fn_v_RdL0_DeleteOpenFile( _p_szFileName, SCR_CDR_c_RdL0_Match );

    /*
     *  Delete context. It's finish...
     */
    fn_v_Cxt_DeleteLast();
}

/*
 *-------------------------------------------------------------------------------------------------
 *  parse a file to get all sections and references
 *  _p_szFileName   :   file name
 *-------------------------------------------------------------------------------------------------
 */
void fn_Scr_vNewParseFileToBuildListOfSectionsAndRefs( char *_szFileName, SCR_tdst_Link_Value *_p_stLVFile )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_tdst_Link_Table			*p_stLTSection;
	SCR_tdst_Cxt_Description    *p_stContext;
    int                         iRead;
	int							cIndent = -1;
	char						*a_szSectionName[ 16 ];
	char						szSectionName[ SCR_CV_ui_Cfg_MaxLenName ];
	SCR_tdst_Link_Value			*a_p_stSection[ 16 ];
	SCR_tdst_Link_Value			*p_stSectionType;
	SCR_tdst_Link_Value			*p_stRefValue;
	SCR_tdst_DyAr_Description	*p_stSectionEntryDyAr;
	tdstEntry					*p_stEntry;
	SCR_tdst_DyAr_Description	*p_stDyAr;
	unsigned int				uiPos;
	tdstReference				*p_stRef;
	char						cRef, cIndex;
	char						*szParam;
	char						*szRefFileName;
	char						szRefName[ SCR_CV_ui_Cfg_MaxLenName ], *p_szRefName, *p_szEndRefFileName;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//    SCR_M_Dbg_Assert_D(_p_szFileName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
     *  One more context.
     */
    p_stContext = fnp_st_Cxt_Add();

    /*
     *  Open the file.
     */
    p_stContext->p_stOpenFile = fnp_st_File_OpenFile(_szFileName);

	cIndent = -1;

	szRefFileName = _szFileName + g_stIniData.lRootForSectionLength;
	p_szEndRefFileName = szRefFileName + strlen( szRefFileName );
	//strcpy( szSectionName, szRefFileName );
	a_szSectionName[ 0 ] = szSectionName;// + ( p_szEndRefFileName - szRefFileName );
	
	p_stLTSection = (SCR_tdst_Link_Table *) _p_stLVFile->ulValue;
    /*
     *  Place file to its SCR_BEGINing.
     *  Parse to the end.
     */
    fn_v_Anl_ContextToFile(p_stContext);
    do
    {
		iRead = fn_Scr_iLineToContext( p_stContext );

		if ( p_stContext->eParseType == SCR_EPT_Cxt_BeginSection )
		{
			if (p_stLTSection == NULL)
			{
				p_stLTSection = (SCR_tdst_Link_Table *) malloc (sizeof( SCR_tdst_Link_Table) );
				SCR_fn_v_Link_InitTable( p_stLTSection );
				_p_stLVFile->ulValue = (unsigned long) p_stLTSection;
			}

			cIndent++;
			/*
			 * get section type
			 */
			p_stSectionType = SCR_fnp_st_Link_SearchKey( &g_stSectionTypeLinkTable, p_stContext->stBuffers.a_szBufferName );

			/*
			 * build full section name
			 */
			if (cIndent)
			{
				*a_szSectionName[ cIndent ] = SCR_CC_c_Cfg_NameSeparator;
				strcpy( a_szSectionName[ cIndent ] + 1, p_stContext->stBuffers.a_szBufferName );
			}
			else
			{
				strcpy( a_szSectionName[ 0 ], p_stContext->stBuffers.a_szBufferName );
			}
			a_szSectionName[ cIndent + 1 ] = a_szSectionName[ cIndent ] + strlen( a_szSectionName[ cIndent ] );
			if ( *p_stContext->stBuffers.a_szBufferNameExt)
			{
				*a_szSectionName[cIndent + 1]++ = SCR_CC_c_Cfg_SectionIdMark;
				strcpy (a_szSectionName[cIndent + 1], p_stContext->stBuffers.a_szBufferNameExt );
				a_szSectionName[ cIndent + 1 ] += strlen( a_szSectionName[ cIndent + 1 ] );
			}

			/*
			 * get or create section link value
			 */
			//a_p_stSection[ cIndent ] = SCR_fnp_st_Link_CreateOrGetLinkFromKey( &g_stSectionLinkTable, szSectionName );
			a_p_stSection[ cIndent ] = SCR_fnp_st_Link_CreateOrGetLinkFromKey( p_stLTSection, szSectionName );
			if (a_p_stSection[ cIndent ]->eState == SCR_ELS_Link_NotInitialized)
			{
				a_p_stSection[ cIndent ]->eState = SCR_ELS_Link_Initialized;
				a_p_stSection[ cIndent ]->stInfos.ulLong1 = p_stContext->stPosition.uiLineInFile;
				a_p_stSection[ cIndent ]->stInfos.ulLong2 = 0;

				if (p_stSectionType->stInfos.ulLong2)
				{
					a_p_stSection[ cIndent ]->stInfos.ulLong3 = (unsigned long) p_stSectionType;
					p_stDyAr = (SCR_tdst_DyAr_Description *) malloc( sizeof(SCR_tdst_DyAr_Description) );
					fn_v_DyAr_InitArray( p_stDyAr );
					a_p_stSection[ cIndent ]->ulValue = (unsigned long) p_stDyAr;
				}
				else
					a_p_stSection[ cIndent ]->ulValue = 0;
			}
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_EndSection )
		{
			*a_szSectionName[ cIndent ] = 0;
			cIndent--;
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_Entry )
		{
			if ( (cIndent >=0) && (a_p_stSection[ cIndent ]->ulValue ) )
			{
				p_stSectionType = (SCR_tdst_Link_Value *) a_p_stSection[ cIndent ]->stInfos.ulLong3;
				p_stSectionEntryDyAr = (SCR_tdst_DyAr_Description *) p_stSectionType->ulValue;
				if ( (p_stEntry = fn_Scr_p_stFindEntry( p_stSectionEntryDyAr, p_stContext->stBuffers.a_szBufferNameExt )) != NULL)
				{
					p_stDyAr = (SCR_tdst_DyAr_Description *) a_p_stSection[ cIndent ]->ulValue;
					cRef = p_stEntry->cNumberOfRefs;
					cIndex = 0;
					szParam = p_stContext->stBuffers.a_szBufferParams;
					while (cRef)
					{
						if ( p_stEntry->a_cIsRef[ cIndex ] )
						{
							cRef--;
							
							if ( p_stEntry->a_cIsRef[cIndex] == 1)
							{
								if (*szParam == '*')
								{
									p_szRefName = szRefFileName;
									strcpy( p_szEndRefFileName, szParam + 1);
								}
								else
								{	
									p_szRefName = szParam;
								}
							}
							else
							{
								p_szRefName = strcpy( szRefName, szParam );
								fn_SpRef_vTransformSpecialRef( p_stSectionType->p_szKey, p_stEntry->szName, cIndex, szRefName );							
							}

							p_stRefValue = SCR_fnp_st_Link_CreateOrGetLinkFromKey( &g_stRefLinkTable, p_szRefName );
							if (p_stRefValue->eState == SCR_ELS_Link_NotInitialized)
							{
								p_stRefValue->eState = SCR_ELS_Link_Initialized;
								p_stRefValue->stInfos.ulLong1 = 1;
							}
							else
							{
								p_stRefValue->stInfos.ulLong1++;
							}
							SCR_M_DyAr_AddElement( tdstReference, uiPos, p_stRef, (*p_stDyAr) );
							p_stRef->uiLine = p_stContext->stPosition.uiLineInFile;
							p_stRef->p_stRef = p_stRefValue;
						}
						cIndex ++;
						szParam += strlen( szParam ) + 1;
					}
				}
			}
		}
	} while(iRead != EOF);

	SCR_fn_v_RdL0_DeleteOpenFile( _szFileName, SCR_CDR_c_RdL0_Match );

    /*
     *  Delete context. It's finish...
     */
    fn_v_Cxt_DeleteLast();
}


/*
 *-------------------------------------------------------------------------------------------------
 *  init a stat structure
 *  _p_szFileName   :   file name
 *-------------------------------------------------------------------------------------------------
 */
void fn_Scr_vInitStat( tdstScriptStat *_stStat )
{
	memset( _stStat, 0, sizeof( tdstScriptStat ) );

	_stStat->ulSectionNameMinLength = 0xFFFFFF;
	_stStat->ulEntryMinLength = 0xFFFFFF;;
}

/*
 *-------------------------------------------------------------------------------------------------
 *  parse a file to get stats on scripts
 *  _p_szFileName   :   file name
 *-------------------------------------------------------------------------------------------------
 */
void fn_Scr_vParseFileForStat(char *_p_szFileName, tdstScriptStat *_stStat )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_tdst_Cxt_Description    *p_stContext;
	unsigned long				ulLength;
    int                         iRead;
	char						*szParam;
	char						cParam;
	unsigned long				ulNumberOfSections = 0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_D(_p_szFileName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
     *  One more context.
     */
    p_stContext = fnp_st_Cxt_Add();

    /*
     *  Open the file.
     */
    p_stContext->p_stOpenFile = fnp_st_File_OpenFile(_p_szFileName);

	_stStat->ulNbFiles++;
	
    /*
     *  Place file to its SCR_BEGINing.
     *  Parse to the end.
     */
    fn_v_Anl_ContextToFile(p_stContext);
    do
    {
		iRead = fn_Scr_iLineToContext( p_stContext );

		if ( p_stContext->eParseType == SCR_EPT_Cxt_BeginSection )
		{
			_stStat->ulNbBeginSectionLines++;
			ulNumberOfSections++;

			ulLength = strlen( p_stContext->stBuffers.a_szBufferName );
			if (ulLength > _stStat->ulSectionNameMaxLength)
			{
				_stStat->ulSectionNameMaxLength = ulLength;
				strcpy( _stStat->szSectionNameMax, p_stContext->stBuffers.a_szBufferName );
			}
			if (ulLength < _stStat->ulSectionNameMinLength)
			{
				_stStat->ulSectionNameMinLength = ulLength;
				strcpy( _stStat->szSectionNameMin, p_stContext->stBuffers.a_szBufferName );
			}
			
			ulLength = strlen( p_stContext->stBuffers.a_szBufferNameExt );
			_stStat->fSectionExtAverageLength = (_stStat->fSectionExtAverageLength * (_stStat->ulNbBeginSectionLines - 1) + ulLength) / _stStat->ulNbBeginSectionLines;
			if (ulLength > _stStat->ulSectionExtMaxLength)
			{
				_stStat->ulSectionExtMaxLength = ulLength;
				strcpy( _stStat->szSectionExtMax, p_stContext->stBuffers.a_szBufferNameExt );
			}

			ulLength = strlen( p_stContext->stBuffers.a_szBufferFormat );
			if (ulLength > _stStat->ulFormatMaxLength)
				_stStat->ulFormatMaxLength = ulLength;

			szParam = p_stContext->stBuffers.a_szBufferParams;
			cParam = 0;
			ulLength = 0;
			while (szParam[ulLength] != 0)
			{
				cParam++;
				ulLength += strlen( &szParam[ulLength] ) + 1;
			}
			ulLength ++;
			if (cParam > _stStat->cMaxParams)
				_stStat->cMaxParams = cParam;
			if (ulLength > _stStat->ulParamsMaxLength)
				_stStat->ulParamsMaxLength = ulLength;
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_EndSection )
		{
			_stStat->ulNbEndSectionLines++;
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_Directive )
		{
			_stStat->ulNbDirectiveLines++;
		}
		else if ( p_stContext->eParseType == SCR_EPT_Cxt_Entry )
		{
			_stStat->ulNbEntryLines++;

			ulLength = strlen( p_stContext->stBuffers.a_szBufferNameExt );
			if (ulLength > _stStat->ulEntryMaxLength)
			{
				_stStat->ulEntryMaxLength = ulLength;
				strcpy( _stStat->szEntryMax, p_stContext->stBuffers.a_szBufferNameExt );
			}
			if (ulLength < _stStat->ulEntryMinLength)
			{
				_stStat->ulEntryMinLength = ulLength;
				strcpy( _stStat->szEntryMin, p_stContext->stBuffers.a_szBufferNameExt );
			}

			ulLength = strlen( p_stContext->stBuffers.a_szBufferFormat );
			if (ulLength > _stStat->ulFormatMaxLength)
				_stStat->ulFormatMaxLength = ulLength;

			szParam = p_stContext->stBuffers.a_szBufferParams;
			cParam = 0;
			ulLength = 0;
			while (szParam[ulLength] != 0)
			{
				cParam++;
				ulLength += strlen( &szParam[ulLength] ) + 1;
			}
			ulLength ++;
			if (cParam > _stStat->cMaxParams)
				_stStat->cMaxParams = cParam;
			if (ulLength > _stStat->ulParamsMaxLength)
				_stStat->ulParamsMaxLength = ulLength;
		}
	} while(iRead != EOF);

	if (ulNumberOfSections > _stStat->ulNbMaxSectionInAFile)
	{
		_stStat->ulNbMaxSectionInAFile = ulNumberOfSections;
		strcpy( _stStat->szFileWithMaxSection, _p_szFileName );
	}

	_stStat->ulNbLines += p_stContext->stPosition.uiLineInFile;
	_stStat->ulNbChars += p_stContext->stPosition.lAfterSeekInFile;
	
	ulLength = p_stContext->stPosition.lAfterSeekInFile;
	if (ulLength > _stStat->ulMaxSize)
	{
		_stStat->ulMaxSize = ulLength;
		strcpy( _stStat->szBiggestFile, _p_szFileName );
	}

	SCR_fn_v_RdL0_DeleteOpenFile( _p_szFileName, SCR_CDR_c_RdL0_Match );

    /*
     *  Delete context. It's finish...
     */
    fn_v_Cxt_DeleteLast();
}

/*
 *-------------------------------------------------------------------------------------------------
 *  parse a file to get stats on mod files
 *  _p_szFileName   :   file name
 *-------------------------------------------------------------------------------------------------
 */
void fn_Scr_vInitModStat( tdstModStat *_pst_Stat )
{
    memset( _pst_Stat, 0, sizeof( tdstModStat ) );
    _pst_Stat->ulMinPoints  = 0xFFFFFF;
    _pst_Stat->ulMinEdges   = 0xFFFFFF;
    _pst_Stat->ulMinElement = 0xFFFFFF;
}

/*
 *-------------------------------------------------------------------------------------------------
 *  parse a file to get stats on mod files
 *  _p_szFileName   :   file name
 *-------------------------------------------------------------------------------------------------
 */
void fn_Scr_vParseFileToCountModData( char *_sz_FileName, tdstModStat *_pst_Stat )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_tdst_Cxt_Description    *p_stContext;
	unsigned long				ulLength;
    int                         iRead;
	char						*szParam;
	char						cParam;
	unsigned long				ulNumberOfSections = 0;
    unsigned long               ulValue;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_D(_sz_FileName != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/*
     *  One more context.
     */
    p_stContext = fnp_st_Cxt_Add();

    /*
     *  Open the file.
     */
    p_stContext->p_stOpenFile = fnp_st_File_OpenFile(_sz_FileName);

    /*
     *  Place file to its SCR_BEGINing.
     *  Parse to the end.
     */
    fn_v_Anl_ContextToFile(p_stContext);
    do
    {
		iRead = fn_Scr_iLineToContext( p_stContext );

		if ( p_stContext->eParseType == SCR_EPT_Cxt_BeginSection )
		{
            if ( stricmp( p_stContext->stBuffers.a_szBufferName, "Geometric" ) == 0)
            {
                _pst_Stat->ulNumber++;

			    szParam = p_stContext->stBuffers.a_szBufferParams;
                if (szParam)
                {
                    ulValue = (unsigned long) atoi( szParam );
                    if (_pst_Stat->ulMaxPoints < ulValue )
                        _pst_Stat->ulMaxPoints = ulValue;
                    if (_pst_Stat->ulMinPoints > ulValue )
                        _pst_Stat->ulMinPoints = ulValue;
                }
                
                szParam += strlen( szParam ) + 1;
                if (szParam)
                {
                    ulValue = atoi( szParam );
                    if (_pst_Stat->ulMaxEdges < ulValue )
                        _pst_Stat->ulMaxEdges = ulValue;
                    if (_pst_Stat->ulMinEdges > ulValue )
                        _pst_Stat->ulMinEdges = ulValue;
                }

                szParam += strlen( szParam ) + 1;
                if (szParam)
                {
                    ulValue = atoi( szParam );
                    if (_pst_Stat->ulMaxElement < ulValue )
                        _pst_Stat->ulMaxElement = ulValue;
                    if (_pst_Stat->ulMinElement > ulValue )
                        _pst_Stat->ulMinElement = ulValue;
                }
            }
		}

    } while(iRead != EOF);

	SCR_fn_v_RdL0_DeleteOpenFile( _sz_FileName, SCR_CDR_c_RdL0_Match );

    /*
     *  Delete context. It's finish...
     */
    fn_v_Cxt_DeleteLast();
}


