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