diff --git a/lib/ulib/.ulibver b/lib/ulib/.ulibver index e1a1aeb..6892c87 100644 --- a/lib/ulib/.ulibver +++ b/lib/ulib/.ulibver @@ -1 +1 @@ -007009000 +007010000 diff --git a/lib/ulib/base b/lib/ulib/base index 0e0d3bd..250087f 100644 --- a/lib/ulib/base +++ b/lib/ulib/base @@ -811,6 +811,90 @@ function path_if_test() { shift done } +function update_link() { + # mettre à jour le lien $2 pour qu'il pointe vers le fichier $1 + [ -L "$2" ] || return 1 + local dest link="$2" + local linkdir="$(dirname "$link")" + local ldest="$(readlink "$link")" + if [ "${ldest#/}" != "$ldest" ]; then + # c'est un lien absolu, faire un lien absolu + dest="$(abspath "$1")" + else + # c'est un lien relatif, faire un lien relatif + dest="$(relpath "$1" "$linkdir")" + fi + if [ -d "$link" ]; then + rm -f "$link" && ln -s "$dest" "$link" + else + ln -sf "$dest" "$link" + fi +} +function move_link() { + # Déplacer le lien $1 vers $2, et mettre à jour la destination du lien si + # elle est exprimée de façon relative + # Si $1 n'est pas un lien, le déplacer normalement avec mv + [ -n "$1" -a -n "$2" ] || return 1 + local link="$1" dest="$2" + [ -d "$dest" ] && dest="$dest/$(basename -- "$link")" + if [ -L "$link" ]; then + link="$(abspath "$link")" + linkdir="$(dirname -- "$link")" + ldest="$(readlink "$link")" + ldest="$(abspath "$ldest" "$linkdir")" + mv "$link" "$dest" || return 1 + update_link "$ldest" "$dest" + else + mv "$link" "$dest" + fi +} +function array_find_links() { + # Chercher dans le répertoire $3 (qui est par défaut le répertoire courant) + # les liens vers le fichier $2, et ajouter leurs chemins absolus dans le + # tableau $1 + local -a __afl_links __afl_result + local __afl_dir="${3:-.}" + local __afl_dest __afl_destname __afl_link __afl_linkdir __afl_ldest + __afl_dest="$(abspath "$2")" + __afl_destname="${__afl_dest##*/}" + array_from_lines __afl_links "$(find "$__afl_dir" -type l)" + for __afl_link in "${__afl_links[@]}"; do + __afl_ldest="$(readlink "$__afl_link")" + # optimiser le calcul: pas besoin d'aller plus loin si les noms ne + # correspondent pas + if [ "$__afl_ldest" != "$__afl_destname" ]; then + [[ "$__afl_ldest" == */"$__afl_destname" ]] || continue + fi + # nous avons un candidate, tester si les chemins correspondent + __afl_link="$(abspath "$__afl_link" "$__afl_dir")" + __afl_linkdir="$(dirname -- "$__afl_link")" + __afl_ldest="$(abspath "$__afl_ldest" "$__afl_linkdir")" + if [ "$__afl_ldest" == "$__afl_dest" ]; then + array_add __afl_result "$__afl_link" + fi + done + array_copy "$1" __afl_result +} +function list_links() { + # Chercher dans le répertoire $2 les liens vers le fichier $1, et les + # afficher, un par ligne. + local -a links + array_find_links links "$@" + array_to_lines links +} +function move_file() { + # Déplacer le fichier $1 vers $2, et mettre à jour les liens $3..@ pour + # qu'ils pointent vers la nouvelle destination + [ -n "$1" -a -n "$2" ] || return 1 + local src="$1" dest="$2" link + shift; shift + [ -d "$dest" ] && dest="$dest/$(basename -- "$src")" + move_link "$src" "$dest" || return + for link in "$@"; do + update_link "$dest" "$link" + done + return 0 +} ################################################################################ ## utilitaires