mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
Previously, if the common ancestor of the two paths is / we would print the absolute second argument, but this PR asks for a relative path in that case as well, which makes sense for the libstdc++.modules.json use case. PR libstdc++/119081 contrib/ChangeLog: * relpath.sh: Give relative path even at /.
82 lines
1.5 KiB
Bash
Executable File
82 lines
1.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
if [ "$1" = "--help" -o $# -ne 2 -o -f "$1" ]; then
|
|
echo Usage: relpath.sh FROM TO
|
|
echo Print the relative path from FROM to TO
|
|
echo FROM must be a directory, but need not exist
|
|
exit 0
|
|
fi
|
|
|
|
from="${1%%/}"
|
|
to="${2%%/}"
|
|
|
|
# The parent directory of a pathname, handling ..
|
|
parent() {
|
|
name=$(basename "$1")
|
|
path=$(dirname "$1")
|
|
top=$(basename "$path")
|
|
if [ "$top" = ".." ]; then
|
|
path=$(parent "$path")
|
|
fi
|
|
if [ "$name" = ".." ]; then
|
|
path=$(parent "$path")
|
|
fi
|
|
echo $path
|
|
}
|
|
|
|
# Canonicalize a directory that contains '..'.
|
|
canonicalize() {
|
|
path=$1
|
|
suffix=
|
|
while ! [ -d "$path" ]; do
|
|
name=$(basename "$path")
|
|
path=$(parent "$path")
|
|
suffix="/$name$suffix"
|
|
done
|
|
if [ -d "$path" ]; then
|
|
echo $(cd "$path"; pwd)$suffix
|
|
else
|
|
echo $1
|
|
fi
|
|
}
|
|
|
|
case "$to$from" in
|
|
*..* )
|
|
from=$(canonicalize "$from")
|
|
to=$(canonicalize "$to")
|
|
;;
|
|
esac
|
|
case "$to$from" in
|
|
*..* )
|
|
echo unable to canonicalize .. >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
back=
|
|
while [ "${to#$from}" = "$to" ]; do
|
|
#echo $from too long
|
|
from=$(dirname $from);
|
|
back=../$back
|
|
|
|
if [ "$from" = / ] && [ "${to#/}" = "$to" ]; then
|
|
echo no common ancestor between $1 and $2 >&2
|
|
exit 1
|
|
elif [ "$from" = . ]; then
|
|
echo no common ancestor between $1 and $2 >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
to=${to#$from}
|
|
to=${to##/}
|
|
back=${back%%/}
|
|
|
|
if [ -n "$to" ] && [ -n "$back" ]; then
|
|
echo $back/$to
|
|
elif [ -n "$back$to" ]; then
|
|
echo $back$to
|
|
else
|
|
echo .
|
|
fi
|