diff options
| author | Rob Mensching <rob@firegiant.com> | 2017-12-02 00:46:11 -0800 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2017-12-02 00:46:11 -0800 |
| commit | 95f2f4425b900374c7d7b583ae810b096121b3c4 (patch) | |
| tree | 0ede0972e849bdc2c57e9535e31fbdd0df113f8d /src/WixToolset.Core/Preprocessor.cs | |
| parent | 720c4a0db1a2fb2aa3e08e5c99d5198873e448ba (diff) | |
| download | wix-95f2f4425b900374c7d7b583ae810b096121b3c4.tar.gz wix-95f2f4425b900374c7d7b583ae810b096121b3c4.tar.bz2 wix-95f2f4425b900374c7d7b583ae810b096121b3c4.zip | |
Implement support for IExtensionCommandLine and IPreprocessorExtension
Diffstat (limited to 'src/WixToolset.Core/Preprocessor.cs')
| -rw-r--r-- | src/WixToolset.Core/Preprocessor.cs | 453 |
1 files changed, 154 insertions, 299 deletions
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 | |||
| 4 | { | 4 | { |
| 5 | using System; | 5 | using System; |
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using System.Diagnostics.CodeAnalysis; | ||
| 8 | using System.Globalization; | 7 | using System.Globalization; |
| 9 | using System.IO; | 8 | using System.IO; |
| 10 | using System.Text; | 9 | using System.Text; |
| @@ -14,6 +13,7 @@ namespace WixToolset.Core | |||
| 14 | using WixToolset.Data; | 13 | using WixToolset.Data; |
| 15 | using WixToolset.Extensibility; | 14 | using WixToolset.Extensibility; |
| 16 | using WixToolset.Core.Preprocess; | 15 | using WixToolset.Core.Preprocess; |
| 16 | using WixToolset.Extensibility.Services; | ||
| 17 | 17 | ||
| 18 | /// <summary> | 18 | /// <summary> |
| 19 | /// Preprocessor object | 19 | /// Preprocessor object |
| @@ -30,42 +30,22 @@ namespace WixToolset.Core | |||
| 30 | }; | 30 | }; |
| 31 | private readonly XmlReaderSettings FragmentXmlReaderSettings = new XmlReaderSettings() | 31 | private readonly XmlReaderSettings FragmentXmlReaderSettings = new XmlReaderSettings() |
| 32 | { | 32 | { |
| 33 | ConformanceLevel = System.Xml.ConformanceLevel.Fragment, | 33 | ConformanceLevel = ConformanceLevel.Fragment, |
| 34 | ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None, | 34 | ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None, |
| 35 | XmlResolver = null, | 35 | XmlResolver = null, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | private List<IPreprocessorExtension> extensions; | 38 | private IPreprocessContext Context { get; set; } |
| 39 | private Dictionary<string, IPreprocessorExtension> extensionsByPrefix; | ||
| 40 | 39 | ||
| 41 | private SourceLineNumber currentLineNumber; | 40 | private Stack<string> CurrentFileStack { get; } = new Stack<string>(); |
| 42 | private Stack<SourceLineNumber> sourceStack; | ||
| 43 | 41 | ||
| 44 | private PreprocessorCore core; | 42 | private Dictionary<string, IPreprocessorExtension> ExtensionsByPrefix { get; } = new Dictionary<string, IPreprocessorExtension>(); |
| 45 | private TextWriter preprocessOut; | ||
| 46 | 43 | ||
| 47 | private Stack<bool> includeNextStack; | 44 | private Stack<bool> IncludeNextStack { get; } = new Stack<bool>(); |
| 48 | private Stack<string> currentFileStack; | ||
| 49 | 45 | ||
| 50 | private Platform currentPlatform; | 46 | private Stack<SourceLineNumber> SourceStack { get; } = new Stack<SourceLineNumber>(); |
| 51 | 47 | ||
| 52 | /// <summary> | 48 | private IPreprocessHelper Helper { get; set; } |
| 53 | /// Creates a new preprocesor. | ||
| 54 | /// </summary> | ||
| 55 | public Preprocessor() | ||
| 56 | { | ||
| 57 | this.IncludeSearchPaths = new List<string>(); | ||
| 58 | |||
| 59 | this.extensions = new List<IPreprocessorExtension>(); | ||
| 60 | this.extensionsByPrefix = new Dictionary<string, IPreprocessorExtension>(); | ||
| 61 | |||
| 62 | this.sourceStack = new Stack<SourceLineNumber>(); | ||
| 63 | |||
| 64 | this.includeNextStack = new Stack<bool>(); | ||
| 65 | this.currentFileStack = new Stack<string>(); | ||
| 66 | |||
| 67 | this.currentPlatform = Platform.X86; | ||
| 68 | } | ||
| 69 | 49 | ||
| 70 | /// <summary> | 50 | /// <summary> |
| 71 | /// Event for ifdef/ifndef directives. | 51 | /// Event for ifdef/ifndef directives. |
| @@ -88,62 +68,6 @@ namespace WixToolset.Core | |||
| 88 | public event ResolvedVariableEventHandler ResolvedVariable; | 68 | public event ResolvedVariableEventHandler ResolvedVariable; |
| 89 | 69 | ||
| 90 | /// <summary> | 70 | /// <summary> |
| 91 | /// Enumeration for preprocessor operations in if statements. | ||
| 92 | /// </summary> | ||
| 93 | private enum PreprocessorOperation | ||
| 94 | { | ||
| 95 | /// <summary>The and operator.</summary> | ||
| 96 | And, | ||
| 97 | |||
| 98 | /// <summary>The or operator.</summary> | ||
| 99 | Or, | ||
| 100 | |||
| 101 | /// <summary>The not operator.</summary> | ||
| 102 | Not | ||
| 103 | } | ||
| 104 | |||
| 105 | /// <summary> | ||
| 106 | /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. | ||
| 107 | /// </summary> | ||
| 108 | /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value> | ||
| 109 | public Platform CurrentPlatform | ||
| 110 | { | ||
| 111 | get { return this.currentPlatform; } | ||
| 112 | set { this.currentPlatform = value; } | ||
| 113 | } | ||
| 114 | |||
| 115 | /// <summary> | ||
| 116 | /// Ordered list of search paths that the precompiler uses to find included files. | ||
| 117 | /// </summary> | ||
| 118 | /// <value>List of ordered search paths to use during precompiling.</value> | ||
| 119 | public IList<string> IncludeSearchPaths { get; private set; } | ||
| 120 | |||
| 121 | /// <summary> | ||
| 122 | /// Specifies the text stream to display the postprocessed data to. | ||
| 123 | /// </summary> | ||
| 124 | /// <value>TextWriter to write preprocessed xml to.</value> | ||
| 125 | public TextWriter PreprocessOut | ||
| 126 | { | ||
| 127 | get { return this.preprocessOut; } | ||
| 128 | set { this.preprocessOut = value; } | ||
| 129 | } | ||
| 130 | |||
| 131 | /// <summary> | ||
| 132 | /// Get the source line information for the current element. The precompiler will insert | ||
| 133 | /// special source line number processing instructions before each element that it | ||
| 134 | /// encounters. This is where those line numbers are read and processed. This function | ||
| 135 | /// may return an array of source line numbers because the element may have come from | ||
| 136 | /// an included file, in which case the chain of imports is expressed in the array. | ||
| 137 | /// </summary> | ||
| 138 | /// <param name="node">Element to get source line information for.</param> | ||
| 139 | /// <returns>Returns the stack of imports used to author the element being processed.</returns> | ||
| 140 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | ||
| 141 | public static SourceLineNumber GetSourceLineNumbers(XmlNode node) | ||
| 142 | { | ||
| 143 | return null; | ||
| 144 | } | ||
| 145 | |||
| 146 | /// <summary> | ||
| 147 | /// Get the source line information for the current element. The precompiler will insert | 71 | /// Get the source line information for the current element. The precompiler will insert |
| 148 | /// special source line number information for each element that it encounters. | 72 | /// special source line number information for each element that it encounters. |
| 149 | /// </summary> | 73 | /// </summary> |
| @@ -159,122 +83,94 @@ namespace WixToolset.Core | |||
| 159 | } | 83 | } |
| 160 | 84 | ||
| 161 | /// <summary> | 85 | /// <summary> |
| 162 | /// Adds an extension. | 86 | /// Preprocesses a file. |
| 163 | /// </summary> | 87 | /// </summary> |
| 164 | /// <param name="extension">The extension to add.</param> | 88 | /// <param name="context">The preprocessing context.</param> |
| 165 | public void AddExtension(IPreprocessorExtension extension) | 89 | /// <returns>XDocument with the postprocessed data.</returns> |
| 90 | public XDocument Process(IPreprocessContext context) | ||
| 166 | { | 91 | { |
| 167 | this.extensions.Add(extension); | 92 | this.Context = context ?? throw new ArgumentNullException(nameof(context)); |
| 168 | 93 | ||
| 169 | if (null != extension.Prefixes) | 94 | using (XmlReader reader = XmlReader.Create(context.SourceFile, DocumentXmlReaderSettings)) |
| 170 | { | 95 | { |
| 171 | foreach (string prefix in extension.Prefixes) | 96 | return Process(context, reader); |
| 172 | { | ||
| 173 | IPreprocessorExtension collidingExtension; | ||
| 174 | if (!this.extensionsByPrefix.TryGetValue(prefix, out collidingExtension)) | ||
| 175 | { | ||
| 176 | this.extensionsByPrefix.Add(prefix, extension); | ||
| 177 | } | ||
| 178 | else | ||
| 179 | { | ||
| 180 | Messaging.Instance.OnMessage(WixErrors.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString())); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | } | 97 | } |
| 184 | |||
| 185 | //if (null != extension.InspectorExtension) | ||
| 186 | //{ | ||
| 187 | // this.inspectorExtensions.Add(extension.InspectorExtension); | ||
| 188 | //} | ||
| 189 | } | 98 | } |
| 190 | 99 | ||
| 191 | /// <summary> | 100 | /// <summary> |
| 192 | /// Preprocesses a file. | 101 | /// Preprocesses a file. |
| 193 | /// </summary> | 102 | /// </summary> |
| 194 | /// <param name="sourceFile">The file to preprocess.</param> | 103 | /// <param name="context">The preprocessing context.</param> |
| 195 | /// <param name="variables">The variables defined prior to preprocessing.</param> | 104 | /// <param name="reader">XmlReader to processing the context.</param> |
| 196 | /// <returns>XDocument with the postprocessed data.</returns> | 105 | /// <returns>XDocument with the postprocessed data.</returns> |
| 197 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | 106 | public XDocument Process(IPreprocessContext context, XmlReader reader) |
| 198 | public XDocument Process(string sourceFile, IDictionary<string, string> variables) | ||
| 199 | { | 107 | { |
| 200 | using (Stream sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) | 108 | if (this.Context == null) |
| 201 | using (XmlReader reader = XmlReader.Create(sourceFile, DocumentXmlReaderSettings)) | ||
| 202 | { | 109 | { |
| 203 | return Process(reader, variables, sourceFile); | 110 | this.Context = context ?? throw new ArgumentNullException(nameof(context)); |
| 111 | } | ||
| 112 | else if (this.Context != context) | ||
| 113 | { | ||
| 114 | throw new ArgumentException(nameof(context)); | ||
| 204 | } | 115 | } |
| 205 | } | ||
| 206 | 116 | ||
| 207 | /// <summary> | 117 | if (String.IsNullOrEmpty(this.Context.SourceFile) && !String.IsNullOrEmpty(reader.BaseURI)) |
| 208 | /// Preprocesses a file. | ||
| 209 | /// </summary> | ||
| 210 | /// <param name="sourceFile">The file to preprocess.</param> | ||
| 211 | /// <param name="variables">The variables defined prior to preprocessing.</param> | ||
| 212 | /// <returns>XDocument with the postprocessed data.</returns> | ||
| 213 | [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")] | ||
| 214 | public XDocument Process(XmlReader reader, IDictionary<string, string> variables, string sourceFile = null) | ||
| 215 | { | ||
| 216 | if (String.IsNullOrEmpty(sourceFile) && !String.IsNullOrEmpty(reader.BaseURI)) | ||
| 217 | { | 118 | { |
| 218 | Uri uri = new Uri(reader.BaseURI); | 119 | var uri = new Uri(reader.BaseURI); |
| 219 | sourceFile = uri.AbsolutePath; | 120 | this.Context.SourceFile = uri.AbsolutePath; |
| 220 | } | 121 | } |
| 221 | 122 | ||
| 222 | this.core = new PreprocessorCore(this.extensionsByPrefix, sourceFile, variables); | 123 | this.Context.CurrentSourceLineNumber = new SourceLineNumber(this.Context.SourceFile); |
| 223 | this.core.ResolvedVariableHandler = this.ResolvedVariable; | ||
| 224 | this.core.CurrentPlatform = this.currentPlatform; | ||
| 225 | this.currentLineNumber = new SourceLineNumber(sourceFile); | ||
| 226 | this.currentFileStack.Clear(); | ||
| 227 | this.currentFileStack.Push(this.core.GetVariableValue(this.currentLineNumber, "sys", "SOURCEFILEDIR")); | ||
| 228 | 124 | ||
| 229 | // Process the reader into the output. | 125 | this.Helper = this.Context.ServiceProvider.GetService<IPreprocessHelper>(); |
| 230 | XDocument output = new XDocument(); | 126 | |
| 231 | try | 127 | foreach (var extension in this.Context.Extensions) |
| 232 | { | 128 | { |
| 233 | foreach (PreprocessorExtension extension in this.extensions) | 129 | if (null != extension.Prefixes) |
| 234 | { | 130 | { |
| 235 | extension.Core = this.core; | 131 | foreach (string prefix in extension.Prefixes) |
| 236 | extension.Initialize(); | 132 | { |
| 133 | if (!this.ExtensionsByPrefix.TryGetValue(prefix, out var collidingExtension)) | ||
| 134 | { | ||
| 135 | this.ExtensionsByPrefix.Add(prefix, extension); | ||
| 136 | } | ||
| 137 | else | ||
| 138 | { | ||
| 139 | this.Context.Messaging.OnMessage(WixErrors.DuplicateExtensionPreprocessorType(extension.GetType().ToString(), prefix, collidingExtension.GetType().ToString())); | ||
| 140 | } | ||
| 141 | } | ||
| 237 | } | 142 | } |
| 238 | 143 | ||
| 239 | this.PreprocessReader(false, reader, output, 0); | 144 | extension.PrePreprocess(context); |
| 240 | } | ||
| 241 | catch (XmlException e) | ||
| 242 | { | ||
| 243 | this.UpdateCurrentLineNumber(reader, 0); | ||
| 244 | throw new WixException(WixErrors.InvalidXml(this.currentLineNumber, "source", e.Message)); | ||
| 245 | } | 145 | } |
| 246 | 146 | ||
| 247 | // Fire event with post-processed document. | 147 | this.CurrentFileStack.Clear(); |
| 248 | ProcessedStreamEventArgs args = new ProcessedStreamEventArgs(sourceFile, output); | 148 | this.CurrentFileStack.Push(this.Helper.GetVariableValue(this.Context, "sys", "SOURCEFILEDIR")); |
| 249 | this.OnProcessedStream(args); | ||
| 250 | 149 | ||
| 251 | // preprocess the generated XML Document | 150 | // Process the reader into the output. |
| 252 | foreach (PreprocessorExtension extension in this.extensions) | 151 | XDocument output = new XDocument(); |
| 152 | try | ||
| 253 | { | 153 | { |
| 254 | extension.PreprocessDocument(output); | 154 | this.PreprocessReader(false, reader, output, 0); |
| 255 | } | ||
| 256 | 155 | ||
| 257 | // finalize the preprocessing | 156 | // Fire event with post-processed document. |
| 258 | foreach (PreprocessorExtension extension in this.extensions) | 157 | this.ProcessedStream?.Invoke(this, new ProcessedStreamEventArgs(this.Context.SourceFile, output)); |
| 259 | { | ||
| 260 | extension.Finish(); | ||
| 261 | extension.Core = null; | ||
| 262 | } | 158 | } |
| 263 | 159 | catch (XmlException e) | |
| 264 | if (this.core.EncounteredError) | ||
| 265 | { | 160 | { |
| 266 | return null; | 161 | this.UpdateCurrentLineNumber(reader, 0); |
| 162 | throw new WixException(WixErrors.InvalidXml(this.Context.CurrentSourceLineNumber, "source", e.Message)); | ||
| 267 | } | 163 | } |
| 268 | else | 164 | finally |
| 269 | { | 165 | { |
| 270 | if (null != this.preprocessOut) | 166 | // Finalize the preprocessing. |
| 167 | foreach (var extension in this.Context.Extensions) | ||
| 271 | { | 168 | { |
| 272 | output.Save(this.preprocessOut); | 169 | extension.PostPreprocess(output); |
| 273 | this.preprocessOut.Flush(); | ||
| 274 | } | 170 | } |
| 275 | |||
| 276 | return output; | ||
| 277 | } | 171 | } |
| 172 | |||
| 173 | return this.Context.Messaging.EncounteredError ? null : output; | ||
| 278 | } | 174 | } |
| 279 | 175 | ||
| 280 | /// <summary> | 176 | /// <summary> |
| @@ -340,42 +236,6 @@ namespace WixToolset.Core | |||
| 340 | } | 236 | } |
| 341 | 237 | ||
| 342 | /// <summary> | 238 | /// <summary> |
| 343 | /// Fires an event when an ifdef/ifndef directive is processed. | ||
| 344 | /// </summary> | ||
| 345 | /// <param name="ea">ifdef/ifndef event arguments.</param> | ||
| 346 | private void OnIfDef(IfDefEventArgs ea) | ||
| 347 | { | ||
| 348 | if (null != this.IfDef) | ||
| 349 | { | ||
| 350 | this.IfDef(this, ea); | ||
| 351 | } | ||
| 352 | } | ||
| 353 | |||
| 354 | /// <summary> | ||
| 355 | /// Fires an event when an included file is processed. | ||
| 356 | /// </summary> | ||
| 357 | /// <param name="ea">Included file event arguments.</param> | ||
| 358 | private void OnIncludedFile(IncludedFileEventArgs ea) | ||
| 359 | { | ||
| 360 | if (null != this.IncludedFile) | ||
| 361 | { | ||
| 362 | this.IncludedFile(this, ea); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | |||
| 366 | /// <summary> | ||
| 367 | /// Fires an event after the file is preprocessed. | ||
| 368 | /// </summary> | ||
| 369 | /// <param name="ea">Included file event arguments.</param> | ||
| 370 | private void OnProcessedStream(ProcessedStreamEventArgs ea) | ||
| 371 | { | ||
| 372 | if (null != this.ProcessedStream) | ||
| 373 | { | ||
| 374 | this.ProcessedStream(this, ea); | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | /// <summary> | ||
| 379 | /// Tests expression to see if it starts with a keyword. | 239 | /// Tests expression to see if it starts with a keyword. |
| 380 | /// </summary> | 240 | /// </summary> |
| 381 | /// <param name="expression">Expression to test.</param> | 241 | /// <param name="expression">Expression to test.</param> |
| @@ -383,7 +243,7 @@ namespace WixToolset.Core | |||
| 383 | /// <returns>true if expression starts with a keyword.</returns> | 243 | /// <returns>true if expression starts with a keyword.</returns> |
| 384 | private static bool StartsWithKeyword(string expression, PreprocessorOperation operation) | 244 | private static bool StartsWithKeyword(string expression, PreprocessorOperation operation) |
| 385 | { | 245 | { |
| 386 | expression = expression.ToUpper(CultureInfo.InvariantCulture); | 246 | expression = expression.ToUpperInvariant(); |
| 387 | switch (operation) | 247 | switch (operation) |
| 388 | { | 248 | { |
| 389 | case PreprocessorOperation.Not: | 249 | case PreprocessorOperation.Not: |
| @@ -431,7 +291,7 @@ namespace WixToolset.Core | |||
| 431 | // update information here in case an error occurs before the next read | 291 | // update information here in case an error occurs before the next read |
| 432 | this.UpdateCurrentLineNumber(reader, offset); | 292 | this.UpdateCurrentLineNumber(reader, offset); |
| 433 | 293 | ||
| 434 | SourceLineNumber sourceLineNumbers = this.currentLineNumber; | 294 | var sourceLineNumbers = this.Context.CurrentSourceLineNumber; |
| 435 | 295 | ||
| 436 | // check for changes in conditional processing | 296 | // check for changes in conditional processing |
| 437 | if (XmlNodeType.ProcessingInstruction == reader.NodeType) | 297 | if (XmlNodeType.ProcessingInstruction == reader.NodeType) |
| @@ -459,14 +319,14 @@ namespace WixToolset.Core | |||
| 459 | name = reader.Value.Trim(); | 319 | name = reader.Value.Trim(); |
| 460 | if (ifContext.IsTrue) | 320 | if (ifContext.IsTrue) |
| 461 | { | 321 | { |
| 462 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null != this.core.GetVariableValue(sourceLineNumbers, name, true)), IfState.If); | 322 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null != this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); |
| 463 | } | 323 | } |
| 464 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true | 324 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true |
| 465 | { | 325 | { |
| 466 | ifContext = new IfContext(); | 326 | ifContext = new IfContext(); |
| 467 | } | 327 | } |
| 468 | ignore = true; | 328 | ignore = true; |
| 469 | OnIfDef(new IfDefEventArgs(sourceLineNumbers, true, ifContext.IsTrue, name)); | 329 | this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, true, ifContext.IsTrue, name)); |
| 470 | break; | 330 | break; |
| 471 | 331 | ||
| 472 | case "ifndef": | 332 | case "ifndef": |
| @@ -474,25 +334,25 @@ namespace WixToolset.Core | |||
| 474 | name = reader.Value.Trim(); | 334 | name = reader.Value.Trim(); |
| 475 | if (ifContext.IsTrue) | 335 | if (ifContext.IsTrue) |
| 476 | { | 336 | { |
| 477 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null == this.core.GetVariableValue(sourceLineNumbers, name, true)), IfState.If); | 337 | ifContext = new IfContext(ifContext.IsTrue & ifContext.Active, (null == this.Helper.GetVariableValue(this.Context, name, true)), IfState.If); |
| 478 | } | 338 | } |
| 479 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true | 339 | else // Use a default IfContext object so we don't try to evaluate the expression if the context isn't true |
| 480 | { | 340 | { |
| 481 | ifContext = new IfContext(); | 341 | ifContext = new IfContext(); |
| 482 | } | 342 | } |
| 483 | ignore = true; | 343 | ignore = true; |
| 484 | OnIfDef(new IfDefEventArgs(sourceLineNumbers, false, !ifContext.IsTrue, name)); | 344 | this.IfDef?.Invoke(this, new IfDefEventArgs(sourceLineNumbers, false, !ifContext.IsTrue, name)); |
| 485 | break; | 345 | break; |
| 486 | 346 | ||
| 487 | case "elseif": | 347 | case "elseif": |
| 488 | if (0 == ifStack.Count) | 348 | if (0 == ifStack.Count) |
| 489 | { | 349 | { |
| 490 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "elseif")); | 350 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); |
| 491 | } | 351 | } |
| 492 | 352 | ||
| 493 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) | 353 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) |
| 494 | { | 354 | { |
| 495 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "elseif")); | 355 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "elseif")); |
| 496 | } | 356 | } |
| 497 | 357 | ||
| 498 | ifContext.IfState = IfState.ElseIf; // we're now in an elseif | 358 | ifContext.IfState = IfState.ElseIf; // we're now in an elseif |
| @@ -510,12 +370,12 @@ namespace WixToolset.Core | |||
| 510 | case "else": | 370 | case "else": |
| 511 | if (0 == ifStack.Count) | 371 | if (0 == ifStack.Count) |
| 512 | { | 372 | { |
| 513 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "else")); | 373 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); |
| 514 | } | 374 | } |
| 515 | 375 | ||
| 516 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) | 376 | if (IfState.If != ifContext.IfState && IfState.ElseIf != ifContext.IfState) |
| 517 | { | 377 | { |
| 518 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "else")); | 378 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "else")); |
| 519 | } | 379 | } |
| 520 | 380 | ||
| 521 | ifContext.IfState = IfState.Else; // we're now in an else | 381 | ifContext.IfState = IfState.Else; // we're now in an else |
| @@ -526,7 +386,7 @@ namespace WixToolset.Core | |||
| 526 | case "endif": | 386 | case "endif": |
| 527 | if (0 == ifStack.Count) | 387 | if (0 == ifStack.Count) |
| 528 | { | 388 | { |
| 529 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "if", "endif")); | 389 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "if", "endif")); |
| 530 | } | 390 | } |
| 531 | 391 | ||
| 532 | ifContext = (IfContext)ifStack.Pop(); | 392 | ifContext = (IfContext)ifStack.Pop(); |
| @@ -606,7 +466,7 @@ namespace WixToolset.Core | |||
| 606 | break; | 466 | break; |
| 607 | 467 | ||
| 608 | case "endforeach": // endforeach is handled in PreprocessForeach, so seeing it here is an error | 468 | case "endforeach": // endforeach is handled in PreprocessForeach, so seeing it here is an error |
| 609 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(this.currentLineNumber, "foreach", "endforeach")); | 469 | throw new WixException(WixErrors.UnmatchedPreprocessorInstruction(sourceLineNumbers, "foreach", "endforeach")); |
| 610 | 470 | ||
| 611 | case "pragma": | 471 | case "pragma": |
| 612 | this.PreprocessPragma(reader.Value, currentContainer); | 472 | this.PreprocessPragma(reader.Value, currentContainer); |
| @@ -619,31 +479,33 @@ namespace WixToolset.Core | |||
| 619 | break; | 479 | break; |
| 620 | 480 | ||
| 621 | case XmlNodeType.Element: | 481 | case XmlNodeType.Element: |
| 622 | if (0 < this.includeNextStack.Count && this.includeNextStack.Peek()) | 482 | if (0 < this.IncludeNextStack.Count && this.IncludeNextStack.Peek()) |
| 623 | { | 483 | { |
| 624 | if ("Include" != reader.LocalName) | 484 | if ("Include" != reader.LocalName) |
| 625 | { | 485 | { |
| 626 | this.core.OnMessage(WixErrors.InvalidDocumentElement(this.currentLineNumber, reader.Name, "include", "Include")); | 486 | this.Context.Messaging.OnMessage(WixErrors.InvalidDocumentElement(sourceLineNumbers, reader.Name, "include", "Include")); |
| 627 | } | 487 | } |
| 628 | 488 | ||
| 629 | this.includeNextStack.Pop(); | 489 | this.IncludeNextStack.Pop(); |
| 630 | this.includeNextStack.Push(false); | 490 | this.IncludeNextStack.Push(false); |
| 631 | break; | 491 | break; |
| 632 | } | 492 | } |
| 633 | 493 | ||
| 634 | bool empty = reader.IsEmptyElement; | 494 | var empty = reader.IsEmptyElement; |
| 635 | XNamespace ns = XNamespace.Get(reader.NamespaceURI); | 495 | var ns = XNamespace.Get(reader.NamespaceURI); |
| 636 | XElement element = new XElement(ns + reader.LocalName); | 496 | var element = new XElement(ns + reader.LocalName); |
| 637 | currentContainer.Add(element); | 497 | currentContainer.Add(element); |
| 638 | 498 | ||
| 639 | this.UpdateCurrentLineNumber(reader, offset); | 499 | this.UpdateCurrentLineNumber(reader, offset); |
| 640 | element.AddAnnotation(this.currentLineNumber); | 500 | element.AddAnnotation(sourceLineNumbers); |
| 641 | 501 | ||
| 642 | while (reader.MoveToNextAttribute()) | 502 | while (reader.MoveToNextAttribute()) |
| 643 | { | 503 | { |
| 644 | string value = this.core.PreprocessString(this.currentLineNumber, reader.Value); | 504 | var value = this.Helper.PreprocessString(this.Context, reader.Value); |
| 645 | XNamespace attribNamespace = XNamespace.Get(reader.NamespaceURI); | 505 | |
| 506 | var attribNamespace = XNamespace.Get(reader.NamespaceURI); | ||
| 646 | attribNamespace = XNamespace.Xmlns == attribNamespace && reader.LocalName.Equals("xmlns") ? XNamespace.None : attribNamespace; | 507 | attribNamespace = XNamespace.Xmlns == attribNamespace && reader.LocalName.Equals("xmlns") ? XNamespace.None : attribNamespace; |
| 508 | |||
| 647 | element.Add(new XAttribute(attribNamespace + reader.LocalName, value)); | 509 | element.Add(new XAttribute(attribNamespace + reader.LocalName, value)); |
| 648 | } | 510 | } |
| 649 | 511 | ||
| @@ -662,12 +524,12 @@ namespace WixToolset.Core | |||
| 662 | break; | 524 | break; |
| 663 | 525 | ||
| 664 | case XmlNodeType.Text: | 526 | case XmlNodeType.Text: |
| 665 | string postprocessedText = this.core.PreprocessString(this.currentLineNumber, reader.Value); | 527 | string postprocessedText = this.Helper.PreprocessString(this.Context, reader.Value); |
| 666 | currentContainer.Add(postprocessedText); | 528 | currentContainer.Add(postprocessedText); |
| 667 | break; | 529 | break; |
| 668 | 530 | ||
| 669 | case XmlNodeType.CDATA: | 531 | case XmlNodeType.CDATA: |
| 670 | string postprocessedValue = this.core.PreprocessString(this.currentLineNumber, reader.Value); | 532 | string postprocessedValue = this.Helper.PreprocessString(this.Context, reader.Value); |
| 671 | currentContainer.Add(new XCData(postprocessedValue)); | 533 | currentContainer.Add(new XCData(postprocessedValue)); |
| 672 | break; | 534 | break; |
| 673 | 535 | ||
| @@ -678,13 +540,13 @@ namespace WixToolset.Core | |||
| 678 | 540 | ||
| 679 | if (0 != ifStack.Count) | 541 | if (0 != ifStack.Count) |
| 680 | { | 542 | { |
| 681 | throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.currentLineNumber, "if", "endif")); | 543 | throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.Context.CurrentSourceLineNumber, "if", "endif")); |
| 682 | } | 544 | } |
| 683 | 545 | ||
| 684 | // TODO: can this actually happen? | 546 | // TODO: can this actually happen? |
| 685 | if (0 != containerStack.Count) | 547 | if (0 != containerStack.Count) |
| 686 | { | 548 | { |
| 687 | throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.currentLineNumber, "nodes", "nodes")); | 549 | throw new WixException(WixErrors.NonterminatedPreprocessorInstruction(this.Context.CurrentSourceLineNumber, "nodes", "nodes")); |
| 688 | } | 550 | } |
| 689 | } | 551 | } |
| 690 | 552 | ||
| @@ -694,12 +556,10 @@ namespace WixToolset.Core | |||
| 694 | /// <param name="errorMessage">Text from source.</param> | 556 | /// <param name="errorMessage">Text from source.</param> |
| 695 | private void PreprocessError(string errorMessage) | 557 | private void PreprocessError(string errorMessage) |
| 696 | { | 558 | { |
| 697 | SourceLineNumber sourceLineNumbers = this.currentLineNumber; | 559 | // Resolve other variables in the error message. |
| 698 | 560 | errorMessage = this.Helper.PreprocessString(this.Context, errorMessage); | |
| 699 | // resolve other variables in the error message | ||
| 700 | errorMessage = this.core.PreprocessString(sourceLineNumbers, errorMessage); | ||
| 701 | 561 | ||
| 702 | throw new WixException(WixErrors.PreprocessorError(sourceLineNumbers, errorMessage)); | 562 | throw new WixException(WixErrors.PreprocessorError(this.Context.CurrentSourceLineNumber, errorMessage)); |
| 703 | } | 563 | } |
| 704 | 564 | ||
| 705 | /// <summary> | 565 | /// <summary> |
| @@ -708,12 +568,10 @@ namespace WixToolset.Core | |||
| 708 | /// <param name="warningMessage">Text from source.</param> | 568 | /// <param name="warningMessage">Text from source.</param> |
| 709 | private void PreprocessWarning(string warningMessage) | 569 | private void PreprocessWarning(string warningMessage) |
| 710 | { | 570 | { |
| 711 | SourceLineNumber sourceLineNumbers = this.currentLineNumber; | 571 | // Resolve other variables in the warning message. |
| 712 | 572 | warningMessage = this.Helper.PreprocessString(this.Context, warningMessage); | |
| 713 | // resolve other variables in the warning message | ||
| 714 | warningMessage = this.core.PreprocessString(sourceLineNumbers, warningMessage); | ||
| 715 | 573 | ||
| 716 | this.core.OnMessage(WixWarnings.PreprocessorWarning(sourceLineNumbers, warningMessage)); | 574 | this.Context.Messaging.OnMessage(WixWarnings.PreprocessorWarning(this.Context.CurrentSourceLineNumber, warningMessage)); |
| 717 | } | 575 | } |
| 718 | 576 | ||
| 719 | /// <summary> | 577 | /// <summary> |
| @@ -722,16 +580,15 @@ namespace WixToolset.Core | |||
| 722 | /// <param name="originalDefine">Text from source.</param> | 580 | /// <param name="originalDefine">Text from source.</param> |
| 723 | private void PreprocessDefine(string originalDefine) | 581 | private void PreprocessDefine(string originalDefine) |
| 724 | { | 582 | { |
| 725 | Match match = defineRegex.Match(originalDefine); | 583 | var match = defineRegex.Match(originalDefine); |
| 726 | SourceLineNumber sourceLineNumbers = this.currentLineNumber; | ||
| 727 | 584 | ||
| 728 | if (!match.Success) | 585 | if (!match.Success) |
| 729 | { | 586 | { |
| 730 | throw new WixException(WixErrors.IllegalDefineStatement(sourceLineNumbers, originalDefine)); | 587 | throw new WixException(WixErrors.IllegalDefineStatement(this.Context.CurrentSourceLineNumber, originalDefine)); |
| 731 | } | 588 | } |
| 732 | 589 | ||
| 733 | string defineName = match.Groups["varName"].Value; | 590 | var defineName = match.Groups["varName"].Value; |
| 734 | string defineValue = match.Groups["varValue"].Value; | 591 | var defineValue = match.Groups["varValue"].Value; |
| 735 | 592 | ||
| 736 | // strip off the optional quotes | 593 | // strip off the optional quotes |
| 737 | if (1 < defineValue.Length && | 594 | if (1 < defineValue.Length && |
| @@ -742,15 +599,15 @@ namespace WixToolset.Core | |||
| 742 | } | 599 | } |
| 743 | 600 | ||
| 744 | // resolve other variables in the variable value | 601 | // resolve other variables in the variable value |
| 745 | defineValue = this.core.PreprocessString(sourceLineNumbers, defineValue); | 602 | defineValue = this.Helper.PreprocessString(this.Context, defineValue); |
| 746 | 603 | ||
| 747 | if (defineName.StartsWith("var.", StringComparison.Ordinal)) | 604 | if (defineName.StartsWith("var.", StringComparison.Ordinal)) |
| 748 | { | 605 | { |
| 749 | this.core.AddVariable(sourceLineNumbers, defineName.Substring(4), defineValue); | 606 | this.Helper.AddVariable(this.Context, defineName.Substring(4), defineValue); |
| 750 | } | 607 | } |
| 751 | else | 608 | else |
| 752 | { | 609 | { |
| 753 | this.core.AddVariable(sourceLineNumbers, defineName, defineValue); | 610 | this.Helper.AddVariable(this.Context, defineName, defineValue); |
| 754 | } | 611 | } |
| 755 | } | 612 | } |
| 756 | 613 | ||
| @@ -760,16 +617,15 @@ namespace WixToolset.Core | |||
| 760 | /// <param name="originalDefine">Text from source.</param> | 617 | /// <param name="originalDefine">Text from source.</param> |
| 761 | private void PreprocessUndef(string originalDefine) | 618 | private void PreprocessUndef(string originalDefine) |
| 762 | { | 619 | { |
| 763 | SourceLineNumber sourceLineNumbers = this.currentLineNumber; | 620 | var name = this.Helper.PreprocessString(this.Context, originalDefine.Trim()); |
| 764 | string name = this.core.PreprocessString(sourceLineNumbers, originalDefine.Trim()); | ||
| 765 | 621 | ||
| 766 | if (name.StartsWith("var.", StringComparison.Ordinal)) | 622 | if (name.StartsWith("var.", StringComparison.Ordinal)) |
| 767 | { | 623 | { |
| 768 | this.core.RemoveVariable(sourceLineNumbers, name.Substring(4)); | 624 | this.Helper.RemoveVariable(this.Context, name.Substring(4)); |
| 769 | } | 625 | } |
| 770 | else | 626 | else |
| 771 | { | 627 | { |
| 772 | this.core.RemoveVariable(sourceLineNumbers, name); | 628 | this.Helper.RemoveVariable(this.Context, name); |
| 773 | } | 629 | } |
| 774 | } | 630 | } |
| 775 | 631 | ||
| @@ -780,12 +636,12 @@ namespace WixToolset.Core | |||
| 780 | /// <param name="parent">Parent container for included content.</param> | 636 | /// <param name="parent">Parent container for included content.</param> |
| 781 | private void PreprocessInclude(string includePath, XContainer parent) | 637 | private void PreprocessInclude(string includePath, XContainer parent) |
| 782 | { | 638 | { |
| 783 | SourceLineNumber sourceLineNumbers = this.currentLineNumber; | 639 | var sourceLineNumbers = this.Context.CurrentSourceLineNumber; |
| 784 | 640 | ||
| 785 | // preprocess variables in the path | 641 | // Preprocess variables in the path. |
| 786 | includePath = this.core.PreprocessString(sourceLineNumbers, includePath); | 642 | includePath = this.Helper.PreprocessString(this.Context, includePath); |
| 787 | 643 | ||
| 788 | string includeFile = this.GetIncludeFile(includePath); | 644 | var includeFile = this.GetIncludeFile(includePath); |
| 789 | 645 | ||
| 790 | if (null == includeFile) | 646 | if (null == includeFile) |
| 791 | { | 647 | { |
| @@ -807,7 +663,7 @@ namespace WixToolset.Core | |||
| 807 | throw new WixException(WixErrors.InvalidXml(sourceLineNumbers, "source", e.Message)); | 663 | throw new WixException(WixErrors.InvalidXml(sourceLineNumbers, "source", e.Message)); |
| 808 | } | 664 | } |
| 809 | 665 | ||
| 810 | this.OnIncludedFile(new IncludedFileEventArgs(sourceLineNumbers, includeFile)); | 666 | this.IncludedFile?.Invoke(this, new IncludedFileEventArgs(sourceLineNumbers, includeFile)); |
| 811 | 667 | ||
| 812 | this.PopInclude(); | 668 | this.PopInclude(); |
| 813 | } | 669 | } |
| @@ -821,11 +677,11 @@ namespace WixToolset.Core | |||
| 821 | /// <param name="offset">Offset for the line numbers.</param> | 677 | /// <param name="offset">Offset for the line numbers.</param> |
| 822 | private void PreprocessForeach(XmlReader reader, XContainer container, int offset) | 678 | private void PreprocessForeach(XmlReader reader, XContainer container, int offset) |
| 823 | { | 679 | { |
| 824 | // find the "in" token | 680 | // Find the "in" token. |
| 825 | int indexOfInToken = reader.Value.IndexOf(" in ", StringComparison.Ordinal); | 681 | var indexOfInToken = reader.Value.IndexOf(" in ", StringComparison.Ordinal); |
| 826 | if (0 > indexOfInToken) | 682 | if (0 > indexOfInToken) |
| 827 | { | 683 | { |
| 828 | throw new WixException(WixErrors.IllegalForeach(this.currentLineNumber, reader.Value)); | 684 | throw new WixException(WixErrors.IllegalForeach(this.Context.CurrentSourceLineNumber, reader.Value)); |
| 829 | } | 685 | } |
| 830 | 686 | ||
| 831 | // parse out the variable name | 687 | // parse out the variable name |
| @@ -833,7 +689,7 @@ namespace WixToolset.Core | |||
| 833 | string varValuesString = reader.Value.Substring(indexOfInToken + 4).Trim(); | 689 | string varValuesString = reader.Value.Substring(indexOfInToken + 4).Trim(); |
| 834 | 690 | ||
| 835 | // preprocess the variable values string because it might be a variable itself | 691 | // preprocess the variable values string because it might be a variable itself |
| 836 | varValuesString = this.core.PreprocessString(this.currentLineNumber, varValuesString); | 692 | varValuesString = this.Helper.PreprocessString(this.Context, varValuesString); |
| 837 | 693 | ||
| 838 | string[] varValues = varValuesString.Split(';'); | 694 | string[] varValues = varValuesString.Split(';'); |
| 839 | 695 | ||
| @@ -895,20 +751,20 @@ namespace WixToolset.Core | |||
| 895 | } | 751 | } |
| 896 | else if (reader.NodeType == XmlNodeType.None) | 752 | else if (reader.NodeType == XmlNodeType.None) |
| 897 | { | 753 | { |
| 898 | throw new WixException(WixErrors.ExpectedEndforeach(this.currentLineNumber)); | 754 | throw new WixException(WixErrors.ExpectedEndforeach(this.Context.CurrentSourceLineNumber)); |
| 899 | } | 755 | } |
| 900 | 756 | ||
| 901 | reader.Read(); | 757 | reader.Read(); |
| 902 | } | 758 | } |
| 903 | 759 | ||
| 904 | using (MemoryStream fragmentStream = new MemoryStream(Encoding.UTF8.GetBytes(fragmentBuilder.ToString()))) | 760 | using (var fragmentStream = new MemoryStream(Encoding.UTF8.GetBytes(fragmentBuilder.ToString()))) |
| 905 | using (XmlReader loopReader = XmlReader.Create(fragmentStream, FragmentXmlReaderSettings)) | 761 | using (var loopReader = XmlReader.Create(fragmentStream, FragmentXmlReaderSettings)) |
| 906 | { | 762 | { |
| 907 | // process each iteration, updating the variable's value each time | 763 | // process each iteration, updating the variable's value each time |
| 908 | foreach (string varValue in varValues) | 764 | foreach (string varValue in varValues) |
| 909 | { | 765 | { |
| 910 | // Always overwrite foreach variables. | 766 | // Always overwrite foreach variables. |
| 911 | this.core.AddVariable(this.currentLineNumber, varName, varValue, false); | 767 | this.Helper.AddVariable(this.Context, varName, varValue, false); |
| 912 | 768 | ||
| 913 | try | 769 | try |
| 914 | { | 770 | { |
| @@ -917,7 +773,7 @@ namespace WixToolset.Core | |||
| 917 | catch (XmlException e) | 773 | catch (XmlException e) |
| 918 | { | 774 | { |
| 919 | this.UpdateCurrentLineNumber(loopReader, offset); | 775 | this.UpdateCurrentLineNumber(loopReader, offset); |
| 920 | throw new WixException(WixErrors.InvalidXml(this.currentLineNumber, "source", e.Message)); | 776 | throw new WixException(WixErrors.InvalidXml(this.Context.CurrentSourceLineNumber, "source", e.Message)); |
| 921 | } | 777 | } |
| 922 | 778 | ||
| 923 | fragmentStream.Position = 0; // seek back to the beginning for the next loop. | 779 | fragmentStream.Position = 0; // seek back to the beginning for the next loop. |
| @@ -931,24 +787,23 @@ namespace WixToolset.Core | |||
| 931 | /// <param name="pragmaText">Text from source.</param> | 787 | /// <param name="pragmaText">Text from source.</param> |
| 932 | private void PreprocessPragma(string pragmaText, XContainer parent) | 788 | private void PreprocessPragma(string pragmaText, XContainer parent) |
| 933 | { | 789 | { |
| 934 | Match match = pragmaRegex.Match(pragmaText); | 790 | var match = pragmaRegex.Match(pragmaText); |
| 935 | SourceLineNumber sourceLineNumbers = this.currentLineNumber; | ||
| 936 | 791 | ||
| 937 | if (!match.Success) | 792 | if (!match.Success) |
| 938 | { | 793 | { |
| 939 | throw new WixException(WixErrors.InvalidPreprocessorPragma(sourceLineNumbers, pragmaText)); | 794 | throw new WixException(WixErrors.InvalidPreprocessorPragma(this.Context.CurrentSourceLineNumber, pragmaText)); |
| 940 | } | 795 | } |
| 941 | 796 | ||
| 942 | // resolve other variables in the pragma argument(s) | 797 | // resolve other variables in the pragma argument(s) |
| 943 | string pragmaArgs = this.core.PreprocessString(sourceLineNumbers, match.Groups["pragmaValue"].Value).Trim(); | 798 | string pragmaArgs = this.Helper.PreprocessString(this.Context, match.Groups["pragmaValue"].Value).Trim(); |
| 944 | 799 | ||
| 945 | try | 800 | try |
| 946 | { | 801 | { |
| 947 | this.core.PreprocessPragma(sourceLineNumbers, match.Groups["pragmaName"].Value.Trim(), pragmaArgs, parent); | 802 | this.Helper.PreprocessPragma(this.Context, match.Groups["pragmaName"].Value.Trim(), pragmaArgs, parent); |
| 948 | } | 803 | } |
| 949 | catch (Exception e) | 804 | catch (Exception e) |
| 950 | { | 805 | { |
| 951 | throw new WixException(WixErrors.PreprocessorExtensionPragmaFailed(sourceLineNumbers, pragmaText, e.Message)); | 806 | throw new WixException(WixErrors.PreprocessorExtensionPragmaFailed(this.Context.CurrentSourceLineNumber, pragmaText, e.Message)); |
| 952 | } | 807 | } |
| 953 | } | 808 | } |
| 954 | 809 | ||
| @@ -975,11 +830,11 @@ namespace WixToolset.Core | |||
| 975 | int endingQuotes = expression.IndexOf('\"', 1); | 830 | int endingQuotes = expression.IndexOf('\"', 1); |
| 976 | if (-1 == endingQuotes) | 831 | if (-1 == endingQuotes) |
| 977 | { | 832 | { |
| 978 | throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.currentLineNumber, originalExpression)); | 833 | throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 979 | } | 834 | } |
| 980 | 835 | ||
| 981 | // cut the quotes off the string | 836 | // cut the quotes off the string |
| 982 | token = this.core.PreprocessString(this.currentLineNumber, expression.Substring(1, endingQuotes - 1)); | 837 | token = this.Helper.PreprocessString(this.Context, expression.Substring(1, endingQuotes - 1)); |
| 983 | 838 | ||
| 984 | // advance past this string | 839 | // advance past this string |
| 985 | expression = expression.Substring(endingQuotes + 1).Trim(); | 840 | expression = expression.Substring(endingQuotes + 1).Trim(); |
| @@ -1009,7 +864,7 @@ namespace WixToolset.Core | |||
| 1009 | 864 | ||
| 1010 | if (-1 == endingParen) | 865 | if (-1 == endingParen) |
| 1011 | { | 866 | { |
| 1012 | throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.currentLineNumber, originalExpression)); | 867 | throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1013 | } | 868 | } |
| 1014 | token = expression.Substring(0, endingParen + 1); | 869 | token = expression.Substring(0, endingParen + 1); |
| 1015 | 870 | ||
| @@ -1115,7 +970,7 @@ namespace WixToolset.Core | |||
| 1115 | { | 970 | { |
| 1116 | try | 971 | try |
| 1117 | { | 972 | { |
| 1118 | varValue = this.core.PreprocessString(this.currentLineNumber, variable); | 973 | varValue = this.Helper.PreprocessString(this.Context, variable); |
| 1119 | } | 974 | } |
| 1120 | catch (ArgumentNullException) | 975 | catch (ArgumentNullException) |
| 1121 | { | 976 | { |
| @@ -1126,12 +981,12 @@ namespace WixToolset.Core | |||
| 1126 | else if (variable.IndexOf("(", StringComparison.Ordinal) != -1 || variable.IndexOf(")", StringComparison.Ordinal) != -1) | 981 | else if (variable.IndexOf("(", StringComparison.Ordinal) != -1 || variable.IndexOf(")", StringComparison.Ordinal) != -1) |
| 1127 | { | 982 | { |
| 1128 | // make sure it doesn't contain parenthesis | 983 | // make sure it doesn't contain parenthesis |
| 1129 | throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.currentLineNumber, originalExpression)); | 984 | throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1130 | } | 985 | } |
| 1131 | else if (variable.IndexOf("\"", StringComparison.Ordinal) != -1) | 986 | else if (variable.IndexOf("\"", StringComparison.Ordinal) != -1) |
| 1132 | { | 987 | { |
| 1133 | // shouldn't contain quotes | 988 | // shouldn't contain quotes |
| 1134 | throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.currentLineNumber, originalExpression)); | 989 | throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1135 | } | 990 | } |
| 1136 | 991 | ||
| 1137 | return varValue; | 992 | return varValue; |
| @@ -1162,7 +1017,7 @@ namespace WixToolset.Core | |||
| 1162 | { | 1017 | { |
| 1163 | if (stringLiteral) | 1018 | if (stringLiteral) |
| 1164 | { | 1019 | { |
| 1165 | throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.currentLineNumber, originalExpression)); | 1020 | throw new WixException(WixErrors.UnmatchedQuotesInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1166 | } | 1021 | } |
| 1167 | 1022 | ||
| 1168 | rightValue = this.GetNextToken(originalExpression, ref expression, out stringLiteral); | 1023 | rightValue = this.GetNextToken(originalExpression, ref expression, out stringLiteral); |
| @@ -1213,7 +1068,7 @@ namespace WixToolset.Core | |||
| 1213 | { | 1068 | { |
| 1214 | if (operation.Length > 0) | 1069 | if (operation.Length > 0) |
| 1215 | { | 1070 | { |
| 1216 | throw new WixException(WixErrors.ExpectedVariable(this.currentLineNumber, originalExpression)); | 1071 | throw new WixException(WixErrors.ExpectedVariable(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1217 | } | 1072 | } |
| 1218 | 1073 | ||
| 1219 | // false expression | 1074 | // false expression |
| @@ -1228,7 +1083,7 @@ namespace WixToolset.Core | |||
| 1228 | } | 1083 | } |
| 1229 | else | 1084 | else |
| 1230 | { | 1085 | { |
| 1231 | throw new WixException(WixErrors.UnexpectedLiteral(this.currentLineNumber, originalExpression)); | 1086 | throw new WixException(WixErrors.UnexpectedLiteral(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1232 | } | 1087 | } |
| 1233 | } | 1088 | } |
| 1234 | else | 1089 | else |
| @@ -1268,11 +1123,11 @@ namespace WixToolset.Core | |||
| 1268 | } | 1123 | } |
| 1269 | catch (FormatException) | 1124 | catch (FormatException) |
| 1270 | { | 1125 | { |
| 1271 | throw new WixException(WixErrors.IllegalIntegerInExpression(this.currentLineNumber, originalExpression)); | 1126 | throw new WixException(WixErrors.IllegalIntegerInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1272 | } | 1127 | } |
| 1273 | catch (OverflowException) | 1128 | catch (OverflowException) |
| 1274 | { | 1129 | { |
| 1275 | throw new WixException(WixErrors.IllegalIntegerInExpression(this.currentLineNumber, originalExpression)); | 1130 | throw new WixException(WixErrors.IllegalIntegerInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1276 | } | 1131 | } |
| 1277 | 1132 | ||
| 1278 | // Compare the numbers | 1133 | // Compare the numbers |
| @@ -1314,7 +1169,7 @@ namespace WixToolset.Core | |||
| 1314 | closeParenIndex = expression.IndexOf(')', closeParenIndex); | 1169 | closeParenIndex = expression.IndexOf(')', closeParenIndex); |
| 1315 | if (closeParenIndex == -1) | 1170 | if (closeParenIndex == -1) |
| 1316 | { | 1171 | { |
| 1317 | throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.currentLineNumber, originalExpression)); | 1172 | throw new WixException(WixErrors.UnmatchedParenthesisInExpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1318 | } | 1173 | } |
| 1319 | 1174 | ||
| 1320 | if (InsideQuotes(expression, closeParenIndex)) | 1175 | if (InsideQuotes(expression, closeParenIndex)) |
| @@ -1363,7 +1218,7 @@ namespace WixToolset.Core | |||
| 1363 | currentValue = !currentValue; | 1218 | currentValue = !currentValue; |
| 1364 | break; | 1219 | break; |
| 1365 | default: | 1220 | default: |
| 1366 | throw new WixException(WixErrors.UnexpectedPreprocessorOperator(this.currentLineNumber, operation.ToString())); | 1221 | throw new WixException(WixErrors.UnexpectedPreprocessorOperator(this.Context.CurrentSourceLineNumber, operation.ToString())); |
| 1367 | } | 1222 | } |
| 1368 | } | 1223 | } |
| 1369 | 1224 | ||
| @@ -1412,7 +1267,7 @@ namespace WixToolset.Core | |||
| 1412 | expression = expression.Trim(); | 1267 | expression = expression.Trim(); |
| 1413 | if (expression.Length == 0) | 1268 | if (expression.Length == 0) |
| 1414 | { | 1269 | { |
| 1415 | throw new WixException(WixErrors.UnexpectedEmptySubexpression(this.currentLineNumber, originalExpression)); | 1270 | throw new WixException(WixErrors.UnexpectedEmptySubexpression(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1416 | } | 1271 | } |
| 1417 | 1272 | ||
| 1418 | // If the expression starts with parenthesis, evaluate it | 1273 | // If the expression starts with parenthesis, evaluate it |
| @@ -1433,7 +1288,7 @@ namespace WixToolset.Core | |||
| 1433 | expression = expression.Substring(3).Trim(); | 1288 | expression = expression.Substring(3).Trim(); |
| 1434 | if (expression.Length == 0) | 1289 | if (expression.Length == 0) |
| 1435 | { | 1290 | { |
| 1436 | throw new WixException(WixErrors.ExpectedExpressionAfterNot(this.currentLineNumber, originalExpression)); | 1291 | throw new WixException(WixErrors.ExpectedExpressionAfterNot(this.Context.CurrentSourceLineNumber, originalExpression)); |
| 1437 | } | 1292 | } |
| 1438 | 1293 | ||
| 1439 | expressionValue = this.EvaluateExpressionRecurse(originalExpression, ref expression, PreprocessorOperation.Not, true); | 1294 | expressionValue = this.EvaluateExpressionRecurse(originalExpression, ref expression, PreprocessorOperation.Not, true); |
| @@ -1462,7 +1317,7 @@ namespace WixToolset.Core | |||
| 1462 | } | 1317 | } |
| 1463 | else | 1318 | else |
| 1464 | { | 1319 | { |
| 1465 | throw new WixException(WixErrors.InvalidSubExpression(this.currentLineNumber, expression, originalExpression)); | 1320 | throw new WixException(WixErrors.InvalidSubExpression(this.Context.CurrentSourceLineNumber, expression, originalExpression)); |
| 1466 | } | 1321 | } |
| 1467 | } | 1322 | } |
| 1468 | 1323 | ||
| @@ -1481,9 +1336,9 @@ namespace WixToolset.Core | |||
| 1481 | { | 1336 | { |
| 1482 | int newLine = lineInfoReader.LineNumber + offset; | 1337 | int newLine = lineInfoReader.LineNumber + offset; |
| 1483 | 1338 | ||
| 1484 | if (this.currentLineNumber.LineNumber != newLine) | 1339 | if (this.Context.CurrentSourceLineNumber.LineNumber != newLine) |
| 1485 | { | 1340 | { |
| 1486 | this.currentLineNumber = new SourceLineNumber(this.currentLineNumber.FileName, newLine); | 1341 | this.Context.CurrentSourceLineNumber = new SourceLineNumber(this.Context.CurrentSourceLineNumber.FileName, newLine); |
| 1487 | } | 1342 | } |
| 1488 | } | 1343 | } |
| 1489 | } | 1344 | } |
| @@ -1494,15 +1349,15 @@ namespace WixToolset.Core | |||
| 1494 | /// <param name="fileName">Name to push on to the stack of included files.</param> | 1349 | /// <param name="fileName">Name to push on to the stack of included files.</param> |
| 1495 | private void PushInclude(string fileName) | 1350 | private void PushInclude(string fileName) |
| 1496 | { | 1351 | { |
| 1497 | if (1023 < this.currentFileStack.Count) | 1352 | if (1023 < this.CurrentFileStack.Count) |
| 1498 | { | 1353 | { |
| 1499 | throw new WixException(WixErrors.TooDeeplyIncluded(this.currentLineNumber, this.currentFileStack.Count)); | 1354 | throw new WixException(WixErrors.TooDeeplyIncluded(this.Context.CurrentSourceLineNumber, this.CurrentFileStack.Count)); |
| 1500 | } | 1355 | } |
| 1501 | 1356 | ||
| 1502 | this.currentFileStack.Push(fileName); | 1357 | this.CurrentFileStack.Push(fileName); |
| 1503 | this.sourceStack.Push(this.currentLineNumber); | 1358 | this.SourceStack.Push(this.Context.CurrentSourceLineNumber); |
| 1504 | this.currentLineNumber = new SourceLineNumber(fileName); | 1359 | this.Context.CurrentSourceLineNumber = new SourceLineNumber(fileName); |
| 1505 | this.includeNextStack.Push(true); | 1360 | this.IncludeNextStack.Push(true); |
| 1506 | } | 1361 | } |
| 1507 | 1362 | ||
| 1508 | /// <summary> | 1363 | /// <summary> |
| @@ -1510,10 +1365,10 @@ namespace WixToolset.Core | |||
| 1510 | /// </summary> | 1365 | /// </summary> |
| 1511 | private void PopInclude() | 1366 | private void PopInclude() |
| 1512 | { | 1367 | { |
| 1513 | this.currentLineNumber = this.sourceStack.Pop(); | 1368 | this.Context.CurrentSourceLineNumber = this.SourceStack.Pop(); |
| 1514 | 1369 | ||
| 1515 | this.currentFileStack.Pop(); | 1370 | this.CurrentFileStack.Pop(); |
| 1516 | this.includeNextStack.Pop(); | 1371 | this.IncludeNextStack.Pop(); |
| 1517 | } | 1372 | } |
| 1518 | 1373 | ||
| 1519 | /// <summary> | 1374 | /// <summary> |
| @@ -1548,8 +1403,8 @@ namespace WixToolset.Core | |||
| 1548 | else // relative path | 1403 | else // relative path |
| 1549 | { | 1404 | { |
| 1550 | // build a string to test the directory containing the source file first | 1405 | // build a string to test the directory containing the source file first |
| 1551 | string currentFolder = this.currentFileStack.Peek(); | 1406 | var currentFolder = this.CurrentFileStack.Peek(); |
| 1552 | string includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder) ?? String.Empty, includePath); | 1407 | var includeTestPath = Path.Combine(Path.GetDirectoryName(currentFolder) , includePath); |
| 1553 | 1408 | ||
| 1554 | // test the source file directory | 1409 | // test the source file directory |
| 1555 | if (File.Exists(includeTestPath)) | 1410 | if (File.Exists(includeTestPath)) |
| @@ -1558,7 +1413,7 @@ namespace WixToolset.Core | |||
| 1558 | } | 1413 | } |
| 1559 | else // test all search paths in the order specified on the command line | 1414 | else // test all search paths in the order specified on the command line |
| 1560 | { | 1415 | { |
| 1561 | foreach (string includeSearchPath in this.IncludeSearchPaths) | 1416 | foreach (var includeSearchPath in this.Context.IncludeSearchPaths) |
| 1562 | { | 1417 | { |
| 1563 | // if the path exists, we have found the final string | 1418 | // if the path exists, we have found the final string |
| 1564 | includeTestPath = Path.Combine(includeSearchPath, includePath); | 1419 | includeTestPath = Path.Combine(includeSearchPath, includePath); |
