multiconf: support des variables de type path et compatibilité avec bash 4.3

This commit is contained in:
Jephté Clain 2017-09-18 11:47:20 +04:00
parent 8e17fb1fb3
commit aff1c15931
1 changed files with 63 additions and 20 deletions

View File

@ -9,7 +9,7 @@ function conf_local() {
# par les fonctions conf_* # par les fonctions conf_*
# cela permet d'utiliser ces fonctions à l'intérieur d'autres fonctions sans # cela permet d'utiliser ces fonctions à l'intérieur d'autres fonctions sans
# polluer l'espace de nom # polluer l'espace de nom
echo "local -a __CONF_ARRAY_VARS" echo "local -a __CONF_ARRAY_VARS __CONF_PATH_VARS"
} }
function conf_auto() { function conf_auto() {
@ -50,27 +50,41 @@ function conf_init() {
# par défaut, les variables sont en mode scalaire: la définition d'une # par défaut, les variables sont en mode scalaire: la définition d'une
# variable écrase la valeur précédente. Avec l'option -a les variables sont # variable écrase la valeur précédente. Avec l'option -a les variables sont
# en mode tableau: les nouvelles valeurs sont rajoutées à la fin du tableau. # en mode tableau: les nouvelles valeurs sont rajoutées à la fin du tableau.
# Avec l'option -p les variables sont en mode chemin: les nouvelles valeurs
# sont ajoutées si elles n'existe pas déjà avec le séparateur ':'
# dans l'exemple suivant: # dans l'exemple suivant:
# conf_init NAME VALUE -a SRCDIRS DESTDIRS # conf_init NAME VALUE -a SRCDIRS DESTDIRS -p LIBPATH
# NAME et VALUE sont scalaires alors que SRCDIRS et DESTDIRS sont tableaux # NAME et VALUE sont scalaires, SRCDIRS et DESTDIRS sont des tableaux et
# Les variables scalaires sont initialisées à la valeur vide ou à la valeur # LIBPATH est de type chemin
# spécifiée e.g.: # Les variables scalaires et chemin sont initialisées à la valeur vide ou à
# conf_init VAR=value # la valeur spécifiée e.g.:
# conf_init VAR=value MYPATH=a:b:c
# Les variables tableaux sont toujours initialisées à la valeur vide # Les variables tableaux sont toujours initialisées à la valeur vide
# L'option -s permet de revenir au mode scalaire # L'option -s permet de revenir au mode scalaire
__CONF_ARRAY_VARS=() __CONF_ARRAY_VARS=()
local __var __array __CONF_PATH_VARS=()
local __var __type=scalar
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
-a|--array) __array=1;; -a|--array) __type=array;;
-s|--scalar) __array=;; -p|--path) __type=path;;
-s|--scalar) __type=scalar;;
*) *)
if [ -n "$__array" ]; then case "$__type" in
array)
eval "${1%%=*}=()" eval "${1%%=*}=()"
array_addu __CONF_ARRAY_VARS "${1%%=*}" array_addu __CONF_ARRAY_VARS "${1%%=*}"
else array_del __CONF_PATH_VARS "${1%%=*}"
;;
path)
setv "$1" setv "$1"
fi array_addu __CONF_PATH_VARS "${1%%=*}"
array_del __CONF_ARRAY_VARS "${1%%=*}"
;;
scalar)
setv "$1"
;;
esac
;; ;;
esac esac
shift shift
@ -118,26 +132,55 @@ function conf_load_files() {
# sourcer les fichiers spécifiés en faisant ce qui est nécessaire pour que # sourcer les fichiers spécifiés en faisant ce qui est nécessaire pour que
# les variables de __CONF_ARRAY_VARS soient correctement traitées. # les variables de __CONF_ARRAY_VARS soient correctement traitées.
local -a __conf_backups __conf_values local -a __conf_backups __conf_values
local __conf_file __conf_name __conf_i __conf_backup local __conf_file __conf_name __conf_i __conf_backup __conf_bn __conf_bv
for __conf_file in "$@"; do for __conf_file in "$@"; do
# faire une copie de sauvegarde puis supprimer les variables tableaux # faire une copie de sauvegarde puis supprimer les variables tableaux
__conf_backups=() __conf_backups=()
for __conf_name in "${__CONF_ARRAY_VARS[@]}"; do for __conf_name in "${__CONF_ARRAY_VARS[@]}" "${__CONF_PATH_VARS[@]}"; do
__conf_backups=("${__conf_backups[@]}" "$(declare -p "$__conf_name")") __conf_backup="$(declare -p "$__conf_name" 2>/dev/null)"
if [ -z "$__conf_backup" ]; then
__conf_backup="$__conf_name="
else
# faire une correction de l'expression parce que la commande
# affichée par declare -p est différente entre bash 4.3 et bash
# 4.4 pour les tableaux. pour le tableau array=(a b) on aura:
# - bash 4.3 affiche declare -a array='([0]="a" [1]="b")'
# - bash 4.4 affiche declare -a array=([0]="a" [1]="b")
__conf_backup="${__conf_backup#declare }"
__conf_bn="${__conf_backup%% *}"
__conf_bv="${__conf_backup#* }"
if [[ "$__conf_bn" == -*a* ]]; then
__conf_bn="${__conf_bv%%=*}"
__conf_bv="${__conf_bv#*=}"
if [ "${__conf_bv:0:2}" == "'(" -a "${__conf_bv: -2:2}" == ")'" ]; then
__conf_backup="$__conf_bn=${__conf_bv:1: -1}"
else
__conf_backup="$__conf_bn=$__conf_bv"
fi
else
__conf_backup="$__conf_bv"
fi
fi
__conf_backups=("${__conf_backups[@]}" "$__conf_backup")
unset "$__conf_name" unset "$__conf_name"
done done
# charger le fichier # charger le fichier
source "$__conf_file" source "$__conf_file"
# puis restaurer les variables ou les fusionner avec une éventuelle nouvelle valeur # puis restaurer les variables ou les fusionner avec une éventuelle nouvelle valeur
__conf_i=0 __conf_i=0
for __conf_name in "${__CONF_ARRAY_VARS[@]}"; do for __conf_name in "${__CONF_ARRAY_VARS[@]}" "${__CONF_PATH_VARS[@]}"; do
__conf_backup="${__conf_backups[$__conf_i]}" __conf_backup="${__conf_backups[$__conf_i]}"
__conf_backup="${__conf_backup#declare * }"
if [ -n "$(declare -p "$__conf_name" 2>/dev/null)" ]; then if [ -n "$(declare -p "$__conf_name" 2>/dev/null)" ]; then
# la variable a été redéfinie, la fusionner avec la précédente valeur # la variable a été redéfinie, la fusionner avec la précédente valeur
if array_contains __CONF_ARRAY_VARS "$__conf_name"; then
array_copy __conf_values "$__conf_name" array_copy __conf_values "$__conf_name"
eval "$__conf_backup" eval "$__conf_backup"
array_extend "$__conf_name" __conf_values array_extend "$__conf_name" __conf_values
elif array_contains __CONF_PATH_VARS "$__conf_name"; then
__conf_values="${!__conf_name}"
eval "$__conf_backup"
uaddpath "$__conf_values" "$__conf_name"
fi
else else
# la variable n'a pas été redéfinie, restaurer la précédente valeur # la variable n'a pas été redéfinie, restaurer la précédente valeur
eval "$__conf_backup" eval "$__conf_backup"