xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/fun/popd (revision b30d1939)
1da2e3ebdSchin#
2da2e3ebdSchin# DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS
3da2e3ebdSchin#
4da2e3ebdSchin# Uses global parameters _push_max _push_top _push_stack
5da2e3ebdSchininteger _push_max=100 _push_top=100
6da2e3ebdSchin# Display directory stack -- $HOME displayed as ~
7da2e3ebdSchinfunction dirs
8da2e3ebdSchin{
9da2e3ebdSchin    typeset dir="${PWD#$HOME/}"
10da2e3ebdSchin    case $dir in
11da2e3ebdSchin    $HOME)
12da2e3ebdSchin        dir=\~
13da2e3ebdSchin        ;;
14da2e3ebdSchin    /*) ;;
15da2e3ebdSchin    *)  dir=\~/$dir
16da2e3ebdSchin    esac
17da2e3ebdSchin    print -r - "$dir ${_push_stack[@]}"
18da2e3ebdSchin}
19da2e3ebdSchin
20da2e3ebdSchin# Change directory and put directory on front of stack
21da2e3ebdSchinfunction pushd
22da2e3ebdSchin{
23da2e3ebdSchin    typeset dir= type=0
24da2e3ebdSchin    integer i
25da2e3ebdSchin    case $1 in
26da2e3ebdSchin    "") # pushd
27da2e3ebdSchin        if    ((_push_top >= _push_max))
28da2e3ebdSchin        then  print pushd: No other directory.
29da2e3ebdSchin              return 1
30da2e3ebdSchin        fi
31da2e3ebdSchin        type=1 dir=${_push_stack[_push_top]}
32da2e3ebdSchin        ;;
33da2e3ebdSchin    +[1-9]|+[1-9][0-9]) # pushd +n
34da2e3ebdSchin        integer i=_push_top$1-1
35da2e3ebdSchin        if    ((i >= _push_max))
36da2e3ebdSchin        then  print pushd: Directory stack not that deep.
37da2e3ebdSchin              return 1
38da2e3ebdSchin        fi
39da2e3ebdSchin        type=2 dir=${_push_stack[i]}
40da2e3ebdSchin        ;;
41da2e3ebdSchin    *)  if    ((_push_top <= 0))
42da2e3ebdSchin        then  print pushd: Directory stack overflow.
43da2e3ebdSchin              return 1
44da2e3ebdSchin        fi
45da2e3ebdSchin    esac
46da2e3ebdSchin    case $dir in
47da2e3ebdSchin    \~*)   dir=$HOME${dir#\~}
48da2e3ebdSchin    esac
49da2e3ebdSchin    cd "${dir:-$1}" > /dev/null || return 1
50da2e3ebdSchin    dir=${OLDPWD#$HOME/}
51da2e3ebdSchin    case $dir in
52da2e3ebdSchin    $HOME)
53da2e3ebdSchin        dir=\~
54da2e3ebdSchin        ;;
55da2e3ebdSchin    /*) ;;
56da2e3ebdSchin    *)  dir=\~/$dir
57da2e3ebdSchin    esac
58da2e3ebdSchin    case $type in
59da2e3ebdSchin    0)  # pushd name
60da2e3ebdSchin        _push_stack[_push_top=_push_top-1]=$dir
61da2e3ebdSchin        ;;
62da2e3ebdSchin    1)  # pushd
63da2e3ebdSchin        _push_stack[_push_top]=$dir
64da2e3ebdSchin        ;;
65da2e3ebdSchin    2)  # push +n
66da2e3ebdSchin        type=${1#+} i=_push_top-1
67da2e3ebdSchin        set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}"
68da2e3ebdSchin        shift $type
69da2e3ebdSchin        for dir
70da2e3ebdSchin        do  (((i=i+1) < _push_max)) || break
71da2e3ebdSchin            _push_stack[i]=$dir
72da2e3ebdSchin        done
73da2e3ebdSchin    esac
74da2e3ebdSchin    dirs
75da2e3ebdSchin}
76da2e3ebdSchin
77da2e3ebdSchin# Pops the top directory
78da2e3ebdSchinfunction popd
79da2e3ebdSchin{
80da2e3ebdSchin    typeset dir
81da2e3ebdSchin    if    ((_push_top >= _push_max))
82da2e3ebdSchin    then  print popd: Nothing to pop.
83da2e3ebdSchin          return 1
84da2e3ebdSchin    fi
85da2e3ebdSchin    case $1 in
86da2e3ebdSchin    "")
87da2e3ebdSchin        dir=${_push_stack[_push_top]}
88da2e3ebdSchin        case $dir in
89da2e3ebdSchin        \~*)   dir=$HOME${dir#\~}
90da2e3ebdSchin        esac
91da2e3ebdSchin        cd "$dir" || return 1
92da2e3ebdSchin        ;;
93da2e3ebdSchin    +[1-9]|+[1-9][0-9])
94da2e3ebdSchin        typeset savedir
95da2e3ebdSchin        integer i=_push_top$1-1
96da2e3ebdSchin        if    ((i >= _push_max))
97da2e3ebdSchin        then  print pushd: Directory stack not that deep.
98da2e3ebdSchin              return 1
99da2e3ebdSchin        fi
100da2e3ebdSchin        while ((i > _push_top))
101da2e3ebdSchin        do _push_stack[i]=${_push_stack[i-1]}
102da2e3ebdSchin              i=i-1
103da2e3ebdSchin        done
104da2e3ebdSchin        ;;
105da2e3ebdSchin    *)  print pushd: Bad directory.
106da2e3ebdSchin        return 1
107da2e3ebdSchin    esac
108da2e3ebdSchin    unset '_push_stack[_push_top]'
109da2e3ebdSchin    _push_top=_push_top+1
110da2e3ebdSchin    dirs
111da2e3ebdSchin}
112