// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).// All rights reserved.// This component and the accompanying materials are made available// under the terms of "Eclipse Public License v1.0"// which accompanies this distribution, and is available// at the URL "http://www.eclipse.org/legal/epl-v10.html".//// Initial Contributors:// Nokia Corporation - initial contribution.//// Contributors://// Description:// NetDial Script Commands// ///** @file Scommand.cpp */#include "SSCRREAD.H"#include "SSCREXEC.H"#include "SIO.H"#include "SLOGGER.H"// Command names_LIT(KSetCommand,"SET");_LIT(KSendCommand,"SEND");_LIT(KWaitCommand,"WAIT");_LIT(KLoopCommand,"LOOP");_LIT(KGotoCommand,"GOTO");_LIT(KExitCommand,"EXIT");_LIT(KDTRCommand,"DTR");_LIT(KDropDTRCommand,"RAISE");_LIT(KRaiseDTRCommand,"DROP");_LIT(KReadCommand,"READ");_LIT(KCharmapCommand,"CHARMAP");_LIT(KTempVarName,"$$TMPVAR$$%d"); //< Temporary variable name// Characters used in scriptsconst TText KCommentChar='!'; const TText KPlusChar='+';const TText KQuoteChar='\"';const TText KOpenChevronChar='<';const TText KCloseChevronChar='>';const TText KOpenExprChar='{';const TText KCloseExprChar='}';const TText KEqualsChar='=';const TText KTabChar='\t';const TText KSpaceChar=' ';const TText KColonChar=':';const TText KOpenSquareBracketChar='[';const TText KCloseSquareBracketChar=']';const TInt KLabelArrayGranularity=5;const TInt32 KMinScriptInteger=0;const TInt32 KMaxScriptInteger=500000;const TReal KMinScriptReal=0.0;const TReal KMaxScriptReal=500000.0;const TInt KMinLoopCounter=1;const TInt KMaxLoopCounter=10000;//// Glossary// ========// String - a text string enclosed in ".."// Character - a single character expressed numnerically enclosed in <..>// Variable - named variable (preset or set in script) ending in $// Expression - any one of the three above// Compound expression - a number of expressions concatenated with +// Token - an expression, compound expression, label or command////// CScriptCommandBase definitions//CScriptCommandBase::CScriptCommandBase(TScriptStatus& aStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv) : iScriptReader(aScriptReader), iVarMan(aVarMan), iCharConv(aCharConv), iTempVarNum(0), iStatus(aStatus)/**Constructor for CScriptCharacterConverter.*/ {}CScriptCommandBase::~CScriptCommandBase()/**Destructor.*/ {}void CScriptCommandBase::ConstructL()/**Instantiates member variables.*/ {}void CScriptCommandBase::Cleanup()/**Cleanup.*/ {}TPtrC CScriptCommandBase::ParseCompoundExpressionL(TInt& aOffset)/**Parses a compound string expression starting at aOffset into a single stringconstant and returns it.*/ { TPtrC wholeExpr; wholeExpr.Set(ParseExpressionL(aOffset)); TBuf<KMaxVarNameLength> varName; varName.Format(KTempVarName,iTempVarNum++); iVarMan->AddVariableL(varName,wholeExpr); HBufC* val=NULL; HBufC* oldVal=NULL; FOREVER { EatSpaces(aOffset); if (aOffset>=iStatus.iLine.Length()) break; if (iStatus.iLine[aOffset]!=KPlusChar) break; TPtrC nextExpr; nextExpr.Set(ParseExpressionL(++aOffset)); val=HBufC::NewLC(wholeExpr.Length()+nextExpr.Length()); TPtr currentExpr(val->Des()); currentExpr.Append(wholeExpr); currentExpr.Append(nextExpr); varName.Format(KTempVarName,iTempVarNum++); iVarMan->AddVariableL(varName,val->Des()); CleanupStack::Pop(); wholeExpr.Set(val->Des()); delete oldVal; oldVal=val; } delete val; User::LeaveIfError(iVarMan->FindVariable(varName,wholeExpr)); return wholeExpr; }TPtrC CScriptCommandBase::ParseExpressionL(TInt& aOffset)/**Parses string expression starting at aOffset according to starting characterand returns value.*/ { EatSpaces(aOffset); if(iStatus.iLine.Length()<=aOffset) User::Leave(KErrNoExpression); switch(iStatus.iLine[aOffset]) //switch(iLine[aOffset+1]) { case KQuoteChar: aOffset++; // skip quote char return ParseStringL(aOffset); case KOpenChevronChar: aOffset++; // skip chevron char return ParseCharacterL(aOffset); default: return ParseVariableL(aOffset); } }TPtrC CScriptCommandBase::ParseStringL(TInt& aOffset)/**Parses a string constant enclosed in "" and returns its value.*/ { return ParseEnclosedStringL(aOffset,KQuoteChar,KErrMissingQuote); }TPtrC CScriptCommandBase::ParseCharacterL(TInt& aOffset)/**Parses a character enclosed in <> and returns its value.*/ { TPtrC charString=ParseEnclosedStringL(aOffset,KCloseChevronChar,KErrMissingChevron); TRadix radix=EDecimal; TInt len=charString.Length(); if (len>2) { if(charString[0]=='0') { switch(charString[1]) { case 'x': case 'X': len-=2; radix=EHex; break; case 'd': case 'D': len-=2; radix=EDecimal; break; case 'o': case 'O': len-=2; radix=EOctal; break; case 'b': case 'B': len-=2; radix=EBinary; break; default: break; } } } TLex lex(charString.Right(len)); TUint val=0; if (lex.Val(val,radix)!=KErrNone) User::Leave(KErrInvalidNumber); TBuf<1> character=(TText*)&val; TBuf<KMaxVarNameLength> varName; varName.Format(KTempVarName,iTempVarNum++); iVarMan->AddVariableL(varName,character); TPtrC temp; iVarMan->FindVariable(varName,temp); return temp; }TPtrC CScriptCommandBase::ParseVariableL(TInt& aOffset)/**Parses a variable and returns its value.*/ { TInt end=FindTokenEnd(aOffset); TPtrC varName=iStatus.iLine.Mid(aOffset,end-aOffset); aOffset=end; TPtrC varValue; if (iVarMan->FindVariable(varName,varValue)==KErrNotFound) { if(!iStatus.iSkip) User::Leave(KErrVariableNotFound); return TPtrC(); } return varValue; }TInt32 CScriptCommandBase::ParseIntegerL(TInt& aOffset)/**Parses an integer and returns its value.*/ { EatSpaces(aOffset); TLex lex(iStatus.iLine); lex.Inc(aOffset); TInt32 val=0; if (lex.Val(val)!=KErrNone) { User::Leave(KErrInvalidNumber); return KMinScriptInteger; } if ((val<KMinScriptInteger) || (val>KMaxScriptInteger)) { User::Leave(KErrNumberOutOfRange); return KMinScriptInteger; } aOffset=lex.Offset(); return val; }TReal CScriptCommandBase::ParseRealL(TInt& aOffset)/**Parses a real number and returns its value.*/ { EatSpaces(aOffset); TLex lex(iStatus.iLine); lex.Inc(aOffset); TReal val=0.0; if (lex.Val(val)!=KErrNone) { User::Leave(KErrInvalidNumber); return KMinScriptReal; } if ((val<KMinScriptReal) || (val>KMaxScriptReal)) { User::Leave(KErrNumberOutOfRange); return KMinScriptReal; } aOffset=lex.Offset(); return val; }TPtrC CScriptCommandBase::ParseCharacterTypeL(TInt& aOffset)/**Parses character type.*/ { EatSpaces(aOffset); if(iStatus.iLine.Length()<=aOffset) // nothing specified so assume default return TPtrC(); TInt startChar=aOffset; if (iStatus.iLine[startChar++]!=KOpenSquareBracketChar) return TPtrC(); // No open bracket so assume default aOffset=startChar; return ParseEnclosedStringL(aOffset,KCloseSquareBracketChar,KErrMissingBracket); }HBufC8* CScriptCommandBase::ConvertLC(const TDesC& aString,TInt& aOffset)/**Converts to correct character set.*/ { TBuf<KMaxCharacterTypeLength> type=ParseCharacterTypeL(aOffset); return iCharConv->ConvertLC(aString,type); }TInt CScriptCommandBase::FindTokenEnd(TInt aOffset)/**Finds end of string beginning at aOffset and returns length.*/ { __ASSERT_DEBUG(aOffset<=iStatus.iLine.Length(), NetDialPanic(EOffsetExceedsLineLength)); if(aOffset==iStatus.iLine.Length()) return aOffset; TInt end; for (end=aOffset; IsValidChar(iStatus.iLine[end]); end++) { if (end>=(iStatus.iLine.Length()-1)) { end++; break; } } return end; }TBool CScriptCommandBase::IsValidChar(const TText& aChar)/**Checks if aChar is a valid character in a script command.*/ { return TChar(aChar).IsAlphaDigit() || (aChar==KDollarChar) || (aChar==KUnderscoreChar) || (aChar==KCommentChar); }void CScriptCommandBase::EatSpaces(TInt& aOffset)/**Ignores spaces, tabs, line feeds and carriage returns and sets aOffset to next non-blank character, or end of line*/ { if(aOffset>=iStatus.iLine.Length()) return; while((iStatus.iLine[aOffset]==KSpaceChar) || (iStatus.iLine[aOffset]==KTabChar) || (iStatus.iLine[aOffset]==KLineFeed) || (iStatus.iLine[aOffset]==KCarriageReturn)) { aOffset++; if(aOffset>=iStatus.iLine.Length()) break; } }void CScriptCommandBase::EatSpacesAndLinesL()/**Ignores spaces and empty lines and sets aOffset to next non-blank character.*/ { EatSpaces(iStatus.iOffset); while(iStatus.iOffset>=iStatus.iLine.Length()) { User::LeaveIfError(iScriptReader->GetNextLine()); // This also resets iStatus.iOffset EatSpaces(iStatus.iOffset); } }void CScriptCommandBase::EatSpacesAndLinesAndCommentsL()/**Ignores spaces, empty lines and comments and sets aOffset to next non-blank or non-comment character*/ { EatSpacesAndLinesL(); while (iStatus.iLine[iStatus.iOffset]==KCommentChar) { iStatus.iOffset=iStatus.iLine.Length(); EatSpacesAndLinesL(); // this will reset iStatus.iOffset if necessary } } TPtrC CScriptCommandBase::ParseEnclosedStringL(TInt& aOffset,TText aChar,TInt aError)/**Parses enclosed string*/ { if(aOffset>=iStatus.iLine.Length()) User::Leave(aError); // no end character before EOL TInt end=aOffset; while (end<iStatus.iLine.Length()) { if (iStatus.iLine[end]==aChar) break; end++; } if (end>=iStatus.iLine.Length()) User::Leave(aError); // no end character before EOL TInt start=aOffset; aOffset=end+1; return iStatus.iLine.Mid(start,end-start); }//// CSetCommand definitions//CSetCommand* CSetCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv)/**2 phased constructor for CSetCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CSetCommand object.*/ { CSetCommand* c=new(ELeave) CSetCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CSetCommand::CSetCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv)/**Constructor for CSetCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.*/ {}CSetCommand::~CSetCommand()/**Destructor.*/ {}TBool CSetCommand::ParseL()/**Parses a SET command. Determines variable name and value and adds to variable list.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KSetCommand)==KErrNone) { if (!iStatus.iSkip) { __FLOG_STMT(_LIT8(KLogStringExecutingSet,"Script:\tExecuting Set");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),KLogStringExecutingSet()); } iStatus.iOffset=end; EatSpaces(iStatus.iOffset); end=FindTokenEnd(iStatus.iOffset); TPtrC varName=iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset); EatSpaces(end); if (iStatus.iLine[end++]!=KEqualsChar) User::Leave(KErrNoEquals); EatSpaces(end); TPtrC value=ParseCompoundExpressionL(end); if (!iStatus.iSkip) { iVarMan->AddVariableL(varName,value); __FLOG_STMT(_LIT(KLogStringSetVar,"Script:\tSet Var: %S To %S")); __FLOG_STATIC2(KNetDialLogFolder(),KNetDialLogFile(),TRefByValue<const TDesC>(KLogStringSetVar()),&varName,&value); } iStatus.iOffset=end; return ETrue; // Consumed } return EFalse; // Not Consumed }//// CSendCommand definitions//CSendCommand* CSendCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptIO* aScriptIO)/**2 phased constructor for CSendCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptIO a pointer to serial comms I/O handler.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CSendCommand object.*/ { CSendCommand* c=new(ELeave) CSendCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv,aScriptIO); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CSendCommand::CSendCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptIO* aScriptIO) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv), iScriptIO(aScriptIO)/**Constructor for CSendCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptIO a pointer to serial comms I/O handler.*/ {}CSendCommand::~CSendCommand()/**Destructor.*/ {}TBool CSendCommand::ParseL()/**Parses SEND command. Parses expression to send and sends it.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if(iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KSendCommand)==0) { if(!iStatus.iSkip) { __FLOG_STMT(_LIT8(KLogStringExecutingSend,"Script:\tExecuting Send");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),KLogStringExecutingSend()); } iStatus.iOffset=end; EatSpaces(iStatus.iOffset); TPtrC temp; temp.Set(ParseCompoundExpressionL(iStatus.iOffset)); HBufC8* buf=ConvertLC(temp,iStatus.iOffset); iSendString.Set(buf->Des()); if(!iStatus.iSkip) { iScriptIO->Write(iSendString);#ifdef __FLOG_ACTIVE _LIT(KLogStringSending,"Script:\tSending %S"); TBuf16<KLogBufferSize> temp; temp.Copy(iSendString.Left(Min(iSendString.Length(),KLogBufferSize))); __FLOG_STATIC1(KNetDialLogFolder(),KNetDialLogFile(),TRefByValue<const TDesC>(KLogStringSending()),&temp);#endif } CleanupStack::PopAndDestroy(); return ETrue; // Consumed } return EFalse; // Not Consumed }//// CLabelSearch definitions//CLabelSearch* CLabelSearch::NewLC(const TDesC& aLabelName)/**2 phased constructor for CLabelSearch, first phase.@param aLabelName is label name.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CLabelSearch object.*/ { CLabelSearch* label=new(ELeave) CLabelSearch(); CleanupStack::PushL(label); label->ConstructL(aLabelName); return label; }CLabelSearch::CLabelSearch() : iStatus(ENotFound), iPosition()/**Constructor for CLabelSearch, used in the first phase of construction.*/ {}void CLabelSearch::ConstructL(const TDesC& aLabelName)/**Instantiates member variables.*/ { iChatString=NULL; iLabelName=HBufC::NewL(aLabelName.Length()); (*iLabelName)=aLabelName; }CLabelSearch::~CLabelSearch()/**Destructor.Don't delete iChatString - that is dealt with by CScriptIO.*/ { delete iLabelName; }void CLabelSearch::CreateCommChatStringL(const TDesC8& aDes,TBool aIsFolded)/**Creates CCommChatString object.*/ { iChatString=CCommChatString::NewL(aDes,aIsFolded); }//// CWaitCommand definitions//CWaitCommand* CWaitCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptIO* aScriptIO,CScriptLabelMan* aLabelMan, CScriptExecutor* aScriptExec)/**2 phased constructor for CWaitCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptIO a pointer to serial comms I/O handler.@param aLabelMan a pointer to label manager.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CWaitCommand object.*/ { CWaitCommand* c=new(ELeave) CWaitCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv,aScriptIO,aLabelMan,aScriptExec); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CWaitCommand::CWaitCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptIO* aScriptIO,CScriptLabelMan* aLabelMan, CScriptExecutor* aScriptExec) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv), iScriptIO(aScriptIO), iLabelMan(aLabelMan), iScriptExec(aScriptExec)/**Constructor for CWaitCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptIO a pointer to serial comms I/O handler.@param aLabelMan a pointer to label manager.*/ {}CWaitCommand::~CWaitCommand()/**Destructor.Clears label array.*/ { DeleteLabelArray(); }TBool CWaitCommand::ParseL()/**Parses WAIT command. Parse according to whether in skip mode or not.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KWaitCommand)==KErrNone) { iStatus.iOffset=end; if (iStatus.iSkip) ParseSkipL(); else ParseActionL(); return ETrue; // Consumed } return EFalse; // Not Consumed }void CWaitCommand::Cleanup()/**Cancels the read and clears out the labels*/ { if (!iStatus.iSkip) { iScriptIO->Cancel(); DeleteLabelArray(); iLabelArray=NULL; } }void CWaitCommand::ParseActionL()/**Parses WAIT command when not in skip mode. Parses wait period, strings and labels and queue a read.*/ { __FLOG_STMT(_LIT8(KLogStringExecutingWait,"Script:\tExecuting Wait");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),KLogStringExecutingWait()); EatSpaces(iStatus.iOffset); TReal waitPeriod=ParseRealL(iStatus.iOffset); EatSpacesAndLinesAndCommentsL(); if (iStatus.iLine[iStatus.iOffset++]!=KOpenExprChar) User::Leave(KErrNoOpenExpression); iLabelArray=new(ELeave) CLabelSearchArray(KLabelArrayGranularity); TBool completed=EFalse; while(!completed) { EatSpacesAndLinesAndCommentsL(); if (iStatus.iLine[iStatus.iOffset]==KCloseExprChar) { completed=ETrue; iStatus.iOffset++; } else { TPtrC temp=ParseCompoundExpressionL(iStatus.iOffset); HBufC8* buf=ConvertLC(temp,iStatus.iOffset); CLabelSearch* label=ParseLabelLC(); TPtrC8 waitString(buf->Des()); label->CreateCommChatStringL(waitString,EFalse); iLabelArray->AppendL(label); // for logging TBuf<KLogBufferSize> labelName; labelName.Copy(label->LabelName().Left(Min(KLogBufferSize,label->LabelName().Length()))); //#ifdef __FLOG_ACTIVE _LIT(KLogStringGog,"Script:\tIf %S is found, Goto %S"); TBuf16<KLogBufferSize> string; string.Copy(waitString.Left(Min(waitString.Length(),KLogBufferSize))); __FLOG_STATIC2(KNetDialLogFolder(),KNetDialLogFile(),TRefByValue<const TDesC>(KLogStringGog()),&string,&labelName);#endif CleanupStack::Pop(); // label - will be deleted from array CleanupStack::PopAndDestroy(); // buf - will have been copied into label array } } // Tell the script executor how long we are going to wait since it // may need to force the server to resend the login prompt and will // need to know how long to wait the second time around iScriptExec->SetRetransmittedLoginTimeout(waitPeriod); iScriptIO->Read(iLabelArray,waitPeriod); }void CWaitCommand::ParseSkipL()/**Parses a WAIT command when in skip mode. Parses expressions and labels but do not queue read.*/ { EatSpaces(iStatus.iOffset); ParseRealL(iStatus.iOffset); // ignore the actual value returned EatSpacesAndLinesAndCommentsL(); if (iStatus.iLine[iStatus.iOffset++]!=KOpenExprChar) User::Leave(KErrNoOpenExpression); TBool completed=EFalse; while (!completed) { EatSpacesAndLinesAndCommentsL(); if (iStatus.iLine[iStatus.iOffset]==KCloseExprChar) { completed=ETrue; iStatus.iOffset++; } else { ParseCompoundExpressionL(iStatus.iOffset); // ignore the return value in skip mode ParseLabelLC(); CleanupStack::PopAndDestroy(); // ignore the label returned } } }CLabelSearch* CWaitCommand::ParseLabelLC()/**Parses label. Parses label name and looks for it in the label list.Returns results of search.*/ { EatSpaces(iStatus.iOffset); TInt start=iStatus.iOffset; iStatus.iOffset=FindTokenEnd(start); TPtrC var=iStatus.iLine.Mid(start,iStatus.iOffset-start); CLabelSearch* labelSearch=CLabelSearch::NewLC(var); TLinePosition pos; if(iLabelMan->FindLabel(var,pos)==KErrNotFound) { pos.Reset(); labelSearch->Set(CLabelSearch::ENotFound,pos); } else labelSearch->Set(CLabelSearch::EResolved,pos); return labelSearch; }TPtrC CWaitCommand::LabelFromIndexL(TInt aIndex)/**Gets label from array by index.*/ { if ((aIndex<0) && (aIndex>iLabelArray->Count())) User::Leave(KErrIllegalWaitLabelIndex); return (*iLabelArray)[aIndex]->LabelName(); }void CWaitCommand::DeleteLabelArray()/**Deletes label array.*/ { if (iLabelArray!=NULL) { TInt count=iLabelArray->Count(); for(TInt i=0; i<count; i++) { delete (*iLabelArray)[i]; } iLabelArray->Delete(0,count); delete iLabelArray; } }//// CLoopCommand definitions//CLoopCommand* CLoopCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv)/**2 phased constructor for CLoopCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CLoopCommand object.*/ { CLoopCommand* c=new(ELeave) CLoopCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CLoopCommand::CLoopCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv), iLoop(EFalse)/**Constructor for CLoopCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.*/ {}CLoopCommand::~CLoopCommand()/**Destructor.*/ {}TBool CLoopCommand::ParseL()/**Parses LOOP command. Checks how many times to loop and records position of beginning of loop.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KLoopCommand)==KErrNone) { if (iLoop) User::Leave(KErrNestedLoop); if (!iStatus.iSkip) { __FLOG_STMT(_LIT8(KLogStringExecutingLoop,"Script:\tExecuting Loop");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),KLogStringExecutingLoop()); } iStatus.iOffset=end; EatSpaces(iStatus.iOffset); iLoopCounter=ParseIntegerL(iStatus.iOffset); if ((iLoopCounter<KMinLoopCounter) || (iLoopCounter>KMaxLoopCounter)) User::Leave(KErrLoopCounterOutOfRange); EatSpacesAndLinesAndCommentsL(); if (iStatus.iLine[iStatus.iOffset++]!=KOpenExprChar) User::Leave(KErrNoOpenExpression); iLoop=ETrue; iScriptReader->CurrentPos(iLoopPosition,iStatus.iOffset); if (!iStatus.iSkip) { __FLOG_STMT(_LIT(KLogStringLoopCounter,"Script:\tLoop Counter %d");) __FLOG_STATIC1(KNetDialLogFolder(),KNetDialLogFile(),KLogStringLoopCounter(),iLoopCounter); } return ETrue; // Consumed } return EFalse; // Not Consumed }TBool CLoopCommand::CheckLoopL()/**Checks how many times loop has been executed and returns to beginning if necessary.*/ { if (iLoop) { EatSpacesAndLinesAndCommentsL(); if(iStatus.iLine[iStatus.iOffset]==KCloseExprChar) { if((--iLoopCounter==0) || (iStatus.iSkip)) { iLoop=EFalse; iStatus.iOffset++; } else { iScriptReader->SetCurrentPos(iLoopPosition); __FLOG_STMT(_LIT8(logString1,"Script:\tRepeat Loop");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString1()); __FLOG_STMT(_LIT8(logString2,"Script:\tLoop Counter %d");) __FLOG_STATIC1(KNetDialLogFolder(),KNetDialLogFile(),logString2(),iLoopCounter); } return ETrue; // Consumed Something } } return EFalse; // Nothing doing... }//// CGotoCommand definitions//CGotoCommand* CGotoCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptLabelMan* aLabelMan)/**2 phased constructor for CGotoCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aLabelMan a pointer to label manager.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CGotoCommand object.*/ { CGotoCommand* c=new(ELeave) CGotoCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv,aLabelMan); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CGotoCommand::CGotoCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptLabelMan* aLabelMan) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv), iLabelMan(aLabelMan)/**Constructor for CGotoCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aLabelMan a pointer to label manager.*/ {}CGotoCommand::~CGotoCommand()/**Destructor.*/ {}TBool CGotoCommand::ParseL()/**Parses GOTO command. Parses label and goto label.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KGotoCommand)==KErrNone) { if(!iStatus.iSkip) { __FLOG_STMT(_LIT8(logString,"Script:\tExecuting Goto");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString()); } iStatus.iOffset=end; EatSpaces(iStatus.iOffset); end=FindTokenEnd(iStatus.iOffset); TPtrC var=iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset); // HBufC* labelName=HBufC::NewLC(var.Length()); // (*labelName)=var; // GotoL(labelName->Des()); // CleanupStack::PopAndDestroy(); Goto(var); iStatus.iOffset=end; return ETrue; // Consumed } return EFalse; // Not Consumed }void CGotoCommand::Goto(const TDesC& aLabelName)/**Finds label in those passed already, or skip lines until it is found.*/ { TLinePosition pos; if(!iStatus.iSkip) { if (iLabelMan->FindLabel(aLabelName,pos)==KErrNotFound) { iSearchName.Copy(aLabelName); iStatus.iSkipModeToggleReq=ETrue; __FLOG_STMT(_LIT(logString1,"Script:\tSearching for Label %S");) __FLOG_STATIC1(KNetDialLogFolder(),KNetDialLogFile(),TRefByValue<const TDesC>(logString1()),&aLabelName); __FLOG_STMT(_LIT8(logString2,"Script:\tEntering Skip Mode");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString2()); } else iScriptReader->SetCurrentPos(pos); } }TBool CGotoCommand::ParseLabelL()/**Parses label and adds it to label list. Compares label against one to be found.*/ { EatSpacesAndLinesAndCommentsL(); TInt start=iStatus.iOffset; TInt end=FindTokenEnd(start); if ((iStatus.iLine.Length()>=(end+1)) && (iStatus.iLine[end]==KColonChar)) { TLinePosition pos; iScriptReader->CurrentPos(pos,end+1); iLabelMan->AddLabelL(iStatus.iLine.Mid(start,end-start),pos); iStatus.iOffset=++end; TLinePosition dummyPos; if (iStatus.iSkip && (iLabelMan->FindLabel(iSearchName,dummyPos)==KErrNone)) { iStatus.iSkipModeToggleReq=ETrue; __FLOG_STMT(_LIT8(logString,"Script:\tExiting Skip Mode");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString()); } return ETrue; } return EFalse; }void CGotoCommand::ServiceSkipReqs()/**Toggles skip mode.*/ { if(iStatus.iSkipModeToggleReq) { iStatus.iSkipModeToggleReq=EFalse; iStatus.iSkip=!iStatus.iSkip; } }//// CDTRCommand definitions//CDTRCommand* CDTRCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptIO* aScriptIO)/**2 phased constructor for CDTRCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptIO a pointer to serial comms I/O handler.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CDTRCommand object.*/ { CDTRCommand* c=new(ELeave) CDTRCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv,aScriptIO); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CDTRCommand::CDTRCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptIO* aScriptIO) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv), iScriptIO(aScriptIO)/**Constructor for CDTRCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptIO a pointer to serial comms I/O handler.*/ {}CDTRCommand::~CDTRCommand()/**Destructor.*/ {}TBool CDTRCommand::ParseL()/**Parses DTR command. Drops or raises appropriately.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KDTRCommand)==KErrNone) { if(!iStatus.iSkip) { __FLOG_STMT(_LIT8(logString1,"Script:\tExecuting DTR");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString1()); } iStatus.iOffset=end; EatSpaces(iStatus.iOffset); end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KRaiseDTRCommand)==KErrNone) { if(!iStatus.iSkip) { __FLOG_STMT(_LIT8(logString2,"Script:\tRaising DTR");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString2()); iScriptIO->RaiseDTR(NULL); } } else if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KDropDTRCommand)==KErrNone) { if(!iStatus.iSkip) { __FLOG_STMT(_LIT8(logString3,"Script:\tDropping DTR");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString3()); iScriptIO->DropDTR(NULL); } } else User::Leave(KErrNoDropOrRaise); iStatus.iOffset=end; return ETrue; // Consumed } return EFalse; // Not Consumed }//// CReadPCTCommand definitions//CReadPCTCommand* CReadPCTCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptExecutor* aScriptExec)/**2 phased constructor for CReadPCTCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptExec a pointer to script executioner.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CReadPCTCommand object.*/ { CReadPCTCommand* c=new(ELeave) CReadPCTCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv,aScriptExec); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CReadPCTCommand::CReadPCTCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv,CScriptExecutor* aScriptExec) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv), iScriptExec(aScriptExec)/**Constructor for CDTRCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@param aScriptExec a pointer to script executioner.*/ {}CReadPCTCommand::~CReadPCTCommand()/**Destructor.*/ {}TBool CReadPCTCommand::ParseL()/**Parses Read command.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KReadCommand)==KErrNone) { if (!iStatus.iSkip) { __FLOG_STMT(_LIT8(logString,"Script:\tExecuting Read");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString()); iCharSet=ParseCharacterTypeL(iStatus.iOffset); iScriptExec->ReadPct(); } iStatus.iOffset=end; return ETrue; // Consumed } return EFalse; // Not Consumed }TBool CReadPCTCommand::CheckReadL()/**Checks Read.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KReadCommand)==KErrNone) return ETrue; else return EFalse; }TPtrC CReadPCTCommand::CharSet()/**Returns used character set.*/ { return iCharSet; }//// CCharMapCommand definitions//CCharMapCommand* CCharMapCommand::NewL(TScriptStatus& aScriptStatus, CScriptReader* aScriptReader, CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv)/**2 phased constructor for CCharMapCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CCharMapCommand object.*/ { CCharMapCommand* c=new(ELeave) CCharMapCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CCharMapCommand::CCharMapCommand(TScriptStatus& aScriptStatus, CScriptReader* aScriptReader, CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv)/**Constructor for CCharMapCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.*/ {}CCharMapCommand::~CCharMapCommand()/**Destructor.*/ {} TBool CCharMapCommand::ParseL()/**Parse.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KCharmapCommand)==KErrNone) { iStatus.iOffset=end; if (!iStatus.iSkip) { iCharConv->SetDefaultCharSet(ParseCharacterTypeL(iStatus.iOffset)); } return ETrue; // Consumed } return EFalse; // Not Consumed }//// CExitCommand definiton//CExitCommand* CExitCommand::NewL(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv)/**2 phased constructor for CExitCommand, first phase.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.@exception Leaves if ConstructL() leaves, or not enough memory is available.@return a new CExitCommand object.*/ { CExitCommand* c=new(ELeave) CExitCommand(aScriptStatus,aScriptReader,aVarMan,aCharConv); CleanupStack::PushL(c); c->ConstructL(); CleanupStack::Pop(); return c; }CExitCommand::CExitCommand(TScriptStatus& aScriptStatus,CScriptReader* aScriptReader,CScriptVarMan* aVarMan,CScriptCharacterConverter* aCharConv) : CScriptCommandBase(aScriptStatus,aScriptReader,aVarMan,aCharConv)/**Constructor for CExitCommand, used in the first phase of construction.@param aScriptStatus is script status.@param aScriptReader a pointer to script reader.@param aVarMan a pointer to variable manager.@param aCharConv a pointer to script character converter.*/ {}CExitCommand::~CExitCommand()/**Destructor.*/ {}TBool CExitCommand::ParseL()/**Parses EXIT command. Parses number or variable and leaves with the appropriate value.*/ { EatSpacesAndLinesAndCommentsL(); TInt end=FindTokenEnd(iStatus.iOffset); if (iStatus.iLine.Mid(iStatus.iOffset,end-iStatus.iOffset).CompareF(KExitCommand)==KErrNone) { if (!iStatus.iSkip) { __FLOG_STMT(_LIT8(logString1,"Script:\tExecuting Exit");) __FLOG_STATIC(KNetDialLogFolder(),KNetDialLogFile(),logString1()); } iStatus.iOffset=end; EatSpaces(iStatus.iOffset); TPtrC exitStatus; TRAPD(ret,(exitStatus.Set(ParseCompoundExpressionL(iStatus.iOffset)))); if (!iStatus.iSkip) { if (ret==KErrNone) { TInt32 val; TLex lex(exitStatus); if(lex.Val(val)!=KErrNone) User::Leave(KErrInvalidNumber); if(val>0) User::Leave(KErrNumberOutOfRange); if(val==0) val=(TInt32)KErrScriptCompleted; User::Leave(val); } else if (ret==KErrNoExpression) User::Leave(KErrScriptCompleted); else { __FLOG_STMT(_LIT8(logString2,"Script:\tExit With Error %d");) __FLOG_STATIC1(KNetDialLogFolder(),KNetDialLogFile(),TRefByValue<const TDesC8>(logString2()),ret); User::Leave(ret); } } return ETrue; // Consumed } return EFalse; // Not Consumed }