# Functions for matching architectures and platforms
#
# Copyright (C) 2012, 2019  Patrick McDermott
#
# This file is part of the ProteanOS Development Kit.
#
# The ProteanOS Development Kit is free software: you can redistribute
# it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# The ProteanOS Development Kit is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the ProteanOS Development Kit.  If not, see
# <http://www.gnu.org/licenses/>.

_match_arch()
{
	local match_arch="${1}"
	local field_arch="${2}"
	shift 2
	local match_arch_rest=
	local field_arch_rest=
	local match_arch_part=
	local field_arch_part=

	# "foo-bar-baz" == "any"
	if [ x"${field_arch}" = x'any' ]; then
		return 0
	fi

	# "foo-bar-baz" == "foo-any-any"
	match_arch_rest="${match_arch}"
	field_arch_rest="${field_arch}"
	while [ -n "${match_arch_rest}" ] && [ -n "${field_arch_rest}" ]; do
		IFS='-' read match_arch_part match_arch_rest <<-EOF
			${match_arch_rest}
			EOF
		IFS='-' read field_arch_part field_arch_rest <<-EOF
			${field_arch_rest}
			EOF
		case "${field_arch_part}" in
			"${match_arch_part}" | 'any') ;;
			*) return 1;;  # Failed match
		esac
	done

	return 0
}

arch_is_concerned()
{
	local host_arch="${1}"
	local arches="${2}"
	shift 2
	local arch=
	local not_arch=
	local seen_arch=

	if [ x"${arches}" = x'' ]; then
		return 0
	elif [ x"${host_arch}" = x'all' ]; then
		if [ x"${arches}" = x'all' ]; then
			return 0
		else
			return 1
		fi
	else
		seen_arch=1
		for arch in ${arches}; do
			not_arch="${arch#!}"
			if [ x"${not_arch}" != x"${arch}" ]; then
				if _match_arch "${host_arch}" "${not_arch}"
				then
					seen_arch=1
					break
				else
					seen_arch=0
				fi
			elif _match_arch "${host_arch}" "${arch}"; then
				seen_arch=0
				break
			fi
		done
		return ${seen_arch}
	fi
}

_match_plat()
{
	local match_plat="${1}"
	local field_plat="${2}"
	shift 2

	if [ x"${field_plat}" = x'any' ]; then
		return 0
	fi
	if [ x"${field_plat}" = x"${match_plat}" ]; then
		return 0
	fi

	return 1
}

plat_is_concerned()
{
	local host_plat="${1}"
	local plats="${2}"
	shift 2
	local plat=
	local not_plat=
	local seen_plat=

	if [ x"${plats}" = x'' ]; then
		return 0
	elif [ x"${host_plat}" = x'all' ]; then
		if [ x"${plats}" = x'all' ]; then
			return 0
		else
			return 1
		fi
	else
		seen_plat=1
		for plat in ${plats}; do
			not_plat="${plat#!}"
			if [ x"${not_plat}" != x"${plat}" ]; then
				if _match_plat "${host_plat}" "${not_plat}"
				then
					seen_plat=1
					break
				else
					seen_plat=0
				fi
			elif _match_plat "${host_plat}" "${plat}"; then
				seen_plat=0
				break
			fi
		done
		return ${seen_plat}
	fi
}