#!/bin/sh
exec perl -x -S $0 ${1+"$@"} # -*-perl-*-
#!perl -w

if ($] !~ /^5\..*/) {
  # uh-oh. this isn't perl 5.
  foreach (split(/:/, $ENV{PATH})) { # try to find "perl5".
    exec("$_/perl5", "-x", "-S", $0, @ARGV) if (-x "$_/perl5");
  }
  # we failed. bail.
  die "Your perl is too old; I need perl 5. See the README for what to do.\n";
}

# load the real script. this is isolated in an 'eval' so perl4 won't
# choke on the perl5-isms.
eval join("\n", <DATA>);
if ($@) { die "$@"; }
__END__
#
# itomf
#
#
# Generate Imakefiles for PDL tree in a friendly manner.
#
# Authors: Jim Zelenka, Marc Unangst, Tammo Spalink, Nat Lanza
#
#
# Copyright (c) of Carnegie Mellon University, 1997,1998,1999.
#
# Permission to reproduce, use, and prepare derivative works of
# this software for internal use is granted provided the copyright
# and "No Warranty" statements are included with all reproductions
# and derivative works. This software may also be redistributed
# without charge provided that the copyright and "No Warranty"
# statements are included in all redistributions.
#
# NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
# CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
# EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
# TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
# OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
# MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
# TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
#


require "stat.pl";
use DirHandle;
use Getopt::Std;

sub dir_exists {
	my($dirname) = @_;
	if (-d $dirname) {
		return(1);
	}
	else {
		return(0);
	}
}

sub exfile_exists {
	my ($filename) = @_;
	if (-x $filename) {
		return(1);
	}
	else {
		return(0);
	}
}

sub getenv {
	my($varname) = @_;
	my($lv);

	foreach $lv (keys %ENV) {
		if ($lv eq $varname) {
			return($ENV{$lv});
		}
	}
	return("");
}

sub read_profile {
    my($prof_name) = @_;

    open(PROFILE, "<$prof_name") || return;
    while(<PROFILE>) {
	eval;
	warn $@ if $@;
    }

    return;
}

sub print_usage {
	print STDERR "usage: ", $0, " [options]\n";
	print STDERR "options:\n";
	print STDERR "         -c  compile cheops clerk and manager\n";
	print STDERR "         -d  specify a destination directory (default ", $say_destdir, ")\n";
	print STDERR "         -D  force drive tip\n";
	print STDERR "         -h  print this usage message\n";
	print STDERR "         -K  build kernel modules\n";
	if ($need_kernel_dir) {
	print STDERR "         -k  specify a ", $kernel_tree_descrip, " (default ", $say_kdir, ")\n";
	}
	print STDERR "         -m  specify a makedepend (default ", $say_makedepend, ")\n";
	print STDERR "         -n  don't run anything, just print the imake command we would execute\n";
	print STDERR "         -p  set PDL build on or off (default ", $default_pdl?"on":"off", ")\n";
	print STDERR "         -r  specify rpc package (default ", $default_rpc, ")\n";
	print STDERR "         -s  force security\n";
	print STDERR "         -x  specify an X11 directory (default ", $say_x11cfgdir, ")\n";
	die "\n";
}

sub setup_kernel_vars {
	if($systype eq "OSF1") {
		$need_kernel_dir = 1;
		$kernel_tree_descrip = "kernel object tree";
		$kernel_tree_envvar = "PDL_KDIR_DUX";
	}

	if ($systype eq "Linux") {
		if ($build_kernel_modules) {
			$need_kernel_dir = 1;
			$kernel_tree_descrip = "kernel source tree";
			$kernel_tree_envvar = "PDL_KDIR_LINUX";
		}
	}

	if ($need_kernel_dir) {
		$kdir = getenv($kernel_tree_envvar);
		if ($systype eq "OSF1") {
			if (($kdir eq "") && getenv("PDL_KDIR")) {
				print STDERR "PDL_KDIR is deprecated, you probably want PDL_KDIR_DUX\n";
				die "\n";
			}
		}
		if ($kdir eq "") {
			$say_kdir = "NONE";
			# I'm a bad person. I'm a lazy person. I won't tell if you add
			# yourself here.
			if ($user eq "jimz\n") {
					if ($systype eq "Linux") {
						$kdir = "/usr16/jimz/linux";
						$say_kdir = $kdir;
					}
					elsif ($systype eq "OSF1") {
						$kdir = "/usr16/jimz/osf3c/obj/alpha/kernel";
						$say_kdir = $kdir;
					}
			}
			# badder than they oughtta be
			if ($user eq "er1p\n") {
				$kdir = "/usr19/er1p/osf3c/obj/alpha/kernel";
				$say_kdir = $kdir;
			}
			# not quite as bad as jim, but worse than erik
			if ($user eq "mju\n") {
				$kdir = "/usr14/mju/src/osf3c/obj/alpha/kernel";
				$say_kdir = $kdir;
			}
			# not bad, at all
			if ($user eq "amiri\n") {
				$kdir = "/usr25/hgobioff/osf3c.Jun30/obj/alpha/kernel";
				$say_kdir = $kdir;
			}
		}
		else {
			$say_kdir = $kdir;
		}
	}
}

# ------ begin main body

local ($opt_a, $opt_c, $opt_D, $opt_h, $opt_k, $opt_K, $opt_m, $opt_n, $opt_s, $opt_x);
local ($say_x11cfgdir, $say_kdir, $say_destdir, $say_makedepend, $s1, $st, $rpc, $default_rpc, $default_pdl);

$imake = "imake";

$default_rpc = "srpc";
$rpc = $default_rpc;
$rpc_val = "2";

$default_pdl = 0;

$s1 = `uname`;
chomp($systype = $s1);

$user = `whoami`;

$need_kernel_dir = 0;
$kernel_tree_descrip = "";
$build_kernel_modules = 0;

setup_kernel_vars();


if($systype eq "Linux") {
	$release = `cat /etc/redhat-release`;
	chomp $release;
	$release =~ /release\s+([.0-9]+)\s+\((\w+)\)/;
	$rh_ver = $1; $rh_name = $2;

	if ($rh_ver < 5) {
	  print "Your Redhat $rh_ver system is too old to compile NASD;n";
	  print "If you think this is really RH5.x or newer, check /etc/redhat-release.\n";
	  die "\n";
	}
}

if (dir_exists("/usr/lib/X11/config")) {
	$x11cfgdir = "/usr/lib/X11/config";
	$say_x11cfgdir = $x11cfgdir;
} elsif (dir_exists("/usr/local/lib/X11/config")) {
	$x11cfgdir = "/usr/local/lib/X11/config";
	$say_x11cfgdir = $x11cfgdir;
} elsif (dir_exists("/usr/X11R6/lib/X11/config")) {
	$x11cfgdir = "/usr/X11R6/lib/X11/config";
	$say_x11cfgdir = $x11cfgdir;
} elsif (dir_exists("/usr/misc/.X11/config")) {
	$x11cfgdir = "/usr/misc/.X11/config";
	$say_x11cfgdir = $x11cfgdir;
} elsif (dir_exists("/usr/openwin/lib/config")) {
	$x11cfgdir = "/usr/openwin/lib/config";
	$say_x11cfgdir = $x11cfgdir;
} else {
	$x11cfgdir = "";
	$say_x11cfgdir = "NONE";
}

if ($systype eq "Linux" && exfile_exists("/usr/bin/X11/gccmakedep")) {
	$makedepend = "/usr/bin/X11/gccmakedep";
	$say_makedepend = $makedepend;
} elsif ($systype eq "Linux" && exfile_exists("/usr/local/bin/gccmakedep")) {
	$makedepend = "/usr/local/bin/gccmakedep";
	$say_makedepend = $makedepend;
} elsif (exfile_exists("/usr/local/bin/makedepend")) {
	$makedepend = "/usr/local/bin/makedepend";
	$say_makedepend = $makedepend;
} elsif (exfile_exists("/usr/bin/X11/makedepend")) {
	$makedepend = "/usr/bin/X11/makedepend";
	$say_makedepend = $makedepend;
} elsif (exfile_exists("/usr/X11R6/bin/makedepend")) {
	$makedepend = "/usr/X11R6/bin/makedepend";
	$say_makedepend = $makedepend;
} elsif (exfile_exists("/usr/openwin/bin/makedepend")) {
	$makedepend = "/usr/openwin/bin/makedepend";
	$say_makedepend = $makedepend;
} else {
	$makedepend = "";
	$say_makedepend = "NONE";
}

$destdir = getenv("NASD_DESTDIR");
if ($destdir eq "") {
	$say_destdir = "NONE";
}
else {
	$say_destdir = $destdir;
}

#
# parse args
#

$opt_s = "";
$opt_D = "";
$opt_r = "";
$opt_p = "";

# read config file
read_profile("itomf.cfg");

# parse args
&print_usage unless getopts('a:cd:D:h:Kk:m:np:r:s:x:');

if ($opt_K) {
	$build_kernel_modules = 1;
}
else {
	$build_kernel_modules = 0;
}

setup_kernel_vars;

if ($opt_h) {
  &print_usage();
}

if ($opt_p eq "on") {
	$build_pdl_str = " -DBUILD_NASD_CMU_PDL=1";
	$say_build_pdl = "on";
}
else {
	if (($opt_p eq "0") || ($opt_p eq "off")) {
		$build_pdl_str = " -DBUILD_NASD_CMU_PDL=0";
		$say_build_pdl = "off";
	}
	else {
		if ($default_pdl) {
			$build_pdl_str = " -DBUILD_NASD_CMU_PDL=1";
			$say_build_pdl = "on";
		}
		else {
			$build_pdl_str = " -DBUILD_NASD_CMU_PDL=0";
			$say_build_pdl = "off";
		}
	}
}

if ($opt_k) {
	$kdir = $opt_k;
}

if ($opt_d) {
	$destdir = $opt_d;
}

if ($opt_x) {
	$x11cfgdir = $opt_x;
}

if ($opt_m) {
	$makedepend = $opt_m;
}

if ($opt_c) {
    $build_cheops = 1;
} else {
    $build_cheops = 0;
}

if ($opt_s) {
    $build_secure_str = " -DBUILD_SECURITY=1";
    $say_build_secure = "on";
}
else {
    if ($opt_s eq "0") {
      $build_secure_str = " -DBUILD_SECURITY=0";
      $say_build_secure = "off";
    }
    else {
      $build_secure_str = "";
      $say_build_secure = "default";
    }
}

if ($opt_D) {
    $build_dtip_str = " -DBUILD_DTIP=1";
    $say_build_dtip = "on";
}
else {
    if (defined $opt_D && $opt_D eq "0") {
      $build_dtip_str = " -DBUILD_DTIP=0";
      $say_build_dtip = "off";
    }
    else {
      $build_dtip_str = "";
      $say_build_dtip = "default";
    }
}

if ($opt_r) {
	if (($opt_r =~ "dce") || ($opt_r =~ "DCE")) {
		$rpc = "dce";
		$rpc_val = "1";
	}
	elsif ($opt_r =~ "srpc") {
		$rpc = "srpc";
		$rpc_val = "2";
	}
	elsif ($opt_r =~ "none") {
		$rpc = "none";
		$rpc_val = "3";
	}
	else {
		$rpc_val = "invalid rpc spec";
		print STDERR "Unknown RPC variant ", $opt_r, "\n";
		&print_usage;
	}
}

if ($destdir eq "") {
	$build_destdir_str = "";
}
else {
	$build_destdir_str = join("", " -DITOMF_NASD_DESTDIR=", $destdir);
}

#
# Check existence of configurable stuff
#

if (!$makedepend) {
	print STDERR "Error: no makedepend set\n";
	die "\n";
}
if (!exfile_exists($makedepend)) {
	print STDERR "Error: ", $makedepend, " does not exist or is not executable.\n";
	die "\n";
}

if (!$kdir && $need_kernel_dir) {
# I'm so bad, I have more than one source tree and I can never remember how to run 
# this damn program.    -david
	print STDERR "Error: ", $kernel_tree_envvar, " not set.\n";
	print STDERR "It should be set to point to a ", $kernel_tree_descrip, ".\n";
	if ($systype eq "OSF1") {
		print STDERR "Perhaps you want to run itomf -k /usrxx/yourname/yourkernel/obj/alpha/kernel ? \n";
	}
	die "\n";
}
if ($need_kernel_dir && !dir_exists($kdir)) {
	print STDERR "Error: ", $kdir, " does not exist or is not a directory.\n";
	die "\n";
}

if (!$x11cfgdir) {
	print STDERR "Error: no X11CFGDIR set\n";
	die "\n";
}
if (!dir_exists($x11cfgdir)) {
	print STDERR "Error: ", $x11cfgdir, " does not exist or is not a directory.\n";
	die "\n";
}


#
# figure out imake command
#

$build_kmod_str = "";

if ($systype eq "AIX") {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd` -DNASD_OSMajorVersion=`uname -v`";
} elsif ($systype eq "SunOS") {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd` -DNASD_OSMajorVersion=`uname -r | cut -d. -f1`";
} elsif ($systype eq "NetBSD" || $systype eq "FreeBSD") {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd`";
} elsif (($systype eq "IRIX") || ($systype eq "IRIX64")) {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd`";
} elsif ($systype eq "OSF1") {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DUseInstalledMotif";
} elsif ($systype eq "Mach") {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd`";
} elsif ($systype eq "Linux") {
	if ($build_kernel_modules) {
		$vstr = get_linux_version($kdir);
		@vstr_comp = split(/\./, $vstr);
		$vminstr = $vstr_comp[1];
		if ($vminstr < 2) {
			die "Kernel modules only supported on 2.2(+).x\n";
		}
		$build_kmod_str = "-DBUILD_NASD_KERNEL_MODULES=1";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd`";
} elsif ($systype eq "ULTRIX") {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd`";
} elsif ($systype eq "HP-UX") {
	if ($build_kernel_modules) {
		die "Kernel modules not supported on this platform\n";
	}
	$platform_imake_flags = "-DTOPDIR=. -DSCD_SRCTOP=`pwd`";
} else {
	print STDERR "Unknown system type ", $systype, ".\n";
	die "\n";
}

$imake_flags = join(" ", $platform_imake_flags, "-I./config -I$x11cfgdir -DUseInstalled -DNASD_ITOMF=1 -DNASD_X11CONFIGDIR=$x11cfgdir  -DBUILD_CHEOPS=$build_cheops -DNASD_MAKEDEPEND=$makedepend");

if ($kdir) {
	$tmp_imake_flags = $imake_flags;
	$imake_flags = join("", $tmp_imake_flags, " -DNASD_KDIR=", $kdir);
}

$build_rpc_str = join("", " -DBUILD_NASD_RPC_PACKAGE=", $rpc_val);

$cmd = join(" ", $imake, $imake_flags, $build_secure_str, $build_dtip_str, $build_rpc_str, $build_destdir_str, $build_kmod_str, $build_pdl_str);

#
# run imake
#

if (!defined($opt_n)) {
	print "Executing: ", $cmd, "\n";
	$st = system($cmd);
	if ($st) {
		print STDERR "\nFailed executing imake command. Sorry.\n";
		die "\n";
	}

	#
	# run make
	#

	if($systype eq "FreeBSD") {
	  $cmd = "gmake Makefiles";
	} else {
	  $cmd = "make Makefiles";
	}
	print "Executing: ", $cmd, "\n";
	$st = system($cmd);
	if ($st) {
		print STDERR "\nFailed executing make command to generate child Makefiles. Sorry.\n";
		die "\n";
	}
} else {
	print "Imake command: ", $cmd, "\n";
}

#
# output status
#

print "\n";
if (!defined($opt_n)) {
	print "Generated Makefile structure\n";
}
if ($kdir) {
	if ($need_kernel_dir) {
		print $kernel_tree_descrip, ": ", $kdir, "\n";
	}
	else {
		print "OPTIONAL NASD_KDIR: ", $kdir, "\n";
	}
}
print "makedepend: ", $makedepend, "\n";
print "X11CFGDIR: ", $x11cfgdir, "\n";
print "Security: ", $say_build_secure, "\n";
print "CMU-PDL: ", $say_build_pdl, "\n";
print "dtip: ", $say_build_dtip, "\n";
print "RPC: ", $rpc, "(", $rpc_val, ")\n";
if ($destdir) {
	print "Install directory: ", $destdir, "\n";
}

sub get_linux_version {
  my ($tree) = @_;

  open (MAKEFILE, "$tree/Makefile") or die "Can't open $tree/Makefile: $!\n";

  my ($version, $patchlevel, $sublevel, $extraversion);
  while (<MAKEFILE>) {
    if (/^VERSION\s*=\s*([^\n]*)$/) { $version = $1; }
    if (/^PATCHLEVEL\s*=\s*([^\n]*)$/) { $patchlevel = $1; }
  if (/^SUBLEVEL\s*=\s*([^\n]*)$/) { $sublevel = $1; }
    if (/^EXTRAVERSION\s*=\s*([^\n]*)$/) { $extraversion = $1; }
  }
  
  close MAKEFILE;

  return "$version.$patchlevel.$sublevel$extraversion";
}
