From 613b5b606bf8b35b064f66bd40f0ebe7079621ac Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Fri, 12 Aug 2022 02:09:07 +0900 Subject: [PATCH] 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. --- include/opt.sh | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) 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" } -- 2.47.3