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 Une fois qu'un type de ligne de commentaire est reconnue, toutes les lignes
de directives suivantes doivent être de ce type. 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 # après analyse d'une ligne, indentation et commentaire avant la directive
_prefix, prefix = make_prop('_prefix', None)[:2] _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 # après analyse d'une ligne, nom de la directive
_action, action = make_prop('_action', None)[:2] _action, action = make_prop('_action', None)[:2]
# après analyse d'une ligne, arguments de la directive # après analyse d'une ligne, arguments de la directive
@ -192,11 +197,11 @@ class IncLine(object):
il_pattern = r'(.*)' # prefix il_pattern = r'(.*)' # prefix
if c in ('*', '@'): if c in ('*', '@'):
self._c = self._orig_c = c self._c = self._orig_c = c
il_pattern += r'(?:@|\*)' il_pattern += r'((?:@|\*)\*?)'
else: else:
self._orig_c = None self._orig_c = None
self._c = '@' self._c = '@'
il_pattern += r'@' il_pattern += r'(@\*?)'
# action # action
il_pattern += r'(%s)' % '|'.join([self._RE_SPECIAL.sub(r'\\\1', action) il_pattern += r'(%s)' % '|'.join([self._RE_SPECIAL.sub(r'\\\1', action)
for action in self.ACTIONS]) for action in self.ACTIONS])
@ -221,10 +226,11 @@ class IncLine(object):
mo = self._re_il.match(line) mo = self._re_il.match(line)
if mo is not None: if mo is not None:
self._prefix = mo.group(1) self._prefix = mo.group(1)
self._locked = mo.group(2) in ('@*', '**')
if self.is_prefix(self._prefix): if self.is_prefix(self._prefix):
self._action = mo.group(2) self._action = mo.group(3)
spaces = mo.group(3) spaces = mo.group(4)
self._args = mo.group(4) self._args = mo.group(5)
if self._NO_SPACES.get(self._action, False): if self._NO_SPACES.get(self._action, False):
# il ne doit pas y avoir d'espaces entre cette directive et # il ne doit pas y avoir d'espaces entre cette directive et
# son argument # son argument
@ -234,6 +240,7 @@ class IncLine(object):
# argument # argument
if self._RE_SPACES.match(spaces): return True if self._RE_SPACES.match(spaces): return True
self._prefix = None self._prefix = None
self._locked = None
self._action = None self._action = None
self._args = None self._args = None
return False return False
@ -246,24 +253,28 @@ class IncLine(object):
def is_provide(self): return self._action == self.PROVIDE def is_provide(self): return self._action == self.PROVIDE
def is_cooked(self): return self._action == self.COOKED 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): def get_include(self, name=None):
if name is None: name = self._args 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): def get_start_inc(self, name=None):
if name is None: name = self._args 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): def get_end_inc(self, name=None):
if name is None: name = self._args 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): def get_require(self, name=None):
if name is None: name = self._args 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): def get_provide(self, name=None):
if name is None: name = self._args 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): def get_cooked(self, args=None):
if args is None: args = self._args 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): class Env(object):
"""Un environnement pour plier ou déplier un fichier. """Un environnement pour plier ou déplier un fichier.
@ -515,7 +526,7 @@ class File(Resource):
if not folding: if not folding:
## nous ne somme pas encore dans une section à replier ## nous ne somme pas encore dans une section à replier
# soit nous débutons 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 folding = True
incindex = index incindex = index
name = il.args 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 ##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Fonctions de base ## Fonctions de base
##@cooked nocomments ##@cooked nocomments
##@*inc[base.ulib
# Emplacement du script courant ## Support des fonctions uprovided(), uprovide() et urequire() de ulib dans le
if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then ## cas où cette librairie n'est pas chargée
# ne pas mettre à jour script, scriptname, scriptdir. Ils ont déjà été if [ -z "$ULIBDIR" -o "$ULIBDIR" != "$ULIBINIT" ]; then
# calculés ULIBPROVIDED=()
: function uprovided() {
elif [ "$0" == "-bash" ]; then local module
scriptname= for module in "${ULIBPROVIDED[@]}"; do
scriptdir= [ "$module" == "$1" ] && return 0
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
################################################################################
## 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 done
return 1
if [ -n "$__e_first" ]; then }
__e_val="$("${__e_cmd[@]}")" || __e_r=$? function uprovide() {
else uprovided "$1" && return 1
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? ULIBPROVIDED=("${ULIBPROVIDED[@]}" "$1")
fi }
__e_first= function urequire() {
done local module r=0
[ -n "$__e_val" ] && echo "$__e_val" for module in "$@"; do
return $__e_r uprovided "$module" && continue
} echo "error: $module: this module is required but cannot be automatically loaded" 1>&2
function setx2() { r=1
# équivalent à setx $1 evalx $2..@ done
local -a __s_args return $r
if [ "$1" == -a ]; then __s_args=(-a); shift; fi }
local __s_var="$1"; shift uprovide base.ulib
if [[ "$__s_var" == *=* ]]; then fi
set -- "${__s_var#*=}" "$@" ##@*inc]base.ulib
__s_var="${__s_var%%=*}" ##@include base.init
fi ##@include base.core
__s_args=("${__s_args[@]}" "$__s_var") ##@include base.string
setx "${__s_args[@]}" evalx "$@" ##@include base.array
} ##@include base.compat
function evalp() { uprovide base
# Implémenter une syntaxe alternative permettant d'enchainer des traitements sur urequire base.init base.core base.string base.array base.compat
# 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
}
## valeurs ## 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() { function yesval() {
# normaliser une valeur vraie: si $1 est une valeur "oui", afficher 1, sinon # normaliser une valeur vraie: si $1 est une valeur "oui", afficher 1, sinon
# afficher une chaine vide # afficher une chaine vide
@ -378,14 +60,6 @@ function normyesvals() {
is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" "" is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" ""
done 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() { function rawecho() {
# afficher une valeur brute. contrairement à echo, ne pas reconnaitre les # afficher une valeur brute. contrairement à echo, ne pas reconnaitre les
# options -e, -E, -n. # 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_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM"
[ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE" [ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE"
fi 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" }'; } function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; }
# sed -i demande un argument # sed -i demande un argument
function sedi() { sed -i '' "$@"; } 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 ## gestion des arguments
function __po_check_options() { function __po_check_options() {

View File

@ -6,6 +6,36 @@ PUBKEYS="@@PUBKEYS@@"
##@inc[../base ##@inc[../base
## Fonctions de 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 if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then
: :
@ -33,6 +63,10 @@ export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc [ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc [ -f ~/.nutoolsrc ] && . ~/.nutoolsrc
##@inc]base.init
##@inc[base.core
## Fonctions de base: fondement
uprovide base.core
function recho() { function recho() {
if [[ "${1:0:2}" == -[eEn] ]]; then if [[ "${1:0:2}" == -[eEn] ]]; then
@ -114,26 +148,28 @@ function _setv() {
eval "$__s_var=\"$(_qval "$*")\"" eval "$__s_var=\"$(_qval "$*")\""
} }
function setx() { function setx() {
local __s_var="$1"; shift if [ "$1" == -a ]; then
if [[ "$__s_var" == *=* ]]; then shift
set -- "${__s_var#*=}" "$@" local __s_array="$1"; shift
__s_var="${__s_var%%=*}" 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 fi
eval "$__s_var="'"$("$@")"'
} }
function _setx() { function _setvx() {
local __s_var="$1"; shift local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"' eval "$__s_var="'"$("$@")"'
} }
function seta() { function _setax() {
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=($("$@" | qlines))"
}
function _seta() {
local __s_array="$1"; shift local __s_array="$1"; shift
eval "$__s_array=($("$@" | qlines))" eval "$__s_array=($("$@" | qlines))"
} }
@ -158,7 +194,7 @@ function evalx() {
__e_cmd=("${__e_cmd[@]}" "$__e_arg") __e_cmd=("${__e_cmd[@]}" "$__e_arg")
done done
if [ -n "$first" ]; then if [ -n "$__e_first" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$? __e_val="$("${__e_cmd[@]}")" || __e_r=$?
else else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? __e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
@ -169,12 +205,15 @@ function evalx() {
return $__e_r return $__e_r
} }
function setx2() { function setx2() {
local -a __s_args
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
local __s_var="$1"; shift local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@" set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}" __s_var="${__s_var%%=*}"
fi fi
setx "$__s_var" evalx "$@" __s_args=("${__s_args[@]}" "$__s_var")
setx "${__s_args[@]}" evalx "$@"
} }
function evalp() { function evalp() {
local __e_arg __e_cmd local __e_arg __e_cmd
@ -232,11 +271,16 @@ function testrp() {
function err2out() { function err2out() {
"$@" 2>&1 "$@" 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 ${*,,} echo ${*,,}
} }
function toupper() { function strupper() {
echo ${*^^} echo ${*^^}
} }
function isnum() { function isnum() {
@ -268,6 +312,56 @@ function is_yes() {
isnum "$1" && [ "$1" -ne 0 ] && return 0 isnum "$1" && [ "$1" -ne 0 ] && return 0
return 1 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() { function yesval() {
is_yes "$1" && echo 1 is_yes "$1" && echo 1
} }
@ -283,13 +377,6 @@ function normyesvals() {
is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" "" is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" ""
done 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() { function rawecho() {
local first local first
while [ "${1:0:1}" == "-" ]; do while [ "${1:0:1}" == "-" ]; do
@ -964,6 +1051,16 @@ function relpath() {
echo "${rp%//}" echo "${rp%//}"
fi 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() { function withinpath() {
local b="$1" p="$2" strict="${3:-N}" local b="$1" p="$2" strict="${3:-N}"
b="$(abspath "$b")" 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_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM"
[ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE" [ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE"
fi 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]../base
##@inc[../sysinfos ##@inc[../sysinfos
## Gestion des informations sur l'hôte local ## 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 _nl2crlf() { _nl2lf | awk '{ print $0 "\r" }'; }
function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; } function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; }
function sedi() { sed -i '' "$@"; } 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() { function __po_check_options() {
local -a options args local -a options args

View File

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

View File

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

192
ucrontab
View File

@ -94,6 +94,36 @@ DEFAULT_GDELAY=15
##@inc[base ##@inc[base
## Fonctions de 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 if [ -n "$UTOOLS_HAVE_SCRIPTVARS" ]; then
: :
@ -121,6 +151,10 @@ export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
[ -f /etc/nutoolsrc ] && . /etc/nutoolsrc [ -f /etc/nutoolsrc ] && . /etc/nutoolsrc
[ -f ~/.nutoolsrc ] && . ~/.nutoolsrc [ -f ~/.nutoolsrc ] && . ~/.nutoolsrc
##@inc]base.init
##@inc[base.core
## Fonctions de base: fondement
uprovide base.core
function recho() { function recho() {
if [[ "${1:0:2}" == -[eEn] ]]; then if [[ "${1:0:2}" == -[eEn] ]]; then
@ -202,26 +236,28 @@ function _setv() {
eval "$__s_var=\"$(_qval "$*")\"" eval "$__s_var=\"$(_qval "$*")\""
} }
function setx() { function setx() {
local __s_var="$1"; shift if [ "$1" == -a ]; then
if [[ "$__s_var" == *=* ]]; then shift
set -- "${__s_var#*=}" "$@" local __s_array="$1"; shift
__s_var="${__s_var%%=*}" 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 fi
eval "$__s_var="'"$("$@")"'
} }
function _setx() { function _setvx() {
local __s_var="$1"; shift local __s_var="$1"; shift
eval "$__s_var="'"$("$@")"' eval "$__s_var="'"$("$@")"'
} }
function seta() { function _setax() {
local __s_array="$1"; shift
if [[ "$__s_array" == *=* ]]; then
set -- "${__s_array#*=}" "$@"
__s_array="${__s_array%%=*}"
fi
eval "$__s_array=($("$@" | qlines))"
}
function _seta() {
local __s_array="$1"; shift local __s_array="$1"; shift
eval "$__s_array=($("$@" | qlines))" eval "$__s_array=($("$@" | qlines))"
} }
@ -246,7 +282,7 @@ function evalx() {
__e_cmd=("${__e_cmd[@]}" "$__e_arg") __e_cmd=("${__e_cmd[@]}" "$__e_arg")
done done
if [ -n "$first" ]; then if [ -n "$__e_first" ]; then
__e_val="$("${__e_cmd[@]}")" || __e_r=$? __e_val="$("${__e_cmd[@]}")" || __e_r=$?
else else
__e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? __e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$?
@ -257,12 +293,15 @@ function evalx() {
return $__e_r return $__e_r
} }
function setx2() { function setx2() {
local -a __s_args
if [ "$1" == -a ]; then __s_args=(-a); shift; fi
local __s_var="$1"; shift local __s_var="$1"; shift
if [[ "$__s_var" == *=* ]]; then if [[ "$__s_var" == *=* ]]; then
set -- "${__s_var#*=}" "$@" set -- "${__s_var#*=}" "$@"
__s_var="${__s_var%%=*}" __s_var="${__s_var%%=*}"
fi fi
setx "$__s_var" evalx "$@" __s_args=("${__s_args[@]}" "$__s_var")
setx "${__s_args[@]}" evalx "$@"
} }
function evalp() { function evalp() {
local __e_arg __e_cmd local __e_arg __e_cmd
@ -320,11 +359,16 @@ function testrp() {
function err2out() { function err2out() {
"$@" 2>&1 "$@" 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 ${*,,} echo ${*,,}
} }
function toupper() { function strupper() {
echo ${*^^} echo ${*^^}
} }
function isnum() { function isnum() {
@ -356,6 +400,56 @@ function is_yes() {
isnum "$1" && [ "$1" -ne 0 ] && return 0 isnum "$1" && [ "$1" -ne 0 ] && return 0
return 1 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() { function yesval() {
is_yes "$1" && echo 1 is_yes "$1" && echo 1
} }
@ -371,13 +465,6 @@ function normyesvals() {
is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" "" is_yes "${!__nyv_yesvar}" && set_var "$__nyv_yesvar" 1 || set_var "$__nyv_yesvar" ""
done 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() { function rawecho() {
local first local first
while [ "${1:0:1}" == "-" ]; do while [ "${1:0:1}" == "-" ]; do
@ -1052,6 +1139,16 @@ function relpath() {
echo "${rp%//}" echo "${rp%//}"
fi 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() { function withinpath() {
local b="$1" p="$2" strict="${3:-N}" local b="$1" p="$2" strict="${3:-N}"
b="$(abspath "$b")" 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_SYSTEM" ] && eval "UNAME_SYSTEM=$UTOOLS_UNAME_SYSTEM"
[ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE" [ -n "$UTOOLS_UNAME_MACHINE" ] && eval "UNAME_MACHINE=$UTOOLS_UNAME_MACHINE"
fi 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]base
##@inc[pretty ##@inc[pretty
## Affichage en couleur, et support de niveaux de "verbosité" et d'interaction ## 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 _nl2crlf() { _nl2lf | awk '{ print $0 "\r" }'; }
function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; } function _nl2cr() { _nl2lf | awk 'BEGIN { ORS="" } { print $0 "\r" }'; }
function sedi() { sed -i '' "$@"; } 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() { function __po_check_options() {
local -a options args local -a options args