|
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 } |