Gentoo Archives: gentoo-dev

From: Mike Frysinger <vapier@g.o>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] new eshopts_{push,pop} functions
Date: Wed, 09 Dec 2009 10:02:45
Message-Id: 200912090341.38018.vapier@gentoo.org
i got tired of copying & pasting the shell option save/restore code, so i
created two helper functions.  am i missing anything before i add to
eutils.eclass ?  i could extend eshopts_pop to take a numeric argument for
number of stack entries to pop, but i dont see much value/use.

# @FUNCTION: eshopts_push
# @USAGE: [options to `set`]
# @DESCRIPTION:
# Often times code will want to enable a shell option to change code behavior.
# Since changing shell options can easily break other pieces of code (which
# assume the default state), eshopts_push is used to (1) push the current shell
# options onto a stack and (2) pass the specified arguments to set.
#
# A common example is to disable shell globbing so that special meaning/care
# may be used with variables/arguments to custom functions.  That would be:
# @CODE
#		eshopts_push -o noglob
#		for x in ${foo} ; do
#			if ...some check... ; then
#				eshopts_pop
#				return 0
#			fi
#		done
#		eshopts_pop
# @CODE
eshopts_push() {
	# have to assume __ESHOPTS_SAVE__ isn't screwed with
	# as a `declare -a` here will reset its value
	local i=${#__ESHOPTS_SAVE__[@]}
	__ESHOPTS_SAVE__[$i]=$-
	[[ $# -eq 0 ]] && return 0
	set "$@" || die "eshopts_push: bad options to set"
}

# @FUNCTION: eshopts_pop
# @USAGE:
# @DESCRIPTION:
# Restore the shell options to the state saved with the corresponding
# eshopts_push call.  See that function for more details.
eshopts_pop() {
	[[ $# -ne 0 ]] && die "eshopts_pop takes no arguments"
	local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 ))
	[[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
	local s=${__ESHOPTS_SAVE__[$i]}
	unset __ESHOPTS_SAVE__[$i]
	set +$-   || die "eshopts_pop: sanity: invalid shell settings !?"
	set -${s} || die "eshopts_pop: sanity: unable to restore saved shell settings"
}

and an example of new usage in eutils.eclass:

@@ -1343,16 +1363,15 @@ check_license() {
 
 	# here is where we check for the licenses the user already
 	# accepted ... if we don't find a match, we make the user accept
-	local shopts=$-
 	local alic
-	set -o noglob #so that bash doesn't expand "*"
+	eshopts_push -o noglob # so that bash doesn't expand "*"
 	for alic in ${ACCEPT_LICENSE} ; do
 		if [[ ${alic} == ${l} ]]; then
-			set +o noglob; set -${shopts} #reset old shell opts
+			eshopts_pop
 			return 0
 		fi
 	done
-	set +o noglob; set -$shopts #reset old shell opts
+	eshopts_pop
 
 	local licmsg=$(emktemp)
 	cat <<-EOF > ${licmsg}

-mike

Attachments

File name MIME type
signature.asc application/pgp-signature