Environment overhaul.
[profile.git] / .profile.d / PATH.bashrc
1 # Path information is stored on separate lines in XXXdirs.
2 # We check each directory exists and add it to the appropriate PATH.
3 # Prepend paths with XXXdirs.pre.  They are guaranteed to precede other paths.
4 # Append paths with XXXdirs.post.  They are not guaranteed to follow others.
5 # Set per-OS files in $SYSTEM[/$ARCHITECTURE] subdirectories of $DIR.
6 #
7
8 # Location of the XXXdirs files.
9 DIR="$HOME/.PATH"
10
11 # Paths to set and the file to get them from @variable to copy from.
12 PATHS="
13 PATH:bindirs
14 C_INCLUDE_PATH:incdirs
15 CPLUS_INCLUDE_PATH:@C_INCLUDE_PATH
16 LD_LIBRARY_PATH:libdirs
17 LD_RUN_PATH:@PATH
18 MANPATH:mandirs
19 PKG_CONFIG_PATH:pkgdirs
20 "
21
22 function sanitisepath() {
23   local paths="${@//:/ }"
24   local sane
25
26   for path in $paths; do
27     paths="${paths## }"
28     paths="${paths%% }"
29     paths="${paths#$path} "
30     if [ "${sane/:$path:/}" = "$sane" ]; then
31       sane="$sane:$path:"
32     fi
33   done
34
35   sane="${sane//::/:}"
36   sane="${sane#:}"
37   sane="${sane%:}"
38
39   echo "$sane"
40 }
41
42 # Set one path to be the same as another.
43 function copypath() {
44   local newpath="$1"; shift
45   local oldpath="$1"; shift
46
47   # Sanitise and export.
48   local path="$(eval echo \$$oldpath)"
49   [ -z "$path" ] || eval "export $newpath='$path'"
50 }
51
52 # Set a path from directories.
53 function makepath() {
54   local newpath="$1"; shift
55   local dirs="$1"; shift
56
57   # Set IFS to newline only so that we can read $(embedded shell commands).
58   local JGD=$IFS
59   IFS='
60 '
61   # Read them.
62   local path=
63   while read dir; do
64     local dir=$(eval echo "$dir")
65     [ -d "$dir" ] || continue
66
67     path="$path:$dir"
68   done < "$dirs"
69
70   # Restore IFS.
71   IFS=$JGD
72
73   # Are we setting, prepending or appending?
74   local existing="$(eval echo \$$newpath)"
75   dirs="${dirs##*/}"
76   local where="${dirs##*.}"
77   case "$where" in
78     "$dirs") ;;
79     pre) path="$path:$existing";;
80     post) path="$existing:$path";;
81     *) return;;
82   esac
83
84   # Sanitise path.
85   path=$(sanitisepath "$path")
86   [ -z "$path" ] && return
87
88   # Export.
89   eval "export $newpath='$path'"
90 }
91
92 # Construct directory list, omitting nonexistent and undefined ones.
93 dirs=
94 for dir in ${SYSTEM:-#}/${ARCHITECTURE:-#} ${SYSTEM:-} ""; do
95   [ "${dir/#/}" = "$dir" ] || continue
96   [ -d "$DIR/$dir" ] || continue
97   dirs="$dirs,$DIR/$dir"
98   dirs="${dirs%%/}"
99 done
100 dirs="${dirs##,}"
101 [ "${dirs/,/}" = "$dirs" ] || dirs="{$dirs}"
102
103 for path in $PATHS; do
104   var="${path%:*}"
105   source="${path#*:}"
106
107   if [ "${source#@}" = "$source" ]; then
108     for dir in $(eval echo $dirs/$source{,.pre,.post}); do
109       [ -e "$dir" ] || continue
110       makepath "$var" "$dir"
111     done
112   else
113     copypath "$var" "${source#@}"
114   fi
115 done
116
117
118 unset DIR PATHS dir dirs path var source sanitisepath copypath makepath newpath setpaths