Convert tabs to spaces

The script used mixed indentation, meaning that it only made sense to
read when the tab width was set properly (to 8). Using consistent
indentation makes the script easier to read.
This commit is contained in:
Zane Duffield
2026-01-14 11:13:36 +11:00
parent cdc010720f
commit 8862ba1999

384
cmdarg.sh
View File

@@ -33,14 +33,14 @@ function cmdarg
local shortopt=${1:0:1} local shortopt=${1:0:1}
local key="$2" local key="$2"
if [[ "$shortopt" == "h" ]]; then if [[ "$shortopt" == "h" ]]; then
echo "-h is reserved for cmdarg usage" >&2 echo "-h is reserved for cmdarg usage" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
if [[ "$(type -t cmdarg_$key)" != "" ]] || \ if [[ "$(type -t cmdarg_$key)" != "" ]] || \
[[ "${CMDARG_FLAGS[$shortopt]}" != "" ]] || \ [[ "${CMDARG_FLAGS[$shortopt]}" != "" ]] || \
[[ "${CMDARG_TYPES[$key]}" != "" ]]; then [[ "${CMDARG_TYPES[$key]}" != "" ]]; then
echo "command line key '$shortopt ($key)' is reserved by cmdarg or defined twice" >&2 echo "command line key '$shortopt ($key)' is reserved by cmdarg or defined twice" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
declare -A argtypemap declare -A argtypemap
@@ -48,31 +48,31 @@ function cmdarg
argtypemap['?']=$CMDARG_FLAG_OPTARG argtypemap['?']=$CMDARG_FLAG_OPTARG
local argtype=${1:1:1} local argtype=${1:1:1}
if [[ "$argtype" =~ ^[\[{]$ ]]; then if [[ "$argtype" =~ ^[\[{]$ ]]; then
echo "Flags required [:?] when specifying Hash or Array arguments (${argtype})" >&2 echo "Flags required [:?] when specifying Hash or Array arguments (${argtype})" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
elif [[ "$argtype" != "" ]]; then elif [[ "$argtype" != "" ]]; then
CMDARG_FLAGS[$shortopt]=${argtypemap["$argtype"]} CMDARG_FLAGS[$shortopt]=${argtypemap["$argtype"]}
if [[ "${1:2:4}" == "[]" ]]; then if [[ "${1:2:4}" == "[]" ]]; then
declare -p ${key} >/dev/null 2>&1 declare -p ${key} >/dev/null 2>&1
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo 'Array variable '"${key}"' does not exist. Array variables MUST be declared by the user!' >&2 echo 'Array variable '"${key}"' does not exist. Array variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
CMDARG_TYPES[$key]=$CMDARG_TYPE_ARRAY CMDARG_TYPES[$key]=$CMDARG_TYPE_ARRAY
elif [[ "${1:2:4}" == "{}" ]]; then elif [[ "${1:2:4}" == "{}" ]]; then
declare -p ${key} >/dev/null 2>&1 declare -p ${key} >/dev/null 2>&1
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo 'Hash variable '"${key}"' does not exist. Hash variables MUST be declared by the user!' >&2 echo 'Hash variable '"${key}"' does not exist. Hash variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
CMDARG_TYPES[$key]=$CMDARG_TYPE_HASH CMDARG_TYPES[$key]=$CMDARG_TYPE_HASH
else else
CMDARG_TYPES[$key]=$CMDARG_TYPE_STRING CMDARG_TYPES[$key]=$CMDARG_TYPE_STRING
fi fi
else else
CMDARG_FLAGS[$shortopt]=$CMDARG_FLAG_NOARG CMDARG_FLAGS[$shortopt]=$CMDARG_FLAG_NOARG
CMDARG_TYPES[$key]=$CMDARG_TYPE_BOOLEAN CMDARG_TYPES[$key]=$CMDARG_TYPE_BOOLEAN
cmdarg_cfg[$key]=false cmdarg_cfg[$key]=false
fi fi
CMDARG["$shortopt"]=$2 CMDARG["$shortopt"]=$2
@@ -80,16 +80,16 @@ function cmdarg
CMDARG_DESC["$shortopt"]=$3 CMDARG_DESC["$shortopt"]=$3
CMDARG_DEFAULT["$shortopt"]=${4:-} CMDARG_DEFAULT["$shortopt"]=${4:-}
if [[ ${CMDARG_FLAGS[$shortopt]} -eq $CMDARG_FLAG_REQARG ]] && [[ "${4:-}" == "" ]]; then if [[ ${CMDARG_FLAGS[$shortopt]} -eq $CMDARG_FLAG_REQARG ]] && [[ "${4:-}" == "" ]]; then
CMDARG_REQUIRED+=($shortopt) CMDARG_REQUIRED+=($shortopt)
else else
CMDARG_OPTIONAL+=($shortopt) CMDARG_OPTIONAL+=($shortopt)
fi fi
cmdarg_cfg["$2"]="${4:-}" cmdarg_cfg["$2"]="${4:-}"
local validatorfunc local validatorfunc
validatorfunc=${5:-} validatorfunc=${5:-}
if [[ "$validatorfunc" != "" ]] && [[ "$(declare -F $validatorfunc)" == "" ]]; then if [[ "$validatorfunc" != "" ]] && [[ "$(declare -F $validatorfunc)" == "" ]]; then
echo "Validators must be bash functions accepting 1 argument (not '$validatorfunc')" >&2 echo "Validators must be bash functions accepting 1 argument (not '$validatorfunc')" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
CMDARG_VALIDATORS["$shortopt"]="$validatorfunc" CMDARG_VALIDATORS["$shortopt"]="$validatorfunc"
CMDARG_GETOPTLIST="${CMDARG_GETOPTLIST}$1" CMDARG_GETOPTLIST="${CMDARG_GETOPTLIST}$1"
@@ -103,9 +103,9 @@ function cmdarg_info
# #
local flags="header|copyright|footer|author" local flags="header|copyright|footer|author"
if [[ ! "$1" =~ $flags ]]; then if [[ ! "$1" =~ $flags ]]; then
echo "cmdarg_info <flag> <value>" >&2 echo "cmdarg_info <flag> <value>" >&2
echo "Where <flag> is one of $flags" >&2 echo "Where <flag> is one of $flags" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
CMDARG_INFO["$1"]=$2 CMDARG_INFO["$1"]=$2
} }
@@ -136,25 +136,25 @@ function cmdarg_describe_default
set +u set +u
if [ "${default}" != "" ]; then if [ "${default}" != "" ]; then
default="(Default \"${default}\")" default="(Default \"${default}\")"
fi fi
case ${argtype} in case ${argtype} in
$CMDARG_TYPE_STRING) $CMDARG_TYPE_STRING)
echo "-${opt},--${longopt} v : String. ${description} ${default}" echo "-${opt},--${longopt} v : String. ${description} ${default}"
;; ;;
$CMDARG_TYPE_BOOLEAN) $CMDARG_TYPE_BOOLEAN)
echo "-${opt},--${longopt} : Boolean. ${description} ${default}" echo "-${opt},--${longopt} : Boolean. ${description} ${default}"
;; ;;
$CMDARG_TYPE_ARRAY) $CMDARG_TYPE_ARRAY)
echo "-${opt},--${longopt} v[, ...] : Array. ${description}. Pass this argument multiple times for multiple values. ${default}" echo "-${opt},--${longopt} v[, ...] : Array. ${description}. Pass this argument multiple times for multiple values. ${default}"
;; ;;
$CMDARG_TYPE_HASH) $CMDARG_TYPE_HASH)
echo "-${opt},--${longopt} k=v{, ..} : Hash. ${description}. Pass this argument multiple times for multiple key/value pairs. ${default}" echo "-${opt},--${longopt} k=v{, ..} : Hash. ${description}. Pass this argument multiple times for multiple key/value pairs. ${default}"
;; ;;
*) *)
echo "Unable to return string description for ${opt}; unknown type ${argtype}" >&2 echo "Unable to return string description for ${opt}; unknown type ${argtype}" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
esac esac
} }
@@ -170,19 +170,19 @@ function cmdarg_usage
echo echo
local key local key
if [[ "${#CMDARG_REQUIRED[@]}" -ne 0 ]]; then if [[ "${#CMDARG_REQUIRED[@]}" -ne 0 ]]; then
echo "Required Arguments:" echo "Required Arguments:"
for key in "${CMDARG_REQUIRED[@]}" for key in "${CMDARG_REQUIRED[@]}"
do do
echo " $(cmdarg_describe $key)" echo " $(cmdarg_describe $key)"
done done
echo echo
fi fi
if [[ "${#CMDARG_OPTIONAL[@]}" -ne 0 ]]; then if [[ "${#CMDARG_OPTIONAL[@]}" -ne 0 ]]; then
echo "Optional Arguments": echo "Optional Arguments":
for key in "${CMDARG_OPTIONAL[@]}" for key in "${CMDARG_OPTIONAL[@]}"
do do
echo " $(cmdarg_describe $key)" echo " $(cmdarg_describe $key)"
done done
fi fi
echo echo
echo "${CMDARG_INFO['footer']}" echo "${CMDARG_INFO['footer']}"
@@ -199,10 +199,10 @@ function cmdarg_validate
local shortopt=${CMDARG_REV[$longopt]} local shortopt=${CMDARG_REV[$longopt]}
if [ "${CMDARG_VALIDATORS[$shortopt]}" != "" ]; then if [ "${CMDARG_VALIDATORS[$shortopt]}" != "" ]; then
( ${CMDARG_VALIDATORS[${shortopt}]} "$value" "$hashkey") ( ${CMDARG_VALIDATORS[${shortopt}]} "$value" "$hashkey")
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Invalid value for -$shortopt : ${value}" >&2 echo "Invalid value for -$shortopt : ${value}" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
fi fi
return 0 return 0
} }
@@ -215,35 +215,35 @@ function cmdarg_set_opt
set +u set +u
case ${CMDARG_TYPES[$key]} in case ${CMDARG_TYPES[$key]} in
$CMDARG_TYPE_STRING) $CMDARG_TYPE_STRING)
cmdarg_cfg[$key]=$arg cmdarg_cfg[$key]=$arg
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
$CMDARG_TYPE_BOOLEAN) $CMDARG_TYPE_BOOLEAN)
cmdarg_cfg[$key]=true cmdarg_cfg[$key]=true
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
$CMDARG_TYPE_ARRAY) $CMDARG_TYPE_ARRAY)
local arrname="${key}" local arrname="${key}"
local str='${#'"$arrname"'[@]}' local str='${#'"$arrname"'[@]}'
local prevlen=$(eval "echo $str") local prevlen=$(eval "echo $str")
eval "${arrname}[$((prevlen + 1))]=\"$arg\"" eval "${arrname}[$((prevlen + 1))]=\"$arg\""
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
$CMDARG_TYPE_HASH) $CMDARG_TYPE_HASH)
local k=${arg%%=*} local k=${arg%%=*}
local v=${arg#*=} local v=${arg#*=}
if [[ "$k" == "$arg" ]] && [[ "$v" == "$arg" ]] && [[ "$k" == "$v" ]]; then if [[ "$k" == "$arg" ]] && [[ "$v" == "$arg" ]] && [[ "$k" == "$v" ]]; then
echo "Malformed hash argument: $arg" >&2 echo "Malformed hash argument: $arg" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
eval "$key[\$k]=\$v" eval "$key[\$k]=\$v"
cmdarg_validate "$key" "$v" "$k" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$v" "$k" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
*) *)
echo "Unable to return string description for ${key}; unknown type ${CMDARG_TYPES[$key]}" >&2 echo "Unable to return string description for ${key}; unknown type ${CMDARG_TYPES[$key]}" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
esac esac
return 0 return 0
} }
@@ -255,25 +255,25 @@ function cmdarg_check_empty
local type=${CMDARG_TYPES[$longopt]} local type=${CMDARG_TYPES[$longopt]}
case $type in case $type in
$CMDARG_TYPE_STRING) $CMDARG_TYPE_STRING)
echo ${cmdarg_cfg[$longopt]} echo ${cmdarg_cfg[$longopt]}
;; ;;
$CMDARG_TYPE_BOOLEAN) $CMDARG_TYPE_BOOLEAN)
echo ${cmdarg_cfg[$longopt]} echo ${cmdarg_cfg[$longopt]}
;; ;;
$CMDARG_TYPE_ARRAY) $CMDARG_TYPE_ARRAY)
local arrname="${longopt}" local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}' local lval='${!'"${arrname}"'[@]}'
eval "echo $lval" eval "echo $lval"
;; ;;
$CMDARG_TYPE_HASH) $CMDARG_TYPE_HASH)
local arrname="${longopt}" local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}' local lval='${!'"${arrname}"'[@]}'
eval "echo $lval" eval "echo $lval"
;; ;;
*) *)
echo "${cmdarg_cfg[$longopt]}" echo "${cmdarg_cfg[$longopt]}"
;; ;;
esac esac
} }
@@ -288,61 +288,61 @@ function cmdarg_parse
local parsing=0 local parsing=0
while [[ $# -ne 0 ]]; do while [[ $# -ne 0 ]]; do
local optarg="" local optarg=""
local opt="" local opt=""
local longopt="" local longopt=""
local fullopt=$1 local fullopt=$1
local is_equals_arg=1 local is_equals_arg=1
shift shift
if [[ "${fullopt}" =~ ^(--[a-zA-Z0-9_\-]+|^-[a-zA-Z0-9])= ]]; then if [[ "${fullopt}" =~ ^(--[a-zA-Z0-9_\-]+|^-[a-zA-Z0-9])= ]]; then
local tmpopt=$fullopt local tmpopt=$fullopt
fullopt=${tmpopt%%=*} fullopt=${tmpopt%%=*}
optarg=${tmpopt##*=} optarg=${tmpopt##*=}
is_equals_arg=0 is_equals_arg=0
fi fi
if [[ "$fullopt" == "--" ]] && [[ $parsing -eq 0 ]]; then if [[ "$fullopt" == "--" ]] && [[ $parsing -eq 0 ]]; then
cmdarg_argv+=($@) cmdarg_argv+=($@)
break break
elif [[ "${fullopt:0:2}" == "--" ]]; then elif [[ "${fullopt:0:2}" == "--" ]]; then
longopt=${fullopt:2} longopt=${fullopt:2}
opt=${CMDARG_REV[$longopt]} opt=${CMDARG_REV[$longopt]}
elif [[ "${fullopt:0:1}" == "-" ]] && [[ ${#fullopt} -eq 2 ]]; then elif [[ "${fullopt:0:1}" == "-" ]] && [[ ${#fullopt} -eq 2 ]]; then
opt=${fullopt:1} opt=${fullopt:1}
longopt=${CMDARG[$opt]} longopt=${CMDARG[$opt]}
elif [[ "${fullopt:0:1}" != "-" ]]; then elif [[ "${fullopt:0:1}" != "-" ]]; then
cmdarg_argv+=("$fullopt") cmdarg_argv+=("$fullopt")
continue continue
else else
echo "Malformed argument: ${fullopt}" >&2 echo "Malformed argument: ${fullopt}" >&2
echo "While parsing: $@" >&2 echo "While parsing: $@" >&2
${cmdarg_helpers['usage']} >&2 ${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
if [[ "$opt" == "h" ]] || [[ "$longopt" == "help" ]]; then if [[ "$opt" == "h" ]] || [[ "$longopt" == "help" ]]; then
${cmdarg_helpers['usage']} >&2 ${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
if [[ $is_equals_arg -eq 1 ]]; then if [[ $is_equals_arg -eq 1 ]]; then
if [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_REQARG} ]] || \ if [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_REQARG} ]] || \
[[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_OPTARG} ]]; then [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_OPTARG} ]]; then
optarg=$1 optarg=$1
shift shift
fi fi
fi fi
if [ ${CMDARG["${opt}"]+abc} ]; then if [ ${CMDARG["${opt}"]+abc} ]; then
cmdarg_set_opt "${CMDARG[$opt]}" "$optarg" cmdarg_set_opt "${CMDARG[$opt]}" "$optarg"
local rc=$? local rc=$?
failed=$((failed + $rc)) failed=$((failed + $rc))
else else
echo "Unknown argument or invalid value : -${opt} | --${longopt}" >&2 echo "Unknown argument or invalid value : -${opt} | --${longopt}" >&2
${cmdarg_helpers['usage']} >&2 ${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
done done
# --- Don't ${CMDARG_ERROR_BEHAVIOR} early during validation, tell the user # --- Don't ${CMDARG_ERROR_BEHAVIOR} early during validation, tell the user
@@ -351,19 +351,19 @@ function cmdarg_parse
local key local key
for key in "${CMDARG_REQUIRED[@]}" for key in "${CMDARG_REQUIRED[@]}"
do do
if [[ "$(cmdarg_check_empty $key)" == "" ]]; then if [[ "$(cmdarg_check_empty $key)" == "" ]]; then
missing="${missing} -${key}" missing="${missing} -${key}"
failed=$((failed + 1)) failed=$((failed + 1))
fi fi
done done
if [ $failed -gt 0 ]; then if [ $failed -gt 0 ]; then
if [[ "$missing" != "" ]]; then if [[ "$missing" != "" ]]; then
echo "Missing arguments : ${missing}" >&2 echo "Missing arguments : ${missing}" >&2
fi fi
echo >&2 echo >&2
${cmdarg_helpers['usage']} >&2 ${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
} }
@@ -374,9 +374,9 @@ function cmdarg_traceback
local FRAMES=${#BASH_LINENO[@]} local FRAMES=${#BASH_LINENO[@]}
# FRAMES-2 skips main, the last one in arrays # FRAMES-2 skips main, the last one in arrays
for ((i=FRAMES-2; i>=1; i--)); do for ((i=FRAMES-2; i>=1; i--)); do
echo ' File' \"${BASH_SOURCE[i+1]}\", line ${BASH_LINENO[i]}, probably in ${FUNCNAME[i+1]} >&2 echo ' File' \"${BASH_SOURCE[i+1]}\", line ${BASH_LINENO[i]}, probably in ${FUNCNAME[i+1]} >&2
# Grab the source code of the line # Grab the source code of the line
sed -n "${BASH_LINENO[i]}{s/^/ /;p}" "${BASH_SOURCE[i+1]}" >&2 sed -n "${BASH_LINENO[i]}{s/^/ /;p}" "${BASH_SOURCE[i+1]}" >&2
done done
echo " Error: $LASTERR" echo " Error: $LASTERR"
unset FRAMES unset FRAMES
@@ -394,20 +394,20 @@ function cmdarg_dump
for key in ${!cmdarg_cfg[@]} for key in ${!cmdarg_cfg[@]}
do do
repr="${key}:${CMDARG_TYPES[$key]}" repr="${key}:${CMDARG_TYPES[$key]}"
if [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_ARRAY ]] || [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_HASH ]] ; then if [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_ARRAY ]] || [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_HASH ]] ; then
arrname="${key}" arrname="${key}"
echo "${repr} => " echo "${repr} => "
keys='${!'"$arrname"'[@]}' keys='${!'"$arrname"'[@]}'
for idx in $(eval "echo $keys") for idx in $(eval "echo $keys")
do do
ref='${'"$arrname"'[$idx]}' ref='${'"$arrname"'[$idx]}'
value=$(eval "echo $ref") value=$(eval "echo $ref")
echo " ${idx} => $value" echo " ${idx} => $value"
done done
else else
echo "${repr} => ${cmdarg_cfg[$key]}" echo "${repr} => ${cmdarg_cfg[$key]}"
fi fi
done done
} }
@@ -420,7 +420,7 @@ function cmdarg_purge
arrays="$arrays CMDARG_FLAGS CMDARG_TYPES cmdarg_argv cmdarg_helpers" arrays="$arrays CMDARG_FLAGS CMDARG_TYPES cmdarg_argv cmdarg_helpers"
for arr in $arrays for arr in $arrays
do do
eval "$arr=()" eval "$arr=()"
done done
cmdarg_helpers['describe']=cmdarg_describe_default cmdarg_helpers['describe']=cmdarg_describe_default
cmdarg_helpers['usage']=cmdarg_usage cmdarg_helpers['usage']=cmdarg_usage