#!/bin/sh -efu
### This file is covered by the GNU General Public License,
### which should be included with libshell as the file LICENSE.
### All copyright information are listed in the COPYING.

if [ -z "${__included_shell_string-}" ]; then
__included_shell_string=1

### Creates a mask of equal length string.
### Usage: fill_mask var str [full-length]
fill_mask()
{
__fill_mask()
{
	local m=
	while :; do
		case $((${#1} - ${#m})) in
			0) break ;;
			1) m="$m?" ;;
			2) m="$m??" ;;
			3) m="$m???" ;;
			4) m="$m????" ;;
			5) m="$m?????" ;;
			6) m="$m??????" ;;
			7) m="$m???????" ;;
			8) m="$m????????" ;;
			9) m="$m?????????" ;;
			*) m="$m??????????" ;;
		esac
	done
	__fill_masko="${m#$2}"
}
	local __fill_masko
	__fill_mask "$2" "${3:-?}"
	unset -f __fill_mask
	eval "$1=\$__fill_masko"
}

__shell_is_bash()
{
	[ -n "${BASH-}" ] && [ -n "${BASH_VERSION-}" ]
}

__shell_is_ksh()
{
	[ -n "${KSH_VERSION-}" ]
}

__shell_string_foreach=0

# Usage: __shell_string_foreach_prepare ctxvar str
__shell_string_foreach_prepare()
{
	set -- "$@" "__shell_string_foreach_${__shell_string_foreach:-0}"
	eval "${3}_line=\"\$2\""
	eval "${3}_mask=\"\""
	eval "${3}_i=0"

	if ! __shell_is_bash && ! __shell_is_ksh; then
		fill_mask "${3}_mask" "$2"
	fi

	eval "$1=\"\$3\""
	__shell_string_foreach=$(( ${__shell_string_foreach:-0} + 1 ))
}

# Usage: __shell_string_foreach_finish ctxvar
__shell_string_foreach_finish()
{
	unset "${1}_line"
	unset "${1}_mask"
	unset "${1}_i"
}

# Usage: __shell_string_foreach_condition ctxvar
__shell_string_foreach_condition()
{
	eval "set -- \"\${${1}_i-}\" \"\${${1}_line-}\""

	if __shell_is_bash || __shell_is_ksh; then
		[ $1 -lt "${#2}" ] ||
			return 1
	else
		[ -n "$2" ] ||
			return 1
	fi
}

# Usage: __shell_string_foreach_continue ctxvar
__shell_string_foreach_continue()
{
	if ! __shell_string_foreach_condition "$1"; then
		__shell_string_foreach_finish "$1"
		return 1
	fi
}

# Usage: __shell_string_foreach_char retchar ctxvar
__shell_string_foreach_char()
{
	if __shell_is_bash || __shell_is_ksh; then
		eval "$1=\"\${${2}_line:\$${2}_i:1}\""
	else
		eval "$1=\"\${${2}_line%\$${2}_mask}\""
	fi
}

# Usage: __shell_string_foreach_char ctxvar
__shell_string_foreach_iter()
{
	if __shell_is_bash || __shell_is_ksh; then
		eval "${1}_i=\$(( \$${1}_i + 1 ))"
	else
		eval "${1}_line=\"\${${1}_line#?}\""
		eval "${1}_mask=\"\${${1}_mask#?}\""
	fi
}

fi #__included_shell_string
