Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 373661
Collapse All | Expand All

(-)/var/portage/eclass/versionator.eclass (-57 / +199 lines)
Lines 315-381 version_is_at_least() { Link Here
315
version_compare() {
315
version_compare() {
316
	eshopts_push -s extglob
316
	eshopts_push -s extglob
317
	local ver_a=${1} ver_b=${2} parts_a parts_b cur_idx_a=0 cur_idx_b=0
317
	local ver_a=${1} ver_b=${2} parts_a parts_b cur_idx_a=0 cur_idx_b=0
318
	local cur_tok_a cur_tok_b num_part_a num_part_b prev_idx_a prev_idx_b
318
	parts_a=( $(get_all_version_components "${ver_a}" ) )
319
	parts_a=( $(get_all_version_components "${ver_a}" ) )
319
	parts_b=( $(get_all_version_components "${ver_b}" ) )
320
	parts_b=( $(get_all_version_components "${ver_b}" ) )
320
321
321
	### compare number parts.
322
	### compare number parts.
322
	local inf_loop=0
323
	local inf_loop=0
323
	while true ; do
324
	while true ; do
324
		inf_loop=$(( ${inf_loop} + 1 ))
325
		(( inf_loop++ ))
325
		[[ ${inf_loop} -gt 20 ]] && \
326
		(( inf_loop > 20 )) && \
326
			die "versionator compare bug [numbers, ${ver_a}, ${ver_b}]"
327
			die "versionator compare bug [numbers, ${ver_a}, ${ver_b}]"
327
328
329
		# Store the current index to test later
330
		prev_idx_a=$cur_idx_a
331
		prev_idx_b=$cur_idx_b
332
328
		# grab the current number components
333
		# grab the current number components
329
		local cur_tok_a=${parts_a[${cur_idx_a}]}
334
		cur_tok_a=${parts_a[cur_idx_a]}
330
		local cur_tok_b=${parts_b[${cur_idx_b}]}
335
		cur_tok_b=${parts_b[cur_idx_b]}
331
336
332
		# number?
337
		# number?
333
		if [[ -n ${cur_tok_a} ]] && [[ -z ${cur_tok_a//[[:digit:]]} ]] ; then
338
		if [[ -n ${cur_tok_a} ]] && [[ -z ${cur_tok_a//[[:digit:]]} ]] ; then
334
			cur_idx_a=$(( ${cur_idx_a} + 1 ))
339
			(( cur_idx_a++ ))
335
			[[ ${parts_a[${cur_idx_a}]} == "." ]] \
340
			[[ ${parts_a[cur_idx_a]} == "." ]] \
336
				&& cur_idx_a=$(( ${cur_idx_a} + 1 ))
341
				&& (( cur_idx_a++ ))
337
		else
342
		else
338
			cur_tok_a=""
343
			cur_tok_a=""
339
		fi
344
		fi
340
345
341
		if [[ -n ${cur_tok_b} ]] && [[ -z ${cur_tok_b//[[:digit:]]} ]] ; then
346
		if [[ -n ${cur_tok_b} ]] && [[ -z ${cur_tok_b//[[:digit:]]} ]] ; then
342
			cur_idx_b=$(( ${cur_idx_b} + 1 ))
347
			(( cur_idx_b++ ))
343
			[[ ${parts_b[${cur_idx_b}]} == "." ]] \
348
			[[ ${parts_b[cur_idx_b]} == "." ]] \
344
				&& cur_idx_b=$(( ${cur_idx_b} + 1 ))
349
				&& (( cur_idx_b++ ))
345
		else
350
		else
346
			cur_tok_b=""
351
			cur_tok_b=""
347
		fi
352
		fi
348
353
349
		# done with number components?
354
		# done with number components?
350
		[[ -z ${cur_tok_a} ]] && [[ -z ${cur_tok_b} ]] && break
355
		[[ -z ${cur_tok_a} && -z ${cur_tok_b} ]] && break
351
356
352
		# to avoid going into octal mode, strip any leading zeros. otherwise
357
		# if a component is blank, then it is the lesser value
353
		# bash will throw a hissy fit on versions like 6.3.068.
358
		[[ -z ${cur_tok_a} ]] && eshopts_pop && return 1
354
		cur_tok_a=${cur_tok_a##+(0)}
359
		[[ -z ${cur_tok_b} ]] && eshopts_pop && return 3
355
		cur_tok_b=${cur_tok_b##+(0)}
360
356
361
		# According to PMS, if we are *not* in the first number part, and either
357
		# if a component is blank, make it zero.
362
		# token begins with "0", then we use a different algorithm (that
358
		[[ -z ${cur_tok_a} ]] && cur_tok_a=0
363
		# effectively does floating point comparison)
359
		[[ -z ${cur_tok_b} ]] && cur_tok_b=0
364
		if [[ ${prev_idx_a} != 0 && ${prev_idx_b} != 0 ]] \
360
365
			&& [[ ${cur_tok_a} == 0* || ${cur_tok_b} == 0* ]] ; then
361
		# compare
366
362
		[[ ${cur_tok_a} -lt ${cur_tok_b} ]] && eshopts_pop && return 1
367
			# strip trailing zeros
363
		[[ ${cur_tok_a} -gt ${cur_tok_b} ]] && eshopts_pop && return 3
368
			cur_tok_a=${cur_tok_a%%+(0)}
369
			cur_tok_b=${cur_tok_b%%+(0)}
370
371
			# do a *string* comparison of the resulting values: 2 > 11
372
			[[ ${cur_tok_a} < ${cur_tok_b} ]] && eshopts_pop && return 1
373
			[[ ${cur_tok_a} > ${cur_tok_b} ]] && eshopts_pop && return 3
374
		else
375
			# to avoid going into octal mode, strip any leading zeros. otherwise
376
			# bash will throw a hissy fit on versions like 6.3.068.
377
			cur_tok_a=${cur_tok_a##+(0)}
378
			cur_tok_b=${cur_tok_b##+(0)}
379
380
			# now if a component is blank, it was originally 0 -- make it so
381
			: ${cur_tok_a:=0}
382
			: ${cur_tok_b:=0}
383
384
			# compare
385
			(( cur_tok_a < cur_tok_b )) && eshopts_pop && return 1
386
			(( cur_tok_a > cur_tok_b )) && eshopts_pop && return 3
387
		fi
364
	done
388
	done
365
389
366
	### number parts equal. compare letter parts.
390
	### number parts equal. compare letter parts.
367
	local letter_a=
391
	local letter_a=
368
	letter_a=${parts_a[${cur_idx_a}]}
392
	letter_a=${parts_a[cur_idx_a]}
369
	if [[ ${#letter_a} -eq 1 ]] && [[ -z ${letter_a/[a-z]} ]] ; then
393
	if [[ ${#letter_a} -eq 1 ]] && [[ -z ${letter_a/[a-z]} ]] ; then
370
		cur_idx_a=$(( ${cur_idx_a} + 1 ))
394
		(( cur_idx_a++ ))
371
	else
395
	else
372
		letter_a="@"
396
		letter_a="@"
373
	fi
397
	fi
374
398
375
	local letter_b=
399
	local letter_b=
376
	letter_b=${parts_b[${cur_idx_b}]}
400
	letter_b=${parts_b[cur_idx_b]}
377
	if [[ ${#letter_b} -eq 1 ]] && [[ -z ${letter_b/[a-z]} ]] ; then
401
	if [[ ${#letter_b} -eq 1 ]] && [[ -z ${letter_b/[a-z]} ]] ; then
378
		cur_idx_b=$(( ${cur_idx_b} + 1 ))
402
		(( cur_idx_b++ ))
379
	else
403
	else
380
		letter_b="@"
404
		letter_b="@"
381
	fi
405
	fi
Lines 385-422 version_compare() { Link Here
385
	[[ ${letter_a} > ${letter_b} ]] && eshopts_pop && return 3
409
	[[ ${letter_a} > ${letter_b} ]] && eshopts_pop && return 3
386
410
387
	### letter parts equal. compare suffixes in order.
411
	### letter parts equal. compare suffixes in order.
388
	local suffix rule part r_lt r_gt
412
	inf_loop=0
389
	for rule in "alpha=1" "beta=1" "pre=1" "rc=1" "p=3" "r=3" ; do
413
	while true ; do
390
		suffix=${rule%%=*}
414
		(( inf_loop++ ))
391
		r_lt=${rule##*=}
415
		(( inf_loop > 20 )) && \
392
		[[ ${r_lt} -eq 1 ]] && r_gt=3 || r_gt=1
416
			die "versionator compare bug [numbers, ${ver_a}, ${ver_b}]"
393
417
		[[ ${parts_a[cur_idx_a]} == "_" ]] && (( cur_idx_a++ ))
394
		local suffix_a=
418
		[[ ${parts_b[cur_idx_b]} == "_" ]] && (( cur_idx_b++ ))
395
		for part in ${parts_a[@]} ; do
396
			[[ ${part#${suffix}} != ${part} ]] && \
397
				[[ -z ${part##${suffix}*([[:digit:]])} ]] && \
398
				suffix_a=${part#${suffix}}0
399
		done
400
419
401
		local suffix_b=
420
		cur_tok_a=${parts_a[cur_idx_a]}
402
		for part in ${parts_b[@]} ; do
421
		cur_tok_b=${parts_b[cur_idx_b]}
403
			[[ ${part#${suffix}} != ${part} ]] && \
422
		local num_part_a=0
404
				[[ -z ${part##${suffix}*([[:digit:]])} ]] && \
423
		local num_part_b=0
405
				suffix_b=${part#${suffix}}0
424
406
		done
425
		if has ${cur_tok_a%%+([0-9])} "alpha" "beta" "pre" "rc" "p"; then
426
			(( cur_idx_a++))
427
			num_part_a=${cur_tok_a##+([a-z])}
428
			# I don't like octal
429
			num_part_a=${num_part_a##+(0)}
430
			: ${num_part_a:=0}
431
			cur_tok_a=${cur_tok_a%%+([0-9])}
432
		else
433
			cur_tok_a=""
434
		fi
435
436
		if has ${cur_tok_b%%+([0-9])} alpha beta pre rc p; then
437
			(( cur_idx_b++))
438
			num_part_b=${cur_tok_b##+([a-z])}
439
			# I still don't like octal
440
			num_part_b=${num_part_b##+(0)}
441
			: ${num_part_b:=0}
442
			cur_tok_b=${cur_tok_b%%+([0-9])}
443
		else
444
			cur_tok_b=""
445
		fi
407
446
408
		[[ -z ${suffix_a} ]] && [[ -z ${suffix_b} ]] && continue
447
		if [[ ${cur_tok_a} != ${cur_tok_b} ]]; then
448
			local suffix
449
			for suffix in alpha beta pre rc "" p; do
450
				[[ ${cur_tok_a} == ${suffix} ]] && eshopts_pop && return 1
451
				[[ ${cur_tok_b} == ${suffix} ]] && eshopts_pop && return 3
452
			done
453
		elif [[ -z ${cur_tok_a} && -z ${cur_tok_b} ]]; then
454
			break
455
		else
456
			(( num_part_a < num_part_b )) && eshopts_pop && return 1
457
			(( num_part_a > num_part_b )) && eshopts_pop && return 3
458
		fi
459
	done
409
460
410
		[[ -z ${suffix_a} ]] && eshopts_pop && return ${r_gt}
461
	# At this point, the only thing that should be left is the -r# part
411
		[[ -z ${suffix_b} ]] && eshopts_pop && return ${r_lt}
462
	[[ ${parts_a[cur_idx_a]} == "-" ]] && (( cur_idx_a++ ))
463
	[[ ${parts_b[cur_idx_b]} == "-" ]] && (( cur_idx_b++ ))
464
465
	# Sanity check
466
	if [[ -n ${parts_a[cur_idx_a]} && ${parts_a[cur_idx_a]} != r+([0-9]) ]] || \
467
		[[ -n ${parts_b[cur_idx_b]} && ${parts_b[cur_idx_b]} != r+([0-9]) ]]; then
468
		die "versionator compare bug [numbers ${ver_a}, ${ver_b}]"
469
	fi
412
470
413
		# avoid octal problems
471
	num_part_a=${parts_a[cur_idx_a]#r}
414
		suffix_a=${suffix_a##+(0)} ; suffix_a=${suffix_a:-0}
472
	num_part_a=${num_part_a##+(0)}
415
		suffix_b=${suffix_b##+(0)} ; suffix_b=${suffix_b:-0}
473
	: ${num_part_a:=0}
474
	num_part_b=${parts_b[cur_idx_b]#r}
475
	num_part_b=${num_part_b##+(0)}
476
	: ${num_part_b:=0}
416
477
417
		[[ ${suffix_a} -lt ${suffix_b} ]] && eshopts_pop && return 1
478
	(( num_part_a < num_part_b )) && eshopts_pop && return 1
418
		[[ ${suffix_a} -gt ${suffix_b} ]] && eshopts_pop && return 3
479
	(( num_part_a > num_part_b )) && eshopts_pop && return 3
419
	done
420
480
421
	### no differences.
481
	### no differences.
422
	eshopts_pop
482
	eshopts_pop
Lines 470-475 version_format_string() { Link Here
470
530
471
__versionator__test_version_compare() {
531
__versionator__test_version_compare() {
472
	eshopts_push -s extglob
532
	eshopts_push -s extglob
533
473
	local lt=1 eq=2 gt=3 p q
534
	local lt=1 eq=2 gt=3 p q
474
535
475
	__versionator__test_version_compare_t() {
536
	__versionator__test_version_compare_t() {
Lines 507-513 __versionator__test_version_compare() { Link Here
507
		1.2.3         $lt 1.2.4
568
		1.2.3         $lt 1.2.4
508
		1.2.4         $gt 1.2.3
569
		1.2.4         $gt 1.2.3
509
570
510
		1.2.0         $eq 1.2
571
		1.2.0         $gt 1.2
511
		1.2.1         $gt 1.2
572
		1.2.1         $gt 1.2
512
		1.2           $lt 1.2.1
573
		1.2           $lt 1.2.1
513
574
Lines 531-537 __versionator__test_version_compare() { Link Here
531
		1.0_alpha6-r1 $gt 1.0_alpha6
592
		1.0_alpha6-r1 $gt 1.0_alpha6
532
		1.0_beta6-r1  $gt 1.0_alpha6-r2
593
		1.0_beta6-r1  $gt 1.0_alpha6-r2
533
594
534
		1.0_pre1      $lt 1.0-p1
595
		1.0_pre1      $lt 1.0_p1
535
596
536
		1.0p          $gt 1.0_p1
597
		1.0p          $gt 1.0_p1
537
		1.0r          $gt 1.0-r1
598
		1.0r          $gt 1.0-r1
Lines 544-550 __versionator__test_version_compare() { Link Here
544
	done
605
	done
545
606
546
607
547
	for q in "alpha beta pre rc=${lt};${gt}" "p r=${gt};${lt}" ; do
608
	for q in "alpha beta pre rc=${lt};${gt}" "p=${gt};${lt}" ; do
548
		for p in ${q%%=*} ; do
609
		for p in ${q%%=*} ; do
549
			local c=${q##*=}
610
			local c=${q##*=}
550
			local alt=${c%%;*} agt=${c##*;}
611
			local alt=${c%%;*} agt=${c##*;}
Lines 564-569 __versionator__test_version_compare() { Link Here
564
			__versionator__test_version_compare_t "1_${p}7"  $eq "1_${p}7"
625
			__versionator__test_version_compare_t "1_${p}7"  $eq "1_${p}7"
565
			__versionator__test_version_compare_t "1_${p}7"  $gt "1_${p}6"
626
			__versionator__test_version_compare_t "1_${p}7"  $gt "1_${p}6"
566
			__versionator__test_version_compare_t "1_${p}09" $eq "1_${p}9"
627
			__versionator__test_version_compare_t "1_${p}09" $eq "1_${p}9"
628
629
			__versionator__test_version_compare_t "1_${p}7-r0"  $eq "1_${p}7"
630
			__versionator__test_version_compare_t "1_${p}7-r0"  $lt "1_${p}7-r1"
631
			__versionator__test_version_compare_t "1_${p}7-r0"  $lt "1_${p}7-r01"
632
			__versionator__test_version_compare_t "1_${p}7-r01" $eq "1_${p}7-r1"
633
			__versionator__test_version_compare_t "1_${p}8-r1"  $gt "1_${p}7-r100"
634
635
			__versionator__test_version_compare_t "1_${p}_alpha" $lt "1_${p}_beta"
567
		done
636
		done
568
	done
637
	done
569
638
Lines 573-577 __versionator__test_version_compare() { Link Here
573
		__versionator__test_version_compare_t "7.2${p}3" $gt "7.2${p}2"
642
		__versionator__test_version_compare_t "7.2${p}3" $gt "7.2${p}2"
574
		__versionator__test_version_compare_t "7.2${p}2" $lt "7.2${p}3"
643
		__versionator__test_version_compare_t "7.2${p}2" $lt "7.2${p}3"
575
	done
644
	done
645
646
	# The following tests all come from portage's test cases:
647
	__versionator__test_version_compare_t "6.0" $gt "5.0"
648
	__versionator__test_version_compare_t "5.0" $gt "5"
649
	__versionator__test_version_compare_t "1.0-r1" $gt "1.0-r0"
650
	__versionator__test_version_compare_t "1.0-r1" $gt "1.0"
651
	__versionator__test_version_compare_t "999999999999999999999999999999" $gt "999999999999999999999999999998"
652
	__versionator__test_version_compare_t "1.0.0" $gt "1.0"
653
	__versionator__test_version_compare_t "1.0.0" $gt "1.0b"
654
	__versionator__test_version_compare_t "1b" $gt "1"
655
	__versionator__test_version_compare_t "1b_p1" $gt "1_p1"
656
	__versionator__test_version_compare_t "1.1b" $gt "1.1"
657
	__versionator__test_version_compare_t "12.2.5" $gt "12.2b"
658
659
	__versionator__test_version_compare_t "4.0" $lt "5.0"
660
	__versionator__test_version_compare_t "5" $lt "5.0"
661
	__versionator__test_version_compare_t "1.0_pre2" $lt "1.0_p2"
662
	__versionator__test_version_compare_t "1.0_alpha2" $lt "1.0_p2"
663
	__versionator__test_version_compare_t "1.0_alpha1" $lt "1.0_beta1"
664
	__versionator__test_version_compare_t "1.0_beta3" $lt "1.0_rc3"
665
	__versionator__test_version_compare_t "1.001000000000000000001" $lt "1.001000000000000000002"
666
	__versionator__test_version_compare_t "1.00100000000" $lt "1.0010000000000000001"
667
	__versionator__test_version_compare_t "999999999999999999999999999998" $lt "999999999999999999999999999999"
668
	__versionator__test_version_compare_t "1.01" $lt "1.1"
669
	__versionator__test_version_compare_t "1.0-r0" $lt "1.0-r1"
670
	__versionator__test_version_compare_t "1.0" $lt "1.0-r1"
671
	__versionator__test_version_compare_t "1.0" $lt "1.0.0"
672
	__versionator__test_version_compare_t "1.0b" $lt "1.0.0"
673
	__versionator__test_version_compare_t "1_p1" $lt "1b_p1"
674
	__versionator__test_version_compare_t "1" $lt "1b"
675
	__versionator__test_version_compare_t "1.1" $lt "1.1b"
676
	__versionator__test_version_compare_t "12.2b" $lt "12.2.5"
677
678
	__versionator__test_version_compare_t "4.0" $eq "4.0"
679
	__versionator__test_version_compare_t "1.0" $eq "1.0"
680
	__versionator__test_version_compare_t "1.0-r0" $eq "1.0"
681
	__versionator__test_version_compare_t "1.0" $eq "1.0-r0"
682
	__versionator__test_version_compare_t "1.0-r0" $eq "1.0-r0"
683
	__versionator__test_version_compare_t "1.0-r1" $eq "1.0-r1"
684
685
	# The following were just tests for != in portage, we need something a bit
686
	# more precise
687
	__versionator__test_version_compare_t "1" $lt "2"
688
	__versionator__test_version_compare_t "1.0_alpha" $lt "1.0_pre"
689
	__versionator__test_version_compare_t "1.0_beta" $gt "1.0_alpha"
690
	__versionator__test_version_compare_t "0" $lt "0.0"
691
	__versionator__test_version_compare_t "1.0-r0" $lt "1.0-r1"
692
	__versionator__test_version_compare_t "1.0-r1" $gt "1.0-r0"
693
	__versionator__test_version_compare_t "1.0" $lt "1.0-r1"
694
	__versionator__test_version_compare_t "1.0-r1" $gt "1.0"
695
	__versionator__test_version_compare_t "1_p1" $lt "1b_p1"
696
	__versionator__test_version_compare_t "1b" $gt "1"
697
	__versionator__test_version_compare_t "1.1b" $gt "1.1"
698
	__versionator__test_version_compare_t "12.2b" $gt "12.2"
699
700
	# The following tests all come from paludis's test cases:
701
	__versionator__test_version_compare_t "1.0" $gt "1"
702
	__versionator__test_version_compare_t "1" $lt "1.0"
703
	__versionator__test_version_compare_t "1.0_alpha" $gt "1_alpha"
704
	__versionator__test_version_compare_t "1.0_alpha" $gt "1"
705
	__versionator__test_version_compare_t "1.0_alpha" $lt "1.0"
706
	__versionator__test_version_compare_t "1.2.0.0_alpha7-r4" $gt "1.2_alpha7-r4"
707
708
	__versionator__test_version_compare_t "0001" $eq "1"
709
	__versionator__test_version_compare_t "01" $eq "001"
710
	__versionator__test_version_compare_t "0001.1" $eq "1.1"
711
	__versionator__test_version_compare_t "01.01" $eq "1.01"
712
	__versionator__test_version_compare_t "1.010" $eq "1.01"
713
	__versionator__test_version_compare_t "1.00" $eq "1.0"
714
	__versionator__test_version_compare_t "1.0100" $eq "1.010"
715
	__versionator__test_version_compare_t "1" $eq "1-r0"
716
	__versionator__test_version_compare_t "1-r00" $eq "1-r0"
717
576
	eshopts_pop
718
	eshopts_pop
577
}
719
}

Return to bug 373661