From 6fd117bed73d65e8e8eb6148371f8f4499ca050d Mon Sep 17 00:00:00 2001 From: Will Allan Date: Wed, 23 Aug 2023 09:17:15 -0700 Subject: [PATCH 1/7] Clear instead of unset OPTARG for valid long option without argument This PR clears OPTARG (as opposed to `unset OPTARG`) for a valid long option without a required argument (e.g. `--charlie`). I believe this matches the behavior of builtin `getopts` for valid short options without an argument. --- lib/getopts_long.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/getopts_long.bash b/lib/getopts_long.bash index ef4616a..0471c39 100644 --- a/lib/getopts_long.bash +++ b/lib/getopts_long.bash @@ -40,7 +40,7 @@ getopts_long() { fi fi elif [[ "${optspec_long}" =~ (^|[[:space:]])${!optvar}([[:space:]]|$) ]]; then - unset OPTARG + OPTARG= else # Invalid option if [[ "${optspec_short:0:1}" == ':' ]]; then From ccf4381891c32efc36dc6bb216a3a2cb8edeb0d3 Mon Sep 17 00:00:00 2001 From: Will Allan Date: Thu, 24 Aug 2023 10:42:48 -0700 Subject: [PATCH 2/7] Fix argument logic --- lib/getopts_long.bash | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/getopts_long.bash b/lib/getopts_long.bash index ef4616a..12c6da6 100644 --- a/lib/getopts_long.bash +++ b/lib/getopts_long.bash @@ -9,10 +9,10 @@ getopts_long() { shift 2 if [[ "${#}" == 0 ]]; then - local args=() - while [[ ${#BASH_ARGV[@]} -gt ${#args[@]} ]]; do - local index=$(( ${#BASH_ARGV[@]} - ${#args[@]} - 1 )) - args[${#args[@]}]="${BASH_ARGV[${index}]}" + local -i index + local -a args=() + for (( i = BASH_ARGC[0] + BASH_ARGC[1] - 1; i >= BASH_ARGC[0]; i-- )); do + args+=("${BASH_ARGV[i]}") done set -- "${args[@]}" fi From d3d705e1156220a4cb0e2a74d36058d1a25a6495 Mon Sep 17 00:00:00 2001 From: Will Allan Date: Thu, 24 Aug 2023 10:44:09 -0700 Subject: [PATCH 3/7] Fix typo --- lib/getopts_long.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/getopts_long.bash b/lib/getopts_long.bash index 12c6da6..82bb05f 100644 --- a/lib/getopts_long.bash +++ b/lib/getopts_long.bash @@ -9,7 +9,7 @@ getopts_long() { shift 2 if [[ "${#}" == 0 ]]; then - local -i index + local -i i local -a args=() for (( i = BASH_ARGC[0] + BASH_ARGC[1] - 1; i >= BASH_ARGC[0]; i-- )); do args+=("${BASH_ARGV[i]}") From 866feaf8320f9b17f56d29f084a3db5184279463 Mon Sep 17 00:00:00 2001 From: Will Allan Date: Mon, 28 Aug 2023 08:53:28 -0700 Subject: [PATCH 4/7] Redeclare OPTARG instead of clear --- lib/getopts_long.bash | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/getopts_long.bash b/lib/getopts_long.bash index 0471c39..7637440 100644 --- a/lib/getopts_long.bash +++ b/lib/getopts_long.bash @@ -40,7 +40,8 @@ getopts_long() { fi fi elif [[ "${optspec_long}" =~ (^|[[:space:]])${!optvar}([[:space:]]|$) ]]; then - OPTARG= + unset OPTARG + declare -g OPTARG else # Invalid option if [[ "${optspec_short:0:1}" == ':' ]]; then From eba2297faae6b97bef3c2afa60e798b4715fba00 Mon Sep 17 00:00:00 2001 From: Will Allan Date: Mon, 28 Aug 2023 09:07:58 -0700 Subject: [PATCH 5/7] Check if !OPTIND is unbound --- lib/getopts_long.bash | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/getopts_long.bash b/lib/getopts_long.bash index 4fb3dd5..d7fd084 100644 --- a/lib/getopts_long.bash +++ b/lib/getopts_long.bash @@ -28,10 +28,9 @@ getopts_long() { # Missing argument if [[ -z "${OPTARG}" ]]; then - OPTARG="${!OPTIND}" && OPTIND=$(( OPTIND + 1 )) - [[ -z "${OPTARG}" ]] || return 0 - - if [[ "${optspec_short:0:1}" == ':' ]]; then + if [[ -n "${!OPTIND:-}" ]]; then + OPTARG="${!OPTIND}" && OPTIND=$(( OPTIND + 1 )) + elif [[ "${optspec_short:0:1}" == ':' ]]; then OPTARG="${!optvar}" && printf -v "${optvar}" ':' else [[ "${OPTERR}" == 0 ]] || \ From a00aec38069befc99dccd52e1519717f97b4d7bd Mon Sep 17 00:00:00 2001 From: Will Allan Date: Mon, 28 Aug 2023 09:30:26 -0700 Subject: [PATCH 6/7] Undo recent commits --- lib/getopts_long.bash | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/getopts_long.bash b/lib/getopts_long.bash index d7fd084..ef4616a 100644 --- a/lib/getopts_long.bash +++ b/lib/getopts_long.bash @@ -9,10 +9,10 @@ getopts_long() { shift 2 if [[ "${#}" == 0 ]]; then - local -i i - local -a args=() - for (( i = BASH_ARGC[0] + BASH_ARGC[1] - 1; i >= BASH_ARGC[0]; i-- )); do - args+=("${BASH_ARGV[i]}") + local args=() + while [[ ${#BASH_ARGV[@]} -gt ${#args[@]} ]]; do + local index=$(( ${#BASH_ARGV[@]} - ${#args[@]} - 1 )) + args[${#args[@]}]="${BASH_ARGV[${index}]}" done set -- "${args[@]}" fi @@ -28,9 +28,10 @@ getopts_long() { # Missing argument if [[ -z "${OPTARG}" ]]; then - if [[ -n "${!OPTIND:-}" ]]; then - OPTARG="${!OPTIND}" && OPTIND=$(( OPTIND + 1 )) - elif [[ "${optspec_short:0:1}" == ':' ]]; then + OPTARG="${!OPTIND}" && OPTIND=$(( OPTIND + 1 )) + [[ -z "${OPTARG}" ]] || return 0 + + if [[ "${optspec_short:0:1}" == ':' ]]; then OPTARG="${!optvar}" && printf -v "${optvar}" ':' else [[ "${OPTERR}" == 0 ]] || \ @@ -40,7 +41,6 @@ getopts_long() { fi elif [[ "${optspec_long}" =~ (^|[[:space:]])${!optvar}([[:space:]]|$) ]]; then unset OPTARG - declare -g OPTARG else # Invalid option if [[ "${optspec_short:0:1}" == ':' ]]; then From 4c5e2d156890bfae8a86e9cf02bcf88a6dcb47c2 Mon Sep 17 00:00:00 2001 From: Will Allan Date: Mon, 28 Aug 2023 09:33:28 -0700 Subject: [PATCH 7/7] Check if !OPTIND is unbound --- lib/getopts_long.bash | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/getopts_long.bash b/lib/getopts_long.bash index ef4616a..d20ba59 100644 --- a/lib/getopts_long.bash +++ b/lib/getopts_long.bash @@ -28,10 +28,9 @@ getopts_long() { # Missing argument if [[ -z "${OPTARG}" ]]; then - OPTARG="${!OPTIND}" && OPTIND=$(( OPTIND + 1 )) - [[ -z "${OPTARG}" ]] || return 0 - - if [[ "${optspec_short:0:1}" == ':' ]]; then + if [[ -n "${!OPTIND:-}" ]]; then + OPTARG="${!OPTIND}" && OPTIND=$(( OPTIND + 1 )) + elif [[ "${optspec_short:0:1}" == ':' ]]; then OPTARG="${!optvar}" && printf -v "${optvar}" ':' else [[ "${OPTERR}" == 0 ]] || \