Ajout des fonctions {build,eval}cmd et upvar

This commit is contained in:
Jephté Clain 2016-06-05 17:41:00 +04:00
parent 7091ecff64
commit 3653f7db5a
1 changed files with 98 additions and 0 deletions

View File

@ -376,3 +376,101 @@ function err2out() {
# lancer la commande $@ en redirigeant la sortie d'erreur sur la sortie standard
"$@" 2>&1
}
# cf http://www.fvue.nl/wiki/Bash:_Passing_variables_by_reference
function upvar() {
# 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.
if unset -v "$1"; then
if [ $# -eq 2 ]; then
eval "$1=\"\$2\""
else
eval "$1=(\"\${@:2}\")"
fi
fi
}
function array_upvar() {
# Comme upvar() mais force la création d'un tableau
unset -v "$1" && eval "$1=(\"\${@:2}\")"
}
function upvars() {
# Version modifiée par rapport à l'original. Il n'est plus nécessaire de
# préfixer une variable scalaire avec -v, et -a peut être spécifié sans
# argument.
# Usage:
# local varname [varname ...] && upvars [varname value] | [-aN varname [value ...]] ...
# Options:
# -a
# assigns remaining values to varname as array
# -aN
# assigns next N values to varname as array. Returns 1 if wrong number of
# options occurs
while [ $# -gt 0 ]; do
case "$1" in
-a)
unset -v "$2" && eval "$2=(\"\${@:3}\")"
break
;;
-a*)
unset -v "$2" && eval "$2=(\"\${@:3:${1#-a}}\")"
shift $((${1#-a} + 2)) || return 1
;;
*)
unset -v "$1" && eval "$1=\"\$2\""
shift; shift
;;
esac
done
}
function __ab_process_pending() {
local -a values
case "$mode" in
cmd) values="$("${pending[@]}")";;
ssplit) eval "values=($("${pending[@]}"))";;
lsplit) eval "values=($("${pending[@]}" | qlines))";;
add) values=("${pending[@]}");;
esac
cmd=("${cmd[@]}" "${values[@]}")
pending=()
}
function array_buildcmd() {
# Construire un tableau dont les éléments sont calculés à partir d'une chaine
# dont les éléments sont séparés par des marqueurs ++X, e.g:
# ++ ou ++c[md] une chaine simple résultat de la commande
# ++s[split] un ensemble d'arguments résultat du split du résultat de la
# commande sur espaces
# ++l[split] un ensemble d'arguments résultat du split du résultat de la
# commande sur les lignes
# ++a[dd] un ensemble d'arguments donnés directement
# Exemple:
# array_buildcmd args echo Copie de ++ ppath "$src" ++a vers ++ ppath "$dest"
local desta="$1"; shift; local "$desta"
local mode=add
local -a pending cmd
while [ $# -gt 0 ]; do
case "$1" in
++c|++cmd|++) __ab_process_pending; mode=cmd;;
++s|++ssplit) __ab_process_pending; mode=ssplit;;
++l|++lsplit) __ab_process_pending; mode=lsplit;;
++a|++add) __ab_process_pending; mode=add;;
*) pending=("${pending[@]}" "$1");;
esac
shift
done
__ab_process_pending
array_upvar "$desta" "${cmd[@]}"
}
function buildcmd() {
local -a args
array_buildcmd args "$@"
qvals "${args[@]}"
}
function evalcmd() {
local -a args
array_buildcmd args "$@"
"${args[@]}"
}