<commit_before># Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

use strict;
use warnings;

use lib '../clownfish/perl/blib/arch';
use lib '../clownfish/perl/blib/lib';
use lib 'clownfish/perl/blib/arch';
use lib 'clownfish/perl/blib/lib';

package Lucy::Build;

# We want to subclass Clownfish::CFC::Perl::Build, but Clownfish might not be
# built yet. So we look in 'clownfish/perl/lib' directly and cleanup @INC
# afterwards.
use lib '../clownfish/perl/lib';
use lib 'clownfish/perl/lib';
use base qw( Clownfish::CFC::Perl::Build );
no lib '../clownfish/perl/lib';
no lib 'clownfish/perl/lib';

our $VERSION = '0.003000';
$VERSION = eval $VERSION;

use File::Spec::Functions qw( catdir catfile updir rel2abs );
use File::Path qw( rmtree );
use File::Copy qw( move );
use Config;
use Env qw( @PATH );
use Carp;
use Cwd qw( getcwd );

BEGIN { unshift @PATH, rel2abs( getcwd() ) }

my @BASE_PATH = __PACKAGE__->cf_base_path;

my $CHARMONIZER_ORIG_DIR = catdir( @BASE_PATH, 'charmonizer' );
my $CHARMONIZE_EXE_PATH  = "charmonize$Config{_exe}";
my $CHARMONY_PATH  = 'charmony.h';
my $LEMON_DIR      = catdir( @BASE_PATH, 'lemon' );
my $LEMON_EXE_PATH = catfile( $LEMON_DIR, "lemon$Config{_exe}" );
my $CORE_SOURCE_DIR = catdir( @BASE_PATH, 'core' );
my $CLOWNFISH_DIR = catdir( @BASE_PATH, 'clownfish', 'perl' );
my $CLOWNFISH_BUILD  = catfile( $CLOWNFISH_DIR, 'Build' );
my $LIB_DIR          = 'lib';

sub new {
    my $self = shift->SUPER::new( recursive_test_files => 1, @_ );

    if ( $ENV{LUCY_VALGRIND} ) {
        my $optimize = $self->config('optimize') || '';
        $optimize =~ s/\-O\d+/-O1/g;
        $self->config( optimize => $optimize );
    }

    my $extra_ccflags = $self->extra_compiler_flags;
    if ( $self->config('gccversion') ) {
        if ( $Config{osname} =~ /openbsd/i && !$Config{usethreads} ) {
            push @$extra_ccflags, '-DLUCY_NOTHREADS';
        }
        if ( defined $ENV{LUCY_VALGRIND} ) {
            push @$extra_ccflags, qw( -DLUCY_VALGRIND -fno-inline-functions );
        }
        elsif ( defined $ENV{LUCY_DEBUG} ) {
            push @$extra_ccflags, qw(
                -DLUCY_DEBUG -pedantic -Wall -Wextra -Wno-variadic-macros
            );
        }
    }
    $self->extra_compiler_flags(@$extra_ccflags);

    $self->clownfish_params( autogen_header => $self->autogen_header );

    return $self;
}

sub _run_make {
    my ( $self, %params ) = @_;
    my @command           = @{ $params{args} };
    my $dir               = $params{dir};
    my $current_directory = getcwd();
    chdir $dir if $dir;
    unshift @command, 'CC=' . $self->config('cc');
    if ( $self->config('cc') =~ /^cl\b/ ) {
        unshift @command, "-f", "Makefile.MSVC";
    }
    elsif ( $^O =~ /mswin/i ) {
        unshift @command, "-f", "Makefile.MinGW";
    }
    unshift @command, "$Config{make}";
    system(@command) and confess("$Config{make} failed");
    chdir $current_directory if $dir;
}

# Build the charmonize executable.
sub ACTION_charmonize {
    my $self = shift;
    print "Building $CHARMONIZE_EXE_PATH...\n\n";
    my $meld_c = rel2abs("charmonize.c");
    $self->add_to_cleanup($meld_c);
    $self->add_to_cleanup($CHARMONIZE_EXE_PATH);
    my $charmonize_main = catfile( $CHARMONIZER_ORIG_DIR, 'charmonize.c' );
    $self->_run_make(
        dir  => $CHARMONIZER_ORIG_DIR,
        args => [ "meld", "PERL=$^X", "FILES=$charmonize_main", "OUT=$meld_c" ],
    );
    if ( !$self->up_to_date( $meld_c, $CHARMONIZE_EXE_PATH ) ) {
        my $cc = $Config{cc};
        my $outflag = $cc =~ /cl\b/ ? "/Fe" : "-o ";
        system("$cc $meld_c $outflag$CHARMONIZE_EXE_PATH")
            and die "Failed to compile $CHARMONIZE_EXE_PATH";
    }
}

# Run the charmonize executable, creating the charmony.h file.
sub ACTION_charmony {
    my $self = shift;
    $self->dispatch('charmonize');
    return if $self->up_to_date( $CHARMONIZE_EXE_PATH, $CHARMONY_PATH );
    print "\nWriting $CHARMONY_PATH...\n\n";

    # Clean up after charmonize if it doesn't succeed on its own.
    $self->add_to_cleanup("_charm*");
    $self->add_to_cleanup($CHARMONY_PATH);

    # Prepare arguments to charmonize.
    my @command = (
        $CHARMONIZE_EXE_PATH,
        '--cc=' . _quotify( $self->config('cc') ),
        '--enable-c',
        '--enable-perl',
        '--',
        $self->config('ccflags'),
        @{ $self->extra_compiler_flags },
    );
    if ( $ENV{CHARM_VALGRIND} ) {
        unshift @command, "valgrind", "--leak-check=yes";
    }
    print join( " ", @command ), $/;

    system(@command) and die "Failed to write $CHARMONY_PATH: $!";
}

sub _quotify {
    my $string = shift;
    $string =~ s/\\/\\\\/g;
    $string =~ s/"/\\"/g;
    return qq|"$string"|;
}

# Build the charmonizer tests.
sub ACTION_charmonizer_tests {
    my $self = shift;
    $self->dispatch('charmony');
    print "Building Charmonizer Tests...\n\n";
    my $flags = join( " ",
        $self->config('ccflags'),<commit_msg>Add Charmony.pm to cleanup<commit_after># Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

use strict;
use warnings;

use lib '../clownfish/perl/blib/arch';
use lib '../clownfish/perl/blib/lib';
use lib 'clownfish/perl/blib/arch';
use lib 'clownfish/perl/blib/lib';

package Lucy::Build;

# We want to subclass Clownfish::CFC::Perl::Build, but Clownfish might not be
# built yet. So we look in 'clownfish/perl/lib' directly and cleanup @INC
# afterwards.
use lib '../clownfish/perl/lib';
use lib 'clownfish/perl/lib';
use base qw( Clownfish::CFC::Perl::Build );
no lib '../clownfish/perl/lib';
no lib 'clownfish/perl/lib';

our $VERSION = '0.003000';
$VERSION = eval $VERSION;

use File::Spec::Functions qw( catdir catfile updir rel2abs );
use File::Path qw( rmtree );
use File::Copy qw( move );
use Config;
use Env qw( @PATH );
use Carp;
use Cwd qw( getcwd );

BEGIN { unshift @PATH, rel2abs( getcwd() ) }

my @BASE_PATH = __PACKAGE__->cf_base_path;

my $CHARMONIZER_ORIG_DIR = catdir( @BASE_PATH, 'charmonizer' );
my $CHARMONIZE_EXE_PATH  = "charmonize$Config{_exe}";
my $CHARMONY_H_PATH      = 'charmony.h';
my $CHARMONY_PM_PATH     = 'Charmony.pm';
my $LEMON_DIR      = catdir( @BASE_PATH, 'lemon' );
my $LEMON_EXE_PATH = catfile( $LEMON_DIR, "lemon$Config{_exe}" );
my $CORE_SOURCE_DIR = catdir( @BASE_PATH, 'core' );
my $CLOWNFISH_DIR = catdir( @BASE_PATH, 'clownfish', 'perl' );
my $CLOWNFISH_BUILD  = catfile( $CLOWNFISH_DIR, 'Build' );
my $LIB_DIR          = 'lib';

sub new {
    my $self = shift->SUPER::new( recursive_test_files => 1, @_ );

    if ( $ENV{LUCY_VALGRIND} ) {
        my $optimize = $self->config('optimize') || '';
        $optimize =~ s/\-O\d+/-O1/g;
        $self->config( optimize => $optimize );
    }

    my $extra_ccflags = $self->extra_compiler_flags;
    if ( $self->config('gccversion') ) {
        if ( $Config{osname} =~ /openbsd/i && !$Config{usethreads} ) {
            push @$extra_ccflags, '-DLUCY_NOTHREADS';
        }
        if ( defined $ENV{LUCY_VALGRIND} ) {
            push @$extra_ccflags, qw( -DLUCY_VALGRIND -fno-inline-functions );
        }
        elsif ( defined $ENV{LUCY_DEBUG} ) {
            push @$extra_ccflags, qw(
                -DLUCY_DEBUG -pedantic -Wall -Wextra -Wno-variadic-macros
            );
        }
    }
    $self->extra_compiler_flags(@$extra_ccflags);

    $self->clownfish_params( autogen_header => $self->autogen_header );

    return $self;
}

sub _run_make {
    my ( $self, %params ) = @_;
    my @command           = @{ $params{args} };
    my $dir               = $params{dir};
    my $current_directory = getcwd();
    chdir $dir if $dir;
    unshift @command, 'CC=' . $self->config('cc');
    if ( $self->config('cc') =~ /^cl\b/ ) {
        unshift @command, "-f", "Makefile.MSVC";
    }
    elsif ( $^O =~ /mswin/i ) {
        unshift @command, "-f", "Makefile.MinGW";
    }
    unshift @command, "$Config{make}";
    system(@command) and confess("$Config{make} failed");
    chdir $current_directory if $dir;
}

# Build the charmonize executable.
sub ACTION_charmonize {
    my $self = shift;
    print "Building $CHARMONIZE_EXE_PATH...\n\n";
    my $meld_c = rel2abs("charmonize.c");
    $self->add_to_cleanup($meld_c);
    $self->add_to_cleanup($CHARMONIZE_EXE_PATH);
    my $charmonize_main = catfile( $CHARMONIZER_ORIG_DIR, 'charmonize.c' );
    $self->_run_make(
        dir  => $CHARMONIZER_ORIG_DIR,
        args => [ "meld", "PERL=$^X", "FILES=$charmonize_main", "OUT=$meld_c" ],
    );
    if ( !$self->up_to_date( $meld_c, $CHARMONIZE_EXE_PATH ) ) {
        my $cc = $Config{cc};
        my $outflag = $cc =~ /cl\b/ ? "/Fe" : "-o ";
        system("$cc $meld_c $outflag$CHARMONIZE_EXE_PATH")
            and die "Failed to compile $CHARMONIZE_EXE_PATH";
    }
}

# Run the charmonize executable, creating the charmony.h file.
sub ACTION_charmony {
    my $self = shift;
    $self->dispatch('charmonize');
    return if $self->up_to_date( $CHARMONIZE_EXE_PATH, [
        $CHARMONY_H_PATH, $CHARMONY_PM_PATH,
    ] );
    print "\nRunning $CHARMONIZE_EXE_PATH...\n\n";

    # Clean up after charmonize if it doesn't succeed on its own.
    $self->add_to_cleanup("_charm*");
    $self->add_to_cleanup($CHARMONY_H_PATH);
    $self->add_to_cleanup($CHARMONY_PM_PATH);

    # Prepare arguments to charmonize.
    my @command = (
        $CHARMONIZE_EXE_PATH,
        '--cc=' . _quotify( $self->config('cc') ),
        '--enable-c',
        '--enable-perl',
        '--',
        $self->config('ccflags'),
        @{ $self->extra_compiler_flags },
    );
    if ( $ENV{CHARM_VALGRIND} ) {
        unshift @command, "valgrind", "--leak-check=yes";
    }
    print join( " ", @command ), $/;

    system(@command) and die "Failed to run $CHARMONIZE_EXE_PATH: $!";
}

sub _quotify {
    my $string = shift;
    $string =~ s/\\/\\\\/g;
    $string =~ s/"/\\"/g;
    return qq|"$string"|;
}

# Build the charmonizer tests.
sub ACTION_charmonizer_tests {
    my $self = shift;
    $self->dispatch('charmony');
    print "Building Charmonizer Tests...\n\n";
    my $flags = join( " ",
        $self->config('ccflags'),
{'fraction_non_alphanumeric': 0.15490757615204373, 'fraction_numerical': 0.0027770545864792156, 'mean_word_length': 3.1025275898896405, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4092674', 'n_tokens_mistral': 4255, 'n_tokens_neox': 4131, 'n_words': 1001}