diff options
author | lbsa71 | 2009-02-19 18:01:33 +0000 |
---|---|---|
committer | lbsa71 | 2009-02-19 18:01:33 +0000 |
commit | 06ece33bee0f046ea5f4b8590cfd9b13dd2e4a38 (patch) | |
tree | 876de8f4db442a7822c73d97a20ef86ca8842e19 /Prebuild/src/Core/Parse/Preprocessor.cs | |
parent | * Fix http://opensimulator.org/mantis/view.php?id=3193 (diff) | |
download | opensim-SC-06ece33bee0f046ea5f4b8590cfd9b13dd2e4a38.zip opensim-SC-06ece33bee0f046ea5f4b8590cfd9b13dd2e4a38.tar.gz opensim-SC-06ece33bee0f046ea5f4b8590cfd9b13dd2e4a38.tar.bz2 opensim-SC-06ece33bee0f046ea5f4b8590cfd9b13dd2e4a38.tar.xz |
* Okay, so finally got my head around this. Problem is that upstream Prebuild copied dlls promiscuously, and this led to the references being all mixed up (/bin dlls overwritten by different versions on every csc)
* Something that thus needs fixing is the fact that ProjectReferences has to be marked
<ProjectReference>
<Private>False</Private>
</ProjectReference>
but that is not configurable in the upstream Xml Schema. I've hardcoded it in our repo for now.
Diffstat (limited to 'Prebuild/src/Core/Parse/Preprocessor.cs')
-rw-r--r-- | Prebuild/src/Core/Parse/Preprocessor.cs | 272 |
1 files changed, 165 insertions, 107 deletions
diff --git a/Prebuild/src/Core/Parse/Preprocessor.cs b/Prebuild/src/Core/Parse/Preprocessor.cs index eea5c30..013f8e1 100644 --- a/Prebuild/src/Core/Parse/Preprocessor.cs +++ b/Prebuild/src/Core/Parse/Preprocessor.cs | |||
@@ -23,18 +23,10 @@ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O | |||
23 | */ | 23 | */ |
24 | #endregion | 24 | #endregion |
25 | 25 | ||
26 | #region CVS Information | ||
27 | /* | ||
28 | * $Source$ | ||
29 | * $Author: jendave $ | ||
30 | * $Date: 2007-04-26 17:10:27 +0900 (Thu, 26 Apr 2007) $ | ||
31 | * $Revision: 236 $ | ||
32 | */ | ||
33 | #endregion | ||
34 | |||
35 | using System; | 26 | using System; |
36 | using System.Collections; | 27 | using System.Collections; |
37 | using System.IO; | 28 | using System.IO; |
29 | using System.Text.RegularExpressions; | ||
38 | using System.Xml; | 30 | using System.Xml; |
39 | 31 | ||
40 | namespace Prebuild.Core.Parse | 32 | namespace Prebuild.Core.Parse |
@@ -79,6 +71,16 @@ namespace Prebuild.Core.Parse | |||
79 | /// </summary> | 71 | /// </summary> |
80 | public class Preprocessor | 72 | public class Preprocessor |
81 | { | 73 | { |
74 | #region Constants | ||
75 | |||
76 | /// <summary> | ||
77 | /// Includes the regex to look for file tags in the <?include | ||
78 | /// ?> processing instruction. | ||
79 | /// </summary> | ||
80 | private static readonly Regex includeFileRegex = new Regex("file=\"(.+?)\""); | ||
81 | |||
82 | #endregion | ||
83 | |||
82 | #region Fields | 84 | #region Fields |
83 | 85 | ||
84 | XmlDocument m_OutDoc; | 86 | XmlDocument m_OutDoc; |
@@ -138,10 +140,10 @@ namespace Prebuild.Core.Parse | |||
138 | return "Win32"; | 140 | return "Win32"; |
139 | } | 141 | } |
140 | 142 | ||
141 | if (File.Exists("/System/Library/Frameworks/Cocoa.framework/Cocoa")) | 143 | if (File.Exists("/System/Library/Frameworks/Cocoa.framework/Cocoa")) |
142 | { | 144 | { |
143 | return "MACOSX"; | 145 | return "MACOSX"; |
144 | } | 146 | } |
145 | 147 | ||
146 | /* | 148 | /* |
147 | * .NET 1.x, under Mono, the UNIX code is 128. Under | 149 | * .NET 1.x, under Mono, the UNIX code is 128. Under |
@@ -236,7 +238,7 @@ namespace Prebuild.Core.Parse | |||
236 | OperatorSymbol oper = OperatorSymbol.None; | 238 | OperatorSymbol oper = OperatorSymbol.None; |
237 | bool inStr = false; | 239 | bool inStr = false; |
238 | char c; | 240 | char c; |
239 | 241 | ||
240 | for(int i = 0; i < exp.Length; i++) | 242 | for(int i = 0; i < exp.Length; i++) |
241 | { | 243 | { |
242 | c = exp[i]; | 244 | c = exp[i]; |
@@ -283,7 +285,7 @@ namespace Prebuild.Core.Parse | |||
283 | { | 285 | { |
284 | oper = OperatorSymbol.NotEqual; | 286 | oper = OperatorSymbol.NotEqual; |
285 | } | 287 | } |
286 | 288 | ||
287 | break; | 289 | break; |
288 | 290 | ||
289 | case '<': | 291 | case '<': |
@@ -295,7 +297,7 @@ namespace Prebuild.Core.Parse | |||
295 | { | 297 | { |
296 | oper = OperatorSymbol.LessThan; | 298 | oper = OperatorSymbol.LessThan; |
297 | } | 299 | } |
298 | 300 | ||
299 | break; | 301 | break; |
300 | 302 | ||
301 | case '>': | 303 | case '>': |
@@ -314,7 +316,7 @@ namespace Prebuild.Core.Parse | |||
314 | } | 316 | } |
315 | } | 317 | } |
316 | 318 | ||
317 | 319 | ||
318 | if(inStr) | 320 | if(inStr) |
319 | { | 321 | { |
320 | throw new WarningException("Expected end of string in expression"); | 322 | throw new WarningException("Expected end of string in expression"); |
@@ -392,9 +394,9 @@ namespace Prebuild.Core.Parse | |||
392 | /// <exception cref="ArgumentException">For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml</exception> | 394 | /// <exception cref="ArgumentException">For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml</exception> |
393 | /// <param name="reader"></param> | 395 | /// <param name="reader"></param> |
394 | /// <returns>the output xml </returns> | 396 | /// <returns>the output xml </returns> |
395 | public string Process(XmlReader reader) | 397 | public string Process(XmlReader initialReader) |
396 | { | 398 | { |
397 | if(reader == null) | 399 | if(initialReader == null) |
398 | { | 400 | { |
399 | throw new ArgumentException("Invalid XML reader to pre-process"); | 401 | throw new ArgumentException("Invalid XML reader to pre-process"); |
400 | } | 402 | } |
@@ -403,119 +405,175 @@ namespace Prebuild.Core.Parse | |||
403 | StringWriter xmlText = new StringWriter(); | 405 | StringWriter xmlText = new StringWriter(); |
404 | XmlTextWriter writer = new XmlTextWriter(xmlText); | 406 | XmlTextWriter writer = new XmlTextWriter(xmlText); |
405 | writer.Formatting = Formatting.Indented; | 407 | writer.Formatting = Formatting.Indented; |
406 | while(reader.Read()) | 408 | |
409 | // Create a queue of XML readers and add the initial | ||
410 | // reader to it. Then we process until we run out of | ||
411 | // readers which lets the <?include?> operation add more | ||
412 | // readers to generate a multi-file parser and not require | ||
413 | // XML fragments that a recursive version would use. | ||
414 | Stack readerStack = new Stack(); | ||
415 | readerStack.Push(initialReader); | ||
416 | |||
417 | while(readerStack.Count > 0) | ||
407 | { | 418 | { |
408 | if(reader.NodeType == XmlNodeType.ProcessingInstruction) | 419 | // Pop off the next reader. |
420 | XmlReader reader = (XmlReader) readerStack.Pop(); | ||
421 | |||
422 | // Process through this XML reader until it is | ||
423 | // completed (or it is replaced by the include | ||
424 | // operation). | ||
425 | while(reader.Read()) | ||
409 | { | 426 | { |
410 | bool ignore = false; | 427 | // The prebuild file has a series of processing |
411 | switch(reader.LocalName) | 428 | // instructions which allow for specific |
429 | // inclusions based on operating system or to | ||
430 | // include additional files. | ||
431 | if(reader.NodeType == XmlNodeType.ProcessingInstruction) | ||
412 | { | 432 | { |
413 | case "if": | 433 | bool ignore = false; |
414 | m_IfStack.Push(context); | ||
415 | context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); | ||
416 | ignore = true; | ||
417 | break; | ||
418 | 434 | ||
419 | case "elseif": | 435 | switch(reader.LocalName) |
420 | if(m_IfStack.Count == 0) | 436 | { |
421 | { | 437 | case "include": |
422 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); | 438 | // use regular expressions to parse out the attributes. |
423 | } | 439 | MatchCollection matches = includeFileRegex.Matches(reader.Value); |
424 | else if(context.State != IfState.If && context.State != IfState.ElseIf) | 440 | |
425 | { | 441 | // make sure there is only one file attribute. |
426 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); | 442 | if(matches.Count > 1) |
427 | } | 443 | { |
444 | throw new WarningException("An <?include ?> node was found, but it specified more than one file."); | ||
445 | } | ||
428 | 446 | ||
429 | context.State = IfState.ElseIf; | 447 | if(matches.Count == 0) |
430 | if(!context.EverKept) | 448 | { |
431 | { | 449 | throw new WarningException("An <?include ?> node was found, but it did not specify the file attribute."); |
432 | context.Keep = ParseExpression(reader.Value); | 450 | } |
433 | } | 451 | |
434 | else | 452 | // Pull the file out from the regex and make sure it is a valid file before using it. |
435 | { | 453 | string filename = matches[0].Groups[1].Value; |
436 | context.Keep = false; | 454 | FileInfo includeFile = new FileInfo(filename); |
437 | } | ||
438 | 455 | ||
439 | ignore = true; | 456 | if(!includeFile.Exists) |
440 | break; | 457 | { |
458 | throw new WarningException("Cannot include file: " + includeFile.FullName); | ||
459 | } | ||
441 | 460 | ||
442 | case "else": | 461 | // Create a new reader object for this file. Then put the old reader back on the stack and start |
443 | if(m_IfStack.Count == 0) | 462 | // processing using this new XML reader. |
444 | { | 463 | XmlReader newReader = new XmlTextReader(includeFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read)); |
445 | throw new WarningException("Unexpected 'else' outside of 'if'"); | ||
446 | } | ||
447 | else if(context.State != IfState.If && context.State != IfState.ElseIf) | ||
448 | { | ||
449 | throw new WarningException("Unexpected 'else' outside of 'if'"); | ||
450 | } | ||
451 | 464 | ||
452 | context.State = IfState.Else; | 465 | readerStack.Push(reader); |
453 | context.Keep = !context.EverKept; | 466 | reader = newReader; |
454 | ignore = true; | 467 | ignore = true; |
455 | break; | 468 | break; |
456 | 469 | ||
457 | case "endif": | 470 | case "if": |
458 | if(m_IfStack.Count == 0) | 471 | m_IfStack.Push(context); |
459 | { | 472 | context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); |
460 | throw new WarningException("Unexpected 'endif' outside of 'if'"); | 473 | ignore = true; |
461 | } | 474 | break; |
462 | 475 | ||
463 | context = (IfContext)m_IfStack.Pop(); | 476 | case "elseif": |
464 | ignore = true; | 477 | if(m_IfStack.Count == 0) |
465 | break; | 478 | { |
466 | } | 479 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); |
480 | } | ||
481 | else if(context.State != IfState.If && context.State != IfState.ElseIf) | ||
482 | { | ||
483 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); | ||
484 | } | ||
467 | 485 | ||
468 | if(ignore) | 486 | context.State = IfState.ElseIf; |
469 | { | 487 | if(!context.EverKept) |
470 | continue; | 488 | { |
471 | } | 489 | context.Keep = ParseExpression(reader.Value); |
472 | }//end pre-proc instruction | 490 | } |
491 | else | ||
492 | { | ||
493 | context.Keep = false; | ||
494 | } | ||
473 | 495 | ||
474 | if(!context.Active || !context.Keep) | 496 | ignore = true; |
475 | { | 497 | break; |
476 | continue; | ||
477 | } | ||
478 | 498 | ||
479 | switch(reader.NodeType) | 499 | case "else": |
480 | { | 500 | if(m_IfStack.Count == 0) |
481 | case XmlNodeType.Element: | 501 | { |
482 | bool empty = reader.IsEmptyElement; | 502 | throw new WarningException("Unexpected 'else' outside of 'if'"); |
483 | writer.WriteStartElement(reader.Name); | 503 | } |
504 | else if(context.State != IfState.If && context.State != IfState.ElseIf) | ||
505 | { | ||
506 | throw new WarningException("Unexpected 'else' outside of 'if'"); | ||
507 | } | ||
484 | 508 | ||
485 | while (reader.MoveToNextAttribute()) | 509 | context.State = IfState.Else; |
486 | { | 510 | context.Keep = !context.EverKept; |
487 | writer.WriteAttributeString(reader.Name, reader.Value); | 511 | ignore = true; |
512 | break; | ||
513 | |||
514 | case "endif": | ||
515 | if(m_IfStack.Count == 0) | ||
516 | { | ||
517 | throw new WarningException("Unexpected 'endif' outside of 'if'"); | ||
518 | } | ||
519 | |||
520 | context = (IfContext)m_IfStack.Pop(); | ||
521 | ignore = true; | ||
522 | break; | ||
488 | } | 523 | } |
489 | 524 | ||
490 | if(empty) | 525 | if(ignore) |
491 | { | 526 | { |
492 | writer.WriteEndElement(); | 527 | continue; |
493 | } | 528 | } |
494 | 529 | }//end pre-proc instruction | |
495 | break; | ||
496 | 530 | ||
497 | case XmlNodeType.EndElement: | 531 | if(!context.Active || !context.Keep) |
498 | writer.WriteEndElement(); | 532 | { |
499 | break; | 533 | continue; |
534 | } | ||
500 | 535 | ||
501 | case XmlNodeType.Text: | 536 | switch(reader.NodeType) |
502 | writer.WriteString(reader.Value); | 537 | { |
503 | break; | 538 | case XmlNodeType.Element: |
539 | bool empty = reader.IsEmptyElement; | ||
540 | writer.WriteStartElement(reader.Name); | ||
541 | |||
542 | while (reader.MoveToNextAttribute()) | ||
543 | { | ||
544 | writer.WriteAttributeString(reader.Name, reader.Value); | ||
545 | } | ||
504 | 546 | ||
505 | case XmlNodeType.CDATA: | 547 | if(empty) |
506 | writer.WriteCData(reader.Value); | 548 | { |
507 | break; | 549 | writer.WriteEndElement(); |
550 | } | ||
551 | |||
552 | break; | ||
508 | 553 | ||
509 | default: | 554 | case XmlNodeType.EndElement: |
510 | break; | 555 | writer.WriteEndElement(); |
556 | break; | ||
557 | |||
558 | case XmlNodeType.Text: | ||
559 | writer.WriteString(reader.Value); | ||
560 | break; | ||
561 | |||
562 | case XmlNodeType.CDATA: | ||
563 | writer.WriteCData(reader.Value); | ||
564 | break; | ||
565 | |||
566 | default: | ||
567 | break; | ||
568 | } | ||
511 | } | 569 | } |
512 | } | ||
513 | 570 | ||
514 | if(m_IfStack.Count != 0) | 571 | if(m_IfStack.Count != 0) |
515 | { | 572 | { |
516 | throw new WarningException("Mismatched 'if', 'endif' pair"); | 573 | throw new WarningException("Mismatched 'if', 'endif' pair"); |
574 | } | ||
517 | } | 575 | } |
518 | 576 | ||
519 | return xmlText.ToString(); | 577 | return xmlText.ToString(); |
520 | } | 578 | } |
521 | 579 | ||