--- path-manipulation.bash 2009-08-07 09:04:23.000000000 -0400 +++ path-manipulation-fixed.bash 2009-08-11 15:52:07.000000000 -0400 @@ -14,14 +14,90 @@ # You should have received a copy of the GNU General Public License along with # eselect. If not, see . -# basename wrapper +# basename function basename() { - echo "${1##*/}" + pstr=${1} + + #strip trailing slashes as long as they're there and we're not down to the + #string consisting of only a single slash + while [[ ${pstr:$(( ${#pstr} - 1 ))} == '/' && ${#pstr} > 1 ]]; do + pstr=${pstr%/} + done + + #do more processing if we don't have just a single slash + if [[ ${pstr} != '/' ]]; then + #strip everything before the last slash + pstr=${pstr##*/} + + #strip the optional suffix if present + [[ ${2} != ${pstr} ]] && pstr=${pstr%${2}} + fi + + echo "${pstr}" + + return 0 } -# dirname wrapper +# dirname function dirname() { - echo "${1%/*}" + pstr=${1} + + if [[ ${#pstr} == 0 ]]; then + #we return a '.' for the empty string + pstr='.' + + else + #strip trailing slashes + while [[ ${pstr:$(( ${#pstr} - 1 ))} == '/' && ${#pstr} > 1 ]]; do + pstr=${pstr%/} + done + + #only continue if we have more than a single slash + if [[ ${pstr} != '/' ]]; then + + #check for slashes in the string + str_has_dirsep ${pstr} + if [[ $? == 0 ]]; then + #strip non-slash characters + let lastind="${#pstr} - 1" + while [[ $lastind > 0 && ${pstr:$lastind} != '/' ]]; do + pstr=${pstr:0:$lastind} + let lastind="${#pstr} - 1" + done + + #strip slash characters + let lastind="${#pstr} - 1" + while [[ $lastind > 0 && ${pstr:$lastind} == '/' ]]; do + pstr=${pstr%/} + let lastind="${#pstr} - 1" + done + + else + #there are no slash characters, dirname is cwd + pstr='.' + fi + + fi + + fi + + echo ${pstr} +} + +#helper for dirname, returns 0 if the string contains a slash, 1 if not +str_has_dirsep() { + str=${1} + + iter=0 + while [ $iter -lt ${#str} ]; do + if [[ ${str:$iter:1} == '/' ]]; then + return 0 + fi + let iter++ + done + + #if we get here, there were no slashes + return 1 } canonicalise() {