5 // Marek Sieradzki (marek.sieradzki@gmail.com)
6 // Lluis Sanchez Gual <lluis@novell.com>
8 // (C) 2005 Marek Sieradzki
9 // Copyright (c) 2008 Novell, Inc (http://www.novell.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
33 using System.Collections;
37 namespace Microsoft.Build.BuildEngine {
38 public static class Utilities {
40 static Hashtable charsToEscape;
44 charsToEscape = new Hashtable ();
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);
57 public static string Escape (string unescapedExpression)
59 StringBuilder sb = new StringBuilder ();
61 foreach (char c in unescapedExpression) {
62 if (charsToEscape.Contains (c))
63 sb.AppendFormat ("%{0:x2}", (int) c);
68 return sb.ToString ();
71 // FIXME: add tests for this
72 internal static string Unescape (string escapedExpression)
74 StringBuilder sb = new StringBuilder ();
77 while (i < escapedExpression.Length) {
78 sb.Append (Uri.HexUnescape (escapedExpression, ref i));
81 return sb.ToString ();
84 internal static string FromMSBuildPath (string relPath)
86 if (relPath == null || relPath.Length == 0)
89 bool is_windows = Path.DirectorySeparatorChar == '\\';
90 string path = relPath;
92 path = path.Replace ("\\", "/");
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] == ':')
98 if (System.IO.File.Exists (path)){
99 return Path.GetFullPath (path);
102 if (Path.IsPathRooted (path)) {
104 // Windows paths are case-insensitive. When mapping an absolute path
105 // we can try to find the correct case for the path.
107 string[] names = path.Substring (1).Split ('/');
110 for (int n=0; n<names.Length; n++) {
113 if (names [n] == ".."){
115 return ""; // Can go further back. It's not an existing file
116 part = Path.GetFullPath (part + "/..");
120 entries = Directory.GetFileSystemEntries (part);
123 foreach (string e in entries) {
124 if (string.Compare (Path.GetFileName (e), names[n], true) == 0) {
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];
139 return Path.GetFullPath (part);
141 return Path.GetFullPath (path);