diff options
Diffstat (limited to 'Prebuild/src/Core/Parse')
-rw-r--r-- | Prebuild/src/Core/Parse/IfContext.cs | 268 | ||||
-rw-r--r-- | Prebuild/src/Core/Parse/Preprocessor.cs | 1088 |
2 files changed, 678 insertions, 678 deletions
diff --git a/Prebuild/src/Core/Parse/IfContext.cs b/Prebuild/src/Core/Parse/IfContext.cs index 7729d3b..3c79d38 100644 --- a/Prebuild/src/Core/Parse/IfContext.cs +++ b/Prebuild/src/Core/Parse/IfContext.cs | |||
@@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea | |||
5 | Redistribution and use in source and binary forms, with or without modification, are permitted | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted |
6 | provided that the following conditions are met: | 6 | provided that the following conditions are met: |
7 | 7 | ||
8 | * Redistributions of source code must retain the above copyright notice, this list of conditions | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions |
9 | and the following disclaimer. | 9 | and the following disclaimer. |
10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions | 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions |
11 | and the following disclaimer in the documentation and/or other materials provided with the | 11 | and the following disclaimer in the documentation and/or other materials provided with the |
12 | distribution. | 12 | distribution. |
13 | * The name of the author may not be used to endorse or promote products derived from this software | 13 | * The name of the author may not be used to endorse or promote products derived from this software |
14 | without specific prior written permission. | 14 | without specific prior written permission. |
15 | 15 | ||
16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, |
17 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 19 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
20 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
@@ -27,128 +27,128 @@ using System; | |||
27 | 27 | ||
28 | namespace Prebuild.Core.Parse | 28 | namespace Prebuild.Core.Parse |
29 | { | 29 | { |
30 | /// <summary> | 30 | /// <summary> |
31 | /// | 31 | /// |
32 | /// </summary> | 32 | /// </summary> |
33 | public enum IfState | 33 | public enum IfState |
34 | { | 34 | { |
35 | /// <summary> | 35 | /// <summary> |
36 | /// | 36 | /// |
37 | /// </summary> | 37 | /// </summary> |
38 | None, | 38 | None, |
39 | /// <summary> | 39 | /// <summary> |
40 | /// | 40 | /// |
41 | /// </summary> | 41 | /// </summary> |
42 | If, | 42 | If, |
43 | /// <summary> | 43 | /// <summary> |
44 | /// | 44 | /// |
45 | /// </summary> | 45 | /// </summary> |
46 | ElseIf, | 46 | ElseIf, |
47 | /// <summary> | 47 | /// <summary> |
48 | /// | 48 | /// |
49 | /// </summary> | 49 | /// </summary> |
50 | Else | 50 | Else |
51 | } | 51 | } |
52 | 52 | ||
53 | /// <summary> | 53 | /// <summary> |
54 | /// Summary description for IfContext. | 54 | /// Summary description for IfContext. |
55 | /// </summary> | 55 | /// </summary> |
56 | // Inspired by the equivalent WiX class (see www.sourceforge.net/projects/wix/) | 56 | // Inspired by the equivalent WiX class (see www.sourceforge.net/projects/wix/) |
57 | public class IfContext | 57 | public class IfContext |
58 | { | 58 | { |
59 | #region Properties | 59 | #region Properties |
60 | 60 | ||
61 | bool m_Active; | 61 | bool m_Active; |
62 | bool m_Keep; | 62 | bool m_Keep; |
63 | bool m_EverKept; | 63 | bool m_EverKept; |
64 | IfState m_State = IfState.None; | 64 | IfState m_State = IfState.None; |
65 | 65 | ||
66 | #endregion | 66 | #endregion |
67 | 67 | ||
68 | #region Constructors | 68 | #region Constructors |
69 | 69 | ||
70 | /// <summary> | 70 | /// <summary> |
71 | /// Initializes a new instance of the <see cref="IfContext"/> class. | 71 | /// Initializes a new instance of the <see cref="IfContext"/> class. |
72 | /// </summary> | 72 | /// </summary> |
73 | /// <param name="active">if set to <c>true</c> [active].</param> | 73 | /// <param name="active">if set to <c>true</c> [active].</param> |
74 | /// <param name="keep">if set to <c>true</c> [keep].</param> | 74 | /// <param name="keep">if set to <c>true</c> [keep].</param> |
75 | /// <param name="state">The state.</param> | 75 | /// <param name="state">The state.</param> |
76 | public IfContext(bool active, bool keep, IfState state) | 76 | public IfContext(bool active, bool keep, IfState state) |
77 | { | 77 | { |
78 | m_Active = active; | 78 | m_Active = active; |
79 | m_Keep = keep; | 79 | m_Keep = keep; |
80 | m_EverKept = keep; | 80 | m_EverKept = keep; |
81 | m_State = state; | 81 | m_State = state; |
82 | } | 82 | } |
83 | 83 | ||
84 | #endregion | 84 | #endregion |
85 | 85 | ||
86 | #region Properties | 86 | #region Properties |
87 | 87 | ||
88 | /// <summary> | 88 | /// <summary> |
89 | /// Gets or sets a value indicating whether this <see cref="IfContext"/> is active. | 89 | /// Gets or sets a value indicating whether this <see cref="IfContext"/> is active. |
90 | /// </summary> | 90 | /// </summary> |
91 | /// <value><c>true</c> if active; otherwise, <c>false</c>.</value> | 91 | /// <value><c>true</c> if active; otherwise, <c>false</c>.</value> |
92 | public bool Active | 92 | public bool Active |
93 | { | 93 | { |
94 | get | 94 | get |
95 | { | 95 | { |
96 | return m_Active; | 96 | return m_Active; |
97 | } | 97 | } |
98 | set | 98 | set |
99 | { | 99 | { |
100 | m_Active = value; | 100 | m_Active = value; |
101 | } | 101 | } |
102 | } | 102 | } |
103 | 103 | ||
104 | /// <summary> | 104 | /// <summary> |
105 | /// Gets or sets a value indicating whether this <see cref="IfContext"/> is keep. | 105 | /// Gets or sets a value indicating whether this <see cref="IfContext"/> is keep. |
106 | /// </summary> | 106 | /// </summary> |
107 | /// <value><c>true</c> if keep; otherwise, <c>false</c>.</value> | 107 | /// <value><c>true</c> if keep; otherwise, <c>false</c>.</value> |
108 | public bool Keep | 108 | public bool Keep |
109 | { | 109 | { |
110 | get | 110 | get |
111 | { | 111 | { |
112 | return m_Keep; | 112 | return m_Keep; |
113 | } | 113 | } |
114 | set | 114 | set |
115 | { | 115 | { |
116 | m_Keep = value; | 116 | m_Keep = value; |
117 | if(m_Keep) | 117 | if(m_Keep) |
118 | { | 118 | { |
119 | m_EverKept = true; | 119 | m_EverKept = true; |
120 | } | 120 | } |
121 | } | 121 | } |
122 | } | 122 | } |
123 | 123 | ||
124 | /// <summary> | 124 | /// <summary> |
125 | /// Gets a value indicating whether [ever kept]. | 125 | /// Gets a value indicating whether [ever kept]. |
126 | /// </summary> | 126 | /// </summary> |
127 | /// <value><c>true</c> if [ever kept]; otherwise, <c>false</c>.</value> | 127 | /// <value><c>true</c> if [ever kept]; otherwise, <c>false</c>.</value> |
128 | public bool EverKept | 128 | public bool EverKept |
129 | { | 129 | { |
130 | get | 130 | get |
131 | { | 131 | { |
132 | return m_EverKept; | 132 | return m_EverKept; |
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | /// <summary> | 136 | /// <summary> |
137 | /// Gets or sets the state. | 137 | /// Gets or sets the state. |
138 | /// </summary> | 138 | /// </summary> |
139 | /// <value>The state.</value> | 139 | /// <value>The state.</value> |
140 | public IfState State | 140 | public IfState State |
141 | { | 141 | { |
142 | get | 142 | get |
143 | { | 143 | { |
144 | return m_State; | 144 | return m_State; |
145 | } | 145 | } |
146 | set | 146 | set |
147 | { | 147 | { |
148 | m_State = value; | 148 | m_State = value; |
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
152 | #endregion | 152 | #endregion |
153 | } | 153 | } |
154 | } | 154 | } |
diff --git a/Prebuild/src/Core/Parse/Preprocessor.cs b/Prebuild/src/Core/Parse/Preprocessor.cs index 0cd6e82..0648fad 100644 --- a/Prebuild/src/Core/Parse/Preprocessor.cs +++ b/Prebuild/src/Core/Parse/Preprocessor.cs | |||
@@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea | |||
5 | Redistribution and use in source and binary forms, with or without modification, are permitted | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted |
6 | provided that the following conditions are met: | 6 | provided that the following conditions are met: |
7 | 7 | ||
8 | * Redistributions of source code must retain the above copyright notice, this list of conditions | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions |
9 | and the following disclaimer. | 9 | and the following disclaimer. |
10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions | 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions |
11 | and the following disclaimer in the documentation and/or other materials provided with the | 11 | and the following disclaimer in the documentation and/or other materials provided with the |
12 | distribution. | 12 | distribution. |
13 | * The name of the author may not be used to endorse or promote products derived from this software | 13 | * The name of the author may not be used to endorse or promote products derived from this software |
14 | without specific prior written permission. | 14 | without specific prior written permission. |
15 | 15 | ||
16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, |
17 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 19 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
20 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
@@ -31,336 +31,336 @@ using System.Xml; | |||
31 | 31 | ||
32 | namespace Prebuild.Core.Parse | 32 | namespace Prebuild.Core.Parse |
33 | { | 33 | { |
34 | /// <summary> | 34 | /// <summary> |
35 | /// | 35 | /// |
36 | /// </summary> | 36 | /// </summary> |
37 | public enum OperatorSymbol | 37 | public enum OperatorSymbol |
38 | { | 38 | { |
39 | /// <summary> | 39 | /// <summary> |
40 | /// | 40 | /// |
41 | /// </summary> | 41 | /// </summary> |
42 | None, | 42 | None, |
43 | /// <summary> | 43 | /// <summary> |
44 | /// | 44 | /// |
45 | /// </summary> | 45 | /// </summary> |
46 | Equal, | 46 | Equal, |
47 | /// <summary> | 47 | /// <summary> |
48 | /// | 48 | /// |
49 | /// </summary> | 49 | /// </summary> |
50 | NotEqual, | 50 | NotEqual, |
51 | /// <summary> | 51 | /// <summary> |
52 | /// | 52 | /// |
53 | /// </summary> | 53 | /// </summary> |
54 | LessThan, | 54 | LessThan, |
55 | /// <summary> | 55 | /// <summary> |
56 | /// | 56 | /// |
57 | /// </summary> | 57 | /// </summary> |
58 | GreaterThan, | 58 | GreaterThan, |
59 | /// <summary> | 59 | /// <summary> |
60 | /// | 60 | /// |
61 | /// </summary> | 61 | /// </summary> |
62 | LessThanEqual, | 62 | LessThanEqual, |
63 | /// <summary> | 63 | /// <summary> |
64 | /// | 64 | /// |
65 | /// </summary> | 65 | /// </summary> |
66 | GreaterThanEqual | 66 | GreaterThanEqual |
67 | } | 67 | } |
68 | 68 | ||
69 | /// <summary> | 69 | /// <summary> |
70 | /// | 70 | /// |
71 | /// </summary> | 71 | /// </summary> |
72 | public class Preprocessor | 72 | public class Preprocessor |
73 | { | 73 | { |
74 | #region Constants | 74 | #region Constants |
75 | 75 | ||
76 | /// <summary> | 76 | /// <summary> |
77 | /// Includes the regex to look for file tags in the <?include | 77 | /// Includes the regex to look for file tags in the <?include |
78 | /// ?> processing instruction. | 78 | /// ?> processing instruction. |
79 | /// </summary> | 79 | /// </summary> |
80 | private static readonly Regex includeFileRegex = new Regex("file=\"(.+?)\""); | 80 | private static readonly Regex includeFileRegex = new Regex("file=\"(.+?)\""); |
81 | 81 | ||
82 | #endregion | 82 | #endregion |
83 | 83 | ||
84 | #region Fields | 84 | #region Fields |
85 | 85 | ||
86 | readonly XmlDocument m_OutDoc = new XmlDocument(); | 86 | readonly XmlDocument m_OutDoc = new XmlDocument(); |
87 | readonly Stack<IfContext> m_IfStack = new Stack<IfContext>(); | 87 | readonly Stack<IfContext> m_IfStack = new Stack<IfContext>(); |
88 | readonly Dictionary<string, object> m_Variables = new Dictionary<string, object>(); | 88 | readonly Dictionary<string, object> m_Variables = new Dictionary<string, object>(); |
89 | 89 | ||
90 | #endregion | 90 | #endregion |
91 | 91 | ||
92 | #region Constructors | 92 | #region Constructors |
93 | 93 | ||
94 | /// <summary> | 94 | /// <summary> |
95 | /// Initializes a new instance of the <see cref="Preprocessor"/> class. | 95 | /// Initializes a new instance of the <see cref="Preprocessor"/> class. |
96 | /// </summary> | 96 | /// </summary> |
97 | public Preprocessor() | 97 | public Preprocessor() |
98 | { | 98 | { |
99 | RegisterVariable("OS", GetOS()); | 99 | RegisterVariable("OS", GetOS()); |
100 | RegisterVariable("RuntimeVersion", Environment.Version.Major); | 100 | RegisterVariable("RuntimeVersion", Environment.Version.Major); |
101 | RegisterVariable("RuntimeMajor", Environment.Version.Major); | 101 | RegisterVariable("RuntimeMajor", Environment.Version.Major); |
102 | RegisterVariable("RuntimeMinor", Environment.Version.Minor); | 102 | RegisterVariable("RuntimeMinor", Environment.Version.Minor); |
103 | RegisterVariable("RuntimeRevision", Environment.Version.Revision); | 103 | RegisterVariable("RuntimeRevision", Environment.Version.Revision); |
104 | } | 104 | } |
105 | 105 | ||
106 | #endregion | 106 | #endregion |
107 | 107 | ||
108 | #region Properties | 108 | #region Properties |
109 | 109 | ||
110 | /// <summary> | 110 | /// <summary> |
111 | /// Gets the processed doc. | 111 | /// Gets the processed doc. |
112 | /// </summary> | 112 | /// </summary> |
113 | /// <value>The processed doc.</value> | 113 | /// <value>The processed doc.</value> |
114 | public XmlDocument ProcessedDoc | 114 | public XmlDocument ProcessedDoc |
115 | { | 115 | { |
116 | get | 116 | get |
117 | { | 117 | { |
118 | return m_OutDoc; | 118 | return m_OutDoc; |
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
122 | #endregion | 122 | #endregion |
123 | 123 | ||
124 | #region Private Methods | 124 | #region Private Methods |
125 | 125 | ||
126 | /// <summary> | 126 | /// <summary> |
127 | /// Parts of this code were taken from NAnt and is subject to the GPL | 127 | /// Parts of this code were taken from NAnt and is subject to the GPL |
128 | /// as per NAnt's license. Thanks to the NAnt guys for this little gem. | 128 | /// as per NAnt's license. Thanks to the NAnt guys for this little gem. |
129 | /// </summary> | 129 | /// </summary> |
130 | /// <returns></returns> | 130 | /// <returns></returns> |
131 | public static string GetOS() | 131 | public static string GetOS() |
132 | { | 132 | { |
133 | PlatformID platId = Environment.OSVersion.Platform; | 133 | PlatformID platId = Environment.OSVersion.Platform; |
134 | if(platId == PlatformID.Win32NT || platId == PlatformID.Win32Windows) | 134 | if(platId == PlatformID.Win32NT || platId == PlatformID.Win32Windows) |
135 | { | 135 | { |
136 | return "Win32"; | 136 | return "Win32"; |
137 | } | 137 | } |
138 | 138 | ||
139 | if (File.Exists("/System/Library/Frameworks/Cocoa.framework/Cocoa")) | 139 | if (File.Exists("/System/Library/Frameworks/Cocoa.framework/Cocoa")) |
140 | { | 140 | { |
141 | return "MACOSX"; | 141 | return "MACOSX"; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * .NET 1.x, under Mono, the UNIX code is 128. Under | 145 | * .NET 1.x, under Mono, the UNIX code is 128. Under |
146 | * .NET 2.x, Mono or MS, the UNIX code is 4 | 146 | * .NET 2.x, Mono or MS, the UNIX code is 4 |
147 | */ | 147 | */ |
148 | if(Environment.Version.Major == 1) | 148 | if(Environment.Version.Major == 1) |
149 | { | 149 | { |
150 | if((int)platId == 128) | 150 | if((int)platId == 128) |
151 | { | 151 | { |
152 | return "UNIX"; | 152 | return "UNIX"; |
153 | } | 153 | } |
154 | } | 154 | } |
155 | else if((int)platId == 4) | 155 | else if((int)platId == 4) |
156 | { | 156 | { |
157 | return "UNIX"; | 157 | return "UNIX"; |
158 | } | 158 | } |
159 | 159 | ||
160 | return "Unknown"; | 160 | return "Unknown"; |
161 | } | 161 | } |
162 | 162 | ||
163 | private static bool CompareNum(OperatorSymbol oper, int val1, int val2) | 163 | private static bool CompareNum(OperatorSymbol oper, int val1, int val2) |
164 | { | 164 | { |
165 | switch(oper) | 165 | switch(oper) |
166 | { | 166 | { |
167 | case OperatorSymbol.Equal: | 167 | case OperatorSymbol.Equal: |
168 | return (val1 == val2); | 168 | return (val1 == val2); |
169 | case OperatorSymbol.NotEqual: | 169 | case OperatorSymbol.NotEqual: |
170 | return (val1 != val2); | 170 | return (val1 != val2); |
171 | case OperatorSymbol.LessThan: | 171 | case OperatorSymbol.LessThan: |
172 | return (val1 < val2); | 172 | return (val1 < val2); |
173 | case OperatorSymbol.LessThanEqual: | 173 | case OperatorSymbol.LessThanEqual: |
174 | return (val1 <= val2); | 174 | return (val1 <= val2); |
175 | case OperatorSymbol.GreaterThan: | 175 | case OperatorSymbol.GreaterThan: |
176 | return (val1 > val2); | 176 | return (val1 > val2); |
177 | case OperatorSymbol.GreaterThanEqual: | 177 | case OperatorSymbol.GreaterThanEqual: |
178 | return (val1 >= val2); | 178 | return (val1 >= val2); |
179 | } | 179 | } |
180 | 180 | ||
181 | throw new WarningException("Unknown operator type"); | 181 | throw new WarningException("Unknown operator type"); |
182 | } | 182 | } |
183 | 183 | ||
184 | private static bool CompareStr(OperatorSymbol oper, string val1, string val2) | 184 | private static bool CompareStr(OperatorSymbol oper, string val1, string val2) |
185 | { | 185 | { |
186 | switch(oper) | 186 | switch(oper) |
187 | { | 187 | { |
188 | case OperatorSymbol.Equal: | 188 | case OperatorSymbol.Equal: |
189 | return (val1 == val2); | 189 | return (val1 == val2); |
190 | case OperatorSymbol.NotEqual: | 190 | case OperatorSymbol.NotEqual: |
191 | return (val1 != val2); | 191 | return (val1 != val2); |
192 | case OperatorSymbol.LessThan: | 192 | case OperatorSymbol.LessThan: |
193 | return (val1.CompareTo(val2) < 0); | 193 | return (val1.CompareTo(val2) < 0); |
194 | case OperatorSymbol.LessThanEqual: | 194 | case OperatorSymbol.LessThanEqual: |
195 | return (val1.CompareTo(val2) <= 0); | 195 | return (val1.CompareTo(val2) <= 0); |
196 | case OperatorSymbol.GreaterThan: | 196 | case OperatorSymbol.GreaterThan: |
197 | return (val1.CompareTo(val2) > 0); | 197 | return (val1.CompareTo(val2) > 0); |
198 | case OperatorSymbol.GreaterThanEqual: | 198 | case OperatorSymbol.GreaterThanEqual: |
199 | return (val1.CompareTo(val2) >= 0); | 199 | return (val1.CompareTo(val2) >= 0); |
200 | } | 200 | } |
201 | 201 | ||
202 | throw new WarningException("Unknown operator type"); | 202 | throw new WarningException("Unknown operator type"); |
203 | } | 203 | } |
204 | 204 | ||
205 | private static char NextChar(int idx, string str) | 205 | private static char NextChar(int idx, string str) |
206 | { | 206 | { |
207 | if((idx + 1) >= str.Length) | 207 | if((idx + 1) >= str.Length) |
208 | { | 208 | { |
209 | return Char.MaxValue; | 209 | return Char.MaxValue; |
210 | } | 210 | } |
211 | 211 | ||
212 | return str[idx + 1]; | 212 | return str[idx + 1]; |
213 | } | 213 | } |
214 | // Very very simple expression parser. Can only match expressions of the form | 214 | // Very very simple expression parser. Can only match expressions of the form |
215 | // <var> <op> <value>: | 215 | // <var> <op> <value>: |
216 | // OS = Windows | 216 | // OS = Windows |
217 | // OS != Linux | 217 | // OS != Linux |
218 | // RuntimeMinor > 0 | 218 | // RuntimeMinor > 0 |
219 | private bool ParseExpression(string exp) | 219 | private bool ParseExpression(string exp) |
220 | { | 220 | { |
221 | if(exp == null) | 221 | if(exp == null) |
222 | { | 222 | { |
223 | throw new ArgumentException("Invalid expression, cannot be null"); | 223 | throw new ArgumentException("Invalid expression, cannot be null"); |
224 | } | 224 | } |
225 | 225 | ||
226 | exp = exp.Trim(); | 226 | exp = exp.Trim(); |
227 | if(exp.Length < 1) | 227 | if(exp.Length < 1) |
228 | { | 228 | { |
229 | throw new ArgumentException("Invalid expression, cannot be 0 length"); | 229 | throw new ArgumentException("Invalid expression, cannot be 0 length"); |
230 | } | 230 | } |
231 | 231 | ||
232 | string id = ""; | 232 | string id = ""; |
233 | string str = ""; | 233 | string str = ""; |
234 | OperatorSymbol oper = OperatorSymbol.None; | 234 | OperatorSymbol oper = OperatorSymbol.None; |
235 | bool inStr = false; | 235 | bool inStr = false; |
236 | 236 | ||
237 | for(int i = 0; i < exp.Length; i++) | 237 | for(int i = 0; i < exp.Length; i++) |
238 | { | 238 | { |
239 | char c = exp[i]; | 239 | char c = exp[i]; |
240 | if(Char.IsWhiteSpace(c)) | 240 | if(Char.IsWhiteSpace(c)) |
241 | { | 241 | { |
242 | continue; | 242 | continue; |
243 | } | 243 | } |
244 | 244 | ||
245 | if(Char.IsLetterOrDigit(c) || c == '_') | 245 | if(Char.IsLetterOrDigit(c) || c == '_') |
246 | { | 246 | { |
247 | if(inStr) | 247 | if(inStr) |
248 | { | 248 | { |
249 | str += c; | 249 | str += c; |
250 | } | 250 | } |
251 | else | 251 | else |
252 | { | 252 | { |
253 | id += c; | 253 | id += c; |
254 | } | 254 | } |
255 | } | 255 | } |
256 | else if(c == '\"') | 256 | else if(c == '\"') |
257 | { | 257 | { |
258 | inStr = !inStr; | 258 | inStr = !inStr; |
259 | if(inStr) | 259 | if(inStr) |
260 | { | 260 | { |
261 | str = ""; | 261 | str = ""; |
262 | } | 262 | } |
263 | } | 263 | } |
264 | else | 264 | else |
265 | { | 265 | { |
266 | if(inStr) | 266 | if(inStr) |
267 | { | 267 | { |
268 | str += c; | 268 | str += c; |
269 | } | 269 | } |
270 | else | 270 | else |
271 | { | 271 | { |
272 | switch(c) | 272 | switch(c) |
273 | { | 273 | { |
274 | case '=': | 274 | case '=': |
275 | oper = OperatorSymbol.Equal; | 275 | oper = OperatorSymbol.Equal; |
276 | break; | 276 | break; |
277 | 277 | ||
278 | case '!': | 278 | case '!': |
279 | if(NextChar(i, exp) == '=') | 279 | if(NextChar(i, exp) == '=') |
280 | { | 280 | { |
281 | oper = OperatorSymbol.NotEqual; | 281 | oper = OperatorSymbol.NotEqual; |
282 | } | 282 | } |
283 | 283 | ||
284 | break; | 284 | break; |
285 | 285 | ||
286 | case '<': | 286 | case '<': |
287 | if(NextChar(i, exp) == '=') | 287 | if(NextChar(i, exp) == '=') |
288 | { | 288 | { |
289 | oper = OperatorSymbol.LessThanEqual; | 289 | oper = OperatorSymbol.LessThanEqual; |
290 | } | 290 | } |
291 | else | 291 | else |
292 | { | 292 | { |
293 | oper = OperatorSymbol.LessThan; | 293 | oper = OperatorSymbol.LessThan; |
294 | } | 294 | } |
295 | 295 | ||
296 | break; | 296 | break; |
297 | 297 | ||
298 | case '>': | 298 | case '>': |
299 | if(NextChar(i, exp) == '=') | 299 | if(NextChar(i, exp) == '=') |
300 | { | 300 | { |
301 | oper = OperatorSymbol.GreaterThanEqual; | 301 | oper = OperatorSymbol.GreaterThanEqual; |
302 | } | 302 | } |
303 | else | 303 | else |
304 | { | 304 | { |
305 | oper = OperatorSymbol.GreaterThan; | 305 | oper = OperatorSymbol.GreaterThan; |
306 | } | 306 | } |
307 | 307 | ||
308 | break; | 308 | break; |
309 | } | 309 | } |
310 | } | 310 | } |
311 | } | 311 | } |
312 | } | 312 | } |
313 | 313 | ||
314 | 314 | ||
315 | if(inStr) | 315 | if(inStr) |
316 | { | 316 | { |
317 | throw new WarningException("Expected end of string in expression"); | 317 | throw new WarningException("Expected end of string in expression"); |
318 | } | 318 | } |
319 | 319 | ||
320 | if(oper == OperatorSymbol.None) | 320 | if(oper == OperatorSymbol.None) |
321 | { | 321 | { |
322 | throw new WarningException("Expected operator in expression"); | 322 | throw new WarningException("Expected operator in expression"); |
323 | } | 323 | } |
324 | if(id.Length < 1) | 324 | if(id.Length < 1) |
325 | { | 325 | { |
326 | throw new WarningException("Expected identifier in expression"); | 326 | throw new WarningException("Expected identifier in expression"); |
327 | } | 327 | } |
328 | if(str.Length < 1) | 328 | if(str.Length < 1) |
329 | { | 329 | { |
330 | throw new WarningException("Expected value in expression"); | 330 | throw new WarningException("Expected value in expression"); |
331 | } | 331 | } |
332 | 332 | ||
333 | bool ret; | 333 | bool ret; |
334 | try | 334 | try |
335 | { | 335 | { |
336 | object val = m_Variables[id.ToLower()]; | 336 | object val = m_Variables[id.ToLower()]; |
337 | if(val == null) | 337 | if(val == null) |
338 | { | 338 | { |
339 | throw new WarningException("Unknown identifier '{0}'", id); | 339 | throw new WarningException("Unknown identifier '{0}'", id); |
340 | } | 340 | } |
341 | 341 | ||
342 | Type t = val.GetType(); | 342 | Type t = val.GetType(); |
343 | if(t.IsAssignableFrom(typeof(int))) | 343 | if(t.IsAssignableFrom(typeof(int))) |
344 | { | 344 | { |
345 | int numVal = (int)val; | 345 | int numVal = (int)val; |
346 | int numVal2 = Int32.Parse(str); | 346 | int numVal2 = Int32.Parse(str); |
347 | ret = CompareNum(oper, numVal, numVal2); | 347 | ret = CompareNum(oper, numVal, numVal2); |
348 | } | 348 | } |
349 | else | 349 | else |
350 | { | 350 | { |
351 | string strVal = val.ToString(); | 351 | string strVal = val.ToString(); |
352 | string strVal2 = str; | 352 | string strVal2 = str; |
353 | ret = CompareStr(oper, strVal, strVal2); | 353 | ret = CompareStr(oper, strVal, strVal2); |
354 | } | 354 | } |
355 | } | 355 | } |
356 | catch(ArgumentException ex) | 356 | catch(ArgumentException ex) |
357 | { | 357 | { |
358 | ex.ToString(); | 358 | ex.ToString(); |
359 | throw new WarningException("Invalid value type for system variable '{0}', expected int", id); | 359 | throw new WarningException("Invalid value type for system variable '{0}', expected int", id); |
360 | } | 360 | } |
361 | 361 | ||
362 | return ret; | 362 | return ret; |
363 | } | 363 | } |
364 | 364 | ||
365 | /// <summary> | 365 | /// <summary> |
366 | /// Taken from current Prebuild included in OpenSim 0.7.x | 366 | /// Taken from current Prebuild included in OpenSim 0.7.x |
@@ -376,13 +376,13 @@ namespace Prebuild.Core.Parse | |||
376 | if (!include.Contains ("*")) { | 376 | if (!include.Contains ("*")) { |
377 | return; | 377 | return; |
378 | } | 378 | } |
379 | 379 | ||
380 | // Console.WriteLine("Processing {0}", include); | 380 | // Console.WriteLine("Processing {0}", include); |
381 | 381 | ||
382 | // Break up the include into pre and post wildcard sections | 382 | // Break up the include into pre and post wildcard sections |
383 | string preWildcard = include.Substring (0, include.IndexOf ("*")); | 383 | string preWildcard = include.Substring (0, include.IndexOf ("*")); |
384 | string postWildcard = include.Substring (include.IndexOf ("*") + 2); | 384 | string postWildcard = include.Substring (include.IndexOf ("*") + 2); |
385 | 385 | ||
386 | // If preWildcard is a directory, recurse | 386 | // If preWildcard is a directory, recurse |
387 | if (Directory.Exists (preWildcard)) { | 387 | if (Directory.Exists (preWildcard)) { |
388 | string[] directories = Directory.GetDirectories (preWildcard); | 388 | string[] directories = Directory.GetDirectories (preWildcard); |
@@ -390,7 +390,7 @@ namespace Prebuild.Core.Parse | |||
390 | Array.Reverse (directories); | 390 | Array.Reverse (directories); |
391 | foreach (string dirPath in directories) { | 391 | foreach (string dirPath in directories) { |
392 | //Console.WriteLine ("Scanning : {0}", dirPath); | 392 | //Console.WriteLine ("Scanning : {0}", dirPath); |
393 | 393 | ||
394 | string includeFile = Path.Combine (dirPath, postWildcard); | 394 | string includeFile = Path.Combine (dirPath, postWildcard); |
395 | if (includeFile.Contains ("*")) { | 395 | if (includeFile.Contains ("*")) { |
396 | // postWildcard included another wildcard, recurse. | 396 | // postWildcard included another wildcard, recurse. |
@@ -408,10 +408,10 @@ namespace Prebuild.Core.Parse | |||
408 | // preWildcard is not a path to a directory, so the wildcard is in the filename | 408 | // preWildcard is not a path to a directory, so the wildcard is in the filename |
409 | string searchFilename = Path.GetFileName (preWildcard.Substring (preWildcard.IndexOf ("/") + 1) + "*" + postWildcard); | 409 | string searchFilename = Path.GetFileName (preWildcard.Substring (preWildcard.IndexOf ("/") + 1) + "*" + postWildcard); |
410 | Console.WriteLine ("searchFilename: {0}", searchFilename); | 410 | Console.WriteLine ("searchFilename: {0}", searchFilename); |
411 | 411 | ||
412 | string searchDirectory = Path.GetDirectoryName (preWildcard); | 412 | string searchDirectory = Path.GetDirectoryName (preWildcard); |
413 | Console.WriteLine ("searchDirectory: {0}", searchDirectory); | 413 | Console.WriteLine ("searchDirectory: {0}", searchDirectory); |
414 | 414 | ||
415 | string[] files = Directory.GetFiles (searchDirectory, searchFilename); | 415 | string[] files = Directory.GetFiles (searchDirectory, searchFilename); |
416 | Array.Sort (files); | 416 | Array.Sort (files); |
417 | Array.Reverse (files); | 417 | Array.Reverse (files); |
@@ -426,227 +426,227 @@ namespace Prebuild.Core.Parse | |||
426 | } | 426 | } |
427 | } | 427 | } |
428 | 428 | ||
429 | #endregion | 429 | #endregion |
430 | 430 | ||
431 | #region Public Methods | 431 | #region Public Methods |
432 | 432 | ||
433 | /// <summary> | 433 | /// <summary> |
434 | /// | 434 | /// |
435 | /// </summary> | 435 | /// </summary> |
436 | /// <param name="name"></param> | 436 | /// <param name="name"></param> |
437 | /// <param name="variableValue"></param> | 437 | /// <param name="variableValue"></param> |
438 | public void RegisterVariable(string name, object variableValue) | 438 | public void RegisterVariable(string name, object variableValue) |
439 | { | 439 | { |
440 | if(name == null || variableValue == null) | 440 | if(name == null || variableValue == null) |
441 | { | 441 | { |
442 | return; | 442 | return; |
443 | } | 443 | } |
444 | 444 | ||
445 | m_Variables[name.ToLower()] = variableValue; | 445 | m_Variables[name.ToLower()] = variableValue; |
446 | } | 446 | } |
447 | 447 | ||
448 | /// <summary> | 448 | /// <summary> |
449 | /// Performs validation on the xml source as well as evaluates conditional and flow expresions | 449 | /// Performs validation on the xml source as well as evaluates conditional and flow expresions |
450 | /// </summary> | 450 | /// </summary> |
451 | /// <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> | 451 | /// <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> |
452 | /// <param name="initialReader"></param> | 452 | /// <param name="initialReader"></param> |
453 | /// <returns>the output xml </returns> | 453 | /// <returns>the output xml </returns> |
454 | public string Process(XmlReader initialReader) | 454 | public string Process(XmlReader initialReader) |
455 | { | 455 | { |
456 | if(initialReader == null) | 456 | if(initialReader == null) |
457 | { | 457 | { |
458 | throw new ArgumentException("Invalid XML reader to pre-process"); | 458 | throw new ArgumentException("Invalid XML reader to pre-process"); |
459 | } | 459 | } |
460 | 460 | ||
461 | IfContext context = new IfContext(true, true, IfState.None); | 461 | IfContext context = new IfContext(true, true, IfState.None); |
462 | StringWriter xmlText = new StringWriter(); | 462 | StringWriter xmlText = new StringWriter(); |
463 | XmlTextWriter writer = new XmlTextWriter(xmlText); | 463 | XmlTextWriter writer = new XmlTextWriter(xmlText); |
464 | writer.Formatting = Formatting.Indented; | 464 | writer.Formatting = Formatting.Indented; |
465 | 465 | ||
466 | // Create a queue of XML readers and add the initial | 466 | // Create a queue of XML readers and add the initial |
467 | // reader to it. Then we process until we run out of | 467 | // reader to it. Then we process until we run out of |
468 | // readers which lets the <?include?> operation add more | 468 | // readers which lets the <?include?> operation add more |
469 | // readers to generate a multi-file parser and not require | 469 | // readers to generate a multi-file parser and not require |
470 | // XML fragments that a recursive version would use. | 470 | // XML fragments that a recursive version would use. |
471 | Stack<XmlReader> readerStack = new Stack<XmlReader>(); | 471 | Stack<XmlReader> readerStack = new Stack<XmlReader>(); |
472 | readerStack.Push(initialReader); | 472 | readerStack.Push(initialReader); |
473 | 473 | ||
474 | while(readerStack.Count > 0) | 474 | while(readerStack.Count > 0) |
475 | { | 475 | { |
476 | // Pop off the next reader. | 476 | // Pop off the next reader. |
477 | XmlReader reader = readerStack.Pop(); | 477 | XmlReader reader = readerStack.Pop(); |
478 | 478 | ||
479 | // Process through this XML reader until it is | 479 | // Process through this XML reader until it is |
480 | // completed (or it is replaced by the include | 480 | // completed (or it is replaced by the include |
481 | // operation). | 481 | // operation). |
482 | while(reader.Read()) | 482 | while(reader.Read()) |
483 | { | 483 | { |
484 | // The prebuild file has a series of processing | 484 | // The prebuild file has a series of processing |
485 | // instructions which allow for specific | 485 | // instructions which allow for specific |
486 | // inclusions based on operating system or to | 486 | // inclusions based on operating system or to |
487 | // include additional files. | 487 | // include additional files. |
488 | if(reader.NodeType == XmlNodeType.ProcessingInstruction) | 488 | if(reader.NodeType == XmlNodeType.ProcessingInstruction) |
489 | { | 489 | { |
490 | bool ignore = false; | 490 | bool ignore = false; |
491 | 491 | ||
492 | switch(reader.LocalName) | 492 | switch(reader.LocalName) |
493 | { | 493 | { |
494 | case "include": | 494 | case "include": |
495 | // use regular expressions to parse out the attributes. | 495 | // use regular expressions to parse out the attributes. |
496 | MatchCollection matches = includeFileRegex.Matches(reader.Value); | 496 | MatchCollection matches = includeFileRegex.Matches(reader.Value); |
497 | 497 | ||
498 | // make sure there is only one file attribute. | 498 | // make sure there is only one file attribute. |
499 | if(matches.Count > 1) | 499 | if(matches.Count > 1) |
500 | { | 500 | { |
501 | throw new WarningException("An <?include ?> node was found, but it specified more than one file."); | 501 | throw new WarningException("An <?include ?> node was found, but it specified more than one file."); |
502 | } | 502 | } |
503 | 503 | ||
504 | if(matches.Count == 0) | 504 | if(matches.Count == 0) |
505 | { | 505 | { |
506 | throw new WarningException("An <?include ?> node was found, but it did not specify the file attribute."); | 506 | throw new WarningException("An <?include ?> node was found, but it did not specify the file attribute."); |
507 | } | 507 | } |
508 | 508 | ||
509 | // ***** Adding for wildcard handling | 509 | // ***** Adding for wildcard handling |
510 | // Push current reader back onto the stack. | 510 | // Push current reader back onto the stack. |
511 | readerStack.Push (reader); | 511 | readerStack.Push (reader); |
512 | 512 | ||
513 | // Pull the file out from the regex and make sure it is a valid file before using it. | 513 | // Pull the file out from the regex and make sure it is a valid file before using it. |
514 | string filename = matches[0].Groups[1].Value; | 514 | string filename = matches[0].Groups[1].Value; |
515 | 515 | ||
516 | filename = String.Join (Path.DirectorySeparatorChar.ToString (), filename.Split (new char[] { '/', '\\' })); | 516 | filename = String.Join (Path.DirectorySeparatorChar.ToString (), filename.Split (new char[] { '/', '\\' })); |
517 | 517 | ||
518 | if (!filename.Contains ("*")) { | 518 | if (!filename.Contains ("*")) { |
519 | 519 | ||
520 | FileInfo includeFile = new FileInfo (filename); | 520 | FileInfo includeFile = new FileInfo (filename); |
521 | if (!includeFile.Exists) { | 521 | if (!includeFile.Exists) { |
522 | throw new WarningException ("Cannot include file: " + includeFile.FullName); | 522 | throw new WarningException ("Cannot include file: " + includeFile.FullName); |
523 | } | 523 | } |
524 | 524 | ||
525 | // Create a new reader object for this file. Then put the old reader back on the stack and start | 525 | // Create a new reader object for this file. Then put the old reader back on the stack and start |
526 | // processing using this new XML reader. | 526 | // processing using this new XML reader. |
527 | 527 | ||
528 | XmlReader newReader = new XmlTextReader (includeFile.Open (FileMode.Open, FileAccess.Read, FileShare.Read)); | 528 | XmlReader newReader = new XmlTextReader (includeFile.Open (FileMode.Open, FileAccess.Read, FileShare.Read)); |
529 | reader = newReader; | 529 | reader = newReader; |
530 | readerStack.Push (reader); | 530 | readerStack.Push (reader); |
531 | 531 | ||
532 | } else { | 532 | } else { |
533 | WildCardInclude (readerStack, filename); | 533 | WildCardInclude (readerStack, filename); |
534 | } | 534 | } |
535 | 535 | ||
536 | reader = (XmlReader)readerStack.Pop (); | 536 | reader = (XmlReader)readerStack.Pop (); |
537 | ignore = true; | 537 | ignore = true; |
538 | break; | 538 | break; |
539 | 539 | ||
540 | case "if": | 540 | case "if": |
541 | m_IfStack.Push(context); | 541 | m_IfStack.Push(context); |
542 | context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); | 542 | context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); |
543 | ignore = true; | 543 | ignore = true; |
544 | break; | 544 | break; |
545 | 545 | ||
546 | case "elseif": | 546 | case "elseif": |
547 | if(m_IfStack.Count == 0) | 547 | if(m_IfStack.Count == 0) |
548 | { | 548 | { |
549 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); | 549 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); |
550 | } | 550 | } |
551 | if(context.State != IfState.If && context.State != IfState.ElseIf) | 551 | if(context.State != IfState.If && context.State != IfState.ElseIf) |
552 | { | 552 | { |
553 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); | 553 | throw new WarningException("Unexpected 'elseif' outside of 'if'"); |
554 | } | 554 | } |
555 | 555 | ||
556 | context.State = IfState.ElseIf; | 556 | context.State = IfState.ElseIf; |
557 | if(!context.EverKept) | 557 | if(!context.EverKept) |
558 | { | 558 | { |
559 | context.Keep = ParseExpression(reader.Value); | 559 | context.Keep = ParseExpression(reader.Value); |
560 | } | 560 | } |
561 | else | 561 | else |
562 | { | 562 | { |
563 | context.Keep = false; | 563 | context.Keep = false; |
564 | } | 564 | } |
565 | 565 | ||
566 | ignore = true; | 566 | ignore = true; |
567 | break; | 567 | break; |
568 | 568 | ||
569 | case "else": | 569 | case "else": |
570 | if(m_IfStack.Count == 0) | 570 | if(m_IfStack.Count == 0) |
571 | { | 571 | { |
572 | throw new WarningException("Unexpected 'else' outside of 'if'"); | 572 | throw new WarningException("Unexpected 'else' outside of 'if'"); |
573 | } | 573 | } |
574 | if(context.State != IfState.If && context.State != IfState.ElseIf) | 574 | if(context.State != IfState.If && context.State != IfState.ElseIf) |
575 | { | 575 | { |
576 | throw new WarningException("Unexpected 'else' outside of 'if'"); | 576 | throw new WarningException("Unexpected 'else' outside of 'if'"); |
577 | } | 577 | } |
578 | 578 | ||
579 | context.State = IfState.Else; | 579 | context.State = IfState.Else; |
580 | context.Keep = !context.EverKept; | 580 | context.Keep = !context.EverKept; |
581 | ignore = true; | 581 | ignore = true; |
582 | break; | 582 | break; |
583 | 583 | ||
584 | case "endif": | 584 | case "endif": |
585 | if(m_IfStack.Count == 0) | 585 | if(m_IfStack.Count == 0) |
586 | { | 586 | { |
587 | throw new WarningException("Unexpected 'endif' outside of 'if'"); | 587 | throw new WarningException("Unexpected 'endif' outside of 'if'"); |
588 | } | 588 | } |
589 | 589 | ||
590 | context = m_IfStack.Pop(); | 590 | context = m_IfStack.Pop(); |
591 | ignore = true; | 591 | ignore = true; |
592 | break; | 592 | break; |
593 | } | 593 | } |
594 | 594 | ||
595 | if(ignore) | 595 | if(ignore) |
596 | { | 596 | { |
597 | continue; | 597 | continue; |
598 | } | 598 | } |
599 | }//end pre-proc instruction | 599 | }//end pre-proc instruction |
600 | 600 | ||
601 | if(!context.Active || !context.Keep) | 601 | if(!context.Active || !context.Keep) |
602 | { | 602 | { |
603 | continue; | 603 | continue; |
604 | } | 604 | } |
605 | 605 | ||
606 | switch(reader.NodeType) | 606 | switch(reader.NodeType) |
607 | { | 607 | { |
608 | case XmlNodeType.Element: | 608 | case XmlNodeType.Element: |
609 | bool empty = reader.IsEmptyElement; | 609 | bool empty = reader.IsEmptyElement; |
610 | writer.WriteStartElement(reader.Name); | 610 | writer.WriteStartElement(reader.Name); |
611 | 611 | ||
612 | while (reader.MoveToNextAttribute()) | 612 | while (reader.MoveToNextAttribute()) |
613 | { | 613 | { |
614 | writer.WriteAttributeString(reader.Name, reader.Value); | 614 | writer.WriteAttributeString(reader.Name, reader.Value); |
615 | } | 615 | } |
616 | 616 | ||
617 | if(empty) | 617 | if(empty) |
618 | { | 618 | { |
619 | writer.WriteEndElement(); | 619 | writer.WriteEndElement(); |
620 | } | 620 | } |
621 | 621 | ||
622 | break; | 622 | break; |
623 | 623 | ||
624 | case XmlNodeType.EndElement: | 624 | case XmlNodeType.EndElement: |
625 | writer.WriteEndElement(); | 625 | writer.WriteEndElement(); |
626 | break; | 626 | break; |
627 | 627 | ||
628 | case XmlNodeType.Text: | 628 | case XmlNodeType.Text: |
629 | writer.WriteString(reader.Value); | 629 | writer.WriteString(reader.Value); |
630 | break; | 630 | break; |
631 | 631 | ||
632 | case XmlNodeType.CDATA: | 632 | case XmlNodeType.CDATA: |
633 | writer.WriteCData(reader.Value); | 633 | writer.WriteCData(reader.Value); |
634 | break; | 634 | break; |
635 | 635 | ||
636 | default: | 636 | default: |
637 | break; | 637 | break; |
638 | } | 638 | } |
639 | } | 639 | } |
640 | 640 | ||
641 | if(m_IfStack.Count != 0) | 641 | if(m_IfStack.Count != 0) |
642 | { | 642 | { |
643 | throw new WarningException("Mismatched 'if', 'endif' pair"); | 643 | throw new WarningException("Mismatched 'if', 'endif' pair"); |
644 | } | 644 | } |
645 | } | 645 | } |
646 | 646 | ||
647 | return xmlText.ToString(); | 647 | return xmlText.ToString(); |
648 | } | 648 | } |
649 | 649 | ||
650 | #endregion | 650 | #endregion |
651 | } | 651 | } |
652 | } | 652 | } |