[xbuild] Function names are case insensitive.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / ConditionFunctionExpression.cs
1 //
2 // ConditionFunctionExpression.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 #if NET_2_0
29
30 using System;
31 using System.Collections.Generic;
32 using System.IO;
33 using System.Reflection;
34 using System.Xml;
35
36 namespace Microsoft.Build.BuildEngine {
37         internal sealed class ConditionFunctionExpression : ConditionExpression {
38         
39                 List <ConditionFactorExpression>        args;
40                 string                                  name;
41                 
42                 static Dictionary <string, MethodInfo>  functions;
43                 
44                 static ConditionFunctionExpression ()
45                 {
46                         Type t = typeof (ConditionFunctionExpression);
47                         string [] names = new string [] { "Exists", "HasTrailingSlash" };
48                 
49                         functions = new Dictionary <string, MethodInfo> (StringComparer.InvariantCultureIgnoreCase);
50                         foreach (string name in names)
51                                 functions.Add (name, t.GetMethod (name, BindingFlags.NonPublic | BindingFlags.Static));
52                 }
53         
54                 public ConditionFunctionExpression (string name, List <ConditionFactorExpression> args)
55                 {
56                         this.args = args;
57                         this.name = name;
58                 }
59                 
60                 public override  bool BoolEvaluate (Project context)
61                 {
62                         if (!functions.ContainsKey (name))
63                                 throw new InvalidOperationException ("Unknown function named: " + name);
64                         
65                         if (functions [name] == null)
66                                 throw new InvalidOperationException ("Unknown function named: " + name);
67                                 
68                         MethodInfo mi = functions [name];
69                         object [] argsArr = new object [args.Count + 1];
70                         int i = 0;
71                         foreach (ConditionFactorExpression cfe in args)
72                                 argsArr [i++] = cfe.StringEvaluate (context);
73                         argsArr [i] = context;
74                                 
75                         return (bool) mi.Invoke (null, argsArr);
76                 }
77                 
78                 public override float NumberEvaluate (Project context)
79                 {
80                         throw new NotSupportedException ();
81                 }
82                 
83                 public override string StringEvaluate (Project context)
84                 {
85                         throw new NotSupportedException ();
86                 }
87                 
88                 public override bool CanEvaluateToBool (Project context)
89                 {
90                         return functions.ContainsKey (name);
91                 }
92                 
93                 public override bool CanEvaluateToNumber (Project context)
94                 {
95                         return false;
96                 }
97                 
98                 public override bool CanEvaluateToString (Project context)
99                 {
100                         return false;
101                 }
102
103 #pragma warning disable 0169
104 #region Functions
105                 // FIXME imported projects
106                 static bool Exists (string file, Project context)
107                 {
108                         string directory  = null;
109                         
110                         if (context.FullFileName != String.Empty)
111                                 directory = Path.GetDirectoryName (context.FullFileName);
112                                 
113                         if (!Path.IsPathRooted (file) && directory != null && directory != String.Empty)
114                                 file = Path.Combine (directory, file);
115                 
116                         return File.Exists (file) || Directory.Exists (file);
117                 }
118
119                 static bool HasTrailingSlash (string file, Project context)
120                 {
121                         if (file == null)
122                                 return false;
123
124                         file = file.Trim ();
125
126                         int len = file.Length;
127                         if (len == 0)
128                                 return false;
129
130                         return file [len - 1] == '\\' || file [len - 1] == '/';
131                 }
132
133 #endregion
134 #pragma warning restore 0169
135
136         }
137 }
138
139 #endif