~ubuntu-branches/debian/sid/nunit/sid

« back to all changes in this revision

Viewing changes to src/ProjectEditor/editor/PathUtils.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2014-09-16 13:43:36 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20140916134336-kjxz48tty6lx2ja5
Tags: 2.6.3+dfsg-1
* [c7bd1b5] Imported Upstream version 2.6.3+dfsg
* [bcb4bf8] Move nunit-console-runner to GAC-installed libnunit2.6, 
  don't treat it as a private lib. This lib is signed, and treated 
  as a GAC lib by consumers such as MonoDevelop.
* [7f08e99] Bump version to 2.6.3 as required
* [84535eb] Refreshed patches
* [8479f61] Split package up into per-assembly packages. This makes 
  ABI tracking easier in the future, as we can meaningfully have GAC 
  policy for cases where ABI isn't truly bumped, and no policy for 
  cases where it is. For example, if nunit.framework bumps ABI but 
  nunit.core does not, previously we would need to rebuild everything 
  using NUnit, but under the new split packaging, that rebuild would 
  not be needed for apps only using nunit.core.
* [17a7dc7] Add missing nunit.mocks.dll to nunit.pc

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ****************************************************************
2
 
// Copyright 2011, Charlie Poole
3
 
// This is free software licensed under the NUnit license. You may
4
 
// obtain a copy of the license at http://nunit.org
5
 
// ****************************************************************
6
 
 
7
 
using System;
8
 
using System.IO;
9
 
using System.Text;
10
 
using System.Reflection;
11
 
using System.Collections.Generic;
12
 
using System.Runtime.InteropServices;
13
 
 
14
 
namespace NUnit.ProjectEditor
15
 
{
16
 
        /// <summary>
17
 
        /// Static methods for manipulating doc paths, including both directories
18
 
        /// and files. Some synonyms for System.Path methods are included as well.
19
 
        /// </summary> 
20
 
        public class PathUtils
21
 
        {
22
 
                public const uint FILE_ATTRIBUTE_DIRECTORY  = 0x00000010;  
23
 
                public const uint FILE_ATTRIBUTE_NORMAL     = 0x00000080;  
24
 
                public const int MAX_PATH = 256;
25
 
 
26
 
                protected static char DirectorySeparatorChar = Path.DirectorySeparatorChar;
27
 
                protected static char AltDirectorySeparatorChar = Path.AltDirectorySeparatorChar;
28
 
 
29
 
                #region Public methods
30
 
 
31
 
                public static bool IsAssemblyFileType( string path )
32
 
                {
33
 
                        string extension = Path.GetExtension( path ).ToLower();
34
 
                        return extension == ".dll" || extension == ".exe";
35
 
                }
36
 
 
37
 
                /// <summary>
38
 
                /// Returns the relative path from a base directory to another
39
 
                /// directory or file.
40
 
                /// </summary>
41
 
                public static string RelativePath( string from, string to )
42
 
                {
43
 
                        if (from == null)
44
 
                                throw new ArgumentNullException (from);
45
 
                        if (to == null)
46
 
                                throw new ArgumentNullException (to);
47
 
 
48
 
            string toPathRoot = Path.GetPathRoot(to);
49
 
            if (toPathRoot == null || toPathRoot == string.Empty)
50
 
                return to;
51
 
            string fromPathRoot = Path.GetPathRoot(from);
52
 
 
53
 
            if (!PathsEqual(toPathRoot, fromPathRoot))
54
 
                return null;
55
 
 
56
 
            string fromNoRoot = from.Substring(fromPathRoot.Length);
57
 
            string toNoRoot = to.Substring(toPathRoot.Length);
58
 
 
59
 
            string[] _from = SplitPath(fromNoRoot);
60
 
            string[] _to = SplitPath(toNoRoot);
61
 
 
62
 
                        StringBuilder sb = new StringBuilder (Math.Max (from.Length, to.Length));
63
 
 
64
 
                        int last_common, min = Math.Min (_from.Length, _to.Length);
65
 
                        for (last_common = 0; last_common < min;  ++last_common) 
66
 
                        {
67
 
                if (!PathsEqual(_from[last_common], _to[last_common]))
68
 
                    break;
69
 
            }
70
 
 
71
 
                        if (last_common < _from.Length)
72
 
                                sb.Append ("..");
73
 
                        for (int i = last_common + 1; i < _from.Length; ++i) 
74
 
                        {
75
 
                                sb.Append (PathUtils.DirectorySeparatorChar).Append ("..");
76
 
                        }
77
 
 
78
 
                        if (sb.Length > 0)
79
 
                                sb.Append (PathUtils.DirectorySeparatorChar);
80
 
                        if (last_common < _to.Length)
81
 
                                sb.Append (_to [last_common]);
82
 
                        for (int i = last_common + 1; i < _to.Length; ++i) 
83
 
                        {
84
 
                                sb.Append (PathUtils.DirectorySeparatorChar).Append (_to [i]);
85
 
                        }
86
 
 
87
 
                        return sb.ToString ();
88
 
                }
89
 
 
90
 
                /// <summary>
91
 
                /// Return the canonical form of a path.
92
 
                /// </summary>
93
 
                public static string Canonicalize( string path )
94
 
                {
95
 
                        List<string> parts = new List<string>(
96
 
                                path.Split( DirectorySeparatorChar, AltDirectorySeparatorChar ) );
97
 
 
98
 
                        for( int index = 0; index < parts.Count; )
99
 
                        {
100
 
                                string part = parts[index];
101
 
                
102
 
                                switch( part )
103
 
                                {
104
 
                                        case ".":
105
 
                                                parts.RemoveAt( index );
106
 
                                                break;
107
 
                                
108
 
                                        case "..":
109
 
                                                parts.RemoveAt( index );
110
 
                                                if ( index > 0 )
111
 
                                                        parts.RemoveAt( --index );
112
 
                                                break;
113
 
                                        default:
114
 
                                                index++;
115
 
                                                break;
116
 
                                }
117
 
                        }
118
 
        
119
 
                        return String.Join( DirectorySeparatorChar.ToString(), parts.ToArray() );
120
 
                }
121
 
 
122
 
                /// <summary>
123
 
                /// True if the two paths are the same. However, two paths
124
 
                /// to the same file or directory using different network
125
 
                /// shares or drive letters are not treated as equal.
126
 
                /// </summary>
127
 
                public static bool SamePath( string path1, string path2 )
128
 
                {
129
 
                        return string.Compare( Canonicalize(path1), Canonicalize(path2), PathUtils.IsWindows() ) == 0;
130
 
                }
131
 
 
132
 
                /// <summary>
133
 
                /// True if the two paths are the same or if the second is
134
 
                /// directly or indirectly under the first. Note that paths 
135
 
                /// using different network shares or drive letters are 
136
 
                /// considered unrelated, even if they end up referencing
137
 
                /// the same subtrees in the file system.
138
 
                /// </summary>
139
 
                public static bool SamePathOrUnder( string path1, string path2 )
140
 
                {
141
 
                        path1 = Canonicalize( path1 );
142
 
                        path2 = Canonicalize( path2 );
143
 
 
144
 
                        int length1 = path1.Length;
145
 
                        int length2 = path2.Length;
146
 
 
147
 
                        // if path1 is longer, then path2 can't be under it
148
 
                        if ( length1 > length2 )
149
 
                                return false;
150
 
 
151
 
                        // if lengths are the same, check for equality
152
 
                        if ( length1 == length2 )
153
 
                                return string.Compare( path1, path2, IsWindows() ) == 0;
154
 
 
155
 
                        // path 2 is longer than path 1: see if initial parts match
156
 
                        if ( string.Compare( path1, path2.Substring( 0, length1 ), IsWindows() ) != 0 )
157
 
                                return false;
158
 
                        
159
 
                        // must match through or up to a directory separator boundary
160
 
                        return  path2[length1-1] == DirectorySeparatorChar ||
161
 
                                path2[length1] == DirectorySeparatorChar;
162
 
                }
163
 
 
164
 
                public static string Combine( string path1, params string[] morePaths )
165
 
                {
166
 
                        string result = path1;
167
 
                        foreach( string path in morePaths )
168
 
                                result = Path.Combine( result, path );
169
 
                        return result;
170
 
                }
171
 
 
172
 
                // TODO: This logic should be in shared source
173
 
                public static string GetAssemblyPath( Assembly assembly )
174
 
                {
175
 
                        string uri = assembly.CodeBase;
176
 
 
177
 
                        // If it wasn't loaded locally, use the Location
178
 
                        if ( !uri.StartsWith( Uri.UriSchemeFile ) )
179
 
                                return assembly.Location;
180
 
 
181
 
                        return GetAssemblyPathFromFileUri( uri );
182
 
                }
183
 
 
184
 
                // Separate method for testability
185
 
                public static string GetAssemblyPathFromFileUri( string uri )
186
 
                {
187
 
                        // Skip over the file://
188
 
                        int start = Uri.UriSchemeFile.Length + Uri.SchemeDelimiter.Length;
189
 
                        
190
 
                        if ( PathUtils.DirectorySeparatorChar == '\\' )
191
 
                        {
192
 
                                if ( uri[start] == '/' && uri[start+2] == ':' )
193
 
                                        ++start;
194
 
                        }
195
 
                        else
196
 
                        {
197
 
                                if ( uri[start] != '/' )
198
 
                                        --start;
199
 
                        }
200
 
 
201
 
                        return uri.Substring( start );
202
 
                }
203
 
                #endregion
204
 
 
205
 
                #region Helper Methods
206
 
 
207
 
                private static bool IsWindows()
208
 
                {
209
 
                        return PathUtils.DirectorySeparatorChar == '\\';
210
 
                }
211
 
 
212
 
        private static string[] SplitPath(string path)
213
 
        {
214
 
            char[] separators = new char[] { PathUtils.DirectorySeparatorChar, PathUtils.AltDirectorySeparatorChar };
215
 
 
216
 
#if CLR_2_0 || CLR_4_0
217
 
            return path.Split(separators, StringSplitOptions.RemoveEmptyEntries);
218
 
#else
219
 
            string[] trialSplit = path.Split(separators);
220
 
            
221
 
            int emptyEntries = 0;
222
 
            foreach(string piece in trialSplit)
223
 
                if (piece == string.Empty)
224
 
                    emptyEntries++;
225
 
 
226
 
            if (emptyEntries == 0)
227
 
                return trialSplit;
228
 
 
229
 
            string[] finalSplit = new string[trialSplit.Length - emptyEntries];
230
 
            int index = 0;
231
 
            foreach(string piece in trialSplit)
232
 
                if (piece != string.Empty)
233
 
                    finalSplit[index++] = piece;
234
 
 
235
 
            return finalSplit;
236
 
#endif
237
 
        }
238
 
 
239
 
        private static bool PathsEqual(string path1, string path2)
240
 
        {
241
 
#if CLR_2_0 || CLR_4_0
242
 
            if (PathUtils.IsWindows())
243
 
                return path1.Equals(path2, StringComparison.InvariantCultureIgnoreCase);
244
 
            else
245
 
                return path1.Equals(path2, StringComparison.InvariantCulture);
246
 
#else
247
 
            if (PathUtils.IsWindows())
248
 
                return path1.ToLower().Equals(path2.ToLower());
249
 
            else
250
 
                return path1.Equals(path2);
251
 
#endif
252
 
        }
253
 
 
254
 
        #endregion
255
 
        }
256
 
}
 
1
// ****************************************************************
 
2
// Copyright 2011, Charlie Poole
 
3
// This is free software licensed under the NUnit license. You may
 
4
// obtain a copy of the license at http://nunit.org
 
5
// ****************************************************************
 
6
 
 
7
using System;
 
8
using System.IO;
 
9
using System.Text;
 
10
using System.Reflection;
 
11
using System.Collections.Generic;
 
12
using System.Runtime.InteropServices;
 
13
 
 
14
namespace NUnit.ProjectEditor
 
15
{
 
16
        /// <summary>
 
17
        /// Static methods for manipulating doc paths, including both directories
 
18
        /// and files. Some synonyms for System.Path methods are included as well.
 
19
        /// </summary> 
 
20
        public class PathUtils
 
21
        {
 
22
                public const uint FILE_ATTRIBUTE_DIRECTORY  = 0x00000010;  
 
23
                public const uint FILE_ATTRIBUTE_NORMAL     = 0x00000080;  
 
24
                public const int MAX_PATH = 256;
 
25
 
 
26
                protected static char DirectorySeparatorChar = Path.DirectorySeparatorChar;
 
27
                protected static char AltDirectorySeparatorChar = Path.AltDirectorySeparatorChar;
 
28
 
 
29
                #region Public methods
 
30
 
 
31
                public static bool IsAssemblyFileType( string path )
 
32
                {
 
33
                        string extension = Path.GetExtension( path ).ToLower();
 
34
                        return extension == ".dll" || extension == ".exe";
 
35
                }
 
36
 
 
37
                /// <summary>
 
38
                /// Returns the relative path from a base directory to another
 
39
                /// directory or file.
 
40
                /// </summary>
 
41
                public static string RelativePath( string from, string to )
 
42
                {
 
43
                        if (from == null)
 
44
                                throw new ArgumentNullException (from);
 
45
                        if (to == null)
 
46
                                throw new ArgumentNullException (to);
 
47
 
 
48
            string toPathRoot = Path.GetPathRoot(to);
 
49
            if (toPathRoot == null || toPathRoot == string.Empty)
 
50
                return to;
 
51
            string fromPathRoot = Path.GetPathRoot(from);
 
52
 
 
53
            if (!PathsEqual(toPathRoot, fromPathRoot))
 
54
                return null;
 
55
 
 
56
            string fromNoRoot = from.Substring(fromPathRoot.Length);
 
57
            string toNoRoot = to.Substring(toPathRoot.Length);
 
58
 
 
59
            string[] _from = SplitPath(fromNoRoot);
 
60
            string[] _to = SplitPath(toNoRoot);
 
61
 
 
62
                        StringBuilder sb = new StringBuilder (Math.Max (from.Length, to.Length));
 
63
 
 
64
                        int last_common, min = Math.Min (_from.Length, _to.Length);
 
65
                        for (last_common = 0; last_common < min;  ++last_common) 
 
66
                        {
 
67
                if (!PathsEqual(_from[last_common], _to[last_common]))
 
68
                    break;
 
69
            }
 
70
 
 
71
                        if (last_common < _from.Length)
 
72
                                sb.Append ("..");
 
73
                        for (int i = last_common + 1; i < _from.Length; ++i) 
 
74
                        {
 
75
                                sb.Append (PathUtils.DirectorySeparatorChar).Append ("..");
 
76
                        }
 
77
 
 
78
                        if (sb.Length > 0)
 
79
                                sb.Append (PathUtils.DirectorySeparatorChar);
 
80
                        if (last_common < _to.Length)
 
81
                                sb.Append (_to [last_common]);
 
82
                        for (int i = last_common + 1; i < _to.Length; ++i) 
 
83
                        {
 
84
                                sb.Append (PathUtils.DirectorySeparatorChar).Append (_to [i]);
 
85
                        }
 
86
 
 
87
                        return sb.ToString ();
 
88
                }
 
89
 
 
90
                /// <summary>
 
91
                /// Return the canonical form of a path.
 
92
                /// </summary>
 
93
                public static string Canonicalize( string path )
 
94
                {
 
95
                        List<string> parts = new List<string>(
 
96
                                path.Split( DirectorySeparatorChar, AltDirectorySeparatorChar ) );
 
97
 
 
98
                        for( int index = 0; index < parts.Count; )
 
99
                        {
 
100
                                string part = parts[index];
 
101
                
 
102
                                switch( part )
 
103
                                {
 
104
                                        case ".":
 
105
                                                parts.RemoveAt( index );
 
106
                                                break;
 
107
                                
 
108
                                        case "..":
 
109
                                                parts.RemoveAt( index );
 
110
                                                if ( index > 0 )
 
111
                                                        parts.RemoveAt( --index );
 
112
                                                break;
 
113
                                        default:
 
114
                                                index++;
 
115
                                                break;
 
116
                                }
 
117
                        }
 
118
        
 
119
                        return String.Join( DirectorySeparatorChar.ToString(), parts.ToArray() );
 
120
                }
 
121
 
 
122
                /// <summary>
 
123
                /// True if the two paths are the same. However, two paths
 
124
                /// to the same file or directory using different network
 
125
                /// shares or drive letters are not treated as equal.
 
126
                /// </summary>
 
127
                public static bool SamePath( string path1, string path2 )
 
128
                {
 
129
                        return string.Compare( Canonicalize(path1), Canonicalize(path2), PathUtils.IsWindows() ) == 0;
 
130
                }
 
131
 
 
132
                /// <summary>
 
133
                /// True if the two paths are the same or if the second is
 
134
                /// directly or indirectly under the first. Note that paths 
 
135
                /// using different network shares or drive letters are 
 
136
                /// considered unrelated, even if they end up referencing
 
137
                /// the same subtrees in the file system.
 
138
                /// </summary>
 
139
                public static bool SamePathOrUnder( string path1, string path2 )
 
140
                {
 
141
                        path1 = Canonicalize( path1 );
 
142
                        path2 = Canonicalize( path2 );
 
143
 
 
144
                        int length1 = path1.Length;
 
145
                        int length2 = path2.Length;
 
146
 
 
147
                        // if path1 is longer, then path2 can't be under it
 
148
                        if ( length1 > length2 )
 
149
                                return false;
 
150
 
 
151
                        // if lengths are the same, check for equality
 
152
                        if ( length1 == length2 )
 
153
                                return string.Compare( path1, path2, IsWindows() ) == 0;
 
154
 
 
155
                        // path 2 is longer than path 1: see if initial parts match
 
156
                        if ( string.Compare( path1, path2.Substring( 0, length1 ), IsWindows() ) != 0 )
 
157
                                return false;
 
158
                        
 
159
                        // must match through or up to a directory separator boundary
 
160
                        return  path2[length1-1] == DirectorySeparatorChar ||
 
161
                                path2[length1] == DirectorySeparatorChar;
 
162
                }
 
163
 
 
164
                public static string Combine( string path1, params string[] morePaths )
 
165
                {
 
166
                        string result = path1;
 
167
                        foreach( string path in morePaths )
 
168
                                result = Path.Combine( result, path );
 
169
                        return result;
 
170
                }
 
171
 
 
172
                // TODO: This logic should be in shared source
 
173
                public static string GetAssemblyPath( Assembly assembly )
 
174
                {
 
175
                        string uri = assembly.CodeBase;
 
176
 
 
177
                        // If it wasn't loaded locally, use the Location
 
178
                        if ( !uri.StartsWith( Uri.UriSchemeFile ) )
 
179
                                return assembly.Location;
 
180
 
 
181
                        return GetAssemblyPathFromFileUri( uri );
 
182
                }
 
183
 
 
184
                // Separate method for testability
 
185
                public static string GetAssemblyPathFromFileUri( string uri )
 
186
                {
 
187
                        // Skip over the file://
 
188
                        int start = Uri.UriSchemeFile.Length + Uri.SchemeDelimiter.Length;
 
189
                        
 
190
                        if ( PathUtils.DirectorySeparatorChar == '\\' )
 
191
                        {
 
192
                                if ( uri[start] == '/' && uri[start+2] == ':' )
 
193
                                        ++start;
 
194
                        }
 
195
                        else
 
196
                        {
 
197
                                if ( uri[start] != '/' )
 
198
                                        --start;
 
199
                        }
 
200
 
 
201
                        return uri.Substring( start );
 
202
                }
 
203
                #endregion
 
204
 
 
205
                #region Helper Methods
 
206
 
 
207
                private static bool IsWindows()
 
208
                {
 
209
                        return PathUtils.DirectorySeparatorChar == '\\';
 
210
                }
 
211
 
 
212
        private static string[] SplitPath(string path)
 
213
        {
 
214
            char[] separators = new char[] { PathUtils.DirectorySeparatorChar, PathUtils.AltDirectorySeparatorChar };
 
215
 
 
216
#if CLR_2_0 || CLR_4_0
 
217
            return path.Split(separators, StringSplitOptions.RemoveEmptyEntries);
 
218
#else
 
219
            string[] trialSplit = path.Split(separators);
 
220
            
 
221
            int emptyEntries = 0;
 
222
            foreach(string piece in trialSplit)
 
223
                if (piece == string.Empty)
 
224
                    emptyEntries++;
 
225
 
 
226
            if (emptyEntries == 0)
 
227
                return trialSplit;
 
228
 
 
229
            string[] finalSplit = new string[trialSplit.Length - emptyEntries];
 
230
            int index = 0;
 
231
            foreach(string piece in trialSplit)
 
232
                if (piece != string.Empty)
 
233
                    finalSplit[index++] = piece;
 
234
 
 
235
            return finalSplit;
 
236
#endif
 
237
        }
 
238
 
 
239
        private static bool PathsEqual(string path1, string path2)
 
240
        {
 
241
#if CLR_2_0 || CLR_4_0
 
242
            if (PathUtils.IsWindows())
 
243
                return path1.Equals(path2, StringComparison.InvariantCultureIgnoreCase);
 
244
            else
 
245
                return path1.Equals(path2, StringComparison.InvariantCulture);
 
246
#else
 
247
            if (PathUtils.IsWindows())
 
248
                return path1.ToLower().Equals(path2.ToLower());
 
249
            else
 
250
                return path1.Equals(path2);
 
251
#endif
 
252
        }
 
253
 
 
254
        #endregion
 
255
        }
 
256
}