summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2013-06-21 23:56:07 +0000
committerMike Frysinger <vapier@gentoo.org>2013-06-21 23:56:07 +0000
commit17cd52180551a00cfd57ea216b868e50f12ee23f (patch)
tree87df475673135eb4a4d762d7d55da41f8b9ae432
parentisdigit: new func for testing if args are all numbers (diff)
downloadgentoo-2-17cd52180551a00cfd57ea216b868e50f12ee23f.tar.gz
gentoo-2-17cd52180551a00cfd57ea216b868e50f12ee23f.tar.bz2
gentoo-2-17cd52180551a00cfd57ea216b868e50f12ee23f.zip
evar_push/evar_pop: new api for saving/restoring variables on a stack
-rw-r--r--eclass/eutils.eclass73
-rwxr-xr-xeclass/tests/eutils:evar.sh97
2 files changed, 169 insertions, 1 deletions
diff --git a/eclass/eutils.eclass b/eclass/eutils.eclass
index 31a501897908..4adbccd23bf7 100644
--- a/eclass/eutils.eclass
+++ b/eclass/eutils.eclass
@@ -1,6 +1,6 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.422 2013/06/21 23:52:50 vapier Exp $
+# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.423 2013/06/21 23:56:06 vapier Exp $
# @ECLASS: eutils.eclass
# @MAINTAINER:
@@ -146,6 +146,77 @@ estack_pop() {
eval unset ${__estack_name}\[${__estack_i}\]
}
+# @FUNCTION: evar_push
+# @USAGE: <variable to save> [more vars to save]
+# @DESCRIPTION:
+# This let's you temporarily modify a variable and then restore it (including
+# set vs unset semantics). Arrays are not supported at this time.
+#
+# This is meant for variables where using `local` does not work (such as
+# exported variables, or only temporarily changing things in a func).
+#
+# For example:
+# @CODE
+# evar_push LC_ALL
+# export LC_ALL=C
+# ... do some stuff that needs LC_ALL=C set ...
+# evar_pop
+#
+# # You can also save/restore more than one var at a time
+# evar_push BUTTERFLY IN THE SKY
+# ... do stuff with the vars ...
+# evar_pop # This restores just one var, SKY
+# ... do more stuff ...
+# evar_pop 3 # This pops the remaining 3 vars
+# @CODE
+evar_push() {
+ local var val
+ for var ; do
+ [[ ${!var+set} == "set" ]] \
+ && val=${!var} \
+ || val="${___ECLASS_ONCE_EUTILS}"
+ estack_push evar "${var}" "${val}"
+ done
+}
+
+# @FUNCTION: evar_push_set
+# @USAGE: <variable to save> [new value to store]
+# @DESCRIPTION:
+# This is a handy shortcut to save and temporarily set a variable. If a value
+# is not specified, the var will be unset.
+evar_push_set() {
+ local var=$1
+ evar_push ${var}
+ case $# in
+ 1) unset ${var} ;;
+ 2) printf -v "${var}" '%s' "$2" ;;
+ *) die "${FUNCNAME}: incorrect # of args: $*" ;;
+ esac
+}
+
+# @FUNCTION: evar_pop
+# @USAGE: [number of vars to restore]
+# @DESCRIPTION:
+# Restore the variables to the state saved with the corresponding
+# evar_push call. See that function for more details.
+evar_pop() {
+ local cnt=${1:-bad}
+ case $# in
+ 0) cnt=1 ;;
+ 1) isdigit "${cnt}" || die "${FUNCNAME}: first arg must be a number: $*" ;;
+ *) die "${FUNCNAME}: only accepts one arg: $*" ;;
+ esac
+
+ local var val
+ while (( cnt-- )) ; do
+ estack_pop evar val || die "${FUNCNAME}: unbalanced push"
+ estack_pop evar var || die "${FUNCNAME}: unbalanced push"
+ [[ ${val} == "${___ECLASS_ONCE_EUTILS}" ]] \
+ && unset ${var} \
+ || printf -v "${var}" '%s' "${val}"
+ done
+}
+
# @FUNCTION: eshopts_push
# @USAGE: [options to `set` or `shopt`]
# @DESCRIPTION:
diff --git a/eclass/tests/eutils:evar.sh b/eclass/tests/eutils:evar.sh
new file mode 100755
index 000000000000..837818de6730
--- /dev/null
+++ b/eclass/tests/eutils:evar.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+
+source tests-common.sh
+
+inherit eutils
+
+tbegin "simple push/pop"
+VAR=1
+evar_push VAR
+pu=$?
+VAR=2
+evar_pop
+po=$?
+[[ ${pu}${po}${VAR} == "001" ]]
+tend $?
+
+tbegin "unset push/pop"
+unset VAR
+evar_push VAR
+pu=$?
+VAR=2
+evar_pop
+po=$?
+[[ ${pu}${po}${VAR+set} == "00" ]]
+tend $?
+
+tbegin "empty push/pop"
+VAR=
+evar_push VAR
+pu=$?
+VAR=2
+evar_pop
+po=$?
+[[ ${pu}${po}${VAR+set}${VAR} == "00set" ]]
+tend $?
+
+tbegin "export push/pop"
+export VAR=exported
+evar_push VAR
+pu=$?
+VAR=2
+evar_pop
+po=$?
+var=$(bash -c 'echo ${VAR}')
+[[ ${pu}${po}${var} == "00exported" ]]
+tend $?
+
+tbegin "unexport push/pop"
+unset VAR
+VAR=not-exported
+evar_push VAR
+pu=$?
+VAR=2
+evar_pop
+po=$?
+var=$(bash -c 'echo ${VAR+set}')
+[[ ${pu}${po}${VAR}${var} == "00not-exported" ]]
+tend $?
+
+tbegin "multi push/pop"
+A=a B=b C=c
+evar_push A B C
+pu=$?
+A=A B=B C=C
+evar_pop 1
+po1=$?
+[[ ${A}${B}${C} == "ABc" ]]
+po2=$?
+evar_pop 2
+po3=$?
+var=$(bash -c 'echo ${VAR+set}')
+[[ ${pu}${po1}${po2}${po3}${A}${B}${C} == "0000abc" ]]
+tend $?
+
+tbegin "simple push_set/pop"
+VAR=1
+evar_push_set VAR 2
+pu=$?
+[[ ${VAR} == "2" ]]
+po1=$?
+evar_pop
+po2=$?
+[[ ${pu}${po1}${po2}${VAR} == "0001" ]]
+tend $?
+
+tbegin "unset push_set/pop"
+VAR=1
+evar_push_set VAR
+pu=$?
+[[ ${VAR+set} != "set" ]]
+po1=$?
+evar_pop
+po2=$?
+[[ ${pu}${po1}${po2}${VAR} == "0001" ]]
+tend $?
+
+texit