summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Xu (Hello71) <alex_y_xu@yahoo.ca>2022-03-06 12:58:06 -0500
committerAlex Xu (Hello71) <alex_y_xu@yahoo.ca>2022-03-06 12:58:06 -0500
commitc41b93e768014e2a3d3d6376b78e790333451076 (patch)
tree7acc5206e79c84755b5ef0e598c10688073bfc4a
parent6638e53935ee1c5f3bfb23c08bd2aae2994b6219 (diff)
downloadnextbin-c41b93e768014e2a3d3d6376b78e790333451076.tar.xz
nextbin-c41b93e768014e2a3d3d6376b78e790333451076.zip
simplify algorithm
-rwxr-xr-xnextbin91
1 files changed, 20 insertions, 71 deletions
diff --git a/nextbin b/nextbin
index fd8faa5..31241ef 100755
--- a/nextbin
+++ b/nextbin
@@ -23,81 +23,30 @@ orig_exe=$1
shift
exe_name=${orig_exe##*/}
-[ -n "$PATH" ] || die 'PATH is empty'
-
-case "$orig_exe" in
- */)
- die 'ends with /'
- ;;
-
- */*)
- orig_dir=${orig_exe%/*}
- ;;
-
- *)
- # either shell has not resolved script-file into a path, or script is
- # in cwd and PATH has . or empty entries
- if ! [ -d "$orig_exe" ] && [ -x "$orig_exe" ]; then
- case ":$PATH:" in
- *::*:.:*|*:.:*::*)
- die 'exe in cwd and PATH has both . and empty entries'
- ;;
+case ":$PATH:" in
+ ::) die 'empty PATH not supported' ;;
+ *:[!/]*) die 'relative PATH elements not supported' ;;
+ *:*/./*:*|*:*/../*:*) die 'PATH elements containing . or .. not supported' ;;
+esac
- *::*)
- orig_dir=
- ;;
+case $orig_exe in
+ # theoretically this could be optimized but it's negligible cost
+ */*) orig_dir=$(cd -L "${orig_exe%/*}" && pwd -L) ;;
+ *) orig_dir=$PWD ;;
+esac
- *:.:*)
- orig_dir=.
- ;;
+# clean up path. theoretically we could allow e.g. PATH=/dir://dir but which
+# would we match for cd /dir; ./exe
+tmp_path=$(printf '%s\n' ":$PATH:" | sed -e 's|/*:|:|g' -e 's|//|/|g')
- *)
- die 'missing /'
- esac
- fi
+case $tmp_path in
+ *:$orig_dir:$orig_dir:*|*:$orig_dir:*:$orig_dir:*)
+ die 'duplicate entry in PATH: %s' "$orig_dir"
esac
-tmp_path=:$PATH:
-new_path=${tmp_path#*:$orig_dir:}
-[ -n "$new_path" ] \
- || die '%s is last PATH entry' "$orig_dir"
-if [ "$new_path" != "$tmp_path" ]; then
- new_path_2=${new_path#*:$orig_dir:}
- [ "$new_path" = "$new_path_2" ] \
- || die 'duplicate entry in PATH: %s' \
- "$orig_exe" "$orig_dir"
-else
- # try to find equivalent path
- found_alt_dir=
- new_orig_dir=
- equiv_orig_dir=$(cd "${orig_dir:-.}" && pwd -L)
- tmp_path_2=$PATH
- while :; do
- p=${tmp_path_2%%:*}
- if [ "$(cd "$p" >/dev/null 2>&1 && pwd -L)" = "$equiv_orig_dir" ]; then
- [ -z "$found_alt_dir" ] \
- || die "duplicate equivalent path in PATH: '%s' = '%s'" \
- "$new_orig_dir" "$p"
- found_alt_dir=1
- new_orig_dir=$p
- fi
- case "$tmp_path_2" in
- *:*) tmp_path_2=${tmp_path_2#*:};;
- *) break
- esac
- done
- if [ -n "$found_alt_dir" ]; then
- new_path=${tmp_path#*:$new_orig_dir:}
- [ -n "$new_path" ] \
- || die '%s is last PATH entry' "$new_orig_dir"
- else
- new_path=$PATH:
- fi
-fi
-
-exe=$(PATH="${new_path%:}" command -v "$exe_name") || true
-[ -n "$exe" ] \
- || die 'PATH lookup failed using %s' \
- "${new_path%:}"
+new_path=${tmp_path#*":$orig_dir:"}
+new_path=${new_path%:}
+exe=$(PATH="$new_path" command -v "$exe_name") || true
+[ -n "$exe" ] || die 'PATH lookup failed using %s' "$new_path"
$action "$exe" "$@"