Last active
January 10, 2021 10:31
-
-
Save ambakshi/445e9dd661ffde8c3724bbd976a882f2 to your computer and use it in GitHub Desktop.
parse-opts.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# MIT Licensensed | |
# Amit Bakshi Jan 2021 | |
# Generic option parser. | |
# Usage: | |
# parse_opts --valid-args 'foo bar link' -- --with-foo=yes --bar=fizz --no-link | |
# | |
# Yields: | |
# O_foo=true | |
# O_bar=fizz | |
# O_link=false | |
# | |
# TODO: Add help generation, maybe from a heredoc that can also serve to | |
# provide the valid options. | |
# | |
parse_opts() { | |
local valid_args="debug verbose quiet" | |
while [ $# -gt 0 ]; do | |
local cmd="$1" | |
shift | |
case "$cmd" in | |
--) break;; | |
--valid-args=*) valid_args+=' '"${cmd#--valid-args=}";; | |
--valid-args) valid_args+=" $1"; shift;; | |
*) echo >&2 "Invalid option for this section"; return 144;; | |
esac | |
done | |
while [ $# -gt 0 ]; do | |
local cmd key value prefix | |
cmd="${1#--}" | |
if [ -n "$cmd" ] && [[ "$cmd" =~ ^([a-zA-Z][a-zA-Z0-9_-]*) ]]; then | |
cmd="${cmd#--}" | |
if [[ "$cmd" =~ ^(without|disable|enable|with) ]]; then | |
prefix=${BASH_REMATCH[1]} | |
cmd="${cmd#$prefix}" | |
cmd="${cmd#-}" | |
fi | |
key="${cmd%%=*}" | |
value="${cmd#$key=}" | |
sep="${cmd%$value}" | |
sep="${sep#$key}" | |
if [ -z "$sep" ]; then | |
value=true | |
elif [ "$sep" = '=' ]; then | |
value="${cmd#$key=}" | |
else | |
echo >&2 "ERROR: Invalid argument. Should be --foo=bar: $1" | |
return 1 | |
fi | |
if [[ "$prefix" =~ ^(without|disable)$ ]]; then | |
if [[ "$value" =~ ^(false|disabled|no|0)$ ]]; then | |
value=true | |
elif [[ "$value" =~ ^(true|enabled|on|1)$ ]]; then | |
value=false | |
fi | |
elif [[ "$prefix" =~ ^(with|enable)$ ]]; then | |
if [[ "$value" =~ ^(false|disabled|no|0)$ ]]; then | |
value=false | |
elif [[ "$value" =~ ^(true|enabled|on|1)$ ]]; then | |
value=true | |
fi | |
elif [ -z "$prefix" ]; then | |
value="${value:-true}" | |
else | |
echo >&2 "ERROR: Invalid option $1" | |
return 1 | |
fi | |
key="${key//-/_}" | |
if [[ "$valid_args" =~ $key ]]; then | |
eval "O_${key}=$value" | |
else | |
echo >&2 "Invalid option: $key" | |
return 145 | |
fi | |
else | |
shift | |
echo "$@" | |
return $# | |
fi | |
shift | |
done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment