#!/usr/bin/perl -w

eval 'exec perl -S $0 ${1+"$@"}'
    if 0;

# This script will create the Makefile to build and install CLC-INTERCAL

# This file is part of CLC-INTERCAL

# Copyright (c) 2008, 2023-2024 Claudio Calvelli, all rights reserved.

# CLC-INTERCAL is copyrighted software. However, permission to use, modify,
# and distribute it is granted provided that the conditions set out in the
# licence agreement are met. See files README and COPYING in the distribution.
;
use Cwd 'cwd';
use File::Path qw(make_path);
use File::Spec::Functions qw(catfile catdir);

use vars qw($VERSION $PERVERSION);
($VERSION) = ($PERVERSION = "CLC-INTERCAL/Base Makefile.PL 1.00") =~ /\s(\S+)$/;

require (catfile(cwd(), qw(INTERCAL Exporter.pm)));
require (catfile(cwd(), qw(INTERCAL InstallModule.pm)));

Language::INTERCAL::InstallModule::add_extra(
    manifest  => \&manifest,
    constants => \&constants,
    iacc_etc  => \&iacc_etc,
    postamble => \&postamble,
);

my $aux_dir = 'aux';
my $src_suffix = 'src';
my $prefix_suffix = 'prefix';

my @aux_src;
my @aux_prefix;

my $postpre = '$(INST_IOFILES)$(DFSEP)postpre.io';
my $iacc = '$(INST_IOFILES)$(DFSEP)iacc.io';
my $perl = '$(PERL) -I$(INST_ARCHLIB) -I$(INST_LIB)';
my $dstdir = catdir('blib', 'iofiles');

my ($nummodule, %nummodule) = Language::INTERCAL::InstallModule::module_search(
    'Numbers',
    ['Numbers-C.xs', undef, \&checknumbers],
    ['Numbers-perl.pm', undef, sub { 1 }],
);
print "Building arithmetic module: $nummodule\n";

import Language::INTERCAL::InstallModule $VERSION;
install Language::INTERCAL::InstallModule 'Base',
    link => \%nummodule,
    prereq => {
	'Carp' => 0,
	'Cwd' => 0,
	'File::Basename' => 0,
	'File::Spec' => 0,
	'Getopt::Long' => 0,
	'IO::File' => 0,
	'IO::Handle' => 0,
    },
    generate => 0;

# check if we can compile an XS
sub checknumbers {
    Language::INTERCAL::InstallModule::compile_check(<<'EOF');
int main(void) {
    return 0;
}
EOF
}

sub manifest {
    my ($iacc, $sick, $iasm) = @_;
    if (s#^$aux_dir/##o) {
	if (/^(.*)\.$src_suffix$/o) {
	    push @aux_src, $1;
	    push @$iacc, $1;
	}
	if (/^(.*)\.$prefix_suffix$/o) {
	    push @aux_prefix, $1;
	    push @$iacc, $1;
	}
    }
}

sub run {
    my ($prog, @args) = @_;
    my $path = catfile('aux', $prog);
    system($^X, $path, @args) == 0 and return;
    $? == -1 and die "$prog: $!\n";
    $? & 0x7f and die "$prog: terminated by signal " . ($? & 0x7f) . "\n";
    die "$prog @args: exit status " . ($? >> 8) . "\n";
}

sub constants {
    my $i = '';
    $i .= "INST_IOFILES = blib\$(DFSEP)iofiles\n";
    $i;
}

sub iacc_etc {
    my $i = '';
    $i .= <<EOF;
IACC_IO = -p$iacc
IACC_DEP = $iacc
POSTPRE_IO = --postpre $postpre
POSTPRE_DEP = $postpre

$postpre : pm_to_blib \$(INST_IOFILES)\$(DFSEP).exists aux\$(DFSEP)mkpostpre
	$perl aux\$(DFSEP)mkpostpre $postpre

$iacc : pm_to_blib \$(INST_IOFILES)\$(DFSEP).exists aux\$(DFSEP)mkfiles \$(INST_IOFILES)\$(DFSEP)iacc.src INTERCAL\$(DFSEP)Generate\$(DFSEP)ByteCode.Data
	$perl aux\$(DFSEP)mkfiles object \$(INST_IOFILES)\$(DFSEP)iacc.src $iacc

\$(INST_IOFILES)\$(DFSEP)asm.bc : \$(INST_IOFILES)\$(DFSEP).exists aux\$(DFSEP)mkasm INTERCAL\$(DFSEP)Generate\$(DFSEP)ByteCode.Data INTERCAL\$(DFSEP)Generate\$(DFSEP)Splats.Data
	\$(PERL) aux\$(DFSEP)mkasm \$(INST_IOFILES)\$(DFSEP)asm.bc

EOF

    $i;
}

sub postamble {
    my $i = '';

    $i .= "\$(INST_IOFILES)\$(DFSEP).exists :: Makefile.PL\n"
	. "\t\$(NOECHO) \$(MKPATH) \$(INST_IOFILES)\n"
	. "\t\$(NOECHO) \$(CHMOD) 755 \$(INST_IOFILES)\n"
	. "\t\$(NOECHO) \$(TOUCH) \$(INST_IOFILES)\$(DFSEP).exists\n\n";

    for my $generated (@aux_prefix) {
	my $gf = "\$(INST_IACC)\$(DFSEP)$generated.iacc";
	my $sf = "\$(INST_IOFILES)\$(DFSEP)$generated.src";
	my $pf = "aux\$(DFSEP)$generated.prefix";

	$i .= <<EOF;
$sf : \$(INST_IOFILES)\$(DFSEP)asm.bc $pf aux\$(DFSEP)joinfiles
	\$(PERL) aux\$(DFSEP)joinfiles $sf $pf \$(INST_IOFILES)\$(DFSEP)asm.bc

$gf : $sf aux\$(DFSEP)mkfiles
	\$(PERL) aux\$(DFSEP)mkfiles compiler $sf $gf

EOF
    }

    for my $sources (@aux_src) {
	my $gf = "\$(INST_IACC)\$(DFSEP)$sources.iacc";
	my $sf = "aux\$(DFSEP)$sources.src";
	$i .= <<EOF;

$gf : $sf aux\$(DFSEP)mkfiles
	\$(PERL) aux\$(DFSEP)mkfiles compiler $sf $gf

EOF
    }

    $i;
}

1;
