parent
b79ceb313b
commit
c0d66c7722
|
@ -12,6 +12,5 @@ USAGE
|
||||||
OPTIONS"
|
OPTIONS"
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_opts "${PRETTYOPTS[@]}" \
|
args=(--help '$exit_with display_help')
|
||||||
--help '$exit_with display_help' \
|
parse_args "$@"; set -- "${args[@]}"
|
||||||
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ OPTIONS
|
||||||
Pour un script exécutable, indiquer le type de script à générer:
|
Pour un script exécutable, indiquer le type de script à générer:
|
||||||
system-or-local, sl -- utilise ulib/auto et genparse()
|
system-or-local, sl -- utilise ulib/auto et genparse()
|
||||||
default, d -- utilise /etc/ulibauto et genparse()
|
default, d -- utilise /etc/ulibauto et genparse()
|
||||||
manual, m -- utilise /etc/ulib et parse_opts()
|
manual, m -- utilise /etc/ulib et parse_args()
|
||||||
vanilla, v -- script simple
|
vanilla, v -- script simple
|
||||||
auto -- choisir system-or-local, default ou manual en fonction de
|
auto -- choisir system-or-local, default ou manual en fonction de
|
||||||
la présence de [lib/]ulib et/ou de /etc/ulibauto
|
la présence de [lib/]ulib et/ou de /etc/ulibauto
|
||||||
|
@ -92,6 +92,7 @@ function __fixtypes() {
|
||||||
esac
|
esac
|
||||||
case "$stype" in
|
case "$stype" in
|
||||||
manual|m) stype=manual;;
|
manual|m) stype=manual;;
|
||||||
|
legacy|l) stype=legacy;;
|
||||||
""|auto|a) stype=auto;;
|
""|auto|a) stype=auto;;
|
||||||
*)
|
*)
|
||||||
ewarn "$stype: sous-type non reconnu. sélection de la valeur 'auto'"
|
ewarn "$stype: sous-type non reconnu. sélection de la valeur 'auto'"
|
||||||
|
@ -150,7 +151,7 @@ Voulez-vous générer un script avec cette configuration?" X &&
|
||||||
par défaut sont utilisés: urequire DEFAULTS et genparse() pour l'analyse des
|
par défaut sont utilisés: urequire DEFAULTS et genparse() pour l'analyse des
|
||||||
arguments.
|
arguments.
|
||||||
- Avec le type 'manual', le fichier /etc/ulib est chargé. Les paramètres par
|
- Avec le type 'manual', le fichier /etc/ulib est chargé. Les paramètres par
|
||||||
défaut sont utilisés manuellement: urequire DEFAULTS et parse_opts() pour
|
défaut sont utilisés manuellement: urequire DEFAULTS et parse_args() pour
|
||||||
l'analyse des arguments.
|
l'analyse des arguments.
|
||||||
- Avec le type 'vanilla', un script simple est généré."
|
- Avec le type 'vanilla', un script simple est généré."
|
||||||
local -a types
|
local -a types
|
||||||
|
@ -216,6 +217,21 @@ USAGE
|
||||||
OPTIONS"
|
OPTIONS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args=(--help '\''$exit_with display_help'\'')
|
||||||
|
parse_args "$@"; set -- "${args[@]}"
|
||||||
|
'
|
||||||
|
;;
|
||||||
|
legacy)
|
||||||
|
echo >>"$file" '
|
||||||
|
function display_help() {
|
||||||
|
uecho "$scriptname:
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
$scriptname [options]
|
||||||
|
|
||||||
|
OPTIONS"
|
||||||
|
}
|
||||||
|
|
||||||
parse_opts "${PRETTYOPTS[@]}" \
|
parse_opts "${PRETTYOPTS[@]}" \
|
||||||
--help '\''$exit_with display_help'\'' \
|
--help '\''$exit_with display_help'\'' \
|
||||||
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
007000000
|
007001000
|
||||||
|
|
423
lib/ulib/base
423
lib/ulib/base
|
@ -37,9 +37,10 @@ fi
|
||||||
##@include base.array
|
##@include base.array
|
||||||
##@include base.quote
|
##@include base.quote
|
||||||
##@include base.split
|
##@include base.split
|
||||||
|
##@include base.args
|
||||||
##@include base.compat
|
##@include base.compat
|
||||||
uprovide base
|
uprovide base
|
||||||
urequire base.init base.core base.string base.num base.bool base.array base.quote base.split base.compat
|
urequire base.init base.core base.string base.num base.bool base.array base.quote base.split base.args base.compat
|
||||||
|
|
||||||
## Informations sur l'hôte sur lequel tourne ce script
|
## Informations sur l'hôte sur lequel tourne ce script
|
||||||
# Type de système
|
# Type de système
|
||||||
|
@ -2305,426 +2306,6 @@ function lawkrun() {
|
||||||
}
|
}
|
||||||
function cawkrun() { LANG=C lawkrun "$@"; }
|
function cawkrun() { LANG=C lawkrun "$@"; }
|
||||||
function awkrun() { LANG=C lawkrun "$@"; }
|
function awkrun() { LANG=C lawkrun "$@"; }
|
||||||
function parse_opts() {
|
|
||||||
# Analyser des arguments. Cette fonction doit être appelée avec une description
|
|
||||||
# des options à analyser, suivie des arguments proprement dits. En fonction des
|
|
||||||
# options rencontrées, certaines variables sont mises à jour.
|
|
||||||
# Les arguments de cette fonction sont donc de la forme 'optdescs -- args'
|
|
||||||
|
|
||||||
# optdescs est une suite d'arguments d'une des formes suivantes: 'opt,opt... var',
|
|
||||||
# 'opt,opt... $cmd', '@ var', '+', '-', '%'
|
|
||||||
# - Dans la forme 'opt var[=value]', opt est une description d'option, var un
|
|
||||||
# nom de variable à mettre à jour, et value une valeur éventuelle pour les
|
|
||||||
# options sans argument. Si plusieurs options sont mentionnées, séparées par des
|
|
||||||
# virgules, alors tous les options partagent les mêmes paramètres.
|
|
||||||
# opt peut être de la forme '-o' ou '--longopt' pour des options sans
|
|
||||||
# arguments. Dans ce cas, var obtient le nombre de fois que l'option est
|
|
||||||
# mentionnée ('' pour aucune mention, '1' pour une seule mention, etc.), sauf si
|
|
||||||
# on utilise la forme var=value, auquel cas la variable obtient la valeur value,
|
|
||||||
# et le nombre d'occurences de l'option n'est pas compté.
|
|
||||||
# Pour faciliter la lecture:
|
|
||||||
# '--opt .' est équivalent à '--opt opt'
|
|
||||||
# '--opt: .' est équivalent à '--opt: opt='
|
|
||||||
# Avec la forme '-o:' ou '--longopt:', l'option prend un argument obligatoire.
|
|
||||||
# Avec la forme '-o::' ou '--longopt::', l'option prend un argument facultatif
|
|
||||||
# (dans ce cas, la valeur de l'option sur la ligne de commande doit
|
|
||||||
# obligatoirement être collée à l'option.)
|
|
||||||
# Si ces options sont mentionnées plusieurs fois sur la ligne de commande, alors
|
|
||||||
# la variable de destination est un tableau qui contient toutes les valeurs.
|
|
||||||
# Le traitement de la valeur d'une variable dépend de la forme utilisée.
|
|
||||||
# - Avec une option sans argument, le comportement est celui décrit ci-dessus.
|
|
||||||
# - Avec une option qui prend des arguments, la forme '-o: var' considère que
|
|
||||||
# var est un tableau qui contiendra toutes les valeurs mentionnées dans les
|
|
||||||
# options. Avec la forme '-o: var=', la variable n'est pas un tableau et
|
|
||||||
# contient toujours la dernière valeur spécifiée.
|
|
||||||
# - Dans la forme 'opt $cmd', la commande cmd est executée avec eval *dès* que
|
|
||||||
# l'option est rencontrée. La variable option_ contient l'option, e.g. '-o' ou
|
|
||||||
# '--longopt'. Le cas échéant, la variable value_ contient la valeur de
|
|
||||||
# l'option. La fonction 'set@ NAME' met à jour la variable NAME, soit en lui
|
|
||||||
# donnant la valeur $value_, soit en l'incrémentant, suivant le type d'option.
|
|
||||||
# La fonction 'inc@ NAME' incrémente la variable NAME, 'res@ NAME [VALUE]'
|
|
||||||
# initialise la variable à la valeur VALUE, 'add@ NAME [VALUE]' met à jour le
|
|
||||||
# tableau NAME, en lui ajoutant la valeur VALUE. Par défaut, VALUE vaut $value_
|
|
||||||
# - Dans la forme '@ var', var est un nom de tableau qui est initialisé avec le
|
|
||||||
# reste des arguments.
|
|
||||||
# - Avec les caractères '-' ou '+', l'on influe sur la méthode d'analyse. Par
|
|
||||||
# défaut, les options sont valides n'importe ou sur la ligne de commande. Avec
|
|
||||||
# '+', l'analyse s'arrête au premier argument qui n'est pas une option. Avec
|
|
||||||
# '-', les options sont valides n'importe ou sur la ligne de commande, mais les
|
|
||||||
# arguments ne sont pas réordonnés, et apparaissent dans l'ordre de leur
|
|
||||||
# mention.
|
|
||||||
# - Toutes les variables mentionnées après le caractère '%' sont
|
|
||||||
# initialisées. Elle sont garanties d'être vides
|
|
||||||
# Si opt est définie plusieurs fois, la dernière définition est celle qui est
|
|
||||||
# retenue, e.g. dans l'exemple suivant, l'option -o prend une valeur et met à
|
|
||||||
# jour la variable second:
|
|
||||||
# parse_opts -o,--longo first=1 -o: second= ....
|
|
||||||
|
|
||||||
# Si une erreur se produit pendant l'analyse, retourner 1. Si '@ var' est
|
|
||||||
# spécifié, insérer le texte de l'erreur comme unique élément du tableau var.
|
|
||||||
# Une suggestion d'utilisation est donc celle-ci:
|
|
||||||
# parse_opts ... @ args -- "$@" && set -- "${args[@]}" || die "$args"
|
|
||||||
|
|
||||||
# D'abord, parser et normaliser les options
|
|
||||||
# options_ contient la liste des options (-o --longo...)
|
|
||||||
# names_ contient la liste des variables qu'il faut mettre à jour (name name...)
|
|
||||||
# flags_ contient la liste des flags pour les options: '' pour une option
|
|
||||||
# simple, ':' pour option avec argument obligatoire, '::' pour option avec
|
|
||||||
# argument facultatif
|
|
||||||
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() {
|
|
||||||
# Parser et normaliser la description des options valides. A l'issue de
|
|
||||||
# l'appel de cette méthode, 3 tableaux sont initialisés, dont chaque
|
|
||||||
# position correspond à une option:
|
|
||||||
# - options_ contient la liste des options valides e.g. (-o --longo...)
|
|
||||||
# - names_ contient la liste des variables qu'il faut mettre à jour pour ces
|
|
||||||
# options e.g. (name name...)
|
|
||||||
# - flags_ contient la liste des flags pour les options: '' pour une option
|
|
||||||
# simple, ':' pour option avec argument obligatoire, '::' pour option avec
|
|
||||||
# argument facultatif, '$' pour une commande à lancer au lieu d'une variable
|
|
||||||
# à mettre à jour.
|
|
||||||
# De plus, les variables suivantes sont initialisées:
|
|
||||||
# - destargs_ obtient la variable qui doit être initialisée avec le reste
|
|
||||||
# des arguments.
|
|
||||||
# - opts_ et longopts_ sont les arguments à utiliser pour la commande getopt
|
|
||||||
# du package util-linux
|
|
||||||
# Retourner le nombre d'arguments à shifter
|
|
||||||
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
|
|
||||||
# annuler les précédentes options + ou -
|
|
||||||
if [ "${opts_#+}" != "$opts_" ]; then
|
|
||||||
opts_="${opts_#+}"
|
|
||||||
elif [ "${opts_#-}" != "$opts_" ]; then
|
|
||||||
opts_="${opts_#-}"
|
|
||||||
fi
|
|
||||||
# puis rajouter l'option
|
|
||||||
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
|
|
||||||
# la valeur mentionnée est toujours ignorée
|
|
||||||
name_="${2%%=*}="
|
|
||||||
[ -n "$reset_" ] && eval "$name_="
|
|
||||||
else
|
|
||||||
name_="$2"
|
|
||||||
[ -n "$reset_" ] && array_new "$name_"
|
|
||||||
fi
|
|
||||||
flag_=::
|
|
||||||
elif [[ "$optdesc_" == *: ]]; then
|
|
||||||
option_="${optdesc_%:}"
|
|
||||||
if [[ "$2" == *=* ]]; then
|
|
||||||
# la valeur mentionnée est toujours ignorée
|
|
||||||
name_="${2%%=*}="
|
|
||||||
[ -n "$reset_" ] && eval "$name_="
|
|
||||||
else
|
|
||||||
name_="$2"
|
|
||||||
[ -n "$reset_" ] && array_new "$name_"
|
|
||||||
fi
|
|
||||||
flag_=:
|
|
||||||
else
|
|
||||||
option_="$optdesc_"
|
|
||||||
name_="$2"
|
|
||||||
[ -n "$reset_" ] && eval "$name_="
|
|
||||||
flag_=
|
|
||||||
fi
|
|
||||||
|
|
||||||
if i_="$(array_find options_ "$option_")"; then
|
|
||||||
# supprimer l'ancienne occurence
|
|
||||||
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))
|
|
||||||
|
|
||||||
# pour construire longopts_ et opts_, enlever $ de flag
|
|
||||||
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() {
|
|
||||||
# vérifier la validité des options mentionnées dans les arguments
|
|
||||||
# Si les options sont valides, retourner 0 et afficher la chaine des
|
|
||||||
# arguments traitées.
|
|
||||||
# Sinon, retourner 1 et initialiaser la variable $destargs_ avec le message
|
|
||||||
# d'erreur.
|
|
||||||
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
|
|
||||||
# relancer la commande pour avoir le message d'erreur
|
|
||||||
LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
function __po_process_options() {
|
|
||||||
# Traiter les 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
|
|
||||||
# option non reconnue. ce cas aurait dû être traité par
|
|
||||||
# __po_check_options.
|
|
||||||
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="$(strlower "${shortopt:0:1}")"
|
|
||||||
[ -n "$shortopt" ] && echo "$shortopt"
|
|
||||||
}
|
|
||||||
HELP_DESC=
|
|
||||||
HELP_USAGE=
|
|
||||||
HELP_OPTIONS=
|
|
||||||
function genparse() {
|
|
||||||
# Afficher une ligne de commande à évaluer pour simplifier l'utilisation de
|
|
||||||
# parse_opts(). Une fonction display_help() par défaut est définie et les
|
|
||||||
# options appropriées de parse_opts sont utilisées pour reconnaître les options
|
|
||||||
# spécifiées par les arguments.
|
|
||||||
# Cette fonction peut être utilisée de cette manière:
|
|
||||||
# HELP_DESC=...
|
|
||||||
# HELP_ARG_DESC=... # pour chaque arg
|
|
||||||
# eval "$(genparse [args...])"
|
|
||||||
# D'autres variables peuvent être définies: HELP_USAGE, HELP_OPTIONS,
|
|
||||||
# HELP_ARG_OPTION. Consulter le source pour connaitre leur utilisation
|
|
||||||
# Les arguments de cette fonction sont de la forme 'sansarg' pour une option
|
|
||||||
# simple qui ne prend pas d'argument ou 'avecarg=[default-value]' pour une
|
|
||||||
# option qui prend un argument. Les options générées sont des options
|
|
||||||
# longues. En l'occurence, les options générées sont respectivement '--sansarg'
|
|
||||||
# et '--avecarg:'
|
|
||||||
# Les variables et les options sont toujours en minuscule. Pour les variables,
|
|
||||||
# le caractère '-' est remplacé par '_'. Si une option contient une lettre en
|
|
||||||
# majuscule, l'option courte correspondante à cette lettre sera aussi reconnue.
|
|
||||||
# Par exemple, la commande suivante:
|
|
||||||
# genparse Force enCoding=utf-8 input= long-Option=
|
|
||||||
# affichera ceci:
|
|
||||||
# function display_help() {
|
|
||||||
# [ -n "$HELP_USAGE" ] || HELP_USAGE="USAGE
|
|
||||||
# $scriptname [options]"
|
|
||||||
# [ -n "$HELP_OPTIONS" ] || HELP_OPTIONS="OPTIONS
|
|
||||||
# ${HELP_FORCE_OPTION:- -f, --force${HELP_FORCE_DESC:+
|
|
||||||
# $HELP_FORCE_DESC}}
|
|
||||||
# ${HELP_ENCODING_OPTION:- -c, --encoding VALUE${HELP_ENCODING_DESC:+
|
|
||||||
# ${HELP_ENCODING_DESC}}}
|
|
||||||
# ${HELP_INPUT_OPTION:- --input VALUE${HELP_INPUT_DESC:+
|
|
||||||
# ${HELP_INPUT_DESC}}}
|
|
||||||
# ${HELP_LONG_OPTION_OPTION:- -o, --long-option VALUE${HELP_LONG_OPTION_DESC:+
|
|
||||||
# ${HELP_LONG_OPTION_DESC}}}"
|
|
||||||
# uecho "${HELP_DESC:+$HELP_DESC
|
|
||||||
#
|
|
||||||
# }$HELP_USAGE${HELP_OPTIONS:+
|
|
||||||
#
|
|
||||||
# $HELP_OPTIONS}"
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# force=
|
|
||||||
# encoding=utf-8
|
|
||||||
# input=""
|
|
||||||
# long_option=""
|
|
||||||
# parse_opts "${PRETTYOPTS[@]}" \
|
|
||||||
# --help '$exit_with display_help' \
|
|
||||||
# -f,--force force=1 \
|
|
||||||
# -c:,--encoding: encoding= \
|
|
||||||
# --input: input= \
|
|
||||||
# -o:,--long-option: long_option= \
|
|
||||||
# @ args -- "$@" && set -- "${args[@]}" || die "$args"
|
|
||||||
|
|
||||||
local -a names descs vars options
|
|
||||||
local i desc var option name uname value shortopt
|
|
||||||
|
|
||||||
# analyser les arguments
|
|
||||||
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
|
|
||||||
|
|
||||||
# afficher la commande parse_opts
|
|
||||||
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() {
|
function __lf_get_age() {
|
||||||
local y=$(date "+%Y")
|
local y=$(date "+%Y")
|
||||||
|
|
|
@ -0,0 +1,449 @@
|
||||||
|
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||||
|
## Analyse des arguments de la ligne de commande
|
||||||
|
##@cooked nocomments
|
||||||
|
##@include base.core
|
||||||
|
##@include base.string
|
||||||
|
##@include base.array
|
||||||
|
uprovide base.args
|
||||||
|
urequire base.core base.string base.array #XXX maj de cette liste
|
||||||
|
|
||||||
|
function __po_parse_optdescs() {
|
||||||
|
# Parser et normaliser la description des options valides. A l'issue de
|
||||||
|
# l'appel de cette méthode, 3 tableaux sont initialisés, dont chaque
|
||||||
|
# position correspond à une option:
|
||||||
|
# - options_ contient la liste des options valides e.g. (-o --longo...)
|
||||||
|
# - names_ contient la liste des variables qu'il faut mettre à jour pour ces
|
||||||
|
# options e.g. (name name...)
|
||||||
|
# - flags_ contient la liste des flags pour les options: '' pour une option
|
||||||
|
# simple, ':' pour option avec argument obligatoire, '::' pour option avec
|
||||||
|
# argument facultatif, '$' pour une commande à lancer au lieu d'une variable
|
||||||
|
# à mettre à jour.
|
||||||
|
# De plus, les variables suivantes sont initialisées:
|
||||||
|
# - destargs_ obtient la variable qui doit être initialisée avec le reste
|
||||||
|
# des arguments.
|
||||||
|
# - opts_ et longopts_ sont les arguments à utiliser pour la commande getopt
|
||||||
|
# du package util-linux
|
||||||
|
# Retourner le nombre d'arguments à shifter
|
||||||
|
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
|
||||||
|
# annuler les précédentes options + ou -
|
||||||
|
if [ "${opts_#+}" != "$opts_" ]; then
|
||||||
|
opts_="${opts_#+}"
|
||||||
|
elif [ "${opts_#-}" != "$opts_" ]; then
|
||||||
|
opts_="${opts_#-}"
|
||||||
|
fi
|
||||||
|
# puis rajouter l'option
|
||||||
|
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
|
||||||
|
# la valeur mentionnée est toujours ignorée
|
||||||
|
name_="${2%%=*}="
|
||||||
|
[ -n "$reset_" ] && eval "$name_="
|
||||||
|
else
|
||||||
|
name_="$2"
|
||||||
|
[ -n "$reset_" ] && eval "$name_=()"
|
||||||
|
fi
|
||||||
|
flag_=::
|
||||||
|
elif [[ "$optdesc_" == *: ]]; then
|
||||||
|
option_="${optdesc_%:}"
|
||||||
|
if [[ "$2" == *=* ]]; then
|
||||||
|
# la valeur mentionnée est toujours ignorée
|
||||||
|
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
|
||||||
|
# supprimer l'ancienne occurence
|
||||||
|
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))
|
||||||
|
|
||||||
|
# pour construire longopts_ et opts_, enlever $ de flag
|
||||||
|
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() {
|
||||||
|
# vérifier la validité des options mentionnées dans les arguments
|
||||||
|
# Si les options sont valides, retourner 0 et afficher la chaine des
|
||||||
|
# arguments traitées.
|
||||||
|
# Sinon, retourner 1 et initialiaser la variable $destargs_ avec le message
|
||||||
|
# d'erreur.
|
||||||
|
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
|
||||||
|
# relancer la commande pour avoir le message d'erreur
|
||||||
|
LANG=C getopt "${getopt_args_[@]}" 2>&1 1>/dev/null
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function __po_process_options() {
|
||||||
|
# Traiter les 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
|
||||||
|
# option non reconnue. ce cas aurait dû être traité par
|
||||||
|
# __po_check_options.
|
||||||
|
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() {
|
||||||
|
# Analyser des arguments. Cette fonction doit être appelée avec une description
|
||||||
|
# des options à analyser, suivie des arguments proprement dits. En fonction des
|
||||||
|
# options rencontrées, certaines variables sont mises à jour.
|
||||||
|
# Les arguments de cette fonction sont donc de la forme 'optdescs -- args'
|
||||||
|
|
||||||
|
# optdescs est une suite d'arguments d'une des formes suivantes: 'opt,opt... var',
|
||||||
|
# 'opt,opt... $cmd', '@ var', '+', '-', '%'
|
||||||
|
# - Dans la forme 'opt var[=value]', opt est une description d'option, var un
|
||||||
|
# nom de variable à mettre à jour, et value une valeur éventuelle pour les
|
||||||
|
# options sans argument. Si plusieurs options sont mentionnées, séparées par des
|
||||||
|
# virgules, alors tous les options partagent les mêmes paramètres.
|
||||||
|
# opt peut être de la forme '-o' ou '--longopt' pour des options sans
|
||||||
|
# arguments. Dans ce cas, var obtient le nombre de fois que l'option est
|
||||||
|
# mentionnée ('' pour aucune mention, '1' pour une seule mention, etc.), sauf si
|
||||||
|
# on utilise la forme var=value, auquel cas la variable obtient la valeur value,
|
||||||
|
# et le nombre d'occurences de l'option n'est pas compté.
|
||||||
|
# Pour faciliter la lecture:
|
||||||
|
# '--opt .' est équivalent à '--opt opt'
|
||||||
|
# '--opt: .' est équivalent à '--opt: opt='
|
||||||
|
# Avec la forme '-o:' ou '--longopt:', l'option prend un argument obligatoire.
|
||||||
|
# Avec la forme '-o::' ou '--longopt::', l'option prend un argument facultatif
|
||||||
|
# (dans ce cas, la valeur de l'option sur la ligne de commande doit
|
||||||
|
# obligatoirement être collée à l'option.)
|
||||||
|
# Si ces options sont mentionnées plusieurs fois sur la ligne de commande, alors
|
||||||
|
# la variable de destination est un tableau qui contient toutes les valeurs.
|
||||||
|
# Le traitement de la valeur d'une variable dépend de la forme utilisée.
|
||||||
|
# - Avec une option sans argument, le comportement est celui décrit ci-dessus.
|
||||||
|
# - Avec une option qui prend des arguments, la forme '-o: var' considère que
|
||||||
|
# var est un tableau qui contiendra toutes les valeurs mentionnées dans les
|
||||||
|
# options. Avec la forme '-o: var=', la variable n'est pas un tableau et
|
||||||
|
# contient toujours la dernière valeur spécifiée.
|
||||||
|
# - Dans la forme 'opt $cmd', la commande cmd est executée avec eval *dès* que
|
||||||
|
# l'option est rencontrée. La variable option_ contient l'option, e.g. '-o' ou
|
||||||
|
# '--longopt'. Le cas échéant, la variable value_ contient la valeur de
|
||||||
|
# l'option. La fonction 'set@ NAME' met à jour la variable NAME, soit en lui
|
||||||
|
# donnant la valeur $value_, soit en l'incrémentant, suivant le type d'option.
|
||||||
|
# La fonction 'inc@ NAME' incrémente la variable NAME, 'res@ NAME [VALUE]'
|
||||||
|
# initialise la variable à la valeur VALUE, 'add@ NAME [VALUE]' met à jour le
|
||||||
|
# tableau NAME, en lui ajoutant la valeur VALUE. Par défaut, VALUE vaut $value_
|
||||||
|
# - Dans la forme '@ var', var est un nom de tableau qui est initialisé avec le
|
||||||
|
# reste des arguments.
|
||||||
|
# - Avec les caractères '-' ou '+', l'on influe sur la méthode d'analyse. Par
|
||||||
|
# défaut, les options sont valides n'importe ou sur la ligne de commande. Avec
|
||||||
|
# '+', l'analyse s'arrête au premier argument qui n'est pas une option. Avec
|
||||||
|
# '-', les options sont valides n'importe ou sur la ligne de commande, mais les
|
||||||
|
# arguments ne sont pas réordonnés, et apparaissent dans l'ordre de leur
|
||||||
|
# mention.
|
||||||
|
# - Toutes les variables mentionnées après le caractère '%' sont
|
||||||
|
# initialisées. Elle sont garanties d'être vides
|
||||||
|
# Si opt est définie plusieurs fois, la dernière définition est celle qui est
|
||||||
|
# retenue, e.g. dans l'exemple suivant, l'option -o prend une valeur et met à
|
||||||
|
# jour la variable second:
|
||||||
|
# parse_opts -o,--longo first=1 -o: second= ....
|
||||||
|
|
||||||
|
# Si une erreur se produit pendant l'analyse, retourner 1. Si '@ var' est
|
||||||
|
# spécifié, insérer le texte de l'erreur comme unique élément du tableau var.
|
||||||
|
# Une suggestion d'utilisation est donc celle-ci:
|
||||||
|
# parse_opts ... @ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||||||
|
|
||||||
|
# D'abord, parser et normaliser les options
|
||||||
|
# options_ contient la liste des options (-o --longo...)
|
||||||
|
# names_ contient la liste des variables qu'il faut mettre à jour (name name...)
|
||||||
|
# flags_ contient la liste des flags pour les options: '' pour une option
|
||||||
|
# simple, ':' pour option avec argument obligatoire, '::' pour option avec
|
||||||
|
# argument facultatif
|
||||||
|
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() {
|
||||||
|
# Simplifier l'utilisation de parse_opts(). En entrée, le tableau args doit être
|
||||||
|
# initialisé avec la liste des options. En sortie, ce tableau contient la liste
|
||||||
|
# des arguments restant sur la ligne de commande. En cas d'erreur, retourner 1.
|
||||||
|
# Exemple d'utilisation:
|
||||||
|
# args=(-c:,--config: .)
|
||||||
|
# parse_args_check "$@" || return
|
||||||
|
parse_opts "${PRETTYOPTS[@]}" "${args[@]}" @ args -- "$@" && return 0
|
||||||
|
eerror "$args"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
function parse_args() {
|
||||||
|
# Simplifier l'utilisation de parse_opts(). En entrée, le tableau args doit être
|
||||||
|
# initialisé avec la liste des options. En sortie, ce tableau contient la liste
|
||||||
|
# des arguments restant sur la ligne de commande. En cas d'erreur, quitter le
|
||||||
|
# script avec die()
|
||||||
|
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() {
|
||||||
|
# Afficher une ligne de commande à évaluer pour simplifier l'utilisation de
|
||||||
|
# parse_opts(). Une fonction display_help() par défaut est définie et les
|
||||||
|
# options appropriées de parse_opts sont utilisées pour reconnaître les options
|
||||||
|
# spécifiées par les arguments.
|
||||||
|
# Cette fonction peut être utilisée de cette manière:
|
||||||
|
# HELP_DESC=...
|
||||||
|
# HELP_ARG_DESC=... # pour chaque arg
|
||||||
|
# eval "$(genparse [args...])"
|
||||||
|
# D'autres variables peuvent être définies: HELP_USAGE, HELP_OPTIONS,
|
||||||
|
# HELP_ARG_OPTION. Consulter le source pour connaitre leur utilisation
|
||||||
|
# Les arguments de cette fonction sont de la forme 'sansarg' pour une option
|
||||||
|
# simple qui ne prend pas d'argument ou 'avecarg=[default-value]' pour une
|
||||||
|
# option qui prend un argument. Les options générées sont des options
|
||||||
|
# longues. En l'occurence, les options générées sont respectivement '--sansarg'
|
||||||
|
# et '--avecarg:'
|
||||||
|
# Les variables et les options sont toujours en minuscule. Pour les variables,
|
||||||
|
# le caractère '-' est remplacé par '_'. Si une option contient une lettre en
|
||||||
|
# majuscule, l'option courte correspondante à cette lettre sera aussi reconnue.
|
||||||
|
# Par exemple, la commande suivante:
|
||||||
|
# genparse Force enCoding=utf-8 input= long-Option=
|
||||||
|
# affichera ceci:
|
||||||
|
# function display_help() {
|
||||||
|
# [ -n "$HELP_USAGE" ] || HELP_USAGE="USAGE
|
||||||
|
# $scriptname [options]"
|
||||||
|
# [ -n "$HELP_OPTIONS" ] || HELP_OPTIONS="OPTIONS
|
||||||
|
# ${HELP_FORCE_OPTION:- -f, --force${HELP_FORCE_DESC:+
|
||||||
|
# $HELP_FORCE_DESC}}
|
||||||
|
# ${HELP_ENCODING_OPTION:- -c, --encoding VALUE${HELP_ENCODING_DESC:+
|
||||||
|
# ${HELP_ENCODING_DESC}}}
|
||||||
|
# ${HELP_INPUT_OPTION:- --input VALUE${HELP_INPUT_DESC:+
|
||||||
|
# ${HELP_INPUT_DESC}}}
|
||||||
|
# ${HELP_LONG_OPTION_OPTION:- -o, --long-option VALUE${HELP_LONG_OPTION_DESC:+
|
||||||
|
# ${HELP_LONG_OPTION_DESC}}}"
|
||||||
|
# uecho "${HELP_DESC:+$HELP_DESC
|
||||||
|
#
|
||||||
|
# }$HELP_USAGE${HELP_OPTIONS:+
|
||||||
|
#
|
||||||
|
# $HELP_OPTIONS}"
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# force=
|
||||||
|
# encoding=utf-8
|
||||||
|
# input=""
|
||||||
|
# long_option=""
|
||||||
|
# parse_opts "${PRETTYOPTS[@]}" \
|
||||||
|
# --help '$exit_with display_help' \
|
||||||
|
# -f,--force force=1 \
|
||||||
|
# -c:,--encoding: encoding= \
|
||||||
|
# --input: input= \
|
||||||
|
# -o:,--long-option: long_option= \
|
||||||
|
# @ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||||||
|
|
||||||
|
local -a names descs vars options
|
||||||
|
local i desc var option name uname value shortopt
|
||||||
|
|
||||||
|
# analyser les arguments
|
||||||
|
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
|
||||||
|
|
||||||
|
# afficher la commande parse_opts
|
||||||
|
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"'
|
||||||
|
}
|
Loading…
Reference in New Issue