here's v2 -mike --- eutils.eclass 22 May 2013 05:10:29 -0000 1.421 +++ eutils.eclass 17 Jun 2013 05:41:58 -0000 @@ -146,6 +146,79 @@ estack_pop() { eval unset ${__estack_name}\[${__estack_i}\] } +# @FUNCTION: evar_push +# @USAGE: [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: [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} ;; + # Can't use `printf -v` as that does not set $var when $2 is "". + 2) eval ${var}=\$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" + # Can't use `printf -v` as that does not set $var when $2 is "". + [[ ${val} == "${___ECLASS_ONCE_EUTILS}" ]] \ + && unset ${var} \ + || eval ${var}=\${val} + done +} + # @FUNCTION: eshopts_push # @USAGE: [options to `set` or `shopt`] # @DESCRIPTION: @@ -218,6 +291,18 @@ eumask_pop() { umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}" } +# @FUNCTION: isdigit +# @USAGE: [more numbers] +# @DESCRIPTION: +# Return true if all arguments are numbers. +isdigit() { + local d + for d ; do + [[ ${d:-bad} == *[!0-9]* ]] && return 1 + done + return 0 +} + # @VARIABLE: EPATCH_SOURCE # @DESCRIPTION: # Default directory to search for patches. @@ -344,8 +429,11 @@ epatch() { local EPATCH_SUFFIX=$1 elif [[ -d $1 ]] ; then - # Some people like to make dirs of patches w/out suffixes (vim) + # We have to force sorting to C so that the wildcard expansion is consistent #471666. + evar_push_set LC_COLLATE C + # Some people like to make dirs of patches w/out suffixes (vim). set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"} + evar_pop elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then # Re-use EPATCH_SOURCE as a search dir