aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Harder <radhermit@gmail.com>2015-07-08 03:29:35 -0400
committerTim Harder <radhermit@gmail.com>2015-07-08 20:09:02 -0400
commite3ab174814370874f65d335ef47fe07fa1fcf088 (patch)
tree2d326647809b9475ce43da73334d3b7f39f67f7d
parentbash: generalize internal error messages (diff)
downloadpkgcore-e3ab174814370874f65d335ef47fe07fa1fcf088.tar.gz
pkgcore-e3ab174814370874f65d335ef47fe07fa1fcf088.tar.bz2
pkgcore-e3ab174814370874f65d335ef47fe07fa1fcf088.zip
bash: add initial var push/pop support
Fixes #17.
-rw-r--r--bash/dont_export_funcs.list2
-rw-r--r--bash/isolated-functions.lib64
2 files changed, 66 insertions, 0 deletions
diff --git a/bash/dont_export_funcs.list b/bash/dont_export_funcs.list
index d217ee92..d611c101 100644
--- a/bash/dont_export_funcs.list
+++ b/bash/dont_export_funcs.list
@@ -118,3 +118,5 @@ __shopt_push
__source_bashrcs
__strip_duplicate_slashes
__timed_call
+__var_pop
+__var_push
diff --git a/bash/isolated-functions.lib b/bash/isolated-functions.lib
index 6152a689..57c96d41 100644
--- a/bash/isolated-functions.lib
+++ b/bash/isolated-functions.lib
@@ -204,6 +204,70 @@ __IFS_pop() {
:
}
+declare -a PKGCORE_VAR_STACK
+
+__var_push() {
+ [[ $# -eq 0 ]] && die "${FUNCNAME}: invoked with no arguments"
+
+ local arg var orig_val
+ for arg in "$@"; do
+ var=${arg%%=*}
+
+ # If the specified variable currently has a value we save it;
+ # otherwise, just push the variable name onto the stack.
+ if orig_val=$(declare -p ${var} 2>/dev/null); then
+ # We can't directly use the declare version because that forces
+ # scope to be localized to the function resetting the values.
+ #
+ # Posix mode needed so set only lists defined variables and not
+ # functions too.
+ __shopt_push -o posix
+ orig_val=$(set | grep "^${var}=")
+ __shopt_pop
+ else
+ orig_val=${var}
+ fi
+
+ # toss the current value
+ unset ${var} 2>/dev/null || die "${FUNCNAME}: '${var}' is readonly"
+
+ # export a new value if one was specified
+ if [[ ${arg} == *=* ]]; then
+ export "${arg}" || die "${FUNCNAME}: failed to export '${arg}'"
+ fi
+
+ PKGCORE_VAR_STACK[${#PKGCORE_VAR_STACK[@]}]=${orig_val}
+ done
+}
+
+__var_pop() {
+ [[ ${#PKGCORE_VAR_STACK[@]} -gt 0 ]] \
+ || die "${FUNCNAME}: invoked with nothing on the stack"
+
+ local count=$1
+ case $# in
+ 0) count=1;;
+ 1) [[ ${count} == *[!0-9]* ]] && die "${FUNCNAME}: arg must be a number: $*";;
+ *) die "${FUNCNAME}: only accepts one arg: $*";;
+ esac
+
+ local var arg
+ while (( count-- )); do
+ arg=${PKGCORE_VAR_STACK[$(( ${#PKGCORE_VAR_STACK[@]} - 1 ))]}
+ var=${arg%%=*}
+
+ # unset the variable on the top of the stack
+ unset ${var} 2>/dev/null || die "${FUNCNAME}: '${var}' is readonly"
+
+ # reset its value if one was stored
+ if [[ ${arg} == *=* ]]; then
+ export "${arg}" || die "${FUNCNAME}: failed to export '${arg}'"
+ fi
+
+ unset PKGCORE_VAR_STACK[$(( ${#PKGCORE_VAR_STACK[@]} - 1 ))]
+ done
+}
+
__qa_invoke() {
if ${PKGCORE_QA_SUPPRESSED:-false}; then
"$@"