1 | # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
---|
2 |
|
---|
3 | # This program is free software; you can redistribute it and/or modify
|
---|
4 | # it under the terms of the GNU General Public License as published by
|
---|
5 | # the Free Software Foundation; either version 2, or (at your option)
|
---|
6 | # any later version.
|
---|
7 |
|
---|
8 | # This program is distributed in the hope that it will be useful,
|
---|
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
11 | # GNU General Public License for more details.
|
---|
12 |
|
---|
13 | # You should have received a copy of the GNU General Public License
|
---|
14 | # along with this program; if not, write to the Free Software
|
---|
15 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
---|
16 | # 02111-1307, USA.
|
---|
17 |
|
---|
18 | package Automake::Version;
|
---|
19 | use strict;
|
---|
20 | use Automake::ChannelDefs;
|
---|
21 |
|
---|
22 | =head1 NAME
|
---|
23 |
|
---|
24 | Automake::Version - version comparison
|
---|
25 |
|
---|
26 | =head1 SYNOPSIS
|
---|
27 |
|
---|
28 | use Automake::Version;
|
---|
29 |
|
---|
30 | print "Version $version is older than required version $required\n"
|
---|
31 | if Automake::Version::check ($version, $required);
|
---|
32 |
|
---|
33 | =head1 DESCRIPTION
|
---|
34 |
|
---|
35 | This module provides support for comparing versions string
|
---|
36 | as they are used in Automake.
|
---|
37 |
|
---|
38 | A version is a string that looks like
|
---|
39 | C<MAJOR.MINOR[.MICRO][ALPHA][-FORK]> where C<MAJOR>, C<MINOR>, and
|
---|
40 | C<MICRO> are digits, C<ALPHA> is a character, and C<FORK> any
|
---|
41 | alphanumeric word.
|
---|
42 |
|
---|
43 | Usually, C<ALPHA> is used to label alpha releases or intermediate
|
---|
44 | snapshots, C<FORK> is used for CVS branches or patched releases, and
|
---|
45 | C<MICRO> is used for bug fixes releases on the C<MAJOR.MINOR> branch.
|
---|
46 |
|
---|
47 | For the purpose of ordering, C<1.4> is the same as C<1.4.0>, but
|
---|
48 | C<1.4g> is the same as C<1.4.99g>. The C<FORK> identifier is ignored
|
---|
49 | in the ordering, except when it looks like C<-pMINOR[ALPHA]>: some
|
---|
50 | versions were labeled like C<1.4-p3a>, this is the same as an alpha
|
---|
51 | release labeled C<1.4.3a>. Yes, it's horrible, but Automake did not
|
---|
52 | support two-dot versions in the past.
|
---|
53 |
|
---|
54 | =head2 FUNCTIONS
|
---|
55 |
|
---|
56 | =over 4
|
---|
57 |
|
---|
58 | =item C<split ($version)>
|
---|
59 |
|
---|
60 | Split the string C<$version> into the corresponding C<(MAJOR, MINOR,
|
---|
61 | MICRO, ALPHA, FORK)> tuple. For instance C<'1.4g'> would be split
|
---|
62 | into C<(1, 4, 99, 'g', '')>. Return C<()> on error.
|
---|
63 |
|
---|
64 | =cut
|
---|
65 |
|
---|
66 | sub split ($)
|
---|
67 | {
|
---|
68 | my ($ver) = @_;
|
---|
69 |
|
---|
70 | # Special case for versions like 1.4-p2a.
|
---|
71 | if ($ver =~ /^(\d+)\.(\d+)(?:-p(\d+)([a-z]+)?)$/)
|
---|
72 | {
|
---|
73 | return ($1, $2, $3, $4 || '', '');
|
---|
74 | }
|
---|
75 | # Common case.
|
---|
76 | elsif ($ver =~ /^(\d+)\.(\d+)(?:\.(\d+))?([a-z])?(?:-([A-Za-z0-9]+))?$/)
|
---|
77 | {
|
---|
78 | return ($1, $2, $3 || (defined $4 ? 99 : 0), $4 || '', $5 || '');
|
---|
79 | }
|
---|
80 | return ();
|
---|
81 | }
|
---|
82 |
|
---|
83 | =item C<compare (\@LVERSION, \@RVERSION)>
|
---|
84 |
|
---|
85 | Compare two version tuples, as returned by C<split>.
|
---|
86 |
|
---|
87 | Return 1, 0, or -1, if C<LVERSION> is found to be respectively
|
---|
88 | greater than, equal to, or less than C<RVERSION>.
|
---|
89 |
|
---|
90 | =cut
|
---|
91 |
|
---|
92 | sub compare (\@\@)
|
---|
93 | {
|
---|
94 | my @l = @{$_[0]};
|
---|
95 | my @r = @{$_[1]};
|
---|
96 |
|
---|
97 | for my $i (0, 1, 2)
|
---|
98 | {
|
---|
99 | return 1 if ($l[$i] > $r[$i]);
|
---|
100 | return -1 if ($l[$i] < $r[$i]);
|
---|
101 | }
|
---|
102 | for my $i (3, 4)
|
---|
103 | {
|
---|
104 | return 1 if ($l[$i] gt $r[$i]);
|
---|
105 | return -1 if ($l[$i] lt $r[$i]);
|
---|
106 | }
|
---|
107 | return 0;
|
---|
108 | }
|
---|
109 |
|
---|
110 | =item C<check($VERSION, $REQUIRED)>
|
---|
111 |
|
---|
112 | Handles the logic of requiring a version number in Automake.
|
---|
113 | C<$VERSION> should be Automake's version, while C<$REQUIRED>
|
---|
114 | is the version required by the user input.
|
---|
115 |
|
---|
116 | Return 0 if the required version is satisfied, 1 otherwise.
|
---|
117 |
|
---|
118 | =cut
|
---|
119 |
|
---|
120 | sub check ($$)
|
---|
121 | {
|
---|
122 | my ($version, $required) = @_;
|
---|
123 | my @version = Automake::Version::split ($version);
|
---|
124 | my @required = Automake::Version::split ($required);
|
---|
125 |
|
---|
126 | prog_error "version is incorrect: $version"
|
---|
127 | if $#version == -1;
|
---|
128 |
|
---|
129 | # This should not happen, because process_option_list and split_version
|
---|
130 | # use similar regexes.
|
---|
131 | prog_error "required version is incorrect: $required"
|
---|
132 | if $#required == -1;
|
---|
133 |
|
---|
134 | # If we require 3.4n-foo then we require something
|
---|
135 | # >= 3.4n, with the `foo' fork identifier.
|
---|
136 | return 1
|
---|
137 | if ($required[4] ne '' && $required[4] ne $version[4]);
|
---|
138 |
|
---|
139 | return 0 > compare (@version, @required);
|
---|
140 | }
|
---|
141 |
|
---|
142 | 1;
|
---|
143 |
|
---|
144 | ### Setup "GNU" style for perl-mode and cperl-mode.
|
---|
145 | ## Local Variables:
|
---|
146 | ## perl-indent-level: 2
|
---|
147 | ## perl-continued-statement-offset: 2
|
---|
148 | ## perl-continued-brace-offset: 0
|
---|
149 | ## perl-brace-offset: 0
|
---|
150 | ## perl-brace-imaginary-offset: 0
|
---|
151 | ## perl-label-offset: -2
|
---|
152 | ## cperl-indent-level: 2
|
---|
153 | ## cperl-brace-offset: 0
|
---|
154 | ## cperl-continued-brace-offset: 0
|
---|
155 | ## cperl-label-offset: -2
|
---|
156 | ## cperl-extra-newline-before-brace: t
|
---|
157 | ## cperl-merge-trailing-else: nil
|
---|
158 | ## cperl-continued-statement-offset: 2
|
---|
159 | ## End:
|
---|