* Makefile ($(build_lib)): Make CYCLIC_DEP_FILES depend on this.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / Utilities.cs
1 //
2 // Utilities.cs:
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Lluis Sanchez Gual <lluis@novell.com>
7 //
8 // (C) 2005 Marek Sieradzki
9 // Copyright (c) 2008 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 #if NET_2_0
31
32 using System;
33 using System.Collections;
34 using System.IO;
35 using System.Text;
36
37 namespace Microsoft.Build.BuildEngine {
38         public static class Utilities {
39         
40                 static Hashtable charsToEscape;
41         
42                 static Utilities ()
43                 {
44                         charsToEscape = new Hashtable ();
45                         
46                         charsToEscape.Add ('$', null);
47                         charsToEscape.Add ('%', null);
48                         charsToEscape.Add ('\'', null);
49                         charsToEscape.Add ('(', null);
50                         charsToEscape.Add (')', null);
51                         charsToEscape.Add ('*', null);
52                         charsToEscape.Add (';', null);
53                         charsToEscape.Add ('?', null);
54                         charsToEscape.Add ('@', null);
55                 }
56         
57                 public static string Escape (string unescapedExpression)
58                 {
59                         StringBuilder sb = new StringBuilder ();
60                         
61                         foreach (char c in unescapedExpression) {
62                                 if (charsToEscape.Contains (c))
63                                         sb.AppendFormat ("%{0:x2}", (int) c);
64                                 else
65                                         sb.Append (c);
66                         }
67                         
68                         return sb.ToString ();
69                 }
70                 
71                 // FIXME: add tests for this
72                 internal static string Unescape (string escapedExpression)
73                 {
74                         StringBuilder sb = new StringBuilder ();
75                         
76                         int i = 0;
77                         while (i < escapedExpression.Length) {
78                                 sb.Append (Uri.HexUnescape (escapedExpression, ref i));
79                         }
80                         
81                         return sb.ToString ();
82                 }
83
84                 internal static string FromMSBuildPath (string relPath)
85                 {
86                         if (relPath == null || relPath.Length == 0)
87                                 return null;
88
89                         bool is_windows = Path.DirectorySeparatorChar == '\\';
90                         string path = relPath;
91                         if (!is_windows)
92                                 path = path.Replace ("\\", "/");
93
94                         // a path with drive letter is invalid/unusable on non-windows
95                         if (!is_windows && char.IsLetter (path [0]) && path.Length > 1 && path[1] == ':')
96                                 return null;
97
98                         if (System.IO.File.Exists (path)){
99                                 return Path.GetFullPath (path);
100                         }
101
102                         if (Path.IsPathRooted (path)) {
103
104                                 // Windows paths are case-insensitive. When mapping an absolute path
105                                 // we can try to find the correct case for the path.
106
107                                 string[] names = path.Substring (1).Split ('/');
108                                 string part = "/";
109
110                                 for (int n=0; n<names.Length; n++) {
111                                         string[] entries;
112
113                                         if (names [n] == ".."){
114                                                 if (part == "/")
115                                                         return ""; // Can go further back. It's not an existing file
116                                                 part = Path.GetFullPath (part + "/..");
117                                                 continue;
118                                         }
119
120                                         entries = Directory.GetFileSystemEntries (part);
121
122                                         string fpath = null;
123                                         foreach (string e in entries) {
124                                                 if (string.Compare (Path.GetFileName (e), names[n], true) == 0) {
125                                                         fpath = e;
126                                                         break;
127                                                 }
128                                         }
129                                         if (fpath == null) {
130                                                 // Part of the path does not exist. Can't do any more checking.
131                                                 part = Path.GetFullPath (part);
132                                                 for (; n < names.Length; n++)
133                                                         part += "/" + names[n];
134                                                 return part;
135                                         }
136
137                                         part = fpath;
138                                 }
139                                 return Path.GetFullPath (part);
140                         } else {
141                                 return Path.GetFullPath (path);
142                         }
143                 }
144         }
145
146 }
147
148 #endif