# Path information is stored on separate lines in XXXdirs.
-# We extract each directory exists and add it to the appropriate PATH.
+# 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="$HOME/.profile.d"
+DIR="$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
+LD_RUN_PATH:@PATH
+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() {
- newpath="$1"; shift
- oldpath="$1"; shift
+ local newpath="$1"; shift
+ local oldpath="$1"; shift
# Sanitise and export.
- path="$(eval echo \$$oldpath)"
+ local path="$(eval echo \$$oldpath)"
[ -z "$path" ] || eval "export $newpath='$path'"
-
- unset path newpath oldpath
}
# Set a path from directories.
function makepath() {
- newpath="$1"; shift
- dirs="$1"; shift
-
- # Check the file exists.
- [ -e "$DIR/$dirs" ] || return
+ local newpath="$1"; shift
+ local dirs="$1"; shift
# Set IFS to newline only so that we can read $(embedded shell commands).
- JGD=$IFS
+ local JGD=$IFS
IFS='
'
# Read them.
- path=
+ local path=
while read dir; do
- dir=$(eval echo "$dir")
+ local dir=$(eval echo "$dir")
[ -d "$dir" ] || continue
path="$path:$dir"
- done < "$DIR/$dirs"
- unset dir
+ done < "$dirs"
# Restore IFS.
IFS=$JGD
- unset 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=${path#:}
+ path=$(sanitisepath "$path")
[ -z "$path" ] && return
# Export.
eval "export $newpath='$path'"
-
- unset path newpath dirs
}
-makepath PATH bindirs
-makepath C_INCLUDE_PATH incdirs
-copypath CPLUS_INCLUDE_PATH C_INCLUDE_PATH
-makepath LD_LIBRARY_PATH libdirs
-copypath LD_RUN_PATH PATH
-makepath MANPATH mandirs
-makepath PKG_CONFIG_PATH pkgdirs
+# 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
+ else
+ copypath "$var" "${source#@}"
+ fi
+done
+
-unset dirs copypath makepath newpath
+unset DIR PATHS dir dirs path var source sanitisepath copypath makepath newpath setpaths