# Functions for parsing dependency field values
#
# Copyright (C) 2012-2014 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
# .
resolve_deps()
{
local new_pkgs="${1}"
local deps="${2}"
shift 2
local all_deps=
local new_deps=
local pkg=
all_deps=''
new_pkgs=" $(printf '%s ' ${new_pkgs})"
while [ "x${new_pkgs}" != 'x' ]; do
all_deps="${all_deps}${new_pkgs}"
new_deps=''
for pkg in ${new_pkgs}; do
case "${pkg}" in
*[!a-z0-9+.:-]*) continue;;
esac
new_deps="${new_deps} $(printf '%s' "${deps}" | \
sed -n "s/^${pkg}: *//p")"
done
new_deps="$(printf '%s\n' ${new_deps} | sort -u)"
new_pkgs=''
for pkg in ${new_deps}; do
if [ "x${all_deps#* ${pkg} }" = "x${all_deps}" ]; then
new_pkgs="${new_pkgs}${pkg} "
fi
done
done
printf '%s\n' "${all_deps% }"
}
parse_dep()
{
local dep="${1}"
local host_arch="${2}"
local host_plat="${3}"
shift 3
local pkgarchqual=
local pkg=
local archqual=
local relver=
local rel=
local ver=
local arches=
local plats=
dep="$(printf '%s\n' "${dep}" | sed -n '
H; # Store each input line in hold space.
${ # On the last line:
g; # Restore everything to pattern space.
s/[\t\n]/ /g; # Replace tabs & newlines with spaces.
s/ *\([(\[<]\) */ \1/g; # One space before "(", "[", and "<".
s/ *\([)\]>]\) */\1 /g; # One space after "(", "[", and "<".
s/ *\(<[<=]\) */\1 /g; # One space after "<<" and "<=".
s/ *\(>[>=]\) */\1 /g; # One space after ">>" and ">=".
s/ *\(=\) */\1 /g; # One space after "=".
s/^ *//; # Remove leading spaces.
s/ *$//; # Remove trailing spaces.
s/ */ /g; # Remove duplicate spaces.
p; # Print the pattern space.
}; # End.
')"
# dep is now of the form:
# pkg[:archqual] [(rel ver)] [\[arches\]] []
pkgarchqual="${dep%% *}"
dep=" ${dep#* }"
pkg="${pkgarchqual%:*}"
if [ "x${pkg}" != "x${pkgarchqual}" ]; then
archqual="${pkgarchqual##*:}"
fi
if [ "x${dep# (*)}" != "x${dep}" ]; then
relver="${dep# (}"
relver="${relver%%)*}"
dep="${dep# (*)}"
rel="${relver% *}"
ver="${relver##* }"
fi
if [ "x${dep# \[*\]}" != "x${dep}" ]; then
arches="${dep# \[}"
arches="${arches%%\]*}"
dep="${dep# \[*\]}"
fi
if [ "x${dep# <*>}" != "x${dep}" ]; then
plats="${dep# <}"
plats="${plats%%>*}"
dep="${dep# <*>}"
fi
if [ "x${host_arch}" != 'x' ] && ! arch_is_concerned \
"${host_arch}" "${arches}"; then
return 0
fi
if [ "x${host_plat}" != 'x' ] && ! plat_is_concerned \
"${host_plat}" "${plats}"; then
return 0
fi
printf '%s' "${pkg}"
[ "x${archqual}" != 'x' ] && printf ':%s' "${archqual}"
[ "x${ver}" != 'x' ] && printf ' (%s %s)' "${rel}" "${ver}"
[ "x${host_arch}" = 'x' ] && [ "x${arches}" != 'x' ] && \
printf ' [%s]' "${arches}"
[ "x${host_plat}" = 'x' ] && [ "x${plats}" != 'x' ] && \
printf ' <%s>' "${plats}"
printf '\n'
return 0
}
reduce_deps()
{
local deps="${1}"
local union="${2}"
local host_arch="${3}"
local host_plat="${4}"
shift 4
local dep_and=
local dep_or=
local dep_list=
local dep_or_list=
local dep=
dep_list=''
IFS=','
for dep_and in ${deps}; do
unset IFS
if ! ${union}; then
dep_or_list=''
IFS='|'
for dep_or in ${dep_and}; do
unset IFS
dep="$(parse_dep "${dep_or}" \
"${host_arch}" "${host_plat}")"
if [ "x${dep}" != 'x' ]; then
if [ "x${dep_or_list}" != 'x' ]; then
dep_or_list="${dep_or_list} | "
fi
dep_or_list="${dep_or_list}${dep}"
fi
done
unset IFS
if [ "x${dep_or_list}" != 'x' ]; then
if [ "x${dep_list}" != 'x' ]; then
dep_list="${dep_list}, "
fi
dep_list="${dep_list}${dep_or_list}"
fi
else
dep="$(parse_dep "${dep_and}" \
"${host_arch}" "${host_plat}")"
if [ "x${dep}" != 'x' ]; then
if [ "x${dep_list}" != 'x' ]; then
dep_list="${dep_list}, "
fi
dep_list="${dep_list}${dep}"
fi
fi
done
unset IFS
printf '%s\n' "${dep_list}"
return 0
}