Try to line up tab header with columns.
[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=${PROFILE_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 MANPATH:mandirs
18 PKG_CONFIG_PATH:pkgdirs
19 "
20
21 function sanitisepath() {
22   local paths="${@//:/ }"
23   local sane
24
25   for path in $paths; do
26     paths="${paths## }"
27     paths="${paths%% }"
28     paths="${paths#$path} "
29     if [ "${sane/:$path:/}" = "$sane" ]; then
30       sane="$sane:$path:"
31     fi
32   done
33
34   sane="${sane//::/:}"
35   sane="${sane#:}"
36   sane="${sane%:}"
37
38   echo "$sane"
39 }
40
41 # Set one path to be the same as another.
42 function copypath() {
43   local newpath="$1"; shift
44   local oldpath="$1"; shift
45
46   # Sanitise and export.
47   local path="$(eval echo \$$oldpath)"
48   [ -z "$path" ] || eval "export $newpath='$path'"
49 }
50
51 # Try to expand variables in a path definition, discarding it if expansion fails.
52 function expandpath() {
53   local path="$1"; shift
54
55   while [ -n "$path" ]; do
56     [ "${path/\$/}" = "$path" ] && return 0
57     path="${path#*\$}"
58
59     local var="${path%%/*}"
60     eval "[ -n \"\$$var\" ] || return 1"
61   done
62
63   return 0
64 }
65
66 # Helper.
67 function addpath() {
68   local path="$1"; shift
69   local dir="$1"; shift
70
71   if ! expandpath "$dir"; then
72     echo "$path"
73   else
74     dir=$(eval echo "$dir")
75     if [ -d "$dir" ]; then
76       echo "$path:$dir"
77     else
78       echo "$path"
79     fi
80   fi
81 }
82
83 # Set a path from directories.
84 function makepath() {
85   local newpath="$1"; shift
86   local dirs="$1"; shift
87
88   # Set IFS to newline only so that we can read $(embedded shell commands).
89   local JGD=$IFS
90   IFS='
91 '
92   # Read them.
93   local path=
94   while read dir; do
95     path=$(addpath "$path" "$dir")
96     if [ -n "$PROFILE_HOME" -a ! "${dir#\$HOME}" = "$dir" ]; then
97       dir="$PROFILE_HOME${dir#\$HOME}"
98       path=$(addpath "$path" "$dir")
99     fi
100   done < "$dirs"
101
102   # Restore IFS.
103   IFS=$JGD
104
105   # Are we setting, prepending or appending?
106   local existing="$(eval echo \$$newpath)"
107   dirs="${dirs##*/}"
108   local where="${dirs##*.}"
109   case "$where" in
110     "$dirs") ;;
111     pre) path="$path:$existing";;
112     post) path="$existing:$path";;
113     *) return;;
114   esac
115
116   # Sanitise path.
117   path=$(sanitisepath "$path")
118   [ -z "$path" ] && return
119
120   # Export.
121   eval "export $newpath='$path'"
122 }
123
124 # Remove entries which are symlinks to other existing entries.
125 function canonicalisepath() {
126   local path="$1"; shift
127   local newpath=
128
129   local JGD=$IFS
130   IFS='
131 '
132
133   local dirs=$(eval echo "\$$path")
134   local check=":$dirs:"
135   for dir in ${dirs//:/
136 }; do
137     if [ -L "$dir" ]; then
138       # Is this a symlink to another entry?
139       local canon=$(readlink -f "$dir" 2>/dev/null)
140       if [ -n "$canon" ]; then
141         [ "${check/:$canon:/}" = "$check" ] || continue
142       fi
143     fi
144
145     newpath="$newpath:$dir"
146   done
147
148   IFS=$JGD
149
150   eval "export $path='${newpath##:}'"
151 }
152
153 # Construct directory list, omitting nonexistent and undefined ones.
154 dirs=
155 for dir in "${SYSTEM:-@}/${ARCHITECTURE:-@}" "${SYSTEM:-@}" ""; do
156   [ "${dir/@/}" = "$dir" ] || continue
157   [ -d "$DIR/$dir" ] || continue
158   dirs="$dirs,$DIR/$dir"
159   dirs="${dirs%%/}"
160 done
161 dirs="${dirs##,}"
162 [ "${dirs/,/}" = "$dirs" ] || dirs="{$dirs}"
163
164 for path in $PATHS; do
165   var="${path%:*}"
166   source="${path#*:}"
167
168   if [ "${source#@}" = "$source" ]; then
169     for dir in $(eval echo $dirs/$source{,.pre,.post}); do
170       [ -e "$dir" ] || continue
171       makepath "$var" "$dir"
172     done
173     canonicalisepath "$var"
174   else
175     copypath "$var" "${source#@}"
176   fi
177 done
178
179 unset DIR PATHS dir dirs path var source expandpath sanitisepath copypath makepath newpath addpath canonicalisepath