#!/bin/bash
# -*-tab-width:4-*-

die() {
	echo $1 >&2
	exit 1
}

_version_parse_range() {
	[[ $1 =~ ^([0-9]+)(-([0-9]*))?$ ]] || die "Bad range syntax: \"$1\""
	start=${BASH_REMATCH[1]}
	[[ ${BASH_REMATCH[2]} ]] && end=${BASH_REMATCH[3]} || end=${start}
	[[ ${start} -gt 0 ]] && [[ -z ${end} || ${start} -le ${end} ]] \
		|| die "Bad range: \"$1\""
}

_version_split() {
	local v=$1 LC_ALL=C

	# get first component
	[[ ${v} =~ ^([A-Za-z]*|[0-9]*) ]] || die "No match"
	comp=("${BASH_REMATCH[1]}")
	v=${v:${#BASH_REMATCH[0]}}

	# get remaining separators and components
	while [[ ${v} ]]; do
		[[ ${v} =~ ^([^A-Za-z0-9]*)([A-Za-z]*|[0-9]*) ]] || die "No match"
		comp+=("${BASH_REMATCH[@]:1:2}")
		v=${v:${#BASH_REMATCH[0]}}
	done
}

version_cut() {
	local start end
	local -a comp

	_version_parse_range "$1"
	_version_split "${2-${PV}}"

	local IFS=
	if [[ ${end} ]]; then
		echo "${comp[*]:(start-1)*2:(end-start)*2+1}"
	else
		echo "${comp[*]:(start-1)*2}"
	fi
}

version_rs() {
	local start end i
	local -a comp

	(( $# & 1 )) && _version_split "${@: -1}" || _version_split "${PV}"

	while [[ $# -ge 2 ]]; do
		_version_parse_range "$1"
		[[ ${end} && ${end} -le $((${#comp[@]}/2)) ]] || end=$((${#comp[@]}/2))
		for (( i = start*2 - 1; i < end*2; i+=2 )); do
			comp[i]=$2
		done
		shift 2
	done

	local IFS=
	echo "${comp[*]}"
}