initial commit
This commit is contained in:
+218
@@ -0,0 +1,218 @@
|
||||
std::mod::init clap 0.1.0
|
||||
|
||||
##
|
||||
# must be called after declaring a `clap__flags` as associative arrays, where:
|
||||
#
|
||||
# Short flags or long flags (e.g. `-h`, `-v`, `--help`) are the keys (with their dashes).
|
||||
#
|
||||
# If the flag expects a value it must have assigned "value", if its a flat flag
|
||||
# "bool", otherwise UB.
|
||||
#
|
||||
# Returns the data in -A clap__options (with values or `1` for boolean flags)
|
||||
# and -a clap_arguments
|
||||
##
|
||||
clap::parse() {
|
||||
declare -gA clap__options=()
|
||||
declare -ga clap__arguments=()
|
||||
|
||||
local flag_i
|
||||
local short_flag
|
||||
local flag_type
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
flag_i="$1"
|
||||
shift
|
||||
|
||||
if [[ "$flag_i" == "--" ]]; then
|
||||
while [ "$#" -gt 0 ]; do
|
||||
clap__arguments+=("$1")
|
||||
shift
|
||||
done
|
||||
elif [[ "$flag_i" == --* ]]; then
|
||||
flag_type="${clap__flags[$flag_i]:-}"
|
||||
std::assert "unrecognized flag: '$flag_i'" -n "$flag_type" || return 1
|
||||
case "$flag_type" in
|
||||
bool)
|
||||
clap__options[$flag_i]=1
|
||||
;;
|
||||
value)
|
||||
clap__options[$flag_i]=${1?"Expected a value for '$flag_i'"}
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
std::panic "invalid flag type '$flag_type' for '$flag_i'"
|
||||
;;
|
||||
esac
|
||||
elif [[ "$flag_i" == -* ]]; then
|
||||
flag_i=${flag_i/-/}
|
||||
# do-while
|
||||
while
|
||||
short_flag=-${flag_i:0:1}
|
||||
flag_i=${flag_i:1}
|
||||
|
||||
flag_type="${clap__flags[$short_flag]:-}"
|
||||
case "$flag_type" in
|
||||
bool)
|
||||
clap__options[$short_flag]=1
|
||||
;;
|
||||
value)
|
||||
if [ -n "$flag_i" ]; then
|
||||
clap__options[$short_flag]=$flag_i
|
||||
flag_i=
|
||||
else
|
||||
clap__options[$short_flag]=${1?"Expected a value for '$flag_i'"}
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
std::panic "invalid flag type '$flag_type' for '$short_flag'"
|
||||
;;
|
||||
esac
|
||||
|
||||
# condition
|
||||
[ -n "$flag_i" ]
|
||||
do true; done
|
||||
else
|
||||
clap__arguments+=("$flag_i")
|
||||
fi
|
||||
done
|
||||
|
||||
export clap__options clap__arguments
|
||||
}
|
||||
|
||||
clap::flag::is-short() {
|
||||
[ "${1:0:1}" == "-" ] && [ "${1:1:1}" != "-" ]
|
||||
}
|
||||
|
||||
clap::flag::is-long() {
|
||||
[ "${1:0:1}" == "-" ] && [ "${1:1:1}" == "-" ]
|
||||
}
|
||||
|
||||
##
|
||||
# $1 = description
|
||||
# $2.. = usage, separated by spaces, HL depends on each word's format
|
||||
#
|
||||
# -a $clap__help_commands ("subcommand Description goes then.")
|
||||
# -a $clap__help_options ("-s", "--long", "-b --both"; and "-s Short.", "--long Long.", "-b --both And both.")
|
||||
#
|
||||
# $CLAP_HL_SECTION = section ansi
|
||||
# $CLAP_HL_WORD = words ansi
|
||||
# $CLAP_HL_OPTION = ansi for optionals
|
||||
##
|
||||
clap::pretty-help() {
|
||||
local ar= # ansi reset
|
||||
if [ -n "${CLAP_HL_SECTION:=}" ] || [ -n "${CLAP_HL_WORD:=}" ] || [ -n "${CLAP_HL_OPTION:=}" ]; then
|
||||
ar=$'\033[0m'
|
||||
fi
|
||||
|
||||
echo "$1"
|
||||
shift
|
||||
|
||||
local typch
|
||||
echo
|
||||
printf "%s" "${CLAP_HL_SECTION}Usage:${ar}"
|
||||
for word in "$0" "$@"; do
|
||||
typch=${word:0:1}
|
||||
if [[ "$typch" == "<" ]] || [[ "$typch" == "[" ]]; then
|
||||
printf "%s" " ${CLAP_HL_OPTION}$word${ar}"
|
||||
else
|
||||
printf "%s" " ${CLAP_HL_WORD}$word${ar}"
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
||||
if [ -n "${clap__help_commands[*]}" ]; then
|
||||
echo
|
||||
echo "${CLAP_HL_SECTION}Commands:${ar}"
|
||||
|
||||
local name max_command=0
|
||||
for command in "${clap__help_commands[@]}"; do
|
||||
name=${command%% *}
|
||||
|
||||
if [ "${#name}" -gt "$max_command" ]; then
|
||||
max_command=${#name}
|
||||
fi
|
||||
done
|
||||
|
||||
local description command_padding
|
||||
for command in "${clap__help_commands[@]}"; do
|
||||
name=${command%% *}
|
||||
description=${command:$((${#name} + 1))}
|
||||
|
||||
command_padding=$((max_command - ${#name}))
|
||||
printf "%s" " ${CLAP_HL_WORD}$name${ar}"
|
||||
if [ -n "$description" ]; then
|
||||
printf "%s" "$(printf "%0.s " $(seq 1 $((command_padding + 2))))$description"
|
||||
fi
|
||||
echo
|
||||
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -n "${clap__help_options[*]}" ]; then
|
||||
echo
|
||||
echo "${CLAP_HL_SECTION}Options:${ar}"
|
||||
|
||||
local any_short=0 max_long=0
|
||||
|
||||
local flagbuf
|
||||
for flags in "${clap__help_options[@]}"; do
|
||||
flagbuf=${flags%% *} # maybe a short
|
||||
|
||||
if clap::flag::is-short "$flagbuf"; then
|
||||
any_short=1 && break
|
||||
fi
|
||||
done
|
||||
|
||||
for flags in "${clap__help_options[@]}"; do
|
||||
flagbuf=${flags%% *} # maybe a short
|
||||
|
||||
if clap::flag::is-short "$flagbuf"; then
|
||||
flags=${flags:$((${#flagbuf} + 1))}
|
||||
fi
|
||||
|
||||
flagbuf=${flags%% *} # maybe a long or desc
|
||||
if clap::flag::is-long "$flagbuf" && [ "${#flagbuf}" -gt "$max_long" ]; then
|
||||
max_long=${#flagbuf}
|
||||
fi
|
||||
done
|
||||
|
||||
local has_to_comma
|
||||
|
||||
for flags in "${clap__help_options[@]}"; do
|
||||
has_to_comma=0
|
||||
|
||||
flagbuf=${flags%% *} # maybe a short
|
||||
printf " "
|
||||
if clap::flag::is-short "$flagbuf"; then
|
||||
flags=${flags:$((${#flagbuf} + 1))}
|
||||
printf "%s" "${CLAP_HL_WORD}$flagbuf${ar}"
|
||||
has_to_comma=1
|
||||
flagbuf=${flags%% *}
|
||||
elif [ "$any_short" -eq 1 ]; then
|
||||
printf " "
|
||||
fi
|
||||
|
||||
# `flagbuf` maybe a long or desc
|
||||
|
||||
if [ "$max_long" -eq 0 ]; then
|
||||
# description 100%
|
||||
if [ -n "$flags" ]; then
|
||||
printf "%s" " $flags"
|
||||
fi
|
||||
elif clap::flag::is-long "$flagbuf"; then
|
||||
flags=${flags:$((${#flagbuf} + 1))}
|
||||
[ "$has_to_comma" -eq 0 ] || printf ", "
|
||||
printf "%s" "${CLAP_HL_WORD}$flagbuf${ar}"
|
||||
|
||||
# description 100%
|
||||
if [ -n "$flags" ]; then
|
||||
printf "%s" "$(printf "%0.s " $(seq 1 $((max_long - ${#flagbuf} + 2))))"
|
||||
printf "%s" "$flags"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
done
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user