From 43d85f96ab061fa7e52cf80cf431f62d256f541f Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Tue, 8 Aug 2017 14:09:04 +0200 Subject: [PATCH] Pmodules/libstd.bash - std::upvar(), std::upvars() added --- Pmodules/libstd.bash | 109 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/Pmodules/libstd.bash b/Pmodules/libstd.bash index 3f142bb..224dac5 100644 --- a/Pmodules/libstd.bash +++ b/Pmodules/libstd.bash @@ -133,6 +133,115 @@ std::read_versions() { done < "${fname}" } +#--- upvars.sh --------------------------------------------------------- +# Bash: Passing variables by reference +# Copyright (C) 2010 Freddy Vulto +# Version: upvars-0.9.dev +# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# Assign variable one scope above the caller +# Usage: local "$1" && upvar $1 "value(s)" +# Param: $1 Variable name to assign value to +# Param: $* Value(s) to assign. If multiple values, an array is +# assigned, otherwise a single value is assigned. +# NOTE: For assigning multiple variables, use 'upvars'. Do NOT +# use multiple 'upvar' calls, since one 'upvar' call might +# reassign a variable to be used by another 'upvar' call. +# Example: +# +# f() { local b; g b; echo $b; } +# g() { local "$1" && upvar $1 bar; } +# f # Ok: b=bar +# +std::upvar() { + if unset -v "$1"; then # Unset & validate varname + if (( $# == 2 )); then + eval $1=\"\$2\" # Return single value + else + eval $1=\(\"\${@:2}\"\) # Return array + fi + fi +} + + +# Assign variables one scope above the caller +# Usage: local varname [varname ...] && +# upvars [-v varname value] | [-aN varname [value ...]] ... +# Available OPTIONS: +# -aN Assign next N values to varname as array +# -v Assign single value to varname +# Return: 1 if error occurs +# Example: +# +# f() { local a b; g a b; declare -p a b; } +# g() { +# local c=( foo bar ) +# local "$1" "$2" && upvars -v $1 A -a${#c[@]} $2 "${c[@]}" +# } +# f # Ok: a=A, b=(foo bar) +# +std::upvars() { + if ! (( $# )); then + echo "${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname"\ + "value] | [-aN varname [value ...]] ..." 1>&2 + return 2 + fi + while (( $# )); do + case $1 in + -a*) + # Error checking + [[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\ + "number specifier" 1>&2; return 1; } + printf %d "${1#-a}" &> /dev/null || { echo "bash:"\ + "${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2 + return 1; } + # Assign array of -aN elements + [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) && + shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\ + "\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; } + ;; + -v) + # Assign single value + [[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" && + shift 3 || { echo "bash: ${FUNCNAME[0]}: $1: missing"\ + "argument(s)" 1>&2; return 1; } + ;; + --help) echo "\ +Usage: local varname [varname ...] && + ${FUNCNAME[0]} [-v varname value] | [-aN varname [value ...]] ... +Available OPTIONS: +-aN VARNAME [value ...] assign next N values to varname as array +-v VARNAME value assign single value to varname +--help display this help and exit +--version output version information and exit" + return 0 ;; + --version) echo "\ +${FUNCNAME[0]}-0.9.dev +Copyright (C) 2010 Freddy Vulto +License GPLv3+: GNU GPL version 3 or later +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law." + return 0 ;; + *) + echo "bash: ${FUNCNAME[0]}: $1: invalid option" 1>&2 + return 1 ;; + esac + done +} # Local Variables: # mode: sh