/* *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * SCR_Pars.c * Parse a line. * * Scripts, Beaudet Christophe *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ /* *================================================================================================= * Includes. *================================================================================================= */ #include #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; }*/