From 70a88062385acc05dc60f5fc908ec2130cbd7441 Mon Sep 17 00:00:00 2001 From: Jephte CLAIN Date: Fri, 5 Sep 2014 22:19:46 +0400 Subject: [PATCH] =?UTF-8?q?changer=20la=20d=C3=A9finition=20de=20qval()=20?= =?UTF-8?q?impl=C3=A9menter=20evalx(),=20evalp(),=20testx(),=20testp()=20e?= =?UTF-8?q?t=20fonctions=20associ=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ulib/.ulibver | 2 +- lib/ulib/base | 166 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 135 insertions(+), 33 deletions(-) diff --git a/lib/ulib/.ulibver b/lib/ulib/.ulibver index a306ab0..a8c61cc 100644 --- a/lib/ulib/.ulibver +++ b/lib/ulib/.ulibver @@ -1 +1 @@ -001005000 +002000000 diff --git a/lib/ulib/base b/lib/ulib/base index c8c9693..34ee99d 100644 --- a/lib/ulib/base +++ b/lib/ulib/base @@ -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