diff --git a/bash/src/_output_color.sh b/bash/src/_output_color.sh new file mode 100644 index 0000000..0ff7718 --- /dev/null +++ b/bash/src/_output_color.sh @@ -0,0 +1,81 @@ +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 + +function __esection() { + local -a lines + local lsep prefix="$(__edate)${NULIB__TLEVEL}" + local length="${COLUMNS:-80}" + setx lsep=__complete "$prefix" "$length" - + + tooenc "$COULEUR_BLEUE$lsep$COULEUR_NORMALE" + [ -n "$*" ] || return 0 + length=$((length - 1)) + setx -a lines=echo "$1" + for line in "${lines[@]}"; do + setx line=__complete "$prefix- $line" "$length" + tooenc "$COULEUR_BLEUE$line-$COULEUR_NORMALE" + done + tooenc "$COULEUR_BLEUE$lsep$COULEUR_NORMALE" +} +function __etitle() { + local -a lines; local maxlen=0 + local prefix="$(__edate)${NULIB__TLEVEL}" + + setx -a lines=echo "$1" + for line in "${lines[@]}"; do + [ ${#line} -gt $maxlen ] && maxlen=${#line} + tooenc "${prefix}${COULEUR_BLEUE}T $line$COULEUR_NORMALE" + done + maxlen=$((maxlen + 2)) + tooenc "${prefix}${COULEUR_BLEUE}T$(__complete "" $maxlen -)${COULEUR_NORMALE}" +} +function __edesc() { + local -a lines + local prefix="$(__edate)${NULIB__TLEVEL}" + + setx -a lines=echo "$1" + for line in "${lines[@]}"; do + tooenc "${prefix}${COULEUR_BLEUE}>${COULEUR_NORMALE} $line" + done +} +function __ebanner() { + local -a lines + local lsep prefix="$(__edate)${NULIB__TLEVEL}" + local length="${COLUMNS:-80}" + setx lsep=__complete "$prefix" "$length" = + + tooenc "$COULEUR_ROUGE$lsep" + length=$((length - 1)) + setx -a lines=echo "$1" + for line in "" "${lines[@]}" ""; do + setx line=__complete "$prefix= $line" "$length" + tooenc "$line=" + done + tooenc "$lsep$COULEUR_NORMALE" +} +function __eimportant() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}!${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __eattention() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}*${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __eerror() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}E${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __ewarn() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}W${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __enote() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_VERTE}N${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __einfo() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLEUE}I${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __edebug() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}D${COULEUR_NORMALE} $(__indent "$1" " ")"; } + +function __estep() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepe() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepw() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepn() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_VERTE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepi() { tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLEUE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estep_() { tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepe_() { tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepw_() { tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepn_() { tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_VERTE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } +function __estepi_() { tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_BLEUE}.${COULEUR_NORMALE} $(__indent "$1" " ")"; } + +function __ebegin() { local p="." i=" "; tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__indent "$1" " "): "; } +function __edoto() { echo_ "."; } +function __edotw() { echo_ "${COULEUR_JAUNE}w${COULEUR_NORMALE}"; } +function __edotx() { echo_ "${COULEUR_ROUGE}x${COULEUR_NORMALE}"; } +function __edotp() { echo_ "${COULEUR_JAUNE}+${COULEUR_NORMALE}"; } +function __edotd() { tooenc "($1)"; } +function __eendo() { echo "${COULEUR_VERTE}[ok]${COULEUR_NORMALE}"; } +function __eendx() { echo "${COULEUR_ROUGE}[error]${COULEUR_NORMALE}"; } diff --git a/bash/src/_output_vanilla.sh b/bash/src/_output_vanilla.sh new file mode 100644 index 0000000..56fc0d3 --- /dev/null +++ b/bash/src/_output_vanilla.sh @@ -0,0 +1,70 @@ +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 + +function __esection() { + local -a lines + local lsep prefix="$(__edate)${NULIB__TLEVEL}" + local length="${COLUMNS:-80}" + setx lsep=__complete "$prefix" "$length" - + + tooenc "$lsep" + [ -n "$*" ] || return 0 + length=$((length - 1)) + setx -a lines=echo "$1" + for line in "${lines[@]}"; do + setx line=__complete "$prefix- $line" "$length" + tooenc "$line-" + done + tooenc "$lsep" +} +function __etitle() { + local p="TITLE: " i=" " + tooenc "$(__edate)${NULIB__TLEVEL}${p}$(__indent "$1" "$i")" +} +function __edesc() { + local p="DESC: " i=" " + tooenc "$(__edate)${NULIB__TLEVEL}${p}$(__indent "$1" "$i")" +} +function __ebanner() { + local -a lines + local lsep prefix="$(__edate)${NULIB__TLEVEL}" + local length="${COLUMNS:-80}" + setx lsep=__complete "$prefix" "$length" = + + tooenc "$lsep" + length=$((length - 1)) + setx -a lines=echo "$1" + for line in "" "${lines[@]}" ""; do + setx line=__complete "$prefix= $line" "$length" + tooenc "$line=" + done + tooenc "$lsep" +} +function __eimportant() { tooenc "$(__edate)${NULIB__TLEVEL}IMPORTANT! $(__indent "$1" " ")"; } +function __eattention() { tooenc "$(__edate)${NULIB__TLEVEL}ATTENTION! $(__indent "$1" " ")"; } +function __eerror() { tooenc "$(__edate)${NULIB__TLEVEL}ERROR: $(__indent "$1" " ")"; } +function __ewarn() { tooenc "$(__edate)${NULIB__TLEVEL}WARNING: $(__indent "$1" " ")"; } +function __enote() { tooenc "$(__edate)${NULIB__TLEVEL}NOTE: $(__indent "$1" " ")"; } +function __einfo() { tooenc "$(__edate)${NULIB__TLEVEL}INFO: $(__indent "$1" " ")"; } +function __edebug() { tooenc "$(__edate)${NULIB__TLEVEL}DEBUG: $(__indent "$1" " ")"; } +function __eecho() { tooenc "$(__edate)${NULIB__TLEVEL}$(__indent "$1")"; } +function __eecho_() { tooenc_ "$(__edate)${NULIB__TLEVEL}$(__indent "$1")"; } + +function __estep() { tooenc "$(__edate)${NULIB__TLEVEL}. $(__indent "$1" " ")"; } +function __estepe() { tooenc "$(__edate)${NULIB__TLEVEL}.E $(__indent "$1" " ")"; } +function __estepw() { tooenc "$(__edate)${NULIB__TLEVEL}.W $(__indent "$1" " ")"; } +function __estepn() { tooenc "$(__edate)${NULIB__TLEVEL}.N $(__indent "$1" " ")"; } +function __estepi() { tooenc "$(__edate)${NULIB__TLEVEL}.I $(__indent "$1" " ")"; } +function __estep_() { tooenc_ "$(__edate)${NULIB__TLEVEL}. $(__indent "$1" " ")"; } +function __estepe_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.E $(__indent "$1" " ")"; } +function __estepw_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.W $(__indent "$1" " ")"; } +function __estepn_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.N $(__indent "$1" " ")"; } +function __estepi_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.I $(__indent "$1" " ")"; } + +function __ebegin() { tooenc_ "$(__edate)${NULIB__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]"; } diff --git a/bash/src/base.args.sh b/bash/src/base.args.sh index 35e804c..835944f 100644 --- a/bash/src/base.args.sh +++ b/bash/src/base.args.sh @@ -115,7 +115,7 @@ optdesc : description de l'option. cette valeur est facultative. si la description commence par ++, c'est une option avancée qui n'est pas affichée par défaut." function parse_args() { - [ -z "$NULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local NULIB_ARGS_SET_X=1; } + eval "$NULIB__DISABLE_SET_X" local __r= local __DIE='[ -n "$NULIB_ARGS_ONERROR_RETURN" ] && return 1 || die' @@ -139,7 +139,7 @@ function parse_args() { __DEFS=("$@") __parse_args || __r=1 fi - [ -n "$NULIB_ARGS_SET_X" ] && set -x + eval "$NULIB__ENABLE_SET_X" if [ -n "$__r" ]; then eval "$__DIE" fi diff --git a/bash/src/base.input.sh b/bash/src/base.input.sh index a2d9258..fa96cfd 100644 --- a/bash/src/base.input.sh +++ b/bash/src/base.input.sh @@ -24,13 +24,9 @@ function uread() { done } -function is_interaction() { - return 1 -} - -function check_interaction() { - return 0 -} +function set_interaction() { :;} +function is_interaction() { return 1; } +function check_interaction() { return 0; } function get_interaction_option() { :;} function ask_yesno() { diff --git a/bash/src/base.output.sh b/bash/src/base.output.sh index 525c78a..f86e461 100644 --- a/bash/src/base.output.sh +++ b/bash/src/base.output.sh @@ -1,6 +1,7 @@ # -*- 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" +nulib__load: _output_vanilla NULIB__TAB=$'\t' NULIB__LATIN1=iso-8859-1 @@ -155,152 +156,154 @@ function elogto() { export NULIB__ESTACK NULIB__TLEVEL function __indent() { # indenter les lignes de $1, sauf la première - if [ "${1/ -/}" != "$1" ]; then - sed "2,\$s/^/${NULIB__TLEVEL}/g" <<<"$1" - else - recho "$1" - fi -} -# fonctions à surcharger pour modifier la façon dont les messages sont affichés -function __eerror() { tooenc "$(__edate)${NULIB__TLEVEL}ERROR $(__indent "$1")"; } -function __ewarn() { tooenc "$(__edate)${NULIB__TLEVEL}WARNING $(__indent "$1")"; } -function __enote() { tooenc "$(__edate)${NULIB__TLEVEL}NOTE $(__indent "$1")"; } -function __ebanner() { - local maxi="${COLUMNS:-80}" - local prefix="$(__edate)${NULIB__TLEVEL}" lsep line - local -a lines - - lsep="$prefix" - while [ ${#lsep} -lt $maxi ]; do lsep="$lsep="; done - - tooenc "$lsep" - maxi=$(($maxi - 1)) - array_xsplitl lines "$1" - for line in "" "${lines[@]}" ""; do - line="$prefix= $line" - if [ ${#line} -le $maxi ]; then - while [ ${#line} -lt $maxi ]; do line="$line "; done - line="$line=" + local -a lines; local line first=1 + local indent="$NULIB__TLEVEL$2" + setx -a lines=echo "$1" + for line in "${lines[@]}"; do + if [ -n "$first" ]; then + recho "$line" + first= + else + recho "$indent$line" fi - tooenc "$line" done - tooenc "$lsep" } -function __eimportant() { tooenc "$(__edate)${NULIB__TLEVEL}IMPORTANT $(__indent "$1")"; } -function __eattention() { tooenc "$(__edate)${NULIB__TLEVEL}ATTENTION $(__indent "$1")"; } -function __einfo() { tooenc "$(__edate)${NULIB__TLEVEL}INFO $(__indent "$1")"; } -function __eecho() { tooenc "$(__edate)${NULIB__TLEVEL}$(__indent "$1")"; } -function __eecho_() { tooenc_ "$(__edate)${NULIB__TLEVEL}$(__indent "$1")"; } -function __edebug() { tooenc "$(__edate)${NULIB__TLEVEL}DEBUG $(__indent "$1")"; } -function __estep() { tooenc "$(__edate)${NULIB__TLEVEL}. $(__indent "$1")"; } -function __estepe() { tooenc "$(__edate)${NULIB__TLEVEL}.E $(__indent "$1")"; } -function __estepw() { tooenc "$(__edate)${NULIB__TLEVEL}.W $(__indent "$1")"; } -function __estepn() { tooenc "$(__edate)${NULIB__TLEVEL}.N $(__indent "$1")"; } -function __estepi() { tooenc "$(__edate)${NULIB__TLEVEL}.I $(__indent "$1")"; } -function __estep_() { tooenc_ "$(__edate)${NULIB__TLEVEL}. $(__indent "$1")"; } -function __estepe_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.E $(__indent "$1")"; } -function __estepw_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.W $(__indent "$1")"; } -function __estepn_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.N $(__indent "$1")"; } -function __estepi_() { tooenc_ "$(__edate)${NULIB__TLEVEL}.I $(__indent "$1")"; } -function __esection() { - local maxi="${COLUMNS:-80}" - local prefix="$(__edate)${NULIB__TLEVEL}" lsep - lsep="$prefix" - while [ ${#lsep} -lt $maxi ]; do lsep="$lsep="; done - - tooenc "$lsep" - if [ -n "$*" ]; then - tooenc "$prefix$*" - tooenc "$lsep" - fi +function __complete() { + # compléter $1 avec $3 jusqu'à obtenir une taille de $2 caractères + local columns="${COLUMNS:-80}" + local line="$1" maxi="${2:-$columns}" sep="${3:- }" + while [ ${#line} -lt $maxi ]; do + line="$line$sep" + done + echo "$line" } -function __etitle() { tooenc "$(__edate)${NULIB__TLEVEL}=== $(__indent "$1")"; } -function __ebegin() { tooenc_ "$(__edate)${NULIB__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 check_verbosity() { return 0; } function get_verbosity_option() { :;} +# tester respectivement si on doit afficher les messages d'erreur, +# d'avertissement, d'information, de debug +function show_error() { return 0; } +function show_warn() { return 0; } +function show_info() { return 0; } +function show_verbose() { return 0; } +function show_debug() { [ -n "$DEBUG" ]; } + # note: toutes les fonctions d'affichage e* écrivent sur stderr -NULIB__EPENDING= -function eflush() { -# Afficher les messages en attente - if [ -n "$NULIB__EPENDING" ]; then recho "$NULIB__EPENDING" 1>&2; NULIB__EPENDING=; fi + +function esection() { +# Afficher une section. Toutes les indentations sont remises à zéro + show_info || return + eval "$NULIB__DISABLE_SET_X" + NULIB__ESTACK= + NULIB__TLEVEL= + __esection "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } -function eclearp() { -# Supprimer les message en attente - NULIB__EPENDING= + +function etitle() { +# Afficher le titre $1. Le contenu sous des titres imbriqués est affiché +# indenté. le titre n'est pas terminé, et il faut le 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 du titre. Puis, le titre est automatiquement terminé +# - Sinon, le titre doit toujours être terminé explicitement. + local title="$1"; shift + # etitle + [ -n "$NULIB__ESTACK" ] && NULIB__TLEVEL="${NULIB__TLEVEL} " + NULIB__ESTACK="$NULIB__ESTACK:t" + if show_info; then + eval "$NULIB__DISABLE_SET_X" + __etitle "$title" 1>&2 + eval "$NULIB__ENABLE_SET_X" + fi + # commande + local r=0 + if [ $# -gt 0 ]; then + "$@"; r=$? + eend $r + fi + return $r } + +function edesc() { +# Afficher une description sous le titre courant + show_info || return + eval "$NULIB__DISABLE_SET_X" + __edesc "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" +} + +function ebanner() { +# Afficher un message très important encadré, puis attendre 5 secondes + show_error || return + eval "$NULIB__DISABLE_SET_X" + __ebanner "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" + sleep 5 +} + +function eimportant() { +# Afficher un message très important + show_error || return + eval "$NULIB__DISABLE_SET_X" + __eimportant "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" +} + +function eattention() { +# Afficher un message important + show_warn || return + eval "$NULIB__DISABLE_SET_X" + __eattention "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" +} + function eerror() { # Afficher un message d'erreur - show_error || return; eflush; __eerror "$*" 1>&2 + show_error || return + eval "$NULIB__DISABLE_SET_X" + __eerror "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } 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 + local msg="$1"; shift + local r=1 if [ $# -eq 0 ]; then - [ -n "$eu__msg" ] && eerror "$eu__msg" - return 1 - elif "$@"; then - : + [ -n "$msg" ] && eerror "$msg" else - eu__r=$? - [ -n "$eu__msg" ] && eerror "$eu__msg" - return $eu__r + "$@"; r=$? + if [ $r -ne 0 -a -n "$msg" ]; then + eerror "$msg" + fi fi - return 0 + return $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=$? + local msg="$1"; shift + local r=0 + if [ $# -gt 0 ]; then + "$@"; r=$? + if [ $r -eq 0 -a -n "$msg" ]; then + eerror "$msg" + fi fi - return $ei__r + return $r } function set_die_return() { - NULIB_DIE="return 1" + NULIB__DIE="return 1" } function die() { [ $# -gt 0 ] && eerror "$@" - local die="${NULIB_DIE:-exit 1}" + local die="${NULIB__DIE:-exit 1}" eval "$die" || return } @@ -308,41 +311,44 @@ function die_with { [ $# -gt 0 ] && eerror "$1" shift [ $# -gt 0 ] && "$@" - local die="${NULIB_DIE:-exit 1}" + local die="${NULIB__DIE:-exit 1}" eval "$die" || return } 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 - local du__die="${NULIB_DIE:-exit 1}" + local msg="$1"; shift + local die="${NULIB__DIE:-exit 1}" + local r=1 if [ $# -eq 0 ]; then - [ -n "$du__msg" ] && eerror "$du__msg" - eval "$du__die" || return - elif "$@"; then - : + [ -n "$msg" ] && eerror "$msg" else - du__r=$? - [ -n "$du__msg" ] && eerror "$du__msg" - eval "${du__die% *} $du__r" || return + "$@"; r=$? + if [ $r -ne 0 -a -n "$msg" ]; then + eerror "$msg" + fi fi - return 0 + if [ $r -ne 0 ]; then + eval "${die% *} $r" || return $r + fi + return $r } 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 - local di__die="${NULIB_DIE:-exit 1}" - [ $# -eq 0 ] && return 0 - if "$@"; then - [ -n "$di__msg" ] && eerror "$di__msg" - eval "${di__die% *} 0" || return - else - di__r=$? + local msg="$1"; shift + local die="${NULIB__DIE:-exit 1}" + local r=0 + if [ $# -gt 0 ]; then + "$@"; r=$? + if [ $r -eq 0 -a -n "$msg" ]; then + eerror "$msg" + fi fi - return $di__r + if [ $r -eq 0 ]; then + eval "${die% *} $r" || return $r + fi + return $r } function exit_with { @@ -352,54 +358,59 @@ function exit_with { function ewarn() { # Afficher un message d'avertissement - show_warn || return; eflush; __ewarn "$*" 1>&2 + show_warn || return + eval "$NULIB__DISABLE_SET_X" + __ewarn "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } + 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 + show_info || return + eval "$NULIB__DISABLE_SET_X" + __enote "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } + function einfo() { # Afficher un message d'information - show_info || return; eflush; __einfo "$*" 1>&2 + show_info || return + eval "$NULIB__DISABLE_SET_X" + __einfo "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } + function eecho() { # Afficher un message d'information sans préfixe - show_info || return; eflush; __eecho "$*" 1>&2 + show_info || return + eval "$NULIB__DISABLE_SET_X" + __eecho "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } + function eecho_() { - show_info || return; eflush; __eecho_ "$*" 1>&2 -} -function edebug() { -# Afficher un message de debug - show_debug || return; eflush; __edebug "$*" 1>&2 + show_info || return + eval "$NULIB__DISABLE_SET_X" + __eecho_ "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } + 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; } + show_info && { __eecho "\$ $cmd" 1>&2; } "$@"; r=$? if [ $r -ne 0 ]; then if show_info; then - eflush; __eecho "^ [EC #$r]" 1>&2 + __eecho "^ [EC #$r]" 1>&2 elif show_error; then - eflush; __eecho "^ $cmd [EC #$r]" 1>&2; + __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 @@ -408,118 +419,36 @@ function trace_error() { "$@"; r=$? if [ $r -ne 0 ]; then local cmd="$(qvals "$@")" - show_error && { eflush; __eecho "^ $cmd [EC #$r]" 1>&2; } + if show_error; then + __eecho "^ $cmd [EC #$r]" 1>&2 + fi fi return $r } -function esection() { - show_info || return; eflush; __esection "$*" 1>&2 +function edebug() { +# Afficher un message de debug + show_debug || return + eval "$NULIB__DISABLE_SET_X" + __edebug "$*" 1>&2 + eval "$NULIB__ENABLE_SET_X" } -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 "$NULIB__ESTACK" ] && NULIB__TLEVEL="${NULIB__TLEVEL} " - NULIB__ESTACK="$NULIB__ESTACK:t" - if show_info; then - if [ -n "$__t_deferred" ]; then - NULIB__EPENDING="${NULIB__EPENDING:+$NULIB__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 estep() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estep "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepe() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepe "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepw() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepw "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepn() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepn "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepi() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepi "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estep_() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estep_ "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepe_() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepe_ "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepw_() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepw_ "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepn_() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepn_ "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } +function estepi_() { show_info || return; eval "$NULIB__DISABLE_SET_X"; __estepi_ "$*" 1>&2; eval "$NULIB__ENABLE_SET_X"; } + 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. @@ -546,7 +475,6 @@ function ebegin() { # ebegin NULIB__ESTACK="$NULIB__ESTACK:b" if show_info; then - eflush __ebegin "$__b_msg" 1>&2 fi # commande @@ -560,13 +488,13 @@ function ebegin() { [ -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 @@ -577,19 +505,20 @@ function edot() { 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. @@ -601,7 +530,6 @@ function ewait() { [ -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 @@ -619,6 +547,7 @@ function ewait() { wait "$1" fi } + function eend() { # Terminer une section. # Avec l'option -c, remettre à zéro toutes les informations de section @@ -635,7 +564,6 @@ function eend() { # terminer ebegin NULIB__ESTACK="${NULIB__ESTACK%:b}" show_info || return - eflush [ -n "$1" ] && s="$1" if [ "$s" == "0" ]; then __eendo 1>&2 @@ -648,6 +576,7 @@ function eend() { NULIB__TLEVEL="${NULIB__TLEVEL% }" fi } + function __elinedots() { ebegin "$1" local line diff --git a/bash/src/pretty.sh b/bash/src/pretty.sh index ab172be..1d24a5b 100644 --- a/bash/src/pretty.sh +++ b/bash/src/pretty.sh @@ -56,77 +56,20 @@ function __set_no_colors() { else is_yes "$1" && NO_COLORS=1 || NO_COLORS= fi + COULEUR_ROUGE="$(get_color RED BOLD)" COULEUR_VERTE="$(get_color GREEN BOLD)" COULEUR_JAUNE="$(get_color YELLOW BOLD)" COULEUR_BLEUE="$(get_color BLUE BOLD)" COULEUR_BLANCHE="$(get_color WHITE BOLD)" COULEUR_NORMALE="$(get_color RESET)" -} -__set_no_colors - -function __eerror() { local p; [ -z "$NO_COLORS" ] && p="E" || p="ERROR"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __ewarn() { local p; [ -z "$NO_COLORS" ] && p="W" || p="WARNING"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __enote() { local p; [ -z "$NO_COLORS" ] && p="N" || p="NOTE"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_VERTE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __ebanner() { - local maxi="${COLUMNS:-80}" - local prefix="$(__edate)${NULIB__TLEVEL}" lsep line - local -a lines - - lsep="$prefix" - while [ ${#lsep} -lt $maxi ]; do lsep="$lsep="; done - - tooenc "$COULEUR_ROUGE$lsep" - maxi=$(($maxi - 1)) - array_xsplitl lines "$1" - for line in "" "${lines[@]}" ""; do - line="$prefix= $line" - if [ ${#line} -le $maxi ]; then - while [ ${#line} -lt $maxi ]; do line="$line "; done - line="$line=" - fi - tooenc "$line" - done - tooenc "$lsep$COULEUR_NORMALE" -} -function __eimportant() { local p; [ -z "$NO_COLORS" ] && p="!" || p="IMPORTANT"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __eattention() { local p; [ -z "$NO_COLORS" ] && p="*" || p="ATTENTION"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __einfo() { local p; [ -z "$NO_COLORS" ] && p="I" || p="INFO"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLEUE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __edebug() { local p; [ -z "$NO_COLORS" ] && p="D" || p="DEBUG"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estep() { local p; [ -z "$NO_COLORS" ] && p="." || p="."; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepe() { local p; [ -z "$NO_COLORS" ] && p="." || p=".E"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepw() { local p; [ -z "$NO_COLORS" ] && p="." || p=".W"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepn() { local p; [ -z "$NO_COLORS" ] && p="." || p=".N"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_VERTE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepi() { local p; [ -z "$NO_COLORS" ] && p="." || p=".I"; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLEUE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estep_() { local p; [ -z "$NO_COLORS" ] && p="." || p="."; tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepe_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".E"; tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_ROUGE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepw_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".W"; tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_JAUNE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepn_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".N"; tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_VERTE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __estepi_() { local p; [ -z "$NO_COLORS" ] && p="." || p=".I"; tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_BLEUE}${p}${COULEUR_NORMALE} $(__indent "$1")"; } -function __esection() { - local maxi="${COLUMNS:-80}" - local prefix="$(__edate)${NULIB__TLEVEL}" lsep - - lsep="$prefix" - while [ ${#lsep} -lt $maxi ]; do lsep="$lsep="; done - - if [ -n "$*" ]; then - tooenc "$COULEUR_BLEUE$lsep" - tooenc "$prefix$*" - tooenc "$lsep$COULEUR_NORMALE" + if [ -n "$NO_COLORS" ]; then + nulib__load: _output_vanilla else - tooenc "$COULEUR_BLEUE$lsep$COULEUR_NORMALE" + nulib__load: _output_color fi } -function __etitle() { local p; [ -z "$NO_COLORS" ] && p="T" || p="==="; tooenc "$(__edate)${NULIB__TLEVEL}${COULEUR_BLEUE}${p} $(get_color _)$(__indent "$1")${COULEUR_NORMALE}"; } -function __ebegin() { local p; [ -z "$NO_COLORS" ] && p="." || p="."; tooenc_ "$(__edate)${NULIB__TLEVEL}${COULEUR_BLANCHE}${p}${COULEUR_NORMALE} $(__indent "$1"): "; } -function __edoto() { echo_ "."; } -function __edotw() { echo_ "${COULEUR_JAUNE}w${COULEUR_NORMALE}"; } -function __edotx() { echo_ "${COULEUR_ROUGE}x${COULEUR_NORMALE}"; } -function __edotp() { echo_ "${COULEUR_JAUNE}+${COULEUR_NORMALE}"; } -function __edotd() { tooenc "($1)"; } -function __eendo() { echo "${COULEUR_VERTE}[ok]${COULEUR_NORMALE}"; } -function __eendx() { echo "${COULEUR_ROUGE}[error]${COULEUR_NORMALE}"; } +__set_no_colors # 5=afficher les messages de debug; 4=afficher les message verbeux; # 3=afficher les message informatifs; 2=afficher les warnings et les notes; @@ -160,6 +103,7 @@ function set_interaction() { esac return 0 } + # Variable à inclure pour lancer automatiquement set_verbosity et # set_interaction en fonction des arguments de la ligne de commande. A utiliser # de cette manière: @@ -175,6 +119,7 @@ function show_warn() { [ "$__verbosity" -ge 2 ]; } function show_info() { [ "$__verbosity" -ge 3 ]; } function show_verbose() { [ "$__verbosity" -ge 4 ]; } function show_debug() { [ -n "$DEBUG" -o "$__verbosity" -ge 5 ]; } + # Vérifier le niveau de verbosité actuel par rapport à l'argument. $1 peut valoir: # -Q retourner true si on peut afficher les messages d'erreur # -q retourner true si on peut afficher les messages d'avertissement @@ -201,6 +146,7 @@ function get_verbosity_option() { 5) echo --debug;; esac } + # Vérifier le niveau d'interaction autorisé par rapport à l'argument. Par # exemple, 'check_interaction -y' signifie "Il ne faut interagir avec # l'utilisateur qu'à partir du niveau d'interaction -y. Suis-je dans les diff --git a/bash/tests/test-output.sh b/bash/tests/test-output.sh index 5917add..ab8dbfc 100755 --- a/bash/tests/test-output.sh +++ b/bash/tests/test-output.sh @@ -11,18 +11,15 @@ args=( ) parse_args "$@"; set -- "${args[@]}" -eerror "erreur" -ewarn "warning" -enote "note" -ebanner "banner" +#ebanner "banner" eimportant "important" eattention "attention" +eerror "error" +ewarn "warn" +enote "note" einfo "info" -eecho "vanilla" +eecho "echo" edebug "debug" -esection - -etitle "title" estep "step" estepe "stepe" @@ -38,7 +35,108 @@ line1 line2 line3" | elinedots "lines" -eend - esection "section" eecho "content" + +etitle "title0" +etitle "title1" +eecho "print under title1" +eend +eecho "print under title0" +eend + +edesc "action avec step" +action "action avec step" +estep "step" +asuccess "action success" + +action "action avec step" +estep "step" +afailure "action failure" + +action "action avec step" +estep "step" +adone "action neutral" + +edesc "actions sans step" +action "action sans step" +asuccess "action success" + +action "action sans step" +afailure "action failure" + +action "action sans step" +adone "action neutral" + +edesc "actions imbriquées" +action "action0" +action "action1" +action "action2" +asuccess "action2 success" +asuccess "action1 success" +asuccess "action0 success" + +edesc "action avec step, sans messages" +action "action avec step, sans messages, success" +estep "step" +asuccess + +action "action avec step, sans messages, failure" +estep "step" +afailure + +action "action avec step, sans messages, done" +estep "step" +adone + +edesc "action sans step, sans messages" +action "action sans step, sans messages, success" +asuccess + +action "action sans step, sans messages, failure" +afailure + +action "action sans step, sans messages, done" +adone + +edesc "actions imbriquées, sans messages" +action "action0" +action "action1" +action "action2" +asuccess +asuccess +asuccess + +################################################################################ + +#ebanner $'multi-line\nbanner' + +esection $'multi-line\nsection' +etitle $'multi-line\ntitle' +etitle $'another\ntitle' +edesc $'multi-line\ndesc' + +#ebanner $'multi-line\nbanner' +eimportant $'multi-line\nimportant' +eattention $'multi-line\nattention' +eerror $'multi-line\nerror' +ewarn $'multi-line\nwarn' +enote $'multi-line\nnote' +einfo $'multi-line\ninfo' +eecho $'multi-line\necho' +edebug $'multi-line\ndebug' + +action $'multi-line\naction' +asuccess +action $'multi-line\naction' +estep $'multi-line\nstep' +afailure +action $'multi-line\naction' +estep $'multi-line\nstep' +asuccess $'multi-line\nsuccess' +action $'multi-line\naction' +estep $'multi-line\nstep' +adone $'multi-line\ndone' + +eend +eend diff --git a/load.sh b/load.sh index da5fc1f..fa544c9 100644 --- a/load.sh +++ b/load.sh @@ -96,6 +96,22 @@ function nulib__define_functions() { } } +function nulib__load:() { + local nl__module nl__nulibdir nl__found + [ $# -gt 0 ] || set DEFAULTS + + for nl__module in "$@"; do + nl__found= + for nl__nulibdir in "${NULIBDIRS[@]}"; do + if [ -f "$nl__nulibdir/$nl__module.sh" ]; then + source "$nl__nulibdir/$nl__module.sh" || die + nl__found=1 + break + fi + done + [ -n "$nl__found" ] || die "nulib: unable to find module $nl__module in (${NULIBDIRS[*]})" + done +} function nulib__require:() { local nr__module nr__nulibdir nr__found [ $# -gt 0 ] || set DEFAULTS @@ -140,11 +156,18 @@ function nulib__require:() { NULIB_MODULE="$nr__orig_module" } +# désactiver set -x +NULIB__DISABLE_SET_X='local NULIB__SET_X; [ -z "$NULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; NULIB__SET_X=1; }' +NULIB__ENABLE_SET_X='[ -n "$NULIB__SET_X" ] && set -x' +# désactiver set -x de manière réentrante +NULIB__RDISABLE_SET_X='[ -z "$NULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local NULIB_REQUIRE_SET_X=1; }; if [ -n "$NULIB_REQUIRE_SET_X" ]; then [ -n "$NULIB_REQUIRE_SET_X_RL1" ] || local NULIB_REQUIRE_SET_X_RL1; local NULIB_REQUIRE_SET_X_RL2=$RANDOM; [ -n "$NULIB_REQUIRE_SET_X_RL1" ] || NULIB_REQUIRE_SET_X_RL1=$NULIB_REQUIRE_SET_X_RL2; fi' +NULIB__RENABLE_SET_X='[ -n "$NULIB_REQUIRE_SET_X" -a "$NULIB_REQUIRE_SET_X_RL1" == "$NULIB_REQUIRE_SET_X_RL2" ] && set -x' + function require:() { - [ -z "$NULIB_NO_DISABLE_SET_X" ] && [[ $- == *x* ]] && { set +x; local NULIB_REQUIRE_SET_X=1; }; if [ -n "$NULIB_REQUIRE_SET_X" ]; then [ -n "$NULIB_REQUIRE_SET_X_RL1" ] || local NULIB_REQUIRE_SET_X_RL1; local NULIB_REQUIRE_SET_X_RL2=$RANDOM; [ -n "$NULIB_REQUIRE_SET_X_RL1" ] || NULIB_REQUIRE_SET_X_RL1=$NULIB_REQUIRE_SET_X_RL2; fi # désactiver set -x de manière réentrante + eval "$NULIB__RDISABLE_SET_X" nulib__define_functions nulib__require: "$@" - [ -n "$NULIB_REQUIRE_SET_X" -a "$NULIB_REQUIRE_SET_X_RL1" == "$NULIB_REQUIRE_SET_X_RL2" ] && set -x + eval "$NULIB__RENABLE_SET_X" return 0 }