diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Parser/PreProcessor/Nodes/SymNodePreProcessorCondition.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Parser/PreProcessor/Nodes/SymNodePreProcessorCondition.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,162 @@ +/* +* Copyright (c) 2004-2008 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: +* +*/ + +using System; +using SymBuildParsingLib.Tree; +using SymBuildParsingLib.Token; +using SymBuildParsingLib.Utils; +using SymBuildParsingLib.Parser.Framework.Document; +using SymBuildParsingLib.Parser.Framework.Nodes; +using SymbianTree; + +namespace SymBuildParsingLib.Parser.PreProcessor.Nodes +{ + public class SymNodePreProcessorCondition : SymNodeCondition + { + #region Constructors & destructor + public SymNodePreProcessorCondition( SymNodeCondition.TType aType ) + : base( aType ) + { + } + + public SymNodePreProcessorCondition( string aName ) + : base( aName ) + { + } + #endregion + + #region From SymNodeCondition + public override void Evaluate( SymParserDocumentContext aContext ) + { + IsEvaluated = false; + + if ( Type == TType.ETypeIf || Type == TType.ETypeElseIf ) + { + // Evaluate the expression, taking into account the current #define'd + // values. Prepares a new document with these expressions evaluated. + SymTokenDocument evalDoc = new SymTokenDocument(); + EvaluateDefineNodes( BalancedArguments, evalDoc, aContext ); + string expression = evalDoc.ChildrenAsString( false, true ); + EvaluationResult = SymExpressionEvaluator.EvaluateAsBoolean( expression ); + } + else if ( Type == TType.ETypeIfdef || Type == TType.ETypeIfndef ) + { + // Convert the tree to a flat expression + string symbol = BalancedArguments.ChildrenAsString( true, true ); + + // Check if the symbol is defined + if ( Type == TType.ETypeIfdef ) + { + EvaluationResult = aContext.DefineDirectory.IsDefined( symbol ); + } + else if ( Type == TType.ETypeIfndef ) + { + EvaluationResult = !aContext.DefineDirectory.IsDefined( symbol ); + } + } + else if ( Type == TType.ETypeElse ) + { + // Else statements always evaluate to true. We let the parent + // conditional expression node decide whether or not this item should + // 'fire' + EvaluationResult = true; + } + + IsEvaluated = true; + } + #endregion + + #region Properties + #endregion + + #region Internal methods + private void EvaluateDefineNodes( SymNode aNode, SymTokenDocument aDocument, SymParserDocumentContext aContext ) + { + foreach( SymNode n in aNode ) + { + if ( n is SymTokenBalancerMarkerLevelNode ) + { + bool added = false; + // + SymTokenBalancerMarkerLevelNode levelNode = (SymTokenBalancerMarkerLevelNode) n; + if ( levelNode.IsFunction ) + { + SymNodeToken functionNameNode = levelNode.FunctionName; + // + if ( functionNameNode.Token.Equals( iDefinedNodeToken ) ) + { + SymTokenContainer defineName = levelNode.ChildTokens; + string flattened = defineName.CoalescedTokenValue; + + // Get definition result + bool isDefined = aContext.DefineDirectory.IsDefined( flattened ); + SymToken isDefinedToken = new SymToken( isDefined.ToString().ToLower(), SymToken.TClass.EClassAlphaNumeric, SymToken.TType.ETypeAlphaNumericNormal ); + + // Remove already added "defined" text node from output document + if ( aDocument.CurrentNode.LastChild is SymNodeToken ) + { + SymNodeToken last = (SymNodeToken) aDocument.CurrentNode.LastChild; + if ( last.Token.Equals( iDefinedNodeToken ) ) + { + last.Remove(); + } + } + + // Add result + aDocument.CurrentNode.Add( new SymNodeToken( isDefinedToken ) ); + added = true; + } + } + + if ( added == false ) + { + if ( levelNode.HasPrevious && levelNode.Previous is SymTokenBalancerNodeEmittedElement ) + { + levelNode.EmittedElementPrevious.AddToDocumentIfEmittable( aDocument ); + } + + SymNode newLevelNode = new SymNodeAddAsChild(); + aDocument.CurrentNode.Add( newLevelNode ); + aDocument.CurrentNode = newLevelNode; + EvaluateDefineNodes( n, aDocument, aContext ); + aDocument.MakeParentCurrent(); + + if ( levelNode.HasNext && levelNode.Next is SymTokenBalancerNodeEmittedElement ) + { + levelNode.EmittedElementNext.AddToDocumentIfEmittable( aDocument ); + } + } + } + else if ( n is SymNodeToken ) + { + SymNodeToken node = (SymNodeToken) n; + SymNodeToken copy = new SymNodeToken( node.Token ); + aDocument.CurrentNode.Add( copy ); + } + else if ( n is SymTokenBalancerNodeEmittedElement ) + { + // Handled when the level marker is reached + } + } + } + #endregion + + #region Data members + private static SymToken iDefinedNodeToken = new SymToken( "defined", SymToken.TClass.EClassAlphaNumeric, SymToken.TType.ETypeAlphaNumericNormal ); + #endregion + } +}