On Sat, 2006-01-28 at 18:15 -0800, Charlie Poole wrote: > Hi Jonathan, > I'll write a test. :-) > > > PathRelativePathTo: this variation on your > > PathUtils.RelativePath works for me (minimally tested): > > This looks too simple to work, but I'll try it. ;-)
Attached is a better version, complete with test cases. The previous function was Unix-native -- it didn't care about drives or other such things that I found in PathUtilTests.cs. The attached version is a little smarter, though it means we can't use the same input strings on both Unix and Windows for testing -- we need platform-specific tests. :-( - Jon
// PathRelativePathTo: using System; using System.IO; using System.Text; /* The relative path is relative from: c:\a\b\path The relative path is relative to: c:\a\x\y\file The relative path is: ..\..\x\y\file */ class Test { static string RelativePath (string from, string to) { if (from == null) throw new ArgumentNullException (from); if (to == null) throw new ArgumentNullException (to); if (!Path.IsPathRooted (to)) return to; if (Path.GetPathRoot (from) != Path.GetPathRoot (to)) return null; string[] _from = from.Split (Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); string[] _to = to.Split (Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); StringBuilder sb = new StringBuilder (Math.Max (from.Length, to.Length)); int last_common, min = Math.Min (_from.Length, _to.Length); for (last_common = 0; last_common < min; ++last_common) { if (!_from [last_common].Equals (_to [last_common])) break; } if (last_common < _from.Length) sb.Append (".."); for (int i = last_common + 1; i < _from.Length; ++i) { sb.Append (Path.DirectorySeparatorChar).Append (".."); } if (sb.Length > 0) sb.Append (Path.DirectorySeparatorChar); if (last_common < _to.Length) sb.Append (_to [last_common]); for (int i = last_common + 1; i < _to.Length; ++i) { sb.Append (Path.DirectorySeparatorChar).Append (_to [i]); } return sb.ToString (); } static void Check (string a, string b) { Console.WriteLine ("\t{0,5}: \"{1}\" == \"{2}\"", a == b, a, b); } public static void Main (string[] args) { Console.WriteLine ("Unix"); Check ("folder2/folder3", RelativePath ("/folder1", "/folder1/folder2/folder3")); Check ("../folder2/folder3", RelativePath ("/folder1", "/folder2/folder3")); Check ("bin/debug", RelativePath ("/folder1", "bin/debug")); Check ("../../d", RelativePath ("/a/b/c", "/a/d")); Console.WriteLine ("Windows"); Check (@"folder2\folder3", RelativePath (@"C:\folder1", @"C:\folder1\folder2\folder3")); Check (@"..\folder2\folder3", RelativePath (@"C:\folder1", @"C:\folder2\folder3")); Check (@"bin\debug", RelativePath (@"C:\folder1", @"bin\debug")); Check (null, RelativePath (@"C:\folder", @"D:\folder")); Check (@"folder2\folder3", RelativePath (@"C:/folder1", @"C:/folder1/folder2/folder3")); Check (@"..\folder2\folder3", RelativePath (@"C:/folder1", @"C:/folder2/folder3")); Check (@"bin/debug", RelativePath (@"C:/folder1", @"bin/debug")); Check (null, RelativePath (@"C:/folder", @"D:/folder")); if (args.Length >= 2) { Console.WriteLine ("from: " + args[0]); Console.WriteLine (" to: " + args[1]); Console.WriteLine (" rel: " + RelativePath (args [0], args [1])); } } }
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list