diff options
author | Mike Frysinger <vapier@gentoo.org> | 2013-06-21 23:56:07 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2013-06-21 23:56:07 +0000 |
commit | 17cd52180551a00cfd57ea216b868e50f12ee23f (patch) | |
tree | 87df475673135eb4a4d762d7d55da41f8b9ae432 | |
parent | isdigit: new func for testing if args are all numbers (diff) | |
download | gentoo-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.eclass | 73 | ||||
-rwxr-xr-x | eclass/tests/eutils:evar.sh | 97 |
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 |