Previously, for source=/a/b/c/d target=/a/bb/c/d it would return ../..b/c/d instead of ../../../bb/c/d
104 lines
3.0 KiB
Diff
104 lines
3.0 KiB
Diff
From 42b6dd4293e07ef53dccc006e576e8b9f40614e6 Mon Sep 17 00:00:00 2001
|
|
From: Ray Donnelly <mingw.android@gmail.com>
|
|
Date: Sat, 12 Apr 2014 15:57:20 +0100
|
|
Subject: [PATCH 1/6] functions: Add CT_FindRelativePath
|
|
|
|
.. needed for Windows due to it lacking a single
|
|
hierarchy filesystem.
|
|
---
|
|
scripts/functions | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 81 insertions(+)
|
|
|
|
diff --git a/scripts/functions b/scripts/functions
|
|
index a309f2d..60a6793 100644
|
|
--- a/scripts/functions
|
|
+++ b/scripts/functions
|
|
@@ -1396,3 +1396,84 @@ CT_DoLoadState(){
|
|
exec >>"${tmp_log_file}"
|
|
rm -f "${state_dir}/tail.log"
|
|
}
|
|
+
|
|
+# Based on https://github.com/Offirmo/offirmo-shell-lib/blob/master/bin/osl_lib_file.sh
|
|
+# .. modified to work with Dash.
|
|
+
|
|
+# both $1 and $2 are absolute paths beginning with /
|
|
+# returns relative path to $2/$target from $1/$source
|
|
+CT_FindRelativePath()
|
|
+{
|
|
+ local insource=$1
|
|
+ local intarget=$2
|
|
+
|
|
+ # Ensure both source and target end with /
|
|
+ # This simplifies the inner loop.
|
|
+ #echo "insource : \"$insource\""
|
|
+ #echo "intarget : \"$intarget\""
|
|
+ case "$insource" in
|
|
+ */) ;;
|
|
+ *) source="$insource"/ ;;
|
|
+ esac
|
|
+
|
|
+ case "$intarget" in
|
|
+ */) ;;
|
|
+ *) target="$intarget"/ ;;
|
|
+ esac
|
|
+
|
|
+ #echo "source : \"$source\""
|
|
+ #echo "target : \"$target\""
|
|
+
|
|
+ local common_part=$source # for now
|
|
+
|
|
+ local result=""
|
|
+
|
|
+ #echo "common_part is now : \"$common_part\""
|
|
+ #echo "result is now : \"$result\""
|
|
+ #echo "target#common_part : \"${target#$common_part}\""
|
|
+ while [ "${target#$common_part}" = "${target}" -a "${common_part}" != "//" ]; do
|
|
+ # no match, means that candidate common part is not correct
|
|
+ # go up one level (reduce common part)
|
|
+ common_part="$(dirname $common_part)"/
|
|
+ # and record that we went back
|
|
+ if [ -z "${result}" ]; then
|
|
+ result="../"
|
|
+ else
|
|
+ result="../$result"
|
|
+ fi
|
|
+ #echo "(w) common_part is now : \"$common_part\""
|
|
+ #echo "(w) result is now : \"$result\""
|
|
+ #echo "(w) target#common_part : \"${target#$common_part}\""
|
|
+ done
|
|
+
|
|
+ #echo "(f) common_part is : \"$common_part\""
|
|
+
|
|
+ if [ "${common_part}" = "//" ]; then
|
|
+ # special case for root (no common path)
|
|
+ common_part="/"
|
|
+ fi
|
|
+
|
|
+ # since we now have identified the common part,
|
|
+ # compute the non-common part
|
|
+ forward_part="${target#$common_part}"
|
|
+ #echo "forward_part = \"$forward_part\""
|
|
+
|
|
+ if [ -n "${result}" -a -n "${forward_part}" ]; then
|
|
+ #echo "(simple concat)"
|
|
+ result="$result$forward_part"
|
|
+ elif [ -n "${forward_part}" ]; then
|
|
+ result="$forward_part"
|
|
+ fi
|
|
+ #echo "result = \"$result\""
|
|
+
|
|
+ # if a / was added to target and result ends in / then remove it now.
|
|
+ if [ "$intarget" != "$target" ]; then
|
|
+ case "$result" in
|
|
+ */) result=$(echo "$result" | awk '{ string=substr($0, 1, length($0)-1); print string; }' ) ;;
|
|
+ esac
|
|
+ fi
|
|
+
|
|
+ echo $result
|
|
+
|
|
+ return 0
|
|
+}
|
|
--
|
|
2.2.1
|
|
|