1#
2# .kshenv -- functions and aliases to provide the beginnings of a ksh 
3#	     environment for bash.
4#
5# Chet Ramey
6# chet@ins.CWRU.Edu
7#
8#
9# These are definitions for the ksh compiled-in `exported aliases'.  There
10# are others, but we already have substitutes for them: "history", "type",
11# and "hash".
12#
13alias r="fc -s"
14alias functions="typeset -f"
15alias integer="typeset -i"
16alias nohup="nohup "
17alias command="command "
18alias stop="kill -s STOP"
19alias redirect="command exec"
20alias hist="fc"
21
22#
23# An almost-ksh compatible `whence' command.  This is as hairy as it is 
24# because of the desire to exactly mimic ksh (whose behavior was determined
25# empirically).
26# 
27# This depends somewhat on knowing the format of the output of the bash
28# `builtin type' command.
29#
30
31whence()
32{
33	local vflag pflag fflag defarg c
34	local path
35
36	vflag= aflag= pflag= fflag=
37	path=
38	if [ "$#" = "0" ] ; then
39		echo "whence: usage: whence [-afpv] name..." >&2
40		return 2
41	fi
42
43	OPTIND=1
44	while getopts "avfp" c
45	do
46		case "$c" in
47		a) defarg=-a ;;
48		f) fflag=1 ;;	# no-op
49		p) pflag=1 ;;
50		v) vflag=1 ;;
51		?) echo "whence: $1: unknown option" >&2
52		   echo "whence: usage: whence [-afpv] name..." >&2
53		   return 2 ;;
54		esac
55	done
56
57	shift $(( $OPTIND - 1 ))
58
59	if [ "$#" = "0" ] ; then
60		echo "whence: usage: whence [-afpv] name..." >&2
61		return 2
62	fi
63
64	for cmd
65	do
66		if [ "$vflag" ]	 ; then
67			if [ -z "$defarg" ]; then
68				builtin type $cmd | sed 1q
69			else
70				if builtin type $defarg -t $cmd | grep 'function$' >/dev/null 2>&1; then
71					# HAIRY awk script to suppress
72					# printing of function body -- could
73					# do it with sed, but I don't have
74					# that kind of time
75					builtin type $defarg $cmd | awk '
76BEGIN {printit = 1;}
77$1 == "'$cmd'" && $2 == "()" {printit=0; next; }
78/^}$/ { if (printit == 0) printit=1 ; else print $0; next ; }
79/.*/ { if (printit) print $0; }'
80				else
81					builtin type $defarg $cmd
82				fi
83			fi
84		else
85			path=$(builtin type $defarg -p $cmd)
86			if [ "$path" ] ; then
87				echo $path
88			else
89				case "$cmd" in
90				/*) echo "" ;;
91				 *) case "$(builtin type -t $cmd)" in
92				    "") echo "" ;;
93				    *) echo "$cmd" ;;
94				    esac
95				    ;;
96				esac
97			fi
98		fi
99	done
100	return 0
101}
102
103#
104# For real ksh homeboy fanatics, redefine the `type' builtin with a ksh
105# version.
106#
107#type()
108#{
109#	whence -v "$*"
110#}
111
112#
113# ksh-like `cd': cd [-LP] [dir [change]]
114#
115cd()
116{
117	OPTIND=1
118	while getopts "LP" opt
119	do
120		case $opt in
121		L|P)	CDOPTS="$CDOPTS -$opt" ;;
122		*)	echo "$FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2
123			return 2;;
124		esac
125	done
126
127	shift $(( $OPTIND - 1 ))
128
129	case $# in
130	0)	builtin cd $CDOPTS "$HOME" ;;
131	1) 	builtin cd $CDOPTS "$@" ;;
132	2)	old="$1" new="$2"
133		case "$PWD" in
134		*$old*)	;;
135		*)	 echo "${0##*/}: $FUNCNAME: bad substitution" >&2 ; return 1 ;;
136		esac
137
138		dir=${PWD//$old/$new}
139
140		builtin cd $CDOPTS "$dir" && echo "$PWD"
141
142		;;
143	*)	echo "${0##*/}: $FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2
144		return 2 ;;
145	esac
146}
147
148#
149# ksh print emulation
150#
151#	print [-Rnprsu[n]] [-f format] [arg ...]
152#
153#	-	end of options
154#	-R	BSD-style -- only accept -n, no escapes
155#	-n	do not add trailing newline
156#	-p	no-op (no coprocesses)
157#	-r	no escapes
158#	-s	print to the history file
159#	-u n	redirect output to fd n
160#	-f format	printf "$format" "$@"
161#
162
163print()
164{
165	local eflag=-e
166	local nflag= fflag= c
167	local fd=1
168
169	OPTIND=1
170	while getopts "fRnprsu:" c
171	do
172		case $c in
173		R)	eflag= ;;
174		r)	eflag= ;;
175		n)	nflag=-n ;;
176		s)	sflag=y ;;
177		f)	fflag=y ;;
178		u)	fd=$OPTARG ;;
179		p)	;;
180		esac
181	done
182	shift $(( $OPTIND - 1 ))
183
184	if [ -n "$fflag" ]; then
185		builtin printf "$@" >&$fd
186		return
187	fi
188
189	case "$sflag" in
190	y)	builtin history -s "$*" ;;
191	*)	builtin echo $eflag $nflag "$@" >&$fd
192	esac
193}
194
195# substring function
196# this function should be equivalent to the substring built-in which was
197# eliminated after the 06/29/84 version
198substring ()
199{
200	local lpat flag str	#local variables
201	set -f
202	case $1 in
203	-l|-L)
204		flag=$1
205		lpat=$2
206		shift 2
207		;;
208	esac
209	# test for too few or too many arguments
210	if [ x"$1" = x ] || [ $# -gt 2 ]; then
211		print -u2 'substring: bad argument count'
212		return 1
213	fi
214	str=$1
215	if [ x"$flag" = x-l ]; then		#substring -l lpat
216		str=${str#$lpat}
217	elif [ x"$flag" = x-L ]; then
218		str=${str##$lpat}		#substring -L lpat
219	fi
220
221	if [ x"$2" != x ]; then
222		echo ${str%$2}
223	else
224		echo $str
225	fi
226
227	return 0
228}
229