modifs.mineures sans commentaires
This commit is contained in:
parent
f9f16ee0f1
commit
4b15b8f600
|
@ -1,7 +1,6 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.args "Fonctions de base: analyse d'arguments"
|
||||
require: base.arr
|
||||
|
||||
function: local_args "Afficher des commandes pour rendre locales des variables utilisées par parse_args()
|
||||
|
||||
|
@ -9,6 +8,8 @@ Cela permet d'utiliser parse_args() à l'intérieur d'une fonction."
|
|||
function local_args() {
|
||||
echo "local args"
|
||||
echo "local NUCORE_ARGS_ONERROR_RETURN=1"
|
||||
echo "local NUCORE_VERBOSITY=\"\$NUCORE_VERBOSITY\""
|
||||
echo "local NUCORE_INTERACTION=\"\$NUCORE_INTERACTION\""
|
||||
}
|
||||
|
||||
function: parse_args "Analyser les arguments de la ligne de commande à partir des définitions du tableau args
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.arr "Fonctions de base: gestion des variables tableaux"
|
||||
require: base.core base.str
|
||||
module: base.array "Fonctions de base: gestion des variables tableaux"
|
||||
|
||||
function: array_count "retourner le nombre d'éléments du tableau \$1"
|
||||
function array_count() {
|
||||
|
@ -269,7 +268,7 @@ function array_splitc() {
|
|||
|
||||
function: array_xsplitl "créer le tableau \$1 avec chaque ligne de \$2"
|
||||
function array_xsplitl() {
|
||||
eval "$1=($(recho_ "$2" | strnl2lf | lawk '
|
||||
eval "$1=($(recho_ "$2" | nl2lf | lawk '
|
||||
{
|
||||
gsub(/'\''/, "'\'\\\\\'\''")
|
||||
print "'\''" $0 "'\''"
|
||||
|
@ -280,7 +279,7 @@ function: array_splitl "créer le tableau \$1 avec chaque ligne de \$2
|
|||
|
||||
Les lignes vides sont ignorés."
|
||||
function array_splitl() {
|
||||
eval "$1=($(recho_ "$2" | strnl2lf | lawk '
|
||||
eval "$1=($(recho_ "$2" | nl2lf | lawk '
|
||||
/^$/ { next }
|
||||
{
|
||||
gsub(/'\''/, "'\'\\\\\'\''")
|
|
@ -1,468 +0,0 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.eval "Fonctions de base: évaluation d'expressions"
|
||||
require: base.str base.arr
|
||||
|
||||
################################################################################
|
||||
# Chaines
|
||||
|
||||
function: evals "Appliquer à une chaine de caractères une suite de traitements, e.g:
|
||||
~~~
|
||||
evals var deref +suffix
|
||||
~~~
|
||||
est équivalent à
|
||||
~~~
|
||||
echo \"\${var}suffix\"
|
||||
~~~
|
||||
|
||||
En commençant avec la valeur initiale \$1, les arguments \$2..* sont des
|
||||
opérations à appliquer dans l'ordre.
|
||||
|
||||
Les opérations suivantes considèrent que la valeur courante est un nom de
|
||||
variable:
|
||||
~~~
|
||||
:- := :? :+ deref dcount
|
||||
~~~
|
||||
|
||||
Toutes les autres opérations travaillent directement avec la valeur
|
||||
courante. Les opérations suivantes appliquent une transformation:
|
||||
~~~
|
||||
# % / : ^ , +# -# +% -% + - mid repl
|
||||
~~~
|
||||
IMPORTANT: aucune de ces fonctions ne met en échappement les valeur des
|
||||
patterns. Ainsi, si un pattern contient des caractères interdits comme \\ ou \$,
|
||||
il faut d'abord le traiter avec _qval()
|
||||
|
||||
Les opérations suivantes font un test sur la valeur et retournent immédiatement:
|
||||
~~~
|
||||
= == != < > -eq -ne -lt -le -gt -ge -n -z
|
||||
~~~
|
||||
|
||||
La syntaxe des opérateurs standards de bash est reprise autant que possible, i.e
|
||||
si on a l'habitude d'écrire ${varOP} en bash, alors la syntaxe à utiliser à
|
||||
priori est 'evals var OP' ou 'evals var deref OP' suivant les
|
||||
opérateurs.
|
||||
|
||||
Autres opérateurs:
|
||||
~~~
|
||||
deref indirection
|
||||
dcount nombre d'éléments du tableau
|
||||
+#STR ajouter un préfixe
|
||||
-#STR supprimer un préfixe
|
||||
+%STR ou +STR ajouter un suffixe
|
||||
-%STR ou -STR supprimer un suffixe
|
||||
mid RANGE traiter la chaine avec strmid()
|
||||
repl FROM TO traiter la chaine avec strrepl()
|
||||
~~~
|
||||
|
||||
Tout autre opérateur est traité comme un appel à une fonction qui prend un seul
|
||||
argument, la valeur courante, et qui affiche le résultat."
|
||||
function evals() {
|
||||
local -a es__tmp
|
||||
local es__value="$1"; shift
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
# l'argument est le nom de la variable
|
||||
:-*|:=*|:\?*|:+*) eval 'es__value="${'"${es__value}$1"'}"';;
|
||||
d|deref) es__value="${!es__value}";;
|
||||
dc|dcount|ds|dsize)
|
||||
es__value="${es__value}[@]"
|
||||
es__tmp=("${!es__value}")
|
||||
es__value="${#es__tmp[@]}"
|
||||
;;
|
||||
# l'argument est la valeur de la variable
|
||||
\#*|%*|/*|:*|^*|,*) eval 'es__value="${es__value'"$1"'}"';;
|
||||
l|length) es__value="${#es__value}";;
|
||||
=|==|!=|\<|\>|-eq|-ne|-lt|-le|-gt|-ge)
|
||||
es__tmp=(\[ "$es__value" "$@" ]); "${es__tmp[@]}"; return $?;;
|
||||
-n|-z) es__tmp=(\[ "$1" "$es__value" ]); "${es__tmp[@]}"; return $?;;
|
||||
+#*) eval 'es__value="'"${1#+#}"'$es__value"';;
|
||||
-#*) eval 'es__value="${es__value'"${1#-}"'}"';;
|
||||
+%*) eval 'es__value="$es__value"'"${1#+%}";;
|
||||
+*) eval 'es__value="$es__value"'"${1#+}";;
|
||||
-%*) eval 'es__value="${es__value'"${1#-}"'}"';;
|
||||
-*) eval 'es__value="${es__value%'"${1#-}"'}"';;
|
||||
mid|strmid) eval 'es__value="$(strmid "$2" "$es__value")"'; shift;;
|
||||
repl|strrepl) eval 'es__value="$(strrepl "$2" "$3" "$es__value")"'; shift; shift;;
|
||||
*) es__value="$("$1" "$es__value")";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
echo "$es__value"
|
||||
}
|
||||
|
||||
function: setxs "équivalent à setx \$1 evals \$2..@"
|
||||
function setxs() {
|
||||
local -a ss__args
|
||||
if [ "$1" == -a ]; then ss__args=(-a); shift; fi
|
||||
local ss__var="$1"; shift
|
||||
if [[ "$ss__var" == *=* ]]; then
|
||||
set -- "${ss__var#*=}" "$@"
|
||||
ss__var="${ss__var%%=*}"
|
||||
fi
|
||||
ss__args=("${ss__args[@]}" "$ss__var")
|
||||
setx "${ss__args[@]}" evals "$@"
|
||||
}
|
||||
|
||||
function: cmds "lancer une commande avec comme argument le résultat de evals
|
||||
|
||||
Par exemple, les deux commandes suivantes sont équivalentes:
|
||||
~~~
|
||||
cmds CMD ARGS... // EVALARGS
|
||||
CMD ARGS... \"\$(evals EVALARGS)\"
|
||||
~~~"
|
||||
function cmds() {
|
||||
local cs__arg
|
||||
local -a cs__cmd
|
||||
while [ $# -gt 0 ]; do
|
||||
cs__arg="$1"; shift
|
||||
[ "$cs__arg" == // ] && break
|
||||
cs__cmd=("${cs__cmd[@]}" "$cs__arg")
|
||||
done
|
||||
"${cs__cmd[@]}" "$(evals "$@")"
|
||||
}
|
||||
|
||||
function: evalm "construire une chaine en mixant chaines statiques et évaluations de commandes
|
||||
|
||||
Par exemple, les deux commandes suivantes sont équivalentes:
|
||||
~~~
|
||||
evalm //\"string\" cmd args // cmd args //\"string\"
|
||||
echo \"string\$(cmd args)\$(cmd args)string\"
|
||||
~~~"
|
||||
function evalm() {
|
||||
local em__val em__arg
|
||||
local -a em__cmd
|
||||
while [ $# -gt 0 ]; do
|
||||
em__arg="$1"
|
||||
if [ "${em__arg#//}" != "$em__arg" ]; then
|
||||
em__val="$em__val${em__arg#//}"
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
em__cmd=()
|
||||
while [ $# -gt 0 ]; do
|
||||
em__arg="$1"
|
||||
[ "${em__arg#//}" != "$em__arg" ] && break
|
||||
shift
|
||||
if [ "${em__arg%//}" != "$em__arg" ]; then
|
||||
local em__tmp="${em__arg%//}"
|
||||
if [ -z "${em__tmp//\\/}" ]; then
|
||||
em__arg="${em__arg#\\}"
|
||||
em__cmd=("${em__cmd[@]}" "$em__arg")
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
em__cmd=("${em__cmd[@]}" "$em__arg")
|
||||
done
|
||||
[ ${#em__cmd[*]} -gt 0 ] && em__val="$em__val$("${em__cmd[@]}")"
|
||||
done
|
||||
echo "$em__val"
|
||||
}
|
||||
|
||||
function: setxm "équivalent à setx \$1 evalm \$2..@"
|
||||
function setxm() {
|
||||
local -a sm__args
|
||||
if [ "$1" == -a ]; then sm__args=(-a); shift; fi
|
||||
local sm__var="$1"; shift
|
||||
if [[ "$sm__var" == *=* ]]; then
|
||||
set -- "${sm__var#*=}" "$@"
|
||||
sm__var="${sm__var%%=*}"
|
||||
fi
|
||||
sm__args=("${sm__args[@]}" "$sm__var")
|
||||
setx "${sm__args[@]}" evalm "$@"
|
||||
}
|
||||
|
||||
function: cmdm "lancer une commande avec comme argument le résultat de evalm
|
||||
|
||||
Par exemple, les deux commandes suivantes sont équivalentes:
|
||||
~~~
|
||||
cmdm CMD ARGS... // EVALARGS
|
||||
CMD ARGS... \"\$(evalm EVALARGS)\"
|
||||
~~~"
|
||||
function cmdm() {
|
||||
local cm__arg
|
||||
local -a cm__cmd
|
||||
while [ $# -gt 0 ]; do
|
||||
cm__arg="$1"; shift
|
||||
[ "$cm__arg" == // ] && break
|
||||
cm__cmd=("${cm__cmd[@]}" "$cm__arg")
|
||||
done
|
||||
"${cm__cmd[@]}" "$(evalm "$@")"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Nombres
|
||||
|
||||
function: evali "Evaluer une expression numérique"
|
||||
function evali() {
|
||||
echo "$(($*))"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Tableaux
|
||||
|
||||
################################################################################
|
||||
# Composition
|
||||
|
||||
function: evalc "Implémenter une syntaxe lisible et naturelle permettant d'enchainer des traitements sur une valeur.
|
||||
|
||||
Par exemple, la commande
|
||||
~~~
|
||||
evalc cmd1... // cmd2... // cmd3...
|
||||
~~~
|
||||
est équivalente à la commande
|
||||
~~~
|
||||
cmd3... \"\$(cmd2... \"\$(cmd1...)\")\"
|
||||
~~~"
|
||||
function evalc() {
|
||||
local ec__arg ec__cmd ec__finalcmd
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
ec__arg="$1"; shift
|
||||
if [ "$ec__arg" == // ]; then
|
||||
if [ ${#ec__cmd} -gt 0 ]; then
|
||||
if [ ${#ec__finalcmd} -eq 0 ]; then ec__finalcmd="$ec__cmd"
|
||||
else ec__finalcmd="$ec__cmd \$($ec__finalcmd)"
|
||||
fi
|
||||
fi
|
||||
ec__cmd=
|
||||
continue
|
||||
elif [ "${ec__arg%//}" != "$ec__arg" ]; then
|
||||
local tmp="${ec__arg%//}"
|
||||
[ -z "${tmp//\\/}" ] && ec__arg="${ec__arg#\\}"
|
||||
fi
|
||||
ec__cmd="$ec__cmd \"$(_qval "$ec__arg")\""
|
||||
done
|
||||
if [ ${#ec__cmd} -gt 0 ]; then
|
||||
if [ ${#ec__finalcmd} -eq 0 ]; then ec__finalcmd="$ec__cmd"
|
||||
else ec__finalcmd="$ec__cmd \$($ec__finalcmd)"
|
||||
fi
|
||||
fi
|
||||
eval "$ec__finalcmd"
|
||||
}
|
||||
|
||||
function: setxc "équivalent à setx \$1 evalc \$2..@"
|
||||
function setxc() {
|
||||
local -a sx__args
|
||||
if [ "$1" == -a ]; then sx__args=(-a); shift; fi
|
||||
local sx__var="$1"; shift
|
||||
if [[ "$sx__var" == *=* ]]; then
|
||||
set -- "${sx__var#*=}" "$@"
|
||||
sx__var="${sx__var%%=*}"
|
||||
fi
|
||||
sx__args=("${sx__args[@]}" "$sx__var")
|
||||
setx "${sx__args[@]}" evalc "$@"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Chainage
|
||||
|
||||
function: evalp "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."
|
||||
function evalp() {
|
||||
local ep__arg ep__cmd
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
ep__arg="$1"; shift
|
||||
if [ "$ep__arg" == // ]; then
|
||||
ep__cmd="$ep__cmd |"
|
||||
continue
|
||||
elif [ "${ep__arg%//}" != "$ep__arg" ]; then
|
||||
local ep__tmp="${ep__arg%//}"
|
||||
if [ -z "${ep__tmp//\\/}" ]; then
|
||||
ep__arg="${ep__arg#\\}"
|
||||
fi
|
||||
fi
|
||||
ep__cmd="${ep__cmd:+$ep__cmd }\"$(_qval "$ep__arg")\""
|
||||
done
|
||||
eval "$ep__cmd"
|
||||
}
|
||||
|
||||
function: setxp "équivalent à setx \$1 evalp \$2..@"
|
||||
function setxp() {
|
||||
local -a sp__args
|
||||
if [ "$1" == -a ]; then sp__args=(-a); shift; fi
|
||||
local sp__var="$1"; shift
|
||||
if [[ "$sp__var" == *=* ]]; then
|
||||
set -- "${sp__var#*=}" "$@"
|
||||
sp__var="${sp__var%%=*}"
|
||||
fi
|
||||
sp__args=("${sp__args[@]}" "$sp__var")
|
||||
setx "${sp__args[@]}" evalp "$@"
|
||||
}
|
||||
|
||||
function: cmdp "lancer une commande avec comme argument le résultat de evalp
|
||||
|
||||
Par exemple, les deux commandes suivantes sont équivalentes:
|
||||
~~~
|
||||
cmdp CMD ARGS... // EVALARGS
|
||||
CMD ARGS... \"\$(evalp EVALARGS)\"
|
||||
~~~"
|
||||
function cmdp() {
|
||||
local cp__arg
|
||||
local -a cp__cmd
|
||||
while [ $# -gt 0 ]; do
|
||||
cp__arg="$1"; shift
|
||||
[ "$cp__arg" == // ] && break
|
||||
cp__cmd=("${cp__cmd[@]}" "$cp__arg")
|
||||
done
|
||||
"${cp__cmd[@]}" "$(evalp "$@")"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Générique
|
||||
|
||||
function: evalx ""
|
||||
function evalx() {
|
||||
:
|
||||
}
|
||||
|
||||
function: setxx "équivalent à setx \$1 evalx \$2..@"
|
||||
function setxx() {
|
||||
local -a sx__args
|
||||
if [ "$1" == -a ]; then sx__args=(-a); shift; fi
|
||||
local sx__var="$1"; shift
|
||||
if [[ "$sx__var" == *=* ]]; then
|
||||
set -- "${sx__var#*=}" "$@"
|
||||
sx__var="${sx__var%%=*}"
|
||||
fi
|
||||
sx__args=("${sx__args[@]}" "$sx__var")
|
||||
setx "${sx__args[@]}" evalx "$@"
|
||||
}
|
||||
|
||||
function: cmdx "lancer une commande avec comme argument le résultat de evalx
|
||||
|
||||
Par exemple, les deux commandes suivantes sont équivalentes:
|
||||
~~~
|
||||
cmdx CMD ARGS... // EVALARGS
|
||||
CMD ARGS... \"\$(evalx EVALARGS)\"
|
||||
~~~"
|
||||
function cmdx() {
|
||||
local cx__arg
|
||||
local -a cx__cmd
|
||||
while [ $# -gt 0 ]; do
|
||||
cx__arg="$1"; shift
|
||||
[ "$cx__arg" == // ] && break
|
||||
cx__cmd=("${cx__cmd[@]}" "$cx__arg")
|
||||
done
|
||||
"${cx__cmd[@]}" "$(evalx "$@")"
|
||||
}
|
||||
|
||||
function: cmdsplitf "\
|
||||
Cette fonction doit être appelée avec N arguments (avec N>1). Elle analyse et
|
||||
découpe l'argument \$N comme avec une ligne de commande du shell. Ensuite, elle
|
||||
appelle la fonction \$1 avec les arguments de \$2 à \${N-1}, suivi des arguments
|
||||
obtenus lors de l'analyse de l'argument \$N. Par exemple, la commande suivante:
|
||||
~~~
|
||||
strsplitf cmd arg1 \"long arg2\" \"arg3 'long arg4'\"
|
||||
~~~
|
||||
est équivalente à:
|
||||
~~~
|
||||
cmd arg1 \"long arg2\" arg3 \"long arg4\"
|
||||
~~~
|
||||
|
||||
Retourner le code 127 si la fonction à appeler n'est pas spécifiée. Retourner le
|
||||
code 126 si une erreur s'est produite lors de l'analyse de l'argument \$N"
|
||||
function cmdsplitf() {
|
||||
[ $# -gt 0 ] || return 127
|
||||
local func count
|
||||
func="$1"; shift
|
||||
count=$#
|
||||
if [ $count -gt 0 ]; then
|
||||
eval 'set -- "${@:1:$(($count-1))}" '"${!count}" || return 126
|
||||
fi
|
||||
"$func" "$@"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Tests
|
||||
|
||||
function: testx "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
|
||||
~~~"
|
||||
function testx() {
|
||||
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
|
||||
~~~"
|
||||
function test2x() {
|
||||
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
|
||||
~~~"
|
||||
function testrx() {
|
||||
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
|
||||
~~~"
|
||||
function testp() {
|
||||
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
|
||||
~~~"
|
||||
function test2p() {
|
||||
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.
|
||||
~~~
|
||||
testrp value == cmd1 // cmd2
|
||||
~~~"
|
||||
function testrp() {
|
||||
local t__val1="$1"; shift
|
||||
local t__op="$1"; shift
|
||||
local t__val2="$(evalp "$@")"
|
||||
eval '[[ "$t__val1" '"$t__op"' "$t__val2" ]]'
|
||||
}
|
|
@ -0,0 +1,586 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.input "Fonctions de base: saisie"
|
||||
|
||||
function toienc() {
|
||||
# $1 étant une variable contenant une chaine encodée dans l'encoding d'entrée $2
|
||||
# (qui vaut par défaut $NUCORE_INPUT_ENCODING), transformer cette chaine en
|
||||
# utf-8
|
||||
local __var="$1" __from="${2:-$NUCORE_INPUT_ENCODING}"
|
||||
if [ "$__from" != "NUCORE__UTF8" ]; then
|
||||
_setv "$__var" "$(iconv -f "$__from" -t utf-8 <<<"${!__var}")"
|
||||
fi
|
||||
}
|
||||
|
||||
function uread() {
|
||||
# Lire une valeur sur stdin et la placer dans la variable $1. On assume que la
|
||||
# valeur en entrée est encodée dans $NUCORE_INPUT_ENCODING
|
||||
[ $# -gt 0 ] || set -- REPLY
|
||||
local __var
|
||||
read "$@"
|
||||
for __var in "$@"; do
|
||||
[ -z "$__var" -o "${__var:0:1}" == "-" ] && continue # ignorer les options
|
||||
toienc "$__var"
|
||||
done
|
||||
}
|
||||
|
||||
function is_interaction() {
|
||||
return 1
|
||||
}
|
||||
|
||||
function check_interaction() {
|
||||
return 0
|
||||
}
|
||||
function get_interaction_option() { :;}
|
||||
|
||||
function ask_yesno() {
|
||||
# Afficher le message $1 suivi de [oN] ou [On] suivant que $2 vaut O ou N, puis
|
||||
# lire la réponse. Retourner 0 si la réponse est vrai, 1 sinon.
|
||||
# Si $1 est une option, elle est utilisée avec check_interaction pour savoir si
|
||||
# on est en mode interactif ou non. A ce moment-là, les valeurs sont décalées
|
||||
# ($2=message, $3=default)
|
||||
# Si $2 vaut C, la valeur par défaut est N si on est interactif, O sinon
|
||||
# Si $2 vaut X, la valeur par défaut est O si on est interactif, N sinon
|
||||
local interactive=1
|
||||
if [[ "$1" == -* ]]; then
|
||||
if [ "$1" != -- ]; then
|
||||
check_interaction "$1" || interactive=
|
||||
fi
|
||||
shift
|
||||
else
|
||||
check_interaction -c || interactive=
|
||||
fi
|
||||
local default="${2:-N}"
|
||||
if [ "$default" == "C" ]; then
|
||||
[ -n "$interactive" ] && default=N || default=O
|
||||
elif [ "$default" == "X" ]; then
|
||||
[ -n "$interactive" ] && default=O || default=N
|
||||
fi
|
||||
if [ -n "$interactive" ]; then
|
||||
eflush
|
||||
local message="$1"
|
||||
local prompt="[oN]"
|
||||
local r
|
||||
is_yes "$default" && prompt="[On]"
|
||||
if [ -n "$message" ]; then
|
||||
__eecho_ "$message" 1>&2
|
||||
else
|
||||
__eecho_ "Voulez-vous continuer?" 1>&2
|
||||
fi
|
||||
tooenc_ " $prompt " 1>&2
|
||||
uread r
|
||||
is_yes "${r:-$default}"
|
||||
else
|
||||
is_yes "$default"
|
||||
fi
|
||||
}
|
||||
|
||||
function ask_any() {
|
||||
# Afficher le message $1 suivi du texte "[$2]" (qui vaut par défaut +Oq), puis
|
||||
# lire la réponse. Les lettres de la chaine de format $2 sont numérotées de 0 à
|
||||
# $((${#2} - 1)). Le code de retour est le numéro de la lettre qui a été
|
||||
# sélectionnée. Cette fonction est une généralisation de ask_yesno() pour
|
||||
# n'importe quel ensemble de lettres.
|
||||
# La première lettre en majuscule est la lettre sélectionnée par défaut.
|
||||
# La lettre O matche toutes les lettres qui signifient oui: o, y, 1, v, t
|
||||
# La lettre N matche toutes les lettres qui signifient non: n, f, 0
|
||||
# Il y a des raccourcis:
|
||||
# +O --> On
|
||||
# +N --> oN
|
||||
# +C --> oN si on est en mode interactif, On sinon
|
||||
# +X --> On si on est en mode interactifn oN sinon
|
||||
# Si $1 est une option, elle est utilisée avec check_interaction pour savoir si
|
||||
# on est en mode interactif ou non. A ce moment-là, les valeurs sont décalées
|
||||
# ($2=message, $3=format)
|
||||
local interactive=1
|
||||
if [[ "$1" == -* ]]; then
|
||||
if [ "$1" != -- ]; then
|
||||
check_interaction "$1" || interactive=
|
||||
fi
|
||||
shift
|
||||
else
|
||||
check_interaction -c || interactive=
|
||||
fi
|
||||
local format="${2:-+Oq}"
|
||||
format="${format/+O/On}"
|
||||
format="${format/+N/oN}"
|
||||
if [ -n "$interactive" ]; then
|
||||
format="${format/+C/oN}"
|
||||
format="${format/+X/On}"
|
||||
else
|
||||
format="${format/+C/On}"
|
||||
format="${format/+X/oN}"
|
||||
fi
|
||||
local i count="${#format}"
|
||||
|
||||
if [ -n "$interactive" ]; then
|
||||
eflush
|
||||
local message="${1:-Voulez-vous continuer?}"
|
||||
local prompt="[$format]"
|
||||
local r f lf defi
|
||||
while true; do
|
||||
__eecho_ "$message $prompt " 1>&2
|
||||
uread r
|
||||
r="$(strlower "${r:0:1}")"
|
||||
i=0; defi=
|
||||
while [ $i -lt $count ]; do
|
||||
f="${format:$i:1}"
|
||||
lf="$(strlower "$f")"
|
||||
[ "$r" == "$lf" ] && return $i
|
||||
if [ -z "$defi" ]; then
|
||||
[ -z "${f/[A-Z]/}" ] && defi="$i"
|
||||
fi
|
||||
if [ "$lf" == o ]; then
|
||||
case "$r" in o|y|1|v|t) return $i;; esac
|
||||
elif [ "$lf" == n ]; then
|
||||
case "$r" in n|f|0) return $i;; esac
|
||||
fi
|
||||
i=$(($i + 1))
|
||||
done
|
||||
[ -z "$r" ] && return ${defi:-0}
|
||||
done
|
||||
else
|
||||
i=0
|
||||
while [ $i -lt $count ]; do
|
||||
f="${format:$i:1}"
|
||||
[ -z "${f/[A-Z]/}" ] && return $i
|
||||
i=$(($i + 1))
|
||||
done
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
function read_value() {
|
||||
# Afficher le message $1 suivi de la valeur par défaut [$3] si elle est non
|
||||
# vide, puis lire la valeur donnée par l'utilisateur. Cette valeur doit être non
|
||||
# vide si $4(=O) est vrai. La valeur saisie est placée dans la variable
|
||||
# $2(=value)
|
||||
# Si $1 est une option, elle est utilisée avec check_interaction pour savoir si
|
||||
# on est en mode interactif ou non. A ce moment-là, les valeurs sont décalées
|
||||
# ($2=message, $3=variable, $4=default, $5=required)
|
||||
# En mode non interactif, c'est la valeur par défaut qui est sélectionnée. Si
|
||||
# l'utilisateur requière que la valeur soit non vide et que la valeur par défaut
|
||||
# est vide, afficher un message d'erreur et retourner faux
|
||||
# read_password() est comme read_value(), mais la valeur saisie n'est pas
|
||||
# affichée, ce qui la rend appropriée pour la lecture d'un mot de passe.
|
||||
local -a __rv_opts; local __rv_readline=1 __rv_showdef=1 __rv_nl=
|
||||
__rv_opts=()
|
||||
[ -n "$NUCORE_NO_READLINE" ] && __rv_readline=
|
||||
__rv_read "$@"
|
||||
}
|
||||
|
||||
function read_password() {
|
||||
local -a __rv_opts __rv_readline= __rv_showdef= __rv_nl=1
|
||||
__rv_opts=(-s)
|
||||
__rv_read "$@"
|
||||
}
|
||||
|
||||
function __rv_read() {
|
||||
local __rv_int=1
|
||||
if [[ "$1" == -* ]]; then
|
||||
if [ "$1" != -- ]; then
|
||||
check_interaction "$1" || __rv_int=
|
||||
fi
|
||||
shift
|
||||
else
|
||||
check_interaction -c || __rv_int=
|
||||
fi
|
||||
local __rv_msg="$1" __rv_v="${2:-value}" __rv_d="$3" __rv_re="${4:-O}"
|
||||
if [ -z "$__rv_int" ]; then
|
||||
# En mode non interactif, retourner la valeur par défaut
|
||||
if is_yes "$__rv_re" && [ -z "$__rv_d" ]; then
|
||||
eerror "La valeur par défaut de $__rv_v doit être non vide"
|
||||
return 1
|
||||
fi
|
||||
_setv "$__rv_v" "$__rv_d"
|
||||
return 0
|
||||
fi
|
||||
|
||||
eflush
|
||||
local __rv_r
|
||||
while true; do
|
||||
if [ -n "$__rv_msg" ]; then
|
||||
__eecho_ "$__rv_msg" 1>&2
|
||||
else
|
||||
__eecho_ "Entrez la valeur" 1>&2
|
||||
fi
|
||||
if [ -n "$__rv_readline" ]; then
|
||||
tooenc_ ": " 1>&2
|
||||
uread -e ${__rv_d:+-i"$__rv_d"} "${__rv_opts[@]}" __rv_r
|
||||
else
|
||||
if [ -n "$__rv_d" ]; then
|
||||
if [ -n "$__rv_showdef" ]; then
|
||||
tooenc_ " [$__rv_d]" 1>&2
|
||||
else
|
||||
tooenc_ " [****]" 1>&2
|
||||
fi
|
||||
fi
|
||||
tooenc_ ": " 1>&2
|
||||
uread "${__rv_opts[@]}" __rv_r
|
||||
[ -n "$__rv_nl" ] && echo
|
||||
fi
|
||||
__rv_r="${__rv_r:-$__rv_d}"
|
||||
if [ -n "$__rv_r" ] || ! is_yes "$__rv_re"; then
|
||||
_setv "$__rv_v" "$__rv_r"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function simple_menu() {
|
||||
# Afficher un menu simple dont les éléments sont les valeurs du tableau
|
||||
# $2(=options). L'option choisie est placée dans la variable $1(=option)
|
||||
# -t TITLE: spécifier le titre du menu
|
||||
# -m YOUR_CHOICE: spécifier le message d'invite pour la sélection de l'option
|
||||
# -d DEFAULT: spécifier l'option par défaut. Par défaut, prendre la valeur
|
||||
# actuelle de la variable $1(=option)
|
||||
local __sm_title= __sm_yourchoice= __sm_default=
|
||||
local -a __sm_args
|
||||
parse_opts -t: __sm_title= -m: __sm_yourchoice= -d: __sm_default= @ __sm_args -- "$@" &&
|
||||
set -- "${__sm_args[@]}" || ewarn "$__sm_args"
|
||||
|
||||
local __sm_option_var="${1:-option}" __sm_options_var="${2:-options}"
|
||||
local __sm_option __sm_options
|
||||
__sm_options="$__sm_options_var[*]"
|
||||
if [ -z "${!__sm_options}" ]; then
|
||||
eerror "Le tableau $__sm_options_var doit être non vide"
|
||||
return 1
|
||||
fi
|
||||
[ -z "$__sm_default" ] && __sm_default="${!__sm_option_var}"
|
||||
|
||||
eflush
|
||||
array_copy __sm_options "$__sm_options_var"
|
||||
local __sm_c=0 __sm_i __sm_choice
|
||||
while true; do
|
||||
if [ "$__sm_c" == "0" ]; then
|
||||
# Afficher le menu
|
||||
[ -n "$__sm_title" ] && __eecho "=== $__sm_title ===" 1>&2
|
||||
__sm_i=1
|
||||
for __sm_option in "${__sm_options[@]}"; do
|
||||
if [ "$__sm_option" == "$__sm_default" ]; then
|
||||
__eecho "$__sm_i*- $__sm_option" 1>&2
|
||||
else
|
||||
__eecho "$__sm_i - $__sm_option" 1>&2
|
||||
fi
|
||||
let __sm_i=$__sm_i+1
|
||||
done
|
||||
fi
|
||||
|
||||
# Afficher les choix
|
||||
if [ -n "$__sm_yourchoice" ]; then
|
||||
__eecho_ "$__sm_yourchoice" 1>&2
|
||||
else
|
||||
__eecho_ "Entrez le numéro de l'option choisie" 1>&2
|
||||
fi
|
||||
tooenc_ ": " 1>&2
|
||||
uread __sm_choice
|
||||
|
||||
# Valeur par défaut
|
||||
if [ -z "$__sm_choice" -a -n "$__sm_default" ]; then
|
||||
__sm_option="$__sm_default"
|
||||
break
|
||||
fi
|
||||
# Vérifier la saisie
|
||||
if [ -n "$__sm_choice" -a -z "${__sm_choice//[0-9]/}" ]; then
|
||||
if [ "$__sm_choice" -gt 0 -a "$__sm_choice" -le "${#__sm_options[*]}" ]; then
|
||||
__sm_option="${__sm_options[$(($__sm_choice - 1))]}"
|
||||
break
|
||||
else
|
||||
eerror "Numéro d'option incorrect"
|
||||
fi
|
||||
else
|
||||
eerror "Vous devez saisir le numéro de l'option choisie"
|
||||
fi
|
||||
|
||||
let __sm_c=$__sm_c+1
|
||||
if [ "$__sm_c" -eq 5 ]; then
|
||||
# sauter une ligne toutes les 4 tentatives
|
||||
tooenc "" 1>&2
|
||||
__sm_c=0
|
||||
fi
|
||||
done
|
||||
_setv "$__sm_option_var" "$__sm_option"
|
||||
}
|
||||
|
||||
function actions_menu() {
|
||||
# Afficher un menu dont les éléments sont les valeurs du tableau $4(=options),
|
||||
# et une liste d'actions tirées du tableau $3(=actions). L'option choisie est
|
||||
# placée dans la variable $2(=option). L'action choisie est placée dans la
|
||||
# variable $1(=action)
|
||||
# Un choix est saisi sous la forme [action]num_option
|
||||
# -t TITLE: spécifier le titre du menu
|
||||
# -m OPT_YOUR_CHOICE: spécifier le message d'invite pour la sélection de
|
||||
# l'action et de l'option
|
||||
# -M ACT_YOUR_CHOICE: spécifier le message d'invite dans le cas où aucune option
|
||||
# n'est disponible. Dans ce cas, seules les actions vides sont possibles.
|
||||
# -e VOID_ACTION: spécifier qu'une action est vide, c'est à dire qu'elle ne
|
||||
# requière pas d'être associée à une option. Par défaut, la dernière action
|
||||
# est classée dans cette catégorie puisque c'est l'action "quitter"
|
||||
# -d DEFAULT_ACTION: choisir l'action par défaut. par défaut, c'est la première
|
||||
# action.
|
||||
# -q QUIT_ACTION: choisir l'option "quitter" qui provoque la sortie du menu sans
|
||||
# choix. par défaut, c'est la dernière action.
|
||||
# -o DEFAULT_OPTION: choisir l'option par défaut. par défaut, prendre la valeur
|
||||
# actuelle de la variable $2(=option)
|
||||
local -a __am_action_descs __am_options __am_void_actions
|
||||
local __am_tmp __am_select_action __am_select_option __am_title __am_optyc __am_actyc
|
||||
local __am_default_action=auto __am_quit_action=auto
|
||||
local __am_default_option=
|
||||
local -a __am_args
|
||||
parse_opts \
|
||||
-t: __am_title= \
|
||||
-m: __am_optyc= \
|
||||
-M: __am_actyc= \
|
||||
-e: __am_void_actions \
|
||||
-d: __am_default_action= \
|
||||
-q: __am_quit_action= \
|
||||
-o: __am_default_option= \
|
||||
@ __am_args -- "$@" && set -- "${__am_args[@]}" || { eerror "$__am_args"; return 1; }
|
||||
|
||||
__am_tmp="${1:-action}"; __am_select_action="${!__am_tmp}"
|
||||
__am_tmp="${2:-option}"; __am_select_option="${!__am_tmp}"
|
||||
[ -n "$__am_default_option" ] && __am_select_option="$__am_default_option"
|
||||
array_copy __am_action_descs "${3:-actions}"
|
||||
array_copy __am_options "${4:-options}"
|
||||
|
||||
eerror_unless [ ${#__am_action_descs[*]} -gt 0 ] "Vous devez spécifier le tableau des actions" || return
|
||||
__actions_menu || return 1
|
||||
_setv "${1:-action}" "$__am_select_action"
|
||||
_setv "${2:-option}" "$__am_select_option"
|
||||
}
|
||||
|
||||
function __actions_menu() {
|
||||
local title="$__am_title"
|
||||
local optyc="$__am_optyc" actyc="$__am_actyc"
|
||||
local default_action="$__am_default_action"
|
||||
local quit_action="$__am_quit_action"
|
||||
local select_action="$__am_select_action"
|
||||
local select_option="$__am_select_option"
|
||||
local -a action_descs options void_actions
|
||||
array_copy action_descs __am_action_descs
|
||||
array_copy options __am_options
|
||||
array_copy void_actions __am_void_actions
|
||||
|
||||
# Calculer la liste des actions valides
|
||||
local no_options
|
||||
array_isempty options && no_options=1
|
||||
|
||||
local -a actions
|
||||
local tmp action name
|
||||
for tmp in "${action_descs[@]}"; do
|
||||
splitfsep2 "$tmp" : action name
|
||||
[ -n "$action" ] || action="${name:0:1}"
|
||||
action="$(strlower "$action")"
|
||||
array_addu actions "$action"
|
||||
done
|
||||
|
||||
# Calculer l'action par défaut
|
||||
if [ "$default_action" == auto ]; then
|
||||
# si action par défaut non spécifiée, alors prendre la première action
|
||||
default_action="$select_action"
|
||||
if [ -n "$default_action" ]; then
|
||||
array_contains actions "$default_action" || default_action=
|
||||
fi
|
||||
[ -n "$default_action" ] || default_action="${actions[0]}"
|
||||
fi
|
||||
default_action="${default_action:0:1}"
|
||||
default_action="$(strlower "$default_action")"
|
||||
|
||||
# Calculer l'action quitter par défaut
|
||||
if [ "$quit_action" == auto ]; then
|
||||
# si action par défaut non spécifiée, alors prendre la dernière action,
|
||||
# s'il y a au moins 2 actions
|
||||
if [ ${#actions[*]} -gt 1 ]; then
|
||||
quit_action="${actions[@]:$((-1)):1}"
|
||||
array_addu void_actions "$quit_action"
|
||||
fi
|
||||
fi
|
||||
quit_action="${quit_action:0:1}"
|
||||
quit_action="$(strlower "$quit_action")"
|
||||
|
||||
# Calculer la ligne des actions à afficher
|
||||
local action_title
|
||||
for tmp in "${action_descs[@]}"; do
|
||||
splitfsep2 "$tmp" : action name
|
||||
[ -n "$action" ] || action="${name:0:1}"
|
||||
[ -n "$name" ] || name="$action"
|
||||
action="$(strlower "$action")"
|
||||
if [ -n "$no_options" ]; then
|
||||
if ! array_contains void_actions "$action"; then
|
||||
array_del actions "$action"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
[ "$action" == "$default_action" ] && name="$name*"
|
||||
action_title="${action_title:+$action_title/}$name"
|
||||
done
|
||||
if [ -n "$default_action" ]; then
|
||||
# si action par défaut invalide, alors pas d'action par défaut
|
||||
array_contains actions "$default_action" || default_action=
|
||||
fi
|
||||
if [ -n "$quit_action" ]; then
|
||||
# si action quitter invalide, alors pas d'action quitter
|
||||
array_contains actions "$quit_action" || quit_action=
|
||||
fi
|
||||
|
||||
# Type de menu
|
||||
if [ -n "$no_options" ]; then
|
||||
if array_isempty void_actions; then
|
||||
eerror "Aucune option n'est définie. Il faut définir le tableau des actions vides"
|
||||
return 1
|
||||
fi
|
||||
__void_actions_menu
|
||||
else
|
||||
__options_actions_menu
|
||||
fi
|
||||
}
|
||||
|
||||
function __void_actions_menu() {
|
||||
eflush
|
||||
local c=0 choice
|
||||
while true; do
|
||||
if [ $c -eq 0 ]; then
|
||||
[ -n "$title" ] && __etitle "$title" 1>&2
|
||||
__eecho_ "=== Actions disponibles: " 1>&2
|
||||
tooenc "$action_title" 1>&2
|
||||
fi
|
||||
if [ -n "$actyc" ]; then
|
||||
__eecho_ "$actyc" 1>&2
|
||||
elif [ -n "$optyc" ]; then
|
||||
__eecho_ "$optyc" 1>&2
|
||||
else
|
||||
__eecho_ "Entrez l'action à effectuer" 1>&2
|
||||
fi
|
||||
tooenc_ ": " 1>&2
|
||||
uread choice
|
||||
if [ -z "$choice" -a -n "$default_action" ]; then
|
||||
select_action="$default_action"
|
||||
break
|
||||
fi
|
||||
|
||||
# vérifier la saisie
|
||||
choice="${choice:0:1}"
|
||||
choice="$(strlower "$choice")"
|
||||
if array_contains actions "$choice"; then
|
||||
select_action="$choice"
|
||||
break
|
||||
elif [ -n "$choice" ]; then
|
||||
eerror "$choice: action incorrecte"
|
||||
else
|
||||
eerror "vous devez saisir l'action à effectuer"
|
||||
fi
|
||||
let c=$c+1
|
||||
if [ $c -eq 5 ]; then
|
||||
# sauter une ligne toutes les 4 tentatives
|
||||
tooenc "" 1>&2
|
||||
c=0
|
||||
fi
|
||||
done
|
||||
__am_select_action="$select_action"
|
||||
__am_select_option=
|
||||
}
|
||||
|
||||
function __options_actions_menu() {
|
||||
eflush
|
||||
local c=0 option choice action option
|
||||
while true; do
|
||||
if [ $c -eq 0 ]; then
|
||||
[ -n "$title" ] && __etitle "$title" 1>&2
|
||||
i=1
|
||||
for option in "${options[@]}"; do
|
||||
if [ "$option" == "$select_option" ]; then
|
||||
tooenc "$i*- $option" 1>&2
|
||||
else
|
||||
tooenc "$i - $option" 1>&2
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
__estepn_ "Actions disponibles: " 1>&2
|
||||
tooenc "$action_title" 1>&2
|
||||
fi
|
||||
if [ -n "$optyc" ]; then
|
||||
__eecho_ "$optyc" 1>&2
|
||||
else
|
||||
__eecho_ "Entrez l'action et le numéro de l'option choisie" 1>&2
|
||||
fi
|
||||
tooenc_ ": " 1>&2
|
||||
uread choice
|
||||
|
||||
# vérifier la saisie
|
||||
if [ -z "$choice" -a -n "$default_action" ]; then
|
||||
action="$default_action"
|
||||
if array_contains void_actions "$action"; then
|
||||
select_action="$action"
|
||||
select_option=
|
||||
break
|
||||
elif [ -n "$select_option" ]; then
|
||||
select_action="$action"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
action="${choice:0:1}"
|
||||
action="$(strlower "$action")"
|
||||
if array_contains actions "$action"; then
|
||||
# on commence par un code d'action valide. cool :-)
|
||||
if array_contains void_actions "$action"; then
|
||||
select_action="$action"
|
||||
select_option=
|
||||
break
|
||||
else
|
||||
option="${choice:1}"
|
||||
option="${option// /}"
|
||||
if [ -z "$option" -a -n "$select_option" ]; then
|
||||
select_action="$action"
|
||||
break
|
||||
elif [ -z "$option" ]; then
|
||||
eerror "vous devez saisir le numéro de l'option"
|
||||
elif isnum "$option"; then
|
||||
if [ $option -gt 0 -a $option -le ${#options[*]} ]; then
|
||||
select_action="$action"
|
||||
select_option="${options[$(($option - 1))]}"
|
||||
break
|
||||
fi
|
||||
else
|
||||
eerror "$option: numéro d'option incorrecte"
|
||||
fi
|
||||
fi
|
||||
elif isnum "$choice"; then
|
||||
# on a simplement donné un numéro d'option
|
||||
action="$default_action"
|
||||
if [ -n "$action" ]; then
|
||||
if array_contains void_actions "$action"; then
|
||||
select_action="$action"
|
||||
select_option=
|
||||
break
|
||||
else
|
||||
option="${choice// /}"
|
||||
if [ -z "$option" ]; then
|
||||
eerror "vous devez saisir le numéro de l'option"
|
||||
elif isnum "$option"; then
|
||||
if [ $option -gt 0 -a $option -le ${#options[*]} ]; then
|
||||
select_action="$action"
|
||||
select_option="${options[$(($option - 1))]}"
|
||||
break
|
||||
fi
|
||||
else
|
||||
eerror "$option: numéro d'option incorrecte"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
eerror "Vous devez spécifier l'action à effectuer"
|
||||
fi
|
||||
elif [ -n "$choice" ]; then
|
||||
eerror "$choice: action et/ou option incorrecte"
|
||||
else
|
||||
eerror "vous devez saisir l'action à effectuer"
|
||||
fi
|
||||
let c=$c+1
|
||||
if [ $c -eq 5 ]; then
|
||||
# sauter une ligne toutes les 4 tentatives
|
||||
tooenc "" 1>&2
|
||||
c=0
|
||||
fi
|
||||
done
|
||||
__am_select_action="$select_action"
|
||||
__am_select_option="$select_option"
|
||||
}
|
1291
bash/src/base.io.sh
1291
bash/src/base.io.sh
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,646 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.output "Fonctions de base: affichage"
|
||||
|
||||
NUCORE__TAB=$'\t'
|
||||
NUCORE__LATIN1=iso-8859-1
|
||||
NUCORE__LATIN9=iso-8859-15
|
||||
NUCORE__UTF8=utf-8
|
||||
|
||||
if [ ! -x "$(which iconv 2>/dev/null)" ]; then
|
||||
function iconv() { cat; }
|
||||
fi
|
||||
|
||||
function nucore__lang_encoding() {
|
||||
case "${LANG,,}" in
|
||||
*@euro) echo "iso-8859-15";;
|
||||
*.utf-8|*.utf8) echo "utf-8";;
|
||||
*) echo "iso-8859-1";;
|
||||
esac
|
||||
}
|
||||
|
||||
function nucore__norm_encoding() {
|
||||
local enc="${1,,}"
|
||||
enc="${enc//[-_]/}"
|
||||
case "$enc" in
|
||||
latin|latin1|iso8859|iso88591|8859|88591) echo "iso-8859-1";;
|
||||
latin9|iso885915|885915) echo "iso-8859-15";;
|
||||
utf|utf8) echo "utf-8";;
|
||||
*) echo "$1";;
|
||||
esac
|
||||
}
|
||||
|
||||
function nucore__init_encoding() {
|
||||
local default_encoding="$(nucore__lang_encoding)"
|
||||
[ -n "$default_encoding" ] || default_encoding=utf-8
|
||||
[ -n "$NUCORE_OUTPUT_ENCODING" ] || NUCORE_OUTPUT_ENCODING="$default_encoding"
|
||||
NUCORE_OUTPUT_ENCODING="$(nucore__norm_encoding "$NUCORE_OUTPUT_ENCODING")"
|
||||
[ -n "$NUCORE_INPUT_ENCODING" ] || NUCORE_INPUT_ENCODING="$NUCORE_OUTPUT_ENCODING"
|
||||
NUCORE_INPUT_ENCODING="$(nucore__norm_encoding "$NUCORE_INPUT_ENCODING")"
|
||||
}
|
||||
[ -n "$NUCORE_LANG" -a -z "$LANG" ] && export NUCORE_LANG LANG="$NUCORE_LANG"
|
||||
nucore__init_encoding
|
||||
|
||||
function noerror() {
|
||||
# lancer la commande "$@" et masquer son code de retour
|
||||
[ $# -gt 0 ] || set :
|
||||
"$@" || return 0
|
||||
}
|
||||
|
||||
function noout() {
|
||||
# lancer la commande "$@" en supprimant sa sortie standard
|
||||
[ $# -gt 0 ] || return 0
|
||||
"$@" >/dev/null
|
||||
}
|
||||
|
||||
function noerr() {
|
||||
# lancer la commande "$@" en supprimant sa sortie d'erreur
|
||||
[ $# -gt 0 ] || return 0
|
||||
"$@" 2>/dev/null
|
||||
}
|
||||
|
||||
function isatty() {
|
||||
# tester si STDOUT n'est pas une redirection
|
||||
tty -s <&1
|
||||
}
|
||||
|
||||
function in_isatty() {
|
||||
# tester si STDIN n'est pas une redirection
|
||||
tty -s
|
||||
}
|
||||
|
||||
function out_isatty() {
|
||||
# tester si STDOUT n'est pas une redirection. identique à isatty()
|
||||
tty -s <&1
|
||||
}
|
||||
|
||||
function err_isatty() {
|
||||
# tester si STDERR n'est pas une redirection
|
||||
tty -s <&2
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
function tooenc() {
|
||||
# $1 étant une chaine encodée en utf-8, l'afficher dans l'encoding de sortie $2
|
||||
# qui vaut par défaut $NUCORE_OUTPUT_ENCODING
|
||||
local value="$1" to="${2:-$NUCORE_OUTPUT_ENCODING}"
|
||||
if [ "$to" == "$NUCORE__UTF8" ]; then
|
||||
recho "$value"
|
||||
else
|
||||
iconv -f -utf-8 -t "$to" <<<"$value"
|
||||
fi
|
||||
}
|
||||
function uecho() { tooenc "$*"; }
|
||||
|
||||
function tooenc_() {
|
||||
# $1 étant une chaine encodée en utf-8, l'afficher sans passer à la ligne dans
|
||||
# l'encoding de sortie $2 qui vaut par défaut $NUCORE_OUTPUT_ENCODING
|
||||
local value="$1" to="${2:-$NUCORE_OUTPUT_ENCODING}"
|
||||
if [ "$to" == "$NUCORE__UTF8" ]; then
|
||||
recho_ "$value"
|
||||
else
|
||||
recho_ "$value" | iconv -f utf-8 -t "$to"
|
||||
fi
|
||||
}
|
||||
function uecho_() { tooenc_ "$*"; }
|
||||
|
||||
# faut-il dater les messages de etitle, estep, ebegin?
|
||||
# Faire NUCORE_EDATE=1 en début de script pour activer cette fonctionnalité
|
||||
export NUCORE_EDATE
|
||||
function __edate() { [ -n "$NUCORE_EDATE" ] && date +"[%d/%m/%Y-%H:%M:%S] "; }
|
||||
|
||||
export NUCORE_ELOG_OVERWRITE
|
||||
function __set_no_colors() { :; }
|
||||
function elogto() {
|
||||
# Activer NUCORE_EDATE et rediriger STDOUT et STDERR vers le fichier $1
|
||||
# Si deux fichiers sont spécifiés, rediriger STDOUT vers $1 et STDERR vers $2
|
||||
# Si aucun fichier n'est spécifié, ne pas faire de redirection
|
||||
# Si la redirection est activée, forcer l'utilisation de l'encoding UTF8
|
||||
# Si NUCORE_ELOG_OVERWRITE=1, alors le fichier en sortie est écrasé. Sinon, les
|
||||
# lignes en sortie lui sont ajoutées
|
||||
NUCORE_EDATE=1
|
||||
if [ -n "$1" -a -n "$2" ]; then
|
||||
LANG=fr_FR.UTF8
|
||||
NUCORE_OUTPUT_ENCODING="$NUCORE__UTF8"
|
||||
__set_no_colors 1
|
||||
if [ -n "$NUCORE_ELOG_OVERWRITE" ]; then
|
||||
exec >"$1" 2>"$2"
|
||||
else
|
||||
exec >>"$1" 2>>"$2"
|
||||
fi
|
||||
elif [ -n "$1" ]; then
|
||||
LANG=fr_FR.UTF8
|
||||
NUCORE_OUTPUT_ENCODING="$NUCORE__UTF8"
|
||||
__set_no_colors 1
|
||||
if [ -n "$NUCORE_ELOG_OVERWRITE" ]; then
|
||||
exec >"$1" 2>&1
|
||||
else
|
||||
exec >>"$1" 2>&1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# variables utilisées pour l'affichage indenté des messages et des titres
|
||||
# NUCORE__ESTACK est la liste des invocations de 'ebegin' et 'etitle' en cours
|
||||
# NUCORE__TLEVEL est l'indentation à appliquer avant d'afficher le message
|
||||
export NUCORE__ESTACK NUCORE__TLEVEL
|
||||
function __indent() {
|
||||
# indenter les lignes de $1, sauf la première
|
||||
if [ "${1/
|
||||
/}" != "$1" ]; then
|
||||
sed "2,\$s/^/${NUCORE__TLEVEL}/g" <<<"$1"
|
||||
else
|
||||
recho "$1"
|
||||
fi
|
||||
}
|
||||
# fonctions à surcharger pour modifier la façon dont les messages sont affichés
|
||||
function __eerror() { tooenc "$(__edate)${NUCORE__TLEVEL}ERROR $(__indent "$1")"; }
|
||||
function __ewarn() { tooenc "$(__edate)${NUCORE__TLEVEL}WARNING $(__indent "$1")"; }
|
||||
function __enote() { tooenc "$(__edate)${NUCORE__TLEVEL}NOTE $(__indent "$1")"; }
|
||||
function __ebanner() {
|
||||
local maxi="${COLUMNS:-80}"
|
||||
local -a lines
|
||||
local psfix line
|
||||
|
||||
psfix="$(__edate)${NUCORE__TLEVEL}"
|
||||
while [ ${#psfix} -lt $maxi ]; do psfix="$psfix="; done
|
||||
|
||||
tooenc "$psfix"
|
||||
maxi=$(($maxi - 1))
|
||||
array_xsplitl lines "$1"
|
||||
for line in "" "${lines[@]}" ""; do
|
||||
line="$(__edate)${NUCORE__TLEVEL}= $line"
|
||||
if [ ${#line} -le $maxi ]; then
|
||||
while [ ${#line} -lt $maxi ]; do line="$line "; done
|
||||
line="$line="
|
||||
fi
|
||||
tooenc "$line"
|
||||
done
|
||||
tooenc "$psfix"
|
||||
}
|
||||
function __eimportant() { tooenc "$(__edate)${NUCORE__TLEVEL}IMPORTANT $(__indent "$1")"; }
|
||||
function __eattention() { tooenc "$(__edate)${NUCORE__TLEVEL}ATTENTION $(__indent "$1")"; }
|
||||
function __einfo() { tooenc "$(__edate)${NUCORE__TLEVEL}INFO $(__indent "$1")"; }
|
||||
function __eecho() { tooenc "$(__edate)${NUCORE__TLEVEL}$(__indent "$1")"; }
|
||||
function __eecho_() { tooenc_ "$(__edate)${NUCORE__TLEVEL}$(__indent "$1")"; }
|
||||
function __edebug() { tooenc "$(__edate)${NUCORE__TLEVEL}DEBUG $(__indent "$1")"; }
|
||||
function __estep() { tooenc "$(__edate)${NUCORE__TLEVEL}. $(__indent "$1")"; }
|
||||
function __estepe() { tooenc "$(__edate)${NUCORE__TLEVEL}.E $(__indent "$1")"; }
|
||||
function __estepw() { tooenc "$(__edate)${NUCORE__TLEVEL}.W $(__indent "$1")"; }
|
||||
function __estepn() { tooenc "$(__edate)${NUCORE__TLEVEL}.N $(__indent "$1")"; }
|
||||
function __estepi() { tooenc "$(__edate)${NUCORE__TLEVEL}.I $(__indent "$1")"; }
|
||||
function __estep_() { tooenc_ "$(__edate)${NUCORE__TLEVEL}. $(__indent "$1")"; }
|
||||
function __estepe_() { tooenc_ "$(__edate)${NUCORE__TLEVEL}.E $(__indent "$1")"; }
|
||||
function __estepw_() { tooenc_ "$(__edate)${NUCORE__TLEVEL}.W $(__indent "$1")"; }
|
||||
function __estepn_() { tooenc_ "$(__edate)${NUCORE__TLEVEL}.N $(__indent "$1")"; }
|
||||
function __estepi_() { tooenc_ "$(__edate)${NUCORE__TLEVEL}.I $(__indent "$1")"; }
|
||||
function __etitle() { tooenc "$(__edate)${NUCORE__TLEVEL}=== $(__indent "$1")"; }
|
||||
function __ebegin() { tooenc_ "$(__edate)${NUCORE__TLEVEL}. $(__indent "$1"): "; }
|
||||
function __edoto() { echo_ "."; }
|
||||
function __edotw() { echo_ "w"; }
|
||||
function __edotx() { echo_ "x"; }
|
||||
function __edotp() { echo_ "+"; }
|
||||
function __edotd() { tooenc "($1)"; }
|
||||
function __eendo() { echo "[ok]"; }
|
||||
function __eendx() { echo "[error]"; }
|
||||
PRETTYOPTS=()
|
||||
function set_verbosity() { :;}
|
||||
function set_interaction() { :;}
|
||||
function show_error() {
|
||||
# tester respectivement si on doit afficher les messages d'erreur,
|
||||
# d'avertissement, d'information, de debug
|
||||
return 0
|
||||
}
|
||||
function show_warn() {
|
||||
return 0
|
||||
}
|
||||
function show_info() {
|
||||
return 0
|
||||
}
|
||||
function show_verbose() {
|
||||
return 0
|
||||
}
|
||||
function show_debug() {
|
||||
[ -n "$DEBUG" ]
|
||||
}
|
||||
function check_verbosity() {
|
||||
return 0
|
||||
}
|
||||
function get_verbosity_option() { :;}
|
||||
|
||||
# note: toutes les fonctions d'affichage e* écrivent sur stderr
|
||||
NUCORE__EPENDING=
|
||||
function eflush() {
|
||||
# Afficher les messages en attente
|
||||
if [ -n "$NUCORE__EPENDING" ]; then recho "$NUCORE__EPENDING" 1>&2; NUCORE__EPENDING=; fi
|
||||
}
|
||||
function eclearp() {
|
||||
# Supprimer les message en attente
|
||||
NUCORE__EPENDING=
|
||||
}
|
||||
function eerror() {
|
||||
# Afficher un message d'erreur
|
||||
show_error || return; eflush; __eerror "$*" 1>&2
|
||||
}
|
||||
|
||||
function die() {
|
||||
[ $# -gt 0 ] && eerror "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function exit_with {
|
||||
if [ $# -gt 0 ]; then "$@"; fi
|
||||
exit $?
|
||||
}
|
||||
|
||||
function die_with {
|
||||
[ $# -gt 0 ] && eerror "$1"
|
||||
shift
|
||||
[ $# -gt 0 ] && "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function die_unless() {
|
||||
# Afficher $1 et quitter le script avec die() si la commande $2..@ retourne FAUX
|
||||
local du__r
|
||||
local du__msg="$1"; shift
|
||||
if [ $# -eq 0 ]; then
|
||||
[ -n "$du__msg" ] && _eerror "$du__msg"
|
||||
exit 1
|
||||
elif "$@"; then
|
||||
:
|
||||
else
|
||||
du__r=$?
|
||||
[ -n "$du__msg" ] && _eerror "$du__msg"
|
||||
exit $du__r
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
function eerror_unless() {
|
||||
# Afficher $1 avec eerror() si la commande $2..@ retourne FAUX. dans tous les cas, retourner le code de retour de la commande.
|
||||
local eu__r
|
||||
local eu__msg="$1"; shift
|
||||
if [ $# -eq 0 ]; then
|
||||
[ -n "$eu__msg" ] && _eerror "$eu__msg"
|
||||
return 1
|
||||
elif "$@"; then
|
||||
:
|
||||
else
|
||||
eu__r=$?
|
||||
[ -n "$eu__msg" ] && _eerror "$eu__msg"
|
||||
return $eu__r
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
function die_if() {
|
||||
# Afficher $1 et quitter le script avec die() si la commande $2..@ retourne VRAI. sinon, retourner le code de retour de la commande
|
||||
local di__r=0
|
||||
local di__msg="$1"; shift
|
||||
[ $# -eq 0 ] && return 0
|
||||
if "$@"; then
|
||||
[ -n "$di__msg" ] && _eerror "$di__msg"
|
||||
exit 0
|
||||
else
|
||||
di__r=$?
|
||||
fi
|
||||
return $di__r
|
||||
}
|
||||
|
||||
function eerror_if() {
|
||||
# Afficher $1 avec eerror() si la commande $2..@ retourne VRAI. dans tous les cas, retourner le code de retour de la commande.
|
||||
local ei__r=0
|
||||
local ei__msg="$1"; shift
|
||||
[ $# -eq 0 ] && return 0
|
||||
if "$@"; then
|
||||
[ -n "$ei__msg" ] && _eerror "$ei__msg"
|
||||
else
|
||||
ei__r=$?
|
||||
fi
|
||||
return $ei__r
|
||||
}
|
||||
|
||||
function ewarn() {
|
||||
# Afficher un message d'avertissement
|
||||
show_warn || return; eflush; __ewarn "$*" 1>&2
|
||||
}
|
||||
function enote() {
|
||||
# Afficher un message d'information de même niveau qu'un avertissement
|
||||
show_info || return; eflush; __enote "$*" 1>&2
|
||||
}
|
||||
function ebanner() {
|
||||
# Afficher un message très important encadré, puis attendre 5 secondes
|
||||
show_error || return; eflush; __ebanner "$*" 1>&2; sleep 5
|
||||
}
|
||||
function eimportant() {
|
||||
# Afficher un message très important
|
||||
show_error || return; eflush; __eimportant "$*" 1>&2
|
||||
}
|
||||
function eattention() {
|
||||
# Afficher un message important
|
||||
show_warn || return; eflush; __eattention "$*" 1>&2
|
||||
}
|
||||
function einfo() {
|
||||
# Afficher un message d'information
|
||||
show_info || return; eflush; __einfo "$*" 1>&2
|
||||
}
|
||||
function eecho() {
|
||||
# Afficher un message d'information sans préfixe
|
||||
show_info || return; eflush; __eecho "$*" 1>&2
|
||||
}
|
||||
function eecho_() {
|
||||
show_info || return; eflush; __eecho_ "$*" 1>&2
|
||||
}
|
||||
function edebug() {
|
||||
# Afficher un message de debug
|
||||
show_debug || return; eflush; __edebug "$*" 1>&2
|
||||
}
|
||||
function trace() {
|
||||
# Afficher la commande $1..@, la lancer, puis afficher son code d'erreur si une
|
||||
# erreur se produit
|
||||
local r cmd="$(qvals "$@")"
|
||||
show_info && { eflush; __eecho "\$ $cmd" 1>&2; }
|
||||
"$@"; r=$?
|
||||
if [ $r -ne 0 ]; then
|
||||
if show_info; then
|
||||
eflush; __eecho "^ [EC #$r]" 1>&2
|
||||
elif show_error; then
|
||||
eflush; __eecho "^ $cmd [EC #$r]" 1>&2;
|
||||
fi
|
||||
fi
|
||||
return $r
|
||||
}
|
||||
function trace_error() {
|
||||
# Lancer la commande $1..@, puis afficher son code d'erreur si une erreur se
|
||||
# produit. La différence avec trace() est que la commande n'est affichée que si
|
||||
# une erreur se produit.
|
||||
local r
|
||||
"$@"; r=$?
|
||||
if [ $r -ne 0 ]; then
|
||||
local cmd="$(qvals "$@")"
|
||||
show_error && { eflush; __eecho "^ $cmd [EC #$r]" 1>&2; }
|
||||
fi
|
||||
return $r
|
||||
}
|
||||
|
||||
function etitle() {
|
||||
# Afficher le titre $1, qui est le début éventuel d'une section. Les section
|
||||
# imbriquées sont affichées indentées. La section n'est pas terminée, et il faut
|
||||
# la terminer explicitement avec eend, sauf dans certains cas précis:
|
||||
# - Si $2..$* est spécifié, c'est une commande. Lancer la commande dans le
|
||||
# contexte de la section. Puis, la section est automatiquement terminée sauf si
|
||||
# l'option -s est spécifiée, auquel cas la section reste ouverte. Si l'option -p
|
||||
# est spécifiée, eclearp() est appelé pour purger les messages en attente
|
||||
# - Dans le cas contraire, l'option -s est ignorée: la section doit toujours
|
||||
# être terminée explicitement.
|
||||
# La fonction etitled() est comme etitle(), mais le titre n'est pas affiché
|
||||
# immédiatement. L'affichage effectif est effectué dès qu'une fonction e* est
|
||||
# utilisée. Ceci permet, avec la fonction eclearp(), de ne pas afficher de titre
|
||||
# pour une section vide.
|
||||
local __t_deferred=
|
||||
__t_etitle "$@"
|
||||
}
|
||||
function etitled() {
|
||||
local __t_deferred=1
|
||||
__t_etitle "$@"
|
||||
}
|
||||
function __t_etitle() {
|
||||
local __t_eend=default
|
||||
local __t_clearp=
|
||||
while [ -n "$1" ]; do
|
||||
if [ "$1" == "--" ]; then
|
||||
shift
|
||||
break
|
||||
elif [ "$1" == "-s" ]; then
|
||||
__t_eend=
|
||||
shift
|
||||
elif [ "$1" == "--eend" ]; then
|
||||
__t_eend=1
|
||||
shift
|
||||
elif [ "$1" == "-p" ]; then
|
||||
__t_clearp=1
|
||||
shift
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
local __t_title="$1"; shift
|
||||
local __t_s=0
|
||||
# etitle
|
||||
[ -n "$NUCORE__ESTACK" ] && NUCORE__TLEVEL="${NUCORE__TLEVEL} "
|
||||
NUCORE__ESTACK="$NUCORE__ESTACK:t"
|
||||
if show_info; then
|
||||
if [ -n "$__t_deferred" ]; then
|
||||
NUCORE__EPENDING="${NUCORE__EPENDING:+$NUCORE__EPENDING
|
||||
}$(__etitle "$__t_title")"
|
||||
else
|
||||
eflush
|
||||
__etitle "$__t_title" 1>&2
|
||||
fi
|
||||
fi
|
||||
# commande
|
||||
if [ $# -gt 0 ]; then
|
||||
"$@"
|
||||
__t_s=$?
|
||||
[ "$__t_eend" == "default" ] && __t_eend=1
|
||||
fi
|
||||
# eend
|
||||
[ "$__t_eend" == "default" ] && __t_eend=
|
||||
if [ -n "$__t_eend" ]; then
|
||||
eend $__t_s
|
||||
[ -n "$__t_clearp" ] && eclearp
|
||||
fi
|
||||
return $__t_s
|
||||
}
|
||||
function estep() {
|
||||
# Afficher la description d'une opération. Cette fonction est particulièrement
|
||||
# appropriée dans le contexte d'un etitle.
|
||||
# Les variantes e (error), w (warning), n (note), i (info) permettent d'afficher
|
||||
# des couleurs différentes, mais toutes sont du niveau info.
|
||||
show_info || return; eflush; __estep "$*" 1>&2
|
||||
}
|
||||
function estepe() {
|
||||
show_info || return; eflush; __estepe "$*" 1>&2
|
||||
}
|
||||
function estepw() {
|
||||
show_info || return; eflush; __estepw "$*" 1>&2
|
||||
}
|
||||
function estepn() {
|
||||
show_info || return; eflush; __estepn "$*" 1>&2
|
||||
}
|
||||
function estepi() {
|
||||
show_info || return; eflush; __estepi "$*" 1>&2
|
||||
}
|
||||
function estep_() {
|
||||
show_info || return; eflush; __estep_ "$*" 1>&2
|
||||
}
|
||||
function estepe_() {
|
||||
show_info || return; eflush; __estepe_ "$*" 1>&2
|
||||
}
|
||||
function estepw_() {
|
||||
show_info || return; eflush; __estepw_ "$*" 1>&2
|
||||
}
|
||||
function estepn_() {
|
||||
show_info || return; eflush; __estepn_ "$*" 1>&2
|
||||
}
|
||||
function estepi_() {
|
||||
show_info || return; eflush; __estepi_ "$*" 1>&2
|
||||
}
|
||||
function ebegin() {
|
||||
# Afficher le message $1, qui décrit le début d'une opération. Cette fonction
|
||||
# débute une section, qu'il faut terminer avec eend.
|
||||
# Si $2..$* est spécifié, c'est une commande. Lancer la commande dans le
|
||||
# contexte de la section. Puis, la section est terminée automatiquement, sauf si
|
||||
# l'option -s est spécifiée, auquel cas la section reste ouverte.
|
||||
local __b_eend=default
|
||||
while [ -n "$1" ]; do
|
||||
if [ "$1" == "--" ]; then
|
||||
shift
|
||||
break
|
||||
elif [ "$1" == "-s" ]; then
|
||||
__b_eend=
|
||||
shift
|
||||
elif [ "$1" == "--eend" ]; then
|
||||
__b_eend=1
|
||||
shift
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
local __b_msg="$1"; shift
|
||||
local __b_s=0
|
||||
# ebegin
|
||||
NUCORE__ESTACK="$NUCORE__ESTACK:b"
|
||||
if show_info; then
|
||||
eflush
|
||||
__ebegin "$__b_msg" 1>&2
|
||||
fi
|
||||
# commande
|
||||
if [ $# -gt 0 ]; then
|
||||
"$@"
|
||||
__b_s=$?
|
||||
[ "$__b_eend" == "default" ] && __b_eend=1
|
||||
fi
|
||||
# eend
|
||||
[ "$__b_eend" == "default" ] && __b_eend=
|
||||
[ -n "$__b_eend" ] && eend $__b_s
|
||||
return $__b_s
|
||||
}
|
||||
function edot() {
|
||||
# Afficher une étape d'une opération, matérialisée par un point '.' ou une
|
||||
# croix 'x' en cas de succès ou d'erreur. Cette fonction est particulièrement
|
||||
# appropriée dans le contexte d'un ebegin.
|
||||
local s=$?
|
||||
show_info || return
|
||||
eflush
|
||||
[ -n "$1" ] && s="$1"
|
||||
shift
|
||||
if [ "$s" == "0" ]; then
|
||||
__edoto 1>&2
|
||||
else
|
||||
__edotx 1>&2
|
||||
fi
|
||||
show_verbose && [ $# -gt 0 ] && __edotd "$*" 1>&2
|
||||
return $s
|
||||
}
|
||||
function edotw() {
|
||||
# Afficher un avertissement comme étape d'une opération, matérialisée par une
|
||||
# lettre 'w' (typiquement de couleur jaune). Cette fonction est particulièrement
|
||||
# appropriée dans le contexte d'un ebegin.
|
||||
local s=$?
|
||||
show_info || return
|
||||
eflush
|
||||
[ -n "$1" ] && s="$1"
|
||||
shift
|
||||
__edotw 1>&2
|
||||
show_verbose && [ $# -gt 0 ] && __edotd "$*" 1>&2
|
||||
return $s
|
||||
}
|
||||
function ewait() {
|
||||
# Afficher les étapes d'une opération qui dure, matérialisées par des '+' toutes
|
||||
# les secondes tant que le processus $1 tourne.
|
||||
# A utiliser de cette manière:
|
||||
# ebegin "msg"
|
||||
# cmd &
|
||||
# ewait $!
|
||||
# eend
|
||||
[ -n "$1" ] || return 1
|
||||
if show_info; then
|
||||
local count=2
|
||||
eflush
|
||||
little_sleep # certains processus retournent tout de suite
|
||||
while is_running "$1"; do
|
||||
sleep 1
|
||||
if [ $count -gt 0 ]; then
|
||||
# attendre 2 secondes avant de commencer à afficher des '+'
|
||||
count=$(($count - 1))
|
||||
else
|
||||
__edotp 1>&2
|
||||
fi
|
||||
done
|
||||
# terminer par un '.'
|
||||
__edoto 1>&2
|
||||
else
|
||||
# ne rien afficher, mais attendre quand même la fin de l'opération
|
||||
wait "$1"
|
||||
fi
|
||||
}
|
||||
function eend() {
|
||||
# Terminer une section.
|
||||
# Avec l'option -c, remettre à zéro toutes les informations de section
|
||||
# Si la section en cours est un ebegin, afficher la fin de l'opération: [ok] ou
|
||||
# [error] en fonction du code de retour de la dernière commande (ou de $1 si
|
||||
# cette valeur est donnée)
|
||||
# Si la section en cours est un etitle, marquer la fin de la section concernée
|
||||
# par le titre.
|
||||
local s=$?
|
||||
if [ "$1" == "-c" ]; then
|
||||
NUCORE__ESTACK=
|
||||
NUCORE__TLEVEL=
|
||||
elif [ "${NUCORE__ESTACK%:b}" != "$NUCORE__ESTACK" ]; then
|
||||
# terminer ebegin
|
||||
NUCORE__ESTACK="${NUCORE__ESTACK%:b}"
|
||||
show_info || return
|
||||
eflush
|
||||
[ -n "$1" ] && s="$1"
|
||||
if [ "$s" == "0" ]; then
|
||||
__eendo 1>&2
|
||||
else
|
||||
__eendx 1>&2
|
||||
fi
|
||||
elif [ "${NUCORE__ESTACK%:t}" != "$NUCORE__ESTACK" ]; then
|
||||
# terminer etitle -s
|
||||
NUCORE__ESTACK="${NUCORE__ESTACK%:t}"
|
||||
NUCORE__TLEVEL="${NUCORE__TLEVEL% }"
|
||||
fi
|
||||
}
|
||||
function __elinedots() {
|
||||
ebegin "$1"
|
||||
local line
|
||||
if show_debug; then
|
||||
while read line; do
|
||||
__edoto 1>&2
|
||||
__edotd "$line" 1>&2
|
||||
done
|
||||
else
|
||||
while read line; do
|
||||
__edoto 1>&2
|
||||
done
|
||||
fi
|
||||
eend
|
||||
}
|
||||
function elinedots() {
|
||||
# Afficher un message comme avec ebegin "$1", puis afficher un point '.' pour
|
||||
# chaque ligne lue sur stdin. Cela permet de suivre une opération. En mode
|
||||
# DEBUG, afficher la ligne affichée plutôt qu'un point.
|
||||
# Si $2..$* sont spécifiés, lancer la commande et suivre sa sortie. Ainsi,
|
||||
# 'elinedots msg cmd args' est un raccourci pour 'cmd args | elinedots msg'
|
||||
local msg="$1"; shift
|
||||
if [ $# -gt 0 ]; then
|
||||
"$@" | __elinedots "$msg"
|
||||
else
|
||||
__elinedots "$msg"
|
||||
fi
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.path "Fonctions de base: gestion des chemins et des fichiers"
|
||||
require: base.core
|
||||
|
||||
function: in_path "tester l'existence d'un programme dans le PATH"
|
||||
function in_path() {
|
||||
|
|
|
@ -8,12 +8,12 @@ if [ -z "$NUCOREDIR" -o "$NUCOREDIR" != "$NUCOREINIT" ]; then
|
|||
fi
|
||||
##@include base.init.sh
|
||||
##@include base.core.sh
|
||||
##@include base.str.sh
|
||||
##@include base.arr.sh
|
||||
##@include base.io.sh
|
||||
##@include base.eval.sh
|
||||
##@include base.string.sh
|
||||
##@include base.array.sh
|
||||
##@include base.output.sh
|
||||
##@include base.input.sh
|
||||
##@include base.split.sh
|
||||
##@include base.path.sh
|
||||
##@include base.args.sh
|
||||
module: base "Chargement de tous les modules base.*"
|
||||
require: base.init base.core base.str base.arr base.io base.eval base.split base.path base.args
|
||||
require: base.init base.core base.string base.array base.output base.input base.split base.path base.args
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.split "Fonctions de base: analyse et découpage de valeurs"
|
||||
require: base.arr
|
||||
|
||||
function: splitfsep "\
|
||||
Découper \$1 de la forme first[SEPsecond] entre first, qui est placé dans la
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
##@cooked nocomments
|
||||
module: base.str "Fonctions de base: gestion des valeurs chaines"
|
||||
module: base.string "Fonctions de base: gestion des valeurs chaines"
|
||||
|
||||
function: strmid "Afficher la plage \$1 de la valeur \$2..*
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
source "$(dirname -- "$0")/../src/nucore.sh" || exit 1
|
||||
#NUCORE_NO_DISABLE_SET_X=1
|
||||
|
||||
eerror "erreur"
|
||||
ewarn "warning"
|
||||
enote "note"
|
||||
ebanner "banner"
|
||||
eimportant "important"
|
||||
eattention "attention"
|
||||
einfo "info"
|
||||
eecho "vanilla"
|
||||
edebug "debug"
|
||||
|
||||
etitle "section"
|
||||
|
||||
estep "step"
|
||||
estepe "stepe"
|
||||
estepw "stepw"
|
||||
estepn "stepn"
|
||||
estepi "stepi"
|
||||
ebegin "begin"
|
||||
edot
|
||||
edotw
|
||||
eend
|
||||
echo "\
|
||||
line1
|
||||
line2
|
||||
line3" | elinedots "lines"
|
||||
|
||||
eend
|
||||
|
Loading…
Reference in New Issue