From 3def66748bb0425490582ea725f543bc17ad47d9 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sat, 16 Dec 2023 16:12:53 +0400 Subject: [PATCH] support --opt et --no-opt automatique --- bash/src/base.args.sh | 42 ++++++++++++++++++++++++------------ bash/src/tests.sh | 6 ++++++ bash/tests/test-args-base.sh | 8 +++++++ bash/tests/test-args-help.sh | 4 +++- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/bash/src/base.args.sh b/bash/src/base.args.sh index bd3d8ec..ac44e3c 100644 --- a/bash/src/base.args.sh +++ b/bash/src/base.args.sh @@ -30,10 +30,10 @@ parse_args "$@"; set -- "${args[@]}" au retour de la fonction, args contient les arguments qui n'ont pas été traités automatiquement. -les options --help et --help-all sont automatiquement gérées. avec --help, -seules les options standards sont affichées. --help-all affiche toutes les -options. les descriptions sont utilisées pour l'affichage de l'aide. une option -avancée est identifiée par une description qui commence par ++ +les options --help et --help++ sont automatiquement gérées. avec --help, seules +les options standards sont affichées. --help++ affiche toutes les options. les +descriptions sont utilisées pour l'affichage de l'aide. une option avancée est +identifiée par une description qui commence par ++ desc : description de l'objet du script ou de la fonction. cette valeur est @@ -84,6 +84,13 @@ action -o,--short,--very-long . -o,--short,--very-long very_long ~~~ + De plus, la valeur spéciale '.' traite les options de la forme --no-opt + comme l'inverse des option --opt. par exemple, les deux définitions + suivantes sont équivalentes: + ~~~ + --opt . --no-opt . + --opt opt --no-opt '$dec@ opt' + ~~~ * 'NAME=VALUE' pour une option sans argument, forcer la valeur spécifiée; pour une option avec argument, prendre la valeur spécifiée comme valeur par défaut si la valeur de l'option est vide @@ -174,7 +181,7 @@ function __parse_args() { __def="${__def#-}" __lopts="$__lopts${__lopts:+,}$__def$__witharg" fi - [ "$__def" == help -o "$__def" == help-all ] && __autohelp= + [ "$__def" == help -o "$__def" == help++ ] && __autohelp= done # sauter l'action shift @@ -184,7 +191,7 @@ function __parse_args() { # __sopts ne doit pas être vide, rajouter ? si aucune option courte n'est # définie, indépendamment de la valeur de autohelp - [ -n "$__autohelp" ] && __lopts="$__lopts${__lopts:+,}help,help-all" + [ -n "$__autohelp" ] && __lopts="$__lopts${__lopts:+,}help,help++" [ -n "$__sopts" ] || __sopts=? __sopts="$__popt$__sopts" @@ -201,14 +208,14 @@ function __parse_args() { fi ## puis traiter les options - local __defname __fixvalue __defvalue __add __action option_ name_ value_ + local __defname __resvalue __decvalue __defvalue __add __action option_ name_ value_ function inc@() { eval "[ -n \"\$$1\" ] || let $1=0" eval "let $1=$1+1" } function dec@() { eval "[ -n \"\$$1\" ] && let $1=$1-1" - eval "[ $1 -eq 0 ] && $1=" + eval "[ \"\$$1\" == 0 ] && $1=" } function res@() { local __value="${value_:-$2}" @@ -219,7 +226,7 @@ function __parse_args() { eval "$1+=(\"\$__value\")" } function set@() { - if [ -n "$__fixvalue" ]; then + if [ -n "$__resvalue" ]; then res@ "$@" elif [ -n "$__witharg" ]; then if is_array "$1"; then @@ -232,6 +239,8 @@ function __parse_args() { [ -z "${!1}" ] && eval "$1=()" add@ "$@" fi + elif [ -n "$__decvalue" ]; then + dec@ "$@" else inc@ "$@" fi @@ -393,23 +402,28 @@ function __parse_opt() { done __defname="${__defname//-/_}" # analyser l'action + __decvalue= if [ "${1#\$}" != "$1" ]; then name_="$__defname" - __fixvalue= + __resvalue= __defvalue= __action="${1#\$}" else if [ "$1" == . ]; then name_="$__defname" - __fixvalue= + __resvalue= __defvalue= + if [ "${name_#no_}" != "$name_" ]; then + name_="${name_#no_}" + __decvalue=1 + fi elif [[ "$1" == *=* ]]; then name_="${1%%=*}" - __fixvalue=1 + __resvalue=1 __defvalue="${1#*=}" else name_="$1" - __fixvalue= + __resvalue= __defvalue= fi __action="$(qvals set@ "$name_" "$__defvalue")" @@ -424,7 +438,7 @@ function __parse_opt() { if [ "$option_" == --help -o "$option" == -? ]; then __action="showhelp@" return 0 - elif [ "$option_" == --help-all ]; then + elif [ "$option_" == --help++ ]; then __action="showhelp@ ++" return 0 fi diff --git a/bash/src/tests.sh b/bash/src/tests.sh index 629abed..86f4dfd 100644 --- a/bash/src/tests.sh +++ b/bash/src/tests.sh @@ -85,36 +85,42 @@ function assert_eq() { local message; tests__set_message "$@" || shift $? [ -n "$message" ] || message="$3" [ -n "$message" ] || message="'$1' and '$2' are not equals" + tests__assert "'$1' must be a number" ok isnum "$1" tests__assert "$message" ok [ "$1" -eq "$2" ] } function assert_ne() { local message; tests__set_message "$@" || shift $? [ -n "$message" ] || message="$3" [ -n "$message" ] || message="'$1' and '$2' are equals" + tests__assert "'$1' must be a number" ok isnum "$1" tests__assert "$message" ok [ "$1" -ne "$2" ] } function assert_gt() { local message; tests__set_message "$@" || shift $? [ -n "$message" ] || message="$3" [ -n "$message" ] || message="'$1' is not greater than '$2'" + tests__assert "'$1' must be a number" ok isnum "$1" tests__assert "$message" ok [ "$1" -gt "$2" ] } function assert_ge() { local message; tests__set_message "$@" || shift $? [ -n "$message" ] || message="$3" [ -n "$message" ] || message="'$1' is not greater than or equals to '$2'" + tests__assert "'$1' must be a number" ok isnum "$1" tests__assert "$message" ok [ "$1" -ge "$2" ] } function assert_lt() { local message; tests__set_message "$@" || shift $? [ -n "$message" ] || message="$3" [ -n "$message" ] || message="'$1' is not less than '$2'" + tests__assert "'$1' must be a number" ok isnum "$1" tests__assert "$message" ok [ "$1" -lt "$2" ] } function assert_le() { local message; tests__set_message "$@" || shift $? [ -n "$message" ] || message="$3" [ -n "$message" ] || message="'$1' is not less than or equals to '$2'" + tests__assert "'$1' must be a number" ok isnum "$1" tests__assert "$message" ok [ "$1" -le "$2" ] } diff --git a/bash/tests/test-args-base.sh b/bash/tests/test-args-base.sh index 0b77517..b6b45da 100755 --- a/bash/tests/test-args-base.sh +++ b/bash/tests/test-args-base.sh @@ -29,6 +29,7 @@ function pa() { -b::,--oopt oopt= "spécifier oopt" -B::,--doopt doopt=default "spécifier doopt" -n,--autoinc . "incrémenter autoinc" + -N,--no-autoinc . "décrémenter autoinc" -v:,--autoval . "spécifier autoval" -x: a1 "autoadd a1 qui n'est pas défini" -y: a2 "autoadd a2 qui est défini à ()" @@ -127,6 +128,13 @@ assert_eq "$autoinc" 2 pa -nnn assert_eq "$autoinc" 3 +pa -nN +assert_z "$autoinc" +pa -nnN +assert_eq "$autoinc" 1 +pa -nnnNN +assert_eq "$autoinc" 1 + pa -v "" assert_is_array autoval assert_array_same autoval "" diff --git a/bash/tests/test-args-help.sh b/bash/tests/test-args-help.sh index d8f41b9..646c392 100755 --- a/bash/tests/test-args-help.sh +++ b/bash/tests/test-args-help.sh @@ -13,4 +13,6 @@ nb: l'aide pour cette option doit faire 3 lignes indentées" ) parse_args "$@"; set -- "${args[@]}" -enote "lancer le script avec --help pour afficher l'aide" +enote "lancer le script +- avec --help pour afficher les options standards uniquement +- avec --help++ pour afficher toutes les options"