mmtestenv/mmtestfw/Source/TestFramework/script.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This module contains CScript class
       
    15 // 
       
    16 //
       
    17 
       
    18 // system includes
       
    19 #include <f32file.h>
       
    20 
       
    21 // test system includes
       
    22 #include <testframework.h>
       
    23 #include "Filename.h"
       
    24 #include "script.h"
       
    25 #include "parseline.h"
       
    26 #include "config.h"
       
    27 
       
    28 #if !defined (__TSU_TESTFRAMEWORK__)
       
    29 /**
       
    30  *
       
    31  * Script files can reference other script files.
       
    32  * KMaxDepthRecursion limits the number of references.
       
    33  * This is to catch accidental circular references in script files
       
    34  * which would otherwise cause the system to continue until all
       
    35  * memory had be used making more CScript objects.
       
    36  *
       
    37  * @xxxx
       
    38  *
       
    39  */
       
    40 const TInt KMaxDepthRecursion = 100; 
       
    41 
       
    42 #endif
       
    43 
       
    44 /**
       
    45  *
       
    46  * Global data : count of how deep in script files parser is.
       
    47  * This is to check against infinite recursion
       
    48  *
       
    49  * NB : we must patch this out for Unit Testing, where script.cpp
       
    50  * is part of a DLL
       
    51  *
       
    52  * @xxxx
       
    53  *
       
    54  */
       
    55 // do not define static if Unit Testing
       
    56 #if !defined (__TSU_TESTFRAMEWORK__)
       
    57 GLDEF_D TInt CScript::iScriptDepth = 0;
       
    58 #endif			
       
    59 
       
    60 /**
       
    61  *
       
    62  * Console prompts
       
    63  *
       
    64  * @xxxx
       
    65  *
       
    66  */
       
    67 //_LIT(KTxtPressAnyKey,"[press any key to continue]\n");	// EABI warning removal
       
    68 //_LIT(KTxtBreakOnError,"The test has failed, press X to terminate this test\n [press any other key to continue]\n");	// EABI warning removal
       
    69 
       
    70 /**
       
    71  *
       
    72  * CScript first-phase constructor
       
    73  *
       
    74  * @xxxx
       
    75  *
       
    76  */
       
    77 CScript::CScript()
       
    78 	{
       
    79 	}
       
    80 
       
    81 /**
       
    82  *
       
    83  * CScript second-phase constructor for a script processor which
       
    84  * does not inherit a parser.
       
    85  *
       
    86  * @param	"CTestUtils* aTestUtils"
       
    87  *			The TestUtils object to use
       
    88  *
       
    89  * @param	"CLog* aLog"
       
    90  *			The logger to use
       
    91  *
       
    92  * @xxxx
       
    93  *
       
    94  */
       
    95 void CScript::ConstructL(CTestUtils* aTestUtils, CLog* aLog, TInt64 aGuardTimer, const TDesC& aMatchString)
       
    96 	{
       
    97 	iLog = aLog;
       
    98 	iGuardTimer = aGuardTimer;
       
    99 
       
   100 	iMatchString = aMatchString.AllocL();
       
   101 
       
   102 	iParse = CParseLine::NewL(this, aTestUtils, aLog, aGuardTimer, *iMatchString);
       
   103 	iParseOwner = ETrue;
       
   104 
       
   105 	iPauseAtEnd = EFalse;
       
   106 
       
   107 #if !defined (__TSU_TESTFRAMEWORK__)
       
   108 	iScriptDepth++;
       
   109 #endif
       
   110 	}
       
   111 
       
   112 /**
       
   113  *
       
   114  * CScript static constructor for a script processor which
       
   115  * does not inherit a parser.
       
   116  *
       
   117  * @param	"CTestUtils* aTestUtils"
       
   118  *			The TestUtils object to use
       
   119  *
       
   120  * @param	"CLog* aLog"
       
   121  *			The logger to use
       
   122  *
       
   123  * @xxxx
       
   124  *
       
   125  */
       
   126 CScript* CScript::NewL(CTestUtils* aTestUtils, CLog * aLog, TInt64 aGuardTimer, const TDesC& aMatchString)
       
   127 	{
       
   128 	CScript * self = new(ELeave) CScript;
       
   129 	CleanupStack::PushL(self);
       
   130 	self->ConstructL(aTestUtils, aLog, aGuardTimer, aMatchString);
       
   131 	CleanupStack::Pop();
       
   132 	return self;
       
   133 	}
       
   134 
       
   135 /**
       
   136  *
       
   137  * CScript static constructor for a script processor which
       
   138  * does not inherit a parser.
       
   139  *
       
   140  * @param	"CTestUtils* aTestUtils"
       
   141  *			The TestUtils object to use
       
   142  *
       
   143  * @param	"CLog* aLog"
       
   144  *			The logger to use
       
   145  *
       
   146  * @xxxx
       
   147  *
       
   148  */
       
   149 CScript* CScript::NewLC(CTestUtils* aTestUtils, CLog * aLog, TInt64 aGuardTimer, const TDesC& aMatchString)
       
   150 	{
       
   151 	CScript * self = new(ELeave) CScript;
       
   152 	CleanupStack::PushL(self);
       
   153 	self->ConstructL(aTestUtils, aLog, aGuardTimer, aMatchString);
       
   154 	return self;
       
   155 	}
       
   156 
       
   157 /**
       
   158  *
       
   159  * CScript second-phase constructor, for a script processor which
       
   160  * inherits a parser.
       
   161  *
       
   162  * @param	"CParseLine* aParse"
       
   163  *			The parser to use
       
   164  *
       
   165  * @param	"CTestUtils*"
       
   166  *			Dummy parameter (would be used for constructing a parser);
       
   167  *			retained to maintain overload distinction
       
   168  *
       
   169  * @param	"CLog * aLog"
       
   170  *			The logger to use
       
   171  *
       
   172  * @xxxx
       
   173  *
       
   174  */
       
   175 void CScript::ConstructL(CParseLine* aParse, CTestUtils*, CLog* aLog, TInt64 aGuardTimer, const TDesC& aMatchString)
       
   176 	{
       
   177 	iLog = aLog;
       
   178 	iGuardTimer = aGuardTimer;
       
   179 		
       
   180 	iMatchString = aMatchString.AllocL(); // should be the same as that for aParse, for moment don't check
       
   181 
       
   182 	iParse = aParse;
       
   183 	iParseOwner = EFalse;
       
   184 
       
   185 	iPauseAtEnd = EFalse;
       
   186 
       
   187 #if !defined (__TSU_TESTFRAMEWORK__)
       
   188 	iScriptDepth++;
       
   189 #endif
       
   190 
       
   191 	}
       
   192 
       
   193 /**
       
   194  *
       
   195  * CScript static constructor for a script processor which
       
   196  * inherits a parser.
       
   197  *
       
   198  * @param	"CParseLine* aParse"
       
   199  *			The parser to use
       
   200  *
       
   201  * @param	"CTestUtils* aTestUtils"
       
   202  *			The TestUtils object to use
       
   203  *
       
   204  * @param	"CLog* aLog"
       
   205  *			The logger to use
       
   206  *
       
   207  * @xxxx
       
   208  *
       
   209  */
       
   210 CScript* CScript::NewL(CParseLine* aParse, CTestUtils* aTestUtils, CLog* aLog, TInt64 aGuardTimer, const TDesC& aMatchString)
       
   211 	{
       
   212 	CScript* self = new(ELeave) CScript;
       
   213 	CleanupStack::PushL(self);
       
   214 	self->ConstructL(aParse, aTestUtils, aLog, aGuardTimer, aMatchString);
       
   215 	CleanupStack::Pop();
       
   216 	return self;
       
   217 	}
       
   218 
       
   219 /**
       
   220  *
       
   221  * CScript static constructor for a script processor which
       
   222  * inherits a parser.
       
   223  *
       
   224  * @param	"CParseLine* aParse"
       
   225  *			The parser to use
       
   226  *
       
   227  * @param	"CTestUtils* aTestUtils"
       
   228  *			The TestUtils object to use
       
   229  *
       
   230  * @param	"CLog* aLog"
       
   231  *			The logger to use
       
   232  *
       
   233  * @xxxx
       
   234  *
       
   235  */
       
   236 CScript* CScript::NewLC(CParseLine* aParse, CTestUtils* aTestUtils, CLog* aLog, TInt64 aGuardTimer, const TDesC& aMatchString)
       
   237 	{
       
   238 	CScript* self = new(ELeave) CScript;
       
   239 	CleanupStack::PushL(self);
       
   240 	self->ConstructL(aParse, aTestUtils, aLog, aGuardTimer, aMatchString);
       
   241 	return self;
       
   242 	}
       
   243 
       
   244 /**
       
   245  *
       
   246  * CScript destructor
       
   247  *
       
   248  * @xxxx
       
   249  *
       
   250  */
       
   251 CScript::~CScript()
       
   252 	{
       
   253 	// delete parser if we own it
       
   254 	if(iParseOwner)
       
   255 		{
       
   256 		delete iParse;
       
   257 		iParse = NULL;
       
   258 		}
       
   259 
       
   260 	// delete scriptbuffer
       
   261 	delete iScriptBuffer;
       
   262 	
       
   263 	delete iMatchString;
       
   264 
       
   265 #if !defined (__TSU_TESTFRAMEWORK__)
       
   266 	iScriptDepth--;
       
   267 #endif
       
   268 	}
       
   269 
       
   270 
       
   271 /**
       
   272  *
       
   273  * Open and read a script file.
       
   274  *
       
   275  * @param	"TFileName aScriptFileName"
       
   276  *			The script file name
       
   277  *
       
   278  * @return	"TBool"
       
   279  *			true if script file successfully read
       
   280  *
       
   281  * @xxxx
       
   282  *
       
   283  */
       
   284 #ifdef EXCLUDE_FOR_UNITTEST
       
   285 TBool CScript::OpenScriptFile(CFileName* /*aScriptFileName*/)
       
   286 	{
       
   287 	// empty function to silence OPT:REF warning under WINS UREL build
       
   288 	return ETrue;
       
   289 	}
       
   290 #else
       
   291 TBool CScript::OpenScriptFile(CFileName* aScriptFileName)
       
   292 	{
       
   293 	// get the full pathname default drive name and extension
       
   294 	_LIT(KRelated,"\\xx.script"); 
       
   295 	TParse parseScriptFileName;
       
   296 	TInt returnCode = parseScriptFileName.Set(aScriptFileName->FileName(), &KRelated, NULL);
       
   297 	if (returnCode != KErrNone)
       
   298 		{
       
   299 		ERR_PRINTF2(_L("Could not set script filename: %S"), &parseScriptFileName.FullName());
       
   300 		Pause();
       
   301 		return EFalse;
       
   302 		}
       
   303 
       
   304 #if !defined (__TSU_TESTFRAMEWORK__)
       
   305 	if (iScriptDepth > KMaxDepthRecursion)
       
   306 		{
       
   307 		// prevent the parser from recursing forever
       
   308 		ERR_PRINTF2(_L("Script parser aborting: depth:%d"), iScriptDepth);
       
   309 		return EFalse;	
       
   310 		}
       
   311 #if !defined(__WINS__)
       
   312 	if (iScriptDepth > 3)
       
   313 		{
       
   314 		// on target, we are likely to KERN-EXEC 3 if nesting more than 4 levels
       
   315 		WARN_PRINTF2(_L("Warning : script parser depth = %d"), iScriptDepth);
       
   316 		}
       
   317 #endif
       
   318 #endif
       
   319 
       
   320 	// connect to the fileserver
       
   321 	returnCode = iTheFs.Connect();
       
   322 	if (returnCode != KErrNone)
       
   323 		{
       
   324 		ERR_PRINTF1(_L("Error trying to connect to the file server") );	
       
   325 		return EFalse;
       
   326 		}
       
   327 
       
   328 
       
   329 	RFile listfile;
       
   330 	// have we got a drive letter specified - if not, check all drives
       
   331 	if (parseScriptFileName.DrivePresent())
       
   332 		{
       
   333 		returnCode = listfile.Open(iTheFs, parseScriptFileName.FullName(), EFileRead | EFileShareAny);
       
   334 		}
       
   335 	else
       
   336 		{
       
   337 		// checks C, D, E and Z drives - this is ugly, is there a better way of doing this?
       
   338 		INFO_PRINTF1(_L("Looking for script file on all drives..."));
       
   339 		_LIT(KDriveC, "C:");
       
   340 		parseScriptFileName.Set(aScriptFileName->FileName(), &KRelated, &KDriveC);
       
   341 		returnCode = listfile.Open(iTheFs, parseScriptFileName.FullName(), EFileRead | EFileShareAny);
       
   342 		if (returnCode != KErrNone)
       
   343 			{
       
   344 			_LIT(KDriveD, "D:");
       
   345 			parseScriptFileName.Set(aScriptFileName->FileName(), &KRelated, &KDriveD);
       
   346 			returnCode = listfile.Open(iTheFs, parseScriptFileName.FullName(), EFileRead | EFileShareAny);
       
   347 			if (returnCode != KErrNone)
       
   348 				{
       
   349 				_LIT(KDriveE, "E:");
       
   350 				parseScriptFileName.Set(aScriptFileName->FileName(), &KRelated, &KDriveE);
       
   351 				returnCode = listfile.Open(iTheFs, parseScriptFileName.FullName(), EFileRead | EFileShareAny);
       
   352 				if (returnCode != KErrNone)
       
   353 					{
       
   354 					_LIT(KDriveZ, "Z:");
       
   355 					parseScriptFileName.Set(aScriptFileName->FileName(), &KRelated, &KDriveZ);
       
   356 					returnCode = listfile.Open(iTheFs, parseScriptFileName.FullName(), EFileRead | EFileShareAny);
       
   357 					}
       
   358 				}
       
   359 			}
       
   360 		}
       
   361 
       
   362 	// check if open fails 
       
   363 	if (returnCode != KErrNone)
       
   364 		{
       
   365 		parseScriptFileName.Set(aScriptFileName->FileName(), &KRelated, NULL);
       
   366 		ERR_PRINTF2(_L("Failed to open script file : %S"), &parseScriptFileName.FullName());
       
   367 		listfile.Close();
       
   368 		iTheFs.Close();
       
   369 		Pause();
       
   370 		return EFalse;
       
   371 		}
       
   372 
       
   373 	// display the file being processed
       
   374 	INFO_PRINTF2(_L("Reading script %S"), &parseScriptFileName.FullName());
       
   375 
       
   376 	// get the script file size
       
   377 	TInt listfilesize;
       
   378 	returnCode = listfile.Size(listfilesize);
       
   379 	if (returnCode != KErrNone)
       
   380 		{
       
   381 		ERR_PRINTF2(_L("Failed to read script file: %S size "), &parseScriptFileName.FullName());
       
   382 		listfile.Close();
       
   383 		iTheFs.Close();
       
   384 		return EFalse;
       
   385 		}
       
   386 
       
   387 	// JW 30-10-02 DEF004555 
       
   388 	// Buffer was being orphaned if already allocated, where there was more than one
       
   389 	// script file on the command line
       
   390 	// Now, we check for this and delete iScriptBuffer if it already exists
       
   391 	if(iScriptBuffer)
       
   392 		{
       
   393 		delete iScriptBuffer;
       
   394 		iScriptBuffer = NULL;
       
   395 		}
       
   396 
       
   397 	// get a buffer to read the file into
       
   398 	TRAPD(err, iScriptBuffer = HBufC8::NewL(listfilesize));
       
   399 	if (err != KErrNone || iScriptBuffer == NULL)
       
   400 		{
       
   401 		ERR_PRINTF2(_L("Failed to allocate memory for script file %S "), &parseScriptFileName.FullName());
       
   402 		listfile.Close();
       
   403 		iTheFs.Close();
       
   404 		return EFalse;
       
   405 		}
       
   406 
       
   407 	// get a pointer to the buffer
       
   408 	TPtr8 ptr = iScriptBuffer->Des();
       
   409 
       
   410 	// read the file into the buffer
       
   411 	returnCode = listfile.Read(ptr);
       
   412 	if (returnCode != KErrNone)
       
   413 		{
       
   414 		ERR_PRINTF2(_L("Failed to read script file %S "), &parseScriptFileName.FullName());
       
   415 		listfile.Close();
       
   416 		iTheFs.Close();
       
   417 		return EFalse;
       
   418 		}
       
   419 
       
   420 	listfile.Close();
       
   421 	iTheFs.Close();
       
   422 	return ETrue;
       
   423 	}
       
   424 #endif // EXCLUDE_FOR_UNITTEST
       
   425 
       
   426 /**
       
   427  *
       
   428  * Parse and execute script file.
       
   429  * Assumes script file has been read into iScriptBuffer
       
   430  *
       
   431  * @return	"TVerdict"
       
   432  *			The script verdict (for logging)
       
   433  *
       
   434  * @xxxx
       
   435  *
       
   436  */
       
   437 TVerdict CScript::ExecuteScriptL()
       
   438 	{
       
   439 	// use TLex to decode the script
       
   440 	TLex8 llex(*iScriptBuffer);
       
   441 
       
   442 	// keep a count of the line number
       
   443 	TInt8 lineNo = 1;
       
   444 
       
   445 	// loop though processing the rest a line at a time
       
   446 	while(!llex.Eos())
       
   447 		{
       
   448 		// skip any spaces
       
   449 		while ( llex.Peek() == ' ' )
       
   450 			llex.Inc();
       
   451 
       
   452 		// mark the start of the line
       
   453 		llex.Mark();
       
   454 		
       
   455 		// move to the next
       
   456 		while(!llex.Eos() && llex.Peek() != '\n')
       
   457 			llex.Inc();
       
   458 
       
   459 		// step over \n
       
   460 		if ( llex.Peek() == '\n' )
       
   461 			llex.Inc();
       
   462 				
       
   463 		// get the line 
       
   464 		TPtrC8 pline = llex.MarkedToken();
       
   465 		if (pline.Length() != 0)
       
   466 			{
       
   467 			// and then process
       
   468 			ProcessLineL(pline, lineNo);
       
   469 			}
       
   470 
       
   471 		// on to the next line
       
   472 		lineNo++;
       
   473 		}
       
   474 
       
   475 	// script processing complete, now return the script verdict
       
   476 	// Note: the script verdicts are just for the log
       
   477 	// if no tests failed then return pass for the script
       
   478 	// this covers scripts which do not test anything
       
   479 	return (iFail == 0 ? EPass : EFail );
       
   480 	}
       
   481 
       
   482 /**
       
   483  *
       
   484  * Process a single line from the script file.
       
   485  *
       
   486  * @param	"const TDesC8& aNarrowline"
       
   487  *			The script line
       
   488  *
       
   489  * @param	"TInt8 lineNo"
       
   490  *			The script line number
       
   491  *
       
   492  * @xxxx
       
   493  *
       
   494  */
       
   495 void CScript::ProcessLineL(const TDesC8& aNarrowline, TInt8 aLineNo)
       
   496 	{
       
   497 	// call parse to process line
       
   498 	iParse->ProcessLineL(aNarrowline, aLineNo);
       
   499 	}
       
   500 
       
   501 /**
       
   502  *
       
   503  * Display the accumulated script results.
       
   504  *
       
   505  * @xxxx
       
   506  *
       
   507  */
       
   508 void CScript::DisplayResults()
       
   509 	{
       
   510 
       
   511 	INFO_PRINTF1(_L("Test Results Summary ") );
       
   512 	INFO_PRINTF1(_L("-------------------- ") );
       
   513 	INFO_PRINTF2(_L("Passed            :%d"),  iPass);
       
   514 	INFO_PRINTF2(_L("Failed            :%d"),  iFail);
       
   515 	INFO_PRINTF2(_L("Inconclusive      :%d"),  iInconclusive);
       
   516 	INFO_PRINTF2(_L("Test suite errors :%d"),  iTestSuiteError);
       
   517 	INFO_PRINTF2(_L("Aborted           :%d"),  iAbort);
       
   518 	INFO_PRINTF2(_L("KnownFailure      :%d"),  iKnownFailure); //A new TVerdict
       
   519 	INFO_PRINTF2(_L("Total             :%d"),  iTotal);
       
   520 
       
   521 	if(iPauseAtEnd)
       
   522 		{
       
   523 		// A pause at the end has been requested
       
   524 		Pause();
       
   525 		}
       
   526 
       
   527 	}
       
   528 
       
   529 /**
       
   530  *
       
   531  * Pause testing.
       
   532  * NOTE : stubbed pending re-implementation of user input
       
   533  *
       
   534  * @xxxx
       
   535  *
       
   536  */
       
   537 void CScript::Pause()
       
   538 	{
       
   539 	WARN_PRINTF1(_L("Warning : PAUSE not implemented"));
       
   540 	}
       
   541 
       
   542 /**
       
   543  *
       
   544  * Display error on the console and invite abort.
       
   545  * NOTE : stubbed pending re-implementation of user input
       
   546  *
       
   547  * @xxxx
       
   548  *
       
   549  */
       
   550 TBool CScript::BreakOnError()
       
   551 	{
       
   552 	WARN_PRINTF1(_L("Warning : BREAK_ON_ERROR not implemented"));
       
   553 	return EFalse;
       
   554 	}
       
   555 
       
   556 /**
       
   557  *
       
   558  * Add a test result to the accumulated totals.
       
   559  *
       
   560  * @param	"TVerdict aTestVerdict"
       
   561  *			The test verdict
       
   562  *
       
   563  * @xxxx
       
   564  *
       
   565  */
       
   566 void CScript::AddResult(TVerdict aTestVerdict)
       
   567 	{
       
   568 	// another test complete, so increment total
       
   569 	iTotal++;
       
   570 
       
   571 	// add in the current result
       
   572 	switch (aTestVerdict) 
       
   573 		{
       
   574 	case EPass:
       
   575 		iPass++;
       
   576 		break;
       
   577 	case EFail:
       
   578 		iFail++;
       
   579 		break;
       
   580 	case EInconclusive:
       
   581 		iInconclusive++;
       
   582 		break;
       
   583 	case ETestSuiteError:
       
   584 		iTestSuiteError++;
       
   585 		break;
       
   586 	case EAbort:
       
   587 		iAbort++;
       
   588 		break;
       
   589 	case EKnownFailure: //A new TVerdict for a known failed test
       
   590 		iKnownFailure++;
       
   591 		break;
       
   592 		}
       
   593 
       
   594 	// display the result
       
   595 	TPtrC verdictText = CLog::TestResultText(aTestVerdict);
       
   596 	TPtrC currentSuiteName = iParse->CurrentSuiteName();
       
   597 	TPtrC currentStepName = iParse->CurrentStepName();
       
   598 
       
   599 	iLog->LogResult(aTestVerdict, _L("Test Result for %S:%S is %S "), 
       
   600 		&currentSuiteName, &currentStepName, &verdictText);
       
   601 	
       
   602 	}
       
   603 
       
   604 /**
       
   605  *
       
   606  * Add a test result from a subscript to the accumulated totals.
       
   607  *
       
   608  * @param	"CScript* aSubScript"
       
   609  *			The subscript
       
   610  *
       
   611  * @xxxx
       
   612  *
       
   613  */
       
   614 void CScript::AddResult(CScript* aSubScript)
       
   615 	{
       
   616 
       
   617 	iPass += aSubScript->iPass;
       
   618 	iFail += aSubScript->iFail;
       
   619 	iInconclusive += aSubScript->iInconclusive;
       
   620 	iTestSuiteError += aSubScript->iTestSuiteError;
       
   621 	iAbort += aSubScript->iAbort;
       
   622 	iKnownFailure += aSubScript->iKnownFailure;
       
   623 	iTotal +=aSubScript->iTotal;
       
   624 	}
       
   625 
       
   626 /**
       
   627  *
       
   628  * Traceable logging function for parseline.
       
   629  *
       
   630  * @param	"const TText8* aFile"
       
   631  *			Source code file name
       
   632  *
       
   633  * @param	"TInt aLine"
       
   634  *			Source code line
       
   635  *
       
   636  * @param	"TInt aSeverity"
       
   637  *			Severity level required to log
       
   638  *
       
   639  * @param	"TRefByValue<const TDesC16> aFmt"
       
   640  *			Printf-style format.
       
   641  *
       
   642  * @param	"..."
       
   643  *			Variable print parameters
       
   644  *
       
   645  * @xxxx
       
   646  *
       
   647  */
       
   648 void CScript::LogExtra(const TText8* aFile, TInt aLine, TInt aSeverity,
       
   649 		TRefByValue<const TDesC16> aFmt,...)
       
   650 	{
       
   651 	VA_LIST aList;
       
   652 	VA_START(aList, aFmt);
       
   653 
       
   654 	if(aSeverity)
       
   655 		{
       
   656 		if(iLog)
       
   657 			{
       
   658 			iLog->LogExtra(aFile, aLine, aSeverity, aFmt, aList);
       
   659 			}
       
   660 		}
       
   661 
       
   662 	VA_END(aList);
       
   663 	}