diff -r 000000000000 -r b16258d2340f applayerprotocols/httptransportfw/Test/T_HttpIntegration/TEngine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applayerprotocols/httptransportfw/Test/T_HttpIntegration/TEngine.cpp Tue Feb 02 01:09:52 2010 +0200 @@ -0,0 +1,1876 @@ +// Copyright (c) 2002-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: +// $Header$ +// The CTEngine is the class that manages the test infrastructure +// It knows how to process scripts and where to find command knowledge +// The plan is: +// Process console command line or command line supplied script +// read in each line (or command) and process that (if appropriate) +// Include Files +// +// + +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- + +const TInt KMaxLogEntrySize = 512; +const TInt KMaxUserEntrySize = 128; + +//----------------------------------------------------------------------------- + +// result define names +_LIT(KLastResultCode, "$LastResult$"); +_LIT(KLastErrorCode, "$LastError$"); + +//----------------------------------------------------------------------------- + +#include "TEngine.h" + +//----------------------------------------------------------------------------- +// This is used by the CallCmdFile, CloseCmdFile and CloseCmdFiles member +// functions to alter the command file context. This function defines the +// call argument tags %0%, %1%, ... %k% to those of the present cmd file. +// If there is no command file, then the argument tags (all) are removed. + +#if !defined(TEMPLATED_CATALOGUE) + +LOCAL_C void SetContextL(CCatalogue *aCatalog, CCmdFile* aCmdFile ) + +#else + +template +LOCAL_C void SetContextL(CCatalogue *aCatalog, CCmdFile* aCmdFile ) + +#endif + +{ +if ( aCmdFile == NULL ) + { + // No command file = console context: parameter markers are not + // recognised at all i.e. remove them all. + TBuf<6> buf; + TInt i; + for ( i = 0; i <= TFR_MAX_CALL_ARGUMENTS; ++i ) + { + buf.Format( _L("%%%d%%"), i ); + aCatalog->Delete(buf); + } + } +else + { + // Command file context: parameters markers will be mapped to the + // file name, to the call arguments and to "". + TBuf<6> buf; + TPtrC arg; + TInt i; + TInt iArgs = aCmdFile->Argc(); + + for ( i = 0; ( (i < TFR_MAX_CALL_ARGUMENTS) && (i < iArgs) ); ++i ) + { + buf.Format(_L("%%%d%%"), i); + arg.Set(aCmdFile->Argv(i)); + aCatalog->Delete(buf); + aCatalog->AddL(buf,arg); + } + + for ( ; i < 10; ++i ) + { + buf.Format(_L("%%%d%%"), i); + aCatalog->Delete(buf); + aCatalog->AddL(buf, _L("")); + } + } + +} + +//----------------------------------------------------------------------------- +// Overflow handler. + +void TTestMachineOverflow::Overflow( TDes16& aDes) +{ +_LIT(KErrOverflowMsg, "..."); +if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); +} + +//----------------------------------------------------------------------------- +// NewL for Console interface + +CTEngine* CTEngine::NewL( CConsoleBase* aConsole ) +{ +CTEngine* self = NewLC(aConsole); +CleanupStack::Pop(self); +return self; +} + +//----------------------------------------------------------------------------- +// NewLC for Console Interface + +CTEngine* CTEngine::NewLC( CConsoleBase* aConsole ) +{ +CTEngine* self = new (ELeave) CTEngine(aConsole); +CleanupStack::PushL(self); +self->ConstructL(); +return self; +} + +//----------------------------------------------------------------------------- +// Destructor + +CTEngine::~CTEngine() +{ +Cancel(); + + iTimer.Close(); + iFileServer.Close(); + delete iCmdFile; + delete iLogFile; + + delete iConsoleReader; + delete iDomain; + delete iDefines; + delete iIFPile; + delete iLogPile; + delete iCmdPile; +} + +//----------------------------------------------------------------------------- + +void CTEngine::ConstructL() +{ + +iConsoleEnabled = ( iConsole != NULL ); + +iCmdPile = CPile::NewL(); +iLogPile = CPile::NewL(); +iIFPile = CPile::NewL(); + + +#if !defined(TEMPLATED_CATALOGUE) +iDefines = CCatalogue::NewL(); +#else +iDefines = CCatalogue::NewL(); +#endif + + +// domain specific catalogue of items. This provides +// a mechanism by which we can disassociate the framework +// from the domain specific commands/data requirements +iDomain = CObjCatalogue::NewL(); + +iConsoleReader = CConsoleReader::NewL(*iConsole); +TInt r = iTimer.CreateLocal(); + +if (r!=KErrNone) + User::Leave(r); + +// Provide access to the fileserver +User::LeaveIfError(iFileServer.Connect()); + +// This is normally true (to enable replication of printed +// output to log (if enabled) +iLogActivity = ETrue; + +// show the unprocessed command lines on screen and log +SetShowCmdLine(ETrue); +} + +//----------------------------------------------------------------------------- + +CTEngine::CTEngine(CConsoleBase* aConsole) + : + CActive(EPriorityStandard), + iStopped(ETrue), + iEchoMode(ETrue), + iConsole(aConsole) +{ +iConsoleEnabled = ( iConsole != NULL ); + +iCmdPath.Zero(); +iLogPath.Zero(); +iCmdline.Zero(); +iCommand.Zero(); +iPrompt.Copy(THA_CommandPrompt); + +CActiveScheduler::Add(this); +} + +//----------------------------------------------------------------------------- + +void CTEngine::SetCmdFamily(CCmdFamily* aCmdFamily) +{ +iCmdFamily = aCmdFamily; +if (aCmdFamily != NULL) + aCmdFamily->SetMachine( this ); +} + +//----------------------------------------------------------------------------- + +TBool CTEngine::ConsoleEnabled( ) +{ +return ( iConsoleEnabled ); +} + +//----------------------------------------------------------------------------- + +void CTEngine::DisableConsole() +{ +iConsoleEnabled = EFalse; +} + +//----------------------------------------------------------------------------- + +void CTEngine::EnableConsole() +{ +iConsoleEnabled = (iConsole != NULL); +} + +//----------------------------------------------------------------------------- + +CConsoleBase* CTEngine::Console() const +{ +return (iConsole); +} + +//----------------------------------------------------------------------------- + +void CTEngine::Write(const TDesC& aText) +{ +if (ConsoleEnabled()) + iConsole->Write(aText); +} + +//----------------------------------------------------------------------------- + +void CTEngine::Writeln( const TDesC& aText ) +{ +if (ConsoleEnabled()) + { + iConsole->Write(aText); + iConsole->Write(TFR_KTxtNewLine); + } +} + +//----------------------------------------------------------------------------- + +void CTEngine::Writeln() +{ +if (ConsoleEnabled()) + iConsole->Write(TFR_KTxtNewLine); +} + +//----------------------------------------------------------------------------- + +void CTEngine::Printf( TRefByValue aFmt, ... ) +{ +VA_LIST list; +VA_START( list, aFmt ); +Printf( aFmt, list ); +} + +//----------------------------------------------------------------------------- + +void CTEngine::Printf( TRefByValue aFmt, VA_LIST& aList ) +{ +if ( ConsoleEnabled() ) + { + iPrintBuf.Zero(); + TRAPD(error,iPrintBuf.AppendFormatList( aFmt, aList, &iOverflow)); + if ( error == KErrNone ) + { + iConsole->Write( iPrintBuf ); + } + else + { + iConsole->Write( TFR_KTxtErrPrintOflo ); + iConsole->Write( TFR_KTxtNewLine ); + } + } +} + +//----------------------------------------------------------------------------- + +void CTEngine::Printfln( TRefByValue aFmt, ... ) +{ +VA_LIST list; +VA_START( list, aFmt ); +Printfln( aFmt, list ); +} + +//----------------------------------------------------------------------------- + +void CTEngine::Printfln( TRefByValue aFmt, VA_LIST& aList ) +{ +if ( ConsoleEnabled( ) ) + { + iPrintBuf.Zero(); + TInt error = KErrNone; + TRAP(error,iPrintBuf.AppendFormatList( aFmt, aList, &iOverflow)); + if ( error != KErrNone ) + return; + TRAP(error,iPrintBuf.AppendFormat( _L("%S"), &iOverflow, &TFR_KTxtNewLine )); + if (error == KErrNone ) + { + iConsole->Write( iPrintBuf ); + } + else + { + iConsole->Write( TFR_KTxtErrPrintOflo ); + iConsole->Write( TFR_KTxtNewLine ); + } + } +} + +//----------------------------------------------------------------------------- + +void CTEngine::Pause(const TDesC& aPrompt) +{ +if (ConsoleEnabled()) + { + iCmdline.Zero(); + iConsole->Write(aPrompt); + if (!IsActive()) + SetActive(); + iConsoleReader->ReadChar(iCmdline, iStatus); + } +else + CompleteRequest(); +} + +//----------------------------------------------------------------------------- + +void CTEngine::Hold(TTimeIntervalMicroSeconds32 aInterval) +{ +iTimer.After(iStatus, aInterval); +SetActive(); +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::SetCmdPath( const TDesC& aPath ) +{ +if (aPath.Length() == 0) + { + Printf(_L("Path is set to: %S\r\n"), &iCmdPath); + return KErrNone; + } + +if (iParse.SetNoWild( aPath, NULL, NULL ) != KErrNone) + return KErrArgument; + +if (!iParse.PathPresent() || iParse.NameOrExtPresent()) + return KErrArgument; + +// set it +iCmdPath.Copy(aPath); + +// echo it +Printf(_L("Path is set to: %S\r\n"), &iCmdPath); + +return KErrNone; +} + +//----------------------------------------------------------------------------- + +TPtrC CTEngine::CmdPath() const +{ +TPtrC path(iCmdPath); +return path; +} + +//----------------------------------------------------------------------------- + +TPtrC CTEngine::FileName() const +{ +TPtrC fileName(iFileName); +return fileName; +} + +//----------------------------------------------------------------------------- +// parameterless version + +TInt CTEngine::CallCmdFile(const TDesC& aFile) +{ +return CallCmdFile(aFile, _L("")); +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::CallCmdFile(const TDesC &aFile, const TDesC &aArgs) +{ +// Make CCmdFile object. +CCmdFile *file = NULL; +TRAPD(error, file = CCmdFile::NewL()); +if ( error != KErrNone ) + return error; + +error = file->Open(iCmdPath, aFile); +if ( error != KErrNone ) + { + delete file; + + // print file x not found echo it + Printf(_L("Error: file [%S] not found\r\n"), &aFile); + Printf(_L(" Check file path <%S>\r\n"), &iCmdPath); + return error; + } + +// Save file name and arguments. +TRAP(error, file->AddArgsL(aFile)); +if (error == KErrNone) + TRAP(error, file->AddArgsL(aArgs)); + +if ( error != KErrNone ) + { + delete file; + return error; + } + +// Check that not too many call arguments. +if ( file->Argc() > (TFR_MAX_CALL_ARGUMENTS + 1)) + { + delete file; + return error = KErrArgument; + } + +// Push present command file to cmdfile pile. +TRAP(error, iCmdPile->PushL( iCmdFile )); +if ( error != KErrNone ) + { + delete file; + return error; + } + +// Switch context to the called command file. +iCmdFile = file; +file = NULL; +TRAP(error, SetContextL(iDefines, iCmdFile)); +return error; +} + +//----------------------------------------------------------------------------- + +CCmdFile* CTEngine::CmdFile() +{ +return iCmdFile; +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::CloseCmdFile() +{ +// Get rid of the present command file (NULL iCmdFile is Ok). +delete iCmdFile; +iCmdFile = NULL; + +// Pop the previous one from the pile (returns NULL if none). +iCmdFile = iCmdPile->Pop(); + +// Switch context to that file (NULL iCmdFile does no harm). +TRAPD(error,SetContextL(iDefines,iCmdFile)); +return error; +} + +//----------------------------------------------------------------------------- + +void CTEngine::CloseCmdFiles() +{ +// Pop and delete all previous command files from the file pile. +iCmdPile->Empty(); + +// Get rid of the present file as well (NULL iCmdFile is Ok). +delete iCmdFile; +iCmdFile = NULL; + +// Switch context to "no command file" (since iCmdFile = NULL). +TRAP_IGNORE(SetContextL(iDefines,iCmdFile)); // doesn't LEAVE, see yourself +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::SetLogPath( const TDesC& aPath ) +{ +if (aPath.Length() == 0) + { + iLogPath.Zero(); + return KErrNone; + } + +if (iParse.SetNoWild( aPath, NULL, NULL ) != KErrNone) + return KErrArgument; + +if (!iParse.PathPresent() || iParse.NameOrExtPresent()) + return KErrArgument; + +TInt error; +RFs fs; +if (error = fs.Connect(), error == KErrNone) + { + error = fs.MkDirAll( iParse.DriveAndPath()); + if (error == KErrAlreadyExists) + error = KErrNone; + + fs.Close(); + if (error == KErrNone) + iLogPath.Copy(aPath); + } +return error; +} + +//----------------------------------------------------------------------------- + +TPtrC CTEngine::LogPath() const +{ +TPtrC logpath(iLogPath); +return logpath; +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::OpenLogFile(const TDesC& aFile) +{ +// Construct a full log file. +TInt error = iParse.Set(aFile, NULL, &iLogPath); +if (error != KErrNone) + return error; + +// Construct and open the new log file. +CLogFile* file = NULL; +TRAP(error, file = CLogFile::NewL()); +if ( error != KErrNone ) + return error; + +error = file->Open( iParse.FullName() ); +if ( error == KErrNone && iLogFile != NULL ) + { + // Close and save the present log file. + iLogFile->Close(); + TRAP(error, iLogPile->PushL(iLogFile)); + if ( error == KErrNone ) + iLogFile = NULL; + } + +if (error == KErrNone) + { + // Switch the log file. + file->PrintHeading(); + iLogFile = file; + file = NULL; + } + +delete file; // is NULL if no errors! +return error; +} + +//----------------------------------------------------------------------------- + +CLogFile *CTEngine::LogFile() +{ +return iLogFile; +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::CloseLogFile( ) +{ +delete iLogFile; +iLogFile = NULL; +iLogFile = iLogPile->Pop(); +TInt error = KErrNone; +if ( iLogFile != NULL ) + error = iLogFile->Open(); +return error; +} + +//----------------------------------------------------------------------------- + +void CTEngine::CloseLogFiles() +{ +TInt count = iLogPile->Count(); +while (count > 0 ) + { + CLogFile* file = iLogPile->Pop(); + delete file; // NULL does no harm! + } + +delete iLogFile; +iLogFile = NULL; +} + +//----------------------------------------------------------------------------- + +void CTEngine::LogWrite( const TDesC& aText ) +{ +if ( iLogFile != NULL ) + iLogFile->Write( aText ); +} + +//----------------------------------------------------------------------------- + +void CTEngine::LogWriteln( const TDesC& aText ) +{ +if ( iLogFile != NULL ) + iLogFile->Writeln( aText ); +} + +//----------------------------------------------------------------------------- + +void CTEngine::LogWriteln() +{ +if ( iLogFile != NULL ) + iLogFile->Writeln(); +} + +//----------------------------------------------------------------------------- + +void CTEngine::LogPrintf( TRefByValue aFmt, ... ) +{ +VA_LIST list; +VA_START(list, aFmt); +LogPrintf(aFmt, list); +} + +//----------------------------------------------------------------------------- + +void CTEngine::LogPrintf( TRefByValue aFmt, VA_LIST& aList ) +{ +if (iLogFile != NULL) + iLogFile->Printf(aFmt, aList); +} + +//----------------------------------------------------------------------------- + +void CTEngine::LogPrintfln( TRefByValue aFmt, ... ) +{ +VA_LIST list; +VA_START(list, aFmt); +LogPrintfln(aFmt, list); +} + +//----------------------------------------------------------------------------- + +void CTEngine::LogPrintfln( TRefByValue aFmt, VA_LIST& aList ) +{ +if (iLogFile != NULL) + { + iLogFile->Printf(aFmt, aList); + iLogFile->Writeln(); + } +} + +//----------------------------------------------------------------------------- +// Standard message output: +// - CTEngine::MsgWrite +// - CTEngine::MsgWriteln +// - CTEngine::MsgWriteln +// - CTEngine::MsgPrintf +// - CTEngine::MsgPrintf +// - CTEngine::MsgPrintfln +// - CTEngine::MsgPrintfln +// +// A message goes to the log if there is one open. The message is printed +// to the display as well, except when having echo mode off and running a +// command file. +// +//----------------------------------------------------------------------------- + +void CTEngine::MsgWrite(const TDesC& aText) +{ +LogWrite(aText); +if (EchoMode() || (iCmdFile == NULL)) + Write(aText); +} + +//----------------------------------------------------------------------------- + +void CTEngine::MsgWriteln(const TDesC& aText) +{ +LogWriteln(aText); +if (EchoMode() || (iCmdFile == NULL)) + Writeln(aText); +} + +//----------------------------------------------------------------------------- + +void CTEngine::MsgWriteln() +{ +LogWriteln(); +if (EchoMode() || (iCmdFile == NULL)) + Writeln(); +} + +//----------------------------------------------------------------------------- + +void CTEngine::MsgPrintf( TRefByValue aFmt, ... ) +{ +VA_LIST list; +VA_START( list, aFmt ); +MsgPrintf( aFmt, list ); +} + +//----------------------------------------------------------------------------- + +void CTEngine::MsgPrintf( TRefByValue aFmt, VA_LIST& aList ) +{ +if ( EchoMode() || (iCmdFile == NULL) ) + { + VA_LIST clone; + Mem::Move( &clone, &aList, sizeof(VA_LIST) ); + LogPrintf( aFmt, aList ); + Printf( aFmt, clone ); + } +else + { + LogPrintf( aFmt, aList ); + } +} + +//----------------------------------------------------------------------------- + +void CTEngine::MsgPrintfln( TRefByValue aFmt, ... ) +{ +VA_LIST list; +VA_START( list, aFmt ); +MsgPrintfln( aFmt, list ); +} + +//----------------------------------------------------------------------------- + +void CTEngine::MsgPrintfln( TRefByValue aFmt, VA_LIST& aList ) +{ +if ( EchoMode() || (iCmdFile == NULL) ) + { + VA_LIST clone; + Mem::Move( &clone, &aList, sizeof(VA_LIST) ); + LogPrintfln( aFmt, aList ); + Printfln( aFmt, clone ); + } +else + LogPrintfln(aFmt, aList); +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::SetPrompt(const TDesC& aPrompt) +{ +// Return error in case a too long prompt was proposed. +if (aPrompt.Length() > iPrompt.MaxLength()) + return KErrTooBig; + +// Otherwise alter trhe prompt and return Ok. +iPrompt.Copy(aPrompt); +return KErrNone; +} + +//----------------------------------------------------------------------------- + +TPtrC CTEngine::Prompt() const +{ +TPtrC prompt(iPrompt); +return prompt; +} + +//----------------------------------------------------------------------------- +// Run +// Start things off! We have a variety of options: +// 1. interactive. (no params) => Call Run() +// 2. semi-interactive. (some params, no script) => Call Run(Args) +// 3. automatic. (some params & script) => Run(Script, Args) + +void CTEngine::Run() +{ +if (!IsActive()) + { + // Start the engine and set the state to get the next cmd + iStopped = EFalse; + iState = EGetNextCmd; + + // Complete request + CompleteRequest(); + } +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::Run(const TDesC& aFile) +{ +return Run(aFile, _L("")); +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::Run(const TDesC& aFile, const TDesC& aArgs) +{ +iStopped = EFalse; + +// Open (call) the command file. Stop test engine if fails. +TInt error = CallCmdFile(aFile, aArgs); +if (error != KErrNone) + StopEngine(); + +// Keep going until stopped or reading the commands fails. +while ((!iStopped) && (error == KErrNone)) + { + error = ReadCmdline(EFalse); + if (error == KErrNone) + { + if (MakeCommand() == KErrNone) + { + TRAP(error,(void) ObeyCommandL()); + } + } + } + +// Make sure that command files and log files get closed and return. +CloseCmdFiles(); +CloseLogFiles(); +return error; +} + +//----------------------------------------------------------------------------- +// CTEngine::Terminate +// +// Terminate processing of command files. If not inside a command file, +// then does not do anything - doesn't even close the opened log files. + +void CTEngine::Terminate() +{ +// Inside command file? +if (iCmdFile != NULL) + { + + // Close all command files. + CloseCmdFiles(); + + // Close all log files. Write the "run aborted" message to the end + // of every log file. + while (iLogPile->Count() > 0) + { + // There is yet at least one log file in pile: write the abort + // message and close => previous file in pile will be opened. + LogWriteln( TFR_KTxtMsgRunAborted ); + (void)CloseLogFile(); + } + + // Close the very last log file too. Having iLogFile = NULL is not + // checkd in here because that doesn't do any harm. + LogWriteln( TFR_KTxtMsgRunAborted ); + delete iLogFile; + iLogFile = NULL; + + // Print abort message to console too. + Writeln( TFR_KTxtMsgRunAborted ); + } +} + +//----------------------------------------------------------------------------- + +void CTEngine::StopEngine( ) +{ +iStopped = ETrue; +CloseCmdFiles(); + +// Print message to console +Writeln(TFR_KTxtMsgRunStopped); +} + +//----------------------------------------------------------------------------- + +TBool CTEngine::Stopped() +{ +return iStopped; +} + +//----------------------------------------------------------------------------- + +void CTEngine::SetEchoMode(const TBool &aBoolean) +{ +iEchoMode = aBoolean; +} + +//----------------------------------------------------------------------------- + +TBool CTEngine::EchoMode() +{ +return iEchoMode; +} + +//----------------------------------------------------------------------------- + +#if !defined(TEMPLATED_CATALOGUE) +CCatalogue *CTEngine::Defines() +#else +CCatalogue *CTEngine::Defines() +#endif +{ +return iDefines; +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::ReadCmdline(TBool aConsole) +{ + +// Reset cmd. +iCmdline.Zero(); + +TInt error = KErrNone; +if (iCmdFile != NULL) + error = ReadCmdFile(); + +else + // Set error to imply that the end of the cmd file has been reached + error = KErrEof; + +if ((error == KErrEof) && aConsole ) + // Get the next cmd line from the console + error = ReadConsole(); + +return error; +} + +//----------------------------------------------------------------------------- +// Read command line (iCmdline) from command files. + +TInt CTEngine::ReadCmdFile() +{ + +// Reset cmd and read from the command files. Close files if at end. +iCmdline.Zero(); +TInt error = KErrEof; +while ((iCmdFile != NULL) && (error == KErrEof)) + { + error = iCmdFile->Read(iCmdline); + if (error == KErrEof) + { + error = CloseCmdFile(); + if (error == KErrNone) + error = KErrEof; + } + else + CompleteRequest(); + + } + +return error; +} + +//----------------------------------------------------------------------------- +// Read command line (iCmdline) from console. + +TInt CTEngine::ReadConsole() +{ +// Get cmd from console - first write prompt. +iConsole->Write(iPrompt); +iConsoleReader->ReadLine(iCmdline, iStatus); +SetActive(); + +return KErrNone; +} + +//----------------------------------------------------------------------------- + +TPtrC CTEngine::GetDefine(const TDesC &aTag) const +{ +TPtrC iVal; +TInt len = aTag.Length(); + +for (TInt i = 0; i < iDefines->Count(); ++i) + { + CLabeledText *tag = iDefines->At(i); + TInt pos = tag->Label().Find(aTag); + //make sure that 'xyz' does not match with '$xyz_abcd$' + if ( (pos == 1) && (tag->Label().Length() == len+2) ) + { + iVal.Set(tag->Value()); + break; + } + } + +return iVal; +} + +//----------------------------------------------------------------------------- +// Make the command (iCommand) to obey. Copies the command line (iCmdline) +// to the iCommand buffer and expands the tags to their defined values. If +// fails, prints out the original command line and an error message. + +TInt CTEngine::MakeCommand() +{ +TInt error = KErrNone; + +// Copy command line from iCmdline buffer to iCommand buffer. +iCommand.Copy(iCmdline); + +// Expand tags = replace tag markers with their defined values. +TInt counter = 0; +TBool proceed = ETrue; +while (proceed && (error == KErrNone)) + { + // One round = replace all tag labels with their values and + // alter the proceed to ETrue in replaced one or more tags. + proceed = EFalse; + for (TInt i = 0; i < iDefines->Count(); ++i) + { + CLabeledText *tag = iDefines->At(i); + TInt pos = iCommand.Find(tag->Label()); + if (pos >= 0) + { + + // More than a hundred replacements as the whole is + // propably due to an infinite loop ( recursive tag + // definitions ): + if (counter > 99) + { + // Propably recursive tag definitions. + MsgWriteln(TfrLex::Trim(iCmdline)); + MsgWriteln(TFR_KTxtErrRecursiveTags); + error = KErrOverflow; + break; + } + + // Check that this very tag replacement won't cause + // overflow in command buffer. + TInt newlength = iCommand.Length() - tag->Label().Length(); + newlength += tag->Value().Length(); + if (newlength > iCommand.MaxLength()) + { + // Command has grown too big in size. + MsgWriteln(TfrLex::Trim( iCmdline)); + MsgWriteln(TFR_KTxtErrTooLongCmd); + error = KErrOverflow; + break; + } + + // Fine, replace the tag with its defined value and + // mark that there shall be at least one more round. + proceed = ETrue; + iCommand.Replace(pos, tag->Label().Length(), tag->Value()); + ++counter; // keep up total count of replacements. + } + } // end-for + } // end-while + +// Return if everything went fine. +if ( error == KErrNone ) + return error; + +// Otherwise terminate command files, unless when in check mode. +if ( (iCmdFamily == NULL) || !iCmdFamily->Switch(CCmdFamily::EParseOnly) ) + Terminate(); + +return error; +} + +//----------------------------------------------------------------------------- + +TInt CTEngine::ObeyCommandL() +{ +TInt error = KErrNone; + +// The command is handled without the leading/trailing spaces. +TPtrC cmd = TfrLex::Trim(iCommand); + +// The command shall be echoed if echo mode is On and command +// was read from a command file. +TBool doEcho = (iEchoMode && (iCmdFile != NULL)); + +// Check if command begins with @ character and remove if yes. +// That kind of commands aren't echoed afterall. +if (cmd.Match(_L("@*")) == 0) + { + // Command is not echoed afterall. + doEcho = EFalse; + + // Remove @ and them trim once more. + cmd.Set(cmd.Ptr()+1, cmd.Length()-1); + cmd.Set(TfrLex::TrimLeft(cmd)); + } + +// Look up from Command Family if there's a registered command to +// handle this very command string. If there is no Command Family +// then there is no handler either. +// bear in mind that we have to possibly skip a valid command if +// our if mode directs us... +CCmdBase *handler = NULL; +if (iCmdFamily != NULL) + handler = iCmdFamily->Recognize(cmd); + +if (handler != NULL) + { + TBool stepover = DetermineStepover(handler); + + if (!stepover) + { + // This one shall be processed. + // ---------------------------- + // Echo the original input command to the display. + + // log command and display the command on the screen if appropriate + if (iShowCmdLine) + MsgWriteln(iCmdline); + else if (doEcho) + Writeln(TfrLex::TrimRight(iCommand)); + + // Write into the log unless that has been prevented. + // and then process the command. + error = handler->ProcessL(cmd); + } + else + // This one shall not be processed. + // -------------------------------- + // Command it is not written to log nor echoed either. + { + error = handler->ProcessStepOverL(); + } + + } +else + { + // There was no handler for this command i.e. it's an unknown + // command and we don't known what to do with it. However, if + // the processing is in step over mode odds commands are here + // silently ignored (not echoed either). + + if (iCmdFamily->StepOver()) + // Step over mode: ignore odd command silently. + error = KErrNone; + + else + { + // Otherwise, echo the original input command to display + // and log an error message. + if (doEcho) + Writeln(TfrLex::TrimRight(iCommand)); + LogWriteln(cmd); + MsgWriteln(TFR_KTxtErrUnknownCmd); + error = KErrNotFound; + } + } + +// if the last command was a 'domain' command store the result (deano requirement) +// unless the last command was IF! +if (handler == NULL || (handler->CommandId() < THA_KCmdMaxStandard)) + ;// do nothing +else + SetErrorDefine(error); + +// As we are recording the value of the return, it is no longer necessary +// to abort here - let the 'script' worry about subsequent action if required + +// Return if successful. +//if (error == KErrNone) +// return error; +// Error/failure: terminate command files, unless when check mode. +//if ((iCmdFamily == NULL) || !iCmdFamily->Switch(CCmdFamily::EParseOnly)) + //Terminate(); + +return error; +} + + +//----------------------------------------------------------------------------- +// Assign the passed value to the last result define + +TBool CTEngine::DetermineStepover(CCmdBase *aHandler) +{ +// Handler was found: check if the command is to be processed +// and if the command is among those to write into the log. +// dont forget to check the if, else, endif situation +// first - incase the if mode needs changing +TBool iSOver = aHandler->StepOver(); + +// we must be aware of the problem of nested loops +// we must 'count' and 'match' the intervening if/else/endif's +// until we get back to our current level +// +// to do this, we need to know what command is being executed +// and use that and the current state to work out where we are. +// At this point we have not set the ifstate so we can predetermine +// the next move. +// +// NOTE: If we encounter if's we must process them (if they are part +// of the correct branch! + +CIFControl::TIFMode eIFMode = GetIfMode(); +CIFControl::TIFProcessing eIFState = GetIfState(); + +// iBranch merely tells us if the current clause return true/false +// not which branch is being executed (thats from eIFState) +TBool iBranch = (iIFPile->Peek()) ? (iIFPile->Peek())->GetIFResult() : EFalse; +TInt iCmd = aHandler->CommandId(); +TBool iInSubClause = EFalse; +switch (iCmd) + { + case THA_KCmdIf : + + // we've encountered an IF statement, which should be processed ONLY + // if we're in the correct branch of a current IF + // if the if is FALSE we still need to count the internal IFs/ELSE/ENDIFs as normal + switch (eIFState) + { + // we are in the middle of an if,else,endif block note: the logic here is tortuous! + // iIfState is true if the IF was true + case CIFControl::EInIF : + + // process the IF if we're in the correct (true) clause this will start + // another IF object (unless it's false) + iSOver = (eIFMode == CIFControl::EELSETrue); + if (iSOver) + // we now have to count the else's and endifs as we're not processing the IF! + { + if (iIFPile->Peek()) + (iIFPile->Peek())->If(); + } + break; + + case CIFControl::EInELSE : + + iSOver = (eIFMode == CIFControl::EIFTrue); + if (iSOver) + { + if (iIFPile->Peek()) + (iIFPile->Peek())->Else(); + } + break; + + // must be a 'virgin' IF so ensure we call it! + default : iSOver = EFalse; break; + } + break; + + case THA_KCmdElse : + + // we're already in an IF or ELSE so merely continue as 'normal' + switch (eIFState) + { + // We should execute the ELSE as this sets up the state var but not the subsequent + // commands as necessary. We are in the middle of an if,else,endif block + // note: the logic here is tortuous! iIfState is true if the IF was true (i.e. + case CIFControl::EInIF : + if (iIFPile->Peek()) + // we need to ensure we're accounting for outer IF's etc + // we need to ensure we process it correctly + iInSubClause = ((iIFPile->Peek())->GetIfCount() > 0) ? ETrue : EFalse; + + if (iInSubClause) + iSOver = iInSubClause; + else + // if the subclause is subject to fail then we should ignore this completely + //iSOver = (eIFMode == CIFControl::EELSETrue) ? ETrue : EFalse; + // if the subclause is subject to fail then we should ignore this completely + // unless we are supposed to execute it... + if (iBranch) + iSOver = (eIFMode == CIFControl::EELSETrue) ? ETrue : EFalse; + else + iSOver = (eIFMode == CIFControl::EELSETrue) ? EFalse : ETrue; + + if (iSOver) + { + if (iIFPile->Peek()) + (iIFPile->Peek())->Else(); + } + break; + + case CIFControl::EInELSE : + if (iIFPile->Peek()) + // we need to ensure we're accounting for outer IF's etc + // we need to ensure we process it correctly + iInSubClause = ((iIFPile->Peek())->GetIfCount() > 0) ? ETrue : EFalse; + + if (iInSubClause) + iSOver = iInSubClause; + else + // if the subclause is subject to fail then we should ignore this completely + // unless we are supposed to execute it... + if (iBranch) + iSOver = (eIFMode == CIFControl::EELSETrue) ? ETrue : EFalse; + else + iSOver = (eIFMode == CIFControl::EELSETrue) ? EFalse : ETrue; + + if (iSOver) + { + if (iIFPile->Peek()) + (iIFPile->Peek())->Else(); + } + break; + + default : + // accept current iSOver state but if we're in the non-executing + // branch of current clause, increment the else count and ensure we + // skip the command + if (!iBranch) + { + if (iIFPile->Peek()) + (iIFPile->Peek())->Else(); + iSOver = true; + } + break; + } + break; + + // ok, here's where the real 'meat' of the situation + case THA_KCmdEndIf : + { + + // we MUST be in an IF sequence, but we also need to be aware + // of the state of any outer IF clause + if (iIFPile->Peek()) + { + // before we decrement our counters, we need to see the state of play + // if we're in an IF which is part of an untrue IF clause *see if test9/10* + // we need to ensure we process it correctly + TInt iIfs = (iIFPile->Peek())->GetIfCount(); + //TInt iElses = (iIFPile->Peek())->GetElseCount(); + iInSubClause = (iIfs == 0) ? EFalse : ETrue; + //iInSubClause = ( (iIfs == 0) && (iElses == 0) ) ? EFalse : ETrue; + + // decrement our counters. If we are NOT in a SubClause then these will + // be zero. If so we SHOULD execute the ENDIF + (iIFPile->Peek())->EndIf(); + } + + switch (eIFState) + { + // we are in the middle of an if,else,endif block + // note: the logic here is tortuous! + // iIfState is true if the IF was true (i.e. + //iSOver = iIfState; break; + case CIFControl::EInIF : + iSOver = (iSOver || (eIFMode == CIFControl::EELSETrue)) && iInSubClause; + break; + case CIFControl::EInELSE : + iSOver = (iSOver || (eIFMode == CIFControl::EIFTrue)) && iInSubClause; + break; + default : + if (iInSubClause) + iSOver = ETrue; + break; + } + break; + } + + // other commands must be checked against our if state! + default : + switch (eIFState) + { + case CIFControl::EInIF : + switch (eIFMode) + { + case CIFControl::EIFTrue : iSOver = EFalse; break; + case CIFControl::EELSETrue : iSOver = ETrue; break; + default : iSOver = ETrue; break; // ????? + } + break; + + case CIFControl::EInELSE : + switch (eIFMode) + { + case CIFControl::EIFTrue : iSOver = ETrue; break; + case CIFControl::EELSETrue : iSOver = EFalse; break; + default : iSOver = ETrue; break; // ????? + //case CIFControl::EENDIF : iSOver = !iBranch; break; + } + break; + + default : + switch (eIFMode) + { + case CIFControl::EIFTrue : iSOver = ETrue; break; + case CIFControl::EELSETrue : iSOver = EFalse; break; + default : iSOver = EFalse; break; // ????? + //case CIFControl::EENDIF : iSOver = ETrue; break; + } + break; + } + break; + } + +return iSOver; +} + +//----------------------------------------------------------------------------- +// Assign the passed value to the last result define + +void CTEngine::SetResultDefine(TInt aValue) + { + TInt error; + + // so that we can process it if required - code stolen from CmdDefine... + TBuf<16+2> taglabel; + taglabel.Format(KLastResultCode); + + // Set tag value to be the last error code received + TBuf<12> tagvalue; + tagvalue.Format(_L("%d"), aValue); + CLabeledText *tag = Defines()->Text(taglabel); + if (tag != NULL) + { + // alter tag + TRAP(error, tag->SetL(tagvalue)); + } + else + { + // Add a tag. + TRAP(error, Defines()->AddL(taglabel, tagvalue)); + } + } + +void CTEngine::SetResultDefine (const TDesC& aDefineTxt, TInt aValue) + { + TInt error; + + TBuf<32+2> taglabel; + + taglabel.Format(_L("$%SHttpStatus$"), &aDefineTxt); + + // Set tag value to be the last error code received + TBuf<16> tagvalue; + tagvalue.Format(_L("%d"), aValue); + CLabeledText *tag = Defines()->Text(taglabel); + + if (tag != NULL) + { + TRAP(error, tag->SetL(tagvalue)); + } + else + { + // Add a tag. + TRAP(error, Defines()->AddL(taglabel, tagvalue)); + } + } + +void CTEngine::DeleteResultDefine (const TDesC& aDefineTxt) + { + TBuf<32+2> taglabel; + + taglabel.Format(_L("$%SHttpStatus$"), &aDefineTxt); + + Defines()->Delete(taglabel); + } + +//----------------------------------------------------------------------------- +// Assign the passed value to the last result define + +void CTEngine::SetErrorDefine(TInt aValue) + { + TInt error; + + // so that we can process it if required - code stolen from CmdDefine... + TBuf<16+2> taglabel; + taglabel.Format(KLastErrorCode); + + // Set tag value to be the last error code received + TBuf<12> tagvalue; + tagvalue.Format(_L("%d"), aValue); + CLabeledText *tag = Defines()->Text(taglabel); + if (tag != NULL) + { + // alter tag + TRAP(error, tag->SetL(tagvalue)); + } + else + { + // Add a tag. + TRAP(error, Defines()->AddL(taglabel, tagvalue)); + } + } + +void CTEngine::SetErrorDefine (const TDesC& aDefineTxt, TInt aValue) + { + TInt error; + + TBuf<32+2> taglabel; + + taglabel.Format(_L("$%SLastEvent$"), &aDefineTxt); + + // Set tag value to be the last error code received + TBuf<16> tagvalue; + tagvalue.Format(_L("%d"), aValue); + CLabeledText *tag = Defines()->Text(taglabel); + + if (tag != NULL) + { + TRAP(error, tag->SetL(tagvalue)); + } + else + { + // Add a tag. + TRAP(error, Defines()->AddL(taglabel, tagvalue)); + } + } + +void CTEngine::DeleteErrorDefine (const TDesC& aDefineTxt) + { + TBuf<32+2> taglabel; + + taglabel.Format(_L("$%SLastEvent$"), &aDefineTxt); + + Defines()->Delete(taglabel); + } + +//----------------------------------------------------------------------------- +// Called by the scheduler evert time request completed. + +void CTEngine::RunL() +{ +switch (iState) + { + case EIdle: + if (iStopped) + // We've finished - close resources... + { + CloseCmdFiles(); + CloseLogFiles(); + + // Cancel... + Cancel(); + + // Stop the active scheduler only if we're driven via commandline script. + // if via interactive then has no meaning! + //if (Console != NULL) + CActiveScheduler::Stop(); + } + break; + + case EStopping: + { + // Close any open sessions and their transactions + if ( iCmdFamily != NULL ) + { + // Perform any operational close/shutdown operations here + //CCmdBase *handler = NULL; + //handler = iCmdFamily->Command(EDoClose); + //STATIC_CAST(CCmdDoClose*, handler)->CloseAll(); + } + iState = EIdle; + } + CompleteRequest(); + break; + + case EGetNextCmd: + // Get the next cmd + if (ReadCmdline(iConsoleEnabled) != KErrNone) + { + // Something went wrong, so stop + iStopped = ETrue; + iState = EIdle; + + // Complete self + CompleteRequest(); + } + else + // Parse the next cmd once we get it + iState = EParseCurrentCmd; + break; + + case EParseCurrentCmd: + // Run the parsed cmd or Could not parse the cmd line so get the next cmd + iState = (MakeCommand() == KErrNone) ? ERunCurrentCmd : EGetNextCmd; + + // Complete self and set active + CompleteRequest(); + break; + + case ERunCurrentCmd: + { + TInt iErr = ObeyCommandL(); + + // Run the cmd - the cmd will complete the request + if (iErr != KErrNone) + { + // if major problem then complete the request + if (!IsActive()) + CompleteRequest(); + else // command requested produced subsequent operational error (i.e. what we're looking for!) + { + // assign the response to an accessible 'variable' + } + } + + // Set state... + iState = (!iStopped) ? EGetNextCmd : EStopping; + } + + break; + + default : break; + } +} + +//----------------------------------------------------------------------------- + +void CTEngine::DoCancel() +{ +iTimer.Cancel(); +iConsoleReader->ReadCancel(); +} + +//----------------------------------------------------------------------------- +// Standard Issue... + +void CTEngine::CompleteRequest() +{ +if (IsActive()) + return ; + +TRequestStatus* pStat = &iStatus; + +User::RequestComplete(pStat, KErrNone); +SetActive(); +} + +//----------------------------------------------------------------------------- +// was 'GetAnEntry' but that is slightly inaccurate! + +void CTEngine::GetUserInput(const TDesC& ourPrompt, TDes& currentstring) +{ +TBuf16 ourLine; +TBuf tempstring; //tempstring is a unicode descriptor + +// create a temporary buffer where the unicode strings are stored in order to +// be displayed +ourLine.Zero(); +tempstring.Copy(currentstring); //Copy current string to Unicode buffer +TKeyCode key = EKeyNull; //current string buffer is 8 bits wide. + +// Unicode string bufffer (tempstring) is 16 bits wide. +FOREVER + { + if (ourLine.Length () == 0) + { + + iConsole->SetPos (0, iConsole->WhereY ()); + iConsole->Printf (_L ("%S"), &ourPrompt); + if (tempstring.Length () != 0) //get tempstring's number of items + iConsole->Printf (_L (" = %S"), &tempstring); //if not zero print them to iTest.Console() + iConsole->Printf (_L (" : ")); + iConsole->ClearToEndOfLine (); + } + + key = iConsole->Getch(); + + if (key == EKeyBackspace) + { + if (ourLine.Length() !=0) + { + ourLine.SetLength(ourLine.Length()-1); + iConsole->Printf(_L ("%c"), key); + iConsole->SetPos(iConsole->WhereX(), iConsole->WhereY()); + iConsole->ClearToEndOfLine(); + } // end if (ourLine.Length() !=0) + } // end if (key == KeyBackSpace) + + + if (key == EKeyDelete) + { + ourLine.Zero(); + iConsole->SetPos(0, iConsole->WhereY()); + iConsole->ClearToEndOfLine(); + tempstring.Copy(ourLine); + break; + } + + if (key == EKeyEnter) + break; + + if (key < ' ') // ascii code thats not a printable character + continue; + + ourLine.Append(key); + iConsole->Printf(_L ("%c"), key); + iConsole->SetPos(iConsole->WhereX(), iConsole->WhereY()); + iConsole->ClearToEndOfLine(); + if (ourLine.Length () == ourLine.MaxLength ()) + break; + } // end of for statement + +if ((key == EKeyEnter) && (ourLine.Length () == 0)) + tempstring.Copy (currentstring); //copy contents of 8 bit "ourLine" descriptor + +iConsole->SetPos(0, iConsole->WhereY()); +iConsole->ClearToEndOfLine(); + +if ((key == EKeyEnter) && (ourLine.Length() !=0)) + tempstring.Copy(ourLine); + +if (tempstring.Length () != 0) //if temstring length is not zero + { + iConsole->Printf(_L(" Entered = %S\n"), &tempstring); //print the contents to iTest.Console() + LogPrintf(_L("%S = %S\n"), &ourPrompt, &tempstring); + } + +iConsole->Printf (_L("\n")); +currentstring.Copy(tempstring); //copy 16 bit tempstring descriptor back +} + +//----------------------------------------------------------------------------- +// File Management and Support +// note: this takes the current 'path' as defined by PATH as the root file path +// if defined. + +TInt CTEngine::SetFileName(const TDesC &aName, RFile &aReqFile) + { + TBuf<256> ourFile(iCmdPath); + ourFile.Append(aName); + + TParse ParsedFileName; + TInt iError = ParsedFileName.Set(ourFile, NULL, NULL); + + if (iError == KErrNone) + {// check is a valid file and open a handle + + // assign the filename to our reference + TFileName fileName; + fileName.Copy(ParsedFileName.FullName()); + + if (iFileServer.IsValidName(fileName)) + { + iError = aReqFile.Open(iFileServer, ParsedFileName.FullName(), EFileRead); + } + } + + return iError; + } + +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Do a formatted dump of binary data, optionally logging it +// Iterate the supplied block of data in blocks of 16 bytes + +void CTEngine::DumpData(const TDesC8& aData, const TBool &logIt) +{ +TInt pos = 0; +TBuf logLine; +TBuf anEntry; + +while (pos < aData.Length()) + { + anEntry.Format(TRefByValue_L("%04x : "), pos); + logLine.Append(anEntry); + + // Hex output + TInt offset; + for (offset = 0; offset < 16; ++offset) + { + if (pos + offset < 10)//aData.Length()) + { + TInt nextByte = aData[pos + offset]; + anEntry.Format(TRefByValue_L("%02x "), nextByte); + logLine.Append(anEntry); + } + else + { + anEntry.Format(TRefByValue_L(" ")); + logLine.Append(anEntry); + } + } + + anEntry.Format(TRefByValue_L(": ")); + logLine.Append(anEntry); + + // Char output + for (offset = 0; offset < 16; ++offset) + { + if (pos + offset < 10)//aData.Length()) + { + TInt nextByte = aData[pos + offset]; + if ((nextByte >= 32) && (nextByte <= 127)) + { + anEntry.Format(TRefByValue_L("%c"), nextByte); + logLine.Append(anEntry); + } + else + { + anEntry.Format(TRefByValue_L(".")); + logLine.Append(anEntry); + } + } + else + { + anEntry.Format(TRefByValue_L(" ")); + logLine.Append(anEntry); + } + } + + if (logIt) + LogPrintf(TRefByValue_L("%S"), &logLine); + + // Advance to next 16 byte segment + pos += 16; + } +} + +//----------------------------------------------------------------------------- + +CIFControl::TIFMode CTEngine::GetIfMode() +{ +return (iIFPile->Peek()) ? (iIFPile->Peek())->GetIFMode() : CIFControl::ENotIf; +} + +//----------------------------------------------------------------------------- + +void CTEngine::SetIfMode(const CIFControl::TIFMode &eMode) +{ +if (iIFPile->Peek()) + (iIFPile->Peek())->SetIFMode(eMode); +} + +//----------------------------------------------------------------------------- + +CIFControl::TIFProcessing CTEngine::GetIfState() +{ +return (iIFPile->Peek()) ? (iIFPile->Peek())->GetIFState() : CIFControl::EIgnoreIF; +} + +//----------------------------------------------------------------------------- + +void CTEngine::SetIfState(const CIFControl::TIFProcessing &eProc) +{ +if (iIFPile->Peek()) + (iIFPile->Peek())->SetIFState(eProc); +} + +//----------------------------------------------------------------------------- +// Create new IF object to manage the current processing +// Use the EndIf to Pop the current object when ENDIF is processed + +void CTEngine::IfL(const CIFControl::TIFMode &eProc, + const TBool &aResult, + const CIFControl::TIFProcessing &aProcess) +{ +CIFControl *cif = CIFControl::NewLC(eProc, aResult, aProcess); + +iIFPile->PushL(cif); +// CleanupStack::PopAndDestroy(); +CleanupStack::Pop(); +} + +//----------------------------------------------------------------------------- + +void CTEngine::EndIf() +{ +if (iIFPile->Peek()) + iIFPile->Skim(); +} + +//----------------------------------------------------------------------------- +// End of File +//-----------------------------------------------------------------------------