<commit_before>package ModPerl::FunctionMap;

use strict;
use warnings FATAL => 'all';
use ModPerl::MapUtil qw();
use ModPerl::ParseSource ();

our @ISA = qw(ModPerl::MapBase);

sub new {
    my $class = shift;
    bless {}, $class;
}

#for adding to function.map
sub generate {
    my $self = shift;

    my $missing = $self->check;
    return unless $missing;

    print " $_\n" for @$missing;
}

sub disabled { shift->{disabled} }

#look for functions that do not exist in *.map
sub check {
    my $self = shift;
    my $map = $self->get;

    my @missing;
    my $mp_func = ModPerl::ParseSource->wanted_functions;

    for my $name (map $_->{name}, @{ $self->function_table() }) {
        next if exists $map->{$name};
        push @missing, $name unless $name =~ /^($mp_func)/o;
    }

    return @missing ? \@missing : undef;
}

#look for functions in *.map that do not exist
my $special_name = qr{(^DEFINE_|DESTROY$)};

sub check_exists {
    my $self = shift;

    my %functions = map { $_->{name}, 1 } @{ $self->function_table() };
    my @missing = ();

    for my $name (keys %{ $self->{map} }) {
        next if $functions{$name};
        push @missing, $name unless $name =~ $special_name;
    }

    return @missing ? \@missing : undef;
}

my $keywords = join '|', qw(MODULE PACKAGE PREFIX BOOT);

sub guess_prefix {
    my $entry = shift;

    my($name, $class) = ($entry->{name}, $entry->{class});
    my $prefix = "";
    $name =~ s/^DEFINE_//;
    $name =~ s/^mpxs_//i;

    (my $guess = lc($entry->{class} || $entry->{module}) . '_') =~ s/::/_/g;
    $guess =~ s/(apache)_/($1|ap)_{1,2}/;

    if ($name =~ s/^($guess).*/$1/i) {
        $prefix = $1;
    }
    else {
        if ($name =~ /^(apr?_)/) {
            $prefix = $1;
        }
    }

    #print "GUESS prefix=$guess, name=$entry->{name} -> $prefix\n";

    return $prefix;
}

sub parse {
    my($self, $fh, $map) = @_;
    my %cur;
    my $disabled = 0;

    while ($fh->readline) {
        if (/($keywords)=/o) {
            $disabled = s/^\W//; #module is disabled
            my %words = $self->parse_keywords($_);

            if ($words{MODULE}) {
                %cur = ();
            }

            if ($words{PACKAGE}) {
                delete $cur{CLASS};
            }

            for (keys %words) {
                $cur{$_} = $words{$_};
            }

            next;
        }

        my($name, $dispatch, $argspec, $alias) = split /\s*\|\s*/;
        my $return_type;

        if ($name =~ s/^([^:]+)://) {
            $return_type = $1;
        }<commit_msg>allow trailing space after the return type definition, to make it easier to align function declarations in the map file PR: Obtained from: Submitted by: Reviewed by:<commit_after>package ModPerl::FunctionMap;

use strict;
use warnings FATAL => 'all';
use ModPerl::MapUtil qw();
use ModPerl::ParseSource ();

our @ISA = qw(ModPerl::MapBase);

sub new {
    my $class = shift;
    bless {}, $class;
}

#for adding to function.map
sub generate {
    my $self = shift;

    my $missing = $self->check;
    return unless $missing;

    print " $_\n" for @$missing;
}

sub disabled { shift->{disabled} }

#look for functions that do not exist in *.map
sub check {
    my $self = shift;
    my $map = $self->get;

    my @missing;
    my $mp_func = ModPerl::ParseSource->wanted_functions;

    for my $name (map $_->{name}, @{ $self->function_table() }) {
        next if exists $map->{$name};
        push @missing, $name unless $name =~ /^($mp_func)/o;
    }

    return @missing ? \@missing : undef;
}

#look for functions in *.map that do not exist
my $special_name = qr{(^DEFINE_|DESTROY$)};

sub check_exists {
    my $self = shift;

    my %functions = map { $_->{name}, 1 } @{ $self->function_table() };
    my @missing = ();

    for my $name (keys %{ $self->{map} }) {
        next if $functions{$name};
        push @missing, $name unless $name =~ $special_name;
    }

    return @missing ? \@missing : undef;
}

my $keywords = join '|', qw(MODULE PACKAGE PREFIX BOOT);

sub guess_prefix {
    my $entry = shift;

    my($name, $class) = ($entry->{name}, $entry->{class});
    my $prefix = "";
    $name =~ s/^DEFINE_//;
    $name =~ s/^mpxs_//i;

    (my $guess = lc($entry->{class} || $entry->{module}) . '_') =~ s/::/_/g;
    $guess =~ s/(apache)_/($1|ap)_{1,2}/;

    if ($name =~ s/^($guess).*/$1/i) {
        $prefix = $1;
    }
    else {
        if ($name =~ /^(apr?_)/) {
            $prefix = $1;
        }
    }

    #print "GUESS prefix=$guess, name=$entry->{name} -> $prefix\n";

    return $prefix;
}

sub parse {
    my($self, $fh, $map) = @_;
    my %cur;
    my $disabled = 0;

    while ($fh->readline) {
        if (/($keywords)=/o) {
            $disabled = s/^\W//; #module is disabled
            my %words = $self->parse_keywords($_);

            if ($words{MODULE}) {
                %cur = ();
            }

            if ($words{PACKAGE}) {
                delete $cur{CLASS};
            }

            for (keys %words) {
                $cur{$_} = $words{$_};
            }

            next;
        }

        my($name, $dispatch, $argspec, $alias) = split /\s*\|\s*/;
        my $return_type;

        if ($name =~ s/^([^:]+)://) {
            $return_type = $1;
            $return_type =~ s/\s+$//;  # allow: char *    :....
        }
{'fraction_non_alphanumeric': 0.19209145427286356, 'fraction_numerical': 0.003373313343328336, 'mean_word_length': 2.0796306982111945, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1176205', 'n_tokens_mistral': 1945, 'n_tokens_neox': 1848, 'n_words': 480}