#!/bin/sh
# $Id: pof,v 0.3 1997/05/25 21:59:03 jpeek Exp $
### pof, puf, lsf, clrf, pof1, pof2, ..., pof8: manipulate MH folder stacks
### Usages:
###     pof             (does: folder -pop)
###     puf [+folder]   (does: folder -push [+folder])
###     lsf             (does: folder -list)
###     clrf            (clears the folder stack by popping repeatedly)
###     pof1            (pops first folder off stack)
###       ...                 ...etc...
###     pof8            (pops eighth folder off stack)
##
##  Most of these links to the script are easy to understand.
##  For instance, "pof" pops the top of the stack and makes it the current
##  folder (replacing the current folder).
##  The links "pof1" thru "pof8" take a little explaining.
##  Like "pof" they pop a folder from the stack, but they pop from
##  anywhere along the stack, and the popped folder does NOT become the
##  current directory.  They're similar to the shell directory-stack
##  commands like "popd +2", which removes the second directory from the
##  stack without changing the current directory.
# 
#                             NO WARRANTY
# 
#   BECAUSE THIS PROGRAM IS AVAILABLE FREE OF CHARGE, THERE IS NO WARRANTY
# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
# REPAIR OR CORRECTION.
# 
#   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGES.


# Can't use arguments like "+2" because they look like folder names,
# so we take the pop location from the command name.  For example,
#   pof   =   folder -pop
#   pof1  =   folder -pop "+1"
#   pof2  =   folder -pop "+2"

# When you install the pof file, make links to clrf, lsf, puf, and pof[2-8].

#                             NO WARRANTY
# 
#   BECAUSE THIS PROGRAM IS AVAILABLE FREE OF CHARGE, THERE IS NO WARRANTY
# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
# REPAIR OR CORRECTION.
# 
#   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGES.


myname=`basename $0` || exit 1

case "$myname" in
lsf)
    # List the folder stack:
    folder -list
    exit
    ;;
clrf)
    # Clear the folder stack by popping until it returns non-zero
    # (when the stack is probably empty):
    while folder -pop >/dev/null
    do :
    done
    exit
    ;;
puf)
    # Push a folder on top of stack.  (We don't have puf1, puf2, etc.)
    # Don't quote the command-line arguments; if none, this swaps top entry.
    # ${1+"$@"} works around a quoting problem in some older shells.
    folder -push ${1+"$@"}
    exit
    ;;
pof)
    # Pop a folder off the front of the stack.  No arguments needed:
    case $# in
    0)  folder -pop; exit;;
    *)  echo "$myname quitting: invalid command-line argument(s): $*" 1>&2
        exit 1
        ;;
    esac
    ;;
# The next cases look like kludges, but they're for shell efficiency
# because they avoid using expr (which isn't built in, so it's slow):
pof1) stop_at=1 levels="1" ;;
pof2) stop_at=2 levels="1 2" ;;
pof3) stop_at=3 levels="1 2 3" ;;
pof4) stop_at=4 levels="1 2 3 4" ;;
pof5) stop_at=5 levels="1 2 3 4 5" ;;
pof6) stop_at=6 levels="1 2 3 4 5 6" ;;
pof7) stop_at=7 levels="1 2 3 4 5 6 7" ;;
pof8) stop_at=8 levels="1 2 3 4 5 6 7 8" ;;
*)  echo "$0 quitting: I don't know how to run myself!" 1>&2; exit 1;;
esac

# If we get here, we need to do some popping and pushing.
to_push=    # list of folders we'll be pushing back on the stack

# Store folder stack "on command line" and be sure it's deep enough.
# ("x" ensures >= 1 argument.  This keeps "set" from listing all variables.)
# $depth has total number folders on stack (doesn't count the current folder).
# Notice that the $1 set here is used in the first pass thru the loop below.
set x `folder -list`; shift
depth=`expr $# - 1`
if [ $# -le $stop_at ]
then
    echo "$myname: folder stack isn't deep enough to pop item #$stop_at." 1>&2
    exit 1
fi

# Pop the folders we want to save.  At the end of this loop,
# the current folder will be the one we want to get rid of:
for level in $levels
do
    # Grab the first folder name (from previous run of "folder")
    # before popping it off.  If we're popping the whole stack,
    # we'll need to replace the final current folder with last on
    # stack; in this case, save the last popped folder in $top_save:
    if [ $level -lt $depth ]
    then to_push="$1 $to_push"
    else top_save="$1"
    fi
    # (Again, use "set" to parse and save folder names; this is efficient.)
    set x `folder -pop` || exit 1
    shift
done

# Pop off the folder we want to toss -- unless we've popped
# everything off the stack by this point, in which case we replace
# the remaining folder (the one we wanted to pop) with the first folder
# to be pushed back.  In any case, don't show folder stack as we do this.
if [ $# -eq 1 ]
then folder -fast "+$top_save" >/dev/null || exit 1
else folder -pop >/dev/null || exit 1
fi

# Push back the folders we saved:
for fol in $to_push
do set x `folder -push "+$fol"` || exit 1
done
# show final folder stack without using a process for "folder -list"
shift; echo "$*"
