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