<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Copyright (C) 2001-2018 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see &lt;https://www.gnu.org/licenses/&gt;.

package Automake::Version;

use 5.006;
use strict;
use Automake::ChannelDefs;

=head1 NAME

Automake::Version - version comparison

=head1 SYNOPSIS

  use Automake::Version;

  print "Version $version is older than required version $required\n"
    if Automake::Version::check ($version, $required);

=head1 DESCRIPTION

This module provides support for comparing versions string
as they are used in Automake.

A version is a string that looks like
C&lt;MAJOR.MINOR[.MICRO][ALPHA][-FORK]&gt; where C&lt;MAJOR&gt;, C&lt;MINOR&gt;, and
C&lt;MICRO&gt; are digits, C&lt;ALPHA&gt; is a character, and C&lt;FORK&gt; any
alphanumeric word.

Usually, C&lt;ALPHA&gt; is used to label alpha releases or intermediate
snapshots, C&lt;FORK&gt; is used for git branches or patched releases, and
C&lt;MICRO&gt; is used for bug fixes releases on the C&lt;MAJOR.MINOR&gt; branch.

For the purpose of ordering, C&lt;1.4&gt; is the same as C&lt;1.4.0&gt;, but
C&lt;1.4g&gt; is the same as C&lt;1.4.99g&gt;.  The C&lt;FORK&gt; identifier is ignored
in the ordering, except when it looks like C&lt;-pMINOR[ALPHA]&gt;: some
versions were labeled like C&lt;1.4-p3a&gt;, this is the same as an alpha
release labeled C&lt;1.4.3a&gt;.  Yes, it's horrible, but Automake did not
support two-dot versions in the past.

=head2 FUNCTIONS

=over 4

=item C&lt;split ($version)&gt;

Split the string C&lt;$version&gt; into the corresponding C&lt;(MAJOR, MINOR,
MICRO, ALPHA, FORK)&gt; tuple.  For instance C&lt;'1.4g'&gt; would be split
into C&lt;(1, 4, 99, 'g', '')&gt;.  Return C&lt;()&gt; on error.

=cut

sub split ($)
{
  my ($ver) = @_;

  # 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 ();
}

=item C&lt;compare (\@LVERSION, \@RVERSION)&gt;

Compare two version tuples, as returned by C&lt;split&gt;.

Return 1, 0, or -1, if C&lt;LVERSION&gt; is found to be respectively
greater than, equal to, or less than C&lt;RVERSION&gt;.

=cut

sub compare (\@\@)
{
  my @l = @{$_[0]};
  my @r = @{$_[1]};

  for my $i (0, 1, 2)
  {
    return 1  if ($l[$i] &gt; $r[$i]);
    return -1 if ($l[$i] &lt; $r[$i]);
  }
  for my $i (3, 4)
  {
    return 1  if ($l[$i] gt $r[$i]);
    return -1 if ($l[$i] lt $r[$i]);
  }
  return 0;
}

=item C&lt;check($VERSION, $REQUIRED)&gt;

Handles the logic of requiring a version number in Automake.
C&lt;$VERSION&gt; should be Automake's version, while C&lt;$REQUIRED&gt;
is the version required by the user input.

Return 0 if the required version is satisfied, 1 otherwise.

=cut

sub check ($$)
{
  my ($version, $required) = @_;
  my @version = Automake::Version::split ($version);
  my @required = Automake::Version::split ($required);

  prog_error "version is incorrect: $version"
    if $#version == -1;

  # This should not happen, because process_option_list and split_version
  # use similar regexes.
  prog_error "required version is incorrect: $required"
    if $#required == -1;

  # If we require 3.4n-foo then we require something
  # &gt;= 3.4n, with the 'foo' fork identifier.
  return 1
    if ($required[4] ne '' &amp;&amp; $required[4] ne $version[4]);

  return 0 &gt; compare (@version, @required);
}

1;
</pre></body></html>