diff options
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); |