changer la définition de qval()

implémenter evalx(), evalp(), testx(), testp() et fonctions associées
This commit is contained in:
Jephte CLAIN 2014-09-05 22:19:46 +04:00
parent 768b5bbf68
commit 70a8806238
2 changed files with 135 additions and 33 deletions

View File

@ -1 +1 @@
001005000
002000000

View File

@ -59,7 +59,7 @@ function recho_() {
echo -n "$@"
fi
}
function qval() {
function _qval() {
# Dans la chaine $*, remplacer \ par \\, " par \", $ par \$, ` par \`
# Cela permet de quoter une chaine à mettre entre guillements. note: la
# protection de ! n'est pas effectuée, parce que le comportement du shell est
@ -72,6 +72,20 @@ function qval() {
s="${s//\`/\\\`}"
recho_ "$s"
}
function qval() {
# Afficher la chaine $* quotée le cas échéant avec "
echo -n \"
_qval "$@"
echo \"
}
function qvalr() {
# Afficher la chaine $* quotée le cas échéant avec ", sauf si elle est vide
if [ -n "$*" ]; then
echo -n \"
_qval "$@"
echo n \"
fi
}
function should_quote() {
# Tester si la chaine $* doit être mise entre quotes
[ -z "$1" ] && return 0
@ -93,7 +107,7 @@ function qvals() {
[ -z "$first" ] && echo -n " "
if should_quote "$arg"; then
echo -n \"
qval "$arg"
_qval "$arg"
echo -n \"
else
recho_ "$arg"
@ -115,12 +129,13 @@ function setv() {
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var=\"$(qval "$*")\""
eval "$__s_var=\"$(_qval "$*")\""
}
function _setv() {
# Comme la fonction setv() mais ne supporte que la syntaxe '_setv var cmd args...'
# Comme la fonction setv() mais ne supporte que la syntaxe '_setv var values...'
# Cette fonction est légèrement plus rapide que setv()
local __s_var="$1"; shift
eval "$__s_var=\"$(qval "$*")\""
eval "$__s_var=\"$(_qval "$*")\""
}
function setx() {
# initialiser la variable $1 avec le résultat de la commande "$2..@"
@ -135,6 +150,7 @@ function setx() {
}
function _setx() {
# Comme la fonction setx() mais ne supporte que la syntaxe '_setx var cmd args...'
# Cette fonction est légèrement plus rapide que setx()
local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"'
}
@ -152,58 +168,140 @@ function seta() {
}
function _seta() {
# Comme la fonction seta() mais ne supporte que la syntaxe '_seta var cmd args...'
# Cette fonction est légèrement plus rapide que seta()
local __s_array="$1"; shift
eval "$__s_array=($("$@" | qlines))"
}
function evalx() {
# évaluer ...
local val arg r=0
local -a cmd
# Implémenter une syntaxe lisible et naturelle permettant d'enchainer des
# traitements sur une valeur. Par exemple, la commande
# evalx cmd1... // cmd2... // cmd3...
# affiche le résultat de la commande "$(cmd3 $(cmd2 $(cmd1)))"
# Retourner le dernier code d'erreur non nul, ou 0 si toutes les commandes se
# sont exécutées sans erreur.
local __e_val __e_arg __e_r=0
local -a __e_cmd
local first=1
local __e_first=1
while [ $# -gt 0 ]; do
cmd=()
__e_cmd=()
while [ $# -gt 0 ]; do
arg="$1"; shift
[ "$arg" == // ] && break
if [ "${arg%//}" != "$arg" ]; then
local tmp="${arg%//}"
if [ -z "${tmp//\\/}" ]; then
arg="${arg#\\}"
cmd=("${cmd[@]}" "$arg")
__e_arg="$1"; shift
[ "$__e_arg" == // ] && break
if [ "${__e_arg%//}" != "$__e_arg" ]; then
local __e_tmp="${__e_arg%//}"
if [ -z "${__e_tmp//\\/}" ]; then
__e_arg="${__e_arg#\\}"
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
continue
fi
fi
cmd=("${cmd[@]}" "$arg")
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
done
if [ -n "$first" ]; then
val="$("${cmd[@]}")" || r=$?
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
val="$("${cmd[@]}" "$val")" || r=$?
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
fi
first=
__e_first=
done
[ -n "$val" ] && echo "$val"
return $r
[ -n "$__e_val" ] && echo "$__e_val"
return $__e_r
}
function setx2() {
# équivalent à setx $1 evalx $2..@
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
setx "$__s_var" evalx "$@"
}
function evalp() {
# évaluer ...
:
# Implémenter une syntaxe alternative permettant d'enchainer des traitements sur
# un flux de données. Par exemple, la commande
# evalp cmd1... // cmd2... // cmd3...
# affiche le résultat de la commande "$(cmd1 | cmd2 | cmd3)"
# Typiquement, cette fonction permet de faciliter la construction d'un
# enchainement de commandes par programme, ou de faciliter l'utilisation de la
# fonction setx() pour récupérer le résultat d'un enchainement. Dans les autres
# cas, il est plus simple et naturel d'écrire les enchainements avec la syntaxe
# de bash.
local __e_arg __e_cmd
while [ $# -gt 0 ]; do
__e_arg="$1"; shift
if [ "$__e_arg" == // ]; then
__e_cmd="$__e_cmd |"
continue
elif [ "${__e_arg%//}" != "$__e_arg" ]; then
local __e_tmp="${__e_arg%//}"
if [ -z "${__e_tmp//\\/}" ]; then
__e_arg="${__e_arg#\\}"
fi
fi
__e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\""
done
eval "$__e_cmd"
}
function testx() {
# tester ...
:
# Faire un test unaire avec la commande [ sur une valeur calculée avec evalx.
# Utiliser la syntaxe 'testx op cmds...' e.g.
# testx -z cmd1 // cmd2
local __t_op="$1"; shift
local __t_val="$(evalx "$@")"
[ $__t_op "$__t_val" ]
}
function test2x() {
# Faire une test binaire avec la commande [ entre une valeur spécifiée et une
# valeur calculée avec evalx. Utiliser la syntaxe 'test2x value op cmds...' e.g.
# test2x value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalx "$@")"
[ "$__t_val1" $__t_op "$__t_val2" ]
}
function testrx() {
# Faire une test binaire avec la commande [[ entre une valeur spécifiée et une
# valeur calculée avec evalx. Utiliser la syntaxe 'testrx value op cmds...' e.g.
# testrx value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalx "$@")"
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
}
function testp() {
# Faire un test unaire avec la commande [ sur une valeur calculée avec evalp.
# Utiliser la syntaxe 'testp op cmds...' e.g.
# testp -z cmd1 // cmd2
local __t_op="$1"; shift
local __t_val="$(evalp "$@")"
[ $__t_op "$__t_val" ]
}
function test2p() {
# Faire une test binaire avec la commande [ entre une valeur spécifiée et une
# valeur calculée avec evalp. Utiliser la syntaxe 'test2p value op cmds...' e.g.
# test2p value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalp "$@")"
[ "$__t_val1" $__t_op "$__t_val2" ]
}
function testrp() {
# Faire une test binaire avec la commande [[ entre une valeur spécifiée et une
# valeur calculée avec evalp. Utiliser la syntaxe 'testrp value op cmds...' e.g.
# test2x value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalp "$@")"
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
}
function e2of() {
function err2out() {
# lancer la commande $@ en redirigeant la sortie d'erreur sur la sortie standard
"$@" 2>&1
}
function nef() {
# lancer la commande $@ et filtrer du résultat toutes les lignes vides
"$@" | sed '/^$/d'
}
## valeurs
function tolower() {
@ -1699,6 +1797,10 @@ function array_lsfiles() {
# noms comme avec list_files
__array_ls files "$@"
}
function filter_empty() {
# Filtrer l'entrée standard en enlevant les lignes vides
sed '/^$/d'
}
function filter_vcspath() {
# L'entrée standard étant une liste de chemins, filtrer les fichiers et
# répertoire qui ont un rapport avec subversion ou git