[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mono-devel-list
Subject:    RE: SPAM-LOW:  Re: [Mono-dev] NUnit 2.2.6 Portability Bug
From:       Jonathan Pryor <jonpryor () vt ! edu>
Date:       2006-01-29 15:11:12
Message-ID: 1138547473.16136.3.camel () localhost ! localdomain
[Download RAW message or body]

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



["prpt.cs" (prpt.cs)]

// 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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic