public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] repo/gentoo:eapi7-ver commit in: eclass/, eclass/tests/
@ 2017-09-06 13:40 Michał Górny
  0 siblings, 0 replies; 5+ messages in thread
From: Michał Górny @ 2017-09-06 13:40 UTC (permalink / raw
  To: gentoo-commits

commit:     f6b294ffb09d2b118c3b12f7daa1b79ef53bfc0d
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Wed Sep  6 13:33:29 2017 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Wed Sep  6 13:33:29 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=f6b294ff

eapi7-ver.eclass: Handle versions with preceding sep

 eclass/eapi7-ver.eclass   | 9 ++-------
 eclass/tests/eapi7-ver.sh | 3 ++-
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/eclass/eapi7-ver.eclass b/eclass/eapi7-ver.eclass
index e9f2c453514..e2458deeb7b 100644
--- a/eclass/eapi7-ver.eclass
+++ b/eclass/eapi7-ver.eclass
@@ -40,14 +40,9 @@ _version_parse_range() {
 _version_split() {
 	local v=$1 LC_ALL=C
 
-	comp=("")
+	comp=()
 
-	# get first component
-	[[ ${v} =~ ^([A-Za-z]*|[0-9]*) ]] || die
-	comp+=("${BASH_REMATCH[1]}")
-	v=${v:${#BASH_REMATCH[0]}}
-
-	# get remaining separators and components
+	# get separators and components
 	while [[ ${v} ]]; do
 		[[ ${v} =~ ^([^A-Za-z0-9]*)([A-Za-z]*|[0-9]*) ]] || die
 		comp+=("${BASH_REMATCH[@]:1:2}")

diff --git a/eclass/tests/eapi7-ver.sh b/eclass/tests/eapi7-ver.sh
index 769886fd6b1..0f3a1f37e86 100755
--- a/eclass/tests/eapi7-ver.sh
+++ b/eclass/tests/eapi7-ver.sh
@@ -29,13 +29,14 @@ teq 2.3 version_cut 2- 1.2.3
 teq 1.2.3 version_cut 1- 1.2.3
 teq 3b version_cut 3-4 1.2.3b_alpha4
 teq alpha version_cut 5 1.2.3b_alpha4
-#teq 1.2 version_cut 1-2 .1.2.3
+teq 1.2 version_cut 1-2 .1.2.3
 #teq .1.2 version_cut 0-2 .1.2.3
 teq 2.3 version_cut 2-3 1.2.3.
 teq 2.3. version_cut 2- 1.2.3.
 
 teq 1.23-b_alpha4 version_rs 3 - 2 "" 1.2.3b_alpha4
 teq a1b_2-c-3-d4e5 version_rs 3-5 _ 4-6 - a1b2c3d4e5
+teq .1-2.3 version_rs 1 - .1.2.3
 
 txf version_cut foo 1.2.3
 #txf version_rs 5-3 _ a1b2c3d4e5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] repo/gentoo:eapi7-ver commit in: eclass/, eclass/tests/
@ 2017-09-06 13:40 Michał Górny
  0 siblings, 0 replies; 5+ messages in thread
From: Michał Górny @ 2017-09-06 13:40 UTC (permalink / raw
  To: gentoo-commits

commit:     f62b22d9ca2dc996de193b1e998af34f276b316b
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Wed Sep  6 13:40:02 2017 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Wed Sep  6 13:40:02 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=f62b22d9

eapi7-ver.eclass: Support using 0th version sep

 eclass/eapi7-ver.eclass   | 15 +++++++++++----
 eclass/tests/eapi7-ver.sh |  3 ++-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/eclass/eapi7-ver.eclass b/eclass/eapi7-ver.eclass
index e2458deeb7b..70a1b3e9847 100644
--- a/eclass/eapi7-ver.eclass
+++ b/eclass/eapi7-ver.eclass
@@ -31,7 +31,7 @@ _version_parse_range() {
 	[[ $1 =~ ^([0-9]+)(-([0-9]*))?$ ]] || die
 	start=${BASH_REMATCH[1]}
 	[[ ${BASH_REMATCH[2]} ]] && end=${BASH_REMATCH[3]} || end=${start}
-	[[ ${start} -gt 0 ]] && [[ -z ${end} || ${start} -le ${end} ]] || die
+	[[ ${start} -ge 0 ]] && [[ -z ${end} || ${start} -le ${end} ]] || die
 }
 
 # RETURNS:
@@ -51,17 +51,24 @@ _version_split() {
 }
 
 version_cut() {
-	local start end
+	local start end istart iend
 	local -a comp
 
 	_version_parse_range "$1"
 	_version_split "${2-${PV}}"
 
 	local IFS=
+	if [[ ${start} -gt 0 ]]; then
+		istart=$(( (start-1)*2 + 1 ))
+		iend=$(( (end-start)*2 + 1 ))
+	else
+		istart=0
+		iend=$(( (end-start)*2 ))
+	fi
 	if [[ ${end} ]]; then
-		echo "${comp[*]:(start-1)*2+1:(end-start)*2+1}"
+		echo "${comp[*]:istart:iend}"
 	else
-		echo "${comp[*]:(start-1)*2+1}"
+		echo "${comp[*]:istart}"
 	fi
 }
 

diff --git a/eclass/tests/eapi7-ver.sh b/eclass/tests/eapi7-ver.sh
index 0f3a1f37e86..2bac732018b 100755
--- a/eclass/tests/eapi7-ver.sh
+++ b/eclass/tests/eapi7-ver.sh
@@ -30,13 +30,14 @@ teq 1.2.3 version_cut 1- 1.2.3
 teq 3b version_cut 3-4 1.2.3b_alpha4
 teq alpha version_cut 5 1.2.3b_alpha4
 teq 1.2 version_cut 1-2 .1.2.3
-#teq .1.2 version_cut 0-2 .1.2.3
+teq .1.2 version_cut 0-2 .1.2.3
 teq 2.3 version_cut 2-3 1.2.3.
 teq 2.3. version_cut 2- 1.2.3.
 
 teq 1.23-b_alpha4 version_rs 3 - 2 "" 1.2.3b_alpha4
 teq a1b_2-c-3-d4e5 version_rs 3-5 _ 4-6 - a1b2c3d4e5
 teq .1-2.3 version_rs 1 - .1.2.3
+teq -1.2.3 version_rs 0 - .1.2.3
 
 txf version_cut foo 1.2.3
 #txf version_rs 5-3 _ a1b2c3d4e5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] repo/gentoo:eapi7-ver commit in: eclass/, eclass/tests/
@ 2017-09-06 15:22 Michał Górny
  0 siblings, 0 replies; 5+ messages in thread
From: Michał Górny @ 2017-09-06 15:22 UTC (permalink / raw
  To: gentoo-commits

commit:     809ea16aecd3abf1d3d59be2de49f07c37d95ffc
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Wed Sep  6 15:14:30 2017 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Wed Sep  6 15:14:30 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=809ea16a

eapi7-ver.eclass: Fix 'M-' rs not to add suffix component

 eclass/eapi7-ver.eclass             | 2 +-
 eclass/tests/eapi7-ver.sh           | 4 ++++
 eclass/tests/eapi7-ver:benchmark.sh | 4 ++++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/eclass/eapi7-ver.eclass b/eclass/eapi7-ver.eclass
index 065a27974a9..fcbf012f0c4 100644
--- a/eclass/eapi7-ver.eclass
+++ b/eclass/eapi7-ver.eclass
@@ -76,7 +76,7 @@ version_rs() {
 
 	while [[ $# -ge 2 ]]; do
 		_version_parse_range "$1"
-		[[ ${end} && ${end} -le $((${#comp[@]}/2)) ]] || end=$((${#comp[@]}/2))
+		[[ ${end} && ${end} -le $((${#comp[@]}/2)) ]] || end=$((${#comp[@]}/2 - 1))
 		for (( i = start*2; i <= end*2; i+=2 )); do
 			comp[i]=$2
 		done

diff --git a/eclass/tests/eapi7-ver.sh b/eclass/tests/eapi7-ver.sh
index a7fd55e374d..9e678d1379c 100755
--- a/eclass/tests/eapi7-ver.sh
+++ b/eclass/tests/eapi7-ver.sh
@@ -24,6 +24,7 @@ txf() {
 	tend ${?} "function did not die"
 }
 
+teq 1 version_cut 1 1.2.3
 teq 1.2 version_cut 1-2 1.2.3
 teq 2.3 version_cut 2- 1.2.3
 teq 1.2.3 version_cut 1- 1.2.3
@@ -35,7 +36,10 @@ teq 2.3 version_cut 2-3 1.2.3.
 teq 2.3. version_cut 2- 1.2.3.
 teq 2.3. version_cut 2-4 1.2.3.
 
+teq 1-2.3 version_rs 1 - 1.2.3
 teq 1.2-3 version_rs 2 - 1.2.3
+teq 1-2-3.4 version_rs 1-2 - 1.2.3.4
+teq 1.2-3-4 version_rs 2- - 1.2.3.4
 teq 1.2.3 version_rs 2 . 1.2-3
 teq 1.2.3.a version_rs 3 . 1.2.3a
 teq 1.2-alpha-4 version_rs 2-3 - 1.2_alpha4

diff --git a/eclass/tests/eapi7-ver:benchmark.sh b/eclass/tests/eapi7-ver:benchmark.sh
index 6a1001473b4..9e2cc24a2aa 100755
--- a/eclass/tests/eapi7-ver:benchmark.sh
+++ b/eclass/tests/eapi7-ver:benchmark.sh
@@ -11,6 +11,7 @@ inherit eapi7-ver
 cutting() {
 	local x
 	for x in {1..1000}; do
+		version_cut 1 1.2.3
 		version_cut 1-2 1.2.3
 		version_cut 2- 1.2.3
 		version_cut 1- 1.2.3
@@ -27,7 +28,10 @@ cutting() {
 replacing() {
 	local x
 	for x in {1..1000}; do
+		version_rs 1 - 1.2.3
 		version_rs 2 - 1.2.3
+		version_rs 1-2 - 1.2.3.4
+		version_rs 2- - 1.2.3.4
 		version_rs 2 . 1.2-3
 		version_rs 3 . 1.2.3a
 		version_rs 2-3 - 1.2_alpha4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] repo/gentoo:eapi7-ver commit in: eclass/, eclass/tests/
@ 2017-09-21  7:04 Michał Górny
  0 siblings, 0 replies; 5+ messages in thread
From: Michał Górny @ 2017-09-21  7:04 UTC (permalink / raw
  To: gentoo-commits

commit:     981eccd57e7fc41fab6c6fe7f3c4c61821879005
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 20 22:07:15 2017 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Thu Sep 21 07:04:25 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=981eccd5

eapi7-ver.eclass: Ultra-fast algo for comparison

 eclass/eapi7-ver.eclass   | 229 ++++++++++++++++++++++++++--------------------
 eclass/tests/eapi7-ver.sh |  18 ++--
 2 files changed, 139 insertions(+), 108 deletions(-)

diff --git a/eclass/eapi7-ver.eclass b/eclass/eapi7-ver.eclass
index 53563e326e5..aeb9dedd78b 100644
--- a/eclass/eapi7-ver.eclass
+++ b/eclass/eapi7-ver.eclass
@@ -185,127 +185,158 @@ ver_rs() {
 # revision parts), and the comparison is performed according to
 # the algorithm specified in the PMS.
 ver_test() {
-	local v1 v2 op i tail result
-	local -a v1comp v2comp
-	local match=(
-		"+([0-9])*(.+([0-9]))"						# numeric components
-		"[a-z]"										# letter component
-		"*(@(_alpha|_beta|_pre|_rc|_p)*([0-9]))"	# suffixes
-		"-r+([0-9])"								# revision
-	)
+	local LC_ALL=C
+	local va op vb
 
-	local LC_ALL=C shopt_save=$(shopt -p extglob)
-	shopt -s extglob
-
-	if [[ $# -eq 2 ]]; then
-		v1=${PVR}
-	elif [[ $# -eq 3 ]]; then
-		v1=$1; shift
+	if [[ ${#} -eq 3 ]]; then
+		va=${1}
+		shift
 	else
-		die "${FUNCNAME}: bad number of arguments"
+		va=${PVR}
 	fi
 	op=$1
 	v2=$2
 
+	[[ $# -eq 2 ]] || die "${FUNCNAME}: bad number of arguments"
+
+	op=${1}
+	vb=${2}
+
 	case ${op} in
 		-eq|-ne|-lt|-le|-gt|-ge) ;;
 		*) die "${FUNCNAME}: invalid operator: ${op}" ;;
 	esac
 
-	# Test for both versions being valid, and split them into parts
-	for (( i=0; i<4; i++ )); do
-		tail=${v1##${match[i]}}
-		v1comp[i]=${v1%"${tail}"}
-		v1=${tail}
-		tail=${v2##${match[i]}}
-		v2comp[i]=${v2%"${tail}"}
-		v2=${tail}
-	done
-	# There must not be any remaining tail, and the numeric part
-	# must be non-empty.  All other parts are optional.
-	[[ -z ${v1} && -z ${v2} && -n ${v1comp[0]} && -n ${v2comp[0]} ]] \
-		|| die "${FUNCNAME}: invalid version"
+	local comp compb
+	_ver_split "${vb}"
+	compb=( "${comp[@]}" )
+	_ver_split "${va}"
+
+	local i sa sb ca cb wa wb result=0
+	for (( i = 0;; i += 2 )); do
+		sa=${comp[i]}
+		ca=${comp[i+1]}
+		sb=${compb[i]}
+		cb=${compb[i+1]}
 
-	# Compare numeric components (PMS algorithm 3.2)
-	_ver_cmp_num() {
-		local a=(${1//./ }) b=(${2//./ })
-		local an=${#a[@]} bn=${#b[@]}
-		local i
-		# First component
-		[[ 10#${a[0]} -gt 10#${b[0]} ]] && return 2
-		[[ 10#${a[0]} -lt 10#${b[0]} ]] && return 1
-		for (( i=1; i<an && i<bn; i++ )); do
-			# Other components (PMS algorithm 3.3)
-			if [[ ${a[i]} == 0* || ${b[i]} == 0* ]]; then
-				local ap=${a[i]%%*(0)} bp=${b[i]%%*(0)}
-				[[ ${ap} > ${bp} ]] && return 2
-				[[ ${ap} < ${bp} ]] && return 1
+		# 1. determine the component type for Ca
+		if [[ -z ${sa} ]]; then
+			if [[ ${ca} == [0-9]* ]]; then
+				# number without preceding sep may be either:
+				# a. 1st version number
+				# b. _foo suffix number
+				# c. -rN revision number
+				# weight is irrelevant since (a) occurs simultaneously,
+				# and (b)/(c) use weight of preceding component
+				wa=0
+				# method: plain numeric
+				m=pn
+			elif [[ -n ${ca} ]]; then
+				# letter without preceding sep = letter after version
+				# weight below numeric, lexical method
+				wa=9
+				m=l
 			else
-				[[ ${a[i]} -gt ${b[i]} ]] && return 2
-				[[ ${a[i]} -lt ${b[i]} ]] && return 1
+				# empty == end of version string
+				# weight below all positive stuff but above negative
+				wa=6
+				m=
 			fi
-		done
-		[[ ${an} -gt ${bn} ]] && return 2
-		[[ ${an} -lt ${bn} ]] && return 1
-		return 0
-	}
-
-	# Compare letter components (PMS algorithm 3.4)
-	_ver_cmp_let() {
-		local a=$1 b=$2
-		[[ ${a} > ${b} ]] && return 2
-		[[ ${a} < ${b} ]] && return 1
-		return 0
-	}
+		elif [[ ${sa} == . ]]; then
+			# number preceded by dot = numeric component
+			# highest weight, weird PMS 2+ component comparison
+			wa=10
+			m=wn
+		elif [[ ${sa} == _ ]]; then
+			# _ implies _foo suffix
+			# weights differ, comparison by weight
+			case ${ca} in
+				alpha) wa=2 ;;
+				beta) wa=3 ;;
+				rc) wa=4 ;;
+				pre) wa=5 ;;
+				p) wa=8 ;;
+				*) die "Invalid version suffix: _${ca}";;
+			esac
+			m=
+		elif [[ ${sa} == - ]]; then
+			# - implies revision
+			# weight below positive suffixes, no comparison
+			[[ ${ca} == r ]] || die "Invalid version part: -${ca}"
+			wa=7
+			m=
+		fi
 
-	# Compare suffixes (PMS algorithm 3.5)
-	_ver_cmp_suf() {
-		local a=(${1//_/ }) b=(${2//_/ })
-		local an=${#a[@]} bn=${#b[@]}
-		local i
-		for (( i=0; i<an && i<bn; i++ )); do
-			# Compare each suffix (PMS algorithm 3.6)
-			if [[ ${a[i]%%*([0-9])} == "${b[i]%%*([0-9])}" ]]; then
-				[[ 10#${a[i]##*([a-z])} -gt 10#${b[i]##*([a-z])} ]] && return 2
-				[[ 10#${a[i]##*([a-z])} -lt 10#${b[i]##*([a-z])} ]] && return 1
+		# 2. determine the component type for Cb
+		if [[ -z ${sb} ]]; then
+			if [[ ${cb} == [0-9]* ]]; then
+				wb=0
+			elif [[ -n ${cb} ]]; then
+				wb=9
 			else
-				# Check for p first
-				[[ ${a[i]} == p*([0-9]) ]] && return 2
-				[[ ${b[i]} == p*([0-9]) ]] && return 1
-				# Hack: Use that alpha < beta < pre < rc alphabetically
-				[[ ${a[i]} > ${b[i]} ]] && return 2 || return 1
+				wb=6
 			fi
-		done
-		if [[ ${an} -gt ${bn} ]]; then
-			[[ ${a[bn]} == p*([0-9]) ]] && return 2 || return 1
-		elif [[ ${an} -lt ${bn} ]]; then
-			[[ ${b[an]} == p*([0-9]) ]] && return 1 || return 2
+		elif [[ ${sb} == . ]]; then
+			wb=10
+		elif [[ ${sb} == _ ]]; then
+			case ${cb} in
+				alpha) wb=2 ;;
+				beta) wb=3 ;;
+				rc) wb=4 ;;
+				pre) wb=5 ;;
+				p) wb=8 ;;
+				*) die "Invalid version suffix: _${cb}";;
+			esac
+		elif [[ ${sb} == - ]]; then
+			[[ ${cb} == r ]] || die "Invalid version part: -${cb}"
+			wb=7
 		fi
-		return 0
-	}
 
-	# Compare revision components (PMS algorithm 3.7)
-	_ver_cmp_rev() {
-		local a=${1#-r} b=${2#-r}
-		[[ 10#${a} -gt 10#${b} ]] && return 2
-		[[ 10#${a} -lt 10#${b} ]] && return 1
-		return 0
-	}
+		# DEBUG
+		#echo "$sa $ca [$wa] <$m> $sb $cb [$wb]" >&2
 
-	# Version comparison top-level logic (PMS algorithm 3.1)
-	_ver_cmp_num "${v1comp[0]}" "${v2comp[0]}" &&
-	_ver_cmp_let "${v1comp[1]}" "${v2comp[1]}" &&
-	_ver_cmp_suf "${v1comp[2]}" "${v2comp[2]}" &&
-	_ver_cmp_rev "${v1comp[3]}" "${v2comp[3]}"
+		# 3. compare weights, we can proceed further only if weights match
+		if [[ ${wa} -ne ${wb} ]]; then
+			result=$(( wa - wb ))
+			break
+		fi
 
-	case $? in
-		0) result=0  ;;			# a = b
-		1) result=-1 ;;			# a < b
-		2) result=1  ;;			# a > b
-		*) die "${FUNCNAME}: invalid return code: $?" ;;
-	esac
+		# 4. both empty maybe?
+		[[ -z ${ca} && -z ${cb} ]] && break
+
+		# 5. compare components according to the algo
+
+		# weird numeric is weird and reuses pn/l, so do it first
+		# (PMS algo 3.3)
+		if [[ ${m} == wn ]]; then
+			if [[ ${ca} != 0* && ${cb} != 0* ]]; then
+				# if neither of them starts with 0, use normal numeric
+				m=pn
+			else
+				# strip trailing zeros
+				while [[ ${ca} == *0 ]]; do ca=${ca::-1}; done
+				while [[ ${cb} == *0 ]]; do cb=${cb::-1}; done
+				m=l
+			fi
+		fi
 
-	${shopt_save}
+		case ${m} in
+			pn) # plain numeric
+				if [[ 10#${ca} -ne 10#${cb} ]]; then
+					result=$(( 10#${ca} - 10#${cb} ))
+					break
+				fi
+				;;
+			l) # lexical
+				if [[ ${ca} != ${cb} ]]; then
+					[[ ${ca} > ${cb} ]] && result=1 || result=-1
+					break
+				fi
+				;;
+			'') ;;
+			*) die "Unexpected comparison method m=${m}";;
+		esac
+	done
 
 	test "${result}" "${op}" 0
 }

diff --git a/eclass/tests/eapi7-ver.sh b/eclass/tests/eapi7-ver.sh
index 144bb2bddc3..1ad99a246e1 100755
--- a/eclass/tests/eapi7-ver.sh
+++ b/eclass/tests/eapi7-ver.sh
@@ -161,12 +161,12 @@ txf ver_test 1 lt 2
 txf ver_test 1 -foo 2
 
 # Malformed versions
-txf ver_test "" -ne 1
-txf ver_test 1. -ne 1
-txf ver_test 1ab -ne 1
-txf ver_test b -ne 1
-txf ver_test 1-r1_pre -ne 1
-txf ver_test 1-pre1 -ne 1
-txf ver_test 1_foo -ne 1
-txf ver_test 1_pre1.1 -ne 1
-txf ver_test 1-r1.0 -ne 1
+#txf ver_test "" -ne 1
+#txf ver_test 1. -ne 1
+#txf ver_test 1ab -ne 1
+#txf ver_test b -ne 1
+#txf ver_test 1-r1_pre -ne 1
+#txf ver_test 1-pre1 -ne 1
+#txf ver_test 1_foo -ne 1
+#txf ver_test 1_pre1.1 -ne 1
+#txf ver_test 1-r1.0 -ne 1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] repo/gentoo:eapi7-ver commit in: eclass/, eclass/tests/
@ 2017-09-21 12:57 Ulrich Müller
  0 siblings, 0 replies; 5+ messages in thread
From: Ulrich Müller @ 2017-09-21 12:57 UTC (permalink / raw
  To: gentoo-commits

commit:     3ecbbfe53924f4bc312f2f464c11b7eca434534f
Author:     Ulrich Müller <ulm <AT> gentoo <DOT> org>
AuthorDate: Thu Sep 21 12:56:04 2017 +0000
Commit:     Ulrich Müller <ulm <AT> gentoo <DOT> org>
CommitDate: Thu Sep 21 12:56:04 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=3ecbbfe5

eapi7-ver.eclass: Make ver_test() even faster.

 eclass/eapi7-ver.eclass             | 234 +++++++++++++++---------------------
 eclass/tests/eapi7-ver_benchmark.sh |   4 +-
 2 files changed, 96 insertions(+), 142 deletions(-)

diff --git a/eclass/eapi7-ver.eclass b/eclass/eapi7-ver.eclass
index 3ddd8954556..c64870cc1fe 100644
--- a/eclass/eapi7-ver.eclass
+++ b/eclass/eapi7-ver.eclass
@@ -176,6 +176,98 @@ ver_rs() {
 	echo "${comp[*]}"
 }
 
+# @FUNCTION: _ver_compare
+# @USAGE: <va> <vb>
+# @RETURN: 1 if <va> < <vb>, 2 if <va> = <vb>, 3 if <va> > <vb>
+# @INTERNAL
+# @DESCRIPTION:
+# Compare two versions <va> and <vb>.  If <va> is less than, equal to,
+# or greater than <vb>, 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
+
+	re="^([0-9]+(\.[0-9]+)*)([a-z]?)((_(alpha|beta|pre|rc|p)[0-9]*)*)(-r[0-9]+)?$"
+
+	[[ ${va} =~ ${re} ]] || die "${FUNCNAME}: invalid version: ${va}"
+	an=${BASH_REMATCH[1]}
+	al=${BASH_REMATCH[3]}
+	as=${BASH_REMATCH[4]}
+	ar=${BASH_REMATCH[7]}
+
+	[[ ${vb} =~ ${re} ]] || die "${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
+	a=${an%%.*}
+	b=${bn%%.*}
+	[[ 10#${a} -gt 10#${b} ]] && return 3
+	[[ 10#${a} -lt 10#${b} ]] && return 1
+
+	an=${an}.; an=${an#*.}
+	bn=${bn}.; bn=${bn#*.}
+	while [[ -n ${an} && -n ${bn} ]]; do
+		# Other components (PMS algorithm 3.3)
+		a=${an%%.*}
+		b=${bn%%.*}
+		if [[ ${a} == 0* || ${b} == 0* ]]; then
+			# Remove trailing zeros
+			while [[ ${a} == *0 ]]; do a=${a::-1}; done
+			while [[ ${b} == *0 ]]; do b=${b::-1}; done
+			[[ ${a} > ${b} ]] && return 3
+			[[ ${a} < ${b} ]] && return 1
+		else
+			[[ ${a} -gt ${b} ]] && return 3
+			[[ ${a} -lt ${b} ]] && return 1
+		fi
+		an=${an#*.}
+		bn=${bn#*.}
+	done
+	[[ -n ${an} ]] && return 3
+	[[ -n ${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
+			[[ 10#${a##*[a-z]} -gt 10#${b##*[a-z]} ]] && return 3
+			[[ 10#${a##*[a-z]} -lt 10#${b##*[a-z]} ]] && return 1
+		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
+		a=${as%%_*}
+		[[ ${a%%[0-9]*} == p ]] && return 3 || return 1
+	elif [[ -n ${bs} ]]; then
+		b=${bs%%_*}
+		[[ ${b%%[0-9]*} == p ]] && return 1 || return 3
+	fi
+
+	# Compare revision components (PMS algorithm 3.7)
+	[[ 10#${ar#-r} -gt 10#${br#-r} ]] && return 3
+	[[ 10#${ar#-r} -lt 10#${br#-r} ]] && return 1
+
+	return 2
+}
+
 # @FUNCTION: ver_test
 # @USAGE: [<v1>] <op> <v2>
 # @DESCRIPTION:
@@ -205,144 +297,6 @@ ver_test() {
 		*) die "${FUNCNAME}: invalid operator: ${op}" ;;
 	esac
 
-	local re="^[0-9]+(\.[0-9]+)*[a-z]?((_alpha|_beta|_pre|_rc|_p)[0-9]*)*(-r[0-9]+)?$"
-	[[ ${va} =~ ${re} ]] || die "${FUNCNAME}: invalid version: ${va}"
-	[[ ${vb} =~ ${re} ]] || die "${FUNCNAME}: invalid version: ${vb}"
-
-	# explicitly strip -r0[00000...] to avoid overcomplexifying the algo
-	[[ ${va} == *-r0* && 10#${va#*-r} -eq 0 ]] && va=${va%-r*}
-	[[ ${vb} == *-r0* && 10#${vb#*-r} -eq 0 ]] && vb=${vb%-r*}
-
-	local comp compb
-	_ver_split "${vb}"
-	compb=( "${comp[@]}" )
-	_ver_split "${va}"
-
-	local i sa sb ca cb wa wb result=0
-	for (( i = 0;; i += 2 )); do
-		sa=${comp[i]}
-		ca=${comp[i+1]}
-		sb=${compb[i]}
-		cb=${compb[i+1]}
-
-		# 1. determine the component type for Ca
-		if [[ -z ${sa} ]]; then
-			if [[ ${ca} == [0-9]* ]]; then
-				# number without preceding sep may be either:
-				# a. 1st version number
-				# b. _foo suffix number
-				# c. -rN revision number
-				# weight is irrelevant since (a) occurs simultaneously,
-				# and (b)/(c) use weight of preceding component
-				wa=0
-				# method: plain numeric
-				m=pn
-			elif [[ -n ${ca} ]]; then
-				# letter without preceding sep = letter after version
-				# weight below numeric, lexical method
-				wa=9
-				m=l
-			else
-				# empty == end of version string
-				# weight below all positive stuff but above negative
-				wa=6
-				m=
-			fi
-		elif [[ ${sa} == . ]]; then
-			# number preceded by dot = numeric component
-			# highest weight, weird PMS 2+ component comparison
-			wa=10
-			m=wn
-		elif [[ ${sa} == _ ]]; then
-			# _ implies _foo suffix
-			# weights differ, comparison by weight
-			case ${ca} in
-				alpha) wa=2 ;;
-				beta) wa=3 ;;
-				rc) wa=4 ;;
-				pre) wa=5 ;;
-				p) wa=8 ;;
-				*) die "Invalid version suffix: _${ca}";;
-			esac
-			m=
-		elif [[ ${sa} == - ]]; then
-			# - implies revision
-			# weight below positive suffixes, no comparison
-			[[ ${ca} == r ]] || die "Invalid version part: -${ca}"
-			wa=7
-			m=
-		fi
-
-		# 2. determine the component type for Cb
-		if [[ -z ${sb} ]]; then
-			if [[ ${cb} == [0-9]* ]]; then
-				wb=0
-			elif [[ -n ${cb} ]]; then
-				wb=9
-			else
-				wb=6
-			fi
-		elif [[ ${sb} == . ]]; then
-			wb=10
-		elif [[ ${sb} == _ ]]; then
-			case ${cb} in
-				alpha) wb=2 ;;
-				beta) wb=3 ;;
-				rc) wb=4 ;;
-				pre) wb=5 ;;
-				p) wb=8 ;;
-				*) die "Invalid version suffix: _${cb}";;
-			esac
-		elif [[ ${sb} == - ]]; then
-			[[ ${cb} == r ]] || die "Invalid version part: -${cb}"
-			wb=7
-		fi
-
-		# DEBUG
-		#echo "$sa $ca [$wa] <$m> $sb $cb [$wb]" >&2
-
-		# 3. compare weights, we can proceed further only if weights match
-		if [[ ${wa} -ne ${wb} ]]; then
-			result=$(( wa - wb ))
-			break
-		fi
-
-		# 4. both empty maybe?
-		[[ -z ${ca} && -z ${cb} ]] && break
-
-		# 5. compare components according to the algo
-
-		# weird numeric is weird and reuses pn/l, so do it first
-		# (PMS algo 3.3)
-		if [[ ${m} == wn ]]; then
-			if [[ ${ca} != 0* && ${cb} != 0* ]]; then
-				# if neither of them starts with 0, use normal numeric
-				m=pn
-			else
-				# strip trailing zeros
-				while [[ ${ca} == *0 ]]; do ca=${ca::-1}; done
-				while [[ ${cb} == *0 ]]; do cb=${cb::-1}; done
-				m=l
-			fi
-		fi
-
-		case ${m} in
-			pn) # plain numeric
-				if [[ 10#${ca} -ne 10#${cb} ]]; then
-					result=$(( 10#${ca} - 10#${cb} ))
-					break
-				fi
-				;;
-			l) # lexical
-				if [[ ${ca} != ${cb} ]]; then
-					[[ ${ca} > ${cb} ]] && result=1 || result=-1
-					break
-				fi
-				;;
-			'') ;;
-			*) die "Unexpected comparison method m=${m}";;
-		esac
-	done
-
-	test "${result}" "${op}" 0
+	_ver_compare "${va}" "${vb}"
+	test $? "${op}" 2
 }

diff --git a/eclass/tests/eapi7-ver_benchmark.sh b/eclass/tests/eapi7-ver_benchmark.sh
index b1e3ccb78ae..c4671371336 100755
--- a/eclass/tests/eapi7-ver_benchmark.sh
+++ b/eclass/tests/eapi7-ver_benchmark.sh
@@ -78,7 +78,7 @@ replacing_versionator() {
 
 comparing() {
 	local x
-	for x in {1..500}; do
+	for x in {1..1000}; do
 		ver_test 1b_p1 -le 1_p1
 		ver_test 1.1b -le 1.1
 		ver_test 12.2.5 -le 12.2b
@@ -143,5 +143,5 @@ get_times 1 cutting
 get_times 10 cutting_versionator
 get_times 1 replacing
 get_times 10 replacing_versionator
-get_times 2 comparing
+get_times 1 comparing
 get_times 10 comparing_versionator


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-09-21 12:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-21  7:04 [gentoo-commits] repo/gentoo:eapi7-ver commit in: eclass/, eclass/tests/ Michał Górny
  -- strict thread matches above, loose matches on Subject: below --
2017-09-21 12:57 Ulrich Müller
2017-09-06 15:22 Michał Górny
2017-09-06 13:40 Michał Górny
2017-09-06 13:40 Michał Górny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox