Files
hpr_website/www/eps/hpr2483/hpr2483_range_parse.sh

107 lines
2.8 KiB
Bash
Executable File

#=== FUNCTION ================================================================
# NAME: range_parse
# DESCRIPTION: Parse a comma-separated list of numbers and "number-number"
# ranges such as '1,3,5-7,9'
# PARAMETERS: 1 - maximum limit of the range
# 2 - entered range expression (e.g. 1-3,7,14)
# 3 - name of the variable to receive the result
# RETURNS: Writes a list of values to the nominated variable and returns
# 0 (true) if the range parsed, and 1 (false) if not
#===============================================================================
function range_parse {
local max=${1?range_parse: arg1 missing}
local range=${2?range_parse: arg2 missing}
local -n result=${3?range_parse: arg3 missing}
local item selection sel err msg exitcode=0
#
# Remove spaces from the range
#
range=${range// /}
#
# Check for invalid characters
#
if [[ $range =~ [^0-9,-] ]]; then
echo "Invalid range: $range"
return 1
fi
#
# Slice up the sub-ranges separated by commas and turn all n-m expressions
# into the intermediate values. Trim the trailing space from the
# concatenation.
#
until [[ -z $range ]]; do
#
# Get a comma-separated item
#
if [[ $range =~ [,] ]]; then
item=${range%%,*}
range=${range#*,}
else
item=$range
range=
fi
#
# Look for a 'number-number' expression
#
if [[ $item =~ [-] ]]; then
if [[ $item =~ ^([0-9]{1,})-([0-9]{1,})$ ]]; then
item=$(eval "echo {${item/-/..}}")
else
echo "Invalid sequence: ${item}"
item=
exitcode=1
fi
fi
selection+="$item "
done
#
# Check for out of bounds problems, sort the values and and make unique
#
if [[ -n $selection ]]; then
#
# Validate the resulting range
#
for i in $selection; do
if [[ $i -lt 1 || $i -gt $max ]]; then
err+="$i "
else
sel+="$i "
fi
done
#
# Report any out of range errors
#
if [[ ${err+"${err}"} ]]; then
msg="$(for i in ${err}; do echo "$i"; done | sort -un)"
msg="${msg//$'\n'/ }"
printf "Value(s) out of range: %s\n" "${msg}"
exitcode=1
fi
#
# Rebuild the selection after having removed errors
#
selection=
if [[ ${sel+"${sel}"} ]]; then
selection="$(for i in ${sel}; do echo "$i"; done | sort -un)"
selection="${selection//$'\n'/ }"
fi
fi
#
# Return the result
#
result="$selection"
return $exitcode
}