From 95f2f4425b900374c7d7b583ae810b096121b3c4 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sat, 2 Dec 2017 00:46:11 -0800 Subject: Implement support for IExtensionCommandLine and IPreprocessorExtension --- src/WixToolset.Core/Preprocessor.cs | 453 ++++++++++++------------------------ 1 file changed, 154 insertions(+), 299 deletions(-) (limited to 'src/WixToolset.Core/Preprocessor.cs') diff --git a/src/WixToolset.Core/Preprocessor.cs b/src/WixToolset.Core/Preprocessor.cs index 3aed0735..195ede9e 100644 --- a/src/WixToolset.Core/Preprocessor.cs +++ b/src/WixToolset.Core/Preprocessor.cs @@ -4,7 +4,6 @@ namespace WixToolset.Core { using System; using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Text; @@ -14,6 +13,7 @@ namespace WixToolset.Core using WixToolset.Data; using WixToolset.Extensibility; using WixToolset.Core.Preprocess; + using WixToolset.Extensibility.Services; /// /// Preprocessor object @@ -30,42 +30,22 @@ namespace WixToolset.Core }; private readonly XmlReaderSettings FragmentXmlReaderSettings = new XmlReaderSettings() { - ConformanceLevel = System.Xml.ConformanceLevel.Fragment, + ConformanceLevel = ConformanceLevel.Fragment, ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None, XmlResolver = null, }; - private List extensions; - private Dictionary extensionsByPrefix; + private IPreprocessContext Context { get; set; } - private SourceLineNumber currentLineNumber; - private Stack sourceStack; + private Stack CurrentFileStack { get; } = new Stack(); - private PreprocessorCore core; - private TextWriter preprocessOut; + private Dictionary ExtensionsByPrefix { get; } = new Dictionary(); - private Stack includeNextStack; - private Stack currentFileStack; + private Stack IncludeNextStack { get; } = new Stack(); - private Platform currentPlatform; + private Stack SourceStack { get; } = new Stack(); - /// - /// Creates a new preprocesor. - /// - public Preprocessor() - { - this.IncludeSearchPaths = new List(); - - this.extensions = new List(); - this.extensionsByPrefix = new Dictionary(); - - this.sourceStack = new Stack(); - - this.includeNextStack = new Stack(); - this.currentFileStack = new Stack(); - - this.currentPlatform = Platform.X86; - } + private IPreprocessHelper Helper { get; set; } /// /// Event for ifdef/ifndef directives. @@ -87,62 +67,6 @@ namespace WixToolset.Core /// public event ResolvedVariableEventHandler ResolvedVariable; - /// - /// Enumeration for preprocessor operations in if statements. - /// - private enum PreprocessorOperation - { - /// The and operator. - And, - - /// The or operator. - Or, - - /// The not operator. - Not - } - - /// - /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. - /// - /// The platform which the compiler will use when defaulting 64-bit attributes and elements. - public Platform CurrentPlatform - { - get { return this.currentPlatform; } - set { this.currentPlatform = value; } - } - - /// - /// Ordered list of search paths that the precompiler uses to find included files. - /// - /// List of ordered search paths to use during precompiling. - public IList IncludeSearchPaths { get; private set; } - - /// - /// Specifies the text stream to display the postprocessed data to. - /// - /// TextWriter to write preprocessed xml to. - public TextWriter PreprocessOut - { - get { return this.preprocessOut; } - set { this.preprocessOut = value; } - } - - /// - /// Get the source line information for the current element. The precompiler will insert - /// special source line number processing instructions before each element that it - /// encounters. This is where those line numbers are read and processed. This function - /// may return an array of source line numbers because the element may have come from - /// an included file, in which case the chain of imports is expressed in the array. - /// - /// Element to get source line information for. - /// Returns the stack of imports used to author the element being processed. - [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] - public static SourceLineNumber GetSourceLineNumbers(XmlNode node) - { - return null; - } - /// /// Get the source line information for the current element. The precompiler will insert /// special source line number information for each element that it encounters. @@ -159,122 +83,94 @@ namespace WixToolset.Core } /// - /// Adds an extension. + /// Preprocesses a file. /// - /// The extension to add. - public void AddExtension(IPreprocessorExtension extension) + /// The preprocessing context. + /// XDocument with the postprocessed data. + public XDocument Process(IPreprocessContext context) { - this.extensions.Add(extension); + this.Context = context ?? throw new ArgumentNullException(nameof(context)); - if (null != extension.Prefixes) + using (XmlReader reader = XmlReader.Create(context.SourceFile, DocumentXmlReaderSettings)) { - foreach (string prefix in extension.Prefixes) - { - IPreprocessorExtension collidingExtension; - if (!this.extensionsByPrefix.TryGetValue(prefix, out collidingExtension)) - { - this.extensionsByPrefix.Add(prefix, extension); - } - else - { - Messaging.Instance.OnMessage(WixErrors.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString())); - } - } + return Process(context, reader); } - - //if (null != extension.InspectorExtension) - //{ - // this.inspectorExtensions.Add(extension.InspectorExtension); - //} } /// /// Preprocesses a file. /// - /// The file to preprocess. - /// The variables defined prior to preprocessing. + /// The preprocessing context. + /// XmlReader to processing the context. /// XDocument with the postprocessed data. - [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] - public XDocument Process(string sourceFile, IDictionary variables) + public XDocument Process(IPreprocessContext context, XmlReader reader) { - using (Stream sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) - using (XmlReader reader = XmlReader.Create(sourceFile, DocumentXmlReaderSettings)) + if (this.Context == null) { - return Process(reader, variables, sourceFile); + this.Context = context ?? throw new ArgumentNullException(nameof(context)); + } + else if (this.Context != context) + { + throw new ArgumentException(nameof(context)); } - } - /// - /// Preprocesses a file. - /// - /// The file to preprocess. - /// The variables defined prior to preprocessing. - /// XDocument with the postprocessed data. - [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] - public XDocument Process(XmlReader reader, IDictionary variables, string sourceFile = null) - { - if (String.IsNullOrEmpty(sourceFile) && !String.IsNullOrEmpty(reader.BaseURI)) + if (String.IsNullOrEmpty(this.Context.SourceFile) && !String.IsNullOrEmpty(reader.BaseURI)) { - Uri uri = new Uri(reader.BaseURI); - sourceFile = uri.AbsolutePath; + var uri = new Uri(reader.BaseURI); + this.Context.SourceFile = uri.AbsolutePath; } - this.core = new PreprocessorCore(this.extensionsByPrefix, sourceFile, variables); - this.core.ResolvedVariableHandler = this.ResolvedVariable; - this.core.CurrentPlatform = this.currentPlatform; - this.currentLineNumber = new SourceLineNumber(sourceFile); - this.currentFileStack.Clear(); - this.currentFileStack.Push(this.core.GetVariableValue(this.currentLineNumber, "sys", "SOURCEFILEDIR")); + this.Context.CurrentSourceLineNumber = new SourceLineNumber(this.Context.SourceFile); - // Process the reader into the output. - XDocument output = new XDocument(); - try + this.Helper = this.Context.ServiceProvider.GetService(); + + foreach (var extension in this.Context.Extensions) { - foreach (PreprocessorExtension extension in this.extensions) + if (null != extension.Prefixes) { - extension.Core = this.core; - extension.Initialize(); + foreach (string prefix in extension.Prefixes) + { + if (!this.ExtensionsByPrefix.TryGetValue(prefix, out var collidingExtension)) + { + this.ExtensionsByPrefix.Add(prefix, extension); + } + else + { + this.Context.Messaging.OnMessage(WixErrors.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString())); + } + } } - this.PreprocessReader(false, reader, output, 0); - } - catch (XmlException e) - { - this.UpdateCurrentLineNumber(reader, 0); - throw new WixException(WixErrors.InvalidXml(this.currentLineNumber, "source", e.Message)); + extension.PrePreprocess(context); } - // Fire event with post-processed document. - ProcessedStreamEventArgs args = new ProcessedStreamEventArgs(sourceFile, output); - this.OnProcessedStream(args); + this.CurrentFileStack.Clear(); + this.CurrentFileStack.Push(this.Helper.GetVariableValue(this.Context, "sys", "SOURCEFILEDIR")); - // preprocess the generated XML Document - foreach (PreprocessorExtension extension in this.extensions) + // Process the reader into the output. + XDocument output = new XDocument(); + try { - extension.PreprocessDocument(output); - } + this.PreprocessReader(false, reader, output, 0); - // finalize the preprocessing - foreach (PreprocessorExtension extension in this.extensions) - { - extension.Finish(); - extension.Core = null; + // Fire event with post-processed document. + this.ProcessedStream?.Invoke(this, new ProcessedStreamEventArgs(this.Context.SourceFile, output)); } - - if (this.core.EncounteredError) + catch (XmlException e) { - return null; + this.UpdateCurrentLineNumber(reader, 0); + throw new WixException(WixErrors.InvalidXml(this.Context.CurrentSourceLineNumber, "source", e.Message)); } - else + finally { - if (null != this.preprocessOut) + // Finalize the preprocessing. + foreach (var extension in this.Context.Extensions) { - output.Save(this.preprocessOut); - this.preprocessOut.Flush(); + extension.PostPreprocess(output); } - - return output; } + + return this.Context.Messaging.EncounteredError ? null : output; } /// @@ -339,42 +235,6 @@ namespace WixToolset.Core return true; } - /// - /// Fires an event when an ifdef/ifndef directive is processed. - /// - /// ifdef/ifndef event arguments. - private void OnIfDef(IfDefEventArgs ea) - { - if (null != this.IfDef) - { - this.IfDef(this, ea); - } - } - - /// - /// Fires an event when an included file is processed. - /// - /// Included file event arguments. - private void OnIncludedFile(IncludedFileEventArgs ea) - { - if (null != this.IncludedFile) - { - this.IncludedFile(this, ea); - } - } - - /// - /// Fires an event after the file is preprocessed. - /// - /// Included file event arguments. - private void OnProcessedStream(ProcessedStreamEventArgs ea) - { - if (null != this.ProcessedStream) - { - this.ProcessedStream(this, ea); - } - } - /// /// Tests expression to see if it starts with a keyword. /// @@ -383,7 +243,7 @@ namespace WixToolset.Core /// true if expression starts with a keyword. private static bool StartsWithKeyword(string expression, PreprocessorOperation operation) { - expression = expression.ToUpper(CultureInfo.InvariantCulture); + expression = expression.ToUpperInvariant(); switch (operation) { case PreprocessorOperation.Not: @@ -431,7 +291,7 @@ namespace WixToolset.Core // update information here in case an error occurs before the next read this.UpdateCurrentLineNumber(reader, offset); - SourceLineNumber sourceLineNumbers = this.currentLineNumber; + var sourceLineNumbers = this.Context.CurrentSourceLineNumber; // check for changes in conditional processing if (XmlNodeType.ProcessingInstruction == reader.NodeType) @@ -459,14 +319,14 @@ namespace WixToolset.Core name = reader.Value.Trim(); if (ifContext.IsTrue) { - ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null != this.core.GetVariableValue(sourceLineNumbers, name, true)), IfState.If); + ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null != this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); } else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true { ifContext = new IfContext(); } ignore = true; - OnIfDef(new IfDefEventArgs(sourceLineNumbers, true, ifContext.IsTrue, name)); + this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, true, ifContext.IsTrue, name)); break; case "ifndef": @@ -474,25 +334,25 @@ namespace WixToolset.Core name = reader.Value.Trim(); if (ifContext.IsTrue) { - ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null == this.core.GetVariableValue(sourceLineNumbers, name, true)), IfState.If); + ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null == this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); } else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true { ifContext = new IfContext(); } ignore = true; - OnIfDef(new IfDefEventArgs(sourceLineNumbers, false, !ifContext.IsTrue, name)); + this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, false, !ifContext.IsTrue, name)); break; case "elseif": if (0 == ifStack.Count) { - throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "elseif")); + throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); } if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) { - throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "elseif")); + throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); } ifContext.IfState = IfState.ElseIf; // we're now in an elseif @@ -510,12 +370,12 @@ namespace WixToolset.Core case "else": if (0 == ifStack.Count) { - throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "else")); + throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); } if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) { - throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "else")); + throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); } ifContext.IfState = IfState.Else; // we're now in an else @@ -526,7 +386,7 @@ namespace WixToolset.Core case "endif": if (0 == ifStack.Count) { - throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "endif")); + throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "endif")); } ifContext = (IfContext)ifStack.Pop(); @@ -606,7 +466,7 @@ namespace WixToolset.Core break; case "endforeach": // endforeach is handled in PreprocessForeach, so seeing it here is an error - throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "foreach", "endforeach")); + throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "foreach", "endforeach")); case "pragma": this.PreprocessPragma(reader.Value, currentContainer); @@ -619,31 +479,33 @@ namespace WixToolset.Core break; case XmlNodeType.Element: - if (0 < this.includeNextStack.Count && this.includeNextStack.Peek()) + if (0 < this.IncludeNextStack.Count && this.IncludeNextStack.Peek()) { if ("Include" != reader.LocalName) { - this.core.OnMessage(WixErrors.InvalidDocumentElement(this.currentLineNumber, reader.Name, "include", "Include")); + this.Context.Messaging.OnMessage(WixErrors.InvalidDocumentElement(sourceLineNumbers, reader.Name, "include", "Include")); } - this.includeNextStack.Pop(); - this.includeNextStack.Push(false); + this.IncludeNextStack.Pop(); + this.IncludeNextStack.Push(false); break; } - bool empty = reader.IsEmptyElement; - XNamespace ns = XNamespace.Get(reader.NamespaceURI); - XElement element = new XElement(ns + reader.LocalName); + var empty = reader.IsEmptyElement; + var ns = XNamespace.Get(reader.NamespaceURI); + var element = new XElement(ns + reader.LocalName); currentContainer.Add(element); this.UpdateCurrentLineNumber(reader, offset); - element.AddAnnotation(this.currentLineNumber); + element.AddAnnotation(sourceLineNumbers); while (reader.MoveToNextAttribute()) { - string value = this.core.PreprocessString(this.currentLineNumber, reader.Value); - XNamespace attribNamespace = XNamespace.Get(reader.NamespaceURI); + var value = this.Helper.PreprocessString(this.Context, reader.Value); + + var attribNamespace = XNamespace.Get(reader.NamespaceURI); attribNamespace = XNamespace.Xmlns == attribNamespace && reader.LocalName.Equals("xmlns") ? XNamespace.None : attribNamespace; + element.Add(new XAttribute(attribNamespace + reader.LocalName, value)); } @@ -662,12 +524,12 @@ namespace WixToolset.Core break; case XmlNodeType.Text: - string postprocessedText = this.core.PreprocessString(this.currentLineNumber, reader.Value); + string postprocessedText = this.Helper.PreprocessString(this.Context, reader.Value); currentContainer.Add(postprocessedText); break; case XmlNodeType.CDATA: - string postprocessedValue = this.core.PreprocessString(this.currentLineNumber, reader.Value); + string postprocessedValue = this.Helper.PreprocessString(this.Context, reader.Value); currentContainer.Add(new XCData(postprocessedValue)); break; @@ -678,13 +540,13 @@ namespace WixToolset.Core if (0 != ifStack.Count) { - throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.currentLineNumber, "if", "endif")); + throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.Context.CurrentSourceLineNumber, "if", "endif")); } // TODO: can this actually happen? if (0 != containerStack.Count) { - throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.currentLineNumber, "nodes", "nodes")); + throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.Context.CurrentSourceLineNumber, "nodes", "nodes")); } } @@ -694,12 +556,10 @@ namespace WixToolset.Core /// Text from source. private void PreprocessError(string errorMessage) { - SourceLineNumber sourceLineNumbers = this.currentLineNumber; - - // resolve other variables in the error message - errorMessage = this.core.PreprocessString(sourceLineNumbers, errorMessage); + // Resolve other variables in the error message. + errorMessage = this.Helper.PreprocessString(this.Context, errorMessage); - throw new WixException(WixErrors.PreprocessorError(sourceLineNumbers, errorMessage)); + throw new WixException(WixErrors.PreprocessorError(this.Context.CurrentSourceLineNumber, errorMessage)); } /// @@ -708,12 +568,10 @@ namespace WixToolset.Core /// Text from source. private void PreprocessWarning(string warningMessage) { - SourceLineNumber sourceLineNumbers = this.currentLineNumber; - - // resolve other variables in the warning message - warningMessage = this.core.PreprocessString(sourceLineNumbers, warningMessage); + // Resolve other variables in the warning message. + warningMessage = this.Helper.PreprocessString(this.Context, warningMessage); - this.core.OnMessage(WixWarnings.PreprocessorWarning(sourceLineNumbers, warningMessage)); + this.Context.Messaging.OnMessage(WixWarnings.PreprocessorWarning(this.Context.CurrentSourceLineNumber, warningMessage)); } /// @@ -722,16 +580,15 @@ namespace WixToolset.Core /// Text from source. private void PreprocessDefine(string originalDefine) { - Match match = defineRegex.Match(originalDefine); - SourceLineNumber sourceLineNumbers = this.currentLineNumber; + var match = defineRegex.Match(originalDefine); if (!match.Success) { - throw new WixException(WixErrors.IllegalDefineStatement(sourceLineNumbers, originalDefine)); + throw new WixException(WixErrors.IllegalDefineStatement(this.Context.CurrentSourceLineNumber, originalDefine)); } - string defineName = match.Groups["varName"].Value; - string defineValue = match.Groups["varValue"].Value; + var defineName = match.Groups["varName"].Value; + var defineValue = match.Groups["varValue"].Value; // strip off the optional quotes if (1 < defineValue.Length && @@ -742,15 +599,15 @@ namespace WixToolset.Core } // resolve other variables in the variable value - defineValue = this.core.PreprocessString(sourceLineNumbers, defineValue); + defineValue = this.Helper.PreprocessString(this.Context, defineValue); if (defineName.StartsWith("var.", StringComparison.Ordinal)) { - this.core.AddVariable(sourceLineNumbers, defineName.Substring(4), defineValue); + this.Helper.AddVariable(this.Context, defineName.Substring(4), defineValue); } else { - this.core.AddVariable(sourceLineNumbers, defineName, defineValue); + this.Helper.AddVariable(this.Context, defineName, defineValue); } } @@ -760,16 +617,15 @@ namespace WixToolset.Core /// Text from source. private void PreprocessUndef(string originalDefine) { - SourceLineNumber sourceLineNumbers = this.currentLineNumber; - string name = this.core.PreprocessString(sourceLineNumbers, originalDefine.Trim()); + var name = this.Helper.PreprocessString(this.Context, originalDefine.Trim()); if (name.StartsWith("var.", StringComparison.Ordinal)) { - this.core.RemoveVariable(sourceLineNumbers, name.Substring(4)); + this.Helper.RemoveVariable(this.Context, name.Substring(4)); } else { - this.core.RemoveVariable(sourceLineNumbers, name); + this.Helper.RemoveVariable(this.Context, name); } } @@ -780,12 +636,12 @@ namespace WixToolset.Core /// Parent container for included content. private void PreprocessInclude(string includePath, XContainer parent) { - SourceLineNumber sourceLineNumbers = this.currentLineNumber; + var sourceLineNumbers = this.Context.CurrentSourceLineNumber; - // preprocess variables in the path - includePath = this.core.PreprocessString(sourceLineNumbers, includePath); + // Preprocess variables in the path. + includePath = this.Helper.PreprocessString(this.Context, includePath); - string includeFile = this.GetIncludeFile(includePath); + var includeFile = this.GetIncludeFile(includePath); if (null == includeFile) { @@ -807,7 +663,7 @@ namespace WixToolset.Core throw new WixException(WixErrors.InvalidXml(sourceLineNumbers, "source", e.Message)); } - this.OnIncludedFile(new IncludedFileEventArgs(sourceLineNumbers, includeFile)); + this.IncludedFile?.Invoke(this, new IncludedFileEventArgs(sourceLineNumbers, includeFile)); this.PopInclude(); } @@ -821,11 +677,11 @@ namespace WixToolset.Core /// Offset for the line numbers. private void PreprocessForeach(XmlReader reader, XContainer container, int offset) { - // find the "in" token - int indexOfInToken = reader.Value.IndexOf(" in ", StringComparison.Ordinal); + // Find the "in" token. + var indexOfInToken = reader.Value.IndexOf(" in ", StringComparison.Ordinal); if (0 > indexOfInToken) { - throw new WixException(WixErrors.IllegalForeach(this.currentLineNumber, reader.Value)); + throw new WixException(WixErrors.IllegalForeach(this.Context.CurrentSourceLineNumber, reader.Value)); } // parse out the variable name @@ -833,7 +689,7 @@ namespace WixToolset.Core string varValuesString = reader.Value.Substring(indexOfInToken + 4).Trim(); // preprocess the variable values string because it might be a variable itself - varValuesString = this.core.PreprocessString(this.currentLineNumber, varValuesString); + varValuesString = this.Helper.PreprocessString(this.Context, varValuesString); string[] varValues = varValuesString.Split(';'); @@ -895,20 +751,20 @@ namespace WixToolset.Core } else if (reader.NodeType == XmlNodeType.None) { - throw new WixException(WixErrors.ExpectedEndforeach(this.currentLineNumber)); + throw new WixException(WixErrors.ExpectedEndforeach(this.Context.CurrentSourceLineNumber)); } reader.Read(); } - using (MemoryStream fragmentStream = new MemoryStream(Encoding.UTF8.GetBytes(fragmentBuilder.ToString()))) - using (XmlReader loopReader = XmlReader.Create(fragmentStream, FragmentXmlReaderSettings)) + using (var fragmentStream = new MemoryStream(Encoding.UTF8.GetBytes(fragmentBuilder.ToString()))) + using (var loopReader = XmlReader.Create(fragmentStream, FragmentXmlReaderSettings)) { // process each iteration, updating the variable's value each time foreach (string varValue in varValues) { // Always overwrite foreach variables. - this.core.AddVariable(this.currentLineNumber, varName, varValue, false); + this.Helper.AddVariable(this.Context, varName, varValue, false); try { @@ -917,7 +773,7 @@ namespace WixToolset.Core catch (XmlException e) { this.UpdateCurrentLineNumber(loopReader, offset); - throw new WixException(WixErrors.InvalidXml(this.currentLineNumber, "source", e.Message)); + throw new WixException(WixErrors.InvalidXml(this.Context.CurrentSourceLineNumber, "source", e.Message)); } fragmentStream.Position = 0; // seek back to the beginning for the next loop. @@ -931,24 +787,23 @@ namespace WixToolset.Core /// Text from source. private void PreprocessPragma(string pragmaText, XContainer parent) { - Match match = pragmaRegex.Match(pragmaText); - SourceLineNumber sourceLineNumbers = this.currentLineNumber; + var match = pragmaRegex.Match(pragmaText); if (!match.Success) { - throw new WixException(WixErrors.InvalidPreprocessorPragma(sourceLineNumbers, pragmaText)); + throw new WixException(WixErrors.InvalidPreprocessorPragma(this.Context.CurrentSourceLineNumber, pragmaText)); } // resolve other variables in the pragma argument(s) - string pragmaArgs = this.core.PreprocessString(sourceLineNumbers, match.Groups["pragmaValue"].Value).Trim(); + string pragmaArgs = this.Helper.PreprocessString(this.Context, match.Groups["pragmaValue"].Value).Trim(); try { - this.core.PreprocessPragma(sourceLineNumbers, match.Groups["pragmaName"].Value.Trim(), pragmaArgs, parent); + this.Helper.PreprocessPragma(this.Context, match.Groups["pragmaName"].Value.Trim(), pragmaArgs, parent); } catch (Exception e) { - throw new WixException(WixErrors.PreprocessorExtensionPragmaFailed(sourceLineNumbers, pragmaText, e.Message)); + throw new WixException(WixErrors.PreprocessorExtensionPragmaFailed(this.Context.CurrentSourceLineNumber, pragmaText, e.Message)); } } @@ -975,11 +830,11 @@ namespace WixToolset.Core int endingQuotes = expression.IndexOf('\"', 1); if (-1 == endingQuotes) { - throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } // cut the quotes off the string - token = this.core.PreprocessString(this.currentLineNumber, expression.Substring(1, endingQuotes - 1)); + token = this.Helper.PreprocessString(this.Context, expression.Substring(1, endingQuotes - 1)); // advance past this string expression = expression.Substring(endingQuotes + 1).Trim(); @@ -1009,7 +864,7 @@ namespace WixToolset.Core if (-1 == endingParen) { - throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } token = expression.Substring(0, endingParen + 1); @@ -1115,7 +970,7 @@ namespace WixToolset.Core { try { - varValue = this.core.PreprocessString(this.currentLineNumber, variable); + varValue = this.Helper.PreprocessString(this.Context, variable); } catch (ArgumentNullException) { @@ -1126,12 +981,12 @@ namespace WixToolset.Core else if (variable.IndexOf("(", StringComparison.Ordinal) != -1 || variable.IndexOf(")", StringComparison.Ordinal) != -1) { // make sure it doesn't contain parenthesis - throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } else if (variable.IndexOf("\"", StringComparison.Ordinal) != -1) { // shouldn't contain quotes - throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } return varValue; @@ -1162,7 +1017,7 @@ namespace WixToolset.Core { if (stringLiteral) { - throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } rightValue = this.GetNextToken(originalExpression, ref expression, out stringLiteral); @@ -1213,7 +1068,7 @@ namespace WixToolset.Core { if (operation.Length > 0) { - throw new WixException(WixErrors.ExpectedVariable(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.ExpectedVariable(this.Context.CurrentSourceLineNumber, originalExpression)); } // false expression @@ -1228,7 +1083,7 @@ namespace WixToolset.Core } else { - throw new WixException(WixErrors.UnexpectedLiteral(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnexpectedLiteral(this.Context.CurrentSourceLineNumber, originalExpression)); } } else @@ -1268,11 +1123,11 @@ namespace WixToolset.Core } catch (FormatException) { - throw new WixException(WixErrors.IllegalIntegerInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.IllegalIntegerInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } catch (OverflowException) { - throw new WixException(WixErrors.IllegalIntegerInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.IllegalIntegerInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } // Compare the numbers @@ -1314,7 +1169,7 @@ namespace WixToolset.Core closeParenIndex = expression.IndexOf(')', closeParenIndex); if (closeParenIndex == -1) { - throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); } if (InsideQuotes(expression, closeParenIndex)) @@ -1363,7 +1218,7 @@ namespace WixToolset.Core currentValue = !currentValue; break; default: - throw new WixException(WixErrors.UnexpectedPreprocessorOperator(this.currentLineNumber, operation.ToString())); + throw new WixException(WixErrors.UnexpectedPreprocessorOperator(this.Context.CurrentSourceLineNumber, operation.ToString())); } } @@ -1412,7 +1267,7 @@ namespace WixToolset.Core expression = expression.Trim(); if (expression.Length == 0) { - throw new WixException(WixErrors.UnexpectedEmptySubexpression(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.UnexpectedEmptySubexpression(this.Context.CurrentSourceLineNumber, originalExpression)); } // If the expression starts with parenthesis, evaluate it @@ -1433,7 +1288,7 @@ namespace WixToolset.Core expression = expression.Substring(3).Trim(); if (expression.Length == 0) { - throw new WixException(WixErrors.ExpectedExpressionAfterNot(this.currentLineNumber, originalExpression)); + throw new WixException(WixErrors.ExpectedExpressionAfterNot(this.Context.CurrentSourceLineNumber, originalExpression)); } expressionValue = this.EvaluateExpressionRecurse(originalExpression, ref expression, PreprocessorOperation.Not, true); @@ -1462,7 +1317,7 @@ namespace WixToolset.Core } else { - throw new WixException(WixErrors.InvalidSubExpression(this.currentLineNumber, expression, originalExpression)); + throw new WixException(WixErrors.InvalidSubExpression(this.Context.CurrentSourceLineNumber, expression, originalExpression)); } } @@ -1481,9 +1336,9 @@ namespace WixToolset.Core { int newLine = lineInfoReader.LineNumber + offset; - if (this.currentLineNumber.LineNumber != newLine) + if (this.Context.CurrentSourceLineNumber.LineNumber != newLine) { - this.currentLineNumber = new SourceLineNumber(this.currentLineNumber.FileName, newLine); + this.Context.CurrentSourceLineNumber = new SourceLineNumber(this.Context.CurrentSourceLineNumber.FileName, newLine); } } } @@ -1494,15 +1349,15 @@ namespace WixToolset.Core /// Name to push on to the stack of included files. private void PushInclude(string fileName) { - if (1023 < this.currentFileStack.Count) + if (1023 < this.CurrentFileStack.Count) { - throw new WixException(WixErrors.TooDeeplyIncluded(this.currentLineNumber, this.currentFileStack.Count)); + throw new WixException(WixErrors.TooDeeplyIncluded(this.Context.CurrentSourceLineNumber, this.CurrentFileStack.Count)); } - this.currentFileStack.Push(fileName); - this.sourceStack.Push(this.currentLineNumber); - this.currentLineNumber = new SourceLineNumber(fileName); - this.includeNextStack.Push(true); + this.CurrentFileStack.Push(fileName); + this.SourceStack.Push(this.Context.CurrentSourceLineNumber); + this.Context.CurrentSourceLineNumber = new SourceLineNumber(fileName); + this.IncludeNextStack.Push(true); } /// @@ -1510,10 +1365,10 @@ namespace WixToolset.Core /// private void PopInclude() { - this.currentLineNumber = this.sourceStack.Pop(); + this.Context.CurrentSourceLineNumber = this.SourceStack.Pop(); - this.currentFileStack.Pop(); - this.includeNextStack.Pop(); + this.CurrentFileStack.Pop(); + this.IncludeNextStack.Pop(); } /// @@ -1548,8 +1403,8 @@ namespace WixToolset.Core else // relative path { // build a string to test the directory containing the source file first - string currentFolder = this.currentFileStack.Peek(); - string includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder) ?? String.Empty, includePath); + var currentFolder = this.CurrentFileStack.Peek(); + var includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder) , includePath); // test the source file directory if (File.Exists(includeTestPath)) @@ -1558,7 +1413,7 @@ namespace WixToolset.Core } else // test all search paths in the order specified on the command line { - foreach (string includeSearchPath in this.IncludeSearchPaths) + foreach (var includeSearchPath in this.Context.IncludeSearchPaths) { // if the path exists, we have found the final string includeTestPath = Path.Combine(includeSearchPath, includePath); -- cgit v1.2.3-55-g6feb