From 89cccefe5ddff1a60c3a9c5584e3ed6f4ddd7f00 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Wed, 20 Mar 2002 22:27:09 +0000 Subject: [PATCH] Add support for two-dot versions. * tests/version5.test: New file. * tests/Makefile.am (TESTS): Add it. * automake.in (version_split, version_compare): New functions. (version_check): Rewrite using version_split and version_compare. (process_option_list): Adjust regex. --- ChangeLog | 10 ++++ automake.in | 121 ++++++++++++++++++++++++++------------------ tests/Makefile.am | 1 + tests/version5.test | 82 ++++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 48 deletions(-) create mode 100755 tests/version5.test diff --git a/ChangeLog b/ChangeLog index f4ea9d79..060971e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2002-03-20 Alexandre Duret-Lutz + + Add support for two-dot versions. + + * tests/version5.test: New file. + * tests/Makefile.am (TESTS): Add it. + * automake.in (version_split, version_compare): New functions. + (version_check): Rewrite using version_split and version_compare. + (process_option_list): Adjust regex. + 2002-03-18 Richard Boulton Fix for PR automake/306: diff --git a/automake.in b/automake.in index c705d3d3..604941d5 100755 --- a/automake.in +++ b/automake.in @@ -1375,65 +1375,90 @@ sub generate_makefile ################################################################ -# A helper which handles the logic of requiring a version number in -# AUTOMAKE_OPTIONS. Return 1 on error, 0 on success. -sub version_check ($$$$) +# A version is a string that looks like +# MAJOR.MINOR[.MICRO][ALPHA][-FORK] +# where +# MAJOR, MINOR, and MICRO are digits, ALPHA is a character, and +# FORK any alphanumeric word. +# Usually, ALPHA is used to label alpha releases or intermediate snapshots, +# FORK is used for CVS branches or patched releases, and MICRO is used +# for bug fixes releases on the MAJOR.MINOR branch. +# +# For the purpose of ordering, 1.4 is the same as 1.4.0, but 1.4g is +# the same as 1.4.99g. The FORK identifier is ignored in the +# ordering, except when it looks like -pMINOR[ALPHA]: some versions +# were labelled like 1.4-p3a, this is the same as an alpha release +# labelled 1.4.3a. Yes it's horrible, but Automake did not support +# two-dot versions in the past. + +# version_split (VERSION) +# ----------------------- +# Split a version string into the corresponding (MAJOR, MINOR, MICRO, +# ALPHA, FORK) tuple. For instance "1.4g" would be split into +# (1, 4, 99, 'g', ''). +# Return () on error. +sub version_split ($) { - my ($rmajor, $rminor, $ralpha, $rfork) = ($1, $2, $3, $4); - - prog_error ("version is incorrect: $VERSION") - if $VERSION !~ /(\d+)\.(\d+)([a-z]?)-?([A-Za-z0-9]+)?/; - - my ($tmajor, $tminor, $talpha, $tfork) = ($1, $2, $3, $4); + my ($ver) = @_; - $rfork ||= ''; - $tfork ||= ''; + # Special case for versions like 1.4-p2a. + if ($ver =~ /^(\d+)\.(\d+)(?:-p(\d+)([a-z]+)?)$/) + { + return ($1, $2, $3, $4 || '', ''); + } + # Common case. + elsif ($ver =~ /^(\d+)\.(\d+)(?:\.(\d+))?([a-z])?(?:-([A-Za-z0-9]+))?$/) + { + return ($1, $2, $3 || (defined $4 ? 99 : 0), $4 || '', $5 || ''); + } + return (); +} - my $rminorminor = 0; - my $tminorminor = 0; +# version_compare (\@LVERSION, \@RVERSION) +# ---------------------------------------- +# Return 1 if LVERSION > RVERSION, +# -1 if LVERSION < RVERSION, +# 0 if LVERSION = RVERSION. +sub version_compare (\@\@) +{ + my @l = @{$_[0]}; + my @r = @{$_[1]}; - # Some versions were labelled like `1.4-p3a'. This is the same as - # an alpha release labelled `1.4.3a'. However, a version like - # `1.4g' is the same as `1.4.99g'. Yes, this sucks. Moral: - # always listen to the users. - if ($rfork =~ /p([0-9]+)([a-z]?)/) + for my $i (0, 1, 2) { - $rminorminor = $1; - # `1.4a-p3b' never existed. But we'll accept it anyway. - $ralpha = $ralpha || $2 || ''; - $rfork = ''; + return 1 if ($l[$i] > $r[$i]); + return -1 if ($l[$i] < $r[$i]); } - if ($tfork =~ /p([0-9]+)([a-z]?)/) + for my $i (3, 4) { - $tminorminor = $1; - # `1.4a-p3b' never existed. But we'll accept it anyway. - $talpha = $talpha || $2 || ''; - $tfork = ''; + return 1 if ($l[$i] gt $r[$i]); + return -1 if ($l[$i] lt $r[$i]); } + return 0; +} + +# Handles the logic of requiring a version number in AUTOMAKE_OPTIONS. +# Return 0 if the required version is satisfied, 1 otherwise. +sub version_check ($) +{ + my ($required) = @_; + my @version = version_split $VERSION; + my @required = version_split $required; + + prog_error ("version is incorrect: $VERSION") + if $#version == -1; - $rminorminor = 99 if $ralpha ne '' && $rminorminor == 0; - $tminorminor = 99 if $talpha ne '' && $tminorminor == 0; + # This should not happen, because process_option_list and split_version + # use similar regexes. + prog_error ("required version is incorrect: $required") + if $#required == -1; - # 2.0 is better than 1.0. - # 1.2 is better than 1.1. - # 1.2a is better than 1.2. # If we require 3.4n-foo then we require something # >= 3.4n, with the `foo' fork identifier. - # The $r* variables are what the user specified. - # The $t* variables denote automake itself. - if ($rmajor > $tmajor - || ($rmajor == $tmajor && $rminor > $tminor) - || ($rminor == $tminor && $rminor == $tminor - && $rminorminor > $tminorminor) - || ($rminor == $tminor && $rminor == $tminor - && $rminorminor == $tminorminor - && $ralpha gt $talpha) - || ($rfork ne '' && $rfork ne $tfork)) - { - return 1; - } + return 1 + if ($required[4] ne '' && $required[4] ne $version[4]); - return 0; + return 0 >= version_compare @version, @required; } # $BOOL @@ -1477,10 +1502,10 @@ sub process_option_list { $use_dependencies = 0; } - elsif (/(\d+)\.(\d+)([a-z]?)(-[A-Za-z0-9]+)?/) + elsif (/^\d+\.\d+(?:\.\d+)?[a-z]?(?:-[A-Za-z0-9]+)?$/) { # Got a version number. - if (version_check ($1, $2, $3, $4)) + if (version_check $&) { if ($config) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 80cc7a7f..b295919b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -349,6 +349,7 @@ version.test \ version2.test \ version3.test \ version4.test \ +version5.test \ vpath.test \ vtexi.test \ vtexi2.test \ diff --git a/tests/version5.test b/tests/version5.test new file mode 100755 index 00000000..e6331c54 --- /dev/null +++ b/tests/version5.test @@ -0,0 +1,82 @@ +#! /bin/sh + +# Exercise &version_compare. + +. $srcdir/defs || exit 1 + +set -e + +# FIXME: probably ought to let users override this like we do in `defs'. +amfile=../../automake + +sed 1q $amfile >>automake_tmp +cat << 'END' >> automake_tmp + +my $failed = 0; + +sub test_version_compare +{ + my ($left, $right, $result) = @_; + my @leftver = Automake::version_split ($left); + my @rightver = Automake::version_split ($right); + if ($#leftver == -1) + { + print "can't grok \"$left\"\n"; + $failed = 1; + return; + } + if ($#rightver == -1) + { + print "can't grok \"$right\"\n"; + $failed = 1; + return; + } + my $res = Automake::version_compare (\@leftver, \@rightver); + if ($res != $result) + { + print "version_compare (\"$left\", \"$right\") = $res! (not $result?)\n"; + $failed = 1; + } +} + +my @tests = ( +# basics + ['1.0', '2.0', -1], + ['2.0', '1.0', 1], + ['1.2', '1.2', 0], + ['1.1', '1.2', -1], + ['1.2', '1.1', 1], +# alphas + ['1.4', '1.4g', -1], + ['1.4g', '1.5', -1], + ['1.4g', '1.4', 1], + ['1.5', '1.4g', 1], + ['1.4a', '1.4g', -1], + ['1.5a', '1.3g', 1], + ['1.6a', '1.6a', 0], +# micros + ['1.5.1', '1.5', 1], + ['1.5.0', '1.5', 0], + ['1.5.4', '1.6.1', -1], +# micros and alphas + ['1.5a', '1.5.1', 1], + ['1.5a', '1.5.1a', 1], + ['1.5a', '1.5.1f', 1], + ['1.5', '1.5.1a', -1], + ['1.5.1a', '1.5.1f', -1], +# special exceptions + ['1.6-p5a', '1.6.5a', 0], + ['1.6', '1.6-p5a', -1], + ['1.6-p4b', '1.6-p5a', -1], + ['1.6-p4b', '1.6-foo', 1], + ['1.6-p4b', '1.6a-foo', -1] +); + +test_version_compare (@{$_}) foreach @tests; + +exit $failed; +END + +cat $amfile >>automake_tmp + +$PERL ./automake_tmp -- 2.43.5