#!/usr/pkg/bin/perl

# this script is used to move/rename the CDDL files from a freebsd tree
# to have the pathnames used in netbsd.

use File::Basename;
use File::Path;

$FTOP = shift;
$NTOP = shift;
$OUT = shift;

sub usage
{
    my ($str) = @_;
    print "$str\n";
    print "usage: $ARGV[0] <freebsd-src> <netbsd-src> <output>\n";
    exit 1;
}

sub remap_pattern {
    my ($s) = @_;
    my $i = 0;

    while ($pmap[$i * 3]) {
	my $match = $pmap[$i * 3 + 0];
	my $old = $pmap[$i * 3 + 1];
	my $new = $pmap[$i * 3 + 2];

	if ($s =~ /$match/) {
	    $s =~ s/$old/$new/;
	    return $s;
	}
	$i++;
    }
    return '';
}

if (! -d "$FTOP")
{
    usage "FreeBSD src path \"$FTOP\" does not exist";
}

if (! -d "$NTOP")
{
    usage "NetBSD src path \"$NTOP\" does not exist";
}

if ( -d "$OUT" )
{
    usage "output path \"$OUT\" already exists";
}

print "FTOP $FTOP\n";
print "NTOP $NTOP\n";
print "OUT $OUT\n";

# freebsd files to ignore
@skip = qw(
Makefile
shlib_version
dtrace/test
#acl/acl_common.h
sys/asm_linkage.h
sys/callo.h
sys/debug_compat.h
sys/disp.h
sys/file.h
sys/freebsd_rwlock.h
sys/lock.h
opensolaris_atomic.S
cddl/contrib/opensolaris/cmd/lockstat
cddl/contrib/opensolaris/cmd/mdb
cddl/contrib/opensolaris/cmd/plockstat
cddl/usr.sbin/zfsd
sys/cddl/boot
);


# map for certain individual files
%imap = qw(
cddl/contrib/opensolaris/cmd/zpool/zpool-features.7	external/cddl/osnet/sbin/zpool/zpool-features.7

cddl/contrib/opensolaris/head/note.h			external/cddl/osnet/dist/head/note.h
cddl/contrib/opensolaris/head/thread.h			external/cddl/osnet/include/thread.h
cddl/contrib/opensolaris/lib/libctf/common/ctf_subr.c	external/cddl/osnet/dist/lib/libctf/common/ctf_subr.c
cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h	external/cddl/osnet/dist/lib/libdtrace/common/dtrace.h
cddl/contrib/opensolaris/lib/libnvpair/nvpair_alloc_system.c	external/cddl/osnet/dist/lib/libnvpair/nvpair_alloc_system.c
cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h	external/cddl/osnet/sys/sys/zfs_context.h 
cddl/contrib/opensolaris/lib/libzpool/common/kernel.c	external/cddl/osnet/dist/lib/libzpool/common/kernel.c
cddl/contrib/opensolaris/lib/libzpool/common/taskq.c	external/cddl/osnet/dist/lib/libzpool/common/taskq.c
cddl/contrib/opensolaris/lib/libzpool/common/util.c	external/cddl/osnet/dist/lib/libzpool/common/util.c

sys/cddl/compat/opensolaris/kern/opensolaris_sunddi.c	external/cddl/osnet/sys/kern/ddi.c
#sys/cddl/compat/opensolaris/sys/systeminfo.h		external/cddl/osnet/dist/uts/common/sys/systeminfo.h

sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_fnvpair.c	external/cddl/osnet/dist/common/nvpair/fnvpair.c
sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c		external/cddl/osnet/dist/common/nvpair/nvpair.c
sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair_alloc_fixed.c external/cddl/osnet/dist/common/nvpair/nvpair_alloc_fixed.c

sys/cddl/dev/dtrace/x86/regset.h			external/cddl/osnet/dev/dtrace/x86/regset.h

sys/cddl/contrib/opensolaris/uts/common/sys/idmap.h	external/cddl/osnet/dist/uts/common/sys/idmap.h
sys/cddl/contrib/opensolaris/uts/common/sys/callb.h	external/cddl/osnet/dist/uts/common/sys/callb.h

sys/cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c	external/cddl/osnet/dist/uts/common/zmod/crc32.c

);


# map of patterns.  each group of 3 lines has:
# pattern to match
# old text to replace
# new text
@pmap = qw(
dt_isadep.c
cddl/contrib/opensolaris/lib/libdtrace
external/cddl/osnet/dist/lib/libdtrace

dtrace_asm|dtrace_isa|dtrace_subr
sys/cddl/dev/dtrace
external/cddl/osnet/dev/dtrace

fasttrap_isa
sys/cddl/contrib/opensolaris/uts
external/cddl/osnet/dist/uts

/tools/ctf/
cddl/contrib/opensolaris/tools/ctf
external/cddl/osnet/dist/tools/ctf

sys/cddl/contrib/opensolaris/common
sys/cddl/contrib/opensolaris
external/cddl/osnet/dist

sys/cddl/contrib/opensolaris/uts/common
sys/cddl/contrib/opensolaris
external/cddl/osnet/dist

sys/cddl/compat/opensolaris/sys
sys/cddl/compat/opensolaris
external/cddl/osnet/sys

sys/cddl/dev
sys/cddl/dev
external/cddl/osnet/dev

cddl/compat/opensolaris/include
cddl/compat/opensolaris/include
external/cddl/osnet/include

cddl/compat/opensolaris/misc
cddl/compat/opensolaris/misc
external/cddl/osnet/lib/libzfs

cddl/contrib/opensolaris/cmd
cddl/contrib/opensolaris/cmd
external/cddl/osnet/dist/cmd

cddl/contrib/opensolaris/lib
cddl/contrib/opensolaris/lib
external/cddl/osnet/dist/lib

);

$ff = `find $NTOP/external/cddl/osnet -type f | grep -v /CVS/ | sed "s,$NTOP/,,"`;
$nf = `find $FTOP/cddl $FTOP/sys/cddl -type f ! -name 'cscope*' | sed "s,$FTOP/,,"`;

for (split(' ', $ff))
{
    chomp;
#    print "Q addbmap $_\n";

    $b = basename($_);
    $bmapc{$b}++;
    $bmap{$b} = $_;
}

for (sort keys %bmapc) {
    print "Q bmap $bmapc{$_} $_ $bmap{$_}\n";
}

for (split(' ', $nf))
{
    my $b, $n, $skip;
    my $x = $_;

#    print "Q loop $x\n";


    # skip some fbsd files that are not in nbsd
    $skip = 0;
    for (@skip) {
	$skip = 1 if ($x =~ /$_/);
    }
    if ($skip) {
	print "Q skip $x\n";
    } else {
	print "Q noskip $x\n";
    }
    next if $skip;


    # map paths for some individual files.
    $n = $imap{$x};
    if ($n) {
	print "Q imap $x $n\n";
    } else {
	print "Q noimap $x\n";
    }
    goto FOUND if $n;


    # map paths for files with unique names.
    $b = basename($x);
    if ($bmapc{$b} == 1) {
	$n = $bmap{$b};
    } else {
	$n = '';
    }
    if ($n) {
	print "Q bmap $x $n\n";
    } else {
	print "Q nobmap $x\n";
    }
    goto FOUND if $n;

    # apply pattern substitutions.
    $n = remap_pattern($x);
    if ($n) {
	print "Q pmap $x $n\n";
    } else {
	print "Q nopmap $x\n";
    }
    goto FOUND if $n;


FOUND:
    if ($n) {
	print "Q found $x $n\n";
    } else {
	print "Q notfound $x\n";
	next;
    }

    File::Path::make_path("$OUT/" . dirname($n));
    system("cp -p $FTOP/$x $OUT/$n");
}
