libncurses: Import https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.5.tar.gz changes

Change-Id: I3433d30ca01359fd2e3623ede96b531f0b39cbfa
Signed-off-by: micky387 <mickaelsaibi@free.fr>
diff --git a/misc/ncu2openbsd b/misc/ncu2openbsd
new file mode 100755
index 0000000..0c3365d
--- /dev/null
+++ b/misc/ncu2openbsd
@@ -0,0 +1,1288 @@
+#!/usr/bin/env perl
+# $Id: ncu2openbsd,v 1.67 2023/09/09 15:59:17 tom Exp $
+# -----------------------------------------------------------------------------
+# Copyright 2021,2023 by Thomas E. Dickey
+#
+#                         All Rights Reserved
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name(s) of the above copyright
+# holders shall not be used in advertising or otherwise to promote the
+# sale, use or other dealings in this Software without prior written
+# authorization.
+# -----------------------------------------------------------------------------
+# https://invisible-island.net/ncurses/ncurses-openbsd.html
+#
+# Update the OpenBSD source-tree given an ncurses tarball or build-tree.
+
+use strict;
+use warnings;
+
+use Getopt::Std;
+use Cwd;
+use Cwd 'abs_path';
+use File::Path qw/ remove_tree /;
+use File::Temp qw/ tempdir /;
+
+$| = 1;
+
+our ( $opt_d, $opt_n, $opt_r, $opt_t, $opt_v, $opt_x, $opt_6 );
+our $source_dir;
+our $target_dir;
+our $update_dir;
+our $backup_dir;
+
+our $tempdir = tempdir( CLEANUP => 1 );
+my $current = getcwd;
+my $working = $current;
+
+our $generated_by = "generated by: ncu2openbsd";
+
+our %setup_dir = qw(
+  lib/libcurses         ncurses
+  lib/libform           form
+  lib/libmenu           menu
+  lib/libpanel          panel
+  usr.bin/infocmp       progs
+  usr.bin/tabs          progs
+  usr.bin/tic           progs
+  usr.bin/toe           progs
+  usr.bin/tput          progs
+  usr.bin/tset          progs
+  share/termtypes       misc
+);
+
+our %generated = qw(
+  codes.c 1
+  comp_captab.c         1
+  comp_userdefs.c       1
+  expanded.c            1
+  fallback.c            1
+  init_keytry.h         1
+  keys.list             1
+  lib_gen.c             1
+  lib_keyname.c         1
+  make_hash             1
+  make_keys             1
+  names.c               1
+  termsort.c            1
+  unctrl.c              1
+);
+
+our %definitions = qw(
+  CAPTOINFO             captoinfo
+  DATADIR               /usr/share
+  INFOCMP               infocmp
+  INFOTOCAP             infotocap
+  NCURSES_MAJOR         5
+  NCURSES_MINOR         7
+  NCURSES_OSPEED        int
+  NCURSES_PATCH         20081102
+  TERMINFO              /usr/share/terminfo
+  TIC                   tic
+  TOE                   toe
+  TPUT                  tput
+  TSET                  tset
+);
+
+sub patchdate() {
+    return $definitions{"NCURSES_PATCH"};
+}
+
+sub failed($) {
+    chdir $current;
+    printf STDERR "? %s\n", $_[0];
+    exit;
+}
+
+sub verbose($) {
+    my $text = shift;
+    printf "%s\n", $text if ($opt_v);
+}
+
+sub read_file($) {
+    my $name = shift;
+    open( my $fp, $name ) || &failed("cannot open $name");
+    my (@input) = <$fp>;
+    chomp @input;
+    close($fp);
+    return @input;
+}
+
+sub read_dir($) {
+    my $path = shift;
+    my @result;
+    if ( opendir( my $dh, $path ) ) {
+        my @data = sort readdir($dh);
+        closedir $dh;
+        for my $d ( 0 .. $#data ) {
+            next if ( $data[$d] =~ /^\.(\.)?$/ );
+            next if ( -l $path . "/" . $data[$d] );
+            $result[ $#result + 1 ] = $data[$d];
+        }
+    }
+    return @result;
+}
+
+sub rename_dir($$) {
+    my $src = shift;
+    my $dst = shift;
+    printf "%% mv %s -> %s\n", $src, $dst if ($opt_v);
+    rename $src, $dst unless ($opt_n);
+}
+
+sub check_sourcedir($) {
+    my $path = shift;
+    &failed("not a directory: $path") unless ( -d $path );
+    my $full = abs_path($path);
+    chdir $full;
+    &failed("not an ncurses source-tree: $path")
+      unless ( -f "NEWS" and -f "dist.mk" );
+    $source_dir = $full;
+}
+
+sub unpack($) {
+    my $path    = shift;
+    my $full    = abs_path($path);
+    my $command = "";
+    if ( $path =~ /\.tgz$/ or $path =~ /\.tar\.gz$/ ) {
+        $command = "tar xzf %s";
+    }
+    elsif ( $path =~ /\.zip$/ ) {
+        $command = "unzip -q %s";
+    }
+    else {
+        &failed("not a gzip'd tarball or zip-file: $path");
+    }
+    chdir $tempdir;
+    system( sprintf( $command, $full ) );
+
+    # there should be exactly one subdirectory -- the source-tree
+    my @data = &read_dir(".");
+    &failed("found no subdirectories of $path") if ( $#data < 0 );
+    &failed( "too many subdirectories: " . $data[0] . " vs " . $data[1] )
+      if ( $#data > 0 );
+    &check_sourcedir( $data[0] );
+}
+
+sub remove_dir($) {
+    my $tree = shift;
+    if ( -d $tree ) {
+        printf "%% rm -rf %s\n", $tree if ($opt_v);
+        remove_tree( $tree, $opt_v ? 1 : 0, 1 ) unless ($opt_n);
+    }
+}
+
+sub copy_CVS($) {
+    my $leaf    = shift;
+    my $src     = $target_dir . $leaf . "/CVS";
+    my $dst     = $update_dir . $leaf . "/CVS";
+    my $verbose = $opt_v ? "v" : "";
+    if ( -d $src and !-d $dst ) {
+        my $mid = $update_dir . $leaf;
+        mkdir $mid unless ( -d $mid );
+        mkdir $dst unless ( -d $dst );
+        system("cp -a$verbose $src/* $dst/");
+    }
+}
+
+sub is_tic_code($) {
+    my $item   = shift;
+    my $result = 0;
+    $result = 1
+      if (
+        $item =~ /^(capconvert
+                   |tic
+                   |dump
+                   |progs
+                   |termsort
+                   |transform
+                   |MKtermsort)/x
+      );
+    return $result;
+}
+
+sub is_ident($$) {
+    my $name = shift;
+    my $text = shift;
+    my $code = 0;
+    $code = 1 if ( $text =~ /\$$name:.*\$/ );
+    return $code;
+}
+
+# We "could", filter out differences with ident's using the diff -I option,
+# but in practice, that is cumbersome.
+sub munge_ident($) {
+    my $target = shift;
+    my $source = $target;
+    $source =~ s/\.update\b//;
+    &failed("bug at $source") if ( $source eq $target );
+    return unless ( -f $source );
+    my @source = &read_file($source);
+    my @target = &read_file($target);
+    my $old_id = "";
+    my $gap_id = 0;
+    my $new_id = "";
+    my $skipit = -1;
+
+    for my $n ( 0 .. $#source ) {
+        if ( &is_ident( "OpenBSD", $source[$n] ) ) {
+            $old_id = $source[$n];
+            $skipit = $n + 1;
+        }
+        elsif ( &is_ident( "Id", $source[$n] ) ) {
+            $new_id = $source[$n];
+            last;
+        }
+        elsif ( $n == $skipit ) {
+            $source[$n] =~ s/\s+$//;
+            if ( $source[$n] eq "" ) {
+                $gap_id = $source[$n];
+            }
+            elsif ( $source[$n] eq '.\"' ) {
+                $gap_id = $source[$n];
+            }
+        }
+    }
+    if ( $old_id ne "" ) {
+        my @update;
+        my $tables = &uses_tables($target);
+        $update[ $#update + 1 ] = $target[0] if ($tables);
+        $update[ $#update + 1 ] = $old_id;
+        $update[ $#update + 1 ] = $gap_id unless ( $gap_id eq 0 );
+        for my $n ( $tables .. $#target ) {
+            if ( &is_ident( "Id", $target[$n] ) ) {
+                $update[ $#update + 1 ] = $new_id;
+            }
+            else {
+                $update[ $#update + 1 ] = $target[$n];
+            }
+        }
+        system("chmod u+w $target");
+        if ( open my $fp, ">", $target ) {
+            for my $n ( 0 .. $#update ) {
+                printf $fp "%s\n", $update[$n];
+            }
+            close $fp;
+            system("chmod u-w $target");
+        }
+    }
+}
+
+# ncurses manual pages provide for renaming the utilities, normally as part of
+# the scripts provided in its sources.  OpenBSD developers do not use those.
+sub munge_docs($) {
+    my $path = shift;
+    my @data = &read_file($path);
+    my $done = 0;
+    for my $n ( 0 .. $#data ) {
+        my $text = $data[$n];
+        $text =~ s/\b1M\b/1/g;
+        $text =~ s/\b3X\b/3/g;
+        $text =~ s/\bcurs_(term(info|cap)\s*3\b)/$1/g;
+        $text =~ s/(\\fB)curs_(term(info|cap)\\f[RP]\(3\))/$1$2/g;
+        my $left = "";
+        while ( $text =~ /@[[:alnum:]_]+@/ ) {
+            my $next = index( $text, "@" );
+            last if ( $next < 0 );
+            $left .= substr( $text, 0, $next++ );
+            $text = substr( $text, $next );
+            $next = index( $text, "@" );
+            last if ( $next < 0 );
+            my $word = substr( $text, 0, $next );
+            if ( $word =~ /^[[:alnum:]_]+/ ) {
+
+                if ( $definitions{$word} ) {
+                    $word = $definitions{$word};
+                }
+                else {
+                    $word = "?";
+                }
+                $left .= $word;
+                $text = substr( $text, $next + 1 );
+            }
+            else {
+                &failed("unexpected definition @$word@");
+            }
+        }
+        $text = $left . $text;
+        if ( $text ne $data[$n] ) {
+            $done++;
+            $data[$n] = $text;
+        }
+    }
+    if ($done) {
+        system("chmod u+w $path");
+        if ( open my $fp, ">", $path ) {
+            for my $n ( 0 .. $#data ) {
+                printf $fp "%s\n", $data[$n];
+            }
+            close $fp;
+            system("chmod u-w $path");
+        }
+    }
+}
+
+sub copy_file($$) {
+    my $src     = shift;
+    my $dst     = shift;
+    my $verbose = $opt_v ? "v" : "";
+    if ( -d $dst ) {
+        my $leaf = $src;
+        $leaf =~ s,^.*/,,;
+        $dst .= "/" . $leaf;
+    }
+    system("chmod u+w $dst") if ( -f $dst );
+    system("cp -a$verbose $src $dst");
+    &munge_ident($dst);
+}
+
+sub copy_code($) {
+    my $src = shift;
+    my $dst = shift;
+    &copy_CVS( substr( $dst, length($update_dir) ) );
+    printf ".. copying files for $dst\n";
+    my @data = &read_dir($src);
+    printf ".. %d entries\n", $#data + 1;
+    my $verbose = $opt_v ? "v" : "";
+    for my $d ( 0 .. $#data ) {
+        my $item     = $data[$d];
+        my $src_item = $src . "/" . $item;
+        next if ( -d $src_item );
+        next if ( -l $src_item );
+        next if ( $item =~ /^\.(\.)?$/ );
+        next if ( $item =~ /\.(bak|in|log|status)$/ );
+        next if ( $item =~ /^llib-/ );
+        next if ( $item =~ /^modules/ );
+        next if ( $item =~ /^[fm]_trace\.c/ and not $opt_t );
+        next
+          if ( $item =~ /^Makefile/ and index( $update_dir, "/share/" ) < 0 );
+        next if ( $item =~ /^README/ );
+        next if ( $item eq "headers" );
+        next if ( $generated{$item} );
+        next if ( $item eq "link_test.c" );
+
+        if ( index( $dst, "/usr.bin/" ) >= 0 ) {
+            next if ( $item =~ /^(clear)/ );    # OpenBSD uses "tput clear"
+            my $prog = $dst;
+            $prog =~ s%^.*/%%;
+            $prog =~ s/(update|backup)//;
+            $prog .= "c";
+            if ( $dst =~ /infocmp/ ) {
+                next if ( $item ne $prog );
+            }
+            elsif ( $dst =~ /tabs/ ) {
+                next if ( $item ne $prog );
+            }
+            elsif ( $dst =~ /tic/ ) {
+                next if ( &is_tic_code($item) == 0 );
+            }
+            elsif ( $dst =~ /toe/ ) {
+                next if ( $item ne $prog );
+            }
+            elsif ( $dst =~ /tput/ ) {
+                next if ( $item ne $prog );
+            }
+            elsif ( $dst =~ /tset/ ) {
+                next if ( $item ne $prog );
+            }
+            else {
+                next;
+            }
+        }
+        system( sprintf( "cp -a$verbose %s %s/%s", $src_item, $dst, $item ) );
+        &munge_ident("$dst/$item");
+    }
+}
+
+# Checking if nroff supports tables is a long-obsolete issue, and is not really
+# necessary, except to match OpenBSD's source-tree.
+sub uses_tables($) {
+    my $docs = shift;
+    my @docs = &read_file($docs);
+    my $code = 0;
+    for my $n ( 0 .. $#docs ) {
+        if ( $docs[$n] =~ /^[.']\\"\s+t\b.*/ ) {
+            $code = 1;
+            last;
+        }
+        elsif ( $docs[$n] =~ /^\./ ) {
+            last;
+        }
+    }
+    return $code;
+}
+
+sub copy_1doc($$) {
+    my $docs = shift;
+    my $src  = "$source_dir/man/$docs";
+    my $dst  = "$update_dir/$docs";
+    $src .= "m" if ( -f "${src}m" );
+    $dst =~ s/x$//;
+    if ( $dst =~ /\.3/ ) {
+        $dst =~ s/\bncurses/curses/ if ( $dst =~ /ncurses\./ );
+        $dst =~ s/\bcurs_//         if ( $dst =~ /_term(cap|info)\./ );
+    }
+    &copy_file( $src, $dst );
+    &munge_docs($dst);
+}
+
+sub copy_docs($) {
+    my $docs = shift;
+    if ( index( $update_dir, "/usr.bin/" ) >= 0 ) {
+        &copy_1doc( $docs . ".1" );
+        if ( $docs eq "tic" ) {
+            &copy_1doc("captoinfo.1");
+            &copy_1doc("infotocap.1");
+        }
+    }
+    else {
+        my @docs = &read_dir("$source_dir/man");
+        if ( $docs eq "curses" ) {
+            for my $n ( 0 .. $#docs ) {
+                next if ( $docs[$n] eq "Makefile" );
+                next if ( $docs[$n] eq "make_sed.sh" );
+                next if ( $docs[$n] eq "man_db.renames" );
+                next if ( $docs[$n] eq "manlinks.sed" );
+                next if ( $docs[$n] =~ /\.(1|head|tail|in)/ );
+                next if ( $docs[$n] =~ /^(form|menu|mitem|panel)/ );
+                &copy_1doc( $docs[$n] );
+            }
+        }
+        elsif ( $docs eq "form" ) {
+            for my $n ( 0 .. $#docs ) {
+                next unless ( $docs[$n] =~ /^form/ );
+                &copy_1doc( $docs[$n] );
+            }
+        }
+        elsif ( $docs eq "menu" ) {
+            for my $n ( 0 .. $#docs ) {
+                next unless ( $docs[$n] =~ /^(menu|mitem)/ );
+                &copy_1doc( $docs[$n] );
+            }
+        }
+        elsif ( $docs eq "panel" ) {
+            for my $n ( 0 .. $#docs ) {
+                next unless ( $docs[$n] =~ /^panel/ );
+                &copy_1doc( $docs[$n] );
+            }
+        }
+    }
+}
+
+sub setup_dir($) {
+    my $dst = shift;
+    &failed("no definition for $dst")
+      unless ( defined $setup_dir{$dst} or $opt_r );
+    $target_dir = sprintf( "%s/%s", $opt_d, $dst );
+    $update_dir = $target_dir . ".update";
+    $backup_dir = $target_dir . ".backup";
+    my $result = 0;
+    if ($opt_r) {
+        &remove_dir($update_dir);
+        if ( $target_dir =~ /\/(tabs|toe)$/ ) {
+            &remove_dir($target_dir);
+        }
+        elsif ( -d $backup_dir ) {
+            &remove_dir($target_dir);
+            &rename_dir( $backup_dir, $target_dir );
+        }
+    }
+    else {
+        &remove_dir($update_dir);
+        mkdir $update_dir;
+
+        # reuse the shared-library version, assuming ABI=5 would involve at
+        # most a minor-version bump.
+        &copy_file( "$target_dir/shlib_version", $update_dir )
+          if ( $dst =~ /^lib\// );
+        &copy_code( $source_dir . "/" . $setup_dir{$dst}, $update_dir )
+          unless ( $setup_dir{$dst} eq "misc" );
+        $result = 1;
+    }
+    return $result;
+}
+
+sub do_build($) {
+    my $command = shift;
+    printf "%% %s\n", $command if ($opt_v);
+    system($command);
+}
+
+sub finish_dir() {
+    printf "** $target_dir\n";
+    system("diff -Naurb $target_dir $update_dir | diffstat -n 30")
+      if ( -d $target_dir );
+    if ($opt_n) {
+        &do_build("cd $update_dir && make -n") if ($opt_x);
+    }
+    else {
+        if ( -d $backup_dir ) {
+            printf STDERR "? backup directory exists: %s\n", $backup_dir;
+        }
+        else {
+            &rename_dir( $target_dir, $backup_dir );
+            &rename_dir( $update_dir, $target_dir );
+        }
+        &do_build("cd $target_dir && make") if ($opt_x);
+    }
+}
+
+################################################################################
+
+sub only_c_files($) {
+    my @data = @{ $_[0] };
+    my %data;
+    for my $n ( 0 .. $#data ) {
+        my $text = $data[$n];
+        $data{$text}++ if ( $text =~ /\.c$/ );
+    }
+    return sort keys %data;
+}
+
+sub makefile_list($$$) {
+    my @data = @{ $_[0] };
+    my $name = $_[1];
+    my $skip = $_[2];
+    my %data;
+    my $state = 0;
+    for my $n ( 0 .. $#data ) {
+        my $text = $data[$n];
+        $text =~ s/^\s+//;
+        next if ( index( $text, $skip ) == 0 );
+        $text =~ s/\s+=/=/;
+        $text =~ s/=\s+/=/;
+        $text =~ s/\s*\\//;
+        $state = 1 if ( $text =~ /^${name}=/ );
+        next unless ( $state == 1 );
+
+        if ( index( $text, "(trace)" ) >= 0 and not $opt_t ) {
+            next unless ( $text =~ /\b(lib_trace|visbuf)\.c$/ );
+        }
+        if ( not $opt_t ) {
+            next if ( $text =~ /\b[fm]_trace\.c$/ );
+        }
+        $text =~ s/^.*=//;
+        $text =~ s/\$o/.o/g;
+        $text =~ s/^.*\///;
+        next           if ( $text eq "link_test.c" );
+        next           if ( $text eq "mf_common.h" );
+        next           if ( $text eq "transform.h" );
+        $data{$text}++ if ( $text ne "" );
+        last           if ( $data[$n] !~ /\\$/ );
+    }
+    return sort keys %data;
+}
+
+sub manpage_list($) {
+    my $path = shift;
+    my @data = &read_dir($path);
+    my %data;
+    for my $n ( 0 .. $#data ) {
+        my $text = $data[$n];
+        $data{$text}++ if ( $text =~ /\.\d$/ );
+    }
+    return sort keys %data;
+}
+
+sub columns_of($) {
+    my $string = shift;
+    my $result = 0;
+    for my $n ( 0 .. length($string) - 1 ) {
+        my $c = substr( $string, $n, 1 );
+        if ( $c eq "\t" ) {
+            $result |= 7;
+            $result++;
+        }
+        elsif ( $c eq "\n" ) {
+            $result = 0;
+        }
+        else {
+            ++$result;
+        }
+    }
+    return $result;
+}
+
+sub format_list($$) {
+    my $name = $_[0];
+    my @data = @{ $_[1] };
+    my $keep = ( defined $_[2] ) ? 1 : 0;
+    my $base;
+    my $fill;
+    if ( length($name) >= 9 ) {
+        $fill = " ";
+        $base = length($name) + 1;
+    }
+    else {
+        $base = 9;
+        $fill = "\t";
+    }
+    my $result = sprintf( "%s%s", $name, $fill );
+    if ( $keep == 0 ) {
+        my %data;
+        for my $n ( 0 .. $#data ) {
+            $data{ $data[$n] } = 1 if ( defined $data[$n] );
+        }
+        @data = sort keys %data;
+    }
+    for my $n ( 0 .. $#data ) {
+        my $data = $data[$n];
+        my $col  = &columns_of($result);
+        my $add  = 1 + length($data);
+        if ( ( $col + $add ) > 76 ) {
+            $result .= " " if ( $col > $base );
+            $base = 9;
+            $fill = "\t";
+            $result .= "\\\n" . $fill . $data;
+        }
+        else {
+            $result .= " " if ( $col > $base );
+            $result .= $data;
+        }
+    }
+    return $result;
+}
+
+################################################################################
+
+sub compare_makefiles($) {
+    if ($opt_v) {
+        my $newfile = shift;
+        my $bakfile =
+          ( -d $backup_dir ? $backup_dir : $target_dir ) . "/Makefile";
+        system("diff -u $bakfile $newfile") if ( -f $bakfile );
+    }
+}
+
+# The curses makefile has to build build-time utilities and generate source.
+sub gen_1st_makefile() {
+    my $libname = "curses";
+    my $oldfile = "$source_dir/n$libname/Makefile";
+    my @oldfile = &read_file($oldfile);
+
+    my $newfile = "$update_dir/Makefile";
+    open( my $fp, ">", $newfile ) || &failed("cannot open $newfile");
+    my @subdirs = (
+        '${.CURDIR}/base', '${.CURDIR}/tinfo',
+        '${.CURDIR}/tty',  '${.CURDIR}/widechar'
+    );
+    $subdirs[ $#subdirs + 1 ] = '${.CURDIR}/trace' if ($opt_t);
+    printf $fp <<EOF;
+# $generated_by
+
+LIB=	$libname
+
+# Uncomment this to enable tracing in libcurses
+#CURSESTRACE=-DTRACE
+
+# This is used to compile terminal info directly into the library
+FALLBACK_LIST=
+
+# XXX - should be defined elsewhere
+AWK?=	/usr/bin/awk
+
+# Search in subdirs
+EOF
+    printf $fp "%s\n", &format_list( ".PATH:", \@subdirs );
+
+    my @autosrc = &makefile_list( \@oldfile, "AUTO_SRC", "?" );
+    my @auto_cc = &only_c_files( \@autosrc );
+    printf $fp "%s\n", &format_list( "SRCS=", \@auto_cc );
+
+    my @sources = &makefile_list( \@oldfile, "C_SRC", "./" );
+    printf $fp "%s\n", &format_list( "SRCS+=", \@sources );
+
+    printf $fp <<EOF;
+
+HOSTCFLAGS?=	\${CFLAGS}
+HOSTLDFLAGS?=	\${LDFLAGS}
+HOSTCFLAGS+=	-I. -I\${.CURDIR} \${CURSESTRACE}
+CFLAGS+=	-I. -I\${.CURDIR} \${CURSESTRACE} -D_XOPEN_SOURCE_EXTENDED -DNDEBUG
+
+EOF
+    my @manpages = &manpage_list($update_dir);
+    printf $fp "%s\n", &format_list( "MAN=", \@manpages );
+
+    $autosrc[ $#autosrc++ ] = "make_hash";
+    $autosrc[ $#autosrc++ ] = "make_keys";
+    printf $fp "%s\n", &format_list( "GENERATED=", \@autosrc );
+    printf $fp <<EOF;
+
+CAPLIST	= \${.CURDIR}/Caps
+USE_BIG_STRINGS	= 1
+
+CLEANFILES+= \${GENERATED}
+
+BUILDFIRST = \${GENERATED}
+
+includes:
+	\@cmp -s \${DESTDIR}/usr/include/ncurses.h \${.CURDIR}/curses.h || \\
+	  \${INSTALL} \${INSTALL_COPY} -m 444 -o \$(BINOWN) -g \$(BINGRP) \\
+	  \${.CURDIR}/curses.h \${DESTDIR}/usr/include/ncurses.h
+	\@cd \${.CURDIR}; for i in ncurses_dll.h unctrl.h term.h termcap.h; do \\
+	  cmp -s \$\$i \${DESTDIR}/usr/include/\$\$i || \\
+	  \${INSTALL} \${INSTALL_COPY} -m 444 -o \$(BINOWN) -g \$(BINGRP) \$\$i \\
+	  \${DESTDIR}/usr/include; done
+
+keys.list: \${.CURDIR}/tinfo/MKkeys_list.sh
+	sh \${.CURDIR}/tinfo/MKkeys_list.sh \${.CURDIR}/Caps | sort > \${.TARGET}
+
+fallback.c: \${.CURDIR}/tinfo/MKfallback.sh
+	sh \${.CURDIR}/tinfo/MKfallback.sh /usr/share/terminfo \${.CURDIR}/../../share/termtypes/termtypes.master \$(FALLBACK_LIST) > \${.TARGET}
+
+lib_gen.c: \${.CURDIR}/base/MKlib_gen.sh
+	sh \${.CURDIR}/base/MKlib_gen.sh "\${CC} -E -P -I\${.CURDIR}" \\
+		"\${AWK}" generated < \${.CURDIR}/curses.h > lib_gen.c
+
+init_keytry.h: make_keys keys.list
+	./make_keys keys.list > \${.TARGET}
+
+make_keys: \${.CURDIR}/tinfo/make_keys.c \${.CURDIR}/curses.priv.h names.c
+	\${HOSTCC} \${LDSTATIC} \${HOSTCFLAGS} \${HOSTLDFLAGS} \\
+		-o \${.TARGET} \${.CURDIR}/tinfo/make_keys.c \${LDADD}
+EOF
+
+    if ( &patchdate >= 20090808 ) {
+        printf $fp <<EOF;
+make_hash:	\${.CURDIR}/tinfo/make_hash.c \\
+		\${.CURDIR}/curses.priv.h \\
+		\${.CURDIR}/hashsize.h
+	\${HOSTCC} \${LDSTATIC} \${HOSTCFLAGS} -DMAIN_PROGRAM \${HOSTLDFLAGS} \\
+		-o \${.TARGET} \${.CURDIR}/tinfo/make_hash.c \${LDADD}
+EOF
+    }
+    else {
+        printf $fp <<EOF;
+make_hash: \${.CURDIR}/tinfo/comp_hash.c \\
+		\${.CURDIR}/curses.priv.h \\
+		\${.CURDIR}/hashsize.h
+	\${HOSTCC} \${LDSTATIC} \${HOSTCFLAGS} -DMAIN_PROGRAM \${HOSTLDFLAGS} \\
+		-o \${.TARGET} \${.CURDIR}/tinfo/comp_hash.c \${LDADD}
+EOF
+    }
+
+    if ( &patchdate >= 20190309 ) {
+        printf $fp <<EOF;
+CAPLIST += \${.CURDIR}/Caps-ncurses
+
+comp_userdefs.c: make_hash \\
+		\${.CURDIR}/hashsize.h \\
+		\${.CURDIR}/tinfo/MKuserdefs.sh
+	sh \${.CURDIR}/tinfo/MKuserdefs.sh \${AWK} \${USE_BIG_STRINGS} \${CAPLIST} > \${.TARGET}
+EOF
+    }
+    printf $fp <<EOF;
+
+expanded.c: \${.CURDIR}/term.h \${.CURDIR}/curses.priv.h \\
+		\${.CURDIR}/ncurses_cfg.h \${.CURDIR}/tty/MKexpanded.sh
+	sh \${.CURDIR}/tty/MKexpanded.sh "\${CC} -E -P" \${CPPFLAGS} > \${.TARGET}
+
+comp_captab.c: make_hash
+	sh \${.CURDIR}/tinfo/MKcaptab.sh \${AWK} \${USE_BIG_STRINGS} \\
+		\${.CURDIR}/tinfo/MKcaptab.awk \${CAPLIST} > \${.TARGET}
+
+lib_keyname.c: keys.list \${.CURDIR}/base/MKkeyname.awk
+	\${AWK} -f \${.CURDIR}/base/MKkeyname.awk \\
+		bigstrings=\${USE_BIG_STRINGS} \\
+		keys.list > \${.TARGET}
+
+names.c: \${.CURDIR}/tinfo/MKnames.awk
+	\${AWK} -f \${.CURDIR}/tinfo/MKnames.awk \\
+		bigstrings=\${USE_BIG_STRINGS} \\
+		\${CAPLIST} > \${.TARGET}
+codes.c: \${.CURDIR}/tinfo/MKcodes.awk
+	\${AWK} -f \${.CURDIR}/tinfo/MKcodes.awk \\
+		bigstrings=\${USE_BIG_STRINGS} \\
+		\${CAPLIST} > \${.TARGET}
+
+unctrl.c: \${.CURDIR}/base/MKunctrl.awk
+	echo | \${AWK} -f \${.CURDIR}/base/MKunctrl.awk bigstrings=1 > \${.TARGET}
+
+.include <bsd.own.mk>
+
+# Link libtermlib, libtermcap to libcurses so we don't break people's Makefiles
+afterinstall:
+	-cd \${DESTDIR}\${LIBDIR}; \\
+	for i in \${_LIBS}; do \\
+	    ln -f \$\$i `echo \$\$i | sed 's/curses/termlib/'`; \\
+	    ln -f \$\$i `echo \$\$i | sed 's/curses/termcap/'`; \\
+	    ln -f \$\$i `echo \$\$i | sed 's/curses/ncurses/'`; \\
+	    ln -f \$\$i `echo \$\$i | sed 's/curses/ncursesw/'`; \\
+	done
+
+.include <bsd.lib.mk>
+EOF
+    close $fp;
+    &compare_makefiles($newfile);
+}
+
+sub gen_lib_makefile($) {
+    my $libname = shift;
+    my $oldfile = "$source_dir/$libname/Makefile";
+    my @oldfile = &read_file($oldfile);
+
+    # in ncurses, header-files are quasi-generated, because the original
+    # header file for form/menu/panel lives in the source-directory, but is
+    # copied to the include-directory with "make sources".
+    my @headers = &makefile_list( \@oldfile, "AUTO_SRC", "?" );
+
+    # The C source is more straightforward.
+    my @sources = &makefile_list( \@oldfile, "C_SRC", "?" );
+    my $newfile = "$update_dir/Makefile";
+    open( my $fp, ">", $newfile ) || &failed("cannot open $newfile");
+    printf $fp <<EOF;
+# $generated_by
+
+LIB=	$libname
+EOF
+
+    printf $fp "%s\n", &format_list( "SRCS=", \@sources );
+    printf $fp "%s\n", &format_list( "HDRS=", \@headers );
+    my $includes = '-I${.CURDIR}/../libcurses';
+    $includes .= ' -I${.CURDIR}/../libmenu' if ( $libname eq "form" );
+    printf $fp <<EOF;
+CFLAGS+=$includes -D_XOPEN_SOURCE_EXTENDED -DNDEBUG
+EOF
+    my @manpages = &manpage_list($update_dir);
+    printf $fp "%s\n", &format_list( "MAN=", \@manpages );
+    printf $fp <<EOF;
+
+includes:
+	\@cd \$\{.CURDIR}; for i in \$\{HDRS}; do \\
+	  cmp -s \$\$i \${DESTDIR}/usr/include/\$\$i || \\
+	  \${INSTALL} \${INSTALL_COPY} -m 444 -o \$(BINOWN) -g \$(BINGRP) \$\$i \\
+	  \${DESTDIR}/usr/include; done
+
+.include <bsd.own.mk>
+
+afterinstall:
+	-cd \${DESTDIR}\${LIBDIR}; \\
+	for i in \${_LIBS}; do \\
+	    ln -f \$\$i `echo \$\$i | sed 's/${libname}/${libname}w/'`; \\
+	done
+
+.include <bsd.lib.mk>
+EOF
+    close $fp;
+    &compare_makefiles($newfile);
+}
+
+sub gen_bin_makefile($) {
+    my $binname = shift;
+    my $oldfile = "$source_dir/progs/Makefile";
+    my @oldfile = &read_file($oldfile);
+    my $newfile = "$update_dir/Makefile";
+
+    open( my $fp, ">", $newfile ) || &failed("cannot open $newfile");
+    my @sources = ("$binname.c");
+    my @links   = ();
+    my @autosrc = &makefile_list( \@oldfile, "AUTO_SRC", "?" );
+
+    my $tput_ver       = 0;
+    my $use_dump_entry = 0;
+    my $use_termsort   = 0;
+    my $use_tparm_type = 0;
+    my $use_transform  = 0;
+
+    $use_dump_entry = 1 if ( $binname eq "infocmp" or $binname eq "tic" );
+    $use_termsort   = 1 if ( $use_dump_entry       or $binname eq "tput" );
+
+    if ( &patchdate >= 20090314 ) {
+        $use_transform = 1 if ( $binname =~ /^(tic|tput|tset)/ );
+    }
+    if ( &patchdate >= 20140521 ) {
+        $use_tparm_type = 1 if ( $binname =~ /^(tic|tput)$/ );
+    }
+    if ( &patchdate >= 20160806 ) {
+        $tput_ver = &patchdate;
+    }
+
+    $sources[ ++$#sources ] = "dump_entry.c" if ($use_dump_entry);
+    $sources[ ++$#sources ] = "tparm_type.c" if ($use_tparm_type);
+    $sources[ ++$#sources ] = "transform.c"  if ($use_transform);
+
+    $autosrc[ ++$#autosrc ] = "termsort.c" if ($use_termsort);
+
+    # transform.h also is generated, but OpenBSD checked-in a copy
+
+    if ( $binname eq "tic" ) {
+        $links[ ++$#links ] = "captoinfo";
+        $links[ ++$#links ] = "infotocap";
+    }
+    elsif ( $binname eq "tabs" ) {
+        $sources[ ++$#sources ] = "tty_settings.c" if ( $tput_ver >= 20161224 );
+    }
+    elsif ( $binname eq "tput" ) {
+        $sources[ ++$#sources ] = "clear_cmd.c"    if ( $tput_ver >= 20161022 );
+        $sources[ ++$#sources ] = "reset_cmd.c"    if ( $tput_ver >= 20160806 );
+        $sources[ ++$#sources ] = "tty_settings.c" if ( $tput_ver >= 20161224 );
+        $links[ ++$#links ]     = "clear";
+    }
+    elsif ( $binname eq "tset" ) {
+        $sources[ ++$#sources ] = "reset_cmd.c"    if ( $tput_ver >= 20160806 );
+        $sources[ ++$#sources ] = "tty_settings.c" if ( $tput_ver >= 20161224 );
+        $links[ ++$#links ]     = "reset";
+    }
+
+    printf $fp <<EOF;
+# $generated_by
+
+PROG=	$binname
+EOF
+    printf $fp "%s\n", &format_list( "SRCS=", \@sources );
+    printf $fp <<EOF;
+CURSES=	\${.CURDIR}/../../lib/libcurses
+DPADD=	\${LIBCURSES}
+LDADD=	-L\${CURSES} -lcurses\t# in-tree link to add _nc_strict_bsd, etc
+EOF
+    if ( $#links >= 0 ) {
+        my @bin_links;
+        for my $n ( 0 .. $#links ) {
+            $bin_links[ ++$#bin_links ] = '${BINDIR}/' . $binname;
+            $bin_links[ ++$#bin_links ] = '${BINDIR}/' . $links[$n];
+        }
+        printf $fp "%s\n", &format_list( "LINKS=", \@bin_links, 1 );
+    }
+    my $ticfix = '${.CURDIR}/';
+    if ( $binname eq "tic" ) {
+        printf $fp <<EOF;
+CFLAGS+= -I\${CURSES} -I\${.CURDIR} -I.
+EOF
+    }
+    else {
+        $ticfix = '${TIC}/';
+        printf $fp <<EOF;
+TIC= \${.CURDIR}/../tic
+CFLAGS+= -I\${CURSES} -I\${TIC} -I\${.CURDIR} -I.
+.PATH:  \${TIC}
+EOF
+    }
+    printf $fp "%s\n", &format_list( "CLEANFILES+=", \@autosrc );
+    if ($use_dump_entry) {
+        printf $fp <<EOF;
+
+dump_entry.o: termsort.c
+EOF
+    }
+    if ($use_termsort) {
+        printf $fp <<EOF;
+
+termsort.c: ${ticfix}MKtermsort.sh
+	sh ${ticfix}MKtermsort.sh awk \${CURSES}/Caps > \${.TARGET}
+EOF
+    }
+    printf $fp <<EOF;
+
+.include <bsd.prog.mk>
+EOF
+    close $fp;
+
+    &compare_makefiles($newfile);
+}
+
+################################################################################
+
+sub setup_lib_libcurses() {
+    if ( &setup_dir("lib/libcurses") ) {
+        &copy_code( "$source_dir/ncurses/base",     "$update_dir/base" );
+        &copy_code( "$source_dir/ncurses/tinfo",    "$update_dir/tinfo" );
+        &copy_code( "$source_dir/ncurses/tty",      "$update_dir/tty" );
+        &copy_code( "$source_dir/ncurses/widechar", "$update_dir/widechar" );
+        &copy_file( "$source_dir/include/Caps",           $update_dir );
+        &copy_file( "$source_dir/include/capdefaults.c",  $update_dir );
+        &copy_file( "$source_dir/include/curses.h",       $update_dir );
+        &copy_file( "$source_dir/include/hashed_db.h",    $update_dir );
+        &copy_file( "$source_dir/include/hashsize.h",     $update_dir );
+        &copy_file( "$source_dir/include/nc_alloc.h",     $update_dir );
+        &copy_file( "$source_dir/include/nc_panel.h",     $update_dir );
+        &copy_file( "$source_dir/include/nc_tparm.h",     $update_dir );
+        &copy_file( "$source_dir/include/ncurses_cfg.h",  $update_dir );
+        &copy_file( "$source_dir/include/ncurses_def.h",  $update_dir );
+        &copy_file( "$source_dir/include/ncurses_dll.h",  $update_dir );
+        &copy_file( "$source_dir/include/parametrized.h", $update_dir );
+        &copy_file( "$source_dir/include/term.h",         $update_dir );
+        &copy_file( "$source_dir/include/termcap.h",      $update_dir );
+        &copy_file( "$source_dir/include/term_entry.h",   $update_dir );
+        &copy_file( "$source_dir/include/tic.h",          $update_dir );
+        &copy_file( "$source_dir/include/unctrl.h",       $update_dir );
+        &copy_file( "$source_dir/man/terminfo.5",         $update_dir );
+        &copy_docs("curses");
+
+        &verbose(".. work around a bug in /bin/sh in OpenBSD");
+        system( "sed -i"
+              . " -e 's,^shift,test \$# != 0 \\&\\& shift,'"
+              . " $update_dir/tinfo/MKfallback.sh" );
+
+        # OpenBSD dropped support for sys/ttydev.h, without mentioning the
+        # system version.  Just trim it.
+        &verbose(".. work around mishandled sys/ttydef.h");
+        system( "sed -i"
+              . " -e '/__FreeBSD_version/s,|| defined(__OpenBSD__),,'"
+              . " $update_dir/tinfo/lib_baudrate.c" );
+
+        if ($opt_t) {
+            &copy_code( "$source_dir/ncurses/trace", "$update_dir/trace" );
+        }
+        else {
+            &copy_file( "$source_dir/ncurses/trace/lib_trace.c", $update_dir );
+            &copy_file( "$source_dir/ncurses/trace/visbuf.c",    $update_dir );
+        }
+        &copy_file( "$source_dir/include/nc_termios.h", $update_dir )
+          if ( &patchdate >= 20110625 );
+        &copy_file( "$source_dir/include/nc_string.h", $update_dir )
+          if ( &patchdate >= 20120222 );
+        &copy_file( "$source_dir/include/nc_access.h", $update_dir )
+          if ( &patchdate >= 20210626 );
+        &copy_file( "$source_dir/include/Caps-ncurses", $update_dir )
+          if ( &patchdate >= 20190302 );
+        &gen_1st_makefile;
+        &finish_dir;
+    }
+}
+
+sub setup_lib_libform() {
+    if ( &setup_dir("lib/libform") ) {
+        &copy_docs("form");
+        &gen_lib_makefile("form");
+        &finish_dir;
+    }
+}
+
+sub setup_lib_libmenu() {
+    if ( &setup_dir("lib/libmenu") ) {
+        &copy_docs("menu");
+        &gen_lib_makefile("menu");
+        &finish_dir;
+    }
+}
+
+sub setup_lib_libpanel() {
+    if ( &setup_dir("lib/libpanel") ) {
+        &copy_docs("panel");
+        &gen_lib_makefile("panel");
+        &finish_dir;
+    }
+}
+
+sub setup_bin_infocmp() {
+    if ( &setup_dir("usr.bin/infocmp") ) {
+        &copy_docs("infocmp");
+        &gen_bin_makefile("infocmp");
+        &finish_dir;
+    }
+}
+
+sub setup_bin_tabs() {
+    if ( &setup_dir("usr.bin/tabs") ) {
+        &copy_docs("tabs");
+        &gen_bin_makefile("tabs");
+        &finish_dir;
+    }
+}
+
+sub setup_bin_tic() {
+    if ( &setup_dir("usr.bin/tic") ) {
+        if ( &patchdate >= 20140521 ) {
+            &copy_file( "$source_dir/progs/tparm_type.c", $update_dir );
+            &copy_file( "$source_dir/progs/tparm_type.h", $update_dir );
+        }
+
+        # shared files for tput/tset
+        if ( &patchdate >= 20160806 ) {
+            &copy_file( "$source_dir/progs/reset_cmd.c", $update_dir );
+            &copy_file( "$source_dir/progs/reset_cmd.h", $update_dir );
+        }
+        if ( &patchdate >= 20161022 ) {
+            &copy_file( "$source_dir/progs/clear_cmd.c", $update_dir );
+            &copy_file( "$source_dir/progs/clear_cmd.h", $update_dir );
+        }
+        if ( &patchdate >= 20161224 ) {
+            &copy_file( "$source_dir/progs/tty_settings.c", $update_dir );
+            &copy_file( "$source_dir/progs/tty_settings.h", $update_dir );
+        }
+        &copy_docs("tic");
+        &gen_bin_makefile("tic");
+        &finish_dir;
+    }
+}
+
+sub setup_bin_toe() {
+    if ( &setup_dir("usr.bin/toe") ) {
+        &copy_docs("toe");
+        &gen_bin_makefile("toe");
+        &finish_dir;
+    }
+}
+
+sub setup_bin_tput() {
+    if ( &setup_dir("usr.bin/tput") ) {
+        &copy_docs("tput");
+        &gen_bin_makefile("tput");
+        &finish_dir;
+    }
+}
+
+sub setup_bin_tset() {
+    if ( &setup_dir("usr.bin/tset") ) {
+        &copy_docs("tset");
+        &gen_bin_makefile("tset");
+        &finish_dir;
+    }
+}
+
+sub setup_terminfo() {
+    if ( &setup_dir("share/termtypes") ) {
+        &copy_code( $target_dir, $update_dir );
+        &copy_file( "$source_dir/misc/terminfo.src",
+            "$update_dir/termtypes.master" );
+
+        # build the terminfo database using the in-tree tic.
+        # This is always best practice, but for ncurses 6.2 in particular is
+        # required.
+        my $prog = abs_path("$target_dir/../../usr.bin/tic");
+        my $libs = abs_path("$target_dir/../../lib/libcurses");
+        if ( defined $prog and defined $libs ) {
+            $prog .= "/tic";
+            &verbose(".. changing makefile to use in-tree tic");
+            system( "sed -i -E "
+                  . "-e 's,(TIC=).*,\\1\t$prog,' "
+                  . "-e 's,(\\\${TIC}),LD_LIBRARY_PATH=$libs \\1,' "
+                  . "$update_dir/Makefile" );
+        }
+        &finish_dir;
+    }
+}
+
+sub configure_tree() {
+    return if ( -f "ncurses/Makefile" );
+    my @search = ( "/usr/share/terminfo", "/usr/local/share/terminfo" );
+    my @prefix = ("./configure");
+    $prefix[ ++$#prefix ] = "--with-abi-version=5"
+      if ( &patchdate >= 20150502 && !$opt_6 );
+    my @options = (
+        "--with-ospeed=int",                               #
+        "--with-shared",                                   #
+        "--without-normal",                                #
+        "--without-debug",                                 #
+        "--with-terminfo-dirs=" . join( ':', @search ),    #
+        "--without-ada",                                   #
+        "--disable-hard-tabs",                             #
+        "--enable-const",                                  #
+        "--enable-getcap",                                 #
+        "--enable-bsdpad",                                 #
+        "--enable-signed-char",                            #
+        "--enable-termcap",                                #
+        "--enable-widec",                                  #
+        "--disable-setuid-environ"
+    );
+    $options[ ++$#options ] = "--with-trace" if ($opt_t);
+    $options[ ++$#options ] = "--enable-string-hacks"
+      if ( &patchdate >= 20120225 );
+    system( join( ' ', @prefix ) . ' ' . join( ' ', @options ) );
+    &failed("problem with configuring") unless ( -f "ncurses/Makefile" );
+
+    system("make sources");
+
+    # OpenBSD developers edit the generated file and do not regen it when
+    # doing upgrades.  This script reflects those edits.
+    system( "sed -i" . " -E"
+          . " -e '/TYPEOF_CHTYPE/s,int,long,'"
+          . " -e '/USE_TERMCAP/d'"
+          . " -e '/HAVE_LIB(FORM|MENU|PANEL)/s,^(.*)\$,/* \\1 */,'"
+          . " -e 's/TERMPATH.*/PURE_TERMINFO 0/'"
+          . " -e '/SYSTEM_NAME/s,\[0-9.\]+,,'"
+          . " include/ncurses_cfg.h" );
+}
+
+sub get_definitions() {
+    my @data = &read_file("dist.mk");
+    for my $n ( 0 .. $#data ) {
+        my $text = $data[$n];
+        $text =~ s/^\s*//;
+        next unless ( $text =~ /^NCURSES.*=/ );
+        $text =~ s/\s*=\s+/=/;
+        my $name = $text;
+        $name =~ s/=.*//;
+        my $value = $text;
+        $value =~ s/^[^=]*=//;
+        $value =~ s/\s.*//;
+        $definitions{$name} = $value;
+    }
+}
+
+sub setup_all_dirs() {
+    printf "** %s all build-directories\n", $opt_r ? "removing" : "setting up";
+    &get_definitions;
+    &configure_tree unless ($opt_r);
+    &setup_lib_libcurses;
+    &setup_lib_libmenu;
+    &setup_lib_libform;    # build after libmenu, for mf_common.h
+    &setup_lib_libpanel;
+    &setup_bin_tic;        # do this first, for shared headers
+    &setup_bin_infocmp;
+    &setup_bin_tabs if ( -f "$source_dir/progs/tabs.c" );
+    &setup_bin_toe;
+    &setup_bin_tput;
+    &setup_bin_tset;
+    &setup_terminfo;
+}
+
+sub usage() {
+    print <<EOF;
+Usage: ncu2openbsd [options] [sourcetree]
+
+Options:
+  -6       use ABI 6 rather than 5 if available
+  -d DST   specify destination (default: /usr/src)
+  -n       no-op, do not update destination
+  -r       remove update, restore sources from ".orig"
+  -t       enable ncurses trace
+  -v       verbose
+  -x       build each directory after setting up
+EOF
+    exit;
+}
+
+$Getopt::Std::STANDARD_HELP_VERSION = 1;
+&getopts('6d:nrtvx') || &usage();
+$opt_d = "/usr/src" unless ($opt_d);
+&usage() unless ( $#ARGV <= 0 );
+
+if ( $#ARGV == 0 ) {
+    if ( -f $ARGV[0] ) {
+        printf "** unpacking sources: %s\n", $ARGV[0];
+        &unpack( $ARGV[0] );
+    }
+    else {
+        &check_sourcedir( $ARGV[0] );
+    }
+}
+else {
+    &check_sourcedir(".");
+}
+
+&setup_all_dirs;
+
+# move out of temp-directory to allow cleanup.
+chdir $current;
+
+1;