2 # $Id: ncu2openbsd,v 1.67 2023/09/09 15:59:17 tom Exp $
3 # -----------------------------------------------------------------------------
4 # Copyright 2021,2023 by Thomas E. Dickey
8 # Permission is hereby granted, free of charge, to any person obtaining a
9 # copy of this software and associated documentation files (the
10 # "Software"), to deal in the Software without restriction, including
11 # without limitation the rights to use, copy, modify, merge, publish,
12 # distribute, sublicense, and/or sell copies of the Software, and to
13 # permit persons to whom the Software is furnished to do so, subject to
14 # the following conditions:
16 # The above copyright notice and this permission notice shall be included
17 # in all copies or substantial portions of the Software.
19 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
23 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 # Except as contained in this notice, the name(s) of the above copyright
28 # holders shall not be used in advertising or otherwise to promote the
29 # sale, use or other dealings in this Software without prior written
31 # -----------------------------------------------------------------------------
32 # https://invisible-island.net/ncurses/ncurses-openbsd.html
34 # Update the OpenBSD source-tree given an ncurses tarball or build-tree.
42 use File::Path qw/ remove_tree /;
43 use File::Temp qw/ tempdir /;
47 our ( $opt_d, $opt_n, $opt_r, $opt_t, $opt_v, $opt_x, $opt_6 );
53 our $tempdir = tempdir( CLEANUP => 1 );
55 my $working = $current;
57 our $generated_by = "generated by: ncu2openbsd";
90 our %definitions = qw(
98 NCURSES_PATCH 20081102
99 TERMINFO /usr/share/terminfo
107 return $definitions{"NCURSES_PATCH"};
112 printf STDERR "? %s\n", $_[0];
118 printf "%s\n", $text if ($opt_v);
123 open( my $fp, $name ) || &failed("cannot open $name");
133 if ( opendir( my $dh, $path ) ) {
134 my @data = sort readdir($dh);
136 for my $d ( 0 .. $#data ) {
137 next if ( $data[$d] =~ /^\.(\.)?$/ );
138 next if ( -l $path . "/" . $data[$d] );
139 $result[ $#result + 1 ] = $data[$d];
148 printf "%% mv %s -> %s\n", $src, $dst if ($opt_v);
149 rename $src, $dst unless ($opt_n);
152 sub check_sourcedir($) {
154 &failed("not a directory: $path") unless ( -d $path );
155 my $full = abs_path($path);
157 &failed("not an ncurses source-tree: $path")
158 unless ( -f "NEWS" and -f "dist.mk" );
164 my $full = abs_path($path);
166 if ( $path =~ /\.tgz$/ or $path =~ /\.tar\.gz$/ ) {
167 $command = "tar xzf %s";
169 elsif ( $path =~ /\.zip$/ ) {
170 $command = "unzip -q %s";
173 &failed("not a gzip'd tarball or zip-file: $path");
176 system( sprintf( $command, $full ) );
178 # there should be exactly one subdirectory -- the source-tree
179 my @data = &read_dir(".");
180 &failed("found no subdirectories of $path") if ( $#data < 0 );
181 &failed( "too many subdirectories: " . $data[0] . " vs " . $data[1] )
183 &check_sourcedir( $data[0] );
189 printf "%% rm -rf %s\n", $tree if ($opt_v);
190 remove_tree( $tree, $opt_v ? 1 : 0, 1 ) unless ($opt_n);
196 my $src = $target_dir . $leaf . "/CVS";
197 my $dst = $update_dir . $leaf . "/CVS";
198 my $verbose = $opt_v ? "v" : "";
199 if ( -d $src and !-d $dst ) {
200 my $mid = $update_dir . $leaf;
201 mkdir $mid unless ( -d $mid );
202 mkdir $dst unless ( -d $dst );
203 system("cp -a$verbose $src/* $dst/");
212 $item =~ /^(capconvert
227 $code = 1 if ( $text =~ /\$$name:.*\$/ );
231 # We "could", filter out differences with ident's using the diff -I option,
232 # but in practice, that is cumbersome.
235 my $source = $target;
236 $source =~ s/\.update\b//;
237 &failed("bug at $source") if ( $source eq $target );
238 return unless ( -f $source );
239 my @source = &read_file($source);
240 my @target = &read_file($target);
246 for my $n ( 0 .. $#source ) {
247 if ( &is_ident( "OpenBSD", $source[$n] ) ) {
248 $old_id = $source[$n];
251 elsif ( &is_ident( "Id", $source[$n] ) ) {
252 $new_id = $source[$n];
255 elsif ( $n == $skipit ) {
256 $source[$n] =~ s/\s+$//;
257 if ( $source[$n] eq "" ) {
258 $gap_id = $source[$n];
260 elsif ( $source[$n] eq '.\"' ) {
261 $gap_id = $source[$n];
265 if ( $old_id ne "" ) {
267 my $tables = &uses_tables($target);
268 $update[ $#update + 1 ] = $target[0] if ($tables);
269 $update[ $#update + 1 ] = $old_id;
270 $update[ $#update + 1 ] = $gap_id unless ( $gap_id eq 0 );
271 for my $n ( $tables .. $#target ) {
272 if ( &is_ident( "Id", $target[$n] ) ) {
273 $update[ $#update + 1 ] = $new_id;
276 $update[ $#update + 1 ] = $target[$n];
279 system("chmod u+w $target");
280 if ( open my $fp, ">", $target ) {
281 for my $n ( 0 .. $#update ) {
282 printf $fp "%s\n", $update[$n];
285 system("chmod u-w $target");
290 # ncurses manual pages provide for renaming the utilities, normally as part of
291 # the scripts provided in its sources. OpenBSD developers do not use those.
294 my @data = &read_file($path);
296 for my $n ( 0 .. $#data ) {
297 my $text = $data[$n];
298 $text =~ s/\b1M\b/1/g;
299 $text =~ s/\b3X\b/3/g;
300 $text =~ s/\bcurs_(term(info|cap)\s*3\b)/$1/g;
301 $text =~ s/(\\fB)curs_(term(info|cap)\\f[RP]\(3\))/$1$2/g;
303 while ( $text =~ /@[[:alnum:]_]+@/ ) {
304 my $next = index( $text, "@" );
305 last if ( $next < 0 );
306 $left .= substr( $text, 0, $next++ );
307 $text = substr( $text, $next );
308 $next = index( $text, "@" );
309 last if ( $next < 0 );
310 my $word = substr( $text, 0, $next );
311 if ( $word =~ /^[[:alnum:]_]+/ ) {
313 if ( $definitions{$word} ) {
314 $word = $definitions{$word};
320 $text = substr( $text, $next + 1 );
323 &failed("unexpected definition @$word@");
326 $text = $left . $text;
327 if ( $text ne $data[$n] ) {
333 system("chmod u+w $path");
334 if ( open my $fp, ">", $path ) {
335 for my $n ( 0 .. $#data ) {
336 printf $fp "%s\n", $data[$n];
339 system("chmod u-w $path");
347 my $verbose = $opt_v ? "v" : "";
353 system("chmod u+w $dst") if ( -f $dst );
354 system("cp -a$verbose $src $dst");
361 ©_CVS( substr( $dst, length($update_dir) ) );
362 printf ".. copying files for $dst\n";
363 my @data = &read_dir($src);
364 printf ".. %d entries\n", $#data + 1;
365 my $verbose = $opt_v ? "v" : "";
366 for my $d ( 0 .. $#data ) {
367 my $item = $data[$d];
368 my $src_item = $src . "/" . $item;
369 next if ( -d $src_item );
370 next if ( -l $src_item );
371 next if ( $item =~ /^\.(\.)?$/ );
372 next if ( $item =~ /\.(bak|in|log|status)$/ );
373 next if ( $item =~ /^llib-/ );
374 next if ( $item =~ /^modules/ );
375 next if ( $item =~ /^[fm]_trace\.c/ and not $opt_t );
377 if ( $item =~ /^Makefile/ and index( $update_dir, "/share/" ) < 0 );
378 next if ( $item =~ /^README/ );
379 next if ( $item eq "headers" );
380 next if ( $generated{$item} );
381 next if ( $item eq "link_test.c" );
383 if ( index( $dst, "/usr.bin/" ) >= 0 ) {
384 next if ( $item =~ /^(clear)/ ); # OpenBSD uses "tput clear"
387 $prog =~ s/(update|backup)//;
389 if ( $dst =~ /infocmp/ ) {
390 next if ( $item ne $prog );
392 elsif ( $dst =~ /tabs/ ) {
393 next if ( $item ne $prog );
395 elsif ( $dst =~ /tic/ ) {
396 next if ( &is_tic_code($item) == 0 );
398 elsif ( $dst =~ /toe/ ) {
399 next if ( $item ne $prog );
401 elsif ( $dst =~ /tput/ ) {
402 next if ( $item ne $prog );
404 elsif ( $dst =~ /tset/ ) {
405 next if ( $item ne $prog );
411 system( sprintf( "cp -a$verbose %s %s/%s", $src_item, $dst, $item ) );
412 &munge_ident("$dst/$item");
416 # Checking if nroff supports tables is a long-obsolete issue, and is not really
417 # necessary, except to match OpenBSD's source-tree.
420 my @docs = &read_file($docs);
422 for my $n ( 0 .. $#docs ) {
423 if ( $docs[$n] =~ /^[.']\\"\s+t\b.*/ ) {
427 elsif ( $docs[$n] =~ /^\./ ) {
436 my $src = "$source_dir/man/$docs";
437 my $dst = "$update_dir/$docs";
438 $src .= "m" if ( -f "${src}m" );
440 if ( $dst =~ /\.3/ ) {
441 $dst =~ s/\bncurses/curses/ if ( $dst =~ /ncurses\./ );
442 $dst =~ s/\bcurs_// if ( $dst =~ /_term(cap|info)\./ );
444 ©_file( $src, $dst );
450 if ( index( $update_dir, "/usr.bin/" ) >= 0 ) {
451 ©_1doc( $docs . ".1" );
452 if ( $docs eq "tic" ) {
453 ©_1doc("captoinfo.1");
454 ©_1doc("infotocap.1");
458 my @docs = &read_dir("$source_dir/man");
459 if ( $docs eq "curses" ) {
460 for my $n ( 0 .. $#docs ) {
461 next if ( $docs[$n] eq "Makefile" );
462 next if ( $docs[$n] eq "make_sed.sh" );
463 next if ( $docs[$n] eq "man_db.renames" );
464 next if ( $docs[$n] eq "manlinks.sed" );
465 next if ( $docs[$n] =~ /\.(1|head|tail|in)/ );
466 next if ( $docs[$n] =~ /^(form|menu|mitem|panel)/ );
467 ©_1doc( $docs[$n] );
470 elsif ( $docs eq "form" ) {
471 for my $n ( 0 .. $#docs ) {
472 next unless ( $docs[$n] =~ /^form/ );
473 ©_1doc( $docs[$n] );
476 elsif ( $docs eq "menu" ) {
477 for my $n ( 0 .. $#docs ) {
478 next unless ( $docs[$n] =~ /^(menu|mitem)/ );
479 ©_1doc( $docs[$n] );
482 elsif ( $docs eq "panel" ) {
483 for my $n ( 0 .. $#docs ) {
484 next unless ( $docs[$n] =~ /^panel/ );
485 ©_1doc( $docs[$n] );
493 &failed("no definition for $dst")
494 unless ( defined $setup_dir{$dst} or $opt_r );
495 $target_dir = sprintf( "%s/%s", $opt_d, $dst );
496 $update_dir = $target_dir . ".update";
497 $backup_dir = $target_dir . ".backup";
500 &remove_dir($update_dir);
501 if ( $target_dir =~ /\/(tabs|toe)$/ ) {
502 &remove_dir($target_dir);
504 elsif ( -d $backup_dir ) {
505 &remove_dir($target_dir);
506 &rename_dir( $backup_dir, $target_dir );
510 &remove_dir($update_dir);
513 # reuse the shared-library version, assuming ABI=5 would involve at
514 # most a minor-version bump.
515 ©_file( "$target_dir/shlib_version", $update_dir )
516 if ( $dst =~ /^lib\// );
517 ©_code( $source_dir . "/" . $setup_dir{$dst}, $update_dir )
518 unless ( $setup_dir{$dst} eq "misc" );
526 printf "%% %s\n", $command if ($opt_v);
531 printf "** $target_dir\n";
532 system("diff -Naurb $target_dir $update_dir | diffstat -n 30")
533 if ( -d $target_dir );
535 &do_build("cd $update_dir && make -n") if ($opt_x);
538 if ( -d $backup_dir ) {
539 printf STDERR "? backup directory exists: %s\n", $backup_dir;
542 &rename_dir( $target_dir, $backup_dir );
543 &rename_dir( $update_dir, $target_dir );
545 &do_build("cd $target_dir && make") if ($opt_x);
549 ################################################################################
551 sub only_c_files($) {
552 my @data = @{ $_[0] };
554 for my $n ( 0 .. $#data ) {
555 my $text = $data[$n];
556 $data{$text}++ if ( $text =~ /\.c$/ );
558 return sort keys %data;
561 sub makefile_list($$$) {
562 my @data = @{ $_[0] };
567 for my $n ( 0 .. $#data ) {
568 my $text = $data[$n];
570 next if ( index( $text, $skip ) == 0 );
574 $state = 1 if ( $text =~ /^${name}=/ );
575 next unless ( $state == 1 );
577 if ( index( $text, "(trace)" ) >= 0 and not $opt_t ) {
578 next unless ( $text =~ /\b(lib_trace|visbuf)\.c$/ );
581 next if ( $text =~ /\b[fm]_trace\.c$/ );
586 next if ( $text eq "link_test.c" );
587 next if ( $text eq "mf_common.h" );
588 next if ( $text eq "transform.h" );
589 $data{$text}++ if ( $text ne "" );
590 last if ( $data[$n] !~ /\\$/ );
592 return sort keys %data;
595 sub manpage_list($) {
597 my @data = &read_dir($path);
599 for my $n ( 0 .. $#data ) {
600 my $text = $data[$n];
601 $data{$text}++ if ( $text =~ /\.\d$/ );
603 return sort keys %data;
609 for my $n ( 0 .. length($string) - 1 ) {
610 my $c = substr( $string, $n, 1 );
615 elsif ( $c eq "\n" ) {
625 sub format_list($$) {
627 my @data = @{ $_[1] };
628 my $keep = ( defined $_[2] ) ? 1 : 0;
631 if ( length($name) >= 9 ) {
633 $base = length($name) + 1;
639 my $result = sprintf( "%s%s", $name, $fill );
642 for my $n ( 0 .. $#data ) {
643 $data{ $data[$n] } = 1 if ( defined $data[$n] );
645 @data = sort keys %data;
647 for my $n ( 0 .. $#data ) {
648 my $data = $data[$n];
649 my $col = &columns_of($result);
650 my $add = 1 + length($data);
651 if ( ( $col + $add ) > 76 ) {
652 $result .= " " if ( $col > $base );
655 $result .= "\\\n" . $fill . $data;
658 $result .= " " if ( $col > $base );
665 ################################################################################
667 sub compare_makefiles($) {
671 ( -d $backup_dir ? $backup_dir : $target_dir ) . "/Makefile";
672 system("diff -u $bakfile $newfile") if ( -f $bakfile );
676 # The curses makefile has to build build-time utilities and generate source.
677 sub gen_1st_makefile() {
678 my $libname = "curses";
679 my $oldfile = "$source_dir/n$libname/Makefile";
680 my @oldfile = &read_file($oldfile);
682 my $newfile = "$update_dir/Makefile";
683 open( my $fp, ">", $newfile ) || &failed("cannot open $newfile");
685 '${.CURDIR}/base', '${.CURDIR}/tinfo',
686 '${.CURDIR}/tty', '${.CURDIR}/widechar'
688 $subdirs[ $#subdirs + 1 ] = '${.CURDIR}/trace' if ($opt_t);
694 # Uncomment this to enable tracing in libcurses
697 # This is used to compile terminal info directly into the library
700 # XXX - should be defined elsewhere
705 printf $fp "%s\n", &format_list( ".PATH:", \@subdirs );
707 my @autosrc = &makefile_list( \@oldfile, "AUTO_SRC", "?" );
708 my @auto_cc = &only_c_files( \@autosrc );
709 printf $fp "%s\n", &format_list( "SRCS=", \@auto_cc );
711 my @sources = &makefile_list( \@oldfile, "C_SRC", "./" );
712 printf $fp "%s\n", &format_list( "SRCS+=", \@sources );
716 HOSTCFLAGS?= \${CFLAGS}
717 HOSTLDFLAGS?= \${LDFLAGS}
718 HOSTCFLAGS+= -I. -I\${.CURDIR} \${CURSESTRACE}
719 CFLAGS+= -I. -I\${.CURDIR} \${CURSESTRACE} -D_XOPEN_SOURCE_EXTENDED -DNDEBUG
722 my @manpages = &manpage_list($update_dir);
723 printf $fp "%s\n", &format_list( "MAN=", \@manpages );
725 $autosrc[ $#autosrc++ ] = "make_hash";
726 $autosrc[ $#autosrc++ ] = "make_keys";
727 printf $fp "%s\n", &format_list( "GENERATED=", \@autosrc );
730 CAPLIST = \${.CURDIR}/Caps
733 CLEANFILES+= \${GENERATED}
735 BUILDFIRST = \${GENERATED}
738 \@cmp -s \${DESTDIR}/usr/include/ncurses.h \${.CURDIR}/curses.h || \\
739 \${INSTALL} \${INSTALL_COPY} -m 444 -o \$(BINOWN) -g \$(BINGRP) \\
740 \${.CURDIR}/curses.h \${DESTDIR}/usr/include/ncurses.h
741 \@cd \${.CURDIR}; for i in ncurses_dll.h unctrl.h term.h termcap.h; do \\
742 cmp -s \$\$i \${DESTDIR}/usr/include/\$\$i || \\
743 \${INSTALL} \${INSTALL_COPY} -m 444 -o \$(BINOWN) -g \$(BINGRP) \$\$i \\
744 \${DESTDIR}/usr/include; done
746 keys.list: \${.CURDIR}/tinfo/MKkeys_list.sh
747 sh \${.CURDIR}/tinfo/MKkeys_list.sh \${.CURDIR}/Caps | sort > \${.TARGET}
749 fallback.c: \${.CURDIR}/tinfo/MKfallback.sh
750 sh \${.CURDIR}/tinfo/MKfallback.sh /usr/share/terminfo \${.CURDIR}/../../share/termtypes/termtypes.master \$(FALLBACK_LIST) > \${.TARGET}
752 lib_gen.c: \${.CURDIR}/base/MKlib_gen.sh
753 sh \${.CURDIR}/base/MKlib_gen.sh "\${CC} -E -P -I\${.CURDIR}" \\
754 "\${AWK}" generated < \${.CURDIR}/curses.h > lib_gen.c
756 init_keytry.h: make_keys keys.list
757 ./make_keys keys.list > \${.TARGET}
759 make_keys: \${.CURDIR}/tinfo/make_keys.c \${.CURDIR}/curses.priv.h names.c
760 \${HOSTCC} \${LDSTATIC} \${HOSTCFLAGS} \${HOSTLDFLAGS} \\
761 -o \${.TARGET} \${.CURDIR}/tinfo/make_keys.c \${LDADD}
764 if ( &patchdate >= 20090808 ) {
766 make_hash: \${.CURDIR}/tinfo/make_hash.c \\
767 \${.CURDIR}/curses.priv.h \\
768 \${.CURDIR}/hashsize.h
769 \${HOSTCC} \${LDSTATIC} \${HOSTCFLAGS} -DMAIN_PROGRAM \${HOSTLDFLAGS} \\
770 -o \${.TARGET} \${.CURDIR}/tinfo/make_hash.c \${LDADD}
775 make_hash: \${.CURDIR}/tinfo/comp_hash.c \\
776 \${.CURDIR}/curses.priv.h \\
777 \${.CURDIR}/hashsize.h
778 \${HOSTCC} \${LDSTATIC} \${HOSTCFLAGS} -DMAIN_PROGRAM \${HOSTLDFLAGS} \\
779 -o \${.TARGET} \${.CURDIR}/tinfo/comp_hash.c \${LDADD}
783 if ( &patchdate >= 20190309 ) {
785 CAPLIST += \${.CURDIR}/Caps-ncurses
787 comp_userdefs.c: make_hash \\
788 \${.CURDIR}/hashsize.h \\
789 \${.CURDIR}/tinfo/MKuserdefs.sh
790 sh \${.CURDIR}/tinfo/MKuserdefs.sh \${AWK} \${USE_BIG_STRINGS} \${CAPLIST} > \${.TARGET}
795 expanded.c: \${.CURDIR}/term.h \${.CURDIR}/curses.priv.h \\
796 \${.CURDIR}/ncurses_cfg.h \${.CURDIR}/tty/MKexpanded.sh
797 sh \${.CURDIR}/tty/MKexpanded.sh "\${CC} -E -P" \${CPPFLAGS} > \${.TARGET}
799 comp_captab.c: make_hash
800 sh \${.CURDIR}/tinfo/MKcaptab.sh \${AWK} \${USE_BIG_STRINGS} \\
801 \${.CURDIR}/tinfo/MKcaptab.awk \${CAPLIST} > \${.TARGET}
803 lib_keyname.c: keys.list \${.CURDIR}/base/MKkeyname.awk
804 \${AWK} -f \${.CURDIR}/base/MKkeyname.awk \\
805 bigstrings=\${USE_BIG_STRINGS} \\
806 keys.list > \${.TARGET}
808 names.c: \${.CURDIR}/tinfo/MKnames.awk
809 \${AWK} -f \${.CURDIR}/tinfo/MKnames.awk \\
810 bigstrings=\${USE_BIG_STRINGS} \\
811 \${CAPLIST} > \${.TARGET}
812 codes.c: \${.CURDIR}/tinfo/MKcodes.awk
813 \${AWK} -f \${.CURDIR}/tinfo/MKcodes.awk \\
814 bigstrings=\${USE_BIG_STRINGS} \\
815 \${CAPLIST} > \${.TARGET}
817 unctrl.c: \${.CURDIR}/base/MKunctrl.awk
818 echo | \${AWK} -f \${.CURDIR}/base/MKunctrl.awk bigstrings=1 > \${.TARGET}
820 .include <bsd.own.mk>
822 # Link libtermlib, libtermcap to libcurses so we don't break people's Makefiles
824 -cd \${DESTDIR}\${LIBDIR}; \\
825 for i in \${_LIBS}; do \\
826 ln -f \$\$i `echo \$\$i | sed 's/curses/termlib/'`; \\
827 ln -f \$\$i `echo \$\$i | sed 's/curses/termcap/'`; \\
828 ln -f \$\$i `echo \$\$i | sed 's/curses/ncurses/'`; \\
829 ln -f \$\$i `echo \$\$i | sed 's/curses/ncursesw/'`; \\
832 .include <bsd.lib.mk>
835 &compare_makefiles($newfile);
838 sub gen_lib_makefile($) {
840 my $oldfile = "$source_dir/$libname/Makefile";
841 my @oldfile = &read_file($oldfile);
843 # in ncurses, header-files are quasi-generated, because the original
844 # header file for form/menu/panel lives in the source-directory, but is
845 # copied to the include-directory with "make sources".
846 my @headers = &makefile_list( \@oldfile, "AUTO_SRC", "?" );
848 # The C source is more straightforward.
849 my @sources = &makefile_list( \@oldfile, "C_SRC", "?" );
850 my $newfile = "$update_dir/Makefile";
851 open( my $fp, ">", $newfile ) || &failed("cannot open $newfile");
858 printf $fp "%s\n", &format_list( "SRCS=", \@sources );
859 printf $fp "%s\n", &format_list( "HDRS=", \@headers );
860 my $includes = '-I${.CURDIR}/../libcurses';
861 $includes .= ' -I${.CURDIR}/../libmenu' if ( $libname eq "form" );
863 CFLAGS+=$includes -D_XOPEN_SOURCE_EXTENDED -DNDEBUG
865 my @manpages = &manpage_list($update_dir);
866 printf $fp "%s\n", &format_list( "MAN=", \@manpages );
870 \@cd \$\{.CURDIR}; for i in \$\{HDRS}; do \\
871 cmp -s \$\$i \${DESTDIR}/usr/include/\$\$i || \\
872 \${INSTALL} \${INSTALL_COPY} -m 444 -o \$(BINOWN) -g \$(BINGRP) \$\$i \\
873 \${DESTDIR}/usr/include; done
875 .include <bsd.own.mk>
878 -cd \${DESTDIR}\${LIBDIR}; \\
879 for i in \${_LIBS}; do \\
880 ln -f \$\$i `echo \$\$i | sed 's/${libname}/${libname}w/'`; \\
883 .include <bsd.lib.mk>
886 &compare_makefiles($newfile);
889 sub gen_bin_makefile($) {
891 my $oldfile = "$source_dir/progs/Makefile";
892 my @oldfile = &read_file($oldfile);
893 my $newfile = "$update_dir/Makefile";
895 open( my $fp, ">", $newfile ) || &failed("cannot open $newfile");
896 my @sources = ("$binname.c");
898 my @autosrc = &makefile_list( \@oldfile, "AUTO_SRC", "?" );
901 my $use_dump_entry = 0;
902 my $use_termsort = 0;
903 my $use_tparm_type = 0;
904 my $use_transform = 0;
906 $use_dump_entry = 1 if ( $binname eq "infocmp" or $binname eq "tic" );
907 $use_termsort = 1 if ( $use_dump_entry or $binname eq "tput" );
909 if ( &patchdate >= 20090314 ) {
910 $use_transform = 1 if ( $binname =~ /^(tic|tput|tset)/ );
912 if ( &patchdate >= 20140521 ) {
913 $use_tparm_type = 1 if ( $binname =~ /^(tic|tput)$/ );
915 if ( &patchdate >= 20160806 ) {
916 $tput_ver = &patchdate;
919 $sources[ ++$#sources ] = "dump_entry.c" if ($use_dump_entry);
920 $sources[ ++$#sources ] = "tparm_type.c" if ($use_tparm_type);
921 $sources[ ++$#sources ] = "transform.c" if ($use_transform);
923 $autosrc[ ++$#autosrc ] = "termsort.c" if ($use_termsort);
925 # transform.h also is generated, but OpenBSD checked-in a copy
927 if ( $binname eq "tic" ) {
928 $links[ ++$#links ] = "captoinfo";
929 $links[ ++$#links ] = "infotocap";
931 elsif ( $binname eq "tabs" ) {
932 $sources[ ++$#sources ] = "tty_settings.c" if ( $tput_ver >= 20161224 );
934 elsif ( $binname eq "tput" ) {
935 $sources[ ++$#sources ] = "clear_cmd.c" if ( $tput_ver >= 20161022 );
936 $sources[ ++$#sources ] = "reset_cmd.c" if ( $tput_ver >= 20160806 );
937 $sources[ ++$#sources ] = "tty_settings.c" if ( $tput_ver >= 20161224 );
938 $links[ ++$#links ] = "clear";
940 elsif ( $binname eq "tset" ) {
941 $sources[ ++$#sources ] = "reset_cmd.c" if ( $tput_ver >= 20160806 );
942 $sources[ ++$#sources ] = "tty_settings.c" if ( $tput_ver >= 20161224 );
943 $links[ ++$#links ] = "reset";
951 printf $fp "%s\n", &format_list( "SRCS=", \@sources );
953 CURSES= \${.CURDIR}/../../lib/libcurses
955 LDADD= -L\${CURSES} -lcurses\t# in-tree link to add _nc_strict_bsd, etc
957 if ( $#links >= 0 ) {
959 for my $n ( 0 .. $#links ) {
960 $bin_links[ ++$#bin_links ] = '${BINDIR}/' . $binname;
961 $bin_links[ ++$#bin_links ] = '${BINDIR}/' . $links[$n];
963 printf $fp "%s\n", &format_list( "LINKS=", \@bin_links, 1 );
965 my $ticfix = '${.CURDIR}/';
966 if ( $binname eq "tic" ) {
968 CFLAGS+= -I\${CURSES} -I\${.CURDIR} -I.
974 TIC= \${.CURDIR}/../tic
975 CFLAGS+= -I\${CURSES} -I\${TIC} -I\${.CURDIR} -I.
979 printf $fp "%s\n", &format_list( "CLEANFILES+=", \@autosrc );
980 if ($use_dump_entry) {
983 dump_entry.o: termsort.c
989 termsort.c: ${ticfix}MKtermsort.sh
990 sh ${ticfix}MKtermsort.sh awk \${CURSES}/Caps > \${.TARGET}
995 .include <bsd.prog.mk>
999 &compare_makefiles($newfile);
1002 ################################################################################
1004 sub setup_lib_libcurses() {
1005 if ( &setup_dir("lib/libcurses") ) {
1006 ©_code( "$source_dir/ncurses/base", "$update_dir/base" );
1007 ©_code( "$source_dir/ncurses/tinfo", "$update_dir/tinfo" );
1008 ©_code( "$source_dir/ncurses/tty", "$update_dir/tty" );
1009 ©_code( "$source_dir/ncurses/widechar", "$update_dir/widechar" );
1010 ©_file( "$source_dir/include/Caps", $update_dir );
1011 ©_file( "$source_dir/include/capdefaults.c", $update_dir );
1012 ©_file( "$source_dir/include/curses.h", $update_dir );
1013 ©_file( "$source_dir/include/hashed_db.h", $update_dir );
1014 ©_file( "$source_dir/include/hashsize.h", $update_dir );
1015 ©_file( "$source_dir/include/nc_alloc.h", $update_dir );
1016 ©_file( "$source_dir/include/nc_panel.h", $update_dir );
1017 ©_file( "$source_dir/include/nc_tparm.h", $update_dir );
1018 ©_file( "$source_dir/include/ncurses_cfg.h", $update_dir );
1019 ©_file( "$source_dir/include/ncurses_def.h", $update_dir );
1020 ©_file( "$source_dir/include/ncurses_dll.h", $update_dir );
1021 ©_file( "$source_dir/include/parametrized.h", $update_dir );
1022 ©_file( "$source_dir/include/term.h", $update_dir );
1023 ©_file( "$source_dir/include/termcap.h", $update_dir );
1024 ©_file( "$source_dir/include/term_entry.h", $update_dir );
1025 ©_file( "$source_dir/include/tic.h", $update_dir );
1026 ©_file( "$source_dir/include/unctrl.h", $update_dir );
1027 ©_file( "$source_dir/man/terminfo.5", $update_dir );
1028 ©_docs("curses");
1030 &verbose(".. work around a bug in /bin/sh in OpenBSD");
1032 . " -e 's,^shift,test \$# != 0 \\&\\& shift,'"
1033 . " $update_dir/tinfo/MKfallback.sh" );
1035 # OpenBSD dropped support for sys/ttydev.h, without mentioning the
1036 # system version. Just trim it.
1037 &verbose(".. work around mishandled sys/ttydef.h");
1039 . " -e '/__FreeBSD_version/s,|| defined(__OpenBSD__),,'"
1040 . " $update_dir/tinfo/lib_baudrate.c" );
1043 ©_code( "$source_dir/ncurses/trace", "$update_dir/trace" );
1046 ©_file( "$source_dir/ncurses/trace/lib_trace.c", $update_dir );
1047 ©_file( "$source_dir/ncurses/trace/visbuf.c", $update_dir );
1049 ©_file( "$source_dir/include/nc_termios.h", $update_dir )
1050 if ( &patchdate >= 20110625 );
1051 ©_file( "$source_dir/include/nc_string.h", $update_dir )
1052 if ( &patchdate >= 20120222 );
1053 ©_file( "$source_dir/include/nc_access.h", $update_dir )
1054 if ( &patchdate >= 20210626 );
1055 ©_file( "$source_dir/include/Caps-ncurses", $update_dir )
1056 if ( &patchdate >= 20190302 );
1062 sub setup_lib_libform() {
1063 if ( &setup_dir("lib/libform") ) {
1065 &gen_lib_makefile("form");
1070 sub setup_lib_libmenu() {
1071 if ( &setup_dir("lib/libmenu") ) {
1073 &gen_lib_makefile("menu");
1078 sub setup_lib_libpanel() {
1079 if ( &setup_dir("lib/libpanel") ) {
1080 ©_docs("panel");
1081 &gen_lib_makefile("panel");
1086 sub setup_bin_infocmp() {
1087 if ( &setup_dir("usr.bin/infocmp") ) {
1088 ©_docs("infocmp");
1089 &gen_bin_makefile("infocmp");
1094 sub setup_bin_tabs() {
1095 if ( &setup_dir("usr.bin/tabs") ) {
1097 &gen_bin_makefile("tabs");
1102 sub setup_bin_tic() {
1103 if ( &setup_dir("usr.bin/tic") ) {
1104 if ( &patchdate >= 20140521 ) {
1105 ©_file( "$source_dir/progs/tparm_type.c", $update_dir );
1106 ©_file( "$source_dir/progs/tparm_type.h", $update_dir );
1109 # shared files for tput/tset
1110 if ( &patchdate >= 20160806 ) {
1111 ©_file( "$source_dir/progs/reset_cmd.c", $update_dir );
1112 ©_file( "$source_dir/progs/reset_cmd.h", $update_dir );
1114 if ( &patchdate >= 20161022 ) {
1115 ©_file( "$source_dir/progs/clear_cmd.c", $update_dir );
1116 ©_file( "$source_dir/progs/clear_cmd.h", $update_dir );
1118 if ( &patchdate >= 20161224 ) {
1119 ©_file( "$source_dir/progs/tty_settings.c", $update_dir );
1120 ©_file( "$source_dir/progs/tty_settings.h", $update_dir );
1123 &gen_bin_makefile("tic");
1128 sub setup_bin_toe() {
1129 if ( &setup_dir("usr.bin/toe") ) {
1131 &gen_bin_makefile("toe");
1136 sub setup_bin_tput() {
1137 if ( &setup_dir("usr.bin/tput") ) {
1139 &gen_bin_makefile("tput");
1144 sub setup_bin_tset() {
1145 if ( &setup_dir("usr.bin/tset") ) {
1147 &gen_bin_makefile("tset");
1152 sub setup_terminfo() {
1153 if ( &setup_dir("share/termtypes") ) {
1154 ©_code( $target_dir, $update_dir );
1155 ©_file( "$source_dir/misc/terminfo.src",
1156 "$update_dir/termtypes.master" );
1158 # build the terminfo database using the in-tree tic.
1159 # This is always best practice, but for ncurses 6.2 in particular is
1161 my $prog = abs_path("$target_dir/../../usr.bin/tic");
1162 my $libs = abs_path("$target_dir/../../lib/libcurses");
1163 if ( defined $prog and defined $libs ) {
1165 &verbose(".. changing makefile to use in-tree tic");
1166 system( "sed -i -E "
1167 . "-e 's,(TIC=).*,\\1\t$prog,' "
1168 . "-e 's,(\\\${TIC}),LD_LIBRARY_PATH=$libs \\1,' "
1169 . "$update_dir/Makefile" );
1175 sub configure_tree() {
1176 return if ( -f "ncurses/Makefile" );
1177 my @search = ( "/usr/share/terminfo", "/usr/local/share/terminfo" );
1178 my @prefix = ("./configure");
1179 $prefix[ ++$#prefix ] = "--with-abi-version=5"
1180 if ( &patchdate >= 20150502 && !$opt_6 );
1182 "--with-ospeed=int", #
1184 "--without-normal", #
1185 "--without-debug", #
1186 "--with-terminfo-dirs=" . join( ':', @search ), #
1188 "--disable-hard-tabs", #
1190 "--enable-getcap", #
1191 "--enable-bsdpad", #
1192 "--enable-signed-char", #
1193 "--enable-termcap", #
1195 "--disable-setuid-environ"
1197 $options[ ++$#options ] = "--with-trace" if ($opt_t);
1198 $options[ ++$#options ] = "--enable-string-hacks"
1199 if ( &patchdate >= 20120225 );
1200 system( join( ' ', @prefix ) . ' ' . join( ' ', @options ) );
1201 &failed("problem with configuring") unless ( -f "ncurses/Makefile" );
1203 system("make sources");
1205 # OpenBSD developers edit the generated file and do not regen it when
1206 # doing upgrades. This script reflects those edits.
1207 system( "sed -i" . " -E"
1208 . " -e '/TYPEOF_CHTYPE/s,int,long,'"
1209 . " -e '/USE_TERMCAP/d'"
1210 . " -e '/HAVE_LIB(FORM|MENU|PANEL)/s,^(.*)\$,/* \\1 */,'"
1211 . " -e 's/TERMPATH.*/PURE_TERMINFO 0/'"
1212 . " -e '/SYSTEM_NAME/s,\[0-9.\]+,,'"
1213 . " include/ncurses_cfg.h" );
1216 sub get_definitions() {
1217 my @data = &read_file("dist.mk");
1218 for my $n ( 0 .. $#data ) {
1219 my $text = $data[$n];
1221 next unless ( $text =~ /^NCURSES.*=/ );
1222 $text =~ s/\s*=\s+/=/;
1226 $value =~ s/^[^=]*=//;
1228 $definitions{$name} = $value;
1232 sub setup_all_dirs() {
1233 printf "** %s all build-directories\n", $opt_r ? "removing" : "setting up";
1235 &configure_tree unless ($opt_r);
1236 &setup_lib_libcurses;
1238 &setup_lib_libform; # build after libmenu, for mf_common.h
1239 &setup_lib_libpanel;
1240 &setup_bin_tic; # do this first, for shared headers
1242 &setup_bin_tabs if ( -f "$source_dir/progs/tabs.c" );
1251 Usage: ncu2openbsd [options] [sourcetree]
1254 -6 use ABI 6 rather than 5 if available
1255 -d DST specify destination (default: /usr/src)
1256 -n no-op, do not update destination
1257 -r remove update, restore sources from ".orig"
1258 -t enable ncurses trace
1260 -x build each directory after setting up
1265 $Getopt::Std::STANDARD_HELP_VERSION = 1;
1266 &getopts('6d:nrtvx') || &usage();
1267 $opt_d = "/usr/src" unless ($opt_d);
1268 &usage() unless ( $#ARGV <= 0 );
1270 if ( $#ARGV == 0 ) {
1271 if ( -f $ARGV[0] ) {
1272 printf "** unpacking sources: %s\n", $ARGV[0];
1273 &unpack( $ARGV[0] );
1276 &check_sourcedir( $ARGV[0] );
1280 &check_sourcedir(".");
1285 # move out of temp-directory to allow cleanup.