diff --git a/pkg_auto/impl/gentoo_ver.sh b/pkg_auto/impl/gentoo_ver.sh new file mode 100644 index 0000000000..1b53ba8ada --- /dev/null +++ b/pkg_auto/impl/gentoo_ver.sh @@ -0,0 +1,151 @@ +# Copyright 1999-2021 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @AUTHOR: +# Ulrich Müller +# Michał Górny + +# It is a cut-down and modified version of the now-gone eapi7-ver.eclass. + +if [[ -z ${__GENTOO_VER_SH_INCLUDED__:-} ]]; then +__GENTOO_VER_SH_INCLUDED__=x + +source "$(dirname "${BASH_SOURCE[0]}")/util.sh" + +VER_ERE="^([0-9]+(\.[0-9]+)*)([a-z]?)((_(alpha|beta|pre|rc|p)[0-9]*)*)(-r[0-9]+)?$" + +# @FUNCTION: _ver_compare_int +# @USAGE: +# @RETURN: 0 if -eq , 1 if -lt , 3 if -gt +# @INTERNAL +# @DESCRIPTION: +# Compare two non-negative integers and , of arbitrary length. +# If is equal to, less than, or greater than , return 0, 1, or 3 +# as exit status, respectively. +_ver_compare_int() { + local a=$1 b=$2 d=$(( ${#1}-${#2} )) + + # Zero-pad to equal length if necessary. + if [[ ${d} -gt 0 ]]; then + printf -v b "%0${d}d%s" 0 "${b}" + elif [[ ${d} -lt 0 ]]; then + printf -v a "%0$(( -d ))d%s" 0 "${a}" + fi + + [[ ${a} > ${b} ]] && return 3 + [[ ${a} == "${b}" ]] +} + +# @FUNCTION: _ver_compare +# @USAGE: +# @RETURN: 1 if < , 2 if = , 3 if > +# @INTERNAL +# @DESCRIPTION: +# Compare two versions and . If is less than, equal to, +# or greater than , return 1, 2, or 3 as exit status, respectively. +_ver_compare() { + local va=${1} vb=${2} a an al as ar b bn bl bs br re LC_ALL=C + + re=${VER_ERE} + + [[ ${va} =~ ${re} ]] || fail "${FUNCNAME}: invalid version: ${va}" + an=${BASH_REMATCH[1]} + al=${BASH_REMATCH[3]} + as=${BASH_REMATCH[4]} + ar=${BASH_REMATCH[7]} + + [[ ${vb} =~ ${re} ]] || fail "${FUNCNAME}: invalid version: ${vb}" + bn=${BASH_REMATCH[1]} + bl=${BASH_REMATCH[3]} + bs=${BASH_REMATCH[4]} + br=${BASH_REMATCH[7]} + + # Compare numeric components (PMS algorithm 3.2) + # First component + _ver_compare_int "${an%%.*}" "${bn%%.*}" || return + + while [[ ${an} == *.* && ${bn} == *.* ]]; do + # Other components (PMS algorithm 3.3) + an=${an#*.} + bn=${bn#*.} + a=${an%%.*} + b=${bn%%.*} + if [[ ${a} == 0* || ${b} == 0* ]]; then + # Remove any trailing zeros + [[ ${a} =~ 0+$ ]] && a=${a%"${BASH_REMATCH[0]}"} + [[ ${b} =~ 0+$ ]] && b=${b%"${BASH_REMATCH[0]}"} + [[ ${a} > ${b} ]] && return 3 + [[ ${a} < ${b} ]] && return 1 + else + _ver_compare_int "${a}" "${b}" || return + fi + done + [[ ${an} == *.* ]] && return 3 + [[ ${bn} == *.* ]] && return 1 + + # Compare letter components (PMS algorithm 3.4) + [[ ${al} > ${bl} ]] && return 3 + [[ ${al} < ${bl} ]] && return 1 + + # Compare suffixes (PMS algorithm 3.5) + as=${as#_}${as:+_} + bs=${bs#_}${bs:+_} + while [[ -n ${as} && -n ${bs} ]]; do + # Compare each suffix (PMS algorithm 3.6) + a=${as%%_*} + b=${bs%%_*} + if [[ ${a%%[0-9]*} == "${b%%[0-9]*}" ]]; then + _ver_compare_int "${a##*[a-z]}" "${b##*[a-z]}" || return + else + # Check for p first + [[ ${a%%[0-9]*} == p ]] && return 3 + [[ ${b%%[0-9]*} == p ]] && return 1 + # Hack: Use that alpha < beta < pre < rc alphabetically + [[ ${a} > ${b} ]] && return 3 || return 1 + fi + as=${as#*_} + bs=${bs#*_} + done + if [[ -n ${as} ]]; then + [[ ${as} == p[_0-9]* ]] && return 3 || return 1 + elif [[ -n ${bs} ]]; then + [[ ${bs} == p[_0-9]* ]] && return 1 || return 3 + fi + + # Compare revision components (PMS algorithm 3.7) + _ver_compare_int "${ar#-r}" "${br#-r}" || return + + return 2 +} + +# symbolic names for use with gentoo_ver_cmp_out +GV_LT=1 +GV_EQ=2 +GV_GT=3 + +# Compare two versions. The result can be compared against GV_LT, GV_EQ and GV_GT variables. +# +# Params: +# +# 1 - version 1 +# 2 - version 2 +# 3 - name of variable to store the result in +function gentoo_ver_cmp_out() { + local v1 v2 + v1=${1}; shift + v2=${1}; shift + local -n out_ref=${1}; shift + + out_ref=0 + _ver_compare "${v1}" "${v2}" || out_ref=${?} + case ${out_ref} in + 1|2|3) + return 0 + ;; + *) + fail "unexpected return value ${out_ref} from _ver_compare for ${v1} and ${v2}" + ;; + esac +} + +fi diff --git a/pkg_auto/impl/pkg_auto_lib.sh b/pkg_auto/impl/pkg_auto_lib.sh index 1c8adba2d6..00acf39270 100644 --- a/pkg_auto/impl/pkg_auto_lib.sh +++ b/pkg_auto/impl/pkg_auto_lib.sh @@ -51,6 +51,7 @@ __PKG_AUTO_LIB_SH_INCLUDED__=x source "$(dirname "${BASH_SOURCE[0]}")/util.sh" source "${PKG_AUTO_IMPL_DIR}/cleanups.sh" +source "${PKG_AUTO_IMPL_DIR}/gentoo_ver.sh" # Sets up the workdir using the passed config. The config can be # created basing on the config_template file or using the @@ -1032,19 +1033,10 @@ function process_listings() { # shellcheck disable=SC1091 # generated file source "${WORKDIR}/globals" - local eclass ver_ere pkg_ere - # shellcheck disable=SC2153 # PORTAGE_STABLE_SUFFIX is not a misspelling - eclass="${PKG_AUTO_DIR}/../${PORTAGE_STABLE_SUFFIX}/eclass/eapi7-ver.eclass" - # line is like ' re=""' - ver_ere=$(grep -e 're=' "${eclass}" || fail "no 're=' line found in eapi7-ver.eclass") - if [[ -z ${ver_ere} ]]; then - fail 'empty version regex from eapi7-ver.eclass' - fi - # strip everything until first quotes - ver_ere=${ver_ere#*'"'} - # strip last quote - ver_ere=${ver_ere%'"'*} - # regexp begins with ^ and ends with $, so strip them too + local ver_ere pkg_ere + # VER_ERE comes from gentoo_ver.sh + ver_ere=${VER_ERE} + # regexp begins with ^ and ends with $, so strip them ver_ere=${ver_ere#'^'} ver_ere=${ver_ere%'$'} pkg_ere='[a-z0-9]*-?[a-z0-9]*/[a-z0-9A-Z_+-]*' @@ -1439,57 +1431,6 @@ function unset_report_mvms() { done } -### -### BEGIN GENTOO VER COMP HACKS -### - -# shellcheck disable=SC2034 # it's here only for the eapi7-ver.eclass -EAPI=6 -function die() { - fail "$*" -} - -# This brings in ver_test function. -# -# shellcheck disable=SC1091 # sourcing external file -source "${PKG_AUTO_DIR}/../sdk_container/src/third_party/portage-stable/eclass/eapi7-ver.eclass" - -unset EAPI - -# symbolic names for use with gentoo_ver_cmp -GV_LT=1 -GV_EQ=2 -GV_GT=3 - -# Compare two versions. The result can be compared against GV_LT, GV_EQ and GV_GT variables. -# -# Params: -# -# 1 - version 1 -# 2 - version 2 -# 3 - name of variable to store the result in -function gentoo_ver_cmp_out() { - local v1 v2 - v1=${1}; shift - v2=${1}; shift - local -n out_ref=${1}; shift - - out_ref=0 - _ver_compare "${v1}" "${v2}" || out_ref=${?} - case ${out_ref} in - 1|2|3) - return 0 - ;; - *) - fail "unexpected return value ${out_ref} from _ver_compare for ${v1} and ${v2}" - ;; - esac -} - -### -### END GENTOO VER COMP HACKS -### - # Finds out the highest and the lowest version from the passed versions. # # Params: