Merge remote-tracking branch 'joncham/sgen-msvc2'
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / ConditionRelationalExpression.cs
1 //
2 // ConditionRelationalExpression.cs
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 // 
7 // (C) 2006 Marek Sieradzki
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 using System;
29 using System.Collections;
30 using System.Xml;
31
32 namespace Microsoft.Build.BuildEngine {
33         internal sealed class ConditionRelationalExpression : ConditionExpression {
34         
35                 readonly ConditionExpression left;
36                 readonly ConditionExpression right;
37                 readonly RelationOperator op;
38                 
39                 public ConditionRelationalExpression (ConditionExpression left,
40                                                       ConditionExpression right,
41                                                       RelationOperator op)
42                 {
43                         this.left = left;
44                         this.right = right;
45                         this.op = op;
46                 }
47                 
48                 public override  bool BoolEvaluate (Project context)
49                 {
50                         if (left.CanEvaluateToNumber (context) && right.CanEvaluateToNumber (context)) {
51                                 float l,r;
52                                 
53                                 l = left.NumberEvaluate (context);
54                                 r = right.NumberEvaluate (context);
55                                 
56                                 return NumberCompare (l, r, op);
57                         } else if (left.CanEvaluateToBool (context) && right.CanEvaluateToBool (context)) {
58                                 bool l,r;
59                                 
60                                 l = left.BoolEvaluate (context);
61                                 r = right.BoolEvaluate (context);
62                                 
63                                 return BoolCompare (l, r, op);
64                         } else {
65                                 string l,r;
66                                 
67                                 l = left.StringEvaluate (context);
68                                 r = right.StringEvaluate (context);
69                                 
70                                 return StringCompare (l, r, op);
71                         }
72                 }
73                 
74                 public override float NumberEvaluate (Project context)
75                 {
76                         throw new NotSupportedException ();
77                 }
78                 
79                 public override string StringEvaluate (Project context)
80                 {
81                         throw new NotSupportedException ();
82                 }
83                 
84                 // FIXME: check if we really can do it
85                 public override bool CanEvaluateToBool (Project context)
86                 {
87                         return true;
88                 }
89                 
90                 public override bool CanEvaluateToNumber (Project context)
91                 {
92                         return false;
93                 }
94                 
95                 public override bool CanEvaluateToString (Project context)
96                 {
97                         return false;
98                 }
99                 
100                 static bool NumberCompare (float l,
101                                            float r,
102                                            RelationOperator op)
103                 {
104                         IComparer comparer = CaseInsensitiveComparer.DefaultInvariant;
105                         
106                         switch (op) {
107                         case RelationOperator.Equal:
108                                 return comparer.Compare (l, r) == 0;
109                         case RelationOperator.NotEqual:
110                                 return comparer.Compare (l, r) != 0;
111                         case RelationOperator.Greater:
112                                 return comparer.Compare (l, r) > 0;
113                         case RelationOperator.GreaterOrEqual:
114                                 return comparer.Compare (l, r) >= 0;
115                         case RelationOperator.Less:
116                                 return comparer.Compare (l, r) < 0;
117                         case RelationOperator.LessOrEqual:
118                                 return comparer.Compare (l, r) <= 0;
119                         default:
120                                 throw new NotSupportedException (String.Format ("Relational operator {0} is not supported.", op));
121                         }
122                 }
123
124                 static bool BoolCompare (bool l,
125                                          bool r,
126                                          RelationOperator op)
127                 {
128                         IComparer comparer = CaseInsensitiveComparer.DefaultInvariant;
129                         
130                         switch (op) {
131                         case RelationOperator.Equal:
132                                 return comparer.Compare (l, r) == 0;
133                         case RelationOperator.NotEqual:
134                                 return comparer.Compare (l, r) != 0;
135                         default:
136                                 throw new NotSupportedException (String.Format ("Relational operator {0} is not supported.", op));
137                         }
138                 }
139
140                 static bool StringCompare (string l,
141                                            string r,
142                                            RelationOperator op)
143                 {
144                         IComparer comparer = CaseInsensitiveComparer.DefaultInvariant;
145                         
146                         switch (op) {
147                         case RelationOperator.Equal:
148                                 return comparer.Compare (l, r) == 0;
149                         case RelationOperator.NotEqual:
150                                 return comparer.Compare (l, r) != 0;
151                         default:
152                                 throw new NotSupportedException (String.Format ("Relational operator {0} is not supported.", op));
153                         }
154                 }
155         }
156         
157         internal enum RelationOperator {
158                 Equal,
159                 NotEqual,
160                 Less,
161                 Greater,
162                 LessOrEqual,
163                 GreaterOrEqual
164         }
165 }