From af3bb37f3d0b55b9a1cf1b8d1498d35f18a85000 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 1 Mar 2017 20:01:31 +0400 Subject: [PATCH] ajout de evals() --- lib/ulib/base.string | 112 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 9 deletions(-) diff --git a/lib/ulib/base.string b/lib/ulib/base.string index 9a7fba3..af5f908 100644 --- a/lib/ulib/base.string +++ b/lib/ulib/base.string @@ -1,5 +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 valeurs scalaires +## Fonctions de base: gestion des valeurs chaines scalaires ##@cooked nocomments # Note: contient du code spécifique à bash 4. Le module base.compat réimplémente # les fonctions concernées pour les rendre compatible avec bash >= 2.x @@ -11,35 +11,35 @@ urequire base.core # il faut d'abord le traiter avec _qval() function straddp() { -# ajouter le préfixe $1 à $2* +# ajouter le préfixe $1 à $2..* local p="$1"; shift echo "$p$*" } function strdelp() { -# enlever le préfixe $1 à $2* +# enlever le préfixe $1 à $2..* local p="$1"; shift local str="$*" echo "${str#$p}" } function strdelp2() { -# enlever le préfixe $1 le plus long à $2* +# enlever le préfixe $1 le plus long à $2..* local p="$1"; shift local str="$*" echo "${str##$p}" } function stradds() { -# ajouter le suffixe $1 à $2* +# ajouter le suffixe $1 à $2..* local s="$1"; shift echo "$*$s" } function strdels() { -# enlever le suffixe $1 à $2* +# enlever le suffixe $1 à $2..* local s="$1"; shift local str="$*" echo "${str%$s}" } function strdels2() { -# enlever le suffixe le plus long $1 à $2* +# enlever le suffixe le plus long $1 à $2..* local s="$1"; shift local str="$*" echo "${str%%$s}" @@ -76,7 +76,7 @@ function struppers() { echo "${*^}" } function strmid() { -# Afficher la plage $1 de la valeur $2*. La plage peut être d'une des formes +# Afficher la plage $1 de la valeur $2..*. La plage peut être d'une des formes # 'start', '[start]:length'. Si start est négatif, le compte est effectué à # partir de la fin de la chaine. Si length est négatif, il est rajouté à la # longueur de la chaine à partir de start @@ -100,7 +100,7 @@ function strmid() { eval 'echo "${str:'" $range"'}"' } function strrepl() { -# Remplacer dans la valeur $3* le motif $1 par la chaine $2. $1 peut commencer +# Remplacer dans la valeur $3..* le motif $1 par la chaine $2. $1 peut commencer # par l'un des caractères /, #, % pour indiquer le type de recherche local pattern="$1"; shift local repl="$1"; shift @@ -217,3 +217,97 @@ function endswith() { local str="$1" pattern="$2" eval '[ "${str%$pattern}" != "$str" ]' } + +function strsplitf() { +# Cette fonction doit être appelée avec N arguments (avec N>1). Elle analyse et +# découpe l'argument $N comme avec une ligne de commande du shell. Ensuite, elle +# appelle la fonction $1 avec les arguments de $2 à ${N-1}, suivi des arguments +# obtenus lors de l'analyse de l'argument $N. Par exemple, la commande suivante: +# strsplitf cmd arg1 "long arg2" "arg3 'long arg4'" +# est équivalente à: +# cmd arg1 "long arg2" arg3 "long arg4" +# Retourner le code 127 si la fonction à appeler n'est pas spécifiée. Retourner +# le code 126 si une erreur s'est produite lors de l'analyse de l'argument $N + [ $# -gt 0 ] || return 127 + local func count + func="$1"; shift + count=$# + if [ $count -gt 0 ]; then + eval 'set -- "${@:1:$(($count-1))}" '"${!count}" || return 126 + fi + "$func" "$@" +} +function strecho() { recho "$@"; } +function strqvals() { +# Afficher chaque argument à part avec des quotes. A chainer avec strsplitf() + qvals "$@" +} +function strqlines() { +# Afficher chaque ligne des fichiers spécifiés comme un argument. A chainer avec +# strsplitf() + local -a lines + _setax lines cat "$@" + qvals "${lines[@]}" +} +function strqarray() { +# Afficher chaque valeur des tableaux $@ comme un argument. A chainer avec +# strsplitf() + local __a __s="qvals" + for __a in "$@"; do __s="$__s \"\${$__a[@]}\""; done + eval "$__s" +} + +function evals() { +# Enchainer des traitements sur des chaines de caractères, comme pour la fonction +# evalx(). Il y a cependant quelques différences: +# - Seules certains fonctions spécifiques peuvent être utilisées: elles sont +# reconnaissables à leur préfixe 'str'. En effet, lors de l'utilisation d'une +# commande par evals(), le préfixe 'str' est systématiquement ajouté. +# - La fonction strsplitf() est traitée de façon particulière pour lancer une +# commande avec le préfixe 'str' +# Ainsi, la commande suivante: +# evals cmd1 // splitf cmd2 +# est équivalente à la commande: +# strplitf strcmd2 "$(strcmd1)" + local __e_val __e_arg __e_r=0 + local __e_firstcmd __e_firstarg __e_splitf + local -a __e_cmd + + __e_firstcmd=1 + while [ $# -gt 0 ]; do + __e_cmd=() + __e_firstarg=1 # premier argument + __e_splitf= # premier argument après splitf + 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 + if [ -n "$__e_firstarg" ]; then + __e_cmd=("str$__e_arg") + __e_firstarg= + [ "$__e_arg" == "splitf" ] && __e_splitf=1 + elif [ -n "$__e_splitf" ]; then + __e_cmd=("${__e_cmd[@]}" "str$__e_arg") + __e_splitf= + else + __e_cmd=("${__e_cmd[@]}" "$__e_arg") + fi + done + + if [ -n "$__e_firstcmd" ]; then + __e_val="$("${__e_cmd[@]}")" || __e_r=$? + else + __e_val="$("${__e_cmd[@]}" "$__e_val")" || __e_r=$? + fi + __e_firstcmd= + done + [ -n "$__e_val" ] && echo "$__e_val" + return $__e_r +}