commencer le découpage fin de base en sous-modules

This commit is contained in:
Jephté Clain 2014-09-17 10:53:12 +04:00
parent fd98fe817e
commit d9266be21b
14 changed files with 806 additions and 611 deletions

View File

@ -62,6 +62,9 @@ class IncLine(object):
//@
''@
Note: le caractère d'inclusion '@*' existe aussi, mais il est particulier:
une fois déplié, il ne peut pas être replié. C'est la propriété locked.
Une fois qu'un type de ligne de commentaire est reconnue, toutes les lignes
de directives suivantes doivent être de ce type.
@ -183,6 +186,8 @@ class IncLine(object):
# après analyse d'une ligne, indentation et commentaire avant la directive
_prefix, prefix = make_prop('_prefix', None)[:2]
# après analyse d'une ligne, est-ce une inclusion verrouillée?
_locked, locked = make_prop('_locked', None)[:2]
# après analyse d'une ligne, nom de la directive
_action, action = make_prop('_action', None)[:2]
# après analyse d'une ligne, arguments de la directive
@ -192,11 +197,11 @@ class IncLine(object):
il_pattern = r'(.*)' # prefix
if c in ('*', '@'):
self._c = self._orig_c = c
il_pattern += r'(?:@|\*)'
il_pattern += r'((?:@|\*)\*?)'
else:
self._orig_c = None
self._c = '@'
il_pattern += r'@'
il_pattern += r'(@\*?)'
# action
il_pattern += r'(%s)' % '|'.join([self._RE_SPECIAL.sub(r'\\\1', action)
for action in self.ACTIONS])
@ -221,10 +226,11 @@ class IncLine(object):
mo = self._re_il.match(line)
if mo is not None:
self._prefix = mo.group(1)
self._locked = mo.group(2) in ('@*', '**')
if self.is_prefix(self._prefix):
self._action = mo.group(2)
spaces = mo.group(3)
self._args = mo.group(4)
self._action = mo.group(3)
spaces = mo.group(4)
self._args = mo.group(5)
if self._NO_SPACES.get(self._action, False):
# il ne doit pas y avoir d'espaces entre cette directive et
# son argument
@ -234,6 +240,7 @@ class IncLine(object):
# argument
if self._RE_SPACES.match(spaces): return True
self._prefix = None
self._locked = None
self._action = None
self._args = None
return False
@ -246,24 +253,28 @@ class IncLine(object):
def is_provide(self): return self._action == self.PROVIDE
def is_cooked(self): return self._action == self.COOKED
def __c_or_locked(self):
if self._locked: return '@*'
else: return self._c
def get_include(self, name=None):
if name is None: name = self._args
return self.TEMPLATES[self.INCLUDE] % (self._prefix, self._c, name)
return self.TEMPLATES[self.INCLUDE] % (self._prefix, self.__c_or_locked(), name)
def get_start_inc(self, name=None):
if name is None: name = self._args
return self.TEMPLATES[self.START_INC] % (self._prefix, self._c, name)
return self.TEMPLATES[self.START_INC] % (self._prefix, self.__c_or_locked(), name)
def get_end_inc(self, name=None):
if name is None: name = self._args
return self.TEMPLATES[self.END_INC] % (self._prefix, self._c, name)
return self.TEMPLATES[self.END_INC] % (self._prefix, self.__c_or_locked(), name)
def get_require(self, name=None):
if name is None: name = self._args
return self.TEMPLATES[self.REQUIRE] % (self._prefix, self._c, name)
return self.TEMPLATES[self.REQUIRE] % (self._prefix, self.__c_or_locked(), name)
def get_provide(self, name=None):
if name is None: name = self._args
return self.TEMPLATES[self.PROVIDE] % (self._prefix, self._c, name)
return self.TEMPLATES[self.PROVIDE] % (self._prefix, self.__c_or_locked(), name)
def get_cooked(self, args=None):
if args is None: args = self._args
return self.TEMPLATES[self.COOKED] % (self._prefix, self._c, args)
return self.TEMPLATES[self.COOKED] % (self._prefix, self.__c_or_locked(), args)
class Env(object):
"""Un environnement pour plier ou déplier un fichier.
@ -515,7 +526,7 @@ class File(Resource):
if not folding:
## nous ne somme pas encore dans une section à replier
# soit nous débutons une section à replier
if il.is_start_inc():
if il.is_start_inc() and not il.locked:
folding = True
incindex = index
name = il.args

View File

@ -1 +1 @@
002004000
003000000

View File

@ -1,361 +1,43 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Fonctions de base
##@cooked nocomments
# Emplacement du script courant
if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then
# ne pas mettre à jour script, scriptname, scriptdir. Ils ont déjà été
# calculés
:
elif [ "$0" == "-bash" ]; then
scriptname=
scriptdir=
script=
elif [ ! -f "$0" -a -f "${0#-}" ]; then
scriptname="$(basename -- "${0#-}")"
scriptdir="$(dirname -- "${0#-}")"
scriptdir="$(cd "$scriptdir"; pwd)"
script="$scriptdir/$scriptname"
else
scriptname="$(basename -- "$0")"
scriptdir="$(dirname -- "$0")"
scriptdir="$(cd "$scriptdir"; pwd)"
script="$scriptdir/$scriptname"
##@*inc[base.ulib
## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le
## cas où cette librairie n'est pas chargée
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
ULIBPROVIDED=()
function uprovided() {
local module
for module in "${ULIBPROVIDED[@]}"; do
[ "$module" == "$1" ] && return 0
done
return 1
}
function uprovide() {
uprovided "$1" && return 1
ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
}
function urequire() {
local module r=0
for module in "$@"; do
uprovided "$module" && continue
echo "error: $module: this module is required but cannot be automatically loaded" 1>&2
r=1
done
return $r
}
uprovide base.ulib
fi
: "${ULIBDIR:=$scriptdir}"
# Repertoire temporaire
[ -z "$TMPDIR" -a -d "$HOME/tmp" ] && TMPDIR="$HOME/tmp"
export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
# User
[ -z "$USER" -a -n "$LOGNAME" ] && export USER="$LOGNAME"
# Le fichier nutoolsrc doit être chargé systématiquement
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc
################################################################################
## core
function recho() {
# afficher une valeur brute. contrairement à la commande echo, ne reconnaitre
# aucune option (i.e. -e, -E, -n ne sont pas signifiants)
if [[ "${1:0:2}" == -[eEn] ]]; then
echo -n -
local first="${1:1}"; shift
echo "$first$@"
else
echo "$@"
fi
}
function recho_() {
# afficher une valeur brute, sans passer à la ligne. contrairement à la commande
# echo, ne reconnaitre aucune option (i.e. -e, -E, -n ne sont pas signifiants)
if [[ "${1:0:2}" == -[eEn] ]]; then
echo -n -
local first="${1:1}"; shift
echo -n "$first$@"
else
echo -n "$@"
fi
}
function _qval() {
# Dans la chaine $*, remplacer \ par \\, " par \", $ par \$, ` par \`
# Cela permet de quoter une chaine à mettre entre guillements.
# Note: la protection de ! n'est pas effectuée, parce que le comportement du
# shell est incohérent entre le shell interactif et les scripts. Pour une
# version plus robuste, il est nécessaire d'utiliser un programme externe tel
# que sed ou awk
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
recho_ "$s"
}
function qval() {
# Afficher la chaine $* quotée avec "
echo -n \"
_qval "$@"
echo \"
}
function qvalr() {
# Afficher la chaine $* quotée avec ", sauf si elle est vide
if [ -n "$*" ]; then
echo -n \"
_qval "$@"
echo n \"
fi
}
function should_quote() {
# Tester si la chaine $* doit être mise entre quotes
[ -z "$1" ] && return 0
local s="${*//[a-zA-Z0-9]/}"
s="${s//,/}"
s="${s//./}"
s="${s//+/}"
s="${s//\//}"
s="${s//-/}"
s="${s//_/}"
s="${s//=/}"
[ -n "$s" ]
}
function qvals() {
# Afficher chaque argument de cette fonction quotée le cas échéant avec "
# Chaque valeur est séparée par un espace.
local arg first=1
for arg in "$@"; do
[ -z "$first" ] && echo -n " "
if should_quote "$arg"; then
echo -n \"
_qval "$arg"
echo -n \"
else
recho_ "$arg"
fi
first=
done
}
function qlines() {
# Traiter chaque ligne de l'entrée standard pour en faire des chaines quotées
# avec '
sed "s/'/'\\\\''/g; s/.*/'&'/g"
}
function setv() {
# initialiser la variable $1 avec la valeur "$2..*"
# note: en principe, la syntaxe est 'setv var values...'. cependant, la
# syntaxe 'setv var=values...' est supportée aussi
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var=\"$(_qval "$*")\""
}
function _setv() {
# Comme la fonction setv() mais ne supporte que la syntaxe '_setv var values...'
# Cette fonction est légèrement plus rapide que setv()
local __s_var="$1"; shift
eval "$__s_var=\"$(_qval "$*")\""
}
function setx() {
# syntaxe 1: setx var cmd
# initialiser la variable $1 avec le résultat de la commande "$2..@"
# note: en principe, la syntaxe est 'setx var cmd args...'. cependant, la
# syntaxe 'setx var=cmd args...' est supportée aussi
# syntaxe 2: setx -a array cmd
# initialiser le tableau $1 avec le résultat de la commande "$2..@", chaque
# ligne du résultat étant un élément du tableau
# note: en principe, la syntaxe est 'setx -a array cmd args...'. cependant, la
# syntaxe 'setx -a array=cmd args...' est supportée aussi
if [ "$1" == -a ]; then
shift
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=($("$@" | qlines))"
else
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var="'"$("$@")"'
fi
}
function _setvx() {
# Comme la fonction setx() mais ne supporte que l'initialisation d'une variable
# scalaire avec la syntaxe '_setvx var cmd args...' pour gagner (un peu) en
# rapidité d'exécution.
local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"'
}
function _setax() {
# Comme la fonction setx() mais ne supporte que l'initialisation d'un tableau
# avec la syntaxe '_setax array cmd args...' pour gagner (un peu) en rapidité
# d'exécution.
local __s_array="$1"; shift
eval "$__s_array=($("$@" | qlines))"
}
function evalx() {
# Implémenter une syntaxe lisible et naturelle permettant d'enchainer des
# traitements sur une valeur. Par exemple, la commande
# evalx cmd1... // cmd2... // cmd3...
# affiche le résultat de la commande "$(cmd3 $(cmd2 $(cmd1)))"
# Retourner le dernier code d'erreur non nul, ou 0 si toutes les commandes se
# sont exécutées sans erreur.
local __e_val __e_arg __e_r=0
local -a __e_cmd
local __e_first=1
while [ $# -gt 0 ]; do
__e_cmd=()
while [ $# -gt 0 ]; do
__e_arg="$1"; shift
[ "$__e_arg" == // ] && break
if [ "${__e_arg%//}" != "$__e_arg" ]; then
local __e_tmp="${__e_arg%//}"
if [ -z "${__e_tmp//\\/}" ]; then
__e_arg="${__e_arg#\\}"
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
continue
fi
fi
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
done
if [ -n "$__e_first" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
fi
__e_first=
done
[ -n "$__e_val" ] && echo "$__e_val"
return $__e_r
}
function setx2() {
# équivalent à setx $1 evalx $2..@
local -a __s_args
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
__s_args=("${__s_args[@]}" "$__s_var")
setx "${__s_args[@]}" evalx "$@"
}
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.
local __e_arg __e_cmd
while [ $# -gt 0 ]; do
__e_arg="$1"; shift
if [ "$__e_arg" == // ]; then
__e_cmd="$__e_cmd |"
continue
elif [ "${__e_arg%//}" != "$__e_arg" ]; then
local __e_tmp="${__e_arg%//}"
if [ -z "${__e_tmp//\\/}" ]; then
__e_arg="${__e_arg#\\}"
fi
fi
__e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\""
done
eval "$__e_cmd"
}
function testx() {
# Faire un test unaire avec la commande [ sur une valeur calculée avec evalx.
# Utiliser la syntaxe 'testx op cmds...' e.g.
# testx -z cmd1 // cmd2
local __t_op="$1"; shift
local __t_val="$(evalx "$@")"
[ $__t_op "$__t_val" ]
}
function test2x() {
# Faire une test binaire avec la commande [ entre une valeur spécifiée et une
# valeur calculée avec evalx. Utiliser la syntaxe 'test2x value op cmds...' e.g.
# test2x value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalx "$@")"
[ "$__t_val1" $__t_op "$__t_val2" ]
}
function testrx() {
# Faire une test binaire avec la commande [[ entre une valeur spécifiée et une
# valeur calculée avec evalx. Utiliser la syntaxe 'testrx value op cmds...' e.g.
# testrx value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalx "$@")"
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
}
function testp() {
# Faire un test unaire avec la commande [ sur une valeur calculée avec evalp.
# Utiliser la syntaxe 'testp op cmds...' e.g.
# testp -z cmd1 // cmd2
local __t_op="$1"; shift
local __t_val="$(evalp "$@")"
[ $__t_op "$__t_val" ]
}
function test2p() {
# Faire une test binaire avec la commande [ entre une valeur spécifiée et une
# valeur calculée avec evalp. Utiliser la syntaxe 'test2p value op cmds...' e.g.
# test2p value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalp "$@")"
[ "$__t_val1" $__t_op "$__t_val2" ]
}
function testrp() {
# Faire une test binaire avec la commande [[ entre une valeur spécifiée et une
# valeur calculée avec evalp. Utiliser la syntaxe 'testrp value op cmds...' e.g.
# testrp value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalp "$@")"
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
}
function err2out() {
# lancer la commande $@ en redirigeant la sortie d'erreur sur la sortie standard
"$@" 2>&1
}
##@*inc]base.ulib
##@include base.init
##@include base.core
##@include base.string
##@include base.array
##@include base.compat
uprovide base
urequire base.init base.core base.string base.array base.compat
## valeurs
function tolower() {
# afficher en minuscule la valeur $1..*
echo ${*,,}
}
function toupper() {
# afficher en majuscule la valeur $1..*
echo ${*^^}
}
function isnum() {
# retourner vrai si $1 est une valeur numérique entière (positive ou négative)
[ ${#1} -gt 0 ] || return 1
local v="$1"
v="${v#-}"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function ispnum() {
# retourner vrai si $1 est une valeur numérique entière positive
[ ${#1} -gt 0 ] || return 1
local v="$1"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function isrnum() {
# retourner vrai si $1 est une valeur numérique réelle (positive ou négative)
# le séparateur décimal peut être . ou ,
[ ${#1} -gt 0 ] || return 1
local v="$1"
v="${v#-}"
v="${v//./}"
v="${v//,/}"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function is_yes() {
# retourner vrai si $1 est une valeur "oui"
case "${1,,}" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
return 1
}
function yesval() {
# normaliser une valeur vraie: si $1 est une valeur "oui", afficher 1, sinon
# afficher une chaine vide
@ -378,14 +60,6 @@ function normyesvals() {
is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" ""
done
}
function is_no() {
# retourner vrai si $1 est une valeur "non"
case "${1,,}" in
n|non|no|f|faux|false|off) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
return 1
}
function rawecho() {
# afficher une valeur brute. contrairement à echo, ne pas reconnaitre les
# options -e, -E, -n.
@ -4351,26 +4025,3 @@ if [ -n "$UTOOLS_CHROOT" ]; then
[ -n "$UTOOLS_UNAME_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM"
[ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE"
fi
################################################################################
## support de ulib dans le cas où cette librairie n'est pas encore chargée
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
ULIBPROVIDED=()
function uprovided() {
array_contains ULIBPROVIDED "$1"
}
function uprovide() {
uprovided "$1" && return 1
array_add ULIBPROVIDED "$1"
}
function urequire() {
# si ulib n'est pas disponible pour charger la librairie, on compte sur
# l'utilisateur pour charger manuellement les librairies nécessaires.
local ulib_
for ulib_ in "$@"; do
uprovided "$ulib_" || ewarn "$ulib_: this module is required"
done
}
uprovide base
fi

5
lib/ulib/base.array Normal file
View File

@ -0,0 +1,5 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Fonctions de base: gestion des tableaux
##@cooked nocomments
uprovide base.array
urequire base.core

35
lib/ulib/base.compat Normal file
View File

@ -0,0 +1,35 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Fonctions de base: support des fonctions obsolètes et des versions de bash < 4.x
##@cooked nocomments
uprovide base.compat
urequire base.string
if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then
if uprovided base.string; then
function strlower() { tr A-Z a-z <<<"$*"; }
function strupper() { tr a-z A-Z <<<"$*"; }
function is_yes() {
case "$1" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
# pour les perfs, n'utiliser strlower que ici
case "$(strlower "$1")" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
return 1
}
function is_no() {
case "$1" in
n|non|no|f|faux|false|off) return 0;;
N|NON|NO|F|FAUX|FALSE|OFF) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
case "$(strlower "$1")" in
n|non|no|f|faux|false|off) return 0;;
esac
return 1
}
fi
fi

280
lib/ulib/base.core Normal file
View File

@ -0,0 +1,280 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Fonctions de base: fondement
##@cooked nocomments
uprovide base.core
function recho() {
# afficher une valeur brute. contrairement à la commande echo, ne reconnaitre
# aucune option (i.e. -e, -E, -n ne sont pas signifiants)
if [[ "${1:0:2}" == -[eEn] ]]; then
echo -n -
local first="${1:1}"; shift
echo "$first$@"
else
echo "$@"
fi
}
function recho_() {
# afficher une valeur brute, sans passer à la ligne. contrairement à la commande
# echo, ne reconnaitre aucune option (i.e. -e, -E, -n ne sont pas signifiants)
if [[ "${1:0:2}" == -[eEn] ]]; then
echo -n -
local first="${1:1}"; shift
echo -n "$first$@"
else
echo -n "$@"
fi
}
function _qval() {
# Dans la chaine $*, remplacer \ par \\, " par \", $ par \$, ` par \`
# Cela permet de quoter une chaine à mettre entre guillements.
# Note: la protection de ! n'est pas effectuée, parce que le comportement du
# shell est incohérent entre le shell interactif et les scripts. Pour une
# version plus robuste, il est nécessaire d'utiliser un programme externe tel
# que sed ou awk
local s="$*"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
recho_ "$s"
}
function qval() {
# Afficher la chaine $* quotée avec "
echo -n \"
_qval "$@"
echo \"
}
function qvalr() {
# Afficher la chaine $* quotée avec ", sauf si elle est vide
if [ -n "$*" ]; then
echo -n \"
_qval "$@"
echo n \"
fi
}
function should_quote() {
# Tester si la chaine $* doit être mise entre quotes
[ -z "$1" ] && return 0
local s="${*//[a-zA-Z0-9]/}"
s="${s//,/}"
s="${s//./}"
s="${s//+/}"
s="${s//\//}"
s="${s//-/}"
s="${s//_/}"
s="${s//=/}"
[ -n "$s" ]
}
function qvals() {
# Afficher chaque argument de cette fonction quotée le cas échéant avec "
# Chaque valeur est séparée par un espace.
local arg first=1
for arg in "$@"; do
[ -z "$first" ] && echo -n " "
if should_quote "$arg"; then
echo -n \"
_qval "$arg"
echo -n \"
else
recho_ "$arg"
fi
first=
done
}
function qlines() {
# Traiter chaque ligne de l'entrée standard pour en faire des chaines quotées
# avec '
sed "s/'/'\\\\''/g; s/.*/'&'/g"
}
function setv() {
# initialiser la variable $1 avec la valeur "$2..*"
# note: en principe, la syntaxe est 'setv var values...'. cependant, la
# syntaxe 'setv var=values...' est supportée aussi
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var=\"$(_qval "$*")\""
}
function _setv() {
# Comme la fonction setv() mais ne supporte que la syntaxe '_setv var values...'
# Cette fonction est légèrement plus rapide que setv()
local __s_var="$1"; shift
eval "$__s_var=\"$(_qval "$*")\""
}
function setx() {
# syntaxe 1: setx var cmd
# initialiser la variable $1 avec le résultat de la commande "$2..@"
# note: en principe, la syntaxe est 'setx var cmd args...'. cependant, la
# syntaxe 'setx var=cmd args...' est supportée aussi
# syntaxe 2: setx -a array cmd
# initialiser le tableau $1 avec le résultat de la commande "$2..@", chaque
# ligne du résultat étant un élément du tableau
# note: en principe, la syntaxe est 'setx -a array cmd args...'. cependant, la
# syntaxe 'setx -a array=cmd args...' est supportée aussi
if [ "$1" == -a ]; then
shift
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=($("$@" | qlines))"
else
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var="'"$("$@")"'
fi
}
function _setvx() {
# Comme la fonction setx() mais ne supporte que l'initialisation d'une variable
# scalaire avec la syntaxe '_setvx var cmd args...' pour gagner (un peu) en
# rapidité d'exécution.
local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"'
}
function _setax() {
# Comme la fonction setx() mais ne supporte que l'initialisation d'un tableau
# avec la syntaxe '_setax array cmd args...' pour gagner (un peu) en rapidité
# d'exécution.
local __s_array="$1"; shift
eval "$__s_array=($("$@" | qlines))"
}
function evalx() {
# Implémenter une syntaxe lisible et naturelle permettant d'enchainer des
# traitements sur une valeur. Par exemple, la commande
# evalx cmd1... // cmd2... // cmd3...
# affiche le résultat de la commande "$(cmd3 $(cmd2 $(cmd1)))"
# Retourner le dernier code d'erreur non nul, ou 0 si toutes les commandes se
# sont exécutées sans erreur.
local __e_val __e_arg __e_r=0
local -a __e_cmd
local __e_first=1
while [ $# -gt 0 ]; do
__e_cmd=()
while [ $# -gt 0 ]; do
__e_arg="$1"; shift
[ "$__e_arg" == // ] && break
if [ "${__e_arg%//}" != "$__e_arg" ]; then
local __e_tmp="${__e_arg%//}"
if [ -z "${__e_tmp//\\/}" ]; then
__e_arg="${__e_arg#\\}"
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
continue
fi
fi
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
done
if [ -n "$__e_first" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
fi
__e_first=
done
[ -n "$__e_val" ] && echo "$__e_val"
return $__e_r
}
function setx2() {
# équivalent à setx $1 evalx $2..@
local -a __s_args
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
__s_args=("${__s_args[@]}" "$__s_var")
setx "${__s_args[@]}" evalx "$@"
}
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.
local __e_arg __e_cmd
while [ $# -gt 0 ]; do
__e_arg="$1"; shift
if [ "$__e_arg" == // ]; then
__e_cmd="$__e_cmd |"
continue
elif [ "${__e_arg%//}" != "$__e_arg" ]; then
local __e_tmp="${__e_arg%//}"
if [ -z "${__e_tmp//\\/}" ]; then
__e_arg="${__e_arg#\\}"
fi
fi
__e_cmd="${__e_cmd:+$__e_cmd }\"$(_qval "$__e_arg")\""
done
eval "$__e_cmd"
}
function testx() {
# Faire un test unaire avec la commande [ sur une valeur calculée avec evalx.
# Utiliser la syntaxe 'testx op cmds...' e.g.
# testx -z cmd1 // cmd2
local __t_op="$1"; shift
local __t_val="$(evalx "$@")"
[ $__t_op "$__t_val" ]
}
function test2x() {
# Faire une test binaire avec la commande [ entre une valeur spécifiée et une
# valeur calculée avec evalx. Utiliser la syntaxe 'test2x value op cmds...' e.g.
# test2x value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalx "$@")"
[ "$__t_val1" $__t_op "$__t_val2" ]
}
function testrx() {
# Faire une test binaire avec la commande [[ entre une valeur spécifiée et une
# valeur calculée avec evalx. Utiliser la syntaxe 'testrx value op cmds...' e.g.
# testrx value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalx "$@")"
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
}
function testp() {
# Faire un test unaire avec la commande [ sur une valeur calculée avec evalp.
# Utiliser la syntaxe 'testp op cmds...' e.g.
# testp -z cmd1 // cmd2
local __t_op="$1"; shift
local __t_val="$(evalp "$@")"
[ $__t_op "$__t_val" ]
}
function test2p() {
# Faire une test binaire avec la commande [ entre une valeur spécifiée et une
# valeur calculée avec evalp. Utiliser la syntaxe 'test2p value op cmds...' e.g.
# test2p value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalp "$@")"
[ "$__t_val1" $__t_op "$__t_val2" ]
}
function testrp() {
# Faire une test binaire avec la commande [[ entre une valeur spécifiée et une
# valeur calculée avec evalp. Utiliser la syntaxe 'testrp value op cmds...' e.g.
# testrp value == cmd1 // cmd2
local __t_val1="$1"; shift
local __t_op="$1"; shift
local __t_val2="$(evalp "$@")"
eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]'
}
function err2out() {
# lancer la commande $@ en redirigeant la sortie d'erreur sur la sortie standard
"$@" 2>&1
}

36
lib/ulib/base.init Normal file
View File

@ -0,0 +1,36 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Fonctions de base: initialisation de l'environnement
##@cooked nocomments
# Emplacement du script courant
if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then
# ne pas mettre à jour script, scriptname, scriptdir. Ils ont déjà été
# calculés
:
elif [ "$0" == "-bash" ]; then
scriptname=
scriptdir=
script=
elif [ ! -f "$0" -a -f "${0#-}" ]; then
scriptname="$(basename -- "${0#-}")"
scriptdir="$(dirname -- "${0#-}")"
scriptdir="$(cd "$scriptdir"; pwd)"
script="$scriptdir/$scriptname"
else
scriptname="$(basename -- "$0")"
scriptdir="$(dirname -- "$0")"
scriptdir="$(cd "$scriptdir"; pwd)"
script="$scriptdir/$scriptname"
fi
: "${ULIBDIR:=$scriptdir}"
# Repertoire temporaire
[ -z "$TMPDIR" -a -d "$HOME/tmp" ] && TMPDIR="$HOME/tmp"
export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
# User
[ -z "$USER" -a -n "$LOGNAME" ] && export USER="$LOGNAME"
# Le fichier nutoolsrc doit être chargé systématiquement
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc

56
lib/ulib/base.string Normal file
View File

@ -0,0 +1,56 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Fonctions de base: gestion des valeurs scalaires
##@cooked nocomments
uprovide base.string
urequire base.core
function strlower() {
# afficher en minuscule la valeur $1..*
echo ${*,,}
}
function strupper() {
# afficher en majuscule la valeur $1..*
echo ${*^^}
}
function isnum() {
# retourner vrai si $1 est une valeur numérique entière (positive ou négative)
[ ${#1} -gt 0 ] || return 1
local v="$1"
v="${v#-}"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function ispnum() {
# retourner vrai si $1 est une valeur numérique entière positive
[ ${#1} -gt 0 ] || return 1
local v="$1"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function isrnum() {
# retourner vrai si $1 est une valeur numérique réelle (positive ou négative)
# le séparateur décimal peut être . ou ,
[ ${#1} -gt 0 ] || return 1
local v="$1"
v="${v#-}"
v="${v//./}"
v="${v//,/}"
v="${v//[0-9]/}"
[ -z "$v" ]
}
function is_yes() {
# retourner vrai si $1 est une valeur "oui"
case "${1,,}" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
return 1
}
function is_no() {
# retourner vrai si $1 est une valeur "non"
case "${1,,}" in
n|non|no|f|faux|false|off) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
return 1
}

32
lib/ulib/base.ulib Normal file
View File

@ -0,0 +1,32 @@
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le
## cas où cette librairie n'est pas chargée
##@cooked nocomments
# Ce fichier ne doit pas être sourcé, mais inclus avec uinc
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
ULIBPROVIDED=()
function uprovided() {
local module
for module in "${ULIBPROVIDED[@]}"; do
[ "$module" == "$1" ] && return 0
done
return 1
}
function uprovide() {
uprovided "$1" && return 1
ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
}
function urequire() {
# si ulib n'est pas disponible pour charger le module, on compte sur
# l'utilisateur pour charger manuellement les librairies nécessaires.
# retourner 1 si un module n'est pas disponible
local module r=0
for module in "$@"; do
uprovided "$module" && continue
echo "error: $module: this module is required but cannot be automatically loaded" 1>&2
r=1
done
return $r
}
uprovide base.ulib
fi

View File

@ -16,32 +16,6 @@ if check_sysinfos -s macosx; then
function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; }
# sed -i demande un argument
function sedi() { sed -i '' "$@"; }
# Sous MacOSX, la version de bash (3.x) ne supporte pas les opérateurs ,, et ^^
function tolower() { tr A-Z a-z <<<"$*"; }
function toupper() { tr a-z A-Z <<<"$*"; }
function is_yes() {
case "$1" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
# pour les perfs, n'utiliser tolower que ici
case "$(tolower "$1")" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
return 1
}
function is_no() {
case "$1" in
n|non|no|f|faux|false|off) return 0;;
N|NON|NO|F|FAUX|FALSE|OFF) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
case "$(tolower "$1")" in
n|non|no|f|faux|false|off) return 0;;
esac
return 1
}
## gestion des arguments
function __po_check_options() {

View File

@ -6,6 +6,36 @@ PUBKEYS="@@PUBKEYS@@"
##@inc[../base
## Fonctions de base
##@*inc[base.ulib
## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le
## cas où cette librairie n'est pas chargée
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
ULIBPROVIDED=()
function uprovided() {
local module
for module in "${ULIBPROVIDED[@]}"; do
[ "$module" == "$1" ] && return 0
done
return 1
}
function uprovide() {
uprovided "$1" && return 1
ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
}
function urequire() {
local module r=0
for module in "$@"; do
uprovided "$module" && continue
echo "error: $module: this module is required but cannot be automatically loaded" 1>&2
r=1
done
return $r
}
uprovide base.ulib
fi
##@*inc]base.ulib
##@inc[base.init
## Fonctions de base: initialisation de l'environnement
if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then
:
@ -33,6 +63,10 @@ export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc
##@inc]base.init
##@inc[base.core
## Fonctions de base: fondement
uprovide base.core
function recho() {
if [[ "${1:0:2}" == -[eEn] ]]; then
@ -114,26 +148,28 @@ function _setv() {
eval "$__s_var=\"$(_qval "$*")\""
}
function setx() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var="'"$("$@")"'
}
function _setx() {
local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"'
}
function seta() {
if [ "$1" == -a ]; then
shift
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=($("$@" | qlines))"
else
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var="'"$("$@")"'
fi
}
function _seta() {
function _setvx() {
local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"'
}
function _setax() {
local __s_array="$1"; shift
eval "$__s_array=($("$@" | qlines))"
}
@ -158,7 +194,7 @@ function evalx() {
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
done
if [ -n "$first" ]; then
if [ -n "$__e_first" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
@ -169,12 +205,15 @@ function evalx() {
return $__e_r
}
function setx2() {
local -a __s_args
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
setx "$__s_var" evalx "$@"
__s_args=("${__s_args[@]}" "$__s_var")
setx "${__s_args[@]}" evalx "$@"
}
function evalp() {
local __e_arg __e_cmd
@ -232,11 +271,16 @@ function testrp() {
function err2out() {
"$@" 2>&1
}
##@inc]base.core
##@inc[base.string
## Fonctions de base: gestion des valeurs scalaires
uprovide base.string
urequire base.core
function tolower() {
function strlower() {
echo ${*,,}
}
function toupper() {
function strupper() {
echo ${*^^}
}
function isnum() {
@ -268,6 +312,56 @@ function is_yes() {
isnum "$1" && [ "$1" -ne 0 ] && return 0
return 1
}
function is_no() {
case "${1,,}" in
n|non|no|f|faux|false|off) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
return 1
}
##@inc]base.string
##@inc[base.array
## Fonctions de base: gestion des tableaux
uprovide base.array
urequire base.core
##@inc]base.array
##@inc[base.compat
## Fonctions de base: support des fonctions obsolètes et des versions de bash < 4.x
uprovide base.compat
urequire base.string
if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then
if uprovided base.string; then
function strlower() { tr A-Z a-z <<<"$*"; }
function strupper() { tr a-z A-Z <<<"$*"; }
function is_yes() {
case "$1" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
case "$(strlower "$1")" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
return 1
}
function is_no() {
case "$1" in
n|non|no|f|faux|false|off) return 0;;
N|NON|NO|F|FAUX|FALSE|OFF) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
case "$(strlower "$1")" in
n|non|no|f|faux|false|off) return 0;;
esac
return 1
}
fi
fi
##@inc]base.compat
uprovide base
urequire base.init base.core base.string base.array base.compat
function yesval() {
is_yes "$1" && echo 1
}
@ -283,13 +377,6 @@ function normyesvals() {
is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" ""
done
}
function is_no() {
case "${1,,}" in
n|non|no|f|faux|false|off) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
return 1
}
function rawecho() {
local first
while [ "${1:0:1}" == "-" ]; do
@ -964,6 +1051,16 @@ function relpath() {
echo "${rp%//}"
fi
}
function relpathx() {
local p="$(relpath "$@")"
if [ -z "$p" ]; then
echo .
elif [ "${p#../}" != "$p" -o "${p#./}" != "$p" ]; then
echo "$p"
else
echo "./$p"
fi
}
function withinpath() {
local b="$1" p="$2" strict="${3:-N}"
b="$(abspath "$b")"
@ -3348,25 +3445,6 @@ if [ -n "$UTOOLS_CHROOT" ]; then
[ -n "$UTOOLS_UNAME_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM"
[ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE"
fi
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
ULIBPROVIDED=()
function uprovided() {
array_contains ULIBPROVIDED "$1"
}
function uprovide() {
uprovided "$1" && return 1
array_add ULIBPROVIDED "$1"
}
function urequire() {
local ulib_
for ulib_ in "$@"; do
uprovided "$ulib_" || ewarn "$ulib_: this module is required"
done
}
uprovide base
fi
##@inc]../base
##@inc[../sysinfos
## Gestion des informations sur l'hôte local
@ -3729,30 +3807,6 @@ if check_sysinfos -s macosx; then
function _nl2crlf() { _nl2lf | awk '{ print $0 "\r" }'; }
function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; }
function sedi() { sed -i '' "$@"; }
function tolower() { tr A-Z a-z <<<"$*"; }
function toupper() { tr a-z A-Z <<<"$*"; }
function is_yes() {
case "$1" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
case "$(tolower "$1")" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
return 1
}
function is_no() {
case "$1" in
n|non|no|f|faux|false|off) return 0;;
N|NON|NO|F|FAUX|FALSE|OFF) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
case "$(tolower "$1")" in
n|non|no|f|faux|false|off) return 0;;
esac
return 1
}
function __po_check_options() {
local -a options args

View File

@ -51,48 +51,52 @@ ULIBINIT="$ULIBDIR"
function uprovided() {
# Tester si le module $1 a déjà été chargé par urequire
local ulib_
for ulib_ in "${ULIBPROVIDED[@]}"; do
[ "$ulib_" == "$1" ] && return 0
local module
for module in "${ULIBPROVIDED[@]}"; do
[ "$module" == "$1" ] && return 0
done
return 1
}
function uprovide() {
# Spécifier que le module $1 a été sourcée, ou prétendre que c'est le cas.
uprovided "$1" && return 0
# Retourner 1 si le module était déjà pourvu, 0 si c'est la première fois
# qu'on le pourvoit
uprovided "$1" && return 1
ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
}
function urequire() {
# Sourcer un fichier recherché dans ULIBDIRS
# Si le fichier est DEFAULTS, charger base, pretty, sysinfos et compat à la
# place
local ulib_ ulibdir_ found_
# Sourcer un module recherché dans ULIBDIRS
# Le module DEFAULTS est traité de façon particulière: si le fichier associé
# n'est pas trouvé, charger base, pretty, sysinfos et compat à la place
# Si un module n'est pas trouvé, quitter le script avec die()
local __u_module __u_ulibdir __u_found
[ -n "$*" ] || set DEFAULTS
for ulib_ in "$@"; do
found_=
for ulibdir_ in "${ULIBDIRS[@]}"; do
if [ -f "$ulibdir_/$ulib_" ]; then
found_=1
if ! uprovided "$ulib_"; then
uprovide "$ulib_"
source "$ulibdir_/$ulib_" || die
for __u_module in "$@"; do
__u_found=
for __u_ulibdir in "${ULIBDIRS[@]}"; do
if [ -f "$__u_ulibdir/$__u_module" ]; then
__u_found=1
if ! uprovided "$__u_module"; then
uprovide "$__u_module"
source "$__u_ulibdir/$__u_module" || die
fi
break
elif [ "$ulib_" == "DEFAULTS" ]; then
found_=1
for ulib_ in base pretty sysinfos compat; do
if ! uprovided "$ulib_"; then
uprovide "$ulib_"
source "$ulibdir_/$ulib_" || die
fi
done
break
if [ -z "$__u_found" -a "$__u_module" == DEFAULTS ]; then
__u_found=1
for __u_module in base pretty sysinfos compat; do
if ! uprovided "$__u_module"; then
uprovide "$__u_module"
source "$__u_ulibdir/$__u_module" || die
fi
done
[ -n "$found_" ] || die "Unable to find $ulib_ in ${ULIBDIR[*]}"
fi
[ -n "$__u_found" ] || die "Unable to find $__u_module in ${ULIBDIR[*]}"
done
return 0
}
function ulibadd() {
@ -103,7 +107,8 @@ function ulibadd() {
function ulibsync() {
# Synchroniser les modules de ulib dans le répertoire $1
local destdir="$(abspath "${1:-.}")"
local __CPNOVCS_RSYNC_ARGS=(-q --delete)
local -a __CPNOVCS_RSYNC_ARGS
__CPNOVCS_RSYNC_ARGS=(-q --delete)
[ "$destdir/ulib" != "$ULIBDIR" ] && cpdirnovcs "$ULIBDIR" "$destdir/ulib"
}

View File

@ -47,44 +47,45 @@ ULIBINIT="$ULIBDIR"
[ -n "$ULIBPROVIDED" ] || ULIBPROVIDED=(ulib)
function uprovided() {
local ulib_
for ulib_ in "${ULIBPROVIDED[@]}"; do
[ "$ulib_" == "$1" ] && return 0
local module
for module in "${ULIBPROVIDED[@]}"; do
[ "$module" == "$1" ] && return 0
done
return 1
}
function uprovide() {
uprovided "$1" && return 0
uprovided "$1" && return 1
ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
}
function urequire() {
local ulib_ ulibdir_ found_
local __u_module __u_ulibdir __u_found
[ -n "$*" ] || set DEFAULTS
for ulib_ in "$@"; do
found_=
for ulibdir_ in "${ULIBDIRS[@]}"; do
if [ -f "$ulibdir_/$ulib_" ]; then
found_=1
if ! uprovided "$ulib_"; then
uprovide "$ulib_"
source "$ulibdir_/$ulib_" || die
for __u_module in "$@"; do
__u_found=
for __u_ulibdir in "${ULIBDIRS[@]}"; do
if [ -f "$__u_ulibdir/$__u_module" ]; then
__u_found=1
if ! uprovided "$__u_module"; then
uprovide "$__u_module"
source "$__u_ulibdir/$__u_module" || die
fi
break
elif [ "$ulib_" == "DEFAULTS" ]; then
found_=1
for ulib_ in base pretty sysinfos compat; do
if ! uprovided "$ulib_"; then
uprovide "$ulib_"
source "$ulibdir_/$ulib_" || die
fi
done
break
if [ -z "$__u_found" -a "$__u_module" == DEFAULTS ]; then
__u_found=1
for __u_module in base pretty sysinfos compat; do
if ! uprovided "$__u_module"; then
uprovide "$__u_module"
source "$__u_ulibdir/$__u_module" || die
fi
done
[ -n "$found_" ] || die "Unable to find $ulib_ in ${ULIBDIR[*]}"
fi
[ -n "$__u_found" ] || die "Unable to find $__u_module in ${ULIBDIR[*]}"
done
return 0
}
function ulibadd() {
@ -93,7 +94,8 @@ function ulibadd() {
function ulibsync() {
local destdir="$(abspath "${1:-.}")"
local __CPNOVCS_RSYNC_ARGS=(-q --delete)
local -a __CPNOVCS_RSYNC_ARGS
__CPNOVCS_RSYNC_ARGS=(-q --delete)
[ "$destdir/ulib" != "$ULIBDIR" ] && cpdirnovcs "$ULIBDIR" "$destdir/ulib"
}

188
ucrontab
View File

@ -94,6 +94,36 @@ DEFAULT_GDELAY=15
##@inc[base
## Fonctions de base
##@*inc[base.ulib
## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le
## cas où cette librairie n'est pas chargée
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
ULIBPROVIDED=()
function uprovided() {
local module
for module in "${ULIBPROVIDED[@]}"; do
[ "$module" == "$1" ] && return 0
done
return 1
}
function uprovide() {
uprovided "$1" && return 1
ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
}
function urequire() {
local module r=0
for module in "$@"; do
uprovided "$module" && continue
echo "error: $module: this module is required but cannot be automatically loaded" 1>&2
r=1
done
return $r
}
uprovide base.ulib
fi
##@*inc]base.ulib
##@inc[base.init
## Fonctions de base: initialisation de l'environnement
if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then
:
@ -121,6 +151,10 @@ export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc
##@inc]base.init
##@inc[base.core
## Fonctions de base: fondement
uprovide base.core
function recho() {
if [[ "${1:0:2}" == -[eEn] ]]; then
@ -202,26 +236,28 @@ function _setv() {
eval "$__s_var=\"$(_qval "$*")\""
}
function setx() {
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var="'"$("$@")"'
}
function _setx() {
local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"'
}
function seta() {
if [ "$1" == -a ]; then
shift
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=($("$@" | qlines))"
else
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
eval "$__s_var="'"$("$@")"'
fi
}
function _seta() {
function _setvx() {
local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"'
}
function _setax() {
local __s_array="$1"; shift
eval "$__s_array=($("$@" | qlines))"
}
@ -246,7 +282,7 @@ function evalx() {
__e_cmd=("${__e_cmd[@]}" "$__e_arg")
done
if [ -n "$first" ]; then
if [ -n "$__e_first" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$?
else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
@ -257,12 +293,15 @@ function evalx() {
return $__e_r
}
function setx2() {
local -a __s_args
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}"
fi
setx "$__s_var" evalx "$@"
__s_args=("${__s_args[@]}" "$__s_var")
setx "${__s_args[@]}" evalx "$@"
}
function evalp() {
local __e_arg __e_cmd
@ -320,11 +359,16 @@ function testrp() {
function err2out() {
"$@" 2>&1
}
##@inc]base.core
##@inc[base.string
## Fonctions de base: gestion des valeurs scalaires
uprovide base.string
urequire base.core
function tolower() {
function strlower() {
echo ${*,,}
}
function toupper() {
function strupper() {
echo ${*^^}
}
function isnum() {
@ -356,6 +400,56 @@ function is_yes() {
isnum "$1" && [ "$1" -ne 0 ] && return 0
return 1
}
function is_no() {
case "${1,,}" in
n|non|no|f|faux|false|off) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
return 1
}
##@inc]base.string
##@inc[base.array
## Fonctions de base: gestion des tableaux
uprovide base.array
urequire base.core
##@inc]base.array
##@inc[base.compat
## Fonctions de base: support des fonctions obsolètes et des versions de bash < 4.x
uprovide base.compat
urequire base.string
if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then
if uprovided base.string; then
function strlower() { tr A-Z a-z <<<"$*"; }
function strupper() { tr a-z A-Z <<<"$*"; }
function is_yes() {
case "$1" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
case "$(strlower "$1")" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
return 1
}
function is_no() {
case "$1" in
n|non|no|f|faux|false|off) return 0;;
N|NON|NO|F|FAUX|FALSE|OFF) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
case "$(strlower "$1")" in
n|non|no|f|faux|false|off) return 0;;
esac
return 1
}
fi
fi
##@inc]base.compat
uprovide base
urequire base.init base.core base.string base.array base.compat
function yesval() {
is_yes "$1" && echo 1
}
@ -371,13 +465,6 @@ function normyesvals() {
is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" ""
done
}
function is_no() {
case "${1,,}" in
n|non|no|f|faux|false|off) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
return 1
}
function rawecho() {
local first
while [ "${1:0:1}" == "-" ]; do
@ -1052,6 +1139,16 @@ function relpath() {
echo "${rp%//}"
fi
}
function relpathx() {
local p="$(relpath "$@")"
if [ -z "$p" ]; then
echo .
elif [ "${p#../}" != "$p" -o "${p#./}" != "$p" ]; then
echo "$p"
else
echo "./$p"
fi
}
function withinpath() {
local b="$1" p="$2" strict="${3:-N}"
b="$(abspath "$b")"
@ -3436,25 +3533,6 @@ if [ -n "$UTOOLS_CHROOT" ]; then
[ -n "$UTOOLS_UNAME_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM"
[ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE"
fi
if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
ULIBPROVIDED=()
function uprovided() {
array_contains ULIBPROVIDED "$1"
}
function uprovide() {
uprovided "$1" && return 1
array_add ULIBPROVIDED "$1"
}
function urequire() {
local ulib_
for ulib_ in "$@"; do
uprovided "$ulib_" || ewarn "$ulib_: this module is required"
done
}
uprovide base
fi
##@inc]base
##@inc[pretty
## Affichage en couleur, et support de niveaux de "verbosité" et d'interaction
@ -4017,30 +4095,6 @@ if check_sysinfos -s macosx; then
function _nl2crlf() { _nl2lf | awk '{ print $0 "\r" }'; }
function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; }
function sedi() { sed -i '' "$@"; }
function tolower() { tr A-Z a-z <<<"$*"; }
function toupper() { tr a-z A-Z <<<"$*"; }
function is_yes() {
case "$1" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
O|OUI|Y|YES|V|VRAI|T|TRUE|ON) return 0;;
esac
isnum "$1" && [ "$1" -ne 0 ] && return 0
case "$(tolower "$1")" in
o|oui|y|yes|v|vrai|t|true|on) return 0;;
esac
return 1
}
function is_no() {
case "$1" in
n|non|no|f|faux|false|off) return 0;;
N|NON|NO|F|FAUX|FALSE|OFF) return 0;;
esac
isnum "$1" && [ "$1" -eq 0 ] && return 0
case "$(tolower "$1")" in
n|non|no|f|faux|false|off) return 0;;
esac
return 1
}
function __po_check_options() {
local -a options args