#!/usr/bin/perl -w

use strict;
use Cwd;

my %ENTITY;

my $pwd = getcwd;
$ENTITY{"PWD"} = $pwd;
my $dirname = $pwd;
$dirname =~ s#.*/##;
$ENTITY{"DIRNAME"} = $dirname;
$ENTITY{"HTML"} = sprintf("file://%s/_html/index.html", $pwd);
$ENTITY{"DVI"} = sprintf("file://%s/_dvi/%s.dvi", $pwd, $dirname);

my $uname = `uname`;
chomp $uname;
$ENTITY{"UNAME"} = $uname;
$ENTITY{"UNAME.ABBREV"} = uc(substr($uname, 0, 1));

my $cflags = '-Wall -O2';
my $arch = `uname -m`;
chomp $arch;
if ($arch eq 'alpha')
{
  $cflags = '-Wall -O1';
}
elsif ($arch ne 'ppc' && $arch ne 'sparc64')
{
  $arch = 'i386';
  $cflags .= ' -march=i586';
}
$ENTITY{"ARCH"} = $arch;
$ENTITY{"CFLAGS"} = $cflags;
$ENTITY{"HOSTTYPE"} = "$uname/$arch";

$ENTITY{"OUT"} = "out/" . $arch;
$ENTITY{"TMP"} = "tmp/" . $arch;

my $cmd = 'readelf -l /bin/sh';
my $elfbase;
open(CMD, $cmd . '|') || die $cmd . ": $!";
while(<CMD>)
{
  if (m/^\s*LOAD\s+/)
  {
    my @number = split;

    # On FreeBSD/alpha the base address is a 64-bit address above 4GB.
    # At least one such machine runs a perl with 32-bit integer arithmetic. 
    # Thus we must handle the value as a string, not a number.
    $elfbase = $number[2];
    $ENTITY{"ELFBASE"} = $elfbase;
    last;
  }
}
close CMD;
die $cmd . ' returned no result.' if (!defined($elfbase));

my $elfmagic = $elfbase;
die "Last digit of ELF base address ($elfbase) is not zero"
unless ($elfmagic =~ s/0$/1/);
$ENTITY{"ELFMAGIC"} = $elfmagic;

open(SGML, '> config.sgml') || die "$!";
printf SGML "<!-- Generated by config.pl, do not edit. -->\n\n";
printf SGML "<!ENTITY %% calc SYSTEM \"%s/calc.sgml\">\n", $ENTITY{"OUT"};

open(MAK, '> config.mak') || die "$!";
print MAK "# Generated by config.pl, do not edit.\n\n";
open(CSH, '> config.csh') || die "$!";
print CSH "# Generated by config.pl, do not edit.\n\n";
open(SH, '> config.sh') || die "$!";
print SH "# Generated by config.pl, do not edit.\n\n";
for my $name(keys(%ENTITY))
{
  printf SGML "<!ENTITY config.%s \"%s\">\n", $name, $ENTITY{$name};
  printf MAK "%s=%s\n", $name, $ENTITY{$name};
  printf CSH "setenv %s '%s'\n", $name, $ENTITY{$name};
  printf SH "%s='%s'\n", $name, $ENTITY{$name};
}
close SH;
close CSH;
close MAK;
close SGML;
