# Copyright (c) 1991, 1993
#       The Regents of the University of California.  All rights reserved.
# Copyright (c) 1997-2005
#       Herbert Xu <herbert@gondor.apana.org.au>.  All rights reserved.
# Copyright (c) 2021
#       Vladimir Oleynik <dzo@simtreas.ru>
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW
#
# rewrote by Vladimir Oleynik for dash (required version minimum 0.5.11):
#  *  allow spaces (but not \n) and metacharacters in dirs
#  *  use tilda if possible
#  *  accept -c -l -n -p -v options, check the number of support arguments
#  *  use stderr for put errors
#  *  do not out extra space by dirs()
#  *  check corrupt of the global variable $DSTACK

_PUSHD_POPD_DIRS_='
_pushd_popd_dirs_(){
	local d o v=-1 sep=" " cd=1 h=~ cr="
"
	OPTIND=1        # reusage
	while getopts ":$opts" o; do
		case "$o" in
		 c) DSTACK=; return 0;;
		 l) h=;;
		 n) cd=;;
		 p) sep=$cr;;
		 v) sep=$cr; v=0;;
		 *) echo "$c: invalid option -$OPTARG" >&2; return 2;;
		esac
	done
	shift $((OPTIND-1))
	if [ $c != pushd -a $# -ne 0 ]; then
		echo "$c: unsupport arguments" >&2
		return 2
	fi
	if [ $c = pushd -a $# -gt 1 ]; then
		echo "$c: too many arguments" >&2
		return 2
	fi
	if [ $c != dirs ]; then
		if [ -z "$1" ]; then
			if [ -z "$DSTACK" ]; then
				echo "$c: directory stack empty" >&2
				return 1
			fi
			d=${DSTACK%%$cr*}
			if [ -z "$d" -o "x$d" = "x$DSTACK" ]; then
				echo "$c: \$DSTACK corrupted" >&2
				return 3
			fi
			DSTACK=${DSTACK#"$d$cr"}
		fi
		d=${1:-$d}
		[ "$cd" ] && { cd "$d" || return; [ $c = pushd ] && d=$oldpwd; }
		[ $c = pushd ] && DSTACK="${d}${cr}${DSTACK}"
	fi
	o=
	while IFS=$cr read -r d; do
		[ -n "$h" -a "(" "x$h" = "x$d" -o "x${d#"$h/"}" != "x$d" ")" ] && d="~${d#"$h"}"
		[ $v -ge 0 ] && { d=$(printf "%2d  %s" $v "$d"); v=$((v+1)); }
		o="${o}${o:+$sep}${d}"
	done << EOF
$(pwd)${DSTACK:+$cr}${DSTACK%$cr}
EOF
	echo -n "$o$cr" # it the trick, echo "$o" may be silently for o="-e"

	_pushd_popd_dirs_() { :; }
}'

pushd() {
	eval "$_PUSHD_POPD_DIRS_" || return
	oldpwd=$(pwd) opts=n c=pushd  _pushd_popd_dirs_ "$@"
}

popd() {
	eval "$_PUSHD_POPD_DIRS_" || return
	opts=n    c=popd  _pushd_popd_dirs_ "$@"
}

dirs() {
	eval "$_PUSHD_POPD_DIRS_" || return
	opts=clpv c=dirs  _pushd_popd_dirs_ "$@"
}
