Remove absolute paths from ts.
[profile.git] / .profile.d / PATH.bashrc
index 1a271aa..ab57aaa 100644 (file)
-# $Id$
-#
 # 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)"
-  [ -z "$path" ] || eval export $newpath="$path"
-
-  unset path newpath oldpath
+  local path="$(eval echo \$$oldpath)"
+  [ -z "$path" ] || eval "export $newpath='$path'"
 }
 
 # 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).
+  local JGD=$IFS
+  IFS='
+'
   # Read them.
-  path=
-  for dir in $(cat "$DIR/$dirs"); do
-    dir=$(eval echo "$dir")
+  local path=
+  while read dir; do
+    local dir=$(eval echo "$dir")
     [ -d "$dir" ] || continue
 
     path="$path:$dir"
-  done
-  unset dir
+  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=${path#:}
+  path=$(sanitisepath "$path")
   [ -z "$path" ] && return
 
   # Export.
-  eval export $newpath="$path"
-
-  unset path newpath dirs
+  eval "export $newpath='$path'"
 }
 
-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