From: Matthias Kruk Date: Thu, 11 Aug 2022 17:09:07 +0000 (+0900) Subject: include/opt: Use associative array to track missing options X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=613b5b606bf8b35b064f66bd40f0ebe7079621ac;p=toolbox include/opt: Use associative array to track missing options The opt module does not track missing options, but instead checks on demand if required options are missing by inspecting all options' flags and value. This approach is needlessly complicated and slow. This commit changes the opt module to track required options using an associative array, allowing the check for missing options to be performed in constant time. --- diff --git a/include/opt.sh b/include/opt.sh index bc844a6..2fce9c5 100644 --- a/include/opt.sh +++ b/include/opt.sh @@ -38,6 +38,7 @@ __init() { declare -Axg __opt_regex declare -Axg __opt_action declare -Axg __opt_map + declare -Axg __opt_required opt_add_arg "h" "help" "" 0 \ "Print this text" \ @@ -125,6 +126,10 @@ opt_add_arg() { __opt_default["$long"]="$default" fi + if (( parsed_flags & __opt_flag_required )); then + __opt_required["$long"]="$long" + fi + return 0 } @@ -156,10 +161,23 @@ opt_print_help() { return 2 } +_opt_have_required() { + local option + local -i err + + err=0 + + for option in "${!__opt_required[@]}"; do + log_error "Missing required option: --$option" + err=1 + done + + return "$err" +} + opt_parse() { local argv=("$@") - local optname local err local i @@ -187,6 +205,10 @@ opt_parse() { action="${__opt_action[$long]}" regex="${__opt_regex[$long]}" + if [[ -n "${__opt_required[$long]}" ]]; then + unset __opt_required["$long"] + fi + if (( flags & __opt_flag_has_value )); then ((i++)) @@ -220,20 +242,9 @@ opt_parse() { fi done - for optname in "${__opt_long[@]}"; do - local flags - - flags="${__opt_flags[$optname]}" - - if ! (( flags & __opt_flag_required )); then - continue - fi - - if ! array_contains "$optname" "${!__opt_value[@]}"; then - log_error "Missing required argument: $optname" - err=1 - fi - done + if ! _opt_have_required; then + return 1 + fi return "$err" }