#!/usr/bin/perl
#
# To compile lparse we need to check two things:
#   - Whether the system has -dl library, and
#   - The version of bison installed
#
use strict;

# Default values for install location and binaries:
my $INSTDIR = "/usr/local/bin";
my $CC = "g++";
my $BISON = "bison";
my $LEX = "flex";

my $debug_makefile = 0;
# Check arguments.
while (my $arg = shift) {
  if ($arg =~ /^--prefix=(.*)$/) {
    $INSTDIR = $1;
  } elsif ($arg =~ /--debug/) {
    $debug_makefile = 1;
  } elsif ($arg =~ /CC=(.*)$/) {
    $CC = $1;
  } elsif ($arg =~ /BISON=(.*)$/) {
    $BISON = $1;
  } elsif ($arg =~ /LEX=(.*)$/) {
    $LEX = $1;
  } else {
    die "usage: configure [CC=path] [BISON=path] [--prefix=installation_path] [--debug]\n";
  }
}


# The first step is to create a temporary file name using the method
# from PerlFAQ.
use IO::File;
use POSIX qw(tmpnam);
my $name;
do {
  $name = tmpnam();
} until (! (-e $name));

# Define autoflush for stdout
$| = 1;

# First, bison version:
print "Checking bison version ...";
`$BISON --version > $name`;
open IN, "$name" or die "Could not create a temporary file. Exiting ...\n";
my $bison_version;
my $bison_letter;
my $bison_found = 0;
while (<IN>) {
  if (/[Bb]ison[^0-9]*(([0-9.]+)([a-z]+)?)*\s*$/) {
    my $whole_version = $1;
    $bison_version = $2;
    $bison_letter = $3;
    print "$whole_version\n";
    $bison_found = 1;
  }
}
close IN;

# Remove tmpfile
unlink ($name);

if (!$bison_found) {
  print "not found\n";
  die "You need bison to compile lparse. Exiting ...\n";
}

my $new_bison = 0; 
if ($bison_version < 1.29) {
  $new_bison = 0;
} elsif (($bison_version eq "1.29") && ($bison_letter eq "a")) {
  $new_bison = 0;
} else {
  $new_bison = 1;
}

# Checking dynamic libraries
print "Checking whether -ldl works ...";
open OUT, ">$name.cc" or die "Cannot open a temporary file for writing";
print OUT "#include<dlfcn.h>\n";
print OUT "int main() { dlopen(\"foo\", RTLD_LAZY); }\n";
close OUT;
`$CC -o $name.out $name.cc -ldl 2> $name`;
my $no_dl = 0;
if ($?) {
  print "not found\n";
  $no_dl = 1;
} else {
  print "found\n";
}
unlink($name);
unlink("$name.out");
unlink("$name.cc");

# Creating the makefiles
print "Creating Makefile ...";
open OUT, ">Makefile" or die "Cannot open Makefile for writing\n";
print OUT "INSTALLATION_PATH=$INSTDIR\n";
close OUT;
`cat Makefile.base >> Makefile`;
print "done\n";

print "Creating src/Makefile ...";
open OUT, ">src/Makefile" or die "Cannot open src/Makefile for writing\n";
print OUT "CC = $CC\n";
print OUT "LEX = $LEX\n";
if ($new_bison) {
  print OUT "YACC = $BISON --defines=parse.cc.h\n";
} else {
  print OUT "YACC = $BISON -d\n";
}

if ($no_dl) {
  print OUT "DLFLAG = \n";
} else {
  print OUT "DLFLAG = -ldl\n";
}

if ($debug_makefile) {
  print OUT "CFLAGS=-g -Wall\n";
  print OUT "LDFLAGS=-g -Wall\n";
} else {
  print OUT "CFLAGS=-O3\n";
  print OUT "LDFLAGS=-O3\n";
}

close OUT;
`cat src/Makefile.base >> src/Makefile`;
print "done\n";

print "Creating src/config.h...";
`cp src/config.base src/config.h`;
open OUT, ">>src/config.h" or die "Cannot open src/config.h for writing\n";
print OUT "/* Define to 1 if you have the <dlfcn.h> header file. *\/\n";
if ($no_dl) {
  print OUT "// ";
}
print OUT "#define HAVE_DLFCN_H 1\n";
if ($no_dl) {
  print OUT "// ";
}
print OUT "/* Define to 1 if you have the `dl' library (-ldl). *\/\n";
if ($no_dl) {
  print OUT "#define HAVE_LIBDL 0\n";
} else {
  print OUT "#define HAVE_LIBDL 1\n";
}
close OUT;
print "done\n";
print "You can compile lparse now by typing 'make'.\n";
