core/src/parser.cpp
changeset 78 b3ffff030d5c
parent 66 2a78c4ff2eab
child 83 706c7a69e448
equal deleted inserted replaced
77:8df58d8c99e8 78:b3ffff030d5c
    52 	{
    52 	{
    53 	}
    53 	}
    54 
    54 
    55 CParser* CParser::NewL(TUint aMode, const TDesC& aDes, RIoSession& aIoSession, RIoReadHandle& aStdin, RIoWriteHandle& aStdout, RIoWriteHandle& aStderr, IoUtils::CEnvironment& aEnv, CCommandFactory& aFactory, MParserObserver* aObserver, TInt aStartingLineNumber)
    55 CParser* CParser::NewL(TUint aMode, const TDesC& aDes, RIoSession& aIoSession, RIoReadHandle& aStdin, RIoWriteHandle& aStdout, RIoWriteHandle& aStderr, IoUtils::CEnvironment& aEnv, CCommandFactory& aFactory, MParserObserver* aObserver, TInt aStartingLineNumber)
    56 	{
    56 	{
    57 	CParser* self = new(ELeave) CParser(aMode, aDes, aIoSession, aStdin, aStdout, aStderr, aEnv, aFactory, aObserver, aStartingLineNumber);
    57 	CParser* self = new(ELeave) CParser(aMode, aIoSession, aStdin, aStdout, aStderr, aEnv, aFactory, aObserver, aStartingLineNumber);
    58 	CleanupStack::PushL(self);
    58 	CleanupStack::PushL(self);
    59 	self->ConstructL();
    59 	self->ConstructL(&aDes, NULL);
       
    60 	CleanupStack::Pop();
       
    61 	return self;
       
    62 	}
       
    63 
       
    64 CParser* CParser::NewL(TUint aMode, RIoReadHandle& aSourceHandle, RIoSession& aIoSession, RIoReadHandle& aStdin, RIoWriteHandle& aStdout, RIoWriteHandle& aStderr, IoUtils::CEnvironment& aEnv, CCommandFactory& aFactory, MParserObserver* aObserver)
       
    65 	{
       
    66 	CParser* self = new(ELeave) CParser(aMode, aIoSession, aStdin, aStdout, aStderr, aEnv, aFactory, aObserver);
       
    67 	CleanupStack::PushL(self);
       
    68 	self->ConstructL(NULL, &aSourceHandle);
    60 	CleanupStack::Pop();
    69 	CleanupStack::Pop();
    61 	return self;
    70 	return self;
    62 	}
    71 	}
    63 
    72 
    64 CParser::~CParser()
    73 CParser::~CParser()
    76 		iStdout.Close();
    85 		iStdout.Close();
    77 		iStderr.Close();
    86 		iStderr.Close();
    78 		}
    87 		}
    79 	}
    88 	}
    80 
    89 
    81 CParser::CParser(TUint aMode, const TDesC& aDes, RIoSession& aIoSession, RIoReadHandle& aStdin, RIoWriteHandle& aStdout, RIoWriteHandle& aStderr, IoUtils::CEnvironment& aEnv, CCommandFactory& aFactory, MParserObserver* aObserver, TInt aStartingLineNumber)
    90 CParser::CParser(TUint aMode, RIoSession& aIoSession, RIoReadHandle& aStdin, RIoWriteHandle& aStdout, RIoWriteHandle& aStderr, IoUtils::CEnvironment& aEnv, CCommandFactory& aFactory, MParserObserver* aObserver, TInt aStartingLineNumber)
    82 	: iMode(aMode), iData(aDes), iIoSession(aIoSession), iStdin(aStdin), iStdout(aStdout), iStderr(aStderr), iEnv(aEnv), iFactory(aFactory), iObserver(aObserver), iCompletionError(aStderr, aEnv), iNextLineNumber(aStartingLineNumber)
    91 	: iMode(aMode), iIoSession(aIoSession), iStdin(aStdin), iStdout(aStdout), iStderr(aStderr), iEnv(aEnv), iFactory(aFactory), iObserver(aObserver), iCompletionError(aStderr, aEnv), iNextLineNumber(aStartingLineNumber)
    83 	{
    92 	{
    84 	}
    93 	}
    85 
    94 
    86 void CParser::ConstructL()
    95 void CParser::ConstructL(const TDesC* aDes, RIoReadHandle* aSourceHandle)
    87 	{
    96 	{
    88 	if (iObserver)
    97 	if (iObserver)
    89 		{
    98 		{
    90 		iCompletionCallBack = new(ELeave) CAsyncCallBack(TCallBack(CompletionCallBack, this), CActive::EPriorityStandard);
    99 		iCompletionCallBack = new(ELeave) CAsyncCallBack(TCallBack(CompletionCallBack, this), CActive::EPriorityStandard);
    91 		}
   100 		}
    98 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine1);
   107 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine1);
    99 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine2);
   108 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine2);
   100 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine3);
   109 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine3);
   101 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine4);
   110 	iLexer1->DefineTokenTypeL(TToken::ENewLine, KNewLine4);
   102 	iLexer1->DefineTokenTypeL(TToken::ESemicolon, KSemicolon);
   111 	iLexer1->DefineTokenTypeL(TToken::ESemicolon, KSemicolon);
   103 	iLexer1->Set(iData, iEnv.EscapeChar());
   112 	if (aDes)
       
   113 		{
       
   114 		iLexer1->Set(*aDes, iEnv.EscapeChar());
       
   115 		}
       
   116 	else
       
   117 		{
       
   118 		iLexer1->Set(*aSourceHandle, iEnv.EscapeChar());
       
   119 		}
   104 
   120 
   105 	iLexer2 = CLexer::NewL(CLexer::EHandleSingleQuotes | CLexer::EHandleDoubleQuotes);
   121 	iLexer2 = CLexer::NewL(CLexer::EHandleSingleQuotes | CLexer::EHandleDoubleQuotes);
   106 	iLexer2->DefineTokenTypeL(TToken::EPipe, KPipe);
   122 	iLexer2->DefineTokenTypeL(TToken::EPipe, KPipe);
   107 	iLexer2->DefineTokenTypeL(TToken::ERedirectStdinFromFile, KRedirectStdinFromFile);
   123 	iLexer2->DefineTokenTypeL(TToken::ERedirectStdinFromFile, KRedirectStdinFromFile);
   108 	iLexer2->DefineTokenTypeL(TToken::ERedirectStdoutToFile, KRedirectStdoutToFile1);
   124 	iLexer2->DefineTokenTypeL(TToken::ERedirectStdoutToFile, KRedirectStdoutToFile1);
   348 		redirection->iType = RPipeSection::TRedirection::EHandle;
   364 		redirection->iType = RPipeSection::TRedirection::EHandle;
   349 		redirection->iHandle = RPipeSection::TRedirection::EStderr;
   365 		redirection->iHandle = RPipeSection::TRedirection::EStderr;
   350 		}
   366 		}
   351 	else
   367 	else
   352 		{
   368 		{
   353 		if (aLexer.More())
   369 		if (aLexer.MoreL())
   354 			{
   370 			{
   355 			redirection->iType = ((aTokenType == TToken::ERedirectStdoutToFileAppend) || (aTokenType == TToken::ERedirectStderrToFileAppend)) ? RPipeSection::TRedirection::EFileAppend : RPipeSection::TRedirection::EFile;
   371 			redirection->iType = ((aTokenType == TToken::ERedirectStdoutToFileAppend) || (aTokenType == TToken::ERedirectStderrToFileAppend)) ? RPipeSection::TRedirection::EFileAppend : RPipeSection::TRedirection::EFile;
   356 			TToken fileName(aLexer.NextToken());
   372 			TToken fileName(aLexer.NextTokenL());
   357 			redirection->SetFileNameL(aCwd, fileName.String());
   373 			redirection->SetFileNameL(aCwd, fileName.String());
   358 			}
   374 			}
   359 		else
   375 		else
   360 			{
   376 			{
   361 			return EFalse;
   377 			return EFalse;
   410 	CleanupStack::PushL(TCleanupItem(CleanupPipeSectionsArray, &pipeSections));
   426 	CleanupStack::PushL(TCleanupItem(CleanupPipeSectionsArray, &pipeSections));
   411 	RPipeSection pipeSection;
   427 	RPipeSection pipeSection;
   412 	CleanupClosePushL(pipeSection);
   428 	CleanupClosePushL(pipeSection);
   413 	TInt offset = iLexer2->CurrentOffset();
   429 	TInt offset = iLexer2->CurrentOffset();
   414 	TBool background(EFalse);
   430 	TBool background(EFalse);
   415 	while (iLexer2->More())
   431 	while (iLexer2->MoreL())
   416 		{
   432 		{
   417 		TToken token(iLexer2->NextToken());
   433 		TToken token(iLexer2->NextTokenL());
   418 		switch (token.Type())
   434 		switch (token.Type())
   419 			{
   435 			{
   420 			case TToken::EPipe:
   436 			case TToken::EPipe:
   421 				{
   437 				{
   422 				pipeSection.iFullName.Set(iData.Ptr() + offset, iLexer2->CurrentOffset() - offset - token.String().Length());
   438 				pipeSection.iFullName.Set(iLexer2->Ptr() + offset, iLexer2->CurrentOffset() - offset - token.String().Length());
   423 				offset = iLexer2->CurrentOffset();
   439 				offset = iLexer2->CurrentOffset();
   424 				User::LeaveIfError(pipeSections.Append(pipeSection));
   440 				User::LeaveIfError(pipeSections.Append(pipeSection));
   425 				new(&pipeSection) RPipeSection;
   441 				new(&pipeSection) RPipeSection;
   426 				break;
   442 				break;
   427 				}
   443 				}
   483 				iExitCallBack->Call();
   499 				iExitCallBack->Call();
   484 				}
   500 				}
   485 			}
   501 			}
   486 		else
   502 		else
   487 			{
   503 			{
   488 			pipeSection.iFullName.Set(iData.Ptr() + offset, iLexer2->CurrentOffset() - offset);
   504 			pipeSection.iFullName.Set(iLexer2->Ptr() + offset, iLexer2->CurrentOffset() - offset);
   489 			User::LeaveIfError(pipeSections.Append(pipeSection));
   505 			User::LeaveIfError(pipeSections.Append(pipeSection));
   490 			CleanupStack::Pop(&pipeSection);
   506 			CleanupStack::Pop(&pipeSection);
   491 			if ((iMode & EDebug) && iObserver)
   507 			if ((iMode & EDebug) && iObserver)
   492 				{
   508 				{
   493 				iObserver->AboutToExecuteLine(pipeLineData, *expandedPipeLine);
   509 				iObserver->AboutToExecuteLine(pipeLineData, *expandedPipeLine);
   502 				{
   518 				{
   503 				ASSERT(iForegroundPipeLine == NULL);
   519 				ASSERT(iForegroundPipeLine == NULL);
   504 				iForegroundPipeLine = CPipeLine::NewL(iIoSession, iStdin, iStdout, iStderr, iEnv, iFactory, pipeSections, background, this, iCompletionError);
   520 				iForegroundPipeLine = CPipeLine::NewL(iIoSession, iStdin, iStdout, iStderr, iEnv, iFactory, pipeSections, background, this, iCompletionError);
   505 				}
   521 				}
   506 			CleanupStack::PopAndDestroy(&pipeSections);
   522 			CleanupStack::PopAndDestroy(&pipeSections);
   507 			if (aIsForeground && !iLexer1->More())
   523 			if (aIsForeground && !iLexer1->MoreL())
   508 				{
   524 				{
   509 				*aIsForeground = !background;
   525 				*aIsForeground = !background;
   510 				}
   526 				}
   511 			if (background && iLexer1->More())
   527 			if (background && iLexer1->MoreL())
   512 				{
   528 				{
   513 				iNextPipeLineCallBack->Call();
   529 				iNextPipeLineCallBack->Call();
   514 				}
   530 				}
   515 			}
   531 			}
   516 		}
   532 		}
   533 
   549 
   534 void CParser::FindNextPipeLineL(TPtrC& aData, TCondition& aCondition, TBool& aReachedLineEnd)
   550 void CParser::FindNextPipeLineL(TPtrC& aData, TCondition& aCondition, TBool& aReachedLineEnd)
   535 	{
   551 	{
   536 	aReachedLineEnd = EFalse;
   552 	aReachedLineEnd = EFalse;
   537 	aCondition = ENone;
   553 	aCondition = ENone;
       
   554 
       
   555 	iLexer1->Purge();
   538 	TInt startOffset = iLexer1->CurrentOffset();
   556 	TInt startOffset = iLexer1->CurrentOffset();
   539 	TInt endOffset = -1;
   557 	TInt endOffset = -1;
   540 
   558 
   541 	TBool foundSomething(EFalse);
   559 	TBool foundSomething(EFalse);
   542 	while (iLexer1->More())
   560 	while (iLexer1->MoreL())
   543 		{
   561 		{
   544 		TBool finished(EFalse);
   562 		TBool finished(EFalse);
   545 		TToken token(iLexer1->NextToken());
   563 		TToken token(iLexer1->NextTokenL());
   546 
   564 
   547 		switch (token.Type())
   565 		switch (token.Type())
   548 			{
   566 			{
   549 			case TToken::EString:
   567 			case TToken::EString:
   550 				{
   568 				{
   614 			}
   632 			}
   615 		}
   633 		}
   616 
   634 
   617 	if (foundSomething)
   635 	if (foundSomething)
   618 		{
   636 		{
   619 		aData.Set(iData.Ptr() + startOffset, endOffset - startOffset);
   637 		aData.Set(iLexer1->Ptr() + startOffset, endOffset - startOffset);
   620 		}
   638 		}
   621 	else
   639 	else
   622 		{
   640 		{
   623 		aData.Set(KNullDesC);
   641 		aData.Set(KNullDesC);
   624 		}
   642 		}
   634 	// Repeatedly check the data for environment variable tokens. This is done in a loop
   652 	// Repeatedly check the data for environment variable tokens. This is done in a loop
   635 	// because there could be variables within variables and we want to expand them all.
   653 	// because there could be variables within variables and we want to expand them all.
   636 	aLexer.Set(*buf, escapeChar);
   654 	aLexer.Set(*buf, escapeChar);
   637 	FOREVER
   655 	FOREVER
   638 		{
   656 		{
   639 		TToken token(aLexer.NextToken());
   657 		TToken token(aLexer.NextTokenL());
   640 		if (token.Type() == TToken::ENull)
   658 		if (token.Type() == TToken::ENull)
   641 			{
   659 			{
   642 			break;
   660 			break;
   643 			}
   661 			}
   644 		else if (token.Type() == TToken::EVariable)
   662 		else if (token.Type() == TToken::EVariable)
   713 
   731 
   714 	HBufC* buf = aData.AllocLC();
   732 	HBufC* buf = aData.AllocLC();
   715 	lexer1->Set(*buf, iEnv.EscapeChar());
   733 	lexer1->Set(*buf, iEnv.EscapeChar());
   716 	FOREVER
   734 	FOREVER
   717 		{
   735 		{
   718 		TToken token(lexer1->NextToken());
   736 		TToken token(lexer1->NextTokenL());
   719 		if (token.Type() == TToken::ENull)
   737 		if (token.Type() == TToken::ENull)
   720 			{
   738 			{
   721 			break;
   739 			break;
   722 			}
   740 			}
   723 		else if (token.Type() == TToken::EString)
   741 		else if (token.Type() == TToken::EString)
   754 	CleanupStack::PopAndDestroy(3, lexer1);
   772 	CleanupStack::PopAndDestroy(3, lexer1);
   755 	CleanupStack::PushL(buf);
   773 	CleanupStack::PushL(buf);
   756 	return buf;
   774 	return buf;
   757 	}
   775 	}
   758 
   776 
   759 TInt CParser::SkipLineRemainder()
   777 void CParser::SkipLineRemainderL()
   760 	{
   778 	{
   761 	while (iLexer1->More())
   779 	TRAPD(err, DoSkipLineRemainderL());
   762 		{
   780 	if (err)
   763 		TToken token(iLexer1->NextToken());
   781 		{
       
   782 		SkipToEnd();
       
   783 		User::Leave(err);
       
   784 		}
       
   785 	}
       
   786 
       
   787 void CParser::DoSkipLineRemainderL()
       
   788 	{
       
   789 	while (iLexer1->MoreL())
       
   790 		{
       
   791 		TToken token(iLexer1->NextTokenL());
   764 		if (token.Type() == TToken::ENewLine)
   792 		if (token.Type() == TToken::ENewLine)
   765 			{
   793 			{
   766 			if (iMode & EExportLineNumbers)
   794 			if (iMode & EExportLineNumbers)
   767 				{
   795 				{
   768 				// can we do something better with errors here?
   796 				iEnv.SetL(KScriptLine, iNextLineNumber++);
   769 				TRAPD(err, iEnv.SetL(KScriptLine, iNextLineNumber++));
       
   770 				if (err!=KErrNone)
       
   771 					{
       
   772 					iCompletionError.Set(err, TError::EFailedToSetScriptLineVar);
       
   773 					return err;
       
   774 					}
       
   775 				}
   797 				}
   776 			break;
   798 			break;
   777 			}
   799 			}
   778 		}
   800 		}
   779 	return KErrNone;
       
   780 	}
   801 	}
   781 
   802 
   782 void CParser::SkipToEnd()
   803 void CParser::SkipToEnd()
   783 	{
   804 	{
   784 	while (iLexer1->More())
   805 	iLexer1->SkipToEnd();
   785 		{
       
   786 		iLexer1->NextToken();
       
   787 		}
       
   788 	}
   806 	}
   789 
   807 
   790 TInt CParser::CompletionCallBack(TAny* aSelf)
   808 TInt CParser::CompletionCallBack(TAny* aSelf)
   791 	{
   809 	{
   792 	CParser* self = static_cast<CParser*>(aSelf);
   810 	CParser* self = static_cast<CParser*>(aSelf);
   807 	return KErrNone;
   825 	return KErrNone;
   808 	}
   826 	}
   809 
   827 
   810 void CParser::HandlePipeLineComplete(CPipeLine& aPipeLine, const TError& aError)
   828 void CParser::HandlePipeLineComplete(CPipeLine& aPipeLine, const TError& aError)
   811 	{
   829 	{
   812 	TRAPD(err, iEnv.SetL(KChildError, aError.Error()));
   830 	TRAPD(err, HandlePipeLineCompleteL(aPipeLine, aError));
   813 	if (err)
   831 	if (err)
   814 		{
   832 		{
   815 		iCompletionError.Set(err, TError::EFailedToSetChildErrorVar);
   833 		iCompletionError.Set(err, TError::EPipelineCompletionError);
   816 		iCompletionCallBack->CallBack();
   834 		iCompletionCallBack->CallBack();
   817 		return;
   835 		return;
   818 		}
   836 		}
       
   837 	}
       
   838 
       
   839 void CParser::HandlePipeLineCompleteL(CPipeLine& aPipeLine, const TError& aError)
       
   840 	{
       
   841 	iEnv.SetL(KChildError, aError.Error());
   819 
   842 
   820 	if ((iMode & EDebug) && iObserver)
   843 	if ((iMode & EDebug) && iObserver)
   821 		{
   844 		{
   822 		iObserver->LineReturned(aError.Error());
   845 		iObserver->LineReturned(aError.Error());
   823 		}
   846 		}
   842 					{
   865 					{
   843 					SkipToEnd();
   866 					SkipToEnd();
   844 					}
   867 					}
   845 				else if (aError.Error() != KErrNone)
   868 				else if (aError.Error() != KErrNone)
   846 					{
   869 					{
   847 					TInt err = SkipLineRemainder();
   870 					SkipLineRemainderL();
   848 					if (err!=KErrNone) SkipToEnd();
       
   849 					}
   871 					}
   850 				break;
   872 				break;
   851 				}
   873 				}
   852 			case EOr:
   874 			case EOr:
   853 				{
   875 				{
   855 					{
   877 					{
   856 					SkipToEnd();
   878 					SkipToEnd();
   857 					}
   879 					}
   858 				else if (aError.Error() == KErrNone)
   880 				else if (aError.Error() == KErrNone)
   859 					{
   881 					{
   860 					TInt err = SkipLineRemainder();
   882 					SkipLineRemainderL();
   861 					if (err!=KErrNone) SkipToEnd();
       
   862 					}
   883 					}
   863 				break;
   884 				break;
   864 				}
   885 				}
   865 			case EAndOr:
   886 			case EAndOr:
   866 				{
   887 				{
   877 			}
   898 			}
   878 
   899 
   879 		delete iForegroundPipeLine;
   900 		delete iForegroundPipeLine;
   880 		iForegroundPipeLine = NULL;
   901 		iForegroundPipeLine = NULL;
   881 
   902 
   882 		if (iLexer1->More())
   903 		if (iLexer1->MoreL())
   883 			{
   904 			{
   884 			iNextPipeLineCallBack->Call();
   905 			iNextPipeLineCallBack->Call();
   885 			}
   906 			}
   886 		}
   907 		}
   887 	else
   908 	else
   894 			iCompletionError.Set(aError);
   915 			iCompletionError.Set(aError);
   895 			}
   916 			}
   896 		delete &aPipeLine;
   917 		delete &aPipeLine;
   897 		}
   918 		}
   898 
   919 
   899 	if (iObserver && !iLexer1->More() && (iForegroundPipeLine == NULL) && (iBackgroundPipeLines.Count() == 0))
   920 	if (iObserver && !iLexer1->MoreL() && (iForegroundPipeLine == NULL) && (iBackgroundPipeLines.Count() == 0))
   900 		{
   921 		{
   901 		iCompletionCallBack->CallBack();
   922 		iCompletionCallBack->CallBack();
   902 		}
   923 		}
   903 	}
   924 	}
   904 
   925