Files
gcc/contrib/relpath.sh
Jason Merrill 90f5dabddb contrib: relpath.sh /lib /include [PR119081]
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 /.
2025-03-12 11:23:59 -04:00

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