/// <summary> /// Takes an absolute path and attempts to convert it to a relative, based on the system, /// or global base if no system is supplied, if it is not a subfolder of the base, it will return the path unaltered /// </summary> public static string TryMakeRelative(this PathEntryCollection collection, string absolutePath, string system = null) { var parentPath = string.IsNullOrWhiteSpace(system) ? collection.GlobalBaseAbsolutePath() : collection.AbsolutePathFor(collection.BaseFor(system), system); #if true if (!absolutePath.IsSubfolderOf(parentPath)) { return(absolutePath); } return(OSTailoredCode.IsUnixHost ? "./" + OSTailoredCode.SimpleSubshell("realpath", $"--relative-to=\"{parentPath}\" \"{absolutePath}\"", $"invalid path {absolutePath} or missing realpath binary") : absolutePath.Replace(parentPath, ".")); #else // written for Unix port but may be useful for .NET Core if (!IsSubfolder(parentPath, absolutePath)) { return(OSTailoredCode.IsUnixHost && parentPath.TrimEnd('.') == $"{absolutePath}/" ? "." : absolutePath); } return(OSTailoredCode.IsUnixHost ? absolutePath.Replace(parentPath.TrimEnd('.'), "./") : absolutePath.Replace(parentPath, ".")); #endif }
private static string AbsolutePathForInner(this PathEntryCollection collection, string path, string systemId) { // Hack if (systemId == "Global") { systemId = null; } // This function translates relative path and special identifiers in absolute paths if (path.Length < 1) { return(collection.GlobalBaseAbsolutePath()); } if (path == "%recent%") { return(Environment.SpecialFolder.Recent.ToString()); } if (path.StartsWith("%exe%")) { return(PathUtils.ExeDirectoryPath + path.Substring(5)); } if (path.StartsWith("%rom%")) { return(collection.LastRomPath + path.Substring(5)); } if (path[0] == '.') { if (!string.IsNullOrWhiteSpace(systemId)) { path = path.Remove(0, 1); path = path.Insert(0, collection.BaseFor(systemId)); } if (path.Length == 1) { return(collection.GlobalBaseAbsolutePath()); } if (path[0] == '.') { path = path.Remove(0, 1); path = path.Insert(0, collection.GlobalBaseAbsolutePath()); } return(path); } if (Path.IsPathRooted(path)) { return(path); } //handling of initial .. was removed (Path.GetFullPath can handle it) //handling of file:// or file:\\ was removed (can Path.GetFullPath handle it? not sure) // all bad paths default to EXE return(PathUtils.ExeDirectoryPath); }
/// <summary> /// Takes an absolute path and attempts to convert it to a relative, based on the system, /// or global base if no system is supplied, if it is not a subfolder of the base, it will return the path unaltered /// </summary> public static string TryMakeRelative(this PathEntryCollection collection, string absolutePath, string system = null) => absolutePath.MakeRelativeTo( string.IsNullOrWhiteSpace(system) ? collection.GlobalBaseAbsolutePath() : collection.AbsolutePathFor(collection.BaseFor(system), system) );