diff --git a/lib/ulib/support/install-pubkeys.sh b/lib/ulib/support/install-pubkeys.sh index 7286a60..b0511cf 100755 --- a/lib/ulib/support/install-pubkeys.sh +++ b/lib/ulib/support/install-pubkeys.sh @@ -230,7 +230,7 @@ function evalx() { [ -n "$__e_val" ] && echo "$__e_val" return $__e_r } -function setx2() { +function setxx() { local -a __s_args if [ "$1" == -a ]; then __s_args=(-a); shift; fi local __s_var="$1"; shift @@ -259,6 +259,17 @@ function evalp() { done eval "$__e_cmd" } +function setxp() { + 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[@]}" evalp "$@" +} function testx() { local __t_op="$1"; shift local __t_val="$(evalx "$@")" @@ -393,6 +404,41 @@ function strrepl() { eval "$cmd" } +function first_char() { + local str="$*" + echo "${str:0:1}" +} +function last_char() { + local str="$*" + echo "${str: -1:1}" +} +function first_chars() { + local str="$*" + recho "${str:0:$((${#1}-1))}" +} +function last_chars() { + local str="$*" + recho "${str:1}" +} +function first_char_is() { + [ "${1:0:1}" == "$2" ] +} +function last_char_is() { + [ "${1:$((-1)):1}" == "$2" ] +} +function beginswith() { + local str="$1" pattern="$2" + eval '[ "${str#$pattern}" != "$str" ]' +} +function endswith() { + local str="$1" pattern="$2" + eval '[ "${str%$pattern}" != "$str" ]' +} +##@inc]base.string +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + function isnum() { [ ${#1} -gt 0 ] || return 1 local v="$1" @@ -415,6 +461,39 @@ function isrnum() { v="${v//[0-9]/}" [ -z "$v" ] } +##@inc]base.num +##@inc[base.bool +## Fonctions de base: valeurs booléennes +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +uprovide base.bool +urequire base.num + function is_yes() { case "${1,,}" in o|oui|y|yes|v|vrai|t|true|on) return 0;; @@ -433,6 +512,541 @@ function yesval() { is_yes "$1" && echo 1 } +function setb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + local __s_r + if "$@" >/dev/null; then + eval "$__s_var=1" + else + __s_r=$? + eval "$__s_var=" + return $__s_r + fi +} +function _setb() { + local __s_var="$1"; shift + if "$@" >/dev/null; then + eval "$__s_var=1" + else + eval "$__s_var=" + fi +} + +function evalb() { + if evalx "$@" >/dev/null; then + echo 1 + else + return $? + fi +} +function setxb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + setx "$__s_var" evalb "$@" +} +##@inc]base.bool +##@inc[base.array +## Fonctions de base: gestion des tableaux +uprovide base.array +urequire base.core +##@inc]base.array +##@inc[base.quote +## Fonctions de base: protection de valeurs chaine +uprovide base.quote +urequire base.core + +function _qawk() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s// +/\\n}" + recho_ "$s" +} +function qawk() { + echo -n \" + _qawk "$@" + echo \" +} +function qseds() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\//\\/}" + recho "$s" +} +function _qform() { + local s="$*" + s="${s//\%/%25}" + s="${s//+/%2B}" + s="${s//&/%26}" + s="${s//=/%3D}" + s="${s// /+}" + recho_ "$s" +} +function qform() { + local s="$*" + if [[ "$s" == *=* ]]; then + _qform "${s%%=*}" + echo -n = + _qform "${s#*=}" + echo + else + _qform "$s" + echo + fi +} +##@inc]base.quote +##@inc[base.split +## Fonctions de base: analyse et découpage de valeurs +uprovide base.split +urequire base.core + +function splitfsep() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%%$2*}" + setv "${4:-second}" "${1#*$2}" + else + setv "${3:-first}" "$1" + setv "${4:-second}" + fi +} +function splitfsep2() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%%$2*}" + setv "${4:-second}" "${1#*$2}" + else + setv "${3:-first}" + setv "${4:-second}" "$1" + fi +} +function splitlsep() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%$2*}" + setv "${4:-second}" "${1##*$2}" + else + setv "${3:-first}" "$1" + setv "${4:-second}" + fi +} +function splitlsep2() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%$2*}" + setv "${4:-second}" "${1##*$2}" + else + setv "${3:-first}" + setv "${4:-second}" "$1" + fi +} +function splitvar() { + splitfsep "$1" = "${2:-name}" "${3:-value}" +} +function splitname() { + splitlsep "$1" . "${2:-basename}" "${3:-ext}" +} +function splithost() { + splitfsep "$1" . "${2:-hostname}" "${3:-domain}" +} +function splituserhost() { + splitfsep2 "$1" @ "${2:-user}" "${3:-host}" +} +function splitpair() { + splitfsep "$1" : "${2:-src}" "${3:-dest}" +} +function splitproxy() { + local __sp_tmp __sp_host __sp_port __sp_creds __sp_user __sp_password + + __sp_tmp="${1#http://}" + if [[ "$__sp_tmp" == *@* ]]; then + __sp_creds="${__sp_tmp%%@*}" + __sp_tmp="${__sp_tmp#${__sp_creds}@}" + splitpair "$__sp_creds" __sp_user __sp_password + fi + __sp_tmp="${__sp_tmp%%/*}" + splitpair "$__sp_tmp" __sp_host __sp_port + [ -n "$__sp_port" ] || __sp_port=3128 + + setv "${2:-host}" "$__sp_host" + setv "${3:-port}" "$__sp_port" + setv "${4:-user}" "$__sp_user" + setv "${5:-password}" "$__sp_password" +} +function spliturl() { + local __su_tmp __su_scheme __su_creds __su_user __su_password __su_host __su_port __su_path + + __su_scheme="${1%%:*}" + __su_tmp="${1#${__su_scheme}://}" + if [[ "$__su_tmp" == */* ]]; then + __su_path="${__su_tmp#*/}" + __su_tmp="${__su_tmp%%/*}" + fi + if [[ "$__su_tmp" == *@* ]]; then + __su_creds="${__su_tmp%%@*}" + __su_tmp="${__su_tmp#${__su_creds}@}" + splitpair "$__su_creds" __su_user __su_password + fi + splitpair "$__su_tmp" __su_host __su_port + if [ -z "$__su_port" ]; then + [ "$__su_scheme" == "http" ] && __su_port=80 + [ "$__su_scheme" == "https" ] && __su_port=443 + [ "$__su_scheme" == "ftp" ] && __su_port=21 + fi + + setv "${2:-scheme}" "$__su_scheme" + setv "${3:-user}" "$__su_user" + setv "${4:-password}" "$__su_password" + setv "${5:-host}" "$__su_host" + setv "${6:-port}" "$__su_port" + setv "${7:-path}" "$__su_path" +} +##@inc]base.split +##@inc[base.args +## Analyse des arguments de la ligne de commande +##@inc[base.core +## Fonctions de base: fondement +uprovide base.core + +function echo_() { + echo -n "$*" +} +function recho() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + [ -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 qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + 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 + [ -z "$first" ] && echo +} +function qlines() { + sed "s/'/'\\\\''/g; s/.*/'&'/g" +} +function setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var=\"$(_qval "$*")\"" +} +function _setv() { + local __s_var="$1"; shift + eval "$__s_var=\"$(_qval "$*")\"" +} +function echo_setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + echo "$__s_var=$(qvalr "$*")" +} +function setx() { + 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() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + 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 setxx() { + 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() { + 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 setxp() { + 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[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.string +## Fonctions de base: gestion des valeurs scalaires +uprovide base.string +urequire base.core + +function straddp() { + local p="$1"; shift + echo "$p$*" +} +function strdelp() { + local p="$1"; shift + local str="$*" + echo "${str#$p}" +} +function strdelp2() { + local p="$1"; shift + local str="$*" + echo "${str##$p}" +} +function stradds() { + local s="$1"; shift + echo "$*$s" +} +function strdels() { + local s="$1"; shift + local str="$*" + echo "${str%$s}" +} +function strdels2() { + local s="$1"; shift + local str="$*" + echo "${str%%$s}" +} +function strlower() { + local str="$*" + echo "${str,,}" +} +function strlower1() { + local str="$*" + echo "${str,}" +} +function strlowers() { + local str="$*" + echo "${*,}" +} +function strupper() { + local str="$*" + echo "${str^^}" +} +function strupper1() { + local str="$*" + echo "${str^}" +} +function struppers() { + echo "${*^}" +} +function strmid() { + local range="$1"; shift + local str="$*" + if [[ "$range" == *:-* ]]; then + local max=${#str} + [ $max -eq 0 ] && return + local start="${range%%:*}" + [ -n "$start" ] || start=0 + while [ "$start" -lt 0 ]; do + start=$(($max$start)) + done + max=$(($max-$start)) + local length="${range#*:}" + while [ "$length" -lt 0 ]; do + length=$(($max$length)) + done + range="$start:$length" + fi + eval 'echo "${str:'" $range"'}"' +} +function strrepl() { + local pattern="$1"; shift + local repl="$1"; shift + local str="$*" + local cmd='echo "${str/' + if [ "${pattern#/}" != "$pattern" ]; then + pattern="${pattern#/}" + cmd="$cmd/" + elif [ "${pattern#\#}" != "$pattern" ]; then + pattern="${pattern#\#}" + cmd="$cmd#" + elif [ "${pattern#%}" != "$pattern" ]; then + pattern="${pattern#%}" + cmd="$cmd%" + fi + cmd="$cmd"'$pattern/$repl}"' + eval "$cmd" +} + function first_char() { local str="$*" echo "${str:0:1}" @@ -469,11 +1083,708 @@ function endswith() { uprovide base.array urequire base.core ##@inc]base.array +uprovide base.args +urequire base.core base.string base.array #XXX maj de cette liste + +function __po_parse_optdescs() { + local -a optdescs_ + local optdesc_ option_ name_ flag_ value_ + local reset_ + local shift_ + local i_ count_ + + let shift_=0 + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + let shift_=$shift_+1 + break + elif [ "$1" == "%" ]; then + reset_=1 + shift + let shift_=$shift_+1 + elif [ "$1" == "-" -o "$1" == "+" ]; then + if [ "${opts_#+}" != "$opts_" ]; then + opts_="${opts_#+}" + elif [ "${opts_#-}" != "$opts_" ]; then + opts_="${opts_#-}" + fi + opts_="$1$opts_" + shift + let shift_=$shift_+1 + elif [ "$1" == "@" ]; then + destargs_="$2" + shift; shift + let shift_=$shift_+2 + elif [[ "$1" == --* ]] || [[ "$1" == -* ]]; then + array_split optdescs_ "$1" "," + if [ "$2" == . ]; then + local autoname_= + for optdesc_ in "${optdescs_[@]}"; do + if [ ${#optdesc_} -gt ${#autoname_} ]; then + autoname_="$optdesc_" + fi + done + while [ -n "$autoname_" -a "${autoname_#-}" != "$autoname_" ]; do autoname_="${autoname_#-}"; done + while [ -n "$autoname_" -a "${autoname_%:}" != "$autoname_" ]; do autoname_="${autoname_%:}"; done + autoname_="${autoname_//-/_}" + shift; shift + set -- dummy "$autoname_" "$@" + fi + for optdesc_ in "${optdescs_[@]}"; do + if [[ "$2" == \$* ]]; then + name_="$2" + if [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + flag_='::$' + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + flag_=':$' + else + option_="$optdesc_" + flag_='$' + fi + elif [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=:: + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=: + else + option_="$optdesc_" + name_="$2" + [ -n "$reset_" ] && eval "$name_=" + flag_= + fi + + if i_="$(array_find options_ "$option_")"; then + options_=("${options_[@]:0:$i_}" "${options_[@]:$(($i_ + 1))}") + names_=("${names_[@]:0:$i_}" "${names_[@]:$(($i_ + 1))}") + flags_=("${flags_[@]:0:$i_}" "${flags_[@]:$(($i_ + 1))}") + fi + options_=("${options_[@]}" "$option_") + names_=("${names_[@]}" "$name_") + flags_=("${flags_[@]}" "$flag_") + done + shift; shift + let shift_=$shift_+2 + else + break + fi + done + + i_=0 + count_=${#options_[*]} + while [ $i_ -lt $count_ ]; do + option_="${options_[$i_]}" + flag_="${flags_[$i_]}" + i_=$(($i_ + 1)) + + flag_="${flag_%$}" + if [[ "$option_" == --* ]]; then + longopts_="${longopts_:+$longopts_,}${option_#--}$flag_" + elif [[ "$option_" == -* ]]; then + opts_="$opts_${option_#-}$flag_" + fi + done + + return $shift_ +} +function __po_check_options() { + local -a getopt_args_ + getopt_args_=(-o "$opts_" ${longopts_:+-l "$longopts_"} -- "$@") + local args_ + if args_="$(getopt -q "${getopt_args_[@]}")"; then + recho "$args_" + return 0 + else + LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null + return 1 + fi +} +function __po_process_options() { + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + break + elif [[ "$1" == -* ]]; then + local i_ + let i_=0 + for option_ in "${options_[@]}"; do + [ "$1" == "${options_[$i_]}" ] && break + let i_=$i_+1 + done + name_="names_[$i_]"; name_="${!name_}" + flag_="flags_[$i_]"; flag_="${!flag_}" + function inc@ { eval "let $1=\$$1+1"; } + function res@ { set_var "$1" "${value_:-$2}"; } + function add@ { array_add "$1" "${value_:-$2}"; } + if [ -z "$name_" ]; then + ewarn "$1: option non reconnue, elle sera ignorée" + elif [[ "$flag_" == *\$ ]]; then + if [[ "$flag_" == :* ]]; then + value_="$2"; shift + function set@ { res@ "$@"; } + else + value_= + function set@ { inc@ "$@"; } + fi + eval "${name_#\$}" + elif [ "$flag_" == "" ]; then + if [[ "$name_" == *=* ]]; then + set_var "${name_%%=*}" "${name_#*=}" + else + inc@ "$name_" + fi + elif [ "$flag_" == ":" -o "$flag_" == "::" ]; then + value_="$2"; shift + if [ "${name_%=}" != "$name_" ]; then + set_var "${name_%=}" "$value_" + elif [[ "$name_" == *=* ]]; then + set_var "${name_%%=*}" "${name_#*=}" + else + array_add "$name_" "$value_" + fi + fi + else + break + fi + shift + done + unset -f inc@ res@ add@ set@ + [ -n "$destargs_" ] && + set_array "$destargs_" @ "$@" + return 0 +} +function parse_opts() { + + + + local -a options_ names_ flags_ destargs_ + local opts_ longopts_ + __po_parse_optdescs "$@" || shift $? + local args_ + if args_="$(__po_check_options "$@")"; then + eval "set -- $args_" + __po_process_options "$@" + else + [ -n "$destargs_" ] && set_var "$destargs_" "$args_" + return 1 + fi +} + +function parse_args_check() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" && return 0 + eerror "$args" + return 1 +} +function parse_args() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" || die "$args" +} + +HELP_DESC= +HELP_USAGE= +HELP_OPTIONS= +function __genparse_shortopt() { + local LC_COLLATE=C + local shortopt="${1//[^A-Z]}" + shortopt="$(strlower "${shortopt:0:1}")" + [ -n "$shortopt" ] && echo "$shortopt" +} +function genparse() { + + local -a names descs vars options + local i desc var option name uname value shortopt + + for var in "$@"; do + if [[ "$var" == *=* ]]; then + splitvar "$var" name value + shortopt="$(__genparse_shortopt "$name")" + option="$(strlower "$name")" + name="${option//-/_}" + array_add names "$name" + array_add descs "${shortopt:+-$shortopt, }--$option VALUE" + array_add vars "$(set_var_cmd "$name" "$value")" + array_add options "${shortopt:+-$shortopt:,}--$option: $name=" + else + name="$var" + shortopt="$(__genparse_shortopt "$name")" + option="$(strlower "$name")" + name="${option//-/_}" + array_add names "$name" + array_add descs "${shortopt:+-$shortopt, }--$option" + array_add vars "$name=" + array_add options "${shortopt:+-$shortopt,}--$option $name=1" + fi + done + + echo -n 'function display_help() { + [ -n "$HELP_USAGE" ] || HELP_USAGE="USAGE + $scriptname' + [ -n "$descs" ] && echo -n ' [options]' + echo '"' + if [ -n "$descs" ]; then + echo -n ' [ -n "$HELP_OPTIONS" ] || HELP_OPTIONS="OPTIONS' + i=0 + while [ $i -lt ${#descs[*]} ]; do + name="${names[$i]}" + uname="$(strupper "$name")" + desc="${descs[$i]}" + echo -n " +\${HELP_${uname}_OPTION:- $desc\${HELP_${uname}_DESC:+ + \${HELP_${uname}_DESC// +/ + }}}" + i=$(($i + 1)) + done + echo '"' + fi + echo ' uecho "${HELP_DESC:+$HELP_DESC + +}$HELP_USAGE${HELP_OPTIONS:+ + +$HELP_OPTIONS}" +} +' + for var in "${vars[@]}"; do + echo "$var" + done + echo 'parse_opts "${PRETTYOPTS[@]}" \' + echo ' --help '\''$exit_with display_help'\'' \' + for option in "${options[@]}"; do + echo " $option \\" + done + echo ' @ args -- "$@" && set -- "${args[@]}" || die "$args"' +} +##@inc]base.args ##@inc[base.compat ## Fonctions de base: support des fonctions obsolètes et des versions de bash < 4.x +##@inc[base.core +## Fonctions de base: fondement +uprovide base.core + +function echo_() { + echo -n "$*" +} +function recho() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + [ -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 qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + 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 + [ -z "$first" ] && echo +} +function qlines() { + sed "s/'/'\\\\''/g; s/.*/'&'/g" +} +function setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var=\"$(_qval "$*")\"" +} +function _setv() { + local __s_var="$1"; shift + eval "$__s_var=\"$(_qval "$*")\"" +} +function echo_setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + echo "$__s_var=$(qvalr "$*")" +} +function setx() { + 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() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + 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 setxx() { + 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() { + 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 setxp() { + 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[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +##@inc[base.bool +## Fonctions de base: valeurs booléennes +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +uprovide base.bool +urequire base.num + +function is_yes() { + 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() { + case "${1,,}" in + n|non|no|f|faux|false|off) return 0;; + esac + isnum "$1" && [ "$1" -eq 0 ] && return 0 + return 1 +} +function yesval() { + is_yes "$1" && echo 1 +} + +function setb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + local __s_r + if "$@" >/dev/null; then + eval "$__s_var=1" + else + __s_r=$? + eval "$__s_var=" + return $__s_r + fi +} +function _setb() { + local __s_var="$1"; shift + if "$@" >/dev/null; then + eval "$__s_var=1" + else + eval "$__s_var=" + fi +} + +function evalb() { + if evalx "$@" >/dev/null; then + echo 1 + else + return $? + fi +} +function setxb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + setx "$__s_var" evalb "$@" +} +##@inc]base.bool +##@inc[base.quote +## Fonctions de base: protection de valeurs chaine +uprovide base.quote +urequire base.core + +function _qawk() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s// +/\\n}" + recho_ "$s" +} +function qawk() { + echo -n \" + _qawk "$@" + echo \" +} +function qseds() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\//\\/}" + recho "$s" +} +function _qform() { + local s="$*" + s="${s//\%/%25}" + s="${s//+/%2B}" + s="${s//&/%26}" + s="${s//=/%3D}" + s="${s// /+}" + recho_ "$s" +} +function qform() { + local s="$*" + if [[ "$s" == *=* ]]; then + _qform "${s%%=*}" + echo -n = + _qform "${s#*=}" + echo + else + _qform "$s" + echo + fi +} +##@inc]base.quote uprovide base.compat +urequire base.core base.num base.bool base.quote +function setx2() { setxx "$@"; } function rawecho() { recho "$@"; } function rawecho_() { recho_ "$@"; } function quote_arg() { _qval "$@"; } @@ -517,6 +1828,7 @@ if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then done echo "${vs[*]}" } + function is_yes() { case "$1" in o|oui|y|yes|v|vrai|t|true|on) return 0;; @@ -542,7 +1854,7 @@ if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then fi ##@inc]base.compat uprovide base -urequire base.init base.core base.string base.quote base.split base.array base.compat +urequire base.init base.core base.string base.num base.bool base.array base.quote base.split base.args base.compat UNAME_SYSTEM=`uname -s` [ "${UNAME_SYSTEM#CYGWIN}" != "$UNAME_SYSTEM" ] && UNAME_SYSTEM=Cygwin @@ -1399,6 +2711,29 @@ function _nl2cr() { function nl2cr() { doinplace "$1" _nl2cr } +function _latin1compat() { + LANG=fr_FR.UTF-8 sed $' +s/[’]/\x27/g +s/[«»]/"/g +s/[\xC2\xA0\xE2\x80\x87\xE2\x80\xAF\xE2\x81\xA0]/ /g +' +} +function _noaccents() { + LANG=fr_FR.UTF-8 sed ' +s/[à]/a/g +s/[éèêë]/e/g +s/[ïî]/i/g +s/[ôö]/o/g +s/[üû]/u/g +s/[ç]/c/g +s/[À]/A/g +s/[ÉÈÊË]/E/g +s/[ÏÎ]/I/g +s/[ÔÖ]/O/g +s/[ÜÛ]/U/g +s/[Ç]/C/g +' +} function list_all() { local curdir="$(pwd)" local b="${1:-.}"; shift @@ -1831,6 +3166,13 @@ function array_newsize(dest, size, i) { dest[i] = "" } } +function array_len(values, count, i) { + count = 0 + for (i in values) { + count++ + } + return count +} function mkindices(values, indices, i, j) { array_new(indices) j = 1 @@ -1858,7 +3200,7 @@ function array_add(dest, value, lastindex) { function array_deli(dest, i, l) { i = int(i) if (i == 0) return - l = length(dest) + l = array_len(dest) while (i < l) { dest[i] = dest[i + 1] i++ @@ -2076,11 +3418,14 @@ function __array_parsecsv(fields, line, nbfields, colsep, qchar, echar, shou i = i + 1 } if (nbfields) { - while (length(fields) < nbfields) { - fields[length(fields) + 1] = "" + nbfields = int(nbfields) + i = array_len(fields) + while (i < nbfields) { + i++ + fields[i] = "" } } - return length(fields) + return array_len(fields) } BEGIN { DEFAULT_COLSEP = "," @@ -2149,7 +3494,7 @@ function printcsv(output, fields) { array_fill(fields) array_printcsv(fields, output) } -function array_findcsv(fields, input, field, value, nbfields, orig, found) { +function array_findcsv(fields, input, field, value, nbfields, orig, found, i) { array_new(orig) array_fill(orig) array_new(fields) @@ -2166,8 +3511,11 @@ function array_findcsv(fields, input, field, value, nbfields, orig, fou if (!found) { delete fields if (nbfields) { - while (length(fields) < nbfields) { - fields[length(fields) + 1] = "" + nbfields = int(nbfields) + i = array_len(fields) + while (i < nbfields) { + i++ + fields[i] = "" } } } @@ -2312,259 +3660,6 @@ function lawkrun() { } function cawkrun() { LANG=C lawkrun "$@"; } function awkrun() { LANG=C lawkrun "$@"; } -function parse_opts() { - - - - local -a options_ names_ flags_ destargs_ - local opts_ longopts_ - __po_parse_optdescs "$@" || shift $? - local args_ - if args_="$(__po_check_options "$@")"; then - eval "set -- $args_" - __po_process_options "$@" - else - [ -n "$destargs_" ] && set_var "$destargs_" "$args_" - return 1 - fi -} -function __po_parse_optdescs() { - local -a optdescs_ - local optdesc_ option_ name_ flag_ value_ - local shift_ - local i_ count_ - - let shift_=0 - while [ -n "$1" ]; do - if [ "$1" == -- ]; then - shift - let shift_=$shift_+1 - break - elif [ "$1" == "-" -o "$1" == "+" ]; then - if [ "${opts_#+}" != "$opts_" ]; then - opts_="${opts_#+}" - elif [ "${opts_#-}" != "$opts_" ]; then - opts_="${opts_#-}" - fi - opts_="$1$opts_" - shift - let shift_=$shift_+1 - elif [ "$1" == "@" ]; then - destargs_="$2" - shift; shift - let shift_=$shift_+2 - elif [[ "$1" == --* ]] || [[ "$1" == -* ]]; then - array_split optdescs_ "$1" "," - for optdesc_ in "${optdescs_[@]}"; do - if [[ "$2" == \$* ]]; then - name_="$2" - if [[ "$optdesc_" == *:: ]]; then - option_="${optdesc_%::}" - flag_='::$' - elif [[ "$optdesc_" == *: ]]; then - option_="${optdesc_%:}" - flag_=':$' - else - option_="$optdesc_" - flag_='$' - fi - elif [[ "$optdesc_" == *:: ]]; then - option_="${optdesc_%::}" - if [[ "$2" == *=* ]]; then - name_="${2%%=*}=" - else - name_="$2" - array_new "$name_" - fi - flag_=:: - elif [[ "$optdesc_" == *: ]]; then - option_="${optdesc_%:}" - if [[ "$2" == *=* ]]; then - name_="${2%%=*}=" - else - name_="$2" - array_new "$name_" - fi - flag_=: - else - option_="$optdesc_" - name_="$2" - flag_= - fi - - if i_="$(array_find options_ "$option_")"; then - options_=("${options_[@]:0:$i_}" "${options_[@]:$(($i_ + 1))}") - names_=("${names_[@]:0:$i_}" "${names_[@]:$(($i_ + 1))}") - flags_=("${flags_[@]:0:$i_}" "${flags_[@]:$(($i_ + 1))}") - fi - options_=("${options_[@]}" "$option_") - names_=("${names_[@]}" "$name_") - flags_=("${flags_[@]}" "$flag_") - done - shift; shift - let shift_=$shift_+2 - else - break - fi - done - - i_=0 - count_=${#options_[*]} - while [ $i_ -lt $count_ ]; do - option_="${options_[$i_]}" - flag_="${flags_[$i_]}" - i_=$(($i_ + 1)) - - flag_="${flag_%$}" - if [[ "$option_" == --* ]]; then - longopts_="${longopts_:+$longopts_,}${option_#--}$flag_" - elif [[ "$option_" == -* ]]; then - opts_="$opts_${option_#-}$flag_" - fi - done - - return $shift_ -} -function __po_check_options() { - local -a getopt_args_ - getopt_args_=(-o "$opts_" ${longopts_:+-l "$longopts_"} -- "$@") - local args_ - if args_="$(getopt -q "${getopt_args_[@]}")"; then - rawecho "$args_" - return 0 - else - LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null - return 1 - fi -} -function __po_process_options() { - while [ -n "$1" ]; do - if [ "$1" == -- ]; then - shift - break - elif [[ "$1" == -* ]]; then - local i_ - let i_=0 - for option_ in "${options_[@]}"; do - [ "$1" == "${options_[$i_]}" ] && break - let i_=$i_+1 - done - name_="names_[$i_]"; name_="${!name_}" - flag_="flags_[$i_]"; flag_="${!flag_}" - function inc@ { eval "let $1=\$$1+1"; } - function res@ { set_var "$1" "${value_:-$2}"; } - function add@ { array_add "$1" "${value_:-$2}"; } - if [ -z "$name_" ]; then - ewarn "$1: option non reconnue, elle sera ignorée" - elif [[ "$flag_" == *\$ ]]; then - if [[ "$flag_" == :* ]]; then - value_="$2"; shift - function set@ { res@ "$@"; } - else - value_= - function set@ { inc@ "$@"; } - fi - eval "${name_#\$}" - elif [ "$flag_" == "" ]; then - if [[ "$name_" == *=* ]]; then - set_var "${name_%%=*}" "${name_#*=}" - else - inc@ "$name_" - fi - elif [ "$flag_" == ":" -o "$flag_" == "::" ]; then - value_="$2"; shift - if [ "${name_%=}" != "$name_" ]; then - set_var "${name_%=}" "$value_" - elif [[ "$name_" == *=* ]]; then - set_var "${name_%%=*}" "${name_#*=}" - else - array_add "$name_" "$value_" - fi - fi - else - break - fi - shift - done - unset -f inc@ res@ add@ set@ - [ -n "$destargs_" ] && - set_array "$destargs_" @ "$@" - return 0 -} -function __genparse_shortopt() { - local LC_COLLATE=C - local shortopt="${1//[^A-Z]}" - shortopt="$(tolower "${shortopt:0:1}")" - [ -n "$shortopt" ] && echo "$shortopt" -} -HELP_DESC= -HELP_USAGE= -HELP_OPTIONS= -function genparse() { - - local -a names descs vars options - local i desc var option name uname value shortopt - - for var in "$@"; do - if [[ "$var" == *=* ]]; then - splitvar "$var" name value - shortopt="$(__genparse_shortopt "$name")" - option="$(tolower "$name")" - name="${option//-/_}" - array_add names "$name" - array_add descs "${shortopt:+-$shortopt, }--$option VALUE" - array_add vars "$(set_var_cmd "$name" "$value")" - array_add options "${shortopt:+-$shortopt:,}--$option: $name=" - else - name="$var" - shortopt="$(__genparse_shortopt "$name")" - option="$(tolower "$name")" - name="${option//-/_}" - array_add names "$name" - array_add descs "${shortopt:+-$shortopt, }--$option" - array_add vars "$name=" - array_add options "${shortopt:+-$shortopt,}--$option $name=1" - fi - done - - echo -n 'function display_help() { - [ -n "$HELP_USAGE" ] || HELP_USAGE="USAGE - $scriptname' - [ -n "$descs" ] && echo -n ' [options]' - echo '"' - if [ -n "$descs" ]; then - echo -n ' [ -n "$HELP_OPTIONS" ] || HELP_OPTIONS="OPTIONS' - i=0 - while [ $i -lt ${#descs[*]} ]; do - name="${names[$i]}" - uname="$(strupper "$name")" - desc="${descs[$i]}" - echo -n " -\${HELP_${uname}_OPTION:- $desc\${HELP_${uname}_DESC:+ - \${HELP_${uname}_DESC// -/ - }}}" - i=$(($i + 1)) - done - echo '"' - fi - echo ' uecho "${HELP_DESC:+$HELP_DESC - -}$HELP_USAGE${HELP_OPTIONS:+ - -$HELP_OPTIONS}" -} -' - for var in "${vars[@]}"; do - echo "$var" - done - echo 'parse_opts "${PRETTYOPTS[@]}" \' - echo ' --help '\''$exit_with display_help'\'' \' - for option in "${options[@]}"; do - echo " $option \\" - done - echo ' @ args -- "$@" && set -- "${args[@]}" || die "$args"' -} function __lf_get_age() { local y=$(date "+%Y") diff --git a/ucrontab b/ucrontab index 5690866..c091fe3 100755 --- a/ucrontab +++ b/ucrontab @@ -318,7 +318,7 @@ function evalx() { [ -n "$__e_val" ] && echo "$__e_val" return $__e_r } -function setx2() { +function setxx() { local -a __s_args if [ "$1" == -a ]; then __s_args=(-a); shift; fi local __s_var="$1"; shift @@ -347,6 +347,17 @@ function evalp() { done eval "$__e_cmd" } +function setxp() { + 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[@]}" evalp "$@" +} function testx() { local __t_op="$1"; shift local __t_val="$(evalx "$@")" @@ -481,6 +492,41 @@ function strrepl() { eval "$cmd" } +function first_char() { + local str="$*" + echo "${str:0:1}" +} +function last_char() { + local str="$*" + echo "${str: -1:1}" +} +function first_chars() { + local str="$*" + recho "${str:0:$((${#1}-1))}" +} +function last_chars() { + local str="$*" + recho "${str:1}" +} +function first_char_is() { + [ "${1:0:1}" == "$2" ] +} +function last_char_is() { + [ "${1:$((-1)):1}" == "$2" ] +} +function beginswith() { + local str="$1" pattern="$2" + eval '[ "${str#$pattern}" != "$str" ]' +} +function endswith() { + local str="$1" pattern="$2" + eval '[ "${str%$pattern}" != "$str" ]' +} +##@inc]base.string +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + function isnum() { [ ${#1} -gt 0 ] || return 1 local v="$1" @@ -503,6 +549,39 @@ function isrnum() { v="${v//[0-9]/}" [ -z "$v" ] } +##@inc]base.num +##@inc[base.bool +## Fonctions de base: valeurs booléennes +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +uprovide base.bool +urequire base.num + function is_yes() { case "${1,,}" in o|oui|y|yes|v|vrai|t|true|on) return 0;; @@ -521,6 +600,541 @@ function yesval() { is_yes "$1" && echo 1 } +function setb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + local __s_r + if "$@" >/dev/null; then + eval "$__s_var=1" + else + __s_r=$? + eval "$__s_var=" + return $__s_r + fi +} +function _setb() { + local __s_var="$1"; shift + if "$@" >/dev/null; then + eval "$__s_var=1" + else + eval "$__s_var=" + fi +} + +function evalb() { + if evalx "$@" >/dev/null; then + echo 1 + else + return $? + fi +} +function setxb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + setx "$__s_var" evalb "$@" +} +##@inc]base.bool +##@inc[base.array +## Fonctions de base: gestion des tableaux +uprovide base.array +urequire base.core +##@inc]base.array +##@inc[base.quote +## Fonctions de base: protection de valeurs chaine +uprovide base.quote +urequire base.core + +function _qawk() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s// +/\\n}" + recho_ "$s" +} +function qawk() { + echo -n \" + _qawk "$@" + echo \" +} +function qseds() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\//\\/}" + recho "$s" +} +function _qform() { + local s="$*" + s="${s//\%/%25}" + s="${s//+/%2B}" + s="${s//&/%26}" + s="${s//=/%3D}" + s="${s// /+}" + recho_ "$s" +} +function qform() { + local s="$*" + if [[ "$s" == *=* ]]; then + _qform "${s%%=*}" + echo -n = + _qform "${s#*=}" + echo + else + _qform "$s" + echo + fi +} +##@inc]base.quote +##@inc[base.split +## Fonctions de base: analyse et découpage de valeurs +uprovide base.split +urequire base.core + +function splitfsep() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%%$2*}" + setv "${4:-second}" "${1#*$2}" + else + setv "${3:-first}" "$1" + setv "${4:-second}" + fi +} +function splitfsep2() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%%$2*}" + setv "${4:-second}" "${1#*$2}" + else + setv "${3:-first}" + setv "${4:-second}" "$1" + fi +} +function splitlsep() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%$2*}" + setv "${4:-second}" "${1##*$2}" + else + setv "${3:-first}" "$1" + setv "${4:-second}" + fi +} +function splitlsep2() { + if [[ "$1" == *"$2"* ]]; then + setv "${3:-first}" "${1%$2*}" + setv "${4:-second}" "${1##*$2}" + else + setv "${3:-first}" + setv "${4:-second}" "$1" + fi +} +function splitvar() { + splitfsep "$1" = "${2:-name}" "${3:-value}" +} +function splitname() { + splitlsep "$1" . "${2:-basename}" "${3:-ext}" +} +function splithost() { + splitfsep "$1" . "${2:-hostname}" "${3:-domain}" +} +function splituserhost() { + splitfsep2 "$1" @ "${2:-user}" "${3:-host}" +} +function splitpair() { + splitfsep "$1" : "${2:-src}" "${3:-dest}" +} +function splitproxy() { + local __sp_tmp __sp_host __sp_port __sp_creds __sp_user __sp_password + + __sp_tmp="${1#http://}" + if [[ "$__sp_tmp" == *@* ]]; then + __sp_creds="${__sp_tmp%%@*}" + __sp_tmp="${__sp_tmp#${__sp_creds}@}" + splitpair "$__sp_creds" __sp_user __sp_password + fi + __sp_tmp="${__sp_tmp%%/*}" + splitpair "$__sp_tmp" __sp_host __sp_port + [ -n "$__sp_port" ] || __sp_port=3128 + + setv "${2:-host}" "$__sp_host" + setv "${3:-port}" "$__sp_port" + setv "${4:-user}" "$__sp_user" + setv "${5:-password}" "$__sp_password" +} +function spliturl() { + local __su_tmp __su_scheme __su_creds __su_user __su_password __su_host __su_port __su_path + + __su_scheme="${1%%:*}" + __su_tmp="${1#${__su_scheme}://}" + if [[ "$__su_tmp" == */* ]]; then + __su_path="${__su_tmp#*/}" + __su_tmp="${__su_tmp%%/*}" + fi + if [[ "$__su_tmp" == *@* ]]; then + __su_creds="${__su_tmp%%@*}" + __su_tmp="${__su_tmp#${__su_creds}@}" + splitpair "$__su_creds" __su_user __su_password + fi + splitpair "$__su_tmp" __su_host __su_port + if [ -z "$__su_port" ]; then + [ "$__su_scheme" == "http" ] && __su_port=80 + [ "$__su_scheme" == "https" ] && __su_port=443 + [ "$__su_scheme" == "ftp" ] && __su_port=21 + fi + + setv "${2:-scheme}" "$__su_scheme" + setv "${3:-user}" "$__su_user" + setv "${4:-password}" "$__su_password" + setv "${5:-host}" "$__su_host" + setv "${6:-port}" "$__su_port" + setv "${7:-path}" "$__su_path" +} +##@inc]base.split +##@inc[base.args +## Analyse des arguments de la ligne de commande +##@inc[base.core +## Fonctions de base: fondement +uprovide base.core + +function echo_() { + echo -n "$*" +} +function recho() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + [ -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 qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + 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 + [ -z "$first" ] && echo +} +function qlines() { + sed "s/'/'\\\\''/g; s/.*/'&'/g" +} +function setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var=\"$(_qval "$*")\"" +} +function _setv() { + local __s_var="$1"; shift + eval "$__s_var=\"$(_qval "$*")\"" +} +function echo_setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + echo "$__s_var=$(qvalr "$*")" +} +function setx() { + 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() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + 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 setxx() { + 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() { + 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 setxp() { + 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[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.string +## Fonctions de base: gestion des valeurs scalaires +uprovide base.string +urequire base.core + +function straddp() { + local p="$1"; shift + echo "$p$*" +} +function strdelp() { + local p="$1"; shift + local str="$*" + echo "${str#$p}" +} +function strdelp2() { + local p="$1"; shift + local str="$*" + echo "${str##$p}" +} +function stradds() { + local s="$1"; shift + echo "$*$s" +} +function strdels() { + local s="$1"; shift + local str="$*" + echo "${str%$s}" +} +function strdels2() { + local s="$1"; shift + local str="$*" + echo "${str%%$s}" +} +function strlower() { + local str="$*" + echo "${str,,}" +} +function strlower1() { + local str="$*" + echo "${str,}" +} +function strlowers() { + local str="$*" + echo "${*,}" +} +function strupper() { + local str="$*" + echo "${str^^}" +} +function strupper1() { + local str="$*" + echo "${str^}" +} +function struppers() { + echo "${*^}" +} +function strmid() { + local range="$1"; shift + local str="$*" + if [[ "$range" == *:-* ]]; then + local max=${#str} + [ $max -eq 0 ] && return + local start="${range%%:*}" + [ -n "$start" ] || start=0 + while [ "$start" -lt 0 ]; do + start=$(($max$start)) + done + max=$(($max-$start)) + local length="${range#*:}" + while [ "$length" -lt 0 ]; do + length=$(($max$length)) + done + range="$start:$length" + fi + eval 'echo "${str:'" $range"'}"' +} +function strrepl() { + local pattern="$1"; shift + local repl="$1"; shift + local str="$*" + local cmd='echo "${str/' + if [ "${pattern#/}" != "$pattern" ]; then + pattern="${pattern#/}" + cmd="$cmd/" + elif [ "${pattern#\#}" != "$pattern" ]; then + pattern="${pattern#\#}" + cmd="$cmd#" + elif [ "${pattern#%}" != "$pattern" ]; then + pattern="${pattern#%}" + cmd="$cmd%" + fi + cmd="$cmd"'$pattern/$repl}"' + eval "$cmd" +} + function first_char() { local str="$*" echo "${str:0:1}" @@ -557,11 +1171,708 @@ function endswith() { uprovide base.array urequire base.core ##@inc]base.array +uprovide base.args +urequire base.core base.string base.array #XXX maj de cette liste + +function __po_parse_optdescs() { + local -a optdescs_ + local optdesc_ option_ name_ flag_ value_ + local reset_ + local shift_ + local i_ count_ + + let shift_=0 + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + let shift_=$shift_+1 + break + elif [ "$1" == "%" ]; then + reset_=1 + shift + let shift_=$shift_+1 + elif [ "$1" == "-" -o "$1" == "+" ]; then + if [ "${opts_#+}" != "$opts_" ]; then + opts_="${opts_#+}" + elif [ "${opts_#-}" != "$opts_" ]; then + opts_="${opts_#-}" + fi + opts_="$1$opts_" + shift + let shift_=$shift_+1 + elif [ "$1" == "@" ]; then + destargs_="$2" + shift; shift + let shift_=$shift_+2 + elif [[ "$1" == --* ]] || [[ "$1" == -* ]]; then + array_split optdescs_ "$1" "," + if [ "$2" == . ]; then + local autoname_= + for optdesc_ in "${optdescs_[@]}"; do + if [ ${#optdesc_} -gt ${#autoname_} ]; then + autoname_="$optdesc_" + fi + done + while [ -n "$autoname_" -a "${autoname_#-}" != "$autoname_" ]; do autoname_="${autoname_#-}"; done + while [ -n "$autoname_" -a "${autoname_%:}" != "$autoname_" ]; do autoname_="${autoname_%:}"; done + autoname_="${autoname_//-/_}" + shift; shift + set -- dummy "$autoname_" "$@" + fi + for optdesc_ in "${optdescs_[@]}"; do + if [[ "$2" == \$* ]]; then + name_="$2" + if [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + flag_='::$' + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + flag_=':$' + else + option_="$optdesc_" + flag_='$' + fi + elif [[ "$optdesc_" == *:: ]]; then + option_="${optdesc_%::}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=:: + elif [[ "$optdesc_" == *: ]]; then + option_="${optdesc_%:}" + if [[ "$2" == *=* ]]; then + name_="${2%%=*}=" + [ -n "$reset_" ] && eval "$name_=" + else + name_="$2" + [ -n "$reset_" ] && eval "$name_=()" + fi + flag_=: + else + option_="$optdesc_" + name_="$2" + [ -n "$reset_" ] && eval "$name_=" + flag_= + fi + + if i_="$(array_find options_ "$option_")"; then + options_=("${options_[@]:0:$i_}" "${options_[@]:$(($i_ + 1))}") + names_=("${names_[@]:0:$i_}" "${names_[@]:$(($i_ + 1))}") + flags_=("${flags_[@]:0:$i_}" "${flags_[@]:$(($i_ + 1))}") + fi + options_=("${options_[@]}" "$option_") + names_=("${names_[@]}" "$name_") + flags_=("${flags_[@]}" "$flag_") + done + shift; shift + let shift_=$shift_+2 + else + break + fi + done + + i_=0 + count_=${#options_[*]} + while [ $i_ -lt $count_ ]; do + option_="${options_[$i_]}" + flag_="${flags_[$i_]}" + i_=$(($i_ + 1)) + + flag_="${flag_%$}" + if [[ "$option_" == --* ]]; then + longopts_="${longopts_:+$longopts_,}${option_#--}$flag_" + elif [[ "$option_" == -* ]]; then + opts_="$opts_${option_#-}$flag_" + fi + done + + return $shift_ +} +function __po_check_options() { + local -a getopt_args_ + getopt_args_=(-o "$opts_" ${longopts_:+-l "$longopts_"} -- "$@") + local args_ + if args_="$(getopt -q "${getopt_args_[@]}")"; then + recho "$args_" + return 0 + else + LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null + return 1 + fi +} +function __po_process_options() { + while [ -n "$1" ]; do + if [ "$1" == -- ]; then + shift + break + elif [[ "$1" == -* ]]; then + local i_ + let i_=0 + for option_ in "${options_[@]}"; do + [ "$1" == "${options_[$i_]}" ] && break + let i_=$i_+1 + done + name_="names_[$i_]"; name_="${!name_}" + flag_="flags_[$i_]"; flag_="${!flag_}" + function inc@ { eval "let $1=\$$1+1"; } + function res@ { set_var "$1" "${value_:-$2}"; } + function add@ { array_add "$1" "${value_:-$2}"; } + if [ -z "$name_" ]; then + ewarn "$1: option non reconnue, elle sera ignorée" + elif [[ "$flag_" == *\$ ]]; then + if [[ "$flag_" == :* ]]; then + value_="$2"; shift + function set@ { res@ "$@"; } + else + value_= + function set@ { inc@ "$@"; } + fi + eval "${name_#\$}" + elif [ "$flag_" == "" ]; then + if [[ "$name_" == *=* ]]; then + set_var "${name_%%=*}" "${name_#*=}" + else + inc@ "$name_" + fi + elif [ "$flag_" == ":" -o "$flag_" == "::" ]; then + value_="$2"; shift + if [ "${name_%=}" != "$name_" ]; then + set_var "${name_%=}" "$value_" + elif [[ "$name_" == *=* ]]; then + set_var "${name_%%=*}" "${name_#*=}" + else + array_add "$name_" "$value_" + fi + fi + else + break + fi + shift + done + unset -f inc@ res@ add@ set@ + [ -n "$destargs_" ] && + set_array "$destargs_" @ "$@" + return 0 +} +function parse_opts() { + + + + local -a options_ names_ flags_ destargs_ + local opts_ longopts_ + __po_parse_optdescs "$@" || shift $? + local args_ + if args_="$(__po_check_options "$@")"; then + eval "set -- $args_" + __po_process_options "$@" + else + [ -n "$destargs_" ] && set_var "$destargs_" "$args_" + return 1 + fi +} + +function parse_args_check() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" && return 0 + eerror "$args" + return 1 +} +function parse_args() { + parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" || die "$args" +} + +HELP_DESC= +HELP_USAGE= +HELP_OPTIONS= +function __genparse_shortopt() { + local LC_COLLATE=C + local shortopt="${1//[^A-Z]}" + shortopt="$(strlower "${shortopt:0:1}")" + [ -n "$shortopt" ] && echo "$shortopt" +} +function genparse() { + + local -a names descs vars options + local i desc var option name uname value shortopt + + for var in "$@"; do + if [[ "$var" == *=* ]]; then + splitvar "$var" name value + shortopt="$(__genparse_shortopt "$name")" + option="$(strlower "$name")" + name="${option//-/_}" + array_add names "$name" + array_add descs "${shortopt:+-$shortopt, }--$option VALUE" + array_add vars "$(set_var_cmd "$name" "$value")" + array_add options "${shortopt:+-$shortopt:,}--$option: $name=" + else + name="$var" + shortopt="$(__genparse_shortopt "$name")" + option="$(strlower "$name")" + name="${option//-/_}" + array_add names "$name" + array_add descs "${shortopt:+-$shortopt, }--$option" + array_add vars "$name=" + array_add options "${shortopt:+-$shortopt,}--$option $name=1" + fi + done + + echo -n 'function display_help() { + [ -n "$HELP_USAGE" ] || HELP_USAGE="USAGE + $scriptname' + [ -n "$descs" ] && echo -n ' [options]' + echo '"' + if [ -n "$descs" ]; then + echo -n ' [ -n "$HELP_OPTIONS" ] || HELP_OPTIONS="OPTIONS' + i=0 + while [ $i -lt ${#descs[*]} ]; do + name="${names[$i]}" + uname="$(strupper "$name")" + desc="${descs[$i]}" + echo -n " +\${HELP_${uname}_OPTION:- $desc\${HELP_${uname}_DESC:+ + \${HELP_${uname}_DESC// +/ + }}}" + i=$(($i + 1)) + done + echo '"' + fi + echo ' uecho "${HELP_DESC:+$HELP_DESC + +}$HELP_USAGE${HELP_OPTIONS:+ + +$HELP_OPTIONS}" +} +' + for var in "${vars[@]}"; do + echo "$var" + done + echo 'parse_opts "${PRETTYOPTS[@]}" \' + echo ' --help '\''$exit_with display_help'\'' \' + for option in "${options[@]}"; do + echo " $option \\" + done + echo ' @ args -- "$@" && set -- "${args[@]}" || die "$args"' +} +##@inc]base.args ##@inc[base.compat ## Fonctions de base: support des fonctions obsolètes et des versions de bash < 4.x +##@inc[base.core +## Fonctions de base: fondement +uprovide base.core + +function echo_() { + echo -n "$*" +} +function recho() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo "$first$@" + else + echo "$@" + fi +} +function recho_() { + if [[ "${1:0:2}" == -[eEn] ]]; then + echo -n - + local first="${1:1}"; shift + echo -n "$first$@" + else + echo -n "$@" + fi +} +function _qval() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//\$/\\\$}" + s="${s//\`/\\\`}" + recho_ "$s" +} +function should_quote() { + [ -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 qval() { + echo -n \" + _qval "$@" + echo \" +} +function qvalm() { + if should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvalr() { + if [ -z "$*" ]; then + : + elif should_quote "$*"; then + echo -n \" + _qval "$@" + echo \" + else + recho "$*" + fi +} +function qvals() { + 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 + [ -z "$first" ] && echo +} +function qlines() { + sed "s/'/'\\\\''/g; s/.*/'&'/g" +} +function setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + eval "$__s_var=\"$(_qval "$*")\"" +} +function _setv() { + local __s_var="$1"; shift + eval "$__s_var=\"$(_qval "$*")\"" +} +function echo_setv() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + echo "$__s_var=$(qvalr "$*")" +} +function setx() { + 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() { + local __s_var="$1"; shift + eval "$__s_var="'"$("$@")"' +} +function _setax() { + local __s_array="$1"; shift + eval "$__s_array=($("$@" | qlines))" +} +function evalx() { + 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 setxx() { + 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() { + 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 setxp() { + 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[@]}" evalp "$@" +} +function testx() { + local __t_op="$1"; shift + local __t_val="$(evalx "$@")" + [ $__t_op "$__t_val" ] +} +function test2x() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrx() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalx "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} +function testp() { + local __t_op="$1"; shift + local __t_val="$(evalp "$@")" + [ $__t_op "$__t_val" ] +} +function test2p() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + [ "$__t_val1" $__t_op "$__t_val2" ] +} +function testrp() { + local __t_val1="$1"; shift + local __t_op="$1"; shift + local __t_val2="$(evalp "$@")" + eval '[[ "$__t_val1" '"$__t_op"' "$__t_val2" ]]' +} + +function err2out() { + "$@" 2>&1 +} +##@inc]base.core +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +##@inc[base.bool +## Fonctions de base: valeurs booléennes +##@inc[base.num +## Fonctions de base: gestion des valeurs numériques +uprovide base.num + +function isnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function ispnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v//[0-9]/}" + [ -z "$v" ] +} +function isrnum() { + [ ${#1} -gt 0 ] || return 1 + local v="$1" + v="${v#-}" + v="${v//./}" + v="${v//,/}" + v="${v//[0-9]/}" + [ -z "$v" ] +} +##@inc]base.num +uprovide base.bool +urequire base.num + +function is_yes() { + 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() { + case "${1,,}" in + n|non|no|f|faux|false|off) return 0;; + esac + isnum "$1" && [ "$1" -eq 0 ] && return 0 + return 1 +} +function yesval() { + is_yes "$1" && echo 1 +} + +function setb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + local __s_r + if "$@" >/dev/null; then + eval "$__s_var=1" + else + __s_r=$? + eval "$__s_var=" + return $__s_r + fi +} +function _setb() { + local __s_var="$1"; shift + if "$@" >/dev/null; then + eval "$__s_var=1" + else + eval "$__s_var=" + fi +} + +function evalb() { + if evalx "$@" >/dev/null; then + echo 1 + else + return $? + fi +} +function setxb() { + local __s_var="$1"; shift + if [[ "$__s_var" == *=* ]]; then + set -- "${__s_var#*=}" "$@" + __s_var="${__s_var%%=*}" + fi + setx "$__s_var" evalb "$@" +} +##@inc]base.bool +##@inc[base.quote +## Fonctions de base: protection de valeurs chaine +uprovide base.quote +urequire base.core + +function _qawk() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s// +/\\n}" + recho_ "$s" +} +function qawk() { + echo -n \" + _qawk "$@" + echo \" +} +function qseds() { + local s="$*" + s="${s//\\/\\\\}" + s="${s//\//\\/}" + recho "$s" +} +function _qform() { + local s="$*" + s="${s//\%/%25}" + s="${s//+/%2B}" + s="${s//&/%26}" + s="${s//=/%3D}" + s="${s// /+}" + recho_ "$s" +} +function qform() { + local s="$*" + if [[ "$s" == *=* ]]; then + _qform "${s%%=*}" + echo -n = + _qform "${s#*=}" + echo + else + _qform "$s" + echo + fi +} +##@inc]base.quote uprovide base.compat +urequire base.core base.num base.bool base.quote +function setx2() { setxx "$@"; } function rawecho() { recho "$@"; } function rawecho_() { recho_ "$@"; } function quote_arg() { _qval "$@"; } @@ -605,6 +1916,7 @@ if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then done echo "${vs[*]}" } + function is_yes() { case "$1" in o|oui|y|yes|v|vrai|t|true|on) return 0;; @@ -630,7 +1942,7 @@ if [ -n "$BASH_VERSINFO" -a "${BASH_VERSINFO[0]}" -lt 4 ]; then fi ##@inc]base.compat uprovide base -urequire base.init base.core base.string base.quote base.split base.array base.compat +urequire base.init base.core base.string base.num base.bool base.array base.quote base.split base.args base.compat UNAME_SYSTEM=`uname -s` [ "${UNAME_SYSTEM#CYGWIN}" != "$UNAME_SYSTEM" ] && UNAME_SYSTEM=Cygwin @@ -1487,6 +2799,29 @@ function _nl2cr() { function nl2cr() { doinplace "$1" _nl2cr } +function _latin1compat() { + LANG=fr_FR.UTF-8 sed $' +s/[’]/\x27/g +s/[«»]/"/g +s/[\xC2\xA0\xE2\x80\x87\xE2\x80\xAF\xE2\x81\xA0]/ /g +' +} +function _noaccents() { + LANG=fr_FR.UTF-8 sed ' +s/[à]/a/g +s/[éèêë]/e/g +s/[ïî]/i/g +s/[ôö]/o/g +s/[üû]/u/g +s/[ç]/c/g +s/[À]/A/g +s/[ÉÈÊË]/E/g +s/[ÏÎ]/I/g +s/[ÔÖ]/O/g +s/[ÜÛ]/U/g +s/[Ç]/C/g +' +} function list_all() { local curdir="$(pwd)" local b="${1:-.}"; shift @@ -1919,6 +3254,13 @@ function array_newsize(dest, size, i) { dest[i] = "" } } +function array_len(values, count, i) { + count = 0 + for (i in values) { + count++ + } + return count +} function mkindices(values, indices, i, j) { array_new(indices) j = 1 @@ -1946,7 +3288,7 @@ function array_add(dest, value, lastindex) { function array_deli(dest, i, l) { i = int(i) if (i == 0) return - l = length(dest) + l = array_len(dest) while (i < l) { dest[i] = dest[i + 1] i++ @@ -2164,11 +3506,14 @@ function __array_parsecsv(fields, line, nbfields, colsep, qchar, echar, shou i = i + 1 } if (nbfields) { - while (length(fields) < nbfields) { - fields[length(fields) + 1] = "" + nbfields = int(nbfields) + i = array_len(fields) + while (i < nbfields) { + i++ + fields[i] = "" } } - return length(fields) + return array_len(fields) } BEGIN { DEFAULT_COLSEP = "," @@ -2237,7 +3582,7 @@ function printcsv(output, fields) { array_fill(fields) array_printcsv(fields, output) } -function array_findcsv(fields, input, field, value, nbfields, orig, found) { +function array_findcsv(fields, input, field, value, nbfields, orig, found, i) { array_new(orig) array_fill(orig) array_new(fields) @@ -2254,8 +3599,11 @@ function array_findcsv(fields, input, field, value, nbfields, orig, fou if (!found) { delete fields if (nbfields) { - while (length(fields) < nbfields) { - fields[length(fields) + 1] = "" + nbfields = int(nbfields) + i = array_len(fields) + while (i < nbfields) { + i++ + fields[i] = "" } } } @@ -2400,259 +3748,6 @@ function lawkrun() { } function cawkrun() { LANG=C lawkrun "$@"; } function awkrun() { LANG=C lawkrun "$@"; } -function parse_opts() { - - - - local -a options_ names_ flags_ destargs_ - local opts_ longopts_ - __po_parse_optdescs "$@" || shift $? - local args_ - if args_="$(__po_check_options "$@")"; then - eval "set -- $args_" - __po_process_options "$@" - else - [ -n "$destargs_" ] && set_var "$destargs_" "$args_" - return 1 - fi -} -function __po_parse_optdescs() { - local -a optdescs_ - local optdesc_ option_ name_ flag_ value_ - local shift_ - local i_ count_ - - let shift_=0 - while [ -n "$1" ]; do - if [ "$1" == -- ]; then - shift - let shift_=$shift_+1 - break - elif [ "$1" == "-" -o "$1" == "+" ]; then - if [ "${opts_#+}" != "$opts_" ]; then - opts_="${opts_#+}" - elif [ "${opts_#-}" != "$opts_" ]; then - opts_="${opts_#-}" - fi - opts_="$1$opts_" - shift - let shift_=$shift_+1 - elif [ "$1" == "@" ]; then - destargs_="$2" - shift; shift - let shift_=$shift_+2 - elif [[ "$1" == --* ]] || [[ "$1" == -* ]]; then - array_split optdescs_ "$1" "," - for optdesc_ in "${optdescs_[@]}"; do - if [[ "$2" == \$* ]]; then - name_="$2" - if [[ "$optdesc_" == *:: ]]; then - option_="${optdesc_%::}" - flag_='::$' - elif [[ "$optdesc_" == *: ]]; then - option_="${optdesc_%:}" - flag_=':$' - else - option_="$optdesc_" - flag_='$' - fi - elif [[ "$optdesc_" == *:: ]]; then - option_="${optdesc_%::}" - if [[ "$2" == *=* ]]; then - name_="${2%%=*}=" - else - name_="$2" - array_new "$name_" - fi - flag_=:: - elif [[ "$optdesc_" == *: ]]; then - option_="${optdesc_%:}" - if [[ "$2" == *=* ]]; then - name_="${2%%=*}=" - else - name_="$2" - array_new "$name_" - fi - flag_=: - else - option_="$optdesc_" - name_="$2" - flag_= - fi - - if i_="$(array_find options_ "$option_")"; then - options_=("${options_[@]:0:$i_}" "${options_[@]:$(($i_ + 1))}") - names_=("${names_[@]:0:$i_}" "${names_[@]:$(($i_ + 1))}") - flags_=("${flags_[@]:0:$i_}" "${flags_[@]:$(($i_ + 1))}") - fi - options_=("${options_[@]}" "$option_") - names_=("${names_[@]}" "$name_") - flags_=("${flags_[@]}" "$flag_") - done - shift; shift - let shift_=$shift_+2 - else - break - fi - done - - i_=0 - count_=${#options_[*]} - while [ $i_ -lt $count_ ]; do - option_="${options_[$i_]}" - flag_="${flags_[$i_]}" - i_=$(($i_ + 1)) - - flag_="${flag_%$}" - if [[ "$option_" == --* ]]; then - longopts_="${longopts_:+$longopts_,}${option_#--}$flag_" - elif [[ "$option_" == -* ]]; then - opts_="$opts_${option_#-}$flag_" - fi - done - - return $shift_ -} -function __po_check_options() { - local -a getopt_args_ - getopt_args_=(-o "$opts_" ${longopts_:+-l "$longopts_"} -- "$@") - local args_ - if args_="$(getopt -q "${getopt_args_[@]}")"; then - rawecho "$args_" - return 0 - else - LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null - return 1 - fi -} -function __po_process_options() { - while [ -n "$1" ]; do - if [ "$1" == -- ]; then - shift - break - elif [[ "$1" == -* ]]; then - local i_ - let i_=0 - for option_ in "${options_[@]}"; do - [ "$1" == "${options_[$i_]}" ] && break - let i_=$i_+1 - done - name_="names_[$i_]"; name_="${!name_}" - flag_="flags_[$i_]"; flag_="${!flag_}" - function inc@ { eval "let $1=\$$1+1"; } - function res@ { set_var "$1" "${value_:-$2}"; } - function add@ { array_add "$1" "${value_:-$2}"; } - if [ -z "$name_" ]; then - ewarn "$1: option non reconnue, elle sera ignorée" - elif [[ "$flag_" == *\$ ]]; then - if [[ "$flag_" == :* ]]; then - value_="$2"; shift - function set@ { res@ "$@"; } - else - value_= - function set@ { inc@ "$@"; } - fi - eval "${name_#\$}" - elif [ "$flag_" == "" ]; then - if [[ "$name_" == *=* ]]; then - set_var "${name_%%=*}" "${name_#*=}" - else - inc@ "$name_" - fi - elif [ "$flag_" == ":" -o "$flag_" == "::" ]; then - value_="$2"; shift - if [ "${name_%=}" != "$name_" ]; then - set_var "${name_%=}" "$value_" - elif [[ "$name_" == *=* ]]; then - set_var "${name_%%=*}" "${name_#*=}" - else - array_add "$name_" "$value_" - fi - fi - else - break - fi - shift - done - unset -f inc@ res@ add@ set@ - [ -n "$destargs_" ] && - set_array "$destargs_" @ "$@" - return 0 -} -function __genparse_shortopt() { - local LC_COLLATE=C - local shortopt="${1//[^A-Z]}" - shortopt="$(tolower "${shortopt:0:1}")" - [ -n "$shortopt" ] && echo "$shortopt" -} -HELP_DESC= -HELP_USAGE= -HELP_OPTIONS= -function genparse() { - - local -a names descs vars options - local i desc var option name uname value shortopt - - for var in "$@"; do - if [[ "$var" == *=* ]]; then - splitvar "$var" name value - shortopt="$(__genparse_shortopt "$name")" - option="$(tolower "$name")" - name="${option//-/_}" - array_add names "$name" - array_add descs "${shortopt:+-$shortopt, }--$option VALUE" - array_add vars "$(set_var_cmd "$name" "$value")" - array_add options "${shortopt:+-$shortopt:,}--$option: $name=" - else - name="$var" - shortopt="$(__genparse_shortopt "$name")" - option="$(tolower "$name")" - name="${option//-/_}" - array_add names "$name" - array_add descs "${shortopt:+-$shortopt, }--$option" - array_add vars "$name=" - array_add options "${shortopt:+-$shortopt,}--$option $name=1" - fi - done - - echo -n 'function display_help() { - [ -n "$HELP_USAGE" ] || HELP_USAGE="USAGE - $scriptname' - [ -n "$descs" ] && echo -n ' [options]' - echo '"' - if [ -n "$descs" ]; then - echo -n ' [ -n "$HELP_OPTIONS" ] || HELP_OPTIONS="OPTIONS' - i=0 - while [ $i -lt ${#descs[*]} ]; do - name="${names[$i]}" - uname="$(strupper "$name")" - desc="${descs[$i]}" - echo -n " -\${HELP_${uname}_OPTION:- $desc\${HELP_${uname}_DESC:+ - \${HELP_${uname}_DESC// -/ - }}}" - i=$(($i + 1)) - done - echo '"' - fi - echo ' uecho "${HELP_DESC:+$HELP_DESC - -}$HELP_USAGE${HELP_OPTIONS:+ - -$HELP_OPTIONS}" -} -' - for var in "${vars[@]}"; do - echo "$var" - done - echo 'parse_opts "${PRETTYOPTS[@]}" \' - echo ' --help '\''$exit_with display_help'\'' \' - for option in "${options[@]}"; do - echo " $option \\" - done - echo ' @ args -- "$@" && set -- "${args[@]}" || die "$args"' -} function __lf_get_age() { local y=$(date "+%Y")