From: Matthias Kruk Date: Thu, 11 Aug 2022 16:54:00 +0000 (+0900) Subject: include/opt: Use an associative array to simplify flag parsing X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=c5e2758931d222fb20b552fb2a0d71fe83e8bbc9;p=toolbox include/opt: Use an associative array to simplify flag parsing When parsing the flags of an option, the opt module uses a case construct, which looks clumsy, isn't very easy to read, and makes adding new flags more complicated than need be. This commit modifies the opt module to use an associative array to simplify flag parsing. This way, the parser only has to use a flag as index into the array in order to find out its internal value. --- diff --git a/include/opt.sh b/include/opt.sh index 0cddf5e..bc844a6 100644 --- a/include/opt.sh +++ b/include/opt.sh @@ -24,6 +24,11 @@ __init() { declare -xgir __opt_flag_required=1 declare -xgir __opt_flag_has_value=2 + declare -xgAr __opt_flags_map=( + ["r"]="$__opt_flag_required" + ["v"]="$__opt_flag_has_value" + ) + declare -Axg __opt_short declare -Axg __opt_long declare -Axg __opt_desc @@ -66,6 +71,31 @@ _opt_is_defined() { return 1 } +_opt_parse_flags() { + local flags="$1" + + local -i parsed_flags + local -i i + + for (( i = 0, parsed_flags = 0; i < ${#flags}; i++ )); do + local flag_name + local flag_value + + flag_name="${flags:$i:1}" + flag_value="${__opt_flags_map[$flag_name]}" + + if (( flag_value == 0 )); then + log_error "Invalid flag: $flag_name" + return 1 + fi + + (( parsed_flags |= flag_value )) + done + + echo "$parsed_flags" + return 0 +} + opt_add_arg() { local short="$1" local long="$2" @@ -75,36 +105,16 @@ opt_add_arg() { local regex="$6" local action="$7" - local num_flags - local bflags - local i + local -i parsed_flags - if _opt_is_defined "-$short" "--$long"; then + if _opt_is_defined "-$short" "--$long" || + ! parsed_flags=$(_opt_parse_flags "$flags"); then return 1 fi - num_flags="${#flags}" - bflags=0 - - for (( i = 0; i < num_flags; i++ )); do - case "${flags:$i:1}" in - "r") - ((bflags |= __opt_flag_required)) - ;; - - "v") - ((bflags |= __opt_flag_has_value)) - ;; - - *) - return 1 - ;; - esac - done - __opt_short["$long"]="$short" __opt_long["$short"]="$long" - __opt_flags["$long"]="$bflags" + __opt_flags["$long"]="$parsed_flags" __opt_desc["$long"]="$desc" __opt_regex["$long"]="$regex" __opt_action["$long"]="$action"