From c41b93e768014e2a3d3d6376b78e790333451076 Mon Sep 17 00:00:00 2001 From: "Alex Xu (Hello71)" Date: Sun, 6 Mar 2022 12:58:06 -0500 Subject: simplify algorithm --- nextbin | 91 +++++++++++++++-------------------------------------------------- 1 file changed, 20 insertions(+), 71 deletions(-) (limited to 'nextbin') 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" "$@" -- cgit v1.2.3-54-g00ecf