crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Parser/PreProcessor/Nodes/SymNodePreProcessorCondition.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 /*
       
     2 * Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 using System;
       
    19 using SymBuildParsingLib.Tree;
       
    20 using SymBuildParsingLib.Token;
       
    21 using SymBuildParsingLib.Utils;
       
    22 using SymBuildParsingLib.Parser.Framework.Document;
       
    23 using SymBuildParsingLib.Parser.Framework.Nodes;
       
    24 using SymbianTree;
       
    25 
       
    26 namespace SymBuildParsingLib.Parser.PreProcessor.Nodes
       
    27 {
       
    28 	public class SymNodePreProcessorCondition : SymNodeCondition
       
    29 	{
       
    30 		#region Constructors & destructor
       
    31 		public SymNodePreProcessorCondition( SymNodeCondition.TType aType )
       
    32 		: base( aType )
       
    33 		{
       
    34 		}
       
    35 
       
    36 		public SymNodePreProcessorCondition( string aName )
       
    37 		: base( aName )
       
    38 		{
       
    39 		}
       
    40 		#endregion
       
    41 
       
    42 		#region From SymNodeCondition
       
    43 		public override void Evaluate( SymParserDocumentContext aContext )
       
    44 		{
       
    45 			IsEvaluated = false;
       
    46 
       
    47 			if	( Type == TType.ETypeIf || Type == TType.ETypeElseIf )
       
    48 			{
       
    49 				// Evaluate the expression, taking into account the current #define'd 
       
    50 				// values. Prepares a new document with these expressions evaluated.
       
    51 				SymTokenDocument evalDoc = new SymTokenDocument();
       
    52 				EvaluateDefineNodes( BalancedArguments, evalDoc, aContext );
       
    53 				string expression = evalDoc.ChildrenAsString( false, true );
       
    54 				EvaluationResult = SymExpressionEvaluator.EvaluateAsBoolean( expression );
       
    55 			}
       
    56 			else if ( Type == TType.ETypeIfdef || Type == TType.ETypeIfndef )
       
    57 			{
       
    58 				// Convert the tree to a flat expression
       
    59 				string symbol = BalancedArguments.ChildrenAsString( true, true );
       
    60 
       
    61 				// Check if the symbol is defined
       
    62 				if ( Type == TType.ETypeIfdef )
       
    63 				{
       
    64 					EvaluationResult = aContext.DefineDirectory.IsDefined( symbol );
       
    65 				}
       
    66 				else if ( Type == TType.ETypeIfndef )
       
    67 				{
       
    68 					EvaluationResult = !aContext.DefineDirectory.IsDefined( symbol );
       
    69 				}
       
    70 			}
       
    71 			else if ( Type == TType.ETypeElse )
       
    72 			{
       
    73 				// Else statements always evaluate to true. We let the parent
       
    74 				// conditional expression node decide whether or not this item should
       
    75 				// 'fire'
       
    76 				EvaluationResult = true;
       
    77 			}
       
    78 
       
    79 			IsEvaluated = true;
       
    80 		}
       
    81 		#endregion
       
    82 
       
    83 		#region Properties
       
    84 		#endregion
       
    85 
       
    86 		#region Internal methods
       
    87 		private void EvaluateDefineNodes( SymNode aNode, SymTokenDocument aDocument, SymParserDocumentContext aContext )
       
    88 		{
       
    89 			foreach( SymNode n in aNode )
       
    90 			{
       
    91 				if	( n is SymTokenBalancerMarkerLevelNode )
       
    92 				{
       
    93 					bool added = false;
       
    94 					//
       
    95 					SymTokenBalancerMarkerLevelNode levelNode = (SymTokenBalancerMarkerLevelNode) n;
       
    96 					if	( levelNode.IsFunction )
       
    97 					{
       
    98 						SymNodeToken functionNameNode = levelNode.FunctionName;
       
    99 						//
       
   100 						if	( functionNameNode.Token.Equals( iDefinedNodeToken ) )
       
   101 						{
       
   102 							SymTokenContainer defineName = levelNode.ChildTokens;
       
   103 							string flattened = defineName.CoalescedTokenValue;
       
   104 							
       
   105 							// Get definition result
       
   106 							bool isDefined = aContext.DefineDirectory.IsDefined( flattened );
       
   107 							SymToken isDefinedToken = new SymToken( isDefined.ToString().ToLower(), SymToken.TClass.EClassAlphaNumeric, SymToken.TType.ETypeAlphaNumericNormal );
       
   108 
       
   109 							// Remove already added "defined" text node from output document
       
   110 							if	( aDocument.CurrentNode.LastChild is SymNodeToken )
       
   111 							{
       
   112 								SymNodeToken last = (SymNodeToken) aDocument.CurrentNode.LastChild;
       
   113 								if	( last.Token.Equals( iDefinedNodeToken ) )
       
   114 								{
       
   115 									last.Remove();
       
   116 								}
       
   117 							}
       
   118 
       
   119 							// Add result
       
   120 							aDocument.CurrentNode.Add( new SymNodeToken( isDefinedToken ) );
       
   121 							added = true;
       
   122 						}
       
   123 					}
       
   124 
       
   125 					if	( added == false )
       
   126 					{
       
   127 						if	( levelNode.HasPrevious && levelNode.Previous is SymTokenBalancerNodeEmittedElement )
       
   128 						{
       
   129 							levelNode.EmittedElementPrevious.AddToDocumentIfEmittable( aDocument );
       
   130 						}
       
   131 
       
   132 						SymNode newLevelNode = new SymNodeAddAsChild();
       
   133 						aDocument.CurrentNode.Add( newLevelNode );
       
   134 						aDocument.CurrentNode = newLevelNode;
       
   135 						EvaluateDefineNodes( n, aDocument, aContext );
       
   136 						aDocument.MakeParentCurrent();
       
   137 
       
   138 						if	( levelNode.HasNext && levelNode.Next is SymTokenBalancerNodeEmittedElement )
       
   139 						{
       
   140 							levelNode.EmittedElementNext.AddToDocumentIfEmittable( aDocument );
       
   141 						}
       
   142 					}
       
   143 				}
       
   144 				else if ( n is SymNodeToken )
       
   145 				{
       
   146 					SymNodeToken node = (SymNodeToken) n;
       
   147 					SymNodeToken copy = new SymNodeToken( node.Token );
       
   148 					aDocument.CurrentNode.Add( copy );
       
   149 				}
       
   150 				else if	( n is SymTokenBalancerNodeEmittedElement )
       
   151 				{
       
   152 					// Handled when the level marker is reached
       
   153 				}
       
   154 			}
       
   155 		}
       
   156 		#endregion
       
   157 
       
   158 		#region Data members
       
   159 		private static SymToken iDefinedNodeToken = new SymToken( "defined", SymToken.TClass.EClassAlphaNumeric, SymToken.TType.ETypeAlphaNumericNormal );
       
   160 		#endregion
       
   161 	}
       
   162 }