crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Parser/PreProcessor/Workers/SymPreProcessorWorkerInclude.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 System.Text;
       
    20 using SymBuildParsingLib.Tree;
       
    21 using SymBuildParsingLib.Token;
       
    22 using SymBuildParsingLib.Common.Objects;
       
    23 using SymBuildParsingLib.Parser.Framework.Parser;
       
    24 using SymBuildParsingLib.Parser.Framework.Workers;
       
    25 using SymBuildParsingLib.Parser.Framework.Document;
       
    26 using SymBuildParsingLib.Parser.PreProcessor.Nodes;
       
    27 
       
    28 namespace SymBuildParsingLib.Parser.PreProcessor.Workers
       
    29 {
       
    30 	public sealed class SymPreProcessorWorkerInclude : SymParserWorkerConsumer
       
    31 	{
       
    32 		#region Constructors & destructor
       
    33 		public SymPreProcessorWorkerInclude( SymParserWorkerContext aContext )
       
    34 			: base( aContext, SymToken.TClass.EClassNewLine, SymParserWorkerConsumer.TDyingAction.EWhenDyingMakeAbsoluteParentNodeCurrent )
       
    35 		{
       
    36 			// Make a new child node for the include
       
    37 			iIncludeNode = new SymNodePreProcessorInclude();
       
    38 			aContext.Document.CurrentNode.Add( iIncludeNode );
       
    39 			aContext.Document.CurrentNode = iIncludeNode;
       
    40 		}
       
    41 		#endregion
       
    42 
       
    43 		#region From SymParserWorkerConsumer
       
    44 		protected override void HandleTerminatingConditionMatch( SymToken aToken )
       
    45 		{
       
    46 			// Update the include so that it contains a fully resolved path
       
    47 			iIncludeNode.IncludeDefinition.AdjustRelativeInclude( WorkerContext.Parser.FileName );
       
    48 
       
    49 			// We've now a fully resolved file name which we can parse, should
       
    50 			// we desire...
       
    51 			string includeFile = iIncludeNode.IncludeDefinition.Location;
       
    52 			if	( Utils.SymFileSystemUtils.FileExists( includeFile ) )
       
    53 			{
       
    54 				// Make a new document context
       
    55 				SymParserDocumentContext subDocumentContext = new SymParserDocumentContext( includeFile, WorkerContext );
       
    56 
       
    57 				// Use the existing document, but with a new context
       
    58 				WorkerContext.Document.PushContext( subDocumentContext );
       
    59 
       
    60 				// Make a new carbon copy of this parser (whatever concrete type it may be)
       
    61 				SymParserBase subParser = WorkerContext.Parser.CarbonCopy( new object[] { WorkerContext.Document } );
       
    62 
       
    63 				// Make the waiting object
       
    64 				SymParserWaiter waiter = new SymParserWaiter( subParser );
       
    65 
       
    66 				// Now parse the file and wait for the result
       
    67 				subParser.Parse();
       
    68 				waiter.Wait();
       
    69 
       
    70 				// Restore the original context
       
    71 				WorkerContext.Document.PopContext();
       
    72 			}
       
    73 		}
       
    74 		#endregion
       
    75 
       
    76 		#region From SymParserWorker
       
    77 		public override SymParserWorker.TTokenConsumptionType OfferToken( SymToken aToken )
       
    78 		{
       
    79 			TTokenConsumptionType ret = TTokenConsumptionType.ETokenNotConsumed;
       
    80 			System.Diagnostics.Debug.Assert( WorkerContext.Document.CurrentNode is SymNodePreProcessorInclude );
       
    81 			
       
    82 			// Only consume tokens whilst we're unsure of the include type (system vs user).
       
    83 			if	( iIncludeNode.IncludeDefinition.Type == SymIncludeDefinition.TType.ETypeUndefined )
       
    84 			{
       
    85 				if	( aToken.Class == SymToken.TClass.EClassQuotation )
       
    86 				{
       
    87 					// Must be a user include if its a quotation that we're handling
       
    88 					iIncludeNode.IncludeDefinition.Type = SymIncludeDefinition.TType.ETypeUser;
       
    89 					ret = TTokenConsumptionType.ETokenConsumed;
       
    90 				}
       
    91 				else if ( aToken.Class == SymToken.TClass.EClassSymbol && aToken.Value == "<" )
       
    92 				{
       
    93 					// Consume it, but don't absorb it
       
    94 					iIncludeNode.IncludeDefinition.Type = SymIncludeDefinition.TType.ETypeSystem;
       
    95 					ret = TTokenConsumptionType.ETokenConsumed;
       
    96 				}
       
    97 			}
       
    98 			else if ( iIncludeNode.IncludeDefinition.Type != SymIncludeDefinition.TType.ETypeUndefined )
       
    99 			{
       
   100 				// Only consume the tokens whilst we've not yet identified the include
       
   101 				// definition location.
       
   102 				if	( iIncludeNode.IncludeDefinition.Location.Length == 0 )
       
   103 				{
       
   104 					if	( iIncludeNode.IncludeDefinition.Type == SymIncludeDefinition.TType.ETypeSystem && aToken.Class == SymToken.TClass.EClassSymbol && aToken.Value == ">" )
       
   105 					{
       
   106 						iIncludeNode.IncludeDefinition.Location = iWorkingIncludePath.ToString();
       
   107 					}
       
   108 					else if ( iIncludeNode.IncludeDefinition.Type == SymIncludeDefinition.TType.ETypeUser && aToken.Class == SymToken.TClass.EClassQuotation && aToken.Type != SymToken.TType.ETypeUnidentified )
       
   109 					{
       
   110 						iIncludeNode.IncludeDefinition.Location = iWorkingIncludePath.ToString();
       
   111 					}
       
   112 					else
       
   113 					{
       
   114 						iWorkingIncludePath.Append( aToken.Value );
       
   115 					}
       
   116 				}
       
   117 			}
       
   118 
       
   119 			// Base class will dequeue us once we reach the new line
       
   120 			ret = base.OfferToken( aToken );
       
   121 			return ret;
       
   122 		}
       
   123 		#endregion
       
   124 
       
   125 		#region Data members
       
   126 		private StringBuilder iWorkingIncludePath = new StringBuilder();
       
   127 		private readonly SymNodePreProcessorInclude iIncludeNode;
       
   128 		#endregion
       
   129 	}
       
   130 }