#! /usr/bin/env perl
# Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License").  You may not use
# this file except in compliance with the License.  You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html

package OpenSSL::Ordinals;

use strict;
use warnings;
use Carp;
use Scalar::Util qw(blessed);
use OpenSSL::Util;

use constant {
    # "magic" filters, see the filters at the end of the file
    F_NAME      => 1,
    F_NUMBER    => 2,
};

=head1 NAME

OpenSSL::Ordinals - a private module to read and walk through ordinals

=head1 SYNOPSIS

  use OpenSSL::Ordinals;

  my $ordinals = OpenSSL::Ordinals->new(from => "foo.num");
  # or alternatively
  my $ordinals = OpenSSL::Ordinals->new();
  $ordinals->load("foo.num");

  foreach ($ordinals->items(comparator => by_name()) {
    print $_->name(), "\n";
  }

=head1 DESCRIPTION

This is a OpenSSL private module to load an ordinals (F<.num>) file and
write out the data you want, sorted and filtered according to your rules.

An ordinals file is a file that enumerates all the symbols that a shared
library or loadable module must export.  Each of them have a unique
assigned number as well as other attributes to indicate if they only exist
on a subset of the supported platforms, or if they are specific to certain
features.

The unique numbers each symbol gets assigned needs to be maintained for a
shared library or module to stay compatible with previous versions on
platforms that maintain a transfer vector indexed by position rather than
by name.  They also help keep information on certain symbols that are
aliases for others for certain platforms, or that have different forms
on different platforms.

=head2 Main methods

=over  4

=cut

=item B<new> I<%options>

Creates a new instance of the C<OpenSSL::Ordinals> class.  It takes options
in keyed pair form, i.e. a series of C<< key => value >> pairs.  Available
options are:

=over 4

=item B<< from => FILENAME >>

Not only create a new instance, but immediately load it with data from the
ordinals file FILENAME.

=back

=cut

sub new {
    my $class = shift;
    my %opts = @_;

    my $instance = {
        filename        => undef, # File name registered when loading
        loaded_maxnum   => 0,     # Highest allocated item number when loading
        loaded_contents => [],    # Loaded items, if loading there was
        maxassigned     => 0,     # Current highest assigned item number
        maxnum          => 0,     # Current highest allocated item number
        contents        => [],    # Items, indexed by number
        name2num        => {},    # Name to number dictionary
        aliases         => {},    # Aliases cache.
        stats           => {},    # Statistics, see 'sub validate'
        debug           => $opts{debug},
    };
    bless $instance, $class;

    $instance->set_version($opts{version});
    $instance->load($opts{from}) if defined($opts{from});

    return $instance;
}

=item B<< $ordinals->load FILENAME >>

Loads the data from FILENAME into the instance.  Any previously loaded data
is dropped.

Two internal databases are created.  One database is simply a copy of the file
contents and is treated as read-only.  The other database is an exact copy of
the first, but is treated as a work database, i.e. it can be modified and added
to.

=cut

sub load {
    my $self = shift;
    my $filename = shift;

    croak "Undefined filename" unless defined($filename);

    my @tmp_contents = ();
    my %tmp_name2num = ();
    my $max_assigned = 0;
    my $max_num = 0;
    open F, '<', $filename or croak "Unable to open $filename";
    while (<F>) {
        s|\R$||;                # Better chomp
        s|#.*||;
        next if /^\s*$/;

        my $item = OpenSSL::Ordinals::Item->new(source => $filename, from => $_);

        my $num = $item->number();
        if ($num eq '?') {
            $num = ++$max_num;
        } elsif ($num eq '?+') {
            $num = $max_num;
        } else {
            croak "Disordered ordinals, number sequence restarted"
                if $max_num > $max_assigned && $num < $max_num;
            croak "Disordered ordinals, $num < $max_num"
                if $num < $max_num;
            $max_assigned = $max_num = $num;
        }

        $item->intnum($num);
        push @{$tmp_contents[$num]}, $item;
        $tmp_name2num{$item->name()} = $num;
    }
    close F;

    $self->{contents} = [ @tmp_contents ];
    $self->{name2num} = { %tmp_name2num };
    $self->{maxassigned} = $max_assigned;
    $self->{maxnum} = $max_num;
    $self->{filename} = $filename;

    # Make a deep copy, allowing {contents} to be an independent work array
    foreach my $i (1..$max_num) {
        if ($tmp_contents[$i]) {
            $self->{loaded_contents}->[$i] =
                [ map { OpenSSL::Ordinals::Item->new($_) }
                  @{$tmp_contents[$i]} ];
        }
    }
    $self->{loaded_maxnum} = $max_num;
    return 1;
}

=item B<< $ordinals->renumber >>

Renumber any item that doesn't have an assigned number yet.

=cut

sub renumber {
    my $self = shift;

    my $max_assigned = 0;
    foreach ($self->items(sort => by_number())) {
        $_->number($_->intnum()) if $_->number() =~ m|^\?|;
        if ($max_assigned < $_->number()) {
            $max_assigned = $_->number();
        }
    }
    $self->{maxassigned} = $max_assigned;
}

=item B<< $ordinals->rewrite >>

=item B<< $ordinals->rewrite >>, I<%options>

If an ordinals file has been loaded, it gets rewritten with the data from
the current work database.

If there are more arguments, they are used as I<%options> with the
same semantics as for B<< $ordinals->items >> described below, apart
from B<sort>, which is forbidden here.

=cut

sub rewrite {
    my $self = shift;
    my %opts = @_;

    $self->write($self->{filename}, %opts);
}

=item B<< $ordinals->write FILENAME >>

=item B<< $ordinals->write FILENAME >>, I<%options>

Writes the current work database data to the ordinals file FILENAME.
This also validates the data, see B<< $ordinals->validate >> below.

If there are more arguments, they are used as I<%options> with the
same semantics as for B<< $ordinals->items >> described next, apart
from B<sort>, which is forbidden here.

=cut

sub write {
    my $self = shift;
    my $filename = shift;
    my %opts = @_;

    croak "Undefined filename" unless defined($filename);
    croak "The 'sort' option is not allowed" if $opts{sort};

    $self->validate();

    open F, '>', $filename or croak "Unable to open $filename";
    foreach ($self->items(%opts, sort => by_number())) {
        print F $_->to_string(),"\n";
    }
    close F;
    $self->{filename} = $filename;
    $self->{loaded_maxnum} = $self->{maxnum};
    return 1;
}

=item B<< $ordinals->items >> I<%options>

Returns a list of items according to a set of criteria.  The criteria is
given in form keyed pair form, i.e. a series of C<< key => value >> pairs.
Available options are:

=over 4

=item B<< sort => SORTFUNCTION >>

SORTFUNCTION is a reference to a function that takes two arguments, which
correspond to the classic C<$a> and C<$b> that are available in a C<sort>
block.

=item B<< filter => FILTERFUNCTION >>

FILTERFUNCTION is a reference to a function that takes one argument, which
is every OpenSSL::Ordinals::Item element available.

=back

=cut

sub items {
    my $self = shift;
    my %opts = @_;

    my $comparator = $opts{sort};
    my $filter = $opts{filter} // sub { 1; };

    my @l = undef;
    if (ref($filter) eq 'ARRAY') {
        # run a "magic" filter
        if    ($filter->[0] == F_NUMBER) {
            my $index = $filter->[1];
            @l = $index ? @{$self->{contents}->[$index] // []} : ();
        } elsif ($filter->[0] == F_NAME) {
            my $index = $self->{name2num}->{$filter->[1]};
            @l = $index ? @{$self->{contents}->[$index] // []} : ();
        } else {
            croak __PACKAGE__."->items called with invalid filter";
        }
    } elsif (ref($filter) eq 'CODE') {
        @l = grep { $filter->($_) }
            map { @{$_ // []} }
            @{$self->{contents}};
    } else {
        croak __PACKAGE__."->items called with invalid filter";
    }

    return sort { $comparator->($a, $b); } @l
        if (defined $comparator);
    return @l;
}

# Put an array of items back into the object after having checked consistency
# If there are exactly two items:
# - They MUST have the same number
# - They MUST have the same version
# - For platforms, both MUST hold the same ones, but with opposite values
# - For features, both MUST hold the same ones.
# - They MUST NOT have identical name, type, numeral, version, platforms, and features
# If there's just one item, just put it in the slot of its number
# In all other cases, something is wrong
sub _putback {
    my $self = shift;
    my @items = @_;

    if (scalar @items < 1 || scalar @items > 2) {
        croak "Wrong number of items: ", scalar @items, "\n ",
            join("\n ", map { $_->{source}.": ".$_->name() } @items), "\n";
    }
    if (scalar @items == 2) {
        # Collect some data
        my %numbers = ();
        my %versions = ();
        my %features = ();
        foreach (@items) {
            $numbers{$_->intnum()} = 1;
            $versions{$_->version()} = 1;
            foreach ($_->features()) {
                $features{$_}++;
            }
        }

        # Check that all items we're trying to put back have the same number
        croak "Items don't have the same numeral: ",
            join(", ", map { $_->name()." => ".$_->intnum() } @items), "\n"
            if (scalar keys %numbers > 1);
        croak "Items don't have the same version: ",
            join(", ", map { $_->name()." => ".$_->version() } @items), "\n"
            if (scalar keys %versions > 1);

        # Check that both items run with the same features
        foreach (@items) {
        }
        foreach (keys %features) {
            delete $features{$_} if $features{$_} == 2;
        }
        croak "Features not in common between ",
            $items[0]->name(), " and ", $items[1]->name(), ":",
            join(", ", sort keys %features), "\n"
            if %features;

        # Check for in addition identical name, type, and platforms
        croak "Duplicate entries for ".$items[0]->name()." from ".
            $items[0]->source()." and ".$items[1]->source()."\n"
            if $items[0]->name() eq $items[1]->name()
            && $items[0]->type() eq $items[2]->type()
            && $items[0]->platforms() eq $items[1]->platforms();

        # Check that all platforms exist in both items, and have opposite values
        my @platforms = ( { $items[0]->platforms() },
                          { $items[1]->platforms() } );
        foreach my $platform (keys %{$platforms[0]}) {
            if (exists $platforms[1]->{$platform}) {
                if ($platforms[0]->{$platform} != !$platforms[1]->{$platform}) {
                    croak "Platforms aren't opposite: ",
                        join(", ",
                             map { my %tmp_h = $_->platforms();
                                   $_->name().":".$platform
                                       ." => "
                                       .$tmp_h{$platform} } @items),
                        "\n";
                }

                # We're done with these
                delete $platforms[0]->{$platform};
                delete $platforms[1]->{$platform};
            }
        }
        # If there are any remaining platforms, something's wrong
        if (%{$platforms[0]} || %{$platforms[0]}) {
            croak "There are platforms not in common between ",
                $items[0]->name(), " and ", $items[1]->name(), "\n";
        }
    }
    $self->{contents}->[$items[0]->intnum()] = [ @items ];
}

sub _parse_platforms {
    my $self = shift;
    my @defs = @_;

    my %platforms = ();
    foreach (@defs) {
        m{^(!)?};
        my $op = !(defined $1 && $1 eq '!');
        my $def = $';

        if ($def =~ m{^_?WIN32$})                   { $platforms{$&} = $op; }
        if ($def =~ m{^__FreeBSD__$})               { $platforms{$&} = $op; }
# For future support
#       if ($def =~ m{^__DragonFly__$})             { $platforms{$&} = $op; }
#       if ($def =~ m{^__OpenBSD__$})               { $platforms{$&} = $op; }
#       if ($def =~ m{^__NetBSD__$})                { $platforms{$&} = $op; }
        if ($def =~ m{^OPENSSL_SYS_})               { $platforms{$'} = $op; }
    }

    return %platforms;
}

sub _parse_features {
    my $self = shift;
    my @defs = @_;

    my %features = ();
    foreach (@defs) {
        m{^(!)?};
        my $op = !(defined $1 && $1 eq '!');
        my $def = $';

        if ($def =~ m{^ZLIB$})                      { $features{$&} =  $op; }
        if ($def =~ m{^OPENSSL_USE_})               { $features{$'} =  $op; }
        if ($def =~ m{^OPENSSL_NO_})                { $features{$'} = !$op; }
    }

    return %features;
}

sub _adjust_version {
    my $self = shift;
    my $version = shift;
    my $baseversion = $self->{baseversion};

    $version = $baseversion
        if ($baseversion ne '*' && $version ne '*'
            && cmp_versions($baseversion, $version) > 0);

    return $version;
}

=item B<< $ordinals->add SOURCE, NAME, TYPE, LIST >>

Adds a new item from file SOURCE named NAME with the type TYPE,
and a set of C macros in
LIST that are expected to be defined or undefined to use this symbol, if
any.  For undefined macros, they each must be prefixed with a C<!>.

If this symbol already exists in loaded data, it will be rewritten using
the new input data, but will keep the same ordinal number and version.
If it's entirely new, it will get a '?' and the current default version.

=cut

sub add {
    my $self = shift;
    my $source = shift;         # file where item was defined
    my $name = shift;
    my $type = shift;           # FUNCTION or VARIABLE
    my @defs = @_;              # Macros from #ifdef and #ifndef
                                # (the latter prefixed with a '!')

    # call signature for debug output
    my $verbsig = "add('$name' , '$type' , [ " . join(', ', @defs) . " ])";

    croak __PACKAGE__."->add got a bad type '$type'"
        unless $type eq 'FUNCTION' || $type eq 'VARIABLE';

    my %platforms = _parse_platforms(@defs);
    my %features = _parse_features(@defs);

    my @items = $self->items(filter => f_name($name));
    my $version = @items ? $items[0]->version() : $self->{currversion};
    my $intnum = @items ? $items[0]->intnum() : ++$self->{maxnum};
    my $number = @items ? $items[0]->number() : '?';
    print STDERR "DEBUG[",__PACKAGE__,":add] $verbsig\n",
        @items ? map { "\t".$_->to_string()."\n" } @items : "No previous items\n",
        if $self->{debug};
    @items = grep { $_->exists() } @items;

    my $new_item =
        OpenSSL::Ordinals::Item->new( source        => $source,
                                      name          => $name,
                                      type          => $type,
                                      number        => $number,
                                      intnum        => $intnum,
                                      version       =>
                                          $self->_adjust_version($version),
                                      exists        => 1,
                                      platforms     => { %platforms },
                                      features      => [
                                          grep { $features{$_} } keys %features
                                      ] );

    push @items, $new_item;
    print STDERR "DEBUG[",__PACKAGE__,"::add] $verbsig\n", map { "\t".$_->to_string()."\n" } @items
        if $self->{debug};
    $self->_putback(@items);

    # If an alias was defined beforehand, add an item for it now
    my $alias = $self->{aliases}->{$name};
    delete $self->{aliases}->{$name};

    # For the caller to show
    my @returns = ( $new_item );
    push @returns, $self->add_alias($source, $alias->{name}, $name, @{$alias->{defs}})
        if defined $alias;
    return @returns;
}

=item B<< $ordinals->add_alias SOURCE, ALIAS, NAME, LIST >>

Adds an alias ALIAS for the symbol NAME from file SOURCE, and a set of C macros
in LIST that are expected to be defined or undefined to use this symbol, if any.
For undefined macros, they each must be prefixed with a C<!>.

If this symbol already exists in loaded data, it will be rewritten using
the new input data.  Otherwise, the data will just be store away, to wait
that the symbol NAME shows up.

=cut

sub add_alias {
    my $self = shift;
    my $source = shift;
    my $alias = shift;          # This is the alias being added
    my $name  = shift;          # For this name (assuming it exists)
    my @defs = @_;              # Platform attributes for the alias

    # call signature for debug output
    my $verbsig =
        "add_alias('$source' , '$alias' , '$name' , [ " . join(', ', @defs) . " ])";

    croak "You're kidding me... $alias == $name" if $alias eq $name;

    my %platforms = _parse_platforms(@defs);
    my %features = _parse_features(@defs);

    croak "Alias with associated features is forbidden\n"
        if %features;

    my $f_byalias = f_name($alias);
    my $f_byname = f_name($name);
    my @items = $self->items(filter => $f_byalias);
    foreach my $item ($self->items(filter => $f_byname)) {
        push @items, $item unless grep { $_ == $item } @items;
    }
    @items = grep { $_->exists() } @items;

    croak "Alias already exists ($alias => $name)"
        if scalar @items > 1;
    if (scalar @items == 0) {
        # The item we want to alias for doesn't exist yet, so we cache the
        # alias and hope the item we're making an alias of shows up later
        $self->{aliases}->{$name} = { source => $source,
                                      name => $alias, defs => [ @defs ] };

        print STDERR "DEBUG[",__PACKAGE__,":add_alias] $verbsig\n",
            "\tSet future alias $alias => $name\n"
            if $self->{debug};
        return ();
    } elsif (scalar @items == 1) {
        # The rule is that an alias is more or less a copy of the original
        # item, just with another name.  Also, the platforms given here are
        # given to the original item as well, with opposite values.
        my %alias_platforms = $items[0]->platforms();
        foreach (keys %platforms) {
            $alias_platforms{$_} = !$platforms{$_};
        }
        # We supposedly do now know how to do this...  *ahem*
        $items[0]->{platforms} = { %alias_platforms };

        my $number =
            $items[0]->number() =~ m|^\?| ? '?+' : $items[0]->number();
        my $alias_item = OpenSSL::Ordinals::Item->new(
            source        => $source,
            name          => $alias,
            type          => $items[0]->type(),
            number        => $number,
            intnum        => $items[0]->intnum(),
            version       => $self->_adjust_version($items[0]->version()),
            exists        => $items[0]->exists(),
            platforms     => { %platforms },
            features      => [ $items[0]->features() ]
           );
        push @items, $alias_item;

        print STDERR "DEBUG[",__PACKAGE__,":add_alias] $verbsig\n",
            map { "\t".$_->to_string()."\n" } @items
            if $self->{debug};
        $self->_putback(@items);

        # For the caller to show
        return ( $alias_item->to_string() );
    }
    croak "$name has an alias already (trying to add alias $alias)\n",
        "\t", join(", ", map { $_->name() } @items), "\n";
}

=item B<< $ordinals->set_version VERSION >>

=item B<< $ordinals->set_version VERSION BASEVERSION >>

Sets the default version for new symbol to VERSION.

If given, BASEVERSION sets the base version, i.e. the minimum version
for all symbols.  If not given, it will be calculated as follows:

=over 4

If the given version is '*', then the base version will also be '*'.

If the given version starts with '0.', the base version will be '0.0.0'.

If the given version starts with '1.0.', the base version will be '1.0.0'.

If the given version starts with '1.1.', the base version will be '1.1.0'.

If the given version has a first number C<N> that's greater than 1, the
base version will be formed from C<N>: 'N.0.0'.

=back

=cut

sub set_version {
    my $self = shift;
    # '*' is for "we don't care"
    my $version = shift // '*';
    my $baseversion = shift // '*';

    if ($baseversion eq '*') {
        $baseversion = $version;
        if ($baseversion ne '*') {
            if ($baseversion =~ m|^(\d+)\.|, $1 > 1) {
                $baseversion = "$1.0.0";
            } else {
                $baseversion =~ s|^0\..*$|0.0.0|;
                $baseversion =~ s|^1\.0\..*$|1.0.0|;
                $baseversion =~ s|^1\.1\..*$|1.1.0|;

                die 'Invalid version'
                    if ($baseversion ne '0.0.0'
                        && $baseversion !~ m|^1\.[01]\.0$|);
            }
        }
    }

    die 'Invalid base version'
        if ($baseversion ne '*' && $version ne '*'
            && cmp_versions($baseversion, $version) > 0);

    $self->{currversion} = $version;
    $self->{baseversion} = $baseversion;
    foreach ($self->items(filter => sub { $_[0] eq '*' })) {
        $_->{version} = $self->{currversion};
    }
    return 1;
}

=item B<< $ordinals->invalidate >>

Invalidates the whole working database.  The practical effect is that all
symbols are set to not exist, but are kept around in the database to retain
ordinal numbers and versions.

=cut

sub invalidate {
    my $self = shift;

    foreach (@{$self->{contents}}) {
        foreach (@{$_ // []}) {
            $_->{exists} = 0;
        }
    }
    $self->{stats} = {};
}

=item B<< $ordinals->validate >>

Validates the current working database by collection statistics on how many
symbols were added and how many were changed.  These numbers can be retrieved
with B<< $ordinals->stats >>.

=cut

sub validate {
    my $self = shift;

    $self->{stats} = {};
    for my $i (1..$self->{maxnum}) {
        if ($i > $self->{loaded_maxnum}
                || (!@{$self->{loaded_contents}->[$i] // []}
                    && @{$self->{contents}->[$i] // []})) {
            $self->{stats}->{new}++;
        }
        if ($i <= $self->{maxassigned}) {
            $self->{stats}->{assigned}++;
        } else {
            $self->{stats}->{unassigned}++;
        }
        next if ($i > $self->{loaded_maxnum});

        my @loaded_strings =
            map { $_->to_string() } @{$self->{loaded_contents}->[$i] // []};
        my @current_strings =
            map { $_->to_string() } @{$self->{contents}->[$i] // []};

        foreach my $str (@current_strings) {
            @loaded_strings = grep { $str ne $_ } @loaded_strings;
        }
        if (@loaded_strings) {
            $self->{stats}->{modified}++;
        }
    }
}

=item B<< $ordinals->stats >>

Returns the statistics that B<validate> calculate.

=cut

sub stats {
    my $self = shift;

    return %{$self->{stats}};
}

=back

=head2 Data elements

Data elements, which is each line in an ordinals file, are instances
of a separate class, OpenSSL::Ordinals::Item, with its own methods:

=over 4

=cut

package OpenSSL::Ordinals::Item;

use strict;
use warnings;
use Carp;

=item B<new> I<%options>

Creates a new instance of the C<OpenSSL::Ordinals::Item> class.  It takes
options in keyed pair form, i.e. a series of C<< key => value >> pairs.
Available options are:

=over 4

=item B<< source => FILENAME >>, B<< from => STRING >>

This will create a new item from FILENAME, filled with data coming from STRING.

STRING must conform to the following EBNF description:

  ordinal string = symbol, spaces, ordinal, spaces, version, spaces,
                   exist, ":", platforms, ":", type, ":", features;
  spaces         = space, { space };
  space          = " " | "\t";
  symbol         = ( letter | "_" ), { letter | digit | "_" };
  ordinal        = number | "?" | "?+";
  version        = number, "_", number, "_", number, [ letter, [ letter ] ];
  exist          = "EXIST" | "NOEXIST";
  platforms      = platform, { ",", platform };
  platform       = ( letter | "_" ) { letter | digit | "_" };
  type           = "FUNCTION" | "VARIABLE";
  features       = feature, { ",", feature };
  feature        = ( letter | "_" ) { letter | digit | "_" };
  number         = digit, { digit };

(C<letter> and C<digit> are assumed self evident)

=item B<< source => FILENAME >>, B<< name => STRING >>, B<< number => NUMBER >>,
      B<< version => STRING >>, B<< exists => BOOLEAN >>, B<< type => STRING >>,
      B<< platforms => HASHref >>, B<< features => LISTref >>

This will create a new item with data coming from the arguments.

=back

=cut

sub new {
    my $class = shift;

    if (ref($_[0]) eq $class) {
        return $class->new( map { $_ => $_[0]->{$_} } keys %{$_[0]} );
    }

    my %opts = @_;

    croak "No argument given" unless %opts;

    my $instance = undef;
    if ($opts{from}) {
        my @a = split /\s+/, $opts{from};

        croak "Badly formatted ordinals string: $opts{from}"
            unless ( scalar @a == 4
                     && $a[0] =~ /^[A-Za-z_][A-Za-z_0-9]*$/
                     && $a[1] =~ /^\d+|\?\+?$/
                     && $a[2] =~ /^(?:\*|\d+_\d+_\d+[a-z]{0,2})$/
                     && $a[3] =~ /^
                                  (?:NO)?EXIST:
                                  [^:]*:
                                  (?:FUNCTION|VARIABLE):
                                  [^:]*
                                  $
                                 /x );

        my @b = split /:/, $a[3];
        %opts = ( source        => $opts{source},
                  name          => $a[0],
                  number        => $a[1],
                  version       => $a[2],
                  exists        => $b[0] eq 'EXIST',
                  platforms     => { map { m|^(!)?|; $' => !$1 }
                                         split /,/,$b[1] },
                  type          => $b[2],
                  features      => [ split /,/,$b[3] // '' ] );
    }

    if ($opts{name} && $opts{version} && defined $opts{exists} && $opts{type}
            && ref($opts{platforms} // {}) eq 'HASH'
            && ref($opts{features} // []) eq 'ARRAY') {
        my $version = $opts{version};
        $version =~ s|_|.|g;

        $instance = { source    => $opts{source},
                      name      => $opts{name},
                      type      => $opts{type},
                      number    => $opts{number},
                      intnum    => $opts{intnum},
                      version   => $version,
                      exists    => !!$opts{exists},
                      platforms => { %{$opts{platforms} // {}} },
                      features  => [ sort @{$opts{features} // []} ] };
    } else {
        croak __PACKAGE__."->new() called with bad arguments\n".
            join("", map { "    $_\t=> ".$opts{$_}."\n" } sort keys %opts);
    }

    return bless $instance, $class;
}

sub DESTROY {
}

=item B<< $item->name >>

The symbol name for this item.

=item B<< $item->number >> (read-write)

The positional number for this item.

This may be '?' for an unassigned symbol, or '?+' for an unassigned symbol
that's an alias for the previous symbol.  '?' and '?+' must be properly
handled by the caller.  The caller may change this to an actual number.

=item B<< $item->version >> (read-only)

The version number for this item.  Please note that these version numbers
have underscore (C<_>) as a separator for the version parts.

=item B<< $item->exists >> (read-only)

A boolean that tells if this symbol exists in code or not.

=item B<< $item->platforms >> (read-only)

A hash table reference.  The keys of the hash table are the names of
the specified platforms, with a value of 0 to indicate that this symbol
isn't available on that platform, and 1 to indicate that it is.  Platforms
that aren't mentioned default to 1.

=item B<< $item->type >> (read-only)

C<FUNCTION> or C<VARIABLE>, depending on what the symbol represents.
Some platforms do not care about this, others do.

=item B<< $item->features >> (read-only)

An array reference, where every item indicates a feature where this symbol
is available.  If no features are mentioned, the symbol is always available.
If any feature is mentioned, this symbol is I<only> available when those
features are enabled.

=cut

our $AUTOLOAD;

# Generic getter
sub AUTOLOAD {
    my $self = shift;
    my $funcname = $AUTOLOAD;
    (my $item = $funcname) =~ s|.*::||g;

    croak "$funcname called as setter" if @_;
    croak "$funcname invalid" unless exists $self->{$item};
    return $self->{$item} if ref($self->{$item}) eq '';
    return @{$self->{$item}} if ref($self->{$item}) eq 'ARRAY';
    return %{$self->{$item}} if ref($self->{$item}) eq 'HASH';
}

=item B<< $item->intnum >> (read-write)

Internal positional number.  If I<< $item->number >> is '?' or '?+', the
caller can use this to set a number for its purposes.
If I<< $item->number >> is a number, I<< $item->intnum >> should be the
same

=cut

# Getter/setters
sub intnum {
    my $self = shift;
    my $value = shift;
    my $item = 'intnum';

    croak "$item called with extra arguments" if @_;
    $self->{$item} = "$value" if defined $value;
    return $self->{$item};
}

sub number {
    my $self = shift;
    my $value = shift;
    my $item = 'number';

    croak "$item called with extra arguments" if @_;
    $self->{$item} = "$value" if defined $value;
    return $self->{$item};
}

=item B<< $item->to_string >>

Converts the item to a string that can be saved in an ordinals file.

=cut

sub to_string {
    my $self = shift;

    croak "Too many arguments" if @_;
    my %platforms = $self->platforms();
    my @features = $self->features();
    my $version = $self->version();
    $version =~ s|\.|_|g;
    return sprintf "%-39s %s\t%s\t%s:%s:%s:%s",
        $self->name(),
        $self->number(),
        $version,
        $self->exists() ? 'EXIST' : 'NOEXIST',
        join(',', (map { ($platforms{$_} ? '' : '!') . $_ }
                   sort keys %platforms)),
        $self->type(),
        join(',', @features);
}

=back

=head2 Comparators and filters

For the B<< $ordinals->items >> method, there are a few functions to create
comparators based on specific data:

=over 4

=cut

# Go back to the main package to create comparators and filters
package OpenSSL::Ordinals;

# Comparators...

=item B<by_name>

Returns a comparator that will compare the names of two OpenSSL::Ordinals::Item
objects.

=cut

sub by_name {
    return sub { $_[0]->name() cmp $_[1]->name() };
}

=item B<by_number>

Returns a comparator that will compare the ordinal numbers of two
OpenSSL::Ordinals::Item objects.

=cut

sub by_number {
    return sub { $_[0]->intnum() <=> $_[1]->intnum() };
}

=item B<by_version>

Returns a comparator that will compare the version of two
OpenSSL::Ordinals::Item objects.

=cut

sub by_version {
    return sub {
        # cmp_versions comes from OpenSSL::Util
        return cmp_versions($_[0]->version(), $_[1]->version());
    }
}

=back

There are also the following filters:

=over 4

=cut

# Filters...  these are called by grep, the return sub must use $_ for
# the item to check

=item B<f_version VERSION>

Returns a filter that only lets through symbols with a version number
matching B<VERSION>.

=cut

sub f_version {
    my $version = shift;

    croak "No version specified"
        unless $version && $version =~ /^\d+\.\d+\.\d+[a-z]{0,2}$/;

    return sub { $_[0]->version() eq $version };
}

=item B<f_number NUMBER>

Returns a filter that only lets through symbols with the ordinal number
matching B<NUMBER>.

NOTE that this returns a "magic" value that can not be used as a function.
It's only useful when passed directly as a filter to B<items>.

=cut

sub f_number {
    my $number = shift;

    croak "No number specified"
        unless $number && $number =~ /^\d+$/;

    return [ F_NUMBER, $number ];
}


=item B<f_name NAME>

Returns a filter that only lets through symbols with the symbol name
matching B<NAME>.

NOTE that this returns a "magic" value that can not be used as a function.
It's only useful when passed directly as a filter to B<items>.

=cut

sub f_name {
    my $name = shift;

    croak "No name specified"
        unless $name;

    return [ F_NAME, $name ];
}

=back

=head1 AUTHORS

Richard Levitte E<lt>levitte@openssl.orgE<gt>.

=cut

1;
