/*
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 *  SCR_Pars.c
 *  Parse a line.
 *
 *  Scripts, Beaudet Christophe
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 */
 
/*
 *=================================================================================================
 *  Includes.
 *=================================================================================================
 */
 
#include <memory.h>
#include "SCR.h"
 
/*
 *=================================================================================================
 *  Global variables.
 *=================================================================================================
 */
 
#define		CAM_C_SizeParamBuffer		SCR_CV_ui_Cfg_MaxNumPars * SCR_CV_ui_Cfg_MaxLenLine * 4
/*
 *	A global array to receive parameters.
 */
char	gs_a_cBufferForParameters[CAM_C_SizeParamBuffer];
char	*gs_p_cNewFreePlace = gs_a_cBufferForParameters;
 
/*
 *	A macro to allocate a parameter.
 */
#define SCR_M_Pars_AllocParam(_Cast, _p_xPointer, _uiSize)\
{\
	_p_xPointer = gs_p_cNewFreePlace;\
	gs_p_cNewFreePlace += (_uiSize * sizeof(_Cast));\
	if(gs_p_cNewFreePlace >= &gs_a_cBufferForParameters[CAM_C_SizeParamBuffer])\
	{\
        strcpy(g_st_Err_GlobalError.a_szBufferTmp1, "Buffer for parameters is too small.\n");\
        strcpy(g_st_Err_GlobalError.a_szBufferTmp2, "It must be increased, so contact CB.\n");\
        SCR_M_Err_RaiseError(SCR_EI_Err_NotEnoughMemory);\
	}\
}
 
/*
 *  Valid characters in a word.
 */
char gs_a256_cIsCharValidForWord[256] =
{
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    /*!*/1,0,/*#*/1,/*$*/1,/*%*/1,/*&*/1,0,0,0,/***/1,/*+*/1,0,/*-*/1,0,0,
    /*0*/1,1,1,1,1,1,1,1,1,1/*9*/,
    0,0,/*<*/1,/*=*/1,/*>*/1,/*?*/1,0,
    /*A*/1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1/*Z*/,
    0,/*\*/1,0,0,/*_*/1,0,
    /*a*/1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1/*z*/,
    0,/*|*/1,0,/*~*/1,0,
 
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
};
 
/*
 *  To count number of read characters.
 */
unsigned int	SCR_g_ui_Pars_NbRead = 0;
 
/*
 *=================================================================================================
 *  Functions.
 *=================================================================================================
 */
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To get a word.
 *  _p_stFile   :   File to read from.
 *  _p_stDest   :   To receive word
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_Word(SCR_tdst_File_Description *_p_stFile, char *_p_szDest)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int     iRead = 0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_p_szDest != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*
     *  Read a character until it is not valid.
     */
    while(iRead != EOF)
    {
        SCR_M_Pars_ReadChar(_p_stFile, iRead);
        if((iRead == EOF) || (gs_a256_cIsCharValidForWord[iRead] == 0))
            break;
        *_p_szDest++ = (char) iRead;
    }
    *_p_szDest = '\0';
 
    /*
     *  Zap eventual blanks after word.
     */ 
	SCR_M_Pars_ZapIfSpace(_p_stFile, iRead);
    return iRead;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To parse a section name.
 *  _p_stFile   :   File to read from.
 *  _p_szAction :   To receive action part of name.
 *  _p_szId     :   To receive ID part of name.
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_SectionName
(
    SCR_tdst_File_Description   *_p_stFile, 
    char                        *_p_szAction,
    char                        *_p_szId
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int     iRead;
    char    *p_szTmpAction;
    char    *p_szTmpId;
	char	cIdPart = 0;	
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_p_szAction != NULL);
    SCR_M_Dbg_Assert_P(_p_szId != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    p_szTmpAction = _p_szAction;
    p_szTmpId = _p_szId;			/* Save begin section mark */
 
    SCR_M_Pars_ReadChar(_p_stFile, iRead);
 
    /*
     *  Action part.
     */
    while((iRead != EOF) && (gs_a256_cIsCharValidForWord[iRead]))
    {
        *p_szTmpAction++ = (char) iRead;
        SCR_M_Pars_ReadChar(_p_stFile, iRead);
    }
    if(iRead == SCR_CC_c_Cfg_SectionIdMark)
		cIdPart = 1;
	else if
	(
		(iRead != '\n')
	&&	(iRead != '\r')
	&&	(iRead != EOF)
	&&	!(SCR_M_Pars_IsSpace(iRead))
	&&	(iRead != SCR_CC_c_Cfg_FormatBegMark)
	&&	(iRead != SCR_CC_c_Cfg_ParamBegMark)
	)
    {
        SCR_M_Err_UpdateSyntaxError();
        *p_szTmpAction = '\0';
        sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Section name is \"%s\".", _p_szAction);
        SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndSectionMark);
    }
 
	/*
	 *  Id part
	 */
	if(cIdPart)
	{
		SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
		while((iRead != EOF) && (gs_a256_cIsCharValidForWord[iRead]))
		{
			*p_szTmpId ++ = (char) iRead;
			SCR_M_Pars_ReadChar(_p_stFile, iRead);
		}
	}
 
    /*
     *  End. Zap eventual spaces after the section name.
     */
    *p_szTmpAction = '\0';
    *p_szTmpId = '\0';
 
	SCR_M_Pars_ZapIfSpace(_p_stFile, iRead);
 
    return iRead;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To parse an array format. Parameters are not convert here.
 *  _p_stFile   :   File to read from.
 *  _pp_szDest  :   To receive the format.
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_FormatArray(SCR_tdst_File_Description *_p_stFile, char **_pp_szDest)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int		iRead;
    char    *p_szFirst;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_pp_szDest != NULL);
    SCR_M_Dbg_Assert_P(*_pp_szDest != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*
     *  Copy array marker SCR_C_c_Cfg_FormatArray in buffer, and read following character.
     */
    p_szFirst = *_pp_szDest;
    *(*_pp_szDest)++ = SCR_CF_c_Cfg_FormatArray;
    SCR_M_Pars_ReadChar(_p_stFile, iRead);
 
    /* Copy array format in buffer */
    *(*_pp_szDest)++ = (char) iRead;
 
    /*
     *  Parse all sorts of array.
     */
    switch(iRead)
    {
    case SCR_CF_c_Cfg_FormatArrayByte:
    case SCR_CF_c_Cfg_FormatArrayShort:
    case SCR_CF_c_Cfg_FormatArrayLong:
    case SCR_CF_c_Cfg_FormatArrayInt:
    case SCR_CF_c_Cfg_FormatArrayFloat:
    case SCR_CF_c_Cfg_FormatArrayDouble:
    case SCR_CF_c_Cfg_FormatArrayBoolean:
    case SCR_CF_c_Cfg_FormatArrayDisEna:
    case SCR_CF_c_Cfg_FormatArrayReferences:
 
        /* Verify that the following character is the end format marker */
        SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
        if(iRead != SCR_CC_c_Cfg_FormatEndMark)
        {
            SCR_M_Err_UpdateSyntaxError();
            *(*_pp_szDest) = '\0';
            sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Format is \"%s\".", p_szFirst);
            SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndFormatMark);
        }
        *(*_pp_szDest)++ = '\0';
 
        /* Read character after end format marker */
        SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
        return iRead;
	}
 
    /* Default : Bad array specified */
    SCR_M_Err_UpdateSyntaxError();
    *(*_pp_szDest)++ = '\0';
    sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Format is \"%s\".", p_szFirst);
    SCR_M_Err_RaiseError(SCR_EI_Err_UnknownFormat);
	return 0;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To parse a scanf format. Parameters are not convert here.
 *  _p_stFile   :   File to read from.
 *  _pp_szDest  :   To receive the format.
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_FormatScanf(SCR_tdst_File_Description *_p_stFile, char **_pp_szDest)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int		iRead;
    char    *p_szFirst;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_pp_szDest != NULL);
    SCR_M_Dbg_Assert_P(*_pp_szDest != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*
     *  Copy scanf format SCR_C_c_Cfg_FormatScanf in buffer, and read following character.
     */
    p_szFirst = *_pp_szDest;
    *(*_pp_szDest)++ = SCR_CF_c_Cfg_FormatScanf;
    SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
 
    /*
     *  Parsing.
     *  Format is scanf + SCR_CC_c_Cfg_ScanfSeparator + scanf +...
     *  Each SCR_CC_c_Cfg_ScanfSeparator is replaced with an '\0'.
     */
    while((iRead != SCR_CC_c_Cfg_FormatEndMark) && (iRead != '\n') && (iRead != (char) EOF))
    {
        if(iRead == SCR_CF_c_Cfg_ScanfSeparator)
            *(*_pp_szDest)++ = '\0';
        else
            *(*_pp_szDest)++ = (char) iRead;
        SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
    }
 
    /*
     *  And of scanf string format.
     *  We verify that there's a end format character.
     */
    *(*_pp_szDest) = '\0';
    if(iRead != SCR_CC_c_Cfg_FormatEndMark)
    {
        SCR_M_Err_UpdateSyntaxError();
        sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Format is \"%s\".", p_szFirst);
        SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndFormatMark);
    }
    *(*_pp_szDest)++ = '\0';
 
    /*
     *  Get next character and zap eventual spaces.
     */
    SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
    return iRead;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To parse a string format. Parameters are not convert here.
 *  _p_stFile   :   File to read from.
 *  _p_szDest   :   To receive the format.
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_Format(SCR_tdst_File_Description *_p_stFile, char *_p_szDest)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int     iRead;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_p_szDest != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*
     *  Get first character.
     */
    SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
 
    switch(iRead)
    {
    /* An array */
    case SCR_CF_c_Cfg_FormatArray:
        iRead = fn_i_Pars_FormatArray(_p_stFile, &_p_szDest);
        break;
 
    /* A scanf format */
    case SCR_CF_c_Cfg_FormatScanf:
        iRead = fn_i_Pars_FormatScanf(_p_stFile, &_p_szDest);
        break;
 
    /* Else error */
    default:
        SCR_M_Err_UpdateSyntaxError();
        sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Format is \"%c\".", iRead);
        SCR_M_Err_RaiseError(SCR_EI_Err_UnknownFormat);
    }
 
    /*
     *  End. Force last character of buffer to be an '\0'.
     */
    *_p_szDest = '\0';    
    return iRead;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To parse a list of parameters.
 *  _p_stFile   :   File to read from.
 *  _p_szDest   :   To receive the list of all parameters.
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_Parameters(SCR_tdst_File_Description *_p_stFile, char *_p_szDest)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int                         iRead = 0;
    char                        *p_szFirst;
    char                        a_szTemp[SCR_CV_ui_Cfg_MaxLenVarName];
    SCR_tdst_Vars_Description   *p_stVar;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_p_szDest != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    while(1)
    {
        SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
 
        /* 
         *  End of parameter list 
		 *	We save a space if there's a separator without a parameter.
         */
        if(iRead == SCR_CC_c_Cfg_ParamEndMark)
        {
			if(_p_szDest[-1] == '\0')
				*_p_szDest++ = SCR_CC_C_Cfg_EmptyParameter;
            *_p_szDest++ = '\0';
            SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
            break;
        }
 
        switch(iRead)
        {
        /* 
         *  End of this parameter. Save '\0' in dest. 
		 *	We save a space if there's a separator without a parameter.
         */
        case SCR_CC_c_Cfg_ParamSeparator:
			if(_p_szDest[-1] == '\0')
				*_p_szDest++ = SCR_CC_C_Cfg_EmptyParameter;
            *_p_szDest++ = '\0';
            break;
 
        /* 
         *  A string marker: We zap the two SCR_C_c_Cfg_StringMark.
         */
        case SCR_CC_c_Cfg_StringMark:
 
            /* We zap string markers */
            p_szFirst = _p_szDest;
            SCR_M_Pars_ReadChar(_p_stFile, iRead);
            while((iRead != EOF) && (iRead != SCR_CC_c_Cfg_StringMark) && (iRead != '\n'))
            {
                *_p_szDest++ = (char) iRead;
                SCR_M_Pars_ReadChar(_p_stFile, iRead);
            }
 
            /* Verify that last character is the string marker too */
            if(iRead != SCR_CC_c_Cfg_StringMark)
            {
                SCR_M_Err_UpdateSyntaxError();
                *_p_szDest = '\0';
                sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "String is \"%s\".", p_szFirst);
                SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndStringMark);
            }
            break;
 
        /* 
         *  A variable mark. Try to replace with its value.
         */
        case SCR_CC_c_Cfg_VarMark:
        {
            /* Get variable name and verify that last character is variable marker */
            p_szFirst = _p_szDest;
            iRead = fn_i_Pars_Word(_p_stFile, a_szTemp);
            if(iRead != SCR_CC_c_Cfg_VarMark)
            {
                SCR_M_Err_UpdateSyntaxError();
                sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Variable is \"%s\".", a_szTemp);
                SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndVarMark);
            }
            /* Search variable and replace with its value (error if it not exists */
            p_stVar = fnp_st_Vars_Search(a_szTemp);
            if(p_stVar)
            {
                strcpy(_p_szDest, p_stVar->a_szVarValue);
                _p_szDest += strlen(_p_szDest);
            }
            else
            {
                SCR_M_Err_UpdateSyntaxError();
                sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Variable is \"%s\".", a_szTemp);
                SCR_M_Err_RaiseError(SCR_EI_Err_UnknownVariable);
            }
            break;
        }
 
        /* 
         *  End of line or file : Error 
         */
        case '\n':
        case EOF:
            SCR_M_Err_UpdateSyntaxError();
            SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndParamsMark);
 
        /* 
         *  The rest. Save character. 
         */
        default:
            *_p_szDest++ = (char) iRead;
            break;
        }
    }
 
    /* Two '\0' to mark the last parameter */
    *_p_szDest = '\0';    
 
    /* Zap spaces after the parameters */
	SCR_M_Pars_ZapIfSpace(_p_stFile, iRead);
 
    return iRead;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To parse format and a list of parameters.
 *  _p_stFile   :   File to read from.
 *  iRead       :   Current character read.
 *  _p_szFormat :   To receive Format.
 *  _p_szParam  :   To receive list of parameters.
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_FormatParameters
(
    SCR_tdst_File_Description   *_p_stFile, 
    int                         iRead,
    char                        *_p_szFormat,
    char                        *_p_szParam
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_p_szFormat != NULL);
    SCR_M_Dbg_Assert_P(_p_szParam != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* 
     *  Format of parameters ?
     */
    if(iRead == SCR_CC_c_Cfg_FormatBegMark)
    {
        iRead = fn_i_Pars_Format(_p_stFile, _p_szFormat);
    }
 
	/*
	 *	A post format.
	 *	Post format is not read by script parser but is for external use only.
	 */
    if(iRead == SCR_CC_c_Cfg_PostFormatBegMark)
	{
		SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
		while
		(
			(iRead != '\n') 
		&&	(iRead != EOF) 
		&&	(iRead != SCR_CC_c_Cfg_PostFormatEndMark)
		)
		{
			SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
		}
		if(iRead != SCR_CC_c_Cfg_PostFormatEndMark)
		{
	        SCR_M_Err_UpdateSyntaxError();
			SCR_M_Err_RaiseError(SCR_EI_Err_MissingEndPostFormatMark);
		}
		SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
	}
 
    /* 
     *  Parameters ?
     */
    if(iRead == SCR_CC_c_Cfg_ParamBegMark)
    {
        iRead = fn_i_Pars_Parameters(_p_stFile, _p_szParam);
    }
 
    /*
     *  Error if format without parameters.
     */
    if((*_p_szFormat) && (!*_p_szParam))
    {
        SCR_M_Err_UpdateSyntaxError();
        SCR_M_Err_RaiseError(SCR_EI_Err_MissingParameters);
    }
 
    /* 
     *  End. We are normally at the end of a line or at the end of file.
     *  If not : There's dummy character at the end of line.
     */
    if((iRead != '\n') && (iRead != EOF))
    {
        SCR_M_Err_UpdateSyntaxError();
        SCR_M_Err_RaiseError(SCR_EI_Err_CorruptEndOfLine);
    }
 
    /* Return last character read */
    return iRead;
}
 
/*===============================================================================================*/
 
/*
 *-------------------------------------------------------------------------------------------------
 *  To parse a line of file.
 *  _p_stFile       :   File to read from.
 *  _p_szKeyword1   :   To receive section action name, directive, end section.
 *  _p_szKeyword2   :   To receive section id name or entry.
 *  _p_szKeyword3   :   To receive format
 *  _p_szKeyword4   :   To receive list of parameters
 *  _p_eParseType   :   To receive the type of the word parsed
 *  _p_uiNbRead     :   To return number of characters read
 *  Returns EOF in case of end of file, else returns last character read.
 *-------------------------------------------------------------------------------------------------
 */
int fn_i_Pars_Line
(
    SCR_tdst_File_Description   *_p_stFile,
    char                        *_p_szKeyword1,
    char                        *_p_szKeyword2,
    char                        *_p_szKeyword3,
    char                        *_p_szKeyword4,
    SCR_tde_Cxt_ParseType       *_p_eParseType,
    unsigned int                *_p_uiNbRead
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int     iRead;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_stFile != NULL);
    SCR_M_Dbg_Assert_P(_p_szKeyword1 != NULL);
    SCR_M_Dbg_Assert_P(_p_szKeyword2 != NULL);
    SCR_M_Dbg_Assert_P(_p_szKeyword3 != NULL);
    SCR_M_Dbg_Assert_P(_p_szKeyword4 != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    *_p_szKeyword1 = '\0';
    *_p_szKeyword2 = '\0';
    *_p_szKeyword3 = '\0';
    *_p_szKeyword4 = '\0';
 
    /*
     *  Place number of characters read to 0.
     */
    SCR_g_ui_Pars_NbRead = 0;
 
    /* 
     *  Get a character.
     */
    SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
    switch(iRead)
    {
    /*
     *  A begin of section.
     */
    case SCR_CC_c_Cfg_SectionBegMark:
 
        /* Get section name (action + id) */
        iRead = fn_i_Pars_SectionName(_p_stFile, _p_szKeyword1, _p_szKeyword2);
 
        /* Get eventual format and parameters of section */
        iRead = fn_i_Pars_FormatParameters(_p_stFile, iRead, _p_szKeyword3, _p_szKeyword4);
 
        *_p_eParseType = SCR_EPT_Cxt_BeginSection;
        *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
        break;
 
    /* 
     *  A end of section.
     */
    case SCR_CC_c_Cfg_SectionEndMark:
 
        /* Get next character */
        SCR_M_Pars_GetNextNonSpaceChar(_p_stFile, iRead);
 
        /* Get eventual format and parameters of end of section */
        iRead = fn_i_Pars_FormatParameters(_p_stFile, iRead, _p_szKeyword3, _p_szKeyword4);
 
        *_p_eParseType = SCR_EPT_Cxt_EndSection;
        *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
        break;
 
    /* 
     *  End of file or line. Terminate parsing.
     */
    case EOF:
    case '\n':
        *_p_eParseType = SCR_EPT_Cxt_None;
        *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
        break;
 
    /* 
     *  A comment. Zap all line.
     */
    case SCR_CC_c_Cfg_CommentMark:
    case SCR_CC_c_Cfg_CommentMark1:
        SCR_M_Pars_ReadChar(_p_stFile, iRead);
        while((iRead != '\n') && (iRead != EOF))
        {
            SCR_M_Pars_ReadChar(_p_stFile, iRead);
        }
        *_p_eParseType = SCR_EPT_Cxt_None;
        *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
        break;
 
    /* 
     *  A script directive.
     */
    case SCR_CC_c_Cfg_DirectiveMark:
 
        /* Get directive word */
        iRead = fn_i_Pars_Word(_p_stFile, _p_szKeyword1);
 
        /* Mark without word : Error */
        if(*_p_szKeyword1 == '\0')
        {
            SCR_M_Err_UpdateSyntaxError();
            SCR_M_Err_RaiseError(SCR_EI_Err_MissingDirectiveName);
        }
 
        /* Get eventual format and parameters of directive */
        iRead = fn_i_Pars_FormatParameters(_p_stFile, iRead, _p_szKeyword3, _p_szKeyword4);
 
        *_p_eParseType = SCR_EPT_Cxt_Directive;
        *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
        break;
 
    /* 
     *  An old section mark.
     */
    case ':':
    {
        char    *p_szTemp;
        iRead = fn_i_Pars_Word(_p_stFile, _p_szKeyword1);
        if((iRead == ':') && (*_p_szKeyword1 == '\0'))
            iRead = fn_i_Pars_Word(_p_stFile, _p_szKeyword1);
 
        /* Is it a end section ? */
        if(!strcmpi(_p_szKeyword1, "EndSection"))
        {
            *_p_eParseType = SCR_EPT_Cxt_EndSection;
            *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
            break;
        }
 
        /* Get id part of section name */
        p_szTemp = _p_szKeyword1;
        while(*p_szTemp == '_')
            p_szTemp++;
        p_szTemp = strchr(p_szTemp, '_');
        if(p_szTemp)
        {
            while(*p_szTemp == '_')
                p_szTemp++;
            if(*p_szTemp != '\0')
            {
                p_szTemp[-1] = '\0';
                strcpy(_p_szKeyword2, p_szTemp);
            }
        }
 
        /* Parse eventual format and parameters of section */
        iRead = fn_i_Pars_FormatParameters(_p_stFile, iRead, _p_szKeyword3, _p_szKeyword4);
 
        /* Type is a begin section */
        *_p_eParseType = SCR_EPT_Cxt_BeginSection;
        *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
        break;
    }
 
    /* 
     *  The rest. Entry or error 
     */
    default:
 
        /* Character read must be a valid one. Error if not */
        if(gs_a256_cIsCharValidForWord[iRead] == 0)
        {
            SCR_M_Err_UpdateSyntaxError();
            sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Character is \"%c\".", iRead);
            SCR_M_Err_RaiseError(SCR_EI_Err_BadCharacter);
        }
 
        /* Save character and parse the following word */
        *_p_szKeyword2++ = (char) iRead;
        iRead = fn_i_Pars_Word(_p_stFile, _p_szKeyword2);
 
        /* Parse eventual format and parameters of entry */
        iRead = fn_i_Pars_FormatParameters(_p_stFile, iRead, _p_szKeyword3, _p_szKeyword4);
 
        *_p_eParseType = SCR_EPT_Cxt_Entry;
        *_p_uiNbRead = SCR_g_ui_Pars_NbRead;
        break;
    }
 
	return iRead;
}
 
/*===============================================================================================*/
 
/*
 *-------------------------------------------------------------------------------------------------
 *  Convert normal parameters to an array of pointers.
 *  _p_szParams         :   Array of parameters to convert.
 *  _ap_szParameters    :   Array to receive parameters.
 *-------------------------------------------------------------------------------------------------
 */
void fn_v_Pars_ConvertNormalParameters(char *_p_szParams, char *_ap_szParameters[])
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned int    uiIndex;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/    
    SCR_M_Dbg_Assert_P(_p_szParams != NULL);
    SCR_M_Dbg_Assert_P(_ap_szParameters != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    uiIndex = 0;
    while(*_p_szParams)
    {
		SCR_M_Pars_AllocParam(char, _ap_szParameters[uiIndex], SCR_CV_ui_Cfg_MaxLenLine);
        strcpy(_ap_szParameters[uiIndex], _p_szParams);
		/* Treat empty parameters */
		if(*_ap_szParameters[uiIndex] == SCR_CC_C_Cfg_EmptyParameter)
			*_ap_szParameters[uiIndex] = '\0';
		uiIndex++;
        _p_szParams += (strlen(_p_szParams) + 1);
    }
    _ap_szParameters[uiIndex] = NULL;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  Convert references array parameters to an array of pointers.
 *  _p_szFormat         :   Format to convert.
 *  _p_szParams         :   Array of parameters to convert.
 *  _ulNumParams        :   Number of parameters.
 *  _ap_szParameters    :   Array to receive parameters.
 *-------------------------------------------------------------------------------------------------
 */
void fn_v_Pars_ConvertArrayRefParameters
(
    char            *_p_szParams,
    unsigned long   _ulNumParams,
    char            *_ap_szParameters[]
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned long           ulIndex;
    unsigned short          uwDynamicFlags;
    char                    *p_szParam1;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_szParams != NULL);
    SCR_M_Dbg_Assert_P(_ap_szParameters != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*
     *  There must have an even number of parameters.
     *  Divide ulNumParams by 2 cause this is the real number of references.
     */
    if((_ulNumParams == 0) || (_ulNumParams & 1))
    {
        SCR_M_Err_UpdateSyntaxError();
        SCR_M_Err_RaiseError(SCR_EI_Err_BadNumParamsAR);
    }
    _ulNumParams >>= 1;
 
    /*
     *  Allocate memory for array.
     */
	SCR_M_Pars_AllocParam(SCR_tdst_Cxt_Values *, _ap_szParameters[1], _ulNumParams);
 
    /* 
     *  Analyse all the reference and get return value.
     */
    for(ulIndex = 0; ulIndex < _ulNumParams; ulIndex++)
    {
        p_szParam1 = _p_szParams + strlen(_p_szParams) + 1;
 
        /* 
         *  Get all dynamic analyse flag.
         */
        uwDynamicFlags = SCR_CDF_uw_Anl_Normal;
        while(*p_szParam1)
        {
            uwDynamicFlags = SCR_CDF_uw_Anl_Normal;
            switch(tolower(*p_szParam1))
            {
            case SCR_CDF_c_Anl_Normal:
                break;
            case SCR_CDF_c_Anl_ForceAnalyse:
                uwDynamicFlags |= SCR_CDF_uw_Anl_ForceAnalyse;
                break;
            default:
                SCR_M_Err_UpdateSyntaxError();
                sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Dynamic flag is \"%c\".", *p_szParam1);
                SCR_M_Err_RaiseError(SCR_EI_Err_UnknownDynamicFlag);
            }
            p_szParam1++;
        }
 
        /* 
         *  Make the analyse and saves the result.
         */
		/*uwDynamicFlags |= SCR_CDF_uw_Anl_WarnIfNotHere;*/
		((SCR_tdst_Cxt_Values **) _ap_szParameters[1])[ulIndex] = 
			SCR_fnp_st_RdL0_AnalyseSection(_p_szParams, uwDynamicFlags);
 
        /* 
         *  Pass to next parameter.
         */
        _p_szParams = p_szParam1 + strlen(p_szParam1) + 1;
    }
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  Convert array parameters to an array of pointers.
 *  _p_szFormat         :   Format to convert.
 *  _p_szParams         :   Array of parameters to convert.
 *  _ap_szParameters    :   Array to receive parameters.
 *-------------------------------------------------------------------------------------------------
 */
#define M_Pars_FillArray(_Cast, _Convert)\
{\
    SCR_M_Pars_AllocParam(_Cast, _ap_szParameters[1], ulNumParams);\
    p_szTemp = _p_szParams;\
    for(ulIndex = 0; ulIndex < ulNumParams; ulIndex++)\
    {\
        ((_Cast *) _ap_szParameters[1])[ulIndex] = (_Cast) _Convert(p_szTemp);\
        p_szTemp += (strlen(p_szTemp) + 1);\
    }\
}
 
/*-----------------------------------------------------------------------------------------------*/
 
#define M_Pars_BoolToChar(_Value)    (!strcmpi(_Value, "FALSE") ? 0 : 1)
#define M_Pars_DEToChar(_Value)      (!strcmpi(_Value, "DISABLE") ? 0 : 1)
 
/*-----------------------------------------------------------------------------------------------*/
 
void fn_v_Pars_ConvertArrayParameters
(
    char *_p_szFormat, 
    char *_p_szParams,
    char *_ap_szParameters[]
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    char            *p_szTemp;
    unsigned long   ulNumParams, ulIndex;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_szFormat != NULL);
    SCR_M_Dbg_Assert_P(_p_szParams != NULL);
    SCR_M_Dbg_Assert_P(_ap_szParameters != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*
     *  Get number of parameters.
     */
    ulNumParams = 0;
    p_szTemp = _p_szParams;
    while(*p_szTemp)
    {
        ulNumParams++;
        p_szTemp += (strlen(p_szTemp) + 1);
    }
 
    /*
     *  Convert array.
     */
    switch(_p_szFormat[1])
    {
    /* Array of byte */
    case SCR_CF_c_Cfg_FormatArrayByte:
        M_Pars_FillArray(char, atol);               
        break;      
 
    /* Array of short */
    case SCR_CF_c_Cfg_FormatArrayShort:
        M_Pars_FillArray(short, atol);              
        break;      
 
    /* Array of long */
    case SCR_CF_c_Cfg_FormatArrayLong:
        M_Pars_FillArray(long, atol);               
        break;  
        
    /* Array of int */
    case SCR_CF_c_Cfg_FormatArrayInt:
        M_Pars_FillArray(int, atoi);                
        break;  
        
    /* Array of float */
    case SCR_CF_c_Cfg_FormatArrayFloat:
        M_Pars_FillArray(float, atof);              
        break;  
        
    /* Array of double */
    case SCR_CF_c_Cfg_FormatArrayDouble:
        M_Pars_FillArray(double, atof);             
        break;  
        
    /* Array of bool */
    case SCR_CF_c_Cfg_FormatArrayBoolean:
        M_Pars_FillArray(char, M_Pars_BoolToChar);  
        break;  
        
    /* Array of dis/ena */
    case SCR_CF_c_Cfg_FormatArrayDisEna:
        M_Pars_FillArray(char, M_Pars_DEToChar);    
        break;  
 
    /* Array of references */
    case SCR_CF_c_Cfg_FormatArrayReferences:
        fn_v_Pars_ConvertArrayRefParameters(_p_szParams, ulNumParams, _ap_szParameters);
        ulNumParams >>= 1;
        break;
    }
 
    /*
     *  First parameter is number of values in array.
     *  Third parameter is NULL.
     */
    SCR_M_Pars_AllocParam(long, _ap_szParameters[0], 1);
    ((long *) _ap_szParameters[0])[0] = ulNumParams;
    _ap_szParameters[2] = NULL;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  Convert scanf parameters to an array of pointers.
 *  _p_szFormat         :   Format to convert.
 *  _p_szParams         :   Array of parameters to convert.
 *  _ap_szParameters    :   Array to receive parameters.
 *-------------------------------------------------------------------------------------------------
 */
void fn_v_Pars_ConvertScanfParameters
(
    char *_p_szFormat, 
    char *_p_szParams,
    char *_ap_szParameters[]
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned long   ulNumFormats, ulNumParams, ulIndex;
    char            *p_szTmpFormat, *p_szTmpParams;
    int             iReturn;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_szFormat != NULL);
    SCR_M_Dbg_Assert_P(_p_szParams != NULL);
    SCR_M_Dbg_Assert_P(_ap_szParameters != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*
     *  Get number of formats.
     */
    ulNumFormats = 0;
    p_szTmpFormat = _p_szFormat;
    while(*p_szTmpFormat)
    {
        ulNumFormats++;
        p_szTmpFormat += (strlen(p_szTmpFormat) + 1);
    }
 
    /*
     *  Get number of parameters.
     */
    ulNumParams = 0;
    p_szTmpParams = _p_szParams;
    while(*p_szTmpParams)
    {
        ulNumParams++;
        p_szTmpParams += (strlen(p_szTmpParams) + 1);
    }
 
    /*
     *  Number of format must be the same that number of parameters.
     */
    if(ulNumFormats != ulNumParams)
    {
        SCR_M_Err_UpdateSyntaxError();
        SCR_M_Err_RaiseError(SCR_EI_Err_BadNumParamsScanf);
    }
 
    /*
     *  Parse each parameter.
     */
    ulIndex = 0;
    while(*_p_szFormat)
    {
        /* Allocate a buffer to receive formatted parameter */
        SCR_M_Pars_AllocParam(char, _ap_szParameters[ulIndex], SCR_CV_ui_Cfg_MaxLenLine);
 
        /* For a string, we recopy all the parameter */
        if(_p_szFormat[1] == 's')
            strcpy(_ap_szParameters[ulIndex++], _p_szParams);
        /* Else we use sscanf to convert parameter */
        else
        {
            iReturn = sscanf(_p_szParams, _p_szFormat, _ap_szParameters[ulIndex++]);
            if((iReturn == 0) || (iReturn == EOF))
            {
                SCR_M_Err_UpdateSyntaxError();
                sprintf
                (
                    g_st_Err_GlobalError.a_szBufferTmp2, 
                    "Format is \"%s\", parameter is \"%s\".", 
                    _p_szFormat, 
                    _p_szParams
                );
                SCR_M_Err_RaiseError(SCR_EI_Err_CantConvertScanfFormat);
            }
        }
        _p_szFormat += (strlen(_p_szFormat) + 1);
        _p_szParams += (strlen(_p_szParams) + 1);
    };
    _ap_szParameters[ulIndex] = NULL;
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  Main function to convert parameters to an array of pointers.
 *  _p_szFormat         :   Format to convert.
 *  _p_szParams         :   Array of parameters to convert.
 *  _ap_szParameters    :   Array to receive parameters.
 *-------------------------------------------------------------------------------------------------
 */
void fn_v_Pars_ConvertParameters
(
    char *_p_szFormat, 
    char *_p_szParams,
    char *_ap_szParameters[]
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_p_szFormat != NULL);
    SCR_M_Dbg_Assert_P(_p_szParams != NULL);
    SCR_M_Dbg_Assert_P(_ap_szParameters != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /* 
     *  Treat format.
     */
    switch(*_p_szFormat)
    {
    /* A list of strings (default) */
    case '\0':

		
		
		
		fn_v_Pars_ConvertNormalParameters(_p_szParams, _ap_szParameters);
        return;
 
    /* An array of something */
    case SCR_CF_c_Cfg_FormatArray:
        fn_v_Pars_ConvertArrayParameters(_p_szFormat, _p_szParams, _ap_szParameters);
        return;
 
    /* A scanf format */
    case SCR_CF_c_Cfg_FormatScanf:
        fn_v_Pars_ConvertScanfParameters(_p_szFormat, _p_szParams, _ap_szParameters);
        return;
    }
}
 
/*
 *-------------------------------------------------------------------------------------------------
 *  Free array of parameters.
 *  _ap_szParameters    :   Array of parameters.
 *-------------------------------------------------------------------------------------------------
 */
void fn_v_Pars_FreeParameters(char *_ap_szParameters[])
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    SCR_M_Dbg_Assert_P(_ap_szParameters != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	if(_ap_szParameters[0])
		gs_p_cNewFreePlace = _ap_szParameters[0];
}
 
/*===============================================================================================*/
 
/*
 *-------------------------------------------------------------------------------------------------
 *	To make a strstr without care of upper or lower cases.
 *	_p_szString	:	String to scan.
 *	_p_szParam	:	Sub string to find.
 *-------------------------------------------------------------------------------------------------
 */
char *SCR_strstri(char *_p_szString, char *_p_szParam)		
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	char	a_szCopy1[256], a_szCopy2[256];
	char	*p_szRes;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	SCR_M_Dbg_Assert_P(_p_szString != NULL);
	SCR_M_Dbg_Assert_P(_p_szParam != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	strcpy(a_szCopy1, _p_szString);
	strcpy(a_szCopy2, _p_szParam);
	p_szRes = strstr(strlwr(a_szCopy1), strlwr(a_szCopy2));
 
	return p_szRes;
};
 
/*
 *-------------------------------------------------------------------------------------------------
 *	Fast strcmpi. From YLT, modifications by CB.
 *-------------------------------------------------------------------------------------------------
 */
/*
int SCR_strcmpi(char *a, char *b)
{
	char	cRetour;
	_asm 
	{
		mov eax,a
		mov ebx,b
 
boucle:
		mov ecx, dword ptr[eax]
		mov edx, dword ptr[ebx]
 
		;***********
		; First word
		;***********
 
		; Must CL be convert (97, 122) ?
		cmp cl,	97
		jl	lowercl
		cmp	cl, 122
		jg	lowercl
		sub	cl, 32
lowercl:
 
		; Must DL be convert (97, 122) ?
		cmp dl,	97
		jl	lowerdl
		cmp	dl, 122
		jg	lowerdl
		sub	dl, 32
lowerdl:
 
		; Compare CL and DL
		sub cl,	dl
		cmp dl,	0
		je  end
		cmp cl,	0
		jne end
 
		mov	cl, ch
		mov	dl, dh
		
		; Must CL be convert (97, 122) ?
		cmp cl,	97
		jl	lowerch
		cmp	cl, 122
		jg	lowerch
		sub	cl, 32
lowerch:
 
		; Must DL be convert (97, 122) ?
		cmp dl,	97
		jl	lowerdh
		cmp	dl, 122
		jg	lowerdh
		sub	dl, 32
lowerdh:
 
		; Compare CL and DL
		sub cl,	dl
		cmp dl,	0
		je  end
		cmp cl,	0
		jne end
 
		;************
		; Second word
		;************
 
		shr ecx,16
		shr edx,16
 
		; Must CL be convert (97, 122) ?
		cmp cl,	97
		jl	lowercl1
		cmp	cl, 122
		jg	lowercl1
		sub	cl, 32
lowercl1:
 
		; Must DL be convert (97, 122) ?
		cmp dl,	97
		jl	lowerdl1
		cmp	dl, 122
		jg	lowerdl1
		sub	dl, 32
lowerdl1:
 
		; Compare CL and DL
		sub cl,	dl
		cmp dl,	0
		je  end
		cmp cl,	0
		jne end
 
		mov	cl, ch
		mov	dl, dh
		
		; Must CL be convert (97, 122) ?
		cmp cl,	97
		jl	lowerch1
		cmp	cl, 122
		jg	lowerch1
		sub	cl, 32
lowerch1:
 
		; Must DL be convert (97, 122) ?
		cmp dl,	97
		jl	lowerdh1
		cmp	dl, 122
		jg	lowerdh1
		sub	dl, 32
lowerdh1:
 
		; Compare CL and DL
		sub cl,	dl
		cmp dl,	0
		je  end
		cmp cl,	0
		jne end
 
		;*************
		; Pass to next 
		;*************
 
		add eax, 4
		add ebx, 4
		jmp boucle
 
		;************************************
		; End of comparison : CL is the value
		;************************************
end:
		mov cRetour,cl
	}
	return (int) cRetour;
}*/
