[gnu.bash.bug] complex functions

beckerd@grover.cs.unc.edu (David Becker) (01/24/90)

I have a script from a friend that gives cd a history in ksh.  I've
found it handier than CDPATH.  Anyways bash barfs.

In particular it doesn't take the typedef flags which isn't too big a
deal but it also won't swallow ((i=cdlen)).  The double parentheses cause a
syntax error.

Should in its present incarnation handle this stuff(ie there's a bug) or
is bash not up to these functions yet?   The texinfo on bash shell
scripts didn't say much.

The first syntax error occurs on line 38 at the ((
#
# CD History function originally by Shane McCaron
# external shell variables
#	CDHISTFILE - where you want the history kept
#

alias cd=_cd

function _cd
{
	typeset -i cdlen i
	typeset t

	if [ $# -eq 0 ]
	then
		set -- $HOME
	fi

	if [ "$CDHISTFILE" -a -r "$CDHISTFILE" ] # if directory history exists
	then
		typeset CDHIST
		i=-1
		while read -r t			# read directory history file
		do
			CDHIST[i=i+1]=$t
		done <$CDHISTFILE
	fi

	if [ "${CDHIST[0]}" != "$PWD" -a "$PWD" != "" ]
	then
		_cdins				# insert $PWD into cd history
	fi

	cdlen=${#CDHIST[*]}			# number of elements in history

	case "$@" in
	-)					# cd to new dir
		if [ "$OLDPWD" = "" ] && ((cdlen>1))  # SYNTAX HERE from BASH
		then
			print ${CDHIST[1]}
			'cd' ${CDHIST[1]}
		else
			'cd' $@
		fi
		;;
	-l)					# print directory list
		typeset -R3 num
		((i=cdlen))
		while (((i=i-1)>=0))
		do
			num=$i
			print "$num ${CDHIST[i]}"
		done
		return
		;;
	-[0-9]|-[0-9][0-9])			# cd to dir in list
		if (((i=${1#-})<cdlen))
		then
			print ${CDHIST[i]}
			'cd' ${CDHIST[i]}
		else
			'cd' $@
		fi
		;;
	-*)					# cd to matched dir in list
		t=${1#-}
		i=1
		while ((i<cdlen))
		do
			case ${CDHIST[i]} in
			*$t*)
				print ${CDHIST[i]}
				'cd' ${CDHIST[i]}
				break
				;;
			esac
			((i=i+1))
		done
		if ((i>=cdlen))
		then
			'cd' $@
		fi
		;;
	*)					# cd to new dir
		'cd' $@
		;;
	esac


	_cdins					# insert $PWD into cd history

	if [ "$CDHISTFILE" ]
	then
		cdlen=${#CDHIST[*]}		# number of elements in history

		i=0
		while ((i<cdlen))
		do
			print -r ${CDHIST[i]}	# update directory history
			((i=i+1))
		done >$CDHISTFILE
	fi
#	set_prompt
	return 0
}

function _cdins					# insert $PWD into cd history
{						# meant to be called only by _cd
	typeset -i i

	((i=0))
	while ((i<${#CDHIST[*]}))		# see if dir is already in list
	do
		if [ "${CDHIST[$i]}" = "$PWD" ]
		then
			break
		fi
		((i=i+1))
	done

	if ((i>22))				# limit max size of list
	then
		i=22
	fi

	while (((i=i-1)>=0))			# bump old dirs in list
	do
		CDHIST[i+1]=${CDHIST[i]}
	done

	CDHIST[0]=$PWD				# insert new directory in list
}


David Becker  beckerd@cs.unc.edu

chet@cwns1.CWRU.EDU (Chet Ramey) (01/24/90)

In article <11606@thorin.cs.unc.edu> beckerd@grover.cs.unc.edu (David Becker) writes:

>In particular it doesn't take the typedef flags which isn't too big a
>deal but it also won't swallow ((i=cdlen)).  The double parentheses cause a
>syntax error.

Bash in its current incarnation has neither integer variables (the `typeset
-i' stuff) nor arithmetic expression evaluation (the `((...))' stuff).  It
doesn't have array variables, either.  I don't really know what Brian's
plans for this are, but I did write an expression evaluator and send it to
him.  I have put in integer variables, though not in a way that's really
satisfactory, and I haven't sent that code to Brian.

You could probably hack this stuff to use regular variables and
expr without too much trouble, or use pushd and popd.

Chet
-- 
Chet Ramey				"Can't you pay a grad student to 
Network Services Group			 read the manual for you?"
Case Western Reserve University			-- Bill Wisner,
chet@ins.CWRU.Edu				   	to Peter Honeyman