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