/* Classic Ladder Project */ /* Copyright (C) 2001-2007 Marc Le Douarain */ /* http://membres.lycos.fr/mavati/classicladder/ */ /* http://www.sourceforge.net/projects/classicladder */ /* June 2007 (but only old code moved here!) */ /* --------------------------------------- */ /* Variable names strings for display/edit */ /* --------------------------------------- */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation; either */ /* version 2.1 of the License, or (at your option) any later version. */ /* This library is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ /* Lesser General Public License for more details. */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "classicladder.h" #include "global.h" #include "symbols.h" #include "vars_names.h" // include the var name table (not a header!) #include "vars_names_list.c" //old code with names directly in it... //to be deleted, but some precise errors codes aren't present in the new function... #ifdef AAAAAAAAA char * CreateVarName(int Type, int Offset) { static char Buffer[20]; switch(Type) { case VAR_MEM_BIT: sprintf(Buffer,"%cB%d",'%',Offset); break; #ifdef OLD_TIMERS_MONOS_SUPPORT case VAR_TIMER_DONE: sprintf(Buffer,"%cT%d.D",'%',Offset); break; case VAR_TIMER_RUNNING: sprintf(Buffer,"%cT%d.R",'%',Offset); break; case VAR_MONOSTABLE_RUNNING: sprintf(Buffer,"%cM%d.R",'%',Offset); break; #endif case VAR_TIMER_IEC_DONE: sprintf(Buffer,"%cTM%d.Q",'%',Offset); break; case VAR_COUNTER_DONE: sprintf(Buffer,"%cC%d.D",'%',Offset); break; case VAR_COUNTER_EMPTY: sprintf(Buffer,"%cC%d.E",'%',Offset); break; case VAR_COUNTER_FULL: sprintf(Buffer,"%cC%d.F",'%',Offset); break; case VAR_STEP_ACTIVITY: sprintf(Buffer,"%cX%d",'%',Offset); break; case VAR_PHYS_INPUT: sprintf(Buffer,"%cI%d",'%',Offset); break; case VAR_PHYS_OUTPUT: sprintf(Buffer,"%cQ%d",'%',Offset); break; case VAR_MEM_WORD: sprintf(Buffer,"%cW%d",'%',Offset); break; case VAR_STEP_TIME: sprintf(Buffer,"%cX%d.V",'%',Offset); break; #ifdef OLD_TIMERS_MONOS_SUPPORT case VAR_TIMER_PRESET: sprintf(Buffer,"%cT%d.P",'%',Offset); break; case VAR_TIMER_VALUE: sprintf(Buffer,"%cT%d.V",'%',Offset); break; case VAR_MONOSTABLE_PRESET: sprintf(Buffer,"%cM%d.P",'%',Offset); break; case VAR_MONOSTABLE_VALUE: sprintf(Buffer,"%cM%d.V",'%',Offset); break; #endif case VAR_TIMER_IEC_PRESET: sprintf(Buffer,"%cTM%d.P",'%',Offset); break; case VAR_TIMER_IEC_VALUE: sprintf(Buffer,"%cTM%d.V",'%',Offset); break; case VAR_COUNTER_PRESET: sprintf(Buffer,"%cC%d.P",'%',Offset); break; case VAR_COUNTER_VALUE: sprintf(Buffer,"%cC%d.V",'%',Offset); break; default: sprintf(Buffer,"???"); break; } printf("infogene display symbols=&i\n",InfosGene->DisplaySymbols); if ( InfosGene->DisplaySymbols ) { // verify if a symbol has been defined for the variable... char * Symbol = ConvVarNameToSymbol( Buffer ); if ( (Symbol!=NULL )||(Symbol[0]!=' ')||(Symbol[0]!='\0')){ return Symbol;} } return Buffer; } /* Convert a string to a number if >=Min and <=Max */ /* return TRUE if okay */ /* (pointer advance !) */ int TextToNumberAndAdvance(char ** text,int ValMin,int ValMaxi,int *ValFound) { int IsOk = TRUE; int Value = 0; char * pScan = *text; char NumberFound = FALSE; while( *pScan>='0' && *pScan<='9' ) { Value = Value*10+(*pScan-'0'); pScan++; NumberFound = TRUE; } if ( !NumberFound || (ValueValMaxi) ) IsOk = FALSE; if (IsOk) { *ValFound = Value; *text = pScan; } return IsOk; } /* Convert a string to variable (type/offset) */ /* if pNumberOfChars not NULL, give length of the string found */ /* return TRUE if okay */ char TextParserForAVar( char * text,int * VarTypeFound,int * VarOffsetFound, int * pNumberOfChars, char PartialNames ) { int TypeFound = 0; int OffsetFound; int IsOk = TRUE; char TimerIEC = FALSE; char * pScanPos = text; // content will be modified when advancing! char * * pPtrScanPos = &pScanPos; char * VarNameFromSymbol = NULL; int MaxNbr = 0; // if not commencing per '%', search the corresponding symbol ! if ( *pScanPos!='%' ) { VarNameFromSymbol = ConvSymbolToVarName( pScanPos ); if ( VarNameFromSymbol==NULL ) { IsOk = FALSE; ErrorMessageVarParser = "Unknown symbol for variable name"; } else { pScanPos = VarNameFromSymbol; } } if ( IsOk ) { // pass the first character '%' (*pPtrScanPos)++; switch(**pPtrScanPos) { case 'B': TypeFound = VAR_MEM_BIT; (*pPtrScanPos)++; if (!TextToNumberAndAdvance(pPtrScanPos,0,NBR_BITS-1,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } break; case 'T': (*pPtrScanPos)++; // New IEC Timer ? if ( **pPtrScanPos=='M' ) { TimerIEC = TRUE; (*pPtrScanPos)++; } MaxNbr = NBR_TIMERS_IEC-1; #ifdef OLD_TIMERS_MONOS_SUPPORT if ( TimerIEC==FALSE ) MaxNbr = NBR_TIMERS-1; #else TimerIEC = TRUE; #endif if (!TextToNumberAndAdvance(pPtrScanPos,0,MaxNbr,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } else { if ( PartialNames==FALSE ) { if ( **pPtrScanPos!=VAR_ATTRIBUTE_SEP ) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (missing '.' character before attribute)"; } else { (*pPtrScanPos)++; switch(**pPtrScanPos) { case 'D': if ( TimerIEC==FALSE ) { TypeFound = VAR_TIMER_DONE; } else { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (unknown attribute)"; } break; case 'Q': if ( TimerIEC==TRUE ) { TypeFound = VAR_TIMER_IEC_DONE; } else { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (unknown attribute)"; } break; case 'R': if ( TimerIEC==FALSE ) { TypeFound = VAR_TIMER_RUNNING; } else { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (unknown attribute)"; } break; case 'P': TypeFound = (TimerIEC==FALSE)?VAR_TIMER_PRESET:VAR_TIMER_IEC_PRESET; break; case 'V': TypeFound = (TimerIEC==FALSE)?VAR_TIMER_VALUE:VAR_TIMER_IEC_VALUE; break; default: IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (unknown attribute)"; break; } (*pPtrScanPos)++; } } } break; #ifdef OLD_TIMERS_MONOS_SUPPORT case 'M': (*pPtrScanPos)++; if (!TextToNumberAndAdvance(pPtrScanPos,0,NBR_MONOSTABLES-1,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } else { if ( PartialNames==FALSE ) { if ( **pPtrScanPos!=VAR_ATTRIBUTE_SEP ) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (missing '.' character before attribute)"; } else { (*pPtrScanPos)++; switch(**pPtrScanPos) { case 'R': TypeFound = VAR_MONOSTABLE_RUNNING; break; case 'P': TypeFound = VAR_MONOSTABLE_PRESET; break; case 'V': TypeFound = VAR_MONOSTABLE_VALUE; break; default: IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (unknown attribute)"; break; } (*pPtrScanPos)++; } } } break; #endif case 'C': (*pPtrScanPos)++; if (!TextToNumberAndAdvance(pPtrScanPos,0,NBR_COUNTERS-1,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } else { if ( PartialNames==FALSE ) { if ( **pPtrScanPos!=VAR_ATTRIBUTE_SEP ) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (missing '.' character before attribute)"; } else { (*pPtrScanPos)++; switch(**pPtrScanPos) { case 'D': TypeFound = VAR_COUNTER_DONE; break; case 'E': TypeFound = VAR_COUNTER_EMPTY; break; case 'F': TypeFound = VAR_COUNTER_FULL; break; case 'P': TypeFound = VAR_COUNTER_PRESET; break; case 'V': TypeFound = VAR_COUNTER_VALUE; break; default: IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (unknown attribute)"; break; } (*pPtrScanPos)++; } } } break; case 'I': TypeFound = VAR_PHYS_INPUT; (*pPtrScanPos)++; if (!TextToNumberAndAdvance(pPtrScanPos,0,NBR_PHYS_INPUTS-1,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } break; case 'Q': TypeFound = VAR_PHYS_OUTPUT; (*pPtrScanPos)++; if (!TextToNumberAndAdvance(pPtrScanPos,0,NBR_PHYS_OUTPUTS-1,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } break; case 'W': TypeFound = VAR_MEM_WORD; (*pPtrScanPos)++; if (!TextToNumberAndAdvance(pPtrScanPos,0,NBR_WORDS-1,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } break; #ifdef SEQUENTIAL_SUPPORT case 'X': TypeFound = VAR_STEP_ACTIVITY; //per default, but it could change later... (*pPtrScanPos)++; if (!TextToNumberAndAdvance(pPtrScanPos,0,NBR_STEPS-1,&OffsetFound)) { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (number value out of bound)"; } else { // verify if there is a '.' after number so that it must be the Xyyy.V form // instead of Xyyy form. if ( **pPtrScanPos==VAR_ATTRIBUTE_SEP ) { (*pPtrScanPos)++; if ( **pPtrScanPos=='V' ) { TypeFound = VAR_STEP_TIME; } else { IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (unknown attribute)"; } } } break; #endif default: IsOk = FALSE; ErrorMessageVarParser = "Unknown variable (on first character following %)"; } if (IsOk) { if ( VarTypeFound ) *VarTypeFound = TypeFound; if ( VarOffsetFound ) *VarOffsetFound = OffsetFound; if ( pNumberOfChars!=NULL ) *pNumberOfChars = (VarNameFromSymbol==NULL)?*pPtrScanPos-text : *pPtrScanPos-VarNameFromSymbol; } else { if ( ErrorMessageVarParser==NULL ) ErrorMessageVarParser = "Unknown variable (global error)"; } } return IsOk; } #endif /* return 0 if bad or the number of characters to pass... */ int ComparStaticPart(char * pSearchedString, char * pComparString) { int iNbrCaracs = 0; do { iNbrCaracs++; } while( (pComparString[ iNbrCaracs ]!='%') && (pComparString[ iNbrCaracs ]!='\0') ); if (strncmp(pSearchedString,pComparString,iNbrCaracs)==0) return iNbrCaracs; return 0; } /* Convert variable name -> internal ID of the corresponding var */ /* a little parser... */ /* return -1 if not found, else the corresponding Variable ID */ char TextParserForAVar( char * TextToParse, int * VarTypeFound,int * VarOffsetFound, int * pNumberOfChars, char PartialNames ) { int iBalayTable = 0; char bFound = FALSE, bEchecCompar,cOneAttributPassed ; int iIdVar = -1,iBalayProf,iTaillePartieStatique; StrConvIdVarName * pConv; char * pVarCherch = TextToParse; char * pBalayVarCherch; int iScruteCarac; int iOffset1; int iOffset2; int iOffset3; //printf( "TextParserForAVar:start...\n" ); if (*TextToParse=='\0' ) return FALSE; // if not commencing per '%', search the corresponding symbol ! if (*pVarCherch!='%') { pVarCherch = ConvSymbolToVarName( TextToParse ); if ( pVarCherch==NULL ) return FALSE; } else { // seems too much short for a base name ! if ( strlen(TextToParse)<3 ) return FALSE; } // pass the start '%' before parsing pVarCherch++; // scanning the base name variables table do { pBalayVarCherch = pVarCherch; bEchecCompar = FALSE; iScruteCarac = 0; iBalayProf = 0; iOffset1 = 0; iOffset2 = 0; iOffset3 = 0; cOneAttributPassed = FALSE; // pointer on the table list pConv = &TableConvIdVarName[ iBalayTable ]; do { // start number mark ? if ( pConv->StringBaseVarName[ iScruteCarac ]=='%' ) { // searching the end number mark in the base variable string do { iScruteCarac++; } while ( (pConv->StringBaseVarName[ iScruteCarac ]!='d') && (pConv->StringBaseVarName[ iScruteCarac ]!='\0') ); iScruteCarac++; // number value in the string searched if ( *pBalayVarCherch>='0' && *pBalayVarCherch<='9' ) { int iNumFound = 0; do { iNumFound = iNumFound*10; iNumFound = iNumFound + *pBalayVarCherch-'0'; pBalayVarCherch++; } while( *pBalayVarCherch>='0' && *pBalayVarCherch<='9'); switch( iBalayProf ) { case 0: iOffset1 = iNumFound; break; case 1: iOffset2 = iNumFound; break; case 2: iOffset3 = iNumFound; break; } iBalayProf++; } else { bEchecCompar = TRUE; } } else { if ( pConv->StringBaseVarName[ iScruteCarac ]=='.' ) cOneAttributPassed = TRUE; // comparing static part... iTaillePartieStatique = ComparStaticPart(pBalayVarCherch,&pConv->StringBaseVarName[ iScruteCarac ]); if (iTaillePartieStatique>0) { iScruteCarac = iScruteCarac+iTaillePartieStatique; pBalayVarCherch = pBalayVarCherch+iTaillePartieStatique; } else { bEchecCompar = TRUE; if ( PartialNames && cOneAttributPassed ) return TRUE; } } // at the end of the reference string ? // if yes it means we have found what we were searching for (else perhaps another one exists starting by the same string) if ( pConv->StringBaseVarName[ iScruteCarac ]=='\0' ) { // verify that there isn't too much characters after ! // if yes, dropped... // Put in comment because it is used in the arithmetic parser !!!!! if ( !bEchecCompar /* && *pBalayVarCherch=='\0' */ ) bFound = TRUE; else bEchecCompar = TRUE; } } while( !bEchecCompar && !bFound ); iBalayTable++; } while( !bFound && TableConvIdVarName[ iBalayTable ].StringBaseVarName ); if (bFound) { char bVerifCoherenceOk = TRUE; // verify if offsets given are in if ( iOffset1>=pConv->iSize1+pConv->iFirstVal1 ) bVerifCoherenceOk = FALSE; if ( iOffset1iFirstVal1 ) bVerifCoherenceOk = FALSE; if ( pConv->iSize2>0 ) { if ( iOffset2>=pConv->iSize2+pConv->iFirstVal2 ) bVerifCoherenceOk = FALSE; if ( iOffset2iFirstVal2 ) bVerifCoherenceOk = FALSE; } if ( pConv->iSize3>0 ) { if ( iOffset3>=pConv->iSize3+pConv->iFirstVal3 ) bVerifCoherenceOk = FALSE; if ( iOffset3iFirstVal3 ) bVerifCoherenceOk = FALSE; } if ( bVerifCoherenceOk==FALSE ) ErrorMessageVarParser = "Unknown variable (number value out of bound)"; if (bVerifCoherenceOk) { // calc final Id if ( pConv->iSize3<=0 && pConv->iSize2<=0 ) { iIdVar = pConv->iIdVar + iOffset1-pConv->iFirstVal1; } else { if ( pConv->iSize3<=0 ) iIdVar = pConv->iIdVar + (iOffset1-pConv->iFirstVal1)*pConv->iSize2 + iOffset2-pConv->iFirstVal2; else iIdVar = pConv->iIdVar + (iOffset1-pConv->iFirstVal1)*pConv->iSize2*pConv->iSize3 + (iOffset2-pConv->iFirstVal2)*pConv->iSize3 + iOffset3-pConv->iFirstVal3; } if ( VarTypeFound!=NULL ) { #ifdef IDVAR_IS_TYPE_AND_OFFSET *VarTypeFound = pConv->iTypeVar; #else *VarTypeFound = VAR_DEFAULT_TYPE; #endif } if ( VarOffsetFound!=NULL ) *VarOffsetFound = iIdVar; if ( pNumberOfChars!=NULL ) *pNumberOfChars = pBalayVarCherch-TextToParse; } else { bFound = FALSE; } } return bFound; } StrConvIdVarName * ConvIdVarEnPtrSurEleConv( int iTypeVarToSearch, int iIdVarCherchee ) { int iBalayTable = 0; char bFound = FALSE; int iIdFound = 0; int iSizeTotal = 0; StrConvIdVarName * pConv; // research in the table list do { pConv = &TableConvIdVarName[ iBalayTable ]; // same type ? #ifdef IDVAR_IS_TYPE_AND_OFFSET if ( pConv->iTypeVar==iTypeVarToSearch ) #endif { iIdFound = pConv->iIdVar; iSizeTotal = (pConv->iSize2<=0)?pConv->iSize1:pConv->iSize1*pConv->iSize2; if ( pConv->iSize3>0 ) iSizeTotal *= pConv->iSize3; /* Offset value between start and end values ? */ if ( (iIdFound<=iIdVarCherchee) && (iIdVarCherchee<(iIdFound+iSizeTotal)) ) bFound = TRUE; else iBalayTable++; } #ifdef IDVAR_IS_TYPE_AND_OFFSET else { iBalayTable++; } #endif } while (!bFound && TableConvIdVarName[ iBalayTable].StringBaseVarName); if (bFound) return pConv; else return NULL; } /* Convert a Type/Id variable into a default base name */ /* return the string character or ??? if not found */ char * CreateVarName( int TypeVarSearched, int OffsetVarSearched ) { static char tcBuffer[ 100 ]; static char tcBuffer2[ 100 ]; int iIdFound; StrConvIdVarName * pConv; // research in the table list pConv = ConvIdVarEnPtrSurEleConv( TypeVarSearched, OffsetVarSearched ); if (pConv) { strcpy(tcBuffer,"%"); iIdFound = pConv->iIdVar; if (pConv->iSize2<=0 && pConv->iSize3<=0) { sprintf(tcBuffer2, pConv->StringBaseVarName, OffsetVarSearched-iIdFound +pConv->iFirstVal1 ); } else { if (pConv->iSize3<=0) sprintf(tcBuffer2, pConv->StringBaseVarName, (OffsetVarSearched-iIdFound)/pConv->iSize2 +pConv->iFirstVal1, (OffsetVarSearched-iIdFound)%pConv->iSize2 +pConv->iFirstVal2 ); else sprintf(tcBuffer2, pConv->StringBaseVarName, (OffsetVarSearched-iIdFound)/(pConv->iSize2*pConv->iSize3) +pConv->iFirstVal1, ((OffsetVarSearched-iIdFound)/pConv->iSize3)%pConv->iSize2 +pConv->iFirstVal2, (OffsetVarSearched-iIdFound)%pConv->iSize3 +pConv->iFirstVal3 ); } strcat(tcBuffer,tcBuffer2); if ( InfosGene->DisplaySymbols ) { // verify if a symbol has been defined for the variable... char * Symbol = ConvVarNameToSymbol( tcBuffer ); if ( (Symbol!=NULL ) && ((Symbol[0]!=' ') || (Symbol[0]!='\0'))) {return Symbol;} } return tcBuffer; } else { return "???"; } } char TestVarIsReadWrite( int TypeVarTested, int OffsetVarTested ) { StrConvIdVarName * pConv; // research in the table list pConv = ConvIdVarEnPtrSurEleConv( TypeVarTested, OffsetVarTested ); if (pConv) { return pConv->cReadWriteAccess; } return FALSE; }