# Path information is stored on separate lines in XXXdirs. # We check each directory exists and add it to the appropriate PATH. # Prepend paths with XXXdirs.pre. They are guaranteed to precede other paths. # Append paths with XXXdirs.post. They are not guaranteed to follow others. # Set per-OS files in $SYSTEM[/$ARCHITECTURE] subdirectories of $DIR. # # Location of the XXXdirs files. DIR=${PROFILE_HOME:-~}/.PATH # Paths to set and the file to get them from @variable to copy from. PATHS=" PATH:bindirs C_INCLUDE_PATH:incdirs CPLUS_INCLUDE_PATH:@C_INCLUDE_PATH LD_LIBRARY_PATH:libdirs MANPATH:mandirs PKG_CONFIG_PATH:pkgdirs " function sanitisepath() { local paths="${@//:/ }" local sane for path in $paths; do paths="${paths## }" paths="${paths%% }" paths="${paths#$path} " if [ "${sane/:$path:/}" = "$sane" ]; then sane="$sane:$path:" fi done sane="${sane//::/:}" sane="${sane#:}" sane="${sane%:}" echo "$sane" } # Set one path to be the same as another. function copypath() { local newpath="$1"; shift local oldpath="$1"; shift # Sanitise and export. local path="$(eval echo \$$oldpath)" [ -z "$path" ] || eval "export $newpath='$path'" } # Try to expand variables in a path definition, discarding it if expansion fails. function expandpath() { local path="$1"; shift while [ -n "$path" ]; do [ "${path/\$/}" = "$path" ] && return 0 path="${path#*\$}" local var="${path%%/*}" eval "[ -n \"\$$var\" ] || return 1" done return 0 } # Helper. function addpath() { local path="$1"; shift local dir="$1"; shift if ! expandpath "$dir"; then echo "$path" else dir=$(eval echo "$dir") if [ -d "$dir" ]; then echo "$path:$dir" else echo "$path" fi fi } # Set a path from directories. function makepath() { local newpath="$1"; shift local dirs="$1"; shift # Set IFS to newline only so that we can read $(embedded shell commands). local JGD=$IFS IFS=' ' # Read them. local path= while read dir; do path=$(addpath "$path" "$dir") if [ -n "$PROFILE_HOME" -a ! "${dir#\$HOME}" = "$dir" ]; then dir="$PROFILE_HOME${dir#\$HOME}" path=$(addpath "$path" "$dir") fi done < "$dirs" # Restore IFS. IFS=$JGD # Are we setting, prepending or appending? local existing="$(eval echo \$$newpath)" dirs="${dirs##*/}" local where="${dirs##*.}" case "$where" in "$dirs") ;; pre) path="$path:$existing";; post) path="$existing:$path";; *) return;; esac # Sanitise path. path=$(sanitisepath "$path") [ -z "$path" ] && return # Export. eval "export $newpath='$path'" } # Remove entries which are symlinks to other existing entries. function canonicalisepath() { local path="$1"; shift local newpath= local JGD=$IFS IFS=' ' local dirs=$(eval echo "\$$path") local check=":$dirs:" for dir in ${dirs//:/ }; do if [ -L "$dir" ]; then # Is this a symlink to another entry? local canon=$(readlink -f "$dir" 2>/dev/null) if [ -n "$canon" ]; then [ "${check/:$canon:/}" = "$check" ] || continue fi fi newpath="$newpath:$dir" done IFS=$JGD eval "export $path='${newpath##:}'" } # Construct directory list, omitting nonexistent and undefined ones. dirs= for dir in "${SYSTEM:-@}/${ARCHITECTURE:-@}" "${SYSTEM:-@}" ""; do [ "${dir/@/}" = "$dir" ] || continue [ -d "$DIR/$dir" ] || continue dirs="$dirs,$DIR/$dir" dirs="${dirs%%/}" done dirs="${dirs##,}" [ "${dirs/,/}" = "$dirs" ] || dirs="{$dirs}" for path in $PATHS; do var="${path%:*}" source="${path#*:}" if [ "${source#@}" = "$source" ]; then for dir in $(eval echo $dirs/$source{,.pre,.post}); do [ -e "$dir" ] || continue makepath "$var" "$dir" done canonicalisepath "$var" else copypath "$var" "${source#@}" fi done unset DIR PATHS dir dirs path var source expandpath sanitisepath copypath makepath newpath addpath canonicalisepath