aboutsummaryrefslogtreecommitdiff
path: root/contrib/ncurses/progs
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ncurses/progs')
-rwxr-xr-xcontrib/ncurses/progs/MKtermsort.sh121
-rw-r--r--contrib/ncurses/progs/Makefile.in243
-rwxr-xr-xcontrib/ncurses/progs/capconvert229
-rw-r--r--contrib/ncurses/progs/clear.c58
-rwxr-xr-xcontrib/ncurses/progs/clear.sh1
-rw-r--r--contrib/ncurses/progs/dump_entry.c913
-rw-r--r--contrib/ncurses/progs/dump_entry.h60
-rw-r--r--contrib/ncurses/progs/infocmp.c1321
-rw-r--r--contrib/ncurses/progs/modules40
-rw-r--r--contrib/ncurses/progs/progs.priv.h160
-rw-r--r--contrib/ncurses/progs/tic.c812
-rw-r--r--contrib/ncurses/progs/toe.c303
-rw-r--r--contrib/ncurses/progs/tput.c312
-rw-r--r--contrib/ncurses/progs/tset.c1200
14 files changed, 5773 insertions, 0 deletions
diff --git a/contrib/ncurses/progs/MKtermsort.sh b/contrib/ncurses/progs/MKtermsort.sh
new file mode 100755
index 000000000000..6cbe9548354e
--- /dev/null
+++ b/contrib/ncurses/progs/MKtermsort.sh
@@ -0,0 +1,121 @@
+#!/bin/sh
+#
+# MKtermsort.sh -- generate indirection vectors for the various sort methods
+#
+# The output of this script is C source for nine arrays that list three sort
+# orders for each of the three different classes of terminfo capabilities.
+#
+AWK=${1-awk}
+DATA=${2-../include/Caps}
+
+echo "/*";
+echo " * termsort.c --- sort order arrays for use by infocmp.";
+echo " *";
+echo " * Note: this file is generated using termsort.sh, do not edit by hand.";
+echo " */";
+
+echo "static const int bool_terminfo_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "bool" {printf("%s\t%d\n", $2, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int num_terminfo_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "num" {printf("%s\t%d\n", $2, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int str_terminfo_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "str" {printf("%s\t%d\n", $2, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int bool_variable_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "bool" {printf("%s\t%d\n", $1, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int num_variable_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "num" {printf("%s\t%d\n", $1, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int str_variable_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "str" {printf("%s\t%d\n", $1, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int bool_termcap_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "bool" {printf("%s\t%d\n", $4, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int num_termcap_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "num" {printf("%s\t%d\n", $4, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int str_termcap_sort[] = {";
+$AWK <$DATA '
+BEGIN {i = 0;}
+/^#/ {next;}
+$3 == "str" {printf("%s\t%d\n", $4, i++);}
+' | sort | $AWK '{print "\t", $2, ",\t/* ", $1, " */";}';
+echo "};";
+echo "";
+
+echo "static const int bool_from_termcap[] = {";
+$AWK <$DATA '
+$3 == "bool" && substr($5, 1, 1) == "-" {print "0,\t/* ", $2, " */";}
+$3 == "bool" && substr($5, 1, 1) == "Y" {print "1,\t/* ", $2, " */";}
+'
+echo "};";
+echo "";
+
+echo "static const int num_from_termcap[] = {";
+$AWK <$DATA '
+$3 == "num" && substr($5, 1, 1) == "-" {print "0,\t/* ", $2, " */";}
+$3 == "num" && substr($5, 1, 1) == "Y" {print "1,\t/* ", $2, " */";}
+'
+echo "};";
+echo "";
+
+echo "static const int str_from_termcap[] = {";
+$AWK <$DATA '
+$3 == "str" && substr($5, 1, 1) == "-" {print "0,\t/* ", $2, " */";}
+$3 == "str" && substr($5, 1, 1) == "Y" {print "1,\t/* ", $2, " */";}
+'
+echo "};";
+echo "";
+
diff --git a/contrib/ncurses/progs/Makefile.in b/contrib/ncurses/progs/Makefile.in
new file mode 100644
index 000000000000..f22a016843bc
--- /dev/null
+++ b/contrib/ncurses/progs/Makefile.in
@@ -0,0 +1,243 @@
+# $Id: Makefile.in,v 1.37 1998/05/31 00:07:33 tom Exp $
+##############################################################################
+# Copyright (c) 1998 Free Software Foundation, Inc. #
+# #
+# 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, distribute #
+# with modifications, 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 COPYRIGHT HOLDERS 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. #
+##############################################################################
+#
+# Author: Thomas E. Dickey <dickey@clark.net> 1996,1997
+#
+# Makefile for ncurses source code.
+#
+# This makes the ncurses utility programs.
+#
+# The variable 'srcdir' refers to the source-distribution, and can be set with
+# the configure script by "--srcdir=DIR".
+#
+# The rules are organized to produce the libraries for the configured models,
+# and the programs with the configured default model.
+
+# turn off _all_ suffix rules; we'll generate our own
+.SUFFIXES:
+
+SHELL = /bin/sh
+THIS = Makefile
+
+CF_MFLAGS = @cf_cv_makeflags@
+@SET_MAKE@
+x = @PROG_EXT@
+
+MODEL = ../@DFT_OBJ_SUBDIR@
+INSTALL_PREFIX = @INSTALL_PREFIX@
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+includedir = @includedir@
+datadir = @datadir@
+
+ticdir = $(datadir)/terminfo
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+
+AWK = @AWK@
+LN_S = @LN_S@
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+
+INCDIR = $(srcdir)/../include
+CPPFLAGS = -I../progs -I$(srcdir) @CPPFLAGS@ \
+ -DHAVE_CONFIG_H -DTERMINFO=\"$(ticdir)\"
+
+CCFLAGS = $(CPPFLAGS) $(CFLAGS)
+
+CFLAGS_NORMAL = $(CCFLAGS)
+CFLAGS_DEBUG = $(CCFLAGS) @CC_G_OPT@ -DTRACE
+CFLAGS_PROFILE = $(CCFLAGS) -pg
+CFLAGS_SHARED = $(CCFLAGS) # @CC_SHARED_OPTS@
+
+CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@)
+
+LD = @LD@
+LINK = @LINK_PROGS@ $(CC)
+LDFLAGS = @EXTRA_LDFLAGS@ \
+ @PROG_ARGS@ @LDFLAGS@ @LD_MODEL@ @LIBS@ @EXTRA_LIBS@
+
+LDFLAGS_NORMAL = $(LDFLAGS)
+LDFLAGS_DEBUG = $(LDFLAGS) @CC_G_OPT@
+LDFLAGS_PROFILE = $(LDFLAGS) -pg
+LDFLAGS_SHARED = $(LDFLAGS) @LD_SHARED_OPTS@
+
+LDFLAGS_DEFAULT = $(LDFLAGS_@DFT_UPR_MODEL@)
+
+LINT = @LINT@
+LINT_OPTS = @LINT_OPTS@
+LINT_LIBS = -lncurses @LIBS@
+
+AUTO_SRC = \
+ termsort.c
+
+PROGS = tic$x toe$x infocmp$x clear$x tput$x tset$x
+
+TESTPROGS = mvcur$x tctest$x hardscroll$x hashmap$x
+
+# Default library, for linking applications
+DEPS_CURSES = @LIB_PREFIX@ncurses@DFT_DEP_SUFFIX@
+
+################################################################################
+all: $(AUTO_SRC) $(PROGS)
+
+sources: $(AUTO_SRC)
+
+install: install.progs
+uninstall: uninstall.progs
+
+# this line simplifies the configure-script
+install.libs:
+uninstall.libs:
+
+install.progs: $(PROGS) $(INSTALL_PREFIX)$(bindir)
+ $(INSTALL_PROGRAM) tic$x $(INSTALL_PREFIX)$(bindir)/tic$x
+ $(INSTALL_PROGRAM) toe$x $(INSTALL_PREFIX)$(bindir)/toe$x
+ $(INSTALL_PROGRAM) infocmp$x $(INSTALL_PREFIX)$(bindir)/infocmp$x
+ $(INSTALL_PROGRAM) clear$x $(INSTALL_PREFIX)$(bindir)/clear$x
+ $(INSTALL_PROGRAM) tput$x $(INSTALL_PREFIX)$(bindir)/tput$x
+ $(INSTALL_PROGRAM) tset$x $(INSTALL_PREFIX)$(bindir)/tset$x
+ @echo "linking captoinfo to tic"
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/captoinfo$x
+ (cd $(INSTALL_PREFIX)$(bindir) && $(LN_S) tic$x captoinfo$x)
+ @echo "linking infotocap to tic"
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/infotocap$x
+ (cd $(INSTALL_PREFIX)$(bindir) && $(LN_S) tic$x infotocap$x)
+ @echo "linking reset to tset"
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/reset$x
+ (cd $(INSTALL_PREFIX)$(bindir) && $(LN_S) tset$x reset$x)
+
+uninstall.progs:
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/tic$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/toe$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/infocmp$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/clear$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/tput$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/tset$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/captoinfo$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/infotocap$x
+ -@rm -f $(INSTALL_PREFIX)$(bindir)/reset$x
+
+$(INSTALL_PREFIX)$(bindir) :
+ $(srcdir)/../mkinstalldirs $@
+
+#
+# Utilities normally built by make all start here
+#
+
+DEPS_TIC = \
+ $(MODEL)/tic.o \
+ $(MODEL)/dump_entry.o
+
+tic$x: $(DEPS_TIC) $(DEPS_CURSES)
+ @ECHO_LINK@ $(LINK) $(DEPS_TIC) $(LDFLAGS_DEFAULT) -o $@
+
+DEPS_TOE = \
+ $(MODEL)/toe.o \
+ $(MODEL)/dump_entry.o
+
+toe$x: $(DEPS_TOE) $(DEPS_CURSES)
+ @ECHO_LINK@ $(LINK) $(DEPS_TOE) $(LDFLAGS_DEFAULT) -o $@
+
+DEPS_CLEAR = \
+ $(MODEL)/clear.o
+
+clear$x: $(DEPS_CLEAR) $(DEPS_CURSES)
+ @ECHO_LINK@ $(LINK) $(DEPS_CLEAR) $(LDFLAGS_DEFAULT) -o $@
+
+DEPS_TPUT = \
+ $(MODEL)/tput.o
+
+tput$x: $(DEPS_TPUT) $(DEPS_CURSES)
+ @ECHO_LINK@ $(LINK) $(DEPS_TPUT) $(LDFLAGS_DEFAULT) -o $@
+
+DEPS_INFOCMP = \
+ $(MODEL)/infocmp.o \
+ $(MODEL)/dump_entry.o
+
+infocmp$x: $(DEPS_INFOCMP) $(DEPS_CURSES)
+ @ECHO_LINK@ $(LINK) $(DEPS_INFOCMP) $(LDFLAGS_DEFAULT) -o $@
+
+DEPS_TSET = \
+ $(MODEL)/tset.o \
+ $(MODEL)/dump_entry.o
+
+tset$x: $(DEPS_TSET) $(DEPS_CURSES)
+ @ECHO_LINK@ $(LINK) $(DEPS_TSET) $(LDFLAGS_DEFAULT) -o $@
+
+termsort.c: $(srcdir)/MKtermsort.sh
+ sh -c "$(srcdir)/MKtermsort.sh $(AWK) $(srcdir)/../include/Caps" >$@
+
+#
+# Utility productions start here
+#
+
+tags:
+ ctags *.[ch]
+
+TAGS:
+ etags *.[ch]
+
+mostlyclean ::
+ -rm -f core tags TAGS *~ *.ln *.atac trace
+ -rm -f $(TESTPROGS)
+
+clean :: mostlyclean
+ -rm -f $(AUTO_SRC)
+ -rm -f $(PROGS)
+
+distclean :: clean
+ -rm -f Makefile
+
+realclean :: distclean
+
+# These rules are used to allow "make -n" to work on a clean directory-tree
+../include/hashsize.h \
+../include/parametrized.h \
+../include/term.h :
+ cd ../include; $(MAKE) $(CF_MFLAGS)
+$(DEPS_CURSES) :
+ cd ../ncurses; $(MAKE) $(CF_MFLAGS)
+
+lint:
+ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/clear.c $(LINT_LIBS)
+ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/infocmp.c $(srcdir)/dump_entry.c $(LINT_LIBS)
+ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tic.c $(srcdir)/dump_entry.c $(LINT_LIBS)
+ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/toe.c $(srcdir)/dump_entry.c $(LINT_LIBS)
+ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tput.c $(LINT_LIBS)
+ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tset.c $(srcdir)/dump_entry.c $(LINT_LIBS)
+
+###############################################################################
+# The remainder of this file is automatically generated during configuration
+###############################################################################
diff --git a/contrib/ncurses/progs/capconvert b/contrib/ncurses/progs/capconvert
new file mode 100755
index 000000000000..2125a0d68d02
--- /dev/null
+++ b/contrib/ncurses/progs/capconvert
@@ -0,0 +1,229 @@
+#!/bin/sh
+# $Id: capconvert,v 1.3 1997/08/02 21:52:06 tom Exp $
+#
+# capconvert -- automated conversion from termcap to terminfo
+#
+
+echo "This script tries to automatically set you up so that your applications"
+echo "that now use termcap can use terminfo and the ncurses library."
+echo ""
+
+# Note, except for telling if we're running under xterm we don't use TERM at
+# all. This is because BSD users not infrequently have multiple termtypes
+# selected by conditionals in tset -- unless they're xterm users, in which
+# case they're on a workstation and probably don't.
+
+# Check to make sure TERMINFO is not already defined
+if test -n "$TERMINFO"
+then
+ echo "TERMINFO is already defined in your environment. This means"
+ echo "you already have a local terminfo tree, so you do not need any"
+ echo "conversion."
+ if test ! -d $TERMINFO ; then
+ echo "Caution: TERMINFO does not point to a directory!"
+ fi
+ exit;
+fi
+
+# Check to see if terminfo is present in one of the standard locations.
+terminfo=no
+for p in $TERMINFO \
+ /usr/lib/terminfo \
+ /usr/share/lib/terminfo \
+ /usr/share/terminfo \
+ /usr/local/lib/terminfo \
+ /usr/local/share/terminfo
+do
+ if test -d $p ; then
+ terminfo=yes
+ break
+ fi
+done
+
+if test $terminfo = yes
+then
+ echo "Your system already has a system-wide terminfo tree."
+ echo ""
+ if test -z "$TERMCAP"
+ then
+ echo "You have no TERMCAP variable set, so we are done."
+ # Assumes the terminfo master covers all canned terminal types
+ exit;
+ fi
+ if test "$TERM" = "xterm"
+ then
+ echo "You are running xterm, which usually sets TERMCAP itself."
+ echo "We can ignore this, because terminfo knows about xterm."
+ echo "So you will just use the system-wide terminfo tree."
+ exit;
+ else
+ echo "We will have to make a local one for you anyway, to capture the effect"
+ echo "of your TERMCAP variable."
+ fi
+else
+ echo "No system-wide terminfo tree. We will make you a local one."
+fi
+echo "";
+
+# Check if test -x works (it's not portable, but useful)
+OPT="-x"
+TMP=test$$; touch $TMP && chmod 755 $TMP
+if test $OPT $TMP ; then
+ chmod 644 $TMP
+ test $OPT $TMP && OPT="-f"
+else
+ OPT="-f"
+fi
+rm -f $TMP
+
+# First step -- go find tic
+TIC=
+IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+for x in $PATH .
+do
+ if test $OPT $x/tic
+ then
+ TIC=$x/tic
+ break
+ fi
+done
+IFS="$ac_save_ifs"
+
+if test -n "$TIC"
+then
+ echo "I see tic at $TIC."
+ case $TIC in # (vi
+ ./tic)
+ if test $OPT ../misc/shlib ; then
+ TIC="../misc/shlib $TIC"
+ fi
+ ;;
+ esac
+else
+ echo "You do not have tic installed anywhere I can see, please fix that."
+ exit;
+fi
+echo "";
+
+# We have tic. Either there's no system terminfo tree or there is one but
+# the user has a TERMCAP variable that may modify a stock description.
+#
+
+# Make the user a terminfo directory
+if test -d $HOME/.terminfo
+then
+ echo "It appears you already have a private terminfo directory"
+ echo "at $HOME/.terminfo; this seems odd, because TERMINFO"
+ echo "is not defined. I am not going to second-guess this -- if you"
+ echo "really want me to try auto-configuring for you, remove or"
+ echo "rename $HOME/terminfo and run me again."
+ exit;
+else
+ echo "I am creating your private terminfo directory at $HOME/.terminfo"
+ mkdir $HOME/.terminfo
+ # Ensure that that's where tic's compilation results.
+ # This isn't strictly necessary with a 1.9.7 or later tic.
+ TERMINFO="$HOME/.terminfo"; export TERMINFO
+fi
+echo "";
+
+# Find a terminfo source to work from
+if test -f ../misc/terminfo.src
+then
+ echo "I see the terminfo master source is handy; I will use that."
+ master=../misc/terminfo.src
+else
+ # Ooops...looks like we're running from somewhere other than the
+ # progs directory of an ncurses source tree.
+ master=`find $HOME -name "*terminfo.src" -print`
+ mcount=`echo $master | wc -l`
+ case $mcount in
+ 0)
+ echo "I can not find a terminfo source file anywhere under your home directory."
+ echo "There should be a file called terminfo.src somewhere in your"
+ echo "ncurses distribution; please put it in your home directotry"
+ echo "and run me again (it does not have to live there permanently)."
+ exit;
+ ;;
+ 1)
+ echo "I see a file called $master."
+ echo "I am going to assume this is the terminfo source included with"
+ echo "the ncurses distribution. If this assumption is wrong, please"
+ echo "interrupt me now! OK to continue?"
+ read ans;
+ ;;
+ 2)
+ echo "I see more than one possible terminfo source. Here they are:"
+ echo $master | sed "/^/s// /";
+ while :
+ do
+ echo "Please tell me which one to use:"
+ read master;
+ if test -f $master
+ then
+ break
+ else
+ echo "That file does not exist. Try again?";
+ fi
+ done
+ ;;
+ esac
+fi
+echo "";
+
+# Now that we have a master, compile it into the local tree
+echo "OK, now I will make your private terminfo tree. This may take a bit..."
+#
+# Kluge alert: we compile terminfo.src in two pieces because a lot of machines
+# with < 16MB RAM choke on tic's core-hog habits.
+trap "rm -f tsplit$$.*" 0 1 2 5 15
+sed -n $master \
+ -e '1,/SPLIT HERE/w 'tsplit$$.01 \
+ -e '/SPLIT HERE/,$w 'tsplit$$.02 \
+ 2>/dev/null
+for x in tsplit$$.*; do eval $TIC $x; done
+rm tsplit$$.*
+trap 0 1 2 5 15
+#
+echo "You now have a private tree under $HOME/.terminfo;"
+echo "the ncurses library will automatically read from it,"
+echo "and ncurses tic will automatically compile entries to it."
+
+# We're done unless user has a .termcap file or equivalent named by TERMCAP
+if test -z "$TERMCAP"
+then
+ echo "You have no TERMCAP set, so we are done."
+fi
+
+# OK, here comes the nasty case...user has a TERMCAP. Instead of
+# trying to follow all the convolutions of the relationship between
+# TERM and TERMCAP (partly because it's too painful, and partly because
+# we don't actually know what TERM will be nor even if it always has
+# the same value for this user) we do the following three steps...
+
+if test -f $HOME/.termcap
+then
+ echo 'I see you have a $HOME/.termcap file. I will compile that.'
+ eval $TIC $HOME/.termcap
+ echo "Done."
+ echo "Note that editing $HOME/.termcap will no longer change the data curses sees."
+elif test -f "$TERMCAP"
+then
+ echo "Your TERMCAP names the file $TERMCAP. I will compile that."
+ eval $TIC $TERMCAP
+ echo "Done."
+ echo "Note that editing $TERMCAP will no longer change the data curses sees."
+else
+ echo "Your TERMCAP value appears to be an entry in termcap format."
+ echo "I will compile it."
+ echo $TERMCAP >myterm$$
+ eval $TIC myterm$$
+ rm myterm$$
+ echo "Done."
+ echo "Note that editing TERMCAP will no longer change the data curses sees."
+fi
+echo "To do that, decompile the terminal decription you want with infocmp(1),"
+echo "edit to taste, and recompile using tic(1)."
+
+# capconvert ends here
+
diff --git a/contrib/ncurses/progs/clear.c b/contrib/ncurses/progs/clear.c
new file mode 100644
index 000000000000..d27b62544a94
--- /dev/null
+++ b/contrib/ncurses/progs/clear.c
@@ -0,0 +1,58 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * clear.c -- clears the terminal's screen
+ */
+
+#include <progs.priv.h>
+
+#include <curses.h>
+
+MODULE_ID("$Id: clear.c,v 1.8 1998/09/26 11:42:50 tom Exp $")
+
+static int putch(int c)
+{
+ return putchar(c);
+}
+
+int main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+ setupterm((char *) 0, STDOUT_FILENO, (int *) 0);
+ return (tputs(clear_screen, lines > 0 ? lines : 1, putch) == ERR)
+ ? EXIT_FAILURE
+ : EXIT_SUCCESS;
+}
diff --git a/contrib/ncurses/progs/clear.sh b/contrib/ncurses/progs/clear.sh
new file mode 100755
index 000000000000..1b6b0bb8a607
--- /dev/null
+++ b/contrib/ncurses/progs/clear.sh
@@ -0,0 +1 @@
+exec tput clear
diff --git a/contrib/ncurses/progs/dump_entry.c b/contrib/ncurses/progs/dump_entry.c
new file mode 100644
index 000000000000..8324fe225228
--- /dev/null
+++ b/contrib/ncurses/progs/dump_entry.c
@@ -0,0 +1,913 @@
+/****************************************************************************
+ * Copyright (c) 1998,1999 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+#define __INTERNAL_CAPS_VISIBLE
+#include <progs.priv.h>
+
+#include "dump_entry.h"
+#include "termsort.c" /* this C file is generated */
+#include <parametrized.h> /* so is this */
+
+MODULE_ID("$Id: dump_entry.c,v 1.37 1999/03/14 12:29:30 tom Exp $")
+
+#define INDENT 8
+
+#define DISCARD(string) string = ABSENT_STRING
+
+static int tversion; /* terminfo version */
+static int outform; /* output format to use */
+static int sortmode; /* sort mode to use */
+static int width = 60; /* max line width for listings */
+static int column; /* current column, limited by 'width' */
+static int oldcol; /* last value of column before wrap */
+static int tracelevel; /* level of debug output */
+static bool pretty; /* true if we format if-then-else strings */
+
+static char *outbuf; /* the output-buffer */
+static size_t out_used; /* ...its current length */
+static size_t out_size; /* ...and its allocated length */
+
+/* indirection pointers for implementing sort and display modes */
+static const int *bool_indirect, *num_indirect, *str_indirect;
+static NCURSES_CONST char * const *bool_names;
+static NCURSES_CONST char * const *num_names;
+static NCURSES_CONST char * const *str_names;
+
+static const char *separator, *trailer;
+
+/* cover various ports and variants of terminfo */
+#define V_ALLCAPS 0 /* all capabilities (SVr4, XSI, ncurses) */
+#define V_SVR1 1 /* SVR1, Ultrix */
+#define V_HPUX 2 /* HP/UX */
+#define V_AIX 3 /* AIX */
+#define V_BSD 4 /* BSD */
+
+#define OBSOLETE(n) (n[0] == 'O' && n[1] == 'T')
+
+#if NCURSES_XNAMES
+#define BoolIndirect(j) ((j >= BOOLCOUNT) ? (j) : ((sortmode == S_NOSORT) ? j : bool_indirect[j]))
+#define NumIndirect(j) ((j >= NUMCOUNT) ? (j) : ((sortmode == S_NOSORT) ? j : num_indirect[j]))
+#define StrIndirect(j) ((j >= STRCOUNT) ? (j) : ((sortmode == S_NOSORT) ? j : str_indirect[j]))
+#else
+#define BoolIndirect(j) ((sortmode == S_NOSORT) ? (j) : bool_indirect[j])
+#define NumIndirect(j) ((sortmode == S_NOSORT) ? (j) : num_indirect[j])
+#define StrIndirect(j) ((sortmode == S_NOSORT) ? (j) : str_indirect[j])
+#endif
+
+#if NO_LEAKS
+void _nc_leaks_dump_entry(void)
+{
+ if (outbuf != 0) {
+ free(outbuf);
+ outbuf = 0;
+ }
+}
+#endif
+
+NCURSES_CONST char *nametrans(const char *name)
+/* translate a capability name from termcap to terminfo */
+{
+ const struct name_table_entry *np;
+
+ if ((np = _nc_find_entry(name, _nc_get_hash_table(0))) != 0)
+ switch(np->nte_type)
+ {
+ case BOOLEAN:
+ if (bool_from_termcap[np->nte_index])
+ return(boolcodes[np->nte_index]);
+ break;
+
+ case NUMBER:
+ if (num_from_termcap[np->nte_index])
+ return(numcodes[np->nte_index]);
+ break;
+
+ case STRING:
+ if (str_from_termcap[np->nte_index])
+ return(strcodes[np->nte_index]);
+ break;
+ }
+
+ return(0);
+}
+
+void dump_init(const char *version, int mode, int sort, int twidth, int traceval, bool formatted)
+/* set up for entry display */
+{
+ width = twidth;
+ pretty = formatted;
+ tracelevel = traceval;
+
+ /* versions */
+ if (version == 0)
+ tversion = V_ALLCAPS;
+ else if (!strcmp(version, "SVr1") || !strcmp(version, "SVR1")
+ || !strcmp(version, "Ultrix"))
+ tversion = V_SVR1;
+ else if (!strcmp(version, "HP"))
+ tversion = V_HPUX;
+ else if (!strcmp(version, "AIX"))
+ tversion = V_AIX;
+ else if (!strcmp(version, "BSD"))
+ tversion = V_BSD;
+ else
+ tversion = V_ALLCAPS;
+
+ /* implement display modes */
+ switch (outform = mode)
+ {
+ case F_LITERAL:
+ case F_TERMINFO:
+ bool_names = boolnames;
+ num_names = numnames;
+ str_names = strnames;
+ separator = twidth ? ", " : ",";
+ trailer = "\n\t";
+ break;
+
+ case F_VARIABLE:
+ bool_names = boolfnames;
+ num_names = numfnames;
+ str_names = strfnames;
+ separator = twidth ? ", " : ",";
+ trailer = "\n\t";
+ break;
+
+ case F_TERMCAP:
+ case F_TCONVERR:
+ bool_names = boolcodes;
+ num_names = numcodes;
+ str_names = strcodes;
+ separator = ":";
+ trailer = "\\\n\t:";
+ break;
+ }
+
+ /* implement sort modes */
+ switch(sortmode = sort)
+ {
+ case S_NOSORT:
+ if (traceval)
+ (void) fprintf(stderr,
+ "%s: sorting by term structure order\n", _nc_progname);
+ break;
+
+ case S_TERMINFO:
+ if (traceval)
+ (void) fprintf(stderr,
+ "%s: sorting by terminfo name order\n", _nc_progname);
+ bool_indirect = bool_terminfo_sort;
+ num_indirect = num_terminfo_sort;
+ str_indirect = str_terminfo_sort;
+ break;
+
+ case S_VARIABLE:
+ if (traceval)
+ (void) fprintf(stderr,
+ "%s: sorting by C variable order\n", _nc_progname);
+ bool_indirect = bool_variable_sort;
+ num_indirect = num_variable_sort;
+ str_indirect = str_variable_sort;
+ break;
+
+ case S_TERMCAP:
+ if (traceval)
+ (void) fprintf(stderr,
+ "%s: sorting by termcap name order\n", _nc_progname);
+ bool_indirect = bool_termcap_sort;
+ num_indirect = num_termcap_sort;
+ str_indirect = str_termcap_sort;
+ break;
+ }
+
+ if (traceval)
+ (void) fprintf(stderr,
+ "%s: width = %d, tversion = %d, outform = %d\n",
+ _nc_progname, width, tversion, outform);
+}
+
+static TERMTYPE *cur_type;
+
+static int dump_predicate(int type, int idx)
+/* predicate function to use for ordinary decompilation */
+{
+ switch(type) {
+ case BOOLEAN:
+ return (cur_type->Booleans[idx] == FALSE)
+ ? FAIL : cur_type->Booleans[idx];
+
+ case NUMBER:
+ return (cur_type->Numbers[idx] == ABSENT_NUMERIC)
+ ? FAIL : cur_type->Numbers[idx];
+
+ case STRING:
+ return (cur_type->Strings[idx] != ABSENT_STRING)
+ ? (int)TRUE : FAIL;
+ }
+
+ return(FALSE); /* pacify compiler */
+}
+
+static void set_obsolete_termcaps(TERMTYPE *tp);
+static void repair_acsc(TERMTYPE *tp);
+
+/* is this the index of a function key string? */
+#define FNKEY(i) (((i)<= 65 && (i)>= 75) || ((i)<= 216 && (i)>= 268))
+
+static bool version_filter(int type, int idx)
+/* filter out capabilities we may want to suppress */
+{
+ switch (tversion)
+ {
+ case V_ALLCAPS: /* SVr4, XSI Curses */
+ return(TRUE);
+
+ case V_SVR1: /* System V Release 1, Ultrix */
+ switch (type)
+ {
+ case BOOLEAN:
+ /* below and including xon_xoff */
+ return ((idx <= 20) ? TRUE : FALSE);
+ case NUMBER:
+ /* below and including width_status_line */
+ return ((idx <= 7) ? TRUE : FALSE);
+ case STRING:
+ /* below and including prtr_non */
+ return ((idx <= 144) ? TRUE : FALSE);
+ }
+ break;
+
+ case V_HPUX: /* Hewlett-Packard */
+ switch (type)
+ {
+ case BOOLEAN:
+ /* below and including xon_xoff */
+ return ((idx <= 20) ? TRUE : FALSE);
+ case NUMBER:
+ /* below and including label_width */
+ return ((idx <= 10) ? TRUE : FALSE);
+ case STRING:
+ if (idx <= 144) /* below and including prtr_non */
+ return(TRUE);
+ else if (FNKEY(idx)) /* function keys */
+ return(TRUE);
+ else if (idx==147||idx==156||idx==157) /* plab_norm,label_on,label_off */
+ return(TRUE);
+ else
+ return(FALSE);
+ }
+ break;
+
+ case V_AIX: /* AIX */
+ switch (type)
+ {
+ case BOOLEAN:
+ /* below and including xon_xoff */
+ return ((idx <= 20) ? TRUE : FALSE);
+ case NUMBER:
+ /* below and including width_status_line */
+ return ((idx <= 7) ? TRUE : FALSE);
+ case STRING:
+ if (idx <= 144) /* below and including prtr_non */
+ return(TRUE);
+ else if (FNKEY(idx)) /* function keys */
+ return(TRUE);
+ else
+ return(FALSE);
+ }
+ break;
+
+ case V_BSD: /* BSD */
+ switch (type)
+ {
+ case BOOLEAN:
+ return bool_from_termcap[idx];
+ case NUMBER:
+ return num_from_termcap[idx];
+ case STRING:
+ return str_from_termcap[idx];
+ }
+ break;
+ }
+
+ return(FALSE); /* pacify the compiler */
+}
+
+static
+void append_output (const char *src)
+{
+ if (src == 0) {
+ out_used = 0;
+ append_output("");
+ } else {
+ size_t need = strlen(src);
+ size_t want = need + out_used + 1;
+ if (want > out_size) {
+ out_size += want; /* be generous */
+ if (outbuf == 0)
+ outbuf = malloc(out_size);
+ else
+ outbuf = realloc(outbuf, out_size);
+ }
+ (void)strcpy(outbuf + out_used, src);
+ out_used += need;
+ }
+}
+
+static
+void force_wrap(void)
+{
+ oldcol = column;
+ append_output(trailer);
+ column = INDENT;
+}
+
+static
+void wrap_concat(const char *src)
+{
+ int need = strlen(src);
+ int want = strlen(separator) + need;
+
+ if (column > INDENT
+ && column + want > width) {
+ force_wrap();
+ }
+ append_output(src);
+ append_output(separator);
+ column += need;
+}
+
+#define IGNORE_SEP_TRAIL(first,last,sep_trail) \
+ if ((size_t)(last - first) > sizeof(sep_trail)-1 \
+ && !strncmp(first, sep_trail, sizeof(sep_trail)-1)) \
+ first += sizeof(sep_trail)-2
+
+/* Returns the nominal length of the buffer assuming it is termcap format,
+ * i.e., the continuation sequence is treated as a single character ":".
+ *
+ * There are several implementations of termcap which read the text into a
+ * fixed-size buffer. Generally they strip the newlines from the text, but may
+ * not do it until after the buffer is read. Also, "tc=" resolution may be
+ * expanded in the same buffer. This function is useful for measuring the size
+ * of the best fixed-buffer implementation; the worst case may be much worse.
+ */
+#ifdef TEST_TERMCAP_LENGTH
+static int termcap_length(const char *src)
+{
+ static const char pattern[] = ":\\\n\t:";
+
+ int len = 0;
+ const char *const t = src + strlen(src);
+
+ while (*src != '\0') {
+ IGNORE_SEP_TRAIL(src, t, pattern);
+ src++;
+ len++;
+ }
+ return len;
+}
+#else
+#define termcap_length(src) strlen(src)
+#endif
+
+static char * fmt_complex(char *dst, char *src, int level)
+{
+ int percent = 0;
+ int n;
+
+ dst += strlen(dst);
+ while (*src != '\0') {
+ switch (*src) {
+ case '\\':
+ percent = 0;
+ *dst++ = *src++;
+ break;
+ case '%':
+ percent = 1;
+ break;
+ case '?': /* "if" */
+ case 't': /* "then" */
+ case 'e': /* "else" */
+ if (percent) {
+ percent = 0;
+ dst[-1] = '\n';
+ for (n = 0; n <= level; n++)
+ *dst++ = '\t';
+ *dst++ = '%';
+ *dst++ = *src;
+ *dst = '\0';
+ if (*src++ == '?') {
+ src = fmt_complex(dst, src, level+1);
+ dst += strlen(dst);
+ } else if (level == 1) {
+ _nc_warning("%%%c without %%?", *src);
+ }
+ continue;
+ }
+ break;
+ case ';': /* "endif" */
+ if (percent) {
+ percent = 0;
+ if (level > 1) {
+ dst[-1] = '\n';
+ for (n = 0; n < level; n++)
+ *dst++ = '\t';
+ *dst++ = '%';
+ *dst++ = *src++;
+ *dst = '\0';
+ return src;
+ }
+ _nc_warning("%%; without %%?");
+ }
+ break;
+ default:
+ percent = 0;
+ break;
+ }
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+ return src;
+}
+
+int fmt_entry(TERMTYPE *tterm,
+ int (*pred)(int type, int idx),
+ bool suppress_untranslatable,
+ bool infodump,
+ int numbers)
+{
+int i, j;
+char buffer[MAX_TERMINFO_LENGTH];
+NCURSES_CONST char *name;
+int predval, len;
+int num_bools = 0;
+int num_values = 0;
+int num_strings = 0;
+bool outcount = 0;
+
+#define WRAP_CONCAT \
+ wrap_concat(buffer); \
+ outcount = TRUE
+
+ len = 12; /* terminfo file-header */
+
+ if (pred == 0) {
+ cur_type = tterm;
+ pred = dump_predicate;
+ }
+
+ append_output(0);
+ append_output(tterm->term_names);
+ append_output(separator);
+ column = out_used;
+ force_wrap();
+
+ for_each_boolean(j,tterm) {
+ i = BoolIndirect(j);
+ name = ExtBoolname(tterm,i,bool_names);
+
+ if (!version_filter(BOOLEAN, i))
+ continue;
+ else if ((outform == F_LITERAL || outform == F_TERMINFO || outform == F_VARIABLE)
+ && (OBSOLETE(name) && outform != F_LITERAL))
+ continue;
+
+ predval = pred(BOOLEAN, i);
+ if (predval != FAIL) {
+ (void) strcpy(buffer, name);
+ if (predval <= 0)
+ (void) strcat(buffer, "@");
+ else if (i + 1 > num_bools)
+ num_bools = i + 1;
+ WRAP_CONCAT;
+ }
+ }
+
+ if (column != INDENT)
+ force_wrap();
+
+ for_each_number(j,tterm) {
+ i = NumIndirect(j);
+ name = ExtNumname(tterm,i,num_names);
+
+ if (!version_filter(NUMBER, i))
+ continue;
+ else if ((outform == F_LITERAL || outform == F_TERMINFO || outform == F_VARIABLE)
+ && (OBSOLETE(name) && outform != F_LITERAL))
+ continue;
+
+ predval = pred(NUMBER, i);
+ if (predval != FAIL) {
+ if (tterm->Numbers[i] < 0) {
+ sprintf(buffer, "%s@", name);
+ } else {
+ sprintf(buffer, "%s#%d", name, tterm->Numbers[i]);
+ if (i + 1 > num_values)
+ num_values = i + 1;
+ }
+ WRAP_CONCAT;
+ }
+ }
+
+ if (column != INDENT)
+ force_wrap();
+
+ len += num_bools
+ + num_values * 2
+ + strlen(tterm->term_names) + 1;
+ if (len & 1)
+ len++;
+
+ repair_acsc(tterm);
+ for_each_string(j, tterm) {
+ i = StrIndirect(j);
+ name = ExtStrname(tterm,i,str_names);
+
+ if (!version_filter(STRING, i))
+ continue;
+ else if ((outform == F_LITERAL || outform == F_TERMINFO || outform == F_VARIABLE)
+ && (OBSOLETE(name) && outform != F_LITERAL))
+ continue;
+
+ /*
+ * Some older versions of vi want rmir/smir to be defined
+ * for ich/ich1 to work. If they're not defined, force
+ * them to be output as defined and empty.
+ */
+ if (outform==F_TERMCAP)
+ {
+#undef CUR
+#define CUR tterm->
+ if (insert_character || parm_ich)
+ {
+ if (&tterm->Strings[i] == &enter_insert_mode
+ && enter_insert_mode == ABSENT_STRING)
+ {
+ (void) strcpy(buffer, "im=");
+ goto catenate;
+ }
+
+ if (&tterm->Strings[i] == &exit_insert_mode
+ && exit_insert_mode == ABSENT_STRING)
+ {
+ (void) strcpy(buffer, "ei=");
+ goto catenate;
+ }
+ }
+
+ if (init_3string != 0
+ && termcap_reset != 0
+ && !strcmp(init_3string, termcap_reset))
+ DISCARD(init_3string);
+
+ if (reset_2string != 0
+ && termcap_reset != 0
+ && !strcmp(reset_2string, termcap_reset))
+ DISCARD(reset_2string);
+ }
+
+ predval = pred(STRING, i);
+ buffer[0] = '\0';
+ if (predval != FAIL) {
+ if (tterm->Strings[i] != ABSENT_STRING
+ && i + 1 > num_strings)
+ num_strings = i + 1;
+ if (!VALID_STRING(tterm->Strings[i]))
+ sprintf(buffer, "%s@", name);
+ else if (outform == F_TERMCAP || outform == F_TCONVERR)
+ {
+ char *srccap = _nc_tic_expand(tterm->Strings[i], FALSE, numbers);
+ char *cv = _nc_infotocap(name, srccap, parametrized[i]);
+
+ if (cv == 0)
+ {
+ if (outform == F_TCONVERR)
+ sprintf(buffer, "%s=!!! %s WILL NOT CONVERT !!!", name, srccap);
+ else if (suppress_untranslatable)
+ continue;
+ else
+ sprintf(buffer, "..%s=%s", name, srccap);
+ }
+ else
+ sprintf(buffer, "%s=%s", name, cv);
+ len += strlen(tterm->Strings[i]) + 1;
+ }
+ else
+ {
+ char *src = _nc_tic_expand(tterm->Strings[i], outform==F_TERMINFO, numbers);
+ sprintf(buffer, "%s=", name);
+ if (pretty && outform==F_TERMINFO)
+ fmt_complex(buffer + strlen(buffer), src, 1);
+ else
+ strcat(buffer, src);
+ len += strlen(tterm->Strings[i]) + 1;
+ }
+
+ catenate:
+ WRAP_CONCAT;
+ }
+ }
+ len += num_strings * 2;
+
+ /*
+ * This piece of code should be an effective inverse of the functions
+ * postprocess_terminfo and postprocess_terminfo in parse_entry.c.
+ * Much more work should be done on this to support dumping termcaps.
+ */
+ if (tversion == V_HPUX)
+ {
+ if (memory_lock)
+ {
+ (void) sprintf(buffer, "meml=%s", memory_lock);
+ WRAP_CONCAT;
+ }
+ if (memory_unlock)
+ {
+ (void) sprintf(buffer, "memu=%s", memory_unlock);
+ WRAP_CONCAT;
+ }
+ }
+ else if (tversion == V_AIX)
+ {
+ if (VALID_STRING(acs_chars))
+ {
+ bool box_ok = TRUE;
+ const char *acstrans = "lqkxjmwuvtn";
+ const char *cp;
+ char *tp, *sp, boxchars[11];
+
+ tp = boxchars;
+ for (cp = acstrans; *cp; cp++)
+ {
+ sp = strchr(acs_chars, *cp);
+ if (sp)
+ *tp++ = sp[1];
+ else
+ {
+ box_ok = FALSE;
+ break;
+ }
+ }
+ tp[0] = '\0';
+
+ if (box_ok)
+ {
+ (void) strcpy(buffer, "box1=");
+ (void) strcat(buffer, _nc_tic_expand(boxchars, outform==F_TERMINFO, numbers));
+ WRAP_CONCAT;
+ }
+ }
+ }
+
+ /*
+ * kludge: trim off trailer to avoid an extra blank line
+ * in infocmp -u output when there are no string differences
+ */
+ if (outcount)
+ {
+ j = out_used;
+ if (j >= 2
+ && outbuf[j-1] == '\t'
+ && outbuf[j-2] == '\n') {
+ out_used -= 2;
+ } else if (j >= 4
+ && outbuf[j-1] == ':'
+ && outbuf[j-2] == '\t'
+ && outbuf[j-3] == '\n'
+ && outbuf[j-4] == '\\') {
+ out_used -= 4;
+ }
+ outbuf[out_used] = '\0';
+ column = oldcol;
+ }
+
+#if 0
+ fprintf(stderr, "num_bools = %d\n", num_bools);
+ fprintf(stderr, "num_values = %d\n", num_values);
+ fprintf(stderr, "num_strings = %d\n", num_strings);
+ fprintf(stderr, "term_names=%s, len=%d, strlen(outbuf)=%d, outbuf=%s\n",
+ tterm->term_names, len, out_used, outbuf);
+#endif
+ /*
+ * Here's where we use infodump to trigger a more stringent length check
+ * for termcap-translation purposes.
+ * Return the length of the raw entry, without tc= expansions,
+ * It gives an idea of which entries are deadly to even *scan past*,
+ * as opposed to *use*.
+ */
+ return(infodump ? len : termcap_length(outbuf));
+}
+
+int dump_entry(TERMTYPE *tterm, bool limited, int numbers, int (*pred)(int type, int idx))
+/* dump a single entry */
+{
+ int len, critlen;
+ const char *legend;
+ bool infodump;
+
+ if (outform==F_TERMCAP || outform==F_TCONVERR)
+ {
+ critlen = MAX_TERMCAP_LENGTH;
+ legend = "older termcap";
+ infodump = FALSE;
+ set_obsolete_termcaps(tterm);
+ }
+ else
+ {
+ critlen = MAX_TERMINFO_LENGTH;
+ legend = "terminfo";
+ infodump = TRUE;
+ }
+
+ if (((len = fmt_entry(tterm, pred, FALSE, infodump, numbers)) > critlen) && limited)
+ {
+ (void) printf("# (untranslatable capabilities removed to fit entry within %d bytes)\n",
+ critlen);
+ if ((len = fmt_entry(tterm, pred, TRUE, infodump, numbers)) > critlen)
+ {
+ /*
+ * We pick on sgr because it's a nice long string capability that
+ * is really just an optimization hack.
+ */
+ char *oldsgr = set_attributes;
+ set_attributes = ABSENT_STRING;
+ (void) printf("# (sgr removed to fit entry within %d bytes)\n",
+ critlen);
+ if ((len = fmt_entry(tterm, pred, TRUE, infodump, numbers)) > critlen)
+ {
+ int oldversion = tversion;
+
+ tversion = V_BSD;
+ (void) printf("# (terminfo-only capabilities suppressed to fit entry within %d bytes)\n",
+ critlen);
+
+ if ((len = fmt_entry(tterm, pred, TRUE, infodump, numbers)) > critlen)
+ {
+ (void) fprintf(stderr,
+ "warning: %s entry is %d bytes long\n",
+ _nc_first_name(tterm->term_names),
+ len);
+ (void) printf(
+ "# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n",
+ len, legend);
+ }
+ tversion = oldversion;
+ }
+ set_attributes = oldsgr;
+ }
+ }
+
+ (void) fputs(outbuf, stdout);
+ return len;
+}
+
+int dump_uses(const char *name, bool infodump)
+/* dump "use=" clauses in the appropriate format */
+{
+ char buffer[MAX_TERMINFO_LENGTH];
+
+ append_output(0);
+ (void)sprintf(buffer, "%s%s", infodump ? "use=" : "tc=", name);
+ wrap_concat(buffer);
+ (void) fputs(outbuf, stdout);
+ return out_used;
+}
+
+void compare_entry(void (*hook)(int t, int i, const char *name), TERMTYPE *tp GCC_UNUSED)
+/* compare two entries */
+{
+ int i, j;
+ NCURSES_CONST char * name;
+
+ (void) fputs(" comparing booleans.\n", stdout);
+ for_each_boolean(j,tp)
+ {
+ i = BoolIndirect(j);
+ name = ExtBoolname(tp,i,bool_names);
+
+ if ((outform == F_LITERAL || outform == F_TERMINFO || outform == F_VARIABLE)
+ && (OBSOLETE(name) && outform != F_LITERAL))
+ continue;
+
+ (*hook)(BOOLEAN, i, name);
+ }
+
+ (void) fputs(" comparing numbers.\n", stdout);
+ for_each_number(j,tp)
+ {
+ i = NumIndirect(j);
+ name = ExtNumname(tp,i,num_names);
+
+ if ((outform==F_LITERAL || outform==F_TERMINFO || outform==F_VARIABLE)
+ && (OBSOLETE(name) && outform != F_LITERAL))
+ continue;
+
+ (*hook)(NUMBER, i, name);
+ }
+
+ (void) fputs(" comparing strings.\n", stdout);
+ for_each_string(j,tp)
+ {
+ i = StrIndirect(j);
+ name = ExtStrname(tp,i,str_names);
+
+ if ((outform==F_LITERAL || outform==F_TERMINFO || outform==F_VARIABLE)
+ && (OBSOLETE(name) && outform != F_LITERAL))
+ continue;
+
+ (*hook)(STRING, i, name);
+ }
+}
+
+#define NOTSET(s) ((s) == 0)
+
+/*
+ * This bit of legerdemain turns all the terminfo variable names into
+ * references to locations in the arrays Booleans, Numbers, and Strings ---
+ * precisely what's needed.
+ */
+#undef CUR
+#define CUR tp->
+
+static void set_obsolete_termcaps(TERMTYPE *tp)
+{
+#include "capdefaults.c"
+}
+
+/*
+ * Convert an alternate-character-set string to canonical form: sorted and
+ * unique.
+ */
+static void repair_acsc(TERMTYPE *tp)
+{
+ if (VALID_STRING(acs_chars)) {
+ size_t n, m;
+ char mapped[256];
+ char extra = 0;
+ unsigned source;
+ unsigned target;
+ bool fix_needed = FALSE;
+
+ for (n = 0, source = 0; acs_chars[n] != 0; n++) {
+ target = acs_chars[n];
+ if (source >= target) {
+ fix_needed = TRUE;
+ break;
+ }
+ source = target;
+ if (acs_chars[n+1])
+ n++;
+ }
+ if (fix_needed) {
+ memset(mapped, 0, sizeof(mapped));
+ for (n = 0; acs_chars[n] != 0; n++) {
+ source = acs_chars[n];
+ if ((target = (unsigned char)acs_chars[n+1]) != 0) {
+ mapped[source] = target;
+ n++;
+ } else {
+ extra = source;
+ }
+ }
+ for (n = m = 0; n < sizeof(mapped); n++) {
+ if (mapped[n]) {
+ acs_chars[m++] = n;
+ acs_chars[m++] = mapped[n];
+ }
+ }
+ if (extra)
+ acs_chars[m++] = extra; /* garbage in, garbage out */
+ acs_chars[m] = 0;
+ }
+ }
+}
diff --git a/contrib/ncurses/progs/dump_entry.h b/contrib/ncurses/progs/dump_entry.h
new file mode 100644
index 000000000000..d7e27c53f667
--- /dev/null
+++ b/contrib/ncurses/progs/dump_entry.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+ * Copyright (c) 1998,1999 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * Dump control definitions and variables
+ */
+
+/* capability output formats */
+#define F_TERMINFO 0 /* use terminfo names */
+#define F_VARIABLE 1 /* use C variable names */
+#define F_TERMCAP 2 /* termcap names with capability conversion */
+#define F_TCONVERR 3 /* as T_TERMCAP, no skip of untranslatables */
+#define F_LITERAL 4 /* like F_TERMINFO, but no smart defaults */
+
+/* capability sort modes */
+#define S_DEFAULT 0 /* sort by terminfo name (implicit) */
+#define S_NOSORT 1 /* don't sort */
+#define S_TERMINFO 2 /* sort by terminfo names (explicit) */
+#define S_VARIABLE 3 /* sort by C variable names */
+#define S_TERMCAP 4 /* sort by termcap names */
+
+extern NCURSES_CONST char *nametrans(const char *);
+extern void dump_init(const char *, int, int, int, int, bool);
+extern int fmt_entry(TERMTYPE *, int (*)(int, int), bool, bool, int);
+extern int dump_entry(TERMTYPE *, bool, int, int (*)(int, int));
+extern int dump_uses(const char *, bool);
+extern void compare_entry(void (*)(int, int, const char *), TERMTYPE *);
+
+#define FAIL -1
diff --git a/contrib/ncurses/progs/infocmp.c b/contrib/ncurses/progs/infocmp.c
new file mode 100644
index 000000000000..596522408515
--- /dev/null
+++ b/contrib/ncurses/progs/infocmp.c
@@ -0,0 +1,1321 @@
+/****************************************************************************
+ * Copyright (c) 1998,1999 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * infocmp.c -- decompile an entry, or compare two entries
+ * written by Eric S. Raymond
+ */
+
+#include <progs.priv.h>
+
+#include <term_entry.h>
+#include <dump_entry.h>
+
+MODULE_ID("$Id: infocmp.c,v 1.44 1999/06/16 00:39:48 tom Exp $")
+
+#define L_CURL "{"
+#define R_CURL "}"
+
+#define MAXTERMS 32 /* max # terminal arguments we can handle */
+
+const char *_nc_progname = "infocmp";
+
+typedef char path[PATH_MAX];
+
+/***************************************************************************
+ *
+ * The following control variables, together with the contents of the
+ * terminfo entries, completely determine the actions of the program.
+ *
+ ***************************************************************************/
+
+static char *tname[MAXTERMS]; /* terminal type names */
+static TERMTYPE term[MAXTERMS]; /* terminfo entries */
+static int termcount; /* count of terminal entries */
+
+static const char *tversion; /* terminfo version selected */
+static int numbers = 0; /* format "%'char'" to/from "%{number}" */
+static int outform; /* output format */
+static int sortmode; /* sort_mode */
+static int itrace; /* trace flag for debugging */
+static int mwidth = 60;
+
+/* main comparison mode */
+static int compare;
+#define C_DEFAULT 0 /* don't force comparison mode */
+#define C_DIFFERENCE 1 /* list differences between two terminals */
+#define C_COMMON 2 /* list common capabilities */
+#define C_NAND 3 /* list capabilities in neither terminal */
+#define C_USEALL 4 /* generate relative use-form entry */
+static bool ignorepads; /* ignore pad prefixes when diffing */
+
+#if NO_LEAKS
+#undef ExitProgram
+static void ExitProgram(int code) GCC_NORETURN;
+static void ExitProgram(int code)
+{
+ while (termcount-- > 0)
+ _nc_free_termtype(&term[termcount]);
+ _nc_leaks_dump_entry();
+ _nc_free_and_exit(code);
+}
+#endif
+
+static char *canonical_name(char *ptr, char *buf)
+/* extract the terminal type's primary name */
+{
+ char *bp;
+
+ (void) strcpy(buf, ptr);
+ if ((bp = strchr(buf, '|')) != (char *)NULL)
+ *bp = '\0';
+
+ return(buf);
+}
+
+/***************************************************************************
+ *
+ * Predicates for dump function
+ *
+ ***************************************************************************/
+
+static int capcmp(const char *s, const char *t)
+/* capability comparison function */
+{
+ if (!VALID_STRING(s) && !VALID_STRING(t))
+ return(0);
+ else if (!VALID_STRING(s) || !VALID_STRING(t))
+ return(1);
+
+ if (ignorepads)
+ return(_nc_capcmp(s, t));
+ else
+ return(strcmp(s, t));
+}
+
+static int use_predicate(int type, int idx)
+/* predicate function to use for use decompilation */
+{
+ TERMTYPE *tp;
+
+ switch(type)
+ {
+ case BOOLEAN: {
+ int is_set = FALSE;
+
+ /*
+ * This assumes that multiple use entries are supposed
+ * to contribute the logical or of their boolean capabilities.
+ * This is true if we take the semantics of multiple uses to
+ * be 'each capability gets the first non-default value found
+ * in the sequence of use entries'.
+ */
+ for (tp = &term[1]; tp < term + termcount; tp++)
+ if (tp->Booleans[idx]) {
+ is_set = TRUE;
+ break;
+ }
+ if (is_set != term->Booleans[idx])
+ return(!is_set);
+ else
+ return(FAIL);
+ }
+
+ case NUMBER: {
+ int value = ABSENT_NUMERIC;
+
+ /*
+ * We take the semantics of multiple uses to be 'each
+ * capability gets the first non-default value found
+ * in the sequence of use entries'.
+ */
+ for (tp = &term[1]; tp < term + termcount; tp++)
+ if (tp->Numbers[idx] >= 0) {
+ value = tp->Numbers[idx];
+ break;
+ }
+
+ if (value != term->Numbers[idx])
+ return(value != ABSENT_NUMERIC);
+ else
+ return(FAIL);
+ }
+
+ case STRING: {
+ char *termstr, *usestr = ABSENT_STRING;
+
+ termstr = term->Strings[idx];
+
+ /*
+ * We take the semantics of multiple uses to be 'each
+ * capability gets the first non-default value found
+ * in the sequence of use entries'.
+ */
+ for (tp = &term[1]; tp < term + termcount; tp++)
+ if (tp->Strings[idx])
+ {
+ usestr = tp->Strings[idx];
+ break;
+ }
+
+ if (usestr == ABSENT_STRING && termstr == ABSENT_STRING)
+ return(FAIL);
+ else if (!usestr || !termstr || capcmp(usestr, termstr))
+ return(TRUE);
+ else
+ return(FAIL);
+ }
+ }
+
+ return(FALSE); /* pacify compiler */
+}
+
+static bool entryeq(TERMTYPE *t1, TERMTYPE *t2)
+/* are two terminal types equal */
+{
+ int i;
+
+ for (i = 0; i < NUM_BOOLEANS(t1); i++)
+ if (t1->Booleans[i] != t2->Booleans[i])
+ return(FALSE);
+
+ for (i = 0; i < NUM_NUMBERS(t1); i++)
+ if (t1->Numbers[i] != t2->Numbers[i])
+ return(FALSE);
+
+ for (i = 0; i < NUM_STRINGS(t1); i++)
+ if (capcmp(t1->Strings[i], t2->Strings[i]))
+ return(FALSE);
+
+ return(TRUE);
+}
+
+#define TIC_EXPAND(result) _nc_tic_expand(result, outform==F_TERMINFO, numbers)
+
+static void compare_predicate(int type, int idx, const char *name)
+/* predicate function to use for entry difference reports */
+{
+ register TERMTYPE *t1 = &term[0];
+ register TERMTYPE *t2 = &term[1];
+ char *s1, *s2;
+
+ switch(type)
+ {
+ case BOOLEAN:
+ switch(compare)
+ {
+ case C_DIFFERENCE:
+ if (t1->Booleans[idx] != t2->Booleans[idx])
+ (void) printf("\t%s: %c:%c.\n",
+ name,
+ t1->Booleans[idx] ? 'T' : 'F',
+ t2->Booleans[idx] ? 'T' : 'F');
+ break;
+
+ case C_COMMON:
+ if (t1->Booleans[idx] && t2->Booleans[idx])
+ (void) printf("\t%s= T.\n", name);
+ break;
+
+ case C_NAND:
+ if (!t1->Booleans[idx] && !t2->Booleans[idx])
+ (void) printf("\t!%s.\n", name);
+ break;
+ }
+ break;
+
+ case NUMBER:
+ switch(compare)
+ {
+ case C_DIFFERENCE:
+ if (t1->Numbers[idx] != t2->Numbers[idx])
+ (void) printf("\t%s: %d:%d.\n",
+ name, t1->Numbers[idx], t2->Numbers[idx]);
+ break;
+
+ case C_COMMON:
+ if (t1->Numbers[idx]!=-1 && t2->Numbers[idx]!=-1
+ && t1->Numbers[idx] == t2->Numbers[idx])
+ (void) printf("\t%s= %d.\n", name, t1->Numbers[idx]);
+ break;
+
+ case C_NAND:
+ if (t1->Numbers[idx]==-1 && t2->Numbers[idx] == -1)
+ (void) printf("\t!%s.\n", name);
+ break;
+ }
+ break;
+
+ case STRING:
+ s1 = t1->Strings[idx];
+ s2 = t2->Strings[idx];
+ switch(compare)
+ {
+ case C_DIFFERENCE:
+ if (capcmp(s1, s2))
+ {
+ char buf1[BUFSIZ], buf2[BUFSIZ];
+
+ if (s1 == (char *)NULL)
+ (void) strcpy(buf1, "NULL");
+ else
+ {
+ (void) strcpy(buf1, "'");
+ (void) strcat(buf1, TIC_EXPAND(s1));
+ (void) strcat(buf1, "'");
+ }
+
+ if (s2 == (char *)NULL)
+ (void) strcpy(buf2, "NULL");
+ else
+ {
+ (void) strcpy(buf2, "'");
+ (void) strcat(buf2, TIC_EXPAND(s2));
+ (void) strcat(buf2, "'");
+ }
+
+ if (strcmp(buf1, buf2))
+ (void) printf("\t%s: %s, %s.\n",
+ name, buf1, buf2);
+ }
+ break;
+
+ case C_COMMON:
+ if (s1 && s2 && !capcmp(s1, s2))
+ (void) printf("\t%s= '%s'.\n", name, TIC_EXPAND(s1));
+ break;
+
+ case C_NAND:
+ if (!s1 && !s2)
+ (void) printf("\t!%s.\n", name);
+ break;
+ }
+ break;
+ }
+
+}
+
+/***************************************************************************
+ *
+ * Init string analysis
+ *
+ ***************************************************************************/
+
+typedef struct {const char *from; const char *to;} assoc;
+
+static const assoc std_caps[] =
+{
+ /* these are specified by X.364 and iBCS2 */
+ {"\033c", "RIS"}, /* full reset */
+ {"\0337", "SC"}, /* save cursor */
+ {"\0338", "RC"}, /* restore cursor */
+ {"\033[r", "RSR"}, /* not an X.364 mnemonic */
+ {"\033[m", "SGR0"}, /* not an X.364 mnemonic */
+ {"\033[2J", "ED2"}, /* clear page */
+
+ /* this group is specified by ISO 2022 */
+ {"\033(0", "ISO DEC G0"}, /* enable DEC graphics for G0 */
+ {"\033(A", "ISO UK G0"}, /* enable UK chars for G0 */
+ {"\033(B", "ISO US G0"}, /* enable US chars for G0 */
+ {"\033)0", "ISO DEC G1"}, /* enable DEC graphics for G1 */
+ {"\033)A", "ISO UK G1"}, /* enable UK chars for G1 */
+ {"\033)B", "ISO US G1"}, /* enable US chars for G1 */
+
+ /* these are DEC private modes widely supported by emulators */
+ {"\033=", "DECPAM"}, /* application keypad mode */
+ {"\033>", "DECPNM"}, /* normal keypad mode */
+ {"\033<", "DECANSI"}, /* enter ANSI mode */
+
+ { (char *)0, (char *)0}
+};
+
+static const assoc private_modes[] =
+/* DEC \E[ ... [hl] modes recognized by many emulators */
+{
+ {"1", "CKM"}, /* application cursor keys */
+ {"2", "ANM"}, /* set VT52 mode */
+ {"3", "COLM"}, /* 132-column mode */
+ {"4", "SCLM"}, /* smooth scroll */
+ {"5", "SCNM"}, /* reverse video mode */
+ {"6", "OM"}, /* origin mode */
+ {"7", "AWM"}, /* wraparound mode */
+ {"8", "ARM"}, /* auto-repeat mode */
+ {(char *)0, (char *)0}
+};
+
+static const assoc ecma_highlights[] =
+/* recognize ECMA attribute sequences */
+{
+ {"0", "NORMAL"}, /* normal */
+ {"1", "+BOLD"}, /* bold on */
+ {"2", "+DIM"}, /* dim on */
+ {"3", "+ITALIC"}, /* italic on */
+ {"4", "+UNDERLINE"}, /* underline on */
+ {"5", "+BLINK"}, /* blink on */
+ {"6", "+FASTBLINK"}, /* fastblink on */
+ {"7", "+REVERSE"}, /* reverse on */
+ {"8", "+INVISIBLE"}, /* invisible on */
+ {"9", "+DELETED"}, /* deleted on */
+ {"10", "MAIN-FONT"}, /* select primary font */
+ {"11", "ALT-FONT-1"}, /* select alternate font 1 */
+ {"12", "ALT-FONT-2"}, /* select alternate font 2 */
+ {"13", "ALT-FONT-3"}, /* select alternate font 3 */
+ {"14", "ALT-FONT-4"}, /* select alternate font 4 */
+ {"15", "ALT-FONT-5"}, /* select alternate font 5 */
+ {"16", "ALT-FONT-6"}, /* select alternate font 6 */
+ {"17", "ALT-FONT-7"}, /* select alternate font 7 */
+ {"18", "ALT-FONT-1"}, /* select alternate font 1 */
+ {"19", "ALT-FONT-1"}, /* select alternate font 1 */
+ {"20", "FRAKTUR"}, /* Fraktur font */
+ {"21", "DOUBLEUNDER"}, /* double underline */
+ {"22", "-DIM"}, /* dim off */
+ {"23", "-ITALIC"}, /* italic off */
+ {"24", "-UNDERLINE"}, /* underline off */
+ {"25", "-BLINK"}, /* blink off */
+ {"26", "-FASTBLINK"}, /* fastblink off */
+ {"27", "-REVERSE"}, /* reverse off */
+ {"28", "-INVISIBLE"}, /* invisible off */
+ {"29", "-DELETED"}, /* deleted off */
+ {(char *)0, (char *)0}
+};
+
+static void analyze_string(const char *name, const char *cap, TERMTYPE *tp)
+{
+ char buf[MAX_TERMINFO_LENGTH];
+ char buf2[MAX_TERMINFO_LENGTH];
+ const char *sp, *ep;
+ const assoc *ap;
+
+ if (cap == ABSENT_STRING || cap == CANCELLED_STRING)
+ return;
+ (void) printf("%s: ", name);
+
+ buf[0] = '\0';
+ for (sp = cap; *sp; sp++)
+ {
+ int i;
+ size_t len = 0;
+ const char *expansion = 0;
+
+ /* first, check other capabilities in this entry */
+ for (i = 0; i < STRCOUNT; i++)
+ {
+ char *cp = tp->Strings[i];
+
+ /* don't use soft-key capabilities */
+ if (strnames[i][0] == 'k' && strnames[i][0] == 'f')
+ continue;
+
+
+ if (cp != ABSENT_STRING && cp != CANCELLED_STRING && cp[0] && cp != cap)
+ {
+ len = strlen(cp);
+ (void) strncpy(buf2, sp, len);
+ buf2[len] = '\0';
+
+ if (_nc_capcmp(cp, buf2))
+ continue;
+
+#define ISRS(s) (!strncmp((s), "is", 2) || !strncmp((s), "rs", 2))
+ /*
+ * Theoretically we just passed the test for translation
+ * (equality once the padding is stripped). However, there
+ * are a few more hoops that need to be jumped so that
+ * identical pairs of initialization and reset strings
+ * don't just refer to each other.
+ */
+ if (ISRS(name) || ISRS(strnames[i]))
+ if (cap < cp)
+ continue;
+#undef ISRS
+
+ expansion = strnames[i];
+ break;
+ }
+ }
+
+ /* now check the standard capabilities */
+ if (!expansion)
+ for (ap = std_caps; ap->from; ap++)
+ {
+ len = strlen(ap->from);
+
+ if (strncmp(ap->from, sp, len) == 0)
+ {
+ expansion = ap->to;
+ break;
+ }
+ }
+
+ /* now check for private-mode sequences */
+ if (!expansion
+ && sp[0] == '\033' && sp[1] == '[' && sp[2] == '?'
+ && (len = strspn(sp + 3, "0123456789;"))
+ && ((sp[3 + len] == 'h') || (sp[3 + len] == 'l')))
+ {
+ char buf3[MAX_TERMINFO_LENGTH];
+
+ (void) strcpy(buf2, (sp[3 + len] == 'h') ? "DEC+" : "DEC-");
+ (void) strncpy(buf3, sp + 3, len);
+ len += 4;
+ buf3[len] = '\0';
+
+ ep = strtok(buf3, ";");
+ do {
+ bool found = FALSE;
+
+ for (ap = private_modes; ap->from; ap++)
+ {
+ size_t tlen = strlen(ap->from);
+
+ if (strncmp(ap->from, ep, tlen) == 0)
+ {
+ (void) strcat(buf2, ap->to);
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ (void) strcat(buf2, ep);
+ (void) strcat(buf2, ";");
+ } while
+ ((ep = strtok((char *)NULL, ";")));
+ buf2[strlen(buf2) - 1] = '\0';
+ expansion = buf2;
+ }
+
+ /* now check for ECMA highlight sequences */
+ if (!expansion
+ && sp[0] == '\033' && sp[1] == '['
+ && (len = strspn(sp + 2, "0123456789;"))
+ && sp[2 + len] == 'm')
+ {
+ char buf3[MAX_TERMINFO_LENGTH];
+
+ (void) strcpy(buf2, "SGR:");
+ (void) strncpy(buf3, sp + 2, len);
+ len += 3;
+ buf3[len] = '\0';
+
+ ep = strtok(buf3, ";");
+ do {
+ bool found = FALSE;
+
+ for (ap = ecma_highlights; ap->from; ap++)
+ {
+ size_t tlen = strlen(ap->from);
+
+ if (strncmp(ap->from, ep, tlen) == 0)
+ {
+ (void) strcat(buf2, ap->to);
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ (void) strcat(buf2, ep);
+ (void) strcat(buf2, ";");
+ } while
+ ((ep = strtok((char *)NULL, ";")));
+
+ buf2[strlen(buf2) - 1] = '\0';
+ expansion = buf2;
+ }
+ /* now check for scroll region reset */
+ if (!expansion)
+ {
+ (void) sprintf(buf2, "\033[1;%dr", tp->Numbers[2]);
+ len = strlen(buf2);
+ if (strncmp(buf2, sp, len) == 0)
+ expansion = "RSR";
+ }
+
+ /* now check for home-down */
+ if (!expansion)
+ {
+ (void) sprintf(buf2, "\033[%d;1H", tp->Numbers[2]);
+ len = strlen(buf2);
+ if (strncmp(buf2, sp, len) == 0)
+ expansion = "LL";
+ }
+
+ /* now look at the expansion we got, if any */
+ if (expansion)
+ {
+ (void) sprintf(buf + strlen(buf), "{%s}", expansion);
+ sp += len - 1;
+ continue;
+ }
+ else
+ {
+ /* couldn't match anything */
+ buf2[0] = *sp;
+ buf2[1] = '\0';
+ (void) strcat(buf, TIC_EXPAND(buf2));
+ }
+ }
+ (void) printf("%s\n", buf);
+}
+
+/***************************************************************************
+ *
+ * File comparison
+ *
+ ***************************************************************************/
+
+static void file_comparison(int argc, char *argv[])
+{
+#define MAXCOMPARE 2
+ /* someday we may allow comparisons on more files */
+ int filecount = 0;
+ ENTRY *heads[MAXCOMPARE];
+ ENTRY *tails[MAXCOMPARE];
+ ENTRY *qp, *rp;
+ int i, n;
+
+ dump_init((char *)NULL, F_LITERAL, S_TERMINFO, 0, itrace, FALSE);
+
+ for (n = 0; n < argc && n < MAXCOMPARE; n++)
+ {
+ if (freopen(argv[n], "r", stdin) == NULL)
+ _nc_err_abort("Can't open %s", argv[n]);
+
+ _nc_head = _nc_tail = (ENTRY *)NULL;
+
+ /* parse entries out of the source file */
+ _nc_set_source(argv[n]);
+ _nc_read_entry_source(stdin, NULL, TRUE, FALSE, NULLHOOK);
+
+ if (itrace)
+ (void) fprintf(stderr, "Resolving file %d...\n", n-0);
+
+ /* do use resolution */
+ if (!_nc_resolve_uses())
+ {
+ (void) fprintf(stderr,
+ "There are unresolved use entries in %s:\n",
+ argv[n]);
+ for_entry_list(qp)
+ if (qp->nuses)
+ {
+ (void) fputs(qp->tterm.term_names, stderr);
+ (void) fputc('\n', stderr);
+ }
+ exit(EXIT_FAILURE);
+ }
+
+ heads[filecount] = _nc_head;
+ tails[filecount] = _nc_tail;
+ filecount++;
+ }
+
+ /* OK, all entries are in core. Ready to do the comparison */
+ if (itrace)
+ (void) fprintf(stderr, "Entries are now in core...\n");
+
+ /*
+ * The entry-matching loop. We're not using the use[]
+ * slots any more (they got zeroed out by resolve_uses) so
+ * we stash each entry's matches in the other file there.
+ * Sigh, this is intrinsically quadratic.
+ */
+ for (qp = heads[0]; qp; qp = qp->next)
+ {
+ for (rp = heads[1]; rp; rp = rp->next)
+ if (_nc_entry_match(qp->tterm.term_names, rp->tterm.term_names))
+ {
+ /*
+ * This is why the uses structure parent element is
+ * (void *) -- so we can have either (char *) for
+ * names or entry structure pointers in them and still
+ * be type-safe.
+ */
+ if (qp->nuses < MAX_USES)
+ qp->uses[qp->nuses].parent = (void *)rp;
+ qp->nuses++;
+
+ if (rp->nuses < MAX_USES)
+ rp->uses[rp->nuses].parent = (void *)qp;
+ rp->nuses++;
+ }
+ }
+
+ /* now we have two circular lists with crosslinks */
+ if (itrace)
+ (void) fprintf(stderr, "Name matches are done...\n");
+
+ for (qp = heads[0]; qp; qp = qp->next)
+ if (qp->nuses > 1)
+ {
+ (void) fprintf(stderr,
+ "%s in file 1 (%s) has %d matches in file 2 (%s):\n",
+ _nc_first_name(qp->tterm.term_names),
+ argv[0],
+ qp->nuses,
+ argv[1]);
+ for (i = 0; i < qp->nuses; i++)
+ (void) fprintf(stderr,
+ "\t%s\n",
+ _nc_first_name(((ENTRY *)qp->uses[i].parent)->tterm.term_names));
+ }
+ for (rp = heads[1]; rp; rp = rp->next)
+ if (rp->nuses > 1)
+ {
+ (void) fprintf(stderr,
+ "%s in file 2 (%s) has %d matches in file 1 (%s):\n",
+ _nc_first_name(rp->tterm.term_names),
+ argv[1],
+ rp->nuses,
+ argv[0]);
+ for (i = 0; i < rp->nuses; i++)
+ (void) fprintf(stderr,
+ "\t%s\n",
+ _nc_first_name(((ENTRY *)rp->uses[i].parent)->tterm.term_names));
+ }
+
+ (void) printf("In file 1 (%s) only:\n", argv[0]);
+ for (qp = heads[0]; qp; qp = qp->next)
+ if (qp->nuses == 0)
+ (void) printf("\t%s\n",
+ _nc_first_name(qp->tterm.term_names));
+
+ (void) printf("In file 2 (%s) only:\n", argv[1]);
+ for (rp = heads[1]; rp; rp = rp->next)
+ if (rp->nuses == 0)
+ (void) printf("\t%s\n",
+ _nc_first_name(rp->tterm.term_names));
+
+ (void) printf("The following entries are equivalent:\n");
+ for (qp = heads[0]; qp; qp = qp->next)
+ {
+ rp = (ENTRY *)qp->uses[0].parent;
+
+ if (qp->nuses == 1 && entryeq(&qp->tterm, &rp->tterm))
+ {
+ char name1[NAMESIZE], name2[NAMESIZE];
+
+ (void) canonical_name(qp->tterm.term_names, name1);
+ (void) canonical_name(rp->tterm.term_names, name2);
+
+ (void) printf("%s = %s\n", name1, name2);
+ }
+ }
+
+ (void) printf("Differing entries:\n");
+ termcount = 2;
+ for (qp = heads[0]; qp; qp = qp->next)
+ {
+ rp = (ENTRY *)qp->uses[0].parent;
+
+#if NCURSES_XNAMES
+ if (termcount > 1)
+ _nc_align_termtype(&qp->tterm, &rp->tterm);
+#endif
+ if (qp->nuses == 1 && !entryeq(&qp->tterm, &rp->tterm))
+ {
+ char name1[NAMESIZE], name2[NAMESIZE];
+
+ term[0] = qp->tterm;
+ term[1] = rp->tterm;
+
+ (void) canonical_name(qp->tterm.term_names, name1);
+ (void) canonical_name(rp->tterm.term_names, name2);
+
+ switch (compare)
+ {
+ case C_DIFFERENCE:
+ if (itrace)
+ (void)fprintf(stderr, "infocmp: dumping differences\n");
+ (void) printf("comparing %s to %s.\n", name1, name2);
+ compare_entry(compare_predicate, term);
+ break;
+
+ case C_COMMON:
+ if (itrace)
+ (void) fprintf(stderr,
+ "infocmp: dumping common capabilities\n");
+ (void) printf("comparing %s to %s.\n", name1, name2);
+ compare_entry(compare_predicate, term);
+ break;
+
+ case C_NAND:
+ if (itrace)
+ (void) fprintf(stderr,
+ "infocmp: dumping differences\n");
+ (void) printf("comparing %s to %s.\n", name1, name2);
+ compare_entry(compare_predicate, term);
+ break;
+
+ }
+ }
+ }
+}
+
+static void usage(void)
+{
+ static const char *tbl[] = {
+ "Usage: infocmp [options] [-A directory] [-B directory] [termname...]"
+ ,""
+ ,"Options:"
+ ," -1 print single-column"
+ ," -C use termcap-names"
+ ," -F compare terminfo-files"
+ ," -I use terminfo-names"
+ ," -L use long names"
+ ," -R subset (see manpage)"
+ ," -T eliminate size limits (test)"
+ ," -V print version"
+ ," -c list common capabilities"
+ ," -d list different capabilities"
+ ," -e format output for C initializer"
+ ," -E format output as C tables"
+ ," -f with -1, format complex strings"
+ ," -G format %{number} to %'char'"
+ ," -g format %'char' to %{number}"
+ ," -i analyze initialization/reset"
+ ," -l output terminfo names"
+ ," -n list capabilities in neither"
+ ," -p ignore padding specifiers"
+ ," -r with -C, output in termcap form"
+ ," -s [d|i|l|c] sort fields"
+ ," -u produce source with 'use='"
+ ," -v number (verbose)"
+ ," -w number (width)"
+ };
+ const size_t first = 3;
+ const size_t last = sizeof(tbl)/sizeof(tbl[0]);
+ const size_t left = (last - first + 1) / 2 + first;
+ size_t n;
+
+ for (n = 0; n < left; n++) {
+ size_t m = (n < first) ? last : n + left - first;
+ if (m < last)
+ fprintf(stderr, "%-40.40s%s\n", tbl[n], tbl[m]);
+ else
+ fprintf(stderr, "%s\n", tbl[n]);
+ }
+ exit(EXIT_FAILURE);
+}
+
+static char * name_initializer(const char *type)
+{
+ static char *initializer;
+ char *s;
+
+ if (initializer == 0)
+ initializer = malloc(strlen(term->term_names) + 20);
+
+ (void) sprintf(initializer, "%s_data_%s", type, term->term_names);
+ for (s = initializer; *s != 0 && *s != '|'; s++)
+ {
+ if (!isalnum(*s))
+ *s = '_';
+ }
+ *s = 0;
+ return initializer;
+}
+
+/* dump C initializers for the terminal type */
+static void dump_initializers(void)
+{
+ int n;
+ const char *str = 0;
+ int size;
+
+ (void) printf("static bool %s[] = %s\n", name_initializer("bool"), L_CURL);
+
+ for_each_boolean(n,term)
+ {
+ switch((int)(term->Booleans[n]))
+ {
+ case TRUE:
+ str = "TRUE";
+ break;
+
+ case FALSE:
+ str = "FALSE";
+ break;
+
+ case ABSENT_BOOLEAN:
+ str = "ABSENT_BOOLEAN";
+ break;
+
+ case CANCELLED_BOOLEAN:
+ str = "CANCELLED_BOOLEAN";
+ break;
+ }
+ (void) printf("\t/* %3d: %-8s */\t%s,\n",
+ n, ExtBoolname(term,n,boolnames), str);
+ }
+ (void) printf("%s;\n", R_CURL);
+
+ (void) printf("static short %s[] = %s\n", name_initializer("number"), L_CURL);
+
+ for_each_number(n,term)
+ {
+ char buf[BUFSIZ];
+ switch (term->Numbers[n])
+ {
+ case ABSENT_NUMERIC:
+ str = "ABSENT_NUMERIC";
+ break;
+ case CANCELLED_NUMERIC:
+ str = "CANCELLED_NUMERIC";
+ break;
+ default:
+ sprintf(buf, "%d", term->Numbers[n]);
+ str = buf;
+ break;
+ }
+ (void) printf("\t/* %3d: %-8s */\t%s,\n", n, ExtNumname(term,n,numnames), str);
+ }
+ (void) printf("%s;\n", R_CURL);
+
+ size = sizeof(TERMTYPE)
+ + (NUM_BOOLEANS(term) * sizeof(term->Booleans[0]))
+ + (NUM_NUMBERS(term) * sizeof(term->Numbers[0]));
+
+ (void) printf("static char * %s[] = %s\n", name_initializer("string"), L_CURL);
+
+ for_each_string(n,term)
+ {
+ char buf[BUFSIZ], *sp, *tp;
+
+ if (term->Strings[n] == ABSENT_STRING)
+ str = "ABSENT_STRING";
+ else if (term->Strings[n] == CANCELLED_STRING)
+ str = "CANCELLED_STRING";
+ else
+ {
+ tp = buf;
+ *tp++ = '"';
+ for (sp = term->Strings[n]; *sp; sp++)
+ {
+ if (isascii(*sp) && isprint(*sp) && *sp !='\\' && *sp != '"')
+ *tp++ = *sp;
+ else
+ {
+ (void) sprintf(tp, "\\%03o", *sp & 0xff);
+ tp += 4;
+ }
+ }
+ *tp++ = '"';
+ *tp = '\0';
+ size += (strlen(term->Strings[n]) + 1);
+ str = buf;
+ }
+#if NCURSES_XNAMES
+ if (n == STRCOUNT)
+ {
+ (void) printf("%s;\n", R_CURL);
+
+ (void) printf("static char * %s[] = %s\n", name_initializer("string_ext"), L_CURL);
+ }
+#endif
+ (void) printf("\t/* %3d: %-8s */\t%s,\n", n, ExtStrname(term,n,strnames), str);
+ }
+ (void) printf("%s;\n", R_CURL);
+}
+
+/* dump C initializers for the terminal type */
+static void dump_termtype(void)
+{
+ (void) printf("\t%s\n\t\t\"%s\",\n", L_CURL, term->term_names);
+ (void) printf("\t\t(char *)0,\t/* pointer to string table */\n");
+
+ (void) printf("\t\t%s,\n", name_initializer("bool"));
+ (void) printf("\t\t%s,\n", name_initializer("number"));
+
+ (void) printf("\t\t%s,\n", name_initializer("string"));
+
+#if NCURSES_XNAMES
+ (void) printf("#if NCURSES_XNAMES\n");
+ (void) printf("\t\t(char *)0,\t/* pointer to extended string table */\n");
+ (void) printf("\t\t%s,\t/* ...corresponding names */\n",
+ (NUM_STRINGS(term) != STRCOUNT)
+ ? name_initializer("string_ext")
+ : "(char **)0");
+
+ (void) printf("\t\t%d,\t\t/* count total Booleans */\n", NUM_BOOLEANS(term));
+ (void) printf("\t\t%d,\t\t/* count total Numbers */\n", NUM_NUMBERS(term));
+ (void) printf("\t\t%d,\t\t/* count total Strings */\n", NUM_STRINGS(term));
+
+ (void) printf("\t\t%d,\t\t/* count extensions to Booleans */\n", NUM_BOOLEANS(term) - BOOLCOUNT);
+ (void) printf("\t\t%d,\t\t/* count extensions to Numbers */\n", NUM_NUMBERS(term) - NUMCOUNT);
+ (void) printf("\t\t%d,\t\t/* count extensions to Strings */\n", NUM_STRINGS(term) - STRCOUNT);
+
+ (void) printf("#endif /* NCURSES_XNAMES */\n");
+#endif /* NCURSES_XNAMES */
+ (void) printf("\t%s\n", R_CURL);
+}
+
+/***************************************************************************
+ *
+ * Main sequence
+ *
+ ***************************************************************************/
+
+int main(int argc, char *argv[])
+{
+ char *terminal, *firstdir, *restdir;
+ /* Avoid "local data >32k" error with mwcc */
+ /* Also avoid overflowing smaller stacks on systems like AmigaOS */
+ path *tfile = malloc(sizeof(path)*MAXTERMS);
+ int c, i, len;
+ bool formatted = FALSE;
+ bool filecompare = FALSE;
+ int initdump = 0;
+ bool init_analyze = FALSE;
+ bool limited = TRUE;
+
+ if ((terminal = getenv("TERM")) == NULL)
+ {
+ (void) fprintf(stderr,
+ "infocmp: environment variable TERM not set\n");
+ return EXIT_FAILURE;
+ }
+
+ /* where is the terminfo database location going to default to? */
+ restdir = firstdir = 0;
+
+ while ((c = getopt(argc, argv, "deEcCfFGgIinlLprR:s:uv:Vw:A:B:1T")) != EOF)
+ switch (c)
+ {
+ case 'd':
+ compare = C_DIFFERENCE;
+ break;
+
+ case 'e':
+ initdump |= 1;
+ break;
+
+ case 'E':
+ initdump |= 2;
+ break;
+
+ case 'c':
+ compare = C_COMMON;
+ break;
+
+ case 'C':
+ outform = F_TERMCAP;
+ tversion = "BSD";
+ if (sortmode == S_DEFAULT)
+ sortmode = S_TERMCAP;
+ break;
+
+ case 'f':
+ formatted = TRUE;
+ break;
+
+ case 'G':
+ numbers = 1;
+ break;
+
+ case 'g':
+ numbers = -1;
+ break;
+
+ case 'F':
+ filecompare = TRUE;
+ break;
+
+ case 'I':
+ outform = F_TERMINFO;
+ if (sortmode == S_DEFAULT)
+ sortmode = S_VARIABLE;
+ tversion = 0;
+ break;
+
+ case 'i':
+ init_analyze = TRUE;
+ break;
+
+ case 'l':
+ outform = F_TERMINFO;
+ break;
+
+ case 'L':
+ outform = F_VARIABLE;
+ if (sortmode == S_DEFAULT)
+ sortmode = S_VARIABLE;
+ break;
+
+ case 'n':
+ compare = C_NAND;
+ break;
+
+ case 'p':
+ ignorepads = TRUE;
+ break;
+
+ case 'r':
+ tversion = 0;
+ limited = FALSE;
+ break;
+
+ case 'R':
+ tversion = optarg;
+ break;
+
+ case 's':
+ if (*optarg == 'd')
+ sortmode = S_NOSORT;
+ else if (*optarg == 'i')
+ sortmode = S_TERMINFO;
+ else if (*optarg == 'l')
+ sortmode = S_VARIABLE;
+ else if (*optarg == 'c')
+ sortmode = S_TERMCAP;
+ else
+ {
+ (void) fprintf(stderr,
+ "infocmp: unknown sort mode\n");
+ return EXIT_FAILURE;
+ }
+ break;
+
+ case 'u':
+ compare = C_USEALL;
+ break;
+
+ case 'v':
+ itrace = atoi(optarg);
+ _nc_tracing = (1 << itrace) - 1;
+ break;
+
+ case 'V':
+ (void) fputs(NCURSES_VERSION, stdout);
+ putchar('\n');
+ ExitProgram(EXIT_SUCCESS);
+
+ case 'w':
+ mwidth = atoi(optarg);
+ break;
+
+ case 'A':
+ firstdir = optarg;
+ break;
+
+ case 'B':
+ restdir = optarg;
+ break;
+
+ case '1':
+ mwidth = 0;
+ break;
+
+ case 'T':
+ limited = FALSE;
+ break;
+ default:
+ usage();
+ }
+
+ /* by default, sort by terminfo name */
+ if (sortmode == S_DEFAULT)
+ sortmode = S_TERMINFO;
+
+ /* set up for display */
+ dump_init(tversion, outform, sortmode, mwidth, itrace, formatted);
+
+ /* make sure we have at least one terminal name to work with */
+ if (optind >= argc)
+ argv[argc++] = terminal;
+
+ /* if user is after a comparison, make sure we have two entries */
+ if (compare != C_DEFAULT && optind >= argc - 1)
+ argv[argc++] = terminal;
+
+ /* exactly two terminal names with no options means do -d */
+ if (argc - optind == 2 && compare == C_DEFAULT)
+ compare = C_DIFFERENCE;
+
+ if (!filecompare)
+ {
+ /* grab the entries */
+ termcount = 0;
+ for (; optind < argc; optind++)
+ {
+ if (termcount >= MAXTERMS)
+ {
+ (void) fprintf(stderr,
+ "infocmp: too many terminal type arguments\n");
+ return EXIT_FAILURE;
+ }
+ else
+ {
+ const char *directory = termcount ? restdir : firstdir;
+ int status;
+
+ tname[termcount] = argv[optind];
+
+ if (directory)
+ {
+ (void) sprintf(tfile[termcount], "%s/%c/%s",
+ directory,
+ *argv[optind], argv[optind]);
+ if (itrace)
+ (void) fprintf(stderr,
+ "infocmp: reading entry %s from file %s\n",
+ argv[optind], tfile[termcount]);
+
+ status = _nc_read_file_entry(tfile[termcount],
+ &term[termcount]);
+ }
+ else
+ {
+ if (itrace)
+ (void) fprintf(stderr,
+ "infocmp: reading entry %s from system directories %s\n",
+ argv[optind], tname[termcount]);
+
+ status = _nc_read_entry(tname[termcount],
+ tfile[termcount],
+ &term[termcount]);
+ directory = TERMINFO; /* for error message */
+ }
+
+ if (status <= 0)
+ {
+ (void) fprintf(stderr,
+ "infocmp: couldn't open terminfo file %s.\n",
+ tfile[termcount]);
+ return EXIT_FAILURE;
+ }
+ termcount++;
+ }
+ }
+
+#if NCURSES_XNAMES
+ if (termcount > 1)
+ _nc_align_termtype(&term[0], &term[1]);
+#endif
+
+ /* dump as C initializer for the terminal type */
+ if (initdump)
+ {
+ if (initdump & 1)
+ dump_termtype();
+ if (initdump & 2)
+ dump_initializers();
+ ExitProgram(EXIT_SUCCESS);
+ }
+
+ /* analyze the init strings */
+ if (init_analyze)
+ {
+#undef CUR
+#define CUR term[0].
+ analyze_string("is1", init_1string, &term[0]);
+ analyze_string("is2", init_2string, &term[0]);
+ analyze_string("is3", init_3string, &term[0]);
+ analyze_string("rs1", reset_1string, &term[0]);
+ analyze_string("rs2", reset_2string, &term[0]);
+ analyze_string("rs3", reset_3string, &term[0]);
+ analyze_string("smcup", enter_ca_mode, &term[0]);
+ analyze_string("rmcup", exit_ca_mode, &term[0]);
+#undef CUR
+ ExitProgram(EXIT_SUCCESS);
+ }
+
+ /*
+ * Here's where the real work gets done
+ */
+ switch (compare)
+ {
+ case C_DEFAULT:
+ if (itrace)
+ (void) fprintf(stderr,
+ "infocmp: about to dump %s\n",
+ tname[0]);
+ (void) printf("#\tReconstructed via infocmp from file: %s\n",
+ tfile[0]);
+ len = dump_entry(&term[0], limited, numbers, NULL);
+ putchar('\n');
+ if (itrace)
+ (void)fprintf(stderr, "infocmp: length %d\n", len);
+ break;
+
+ case C_DIFFERENCE:
+ if (itrace)
+ (void)fprintf(stderr, "infocmp: dumping differences\n");
+ (void) printf("comparing %s to %s.\n", tname[0], tname[1]);
+ compare_entry(compare_predicate, term);
+ break;
+
+ case C_COMMON:
+ if (itrace)
+ (void) fprintf(stderr,
+ "infocmp: dumping common capabilities\n");
+ (void) printf("comparing %s to %s.\n", tname[0], tname[1]);
+ compare_entry(compare_predicate, term);
+ break;
+
+ case C_NAND:
+ if (itrace)
+ (void) fprintf(stderr,
+ "infocmp: dumping differences\n");
+ (void) printf("comparing %s to %s.\n", tname[0], tname[1]);
+ compare_entry(compare_predicate, term);
+ break;
+
+ case C_USEALL:
+ if (itrace)
+ (void) fprintf(stderr, "infocmp: dumping use entry\n");
+ len = dump_entry(&term[0], limited, numbers, use_predicate);
+ for (i = 1; i < termcount; i++)
+ len += dump_uses(tname[i], !(outform==F_TERMCAP || outform==F_TCONVERR));
+ putchar('\n');
+ if (itrace)
+ (void)fprintf(stderr, "infocmp: length %d\n", len);
+ break;
+ }
+ }
+ else if (compare == C_USEALL)
+ (void) fprintf(stderr, "Sorry, -u doesn't work with -F\n");
+ else if (compare == C_DEFAULT)
+ (void) fprintf(stderr, "Use `tic -[CI] <file>' for this.\n");
+ else if (argc - optind != 2)
+ (void) fprintf(stderr,
+ "File comparison needs exactly two file arguments.\n");
+ else
+ file_comparison(argc-optind, argv+optind);
+
+ ExitProgram(EXIT_SUCCESS);
+}
+
+/* infocmp.c ends here */
diff --git a/contrib/ncurses/progs/modules b/contrib/ncurses/progs/modules
new file mode 100644
index 000000000000..54cd2020269e
--- /dev/null
+++ b/contrib/ncurses/progs/modules
@@ -0,0 +1,40 @@
+# Program modules (some are in ncurses lib!)
+##############################################################################
+# Copyright (c) 1998 Free Software Foundation, Inc. #
+# #
+# 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, distribute #
+# with modifications, 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 COPYRIGHT HOLDERS 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. #
+##############################################################################
+#
+# Author: Thomas E. Dickey <dickey@clark.net> 1995,1997
+#
+
+@ base
+clear progs $(srcdir) ../include/term.h
+tic progs $(srcdir) ../include/term.h $(INCDIR)/tic.h $(srcdir)/dump_entry.h
+toe progs $(srcdir) ../include/term.h $(INCDIR)/tic.h $(srcdir)/dump_entry.h
+dump_entry progs $(srcdir) ../include/term.h $(INCDIR)/tic.h $(srcdir)/dump_entry.h ../include/parametrized.h termsort.c
+infocmp progs $(srcdir) ../include/term.h $(INCDIR)/tic.h $(srcdir)/dump_entry.h
+tput progs $(srcdir) ../include/term.h
+tset progs $(srcdir) ../include/term.h
diff --git a/contrib/ncurses/progs/progs.priv.h b/contrib/ncurses/progs/progs.priv.h
new file mode 100644
index 000000000000..3384d37c4e6d
--- /dev/null
+++ b/contrib/ncurses/progs/progs.priv.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey <dickey@clark.net> 1997,1998 *
+ ****************************************************************************/
+/*
+ * $Id: progs.priv.h,v 1.19 1999/02/23 11:10:32 tom Exp $
+ *
+ * progs.priv.h
+ *
+ * Header file for curses utility programs
+ */
+
+#include <ncurses_cfg.h>
+
+#ifdef USE_RCS_IDS
+#define MODULE_ID(id) static const char Ident[] = id;
+#else
+#define MODULE_ID(id) /*nothing*/
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/types.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#else
+# if HAVE_LIBC_H
+# include <libc.h>
+# endif
+#endif
+
+#if HAVE_SYS_BSDTYPES_H
+#include <sys/bsdtypes.h> /* needed for ISC */
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#elif HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#include <errno.h>
+
+#if DECL_ERRNO
+extern int errno;
+#endif
+
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#else
+/* 'getopt()' may be prototyped in <stdlib.h>, but declaring its
+ * variables doesn't hurt.
+ */
+extern char *optarg;
+extern int optind;
+#endif /* HAVE_GETOPT_H */
+
+#include <curses.h>
+#include <term_entry.h>
+#include <tic.h>
+#include <nc_alloc.h>
+
+/* usually in <unistd.h> */
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+#ifndef F_OK
+#define F_OK 0 /* Test for existence. */
+#endif
+
+/* usually in <unistd.h> */
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+/* may be in limits.h, included from various places */
+#ifndef PATH_MAX
+# if defined(_POSIX_PATH_MAX)
+# define PATH_MAX _POSIX_PATH_MAX
+# elif defined(MAXPATHLEN)
+# define PATH_MAX MAXPATHLEN
+# else
+# define PATH_MAX 255 /* the Posix minimum pathsize */
+# endif
+#endif
+
+/* We use isascii only to guard against use of 7-bit ctype tables in the
+ * isprint test in infocmp.
+ */
+#ifndef HAVE_ISASCII
+# undef isascii
+# if ('z'-'a' == 25) && ('z' < 127) && ('Z'-'A' == 25) && ('Z' < 127) && ('9' < 127)
+# define isascii(c) (((c) & 0xff) <= 127)
+# else
+# define isascii(c) 1 /* not really ascii anyway */
+# endif
+#endif
diff --git a/contrib/ncurses/progs/tic.c b/contrib/ncurses/progs/tic.c
new file mode 100644
index 000000000000..d81af0a3cdc6
--- /dev/null
+++ b/contrib/ncurses/progs/tic.c
@@ -0,0 +1,812 @@
+/****************************************************************************
+ * Copyright (c) 1998,1999 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+/*
+ * tic.c --- Main program for terminfo compiler
+ * by Eric S. Raymond
+ *
+ */
+
+#include <progs.priv.h>
+
+#include <dump_entry.h>
+#include <term_entry.h>
+
+MODULE_ID("$Id: tic.c,v 1.51 1999/06/19 21:35:36 Philippe.De.Muyter Exp $")
+
+const char *_nc_progname = "tic";
+
+static FILE *log_fp;
+static FILE *tmp_fp;
+static bool showsummary = FALSE;
+static const char *to_remove;
+
+static void (*save_check_termtype)(TERMTYPE *);
+static void check_termtype(TERMTYPE *tt);
+
+static const char usage_string[] = "[-h] [-v[n]] [-e names] [-CILNRTcfrswx1] source-file\n";
+
+static void cleanup(void)
+{
+ if (tmp_fp != 0)
+ fclose(tmp_fp);
+ if (to_remove != 0) {
+#if HAVE_REMOVE
+ remove(to_remove);
+#else
+ unlink(to_remove);
+#endif
+ }
+}
+
+static void failed(const char *msg)
+{
+ perror(msg);
+ cleanup();
+ exit(EXIT_FAILURE);
+}
+
+static void usage(void)
+{
+ static const char *const tbl[] = {
+ "Options:",
+ " -1 format translation output one capability per line",
+ " -C translate entries to termcap source form",
+ " -I translate entries to terminfo source form",
+ " -L translate entries to full terminfo source form",
+ " -N disable smart defaults for source translation",
+ " -R restrict translation to given terminfo/termcap version",
+ " -T remove size-restrictions on compiled description",
+ " -c check only, validate input without compiling or translating",
+ " -f format complex strings for readability",
+ " -G format %{number} to %'char'",
+ " -g format %'char' to %{number}",
+ " -e<names> translate/compile only entries named by comma-separated list",
+ " -o<dir> set output directory for compiled entry writes",
+ " -r force resolution of all use entries in source translation",
+ " -s print summary statistics",
+ " -v[n] set verbosity level",
+ " -w[n] set format width for translation output",
+#if NCURSES_XNAMES
+ " -x treat unknown capabilities as user-defined",
+#endif
+ "",
+ "Parameters:",
+ " <file> file to translate or compile"
+ };
+ size_t j;
+
+ printf("Usage: %s %s\n", _nc_progname, usage_string);
+ for (j = 0; j < sizeof(tbl)/sizeof(tbl[0]); j++)
+ puts(tbl[j]);
+ exit(EXIT_FAILURE);
+}
+
+#define L_BRACE '{'
+#define R_BRACE '}'
+#define S_QUOTE '\'';
+
+static void write_it(ENTRY *ep)
+{
+ unsigned n;
+ int ch;
+ char *s, *d, *t;
+ char result[MAX_ENTRY_SIZE];
+
+ /*
+ * Look for strings that contain %{number}, convert them to %'char',
+ * which is shorter and runs a little faster.
+ */
+ for (n = 0; n < STRCOUNT; n++) {
+ s = ep->tterm.Strings[n];
+ if (VALID_STRING(s)
+ && strchr(s, L_BRACE) != 0) {
+ d = result;
+ t = s;
+ while ((ch = *t++) != 0) {
+ *d++ = ch;
+ if (ch == '\\') {
+ *d++ = *t++;
+ } else if ((ch == '%')
+ && (*t == L_BRACE)) {
+ char *v = 0;
+ long value = strtol(t+1, &v, 0);
+ if (v != 0
+ && *v == R_BRACE
+ && value > 0
+ && value != '\\' /* FIXME */
+ && value < 127
+ && isprint((int)value)) {
+ *d++ = S_QUOTE;
+ *d++ = (int)value;
+ *d++ = S_QUOTE;
+ t = (v + 1);
+ }
+ }
+ }
+ *d = 0;
+ if (strlen(result) < strlen(s))
+ strcpy(s, result);
+ }
+ }
+
+ _nc_set_type(_nc_first_name(ep->tterm.term_names));
+ _nc_curr_line = ep->startline;
+ _nc_write_entry(&ep->tterm);
+}
+
+static bool immedhook(ENTRY *ep GCC_UNUSED)
+/* write out entries with no use capabilities immediately to save storage */
+{
+#ifndef HAVE_BIG_CORE
+ /*
+ * This is strictly a core-economy kluge. The really clean way to handle
+ * compilation is to slurp the whole file into core and then do all the
+ * name-collision checks and entry writes in one swell foop. But the
+ * terminfo master file is large enough that some core-poor systems swap
+ * like crazy when you compile it this way...there have been reports of
+ * this process taking *three hours*, rather than the twenty seconds or
+ * less typical on my development box.
+ *
+ * So. This hook *immediately* writes out the referenced entry if it
+ * has no use capabilities. The compiler main loop refrains from
+ * adding the entry to the in-core list when this hook fires. If some
+ * other entry later needs to reference an entry that got written
+ * immediately, that's OK; the resolution code will fetch it off disk
+ * when it can't find it in core.
+ *
+ * Name collisions will still be detected, just not as cleanly. The
+ * write_entry() code complains before overwriting an entry that
+ * postdates the time of tic's first call to write_entry(). Thus
+ * it will complain about overwriting entries newly made during the
+ * tic run, but not about overwriting ones that predate it.
+ *
+ * The reason this is a hook, and not in line with the rest of the
+ * compiler code, is that the support for termcap fallback cannot assume
+ * it has anywhere to spool out these entries!
+ *
+ * The _nc_set_type() call here requires a compensating one in
+ * _nc_parse_entry().
+ *
+ * If you define HAVE_BIG_CORE, you'll disable this kluge. This will
+ * make tic a bit faster (because the resolution code won't have to do
+ * disk I/O nearly as often).
+ */
+ if (ep->nuses == 0)
+ {
+ int oldline = _nc_curr_line;
+
+ write_it(ep);
+ _nc_curr_line = oldline;
+ free(ep->tterm.str_table);
+ return(TRUE);
+ }
+#endif /* HAVE_BIG_CORE */
+ return(FALSE);
+}
+
+static void put_translate(int c)
+/* emit a comment char, translating terminfo names to termcap names */
+{
+ static bool in_name = FALSE;
+ static char namebuf[132], suffix[132], *sp;
+
+ if (!in_name)
+ {
+ if (c == '<')
+ {
+ in_name = TRUE;
+ sp = namebuf;
+ }
+ else
+ putchar(c);
+ }
+ else if (c == '\n' || c == '@')
+ {
+ *sp++ = '\0';
+ (void) putchar('<');
+ (void) fputs(namebuf, stdout);
+ putchar(c);
+ in_name = FALSE;
+ }
+ else if (c != '>')
+ *sp++ = c;
+ else /* ah! candidate name! */
+ {
+ char *up;
+ NCURSES_CONST char *tp;
+
+ *sp++ = '\0';
+ in_name = FALSE;
+
+ suffix[0] = '\0';
+ if ((up = strchr(namebuf, '#')) != 0
+ || (up = strchr(namebuf, '=')) != 0
+ || ((up = strchr(namebuf, '@')) != 0 && up[1] == '>'))
+ {
+ (void) strcpy(suffix, up);
+ *up = '\0';
+ }
+
+ if ((tp = nametrans(namebuf)) != 0)
+ {
+ (void) putchar(':');
+ (void) fputs(tp, stdout);
+ (void) fputs(suffix, stdout);
+ (void) putchar(':');
+ }
+ else
+ {
+ /* couldn't find a translation, just dump the name */
+ (void) putchar('<');
+ (void) fputs(namebuf, stdout);
+ (void) fputs(suffix, stdout);
+ (void) putchar('>');
+ }
+
+ }
+}
+
+/* Returns a string, stripped of leading/trailing whitespace */
+static char *stripped(char *src)
+{
+ while (isspace(*src))
+ src++;
+ if (*src != '\0') {
+ char *dst = strcpy(malloc(strlen(src)+1), src);
+ size_t len = strlen(dst);
+ while (--len != 0 && isspace(dst[len]))
+ dst[len] = '\0';
+ return dst;
+ }
+ return 0;
+}
+
+/* Parse the "-e" option-value into a list of names */
+static const char **make_namelist(char *src)
+{
+ const char **dst = 0;
+
+ char *s, *base;
+ unsigned pass, n, nn;
+ char buffer[BUFSIZ];
+
+ if (src == 0) {
+ /* EMPTY */;
+ } else if (strchr(src, '/') != 0) { /* a filename */
+ FILE *fp = fopen(src, "r");
+ if (fp == 0)
+ failed(src);
+
+ for (pass = 1; pass <= 2; pass++) {
+ nn = 0;
+ while (fgets(buffer, sizeof(buffer), fp) != 0) {
+ if ((s = stripped(buffer)) != 0) {
+ if (dst != 0)
+ dst[nn] = s;
+ nn++;
+ }
+ }
+ if (pass == 1) {
+ dst = (const char **)calloc(nn+1, sizeof(*dst));
+ rewind(fp);
+ }
+ }
+ fclose(fp);
+ } else { /* literal list of names */
+ for (pass = 1; pass <= 2; pass++) {
+ for (n = nn = 0, base = src; ; n++) {
+ int mark = src[n];
+ if (mark == ',' || mark == '\0') {
+ if (pass == 1) {
+ nn++;
+ } else {
+ src[n] = '\0';
+ if ((s = stripped(base)) != 0)
+ dst[nn++] = s;
+ base = &src[n+1];
+ }
+ }
+ if (mark == '\0')
+ break;
+ }
+ if (pass == 1)
+ dst = (const char **)calloc(nn+1, sizeof(*dst));
+ }
+ }
+ if (showsummary) {
+ fprintf(log_fp, "Entries that will be compiled:\n");
+ for (n = 0; dst[n] != 0; n++)
+ fprintf(log_fp, "%d:%s\n", n+1, dst[n]);
+ }
+ return dst;
+}
+
+static bool matches(const char **needle, const char *haystack)
+/* does entry in needle list match |-separated field in haystack? */
+{
+ bool code = FALSE;
+ size_t n;
+
+ if (needle != 0)
+ {
+ for (n = 0; needle[n] != 0; n++)
+ {
+ if (_nc_name_match(haystack, needle[n], "|"))
+ {
+ code = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ code = TRUE;
+ return(code);
+}
+
+int main (int argc, char *argv[])
+{
+char my_tmpname[PATH_MAX];
+int v_opt = -1, debug_level;
+int smart_defaults = TRUE;
+char *termcap;
+ENTRY *qp;
+
+int this_opt, last_opt = '?';
+
+int outform = F_TERMINFO; /* output format */
+int sortmode = S_TERMINFO; /* sort_mode */
+
+int width = 60;
+bool formatted = FALSE; /* reformat complex strings? */
+int numbers = 0; /* format "%'char'" to/from "%{number}" */
+bool infodump = FALSE; /* running as captoinfo? */
+bool capdump = FALSE; /* running as infotocap? */
+bool forceresolve = FALSE; /* force resolution */
+bool limited = TRUE;
+char *tversion = (char *)NULL;
+const char *source_file = "terminfo";
+const char **namelst = 0;
+char *outdir = (char *)NULL;
+bool check_only = FALSE;
+
+ log_fp = stderr;
+
+ if ((_nc_progname = strrchr(argv[0], '/')) == NULL)
+ _nc_progname = argv[0];
+ else
+ _nc_progname++;
+
+ infodump = (strcmp(_nc_progname, "captoinfo") == 0);
+ capdump = (strcmp(_nc_progname, "infotocap") == 0);
+#if NCURSES_XNAMES
+ use_extended_names(FALSE);
+#endif
+
+ /*
+ * Processing arguments is a little complicated, since someone made a
+ * design decision to allow the numeric values for -w, -v options to
+ * be optional.
+ */
+ while ((this_opt = getopt(argc, argv, "0123456789CILNR:TVce:fGgo:rsvwx")) != EOF) {
+ if (isdigit(this_opt)) {
+ switch (last_opt) {
+ case 'v':
+ v_opt = (v_opt * 10) + (this_opt - '0');
+ break;
+ case 'w':
+ width = (width * 10) + (this_opt - '0');
+ break;
+ default:
+ if (this_opt != '1')
+ usage();
+ last_opt = this_opt;
+ width = 0;
+ }
+ continue;
+ }
+ switch (this_opt) {
+ case 'C':
+ capdump = TRUE;
+ outform = F_TERMCAP;
+ sortmode = S_TERMCAP;
+ break;
+ case 'I':
+ infodump = TRUE;
+ outform = F_TERMINFO;
+ sortmode = S_TERMINFO;
+ break;
+ case 'L':
+ infodump = TRUE;
+ outform = F_VARIABLE;
+ sortmode = S_VARIABLE;
+ break;
+ case 'N':
+ smart_defaults = FALSE;
+ break;
+ case 'R':
+ tversion = optarg;
+ break;
+ case 'T':
+ limited = FALSE;
+ break;
+ case 'V':
+ puts(NCURSES_VERSION);
+ return EXIT_SUCCESS;
+ case 'c':
+ check_only = TRUE;
+ break;
+ case 'e':
+ namelst = make_namelist(optarg);
+ break;
+ case 'f':
+ formatted = TRUE;
+ break;
+ case 'G':
+ numbers = 1;
+ break;
+ case 'g':
+ numbers = -1;
+ break;
+ case 'o':
+ outdir = optarg;
+ break;
+ case 'r':
+ forceresolve = TRUE;
+ break;
+ case 's':
+ showsummary = TRUE;
+ break;
+ case 'v':
+ v_opt = 0;
+ break;
+ case 'w':
+ width = 0;
+ break;
+#if NCURSES_XNAMES
+ case 'x':
+ use_extended_names(TRUE);
+ break;
+#endif
+ default:
+ usage();
+ }
+ last_opt = this_opt;
+ }
+
+ debug_level = (v_opt > 0) ? v_opt : (v_opt == 0);
+ _nc_tracing = (1 << debug_level) - 1;
+
+ if (_nc_tracing)
+ {
+ save_check_termtype = _nc_check_termtype;
+ _nc_check_termtype = check_termtype;
+ }
+
+#ifndef HAVE_BIG_CORE
+ /*
+ * Aaargh! immedhook seriously hoses us!
+ *
+ * One problem with immedhook is it means we can't do -e. Problem
+ * is that we can't guarantee that for each terminal listed, all the
+ * terminals it depends on will have been kept in core for reference
+ * resolution -- in fact it's certain the primitive types at the end
+ * of reference chains *won't* be in core unless they were explicitly
+ * in the select list themselves.
+ */
+ if (namelst && (!infodump && !capdump))
+ {
+ (void) fprintf(stderr,
+ "Sorry, -e can't be used without -I or -C\n");
+ cleanup();
+ return EXIT_FAILURE;
+ }
+#endif /* HAVE_BIG_CORE */
+
+ if (optind < argc) {
+ source_file = argv[optind++];
+ if (optind < argc) {
+ fprintf (stderr,
+ "%s: Too many file names. Usage:\n\t%s %s",
+ _nc_progname,
+ _nc_progname,
+ usage_string);
+ return EXIT_FAILURE;
+ }
+ } else {
+ if (infodump == TRUE) {
+ /* captoinfo's no-argument case */
+ source_file = "/etc/termcap";
+ if ((termcap = getenv("TERMCAP")) != 0
+ && (namelst = make_namelist(getenv("TERM"))) != 0) {
+ if (access(termcap, F_OK) == 0) {
+ /* file exists */
+ source_file = termcap;
+ } else
+ if ((source_file = tmpnam(my_tmpname)) != 0
+ && (tmp_fp = fopen(source_file, "w")) != 0) {
+ fprintf(tmp_fp, "%s\n", termcap);
+ fclose(tmp_fp);
+ tmp_fp = fopen(source_file, "r");
+ to_remove = source_file;
+ } else {
+ failed("tmpnam");
+ }
+ }
+ } else {
+ /* tic */
+ fprintf (stderr,
+ "%s: File name needed. Usage:\n\t%s %s",
+ _nc_progname,
+ _nc_progname,
+ usage_string);
+ cleanup();
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (tmp_fp == 0
+ && (tmp_fp = fopen(source_file, "r")) == 0) {
+ fprintf (stderr, "%s: Can't open %s\n", _nc_progname, source_file);
+ return EXIT_FAILURE;
+ }
+
+ if (infodump)
+ dump_init(tversion,
+ smart_defaults
+ ? outform
+ : F_LITERAL,
+ sortmode, width, debug_level, formatted);
+ else if (capdump)
+ dump_init(tversion,
+ outform,
+ sortmode, width, debug_level, FALSE);
+
+ /* parse entries out of the source file */
+ _nc_set_source(source_file);
+#ifndef HAVE_BIG_CORE
+ if (!(check_only || infodump || capdump))
+ _nc_set_writedir(outdir);
+#endif /* HAVE_BIG_CORE */
+ _nc_read_entry_source(tmp_fp, (char *)NULL,
+ !smart_defaults, FALSE,
+ (check_only || infodump || capdump) ? NULLHOOK : immedhook);
+
+ /* do use resolution */
+ if (check_only || (!infodump && !capdump) || forceresolve) {
+ if (!_nc_resolve_uses() && !check_only) {
+ cleanup();
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* length check */
+ if (check_only && (capdump || infodump))
+ {
+ for_entry_list(qp)
+ {
+ if (matches(namelst, qp->tterm.term_names))
+ {
+ int len = fmt_entry(&qp->tterm, NULL, TRUE, infodump, numbers);
+
+ if (len>(infodump?MAX_TERMINFO_LENGTH:MAX_TERMCAP_LENGTH))
+ (void) fprintf(stderr,
+ "warning: resolved %s entry is %d bytes long\n",
+ _nc_first_name(qp->tterm.term_names),
+ len);
+ }
+ }
+ }
+
+ /* write or dump all entries */
+ if (!check_only)
+ {
+ if (!infodump && !capdump)
+ {
+ _nc_set_writedir(outdir);
+ for_entry_list(qp)
+ if (matches(namelst, qp->tterm.term_names))
+ write_it(qp);
+ }
+ else
+ {
+ /* this is in case infotocap() generates warnings */
+ _nc_curr_col = _nc_curr_line = -1;
+
+ for_entry_list(qp)
+ if (matches(namelst, qp->tterm.term_names))
+ {
+ int j = qp->cend - qp->cstart;
+ int len = 0;
+
+ /* this is in case infotocap() generates warnings */
+ _nc_set_type(_nc_first_name(qp->tterm.term_names));
+
+ (void) fseek(tmp_fp, qp->cstart, SEEK_SET);
+ while (j-- )
+ if (infodump)
+ (void) putchar(fgetc(tmp_fp));
+ else
+ put_translate(fgetc(tmp_fp));
+
+ len = dump_entry(&qp->tterm, limited, numbers, NULL);
+ for (j = 0; j < qp->nuses; j++)
+ len += dump_uses((char *)(qp->uses[j].parent), infodump);
+ (void) putchar('\n');
+ if (debug_level != 0 && !limited)
+ printf("# length=%d\n", len);
+ }
+ if (!namelst)
+ {
+ int c, oldc = '\0';
+ bool in_comment = FALSE;
+ bool trailing_comment = FALSE;
+
+ (void) fseek(tmp_fp, _nc_tail->cend, SEEK_SET);
+ while ((c = fgetc(tmp_fp)) != EOF)
+ {
+ if (oldc == '\n') {
+ if (c == '#') {
+ trailing_comment = TRUE;
+ in_comment = TRUE;
+ } else {
+ in_comment = FALSE;
+ }
+ }
+ if (trailing_comment
+ && (in_comment || (oldc == '\n' && c == '\n')))
+ putchar(c);
+ oldc = c;
+ }
+ }
+ }
+ }
+
+ /* Show the directory into which entries were written, and the total
+ * number of entries
+ */
+ if (showsummary
+ && (!(check_only || infodump || capdump))) {
+ int total = _nc_tic_written();
+ if (total != 0)
+ fprintf(log_fp, "%d entries written to %s\n",
+ total,
+ _nc_tic_dir((char *)0));
+ else
+ fprintf(log_fp, "No entries written\n");
+ }
+ cleanup();
+ return(EXIT_SUCCESS);
+}
+
+/*
+ * This bit of legerdemain turns all the terminfo variable names into
+ * references to locations in the arrays Booleans, Numbers, and Strings ---
+ * precisely what's needed (see comp_parse.c).
+ */
+
+TERMINAL *cur_term; /* tweak to avoid linking lib_cur_term.c */
+
+#undef CUR
+#define CUR tp->
+
+/* other sanity-checks (things that we don't want in the normal
+ * logic that reads a terminfo entry)
+ */
+static void check_termtype(TERMTYPE *tp)
+{
+ bool conflict = FALSE;
+ unsigned j, k;
+ char fkeys[STRCOUNT];
+
+ /*
+ * A terminal entry may contain more than one keycode assigned to
+ * a given string (e.g., KEY_END and KEY_LL). But curses will only
+ * return one (the last one assigned).
+ */
+ memset(fkeys, 0, sizeof(fkeys));
+ for (j = 0; _nc_tinfo_fkeys[j].code; j++) {
+ char *a = tp->Strings[_nc_tinfo_fkeys[j].offset];
+ bool first = TRUE;
+ if (!VALID_STRING(a))
+ continue;
+ for (k = j+1; _nc_tinfo_fkeys[k].code; k++) {
+ char *b = tp->Strings[_nc_tinfo_fkeys[k].offset];
+ if (!VALID_STRING(b)
+ || fkeys[k])
+ continue;
+ if (!strcmp(a,b)) {
+ fkeys[j] = 1;
+ fkeys[k] = 1;
+ if (first) {
+ if (!conflict) {
+ _nc_warning("Conflicting key definitions (using the last)");
+ conflict = TRUE;
+ }
+ fprintf(stderr, "... %s is the same as %s",
+ keyname(_nc_tinfo_fkeys[j].code),
+ keyname(_nc_tinfo_fkeys[k].code));
+ first = FALSE;
+ } else {
+ fprintf(stderr, ", %s",
+ keyname(_nc_tinfo_fkeys[k].code));
+ }
+ }
+ }
+ if (!first)
+ fprintf(stderr, "\n");
+ }
+
+ /*
+ * Quick check for color. We could also check if the ANSI versus
+ * non-ANSI strings are misused.
+ */
+ if ((max_colors > 0) != (max_pairs > 0)
+ || (max_colors > max_pairs))
+ _nc_warning("inconsistent values for max_colors and max_pairs");
+
+ PAIRED(set_foreground, set_background)
+ PAIRED(set_a_foreground, set_a_background)
+
+ /*
+ * These may be mismatched because the terminal description relies on
+ * restoring the cursor visibility by resetting it.
+ */
+ ANDMISSING(cursor_invisible, cursor_normal)
+ ANDMISSING(cursor_visible, cursor_normal)
+
+ /*
+ * From XSI & O'Reilly, we gather that sc/rc are required if csr is
+ * given, because the cursor position after the scrolling operation is
+ * performed is undefined.
+ */
+ ANDMISSING(change_scroll_region, save_cursor)
+ ANDMISSING(change_scroll_region, restore_cursor)
+
+ /*
+ * Some standard applications (e.g., vi) and some non-curses
+ * applications (e.g., jove) get confused if we have both ich/ich1 and
+ * smir/rmir. Let's be nice and warn about that, too, even though
+ * ncurses handles it.
+ */
+ if ((PRESENT(enter_insert_mode) || PRESENT(exit_insert_mode))
+ && (PRESENT(insert_character) || PRESENT(parm_ich))) {
+ _nc_warning("non-curses applications may be confused by ich/ich1 with smir/rmir");
+ }
+
+ /*
+ * Finally, do the non-verbose checks
+ */
+ if (save_check_termtype != 0)
+ save_check_termtype(tp);
+}
diff --git a/contrib/ncurses/progs/toe.c b/contrib/ncurses/progs/toe.c
new file mode 100644
index 000000000000..f2c5c5ec832d
--- /dev/null
+++ b/contrib/ncurses/progs/toe.c
@@ -0,0 +1,303 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+/*
+ * toe.c --- table of entries report generator
+ *
+ */
+
+#include <progs.priv.h>
+
+#include <sys/stat.h>
+
+#include <dump_entry.h>
+#include <term_entry.h>
+
+MODULE_ID("$Id: toe.c,v 0.19 1998/03/08 01:02:46 tom Exp $")
+
+const char *_nc_progname;
+
+static int typelist(int eargc, char *eargv[], bool,
+ void (*)(const char *, TERMTYPE *));
+static void deschook(const char *, TERMTYPE *);
+
+#if NO_LEAKS
+#undef ExitProgram
+static void ExitProgram(int code) GCC_NORETURN;
+static void ExitProgram(int code)
+{
+ _nc_free_entries(_nc_head);
+ _nc_leaks_dump_entry();
+ _nc_free_and_exit(code);
+}
+#endif
+
+int main (int argc, char *argv[])
+{
+ bool direct_dependencies = FALSE;
+ bool invert_dependencies = FALSE;
+ bool header = FALSE;
+ int i, c, debug_level = 0;
+ int code;
+
+ if ((_nc_progname = strrchr(argv[0], '/')) == NULL)
+ _nc_progname = argv[0];
+ else
+ _nc_progname++;
+
+ while ((c = getopt(argc, argv, "huv:UV")) != EOF)
+ switch (c)
+ {
+ case 'h':
+ header = TRUE;
+ break;
+ case 'u':
+ direct_dependencies = TRUE;
+ break;
+ case 'v':
+ debug_level = atoi(optarg);
+ _nc_tracing = (1 << debug_level) - 1;
+ break;
+ case 'U':
+ invert_dependencies = TRUE;
+ break;
+ case 'V':
+ (void) fputs(NCURSES_VERSION, stdout);
+ putchar('\n');
+ ExitProgram(EXIT_SUCCESS);
+ default:
+ (void) fprintf (stderr, "usage: toe [-huUV] [-v n] [file...]\n");
+ ExitProgram(EXIT_FAILURE);
+ }
+
+ if (direct_dependencies || invert_dependencies)
+ {
+ if (freopen(argv[optind], "r", stdin) == NULL)
+ {
+ (void) fflush(stdout);
+ fprintf(stderr, "%s: can't open %s\n", _nc_progname, argv[optind]);
+ ExitProgram(EXIT_FAILURE);
+ }
+
+ /* parse entries out of the source file */
+ _nc_set_source(argv[optind]);
+ _nc_read_entry_source(stdin, (char *)NULL,
+ FALSE, FALSE,
+ NULLHOOK);
+ }
+
+ /* maybe we want a direct-dependency listing? */
+ if (direct_dependencies)
+ {
+ ENTRY *qp;
+
+ for_entry_list(qp)
+ if (qp->nuses)
+ {
+ int j;
+
+ (void) printf("%s:", _nc_first_name(qp->tterm.term_names));
+ for (j = 0; j < qp->nuses; j++)
+ (void) printf(" %s", (char *)(qp->uses[j].parent));
+ putchar('\n');
+ }
+
+ ExitProgram(EXIT_SUCCESS);
+ }
+
+ /* maybe we want a reverse-dependency listing? */
+ if (invert_dependencies)
+ {
+ ENTRY *qp, *rp;
+ int matchcount;
+
+ for_entry_list(qp)
+ {
+ matchcount = 0;
+ for_entry_list(rp)
+ {
+ if (rp->nuses == 0)
+ continue;
+
+ for (i = 0; i < rp->nuses; i++)
+ if (_nc_name_match(qp->tterm.term_names,(char*)rp->uses[i].parent, "|"))
+ {
+ if (matchcount++ == 0)
+ (void) printf("%s:",
+ _nc_first_name(qp->tterm.term_names));
+ (void) printf(" %s",
+ _nc_first_name(rp->tterm.term_names));
+ }
+ }
+ if (matchcount)
+ putchar('\n');
+ }
+
+ ExitProgram(EXIT_SUCCESS);
+ }
+
+ /*
+ * If we get this far, user wants a simple terminal type listing.
+ */
+ if (optind < argc) {
+ code = typelist(argc-optind, argv+optind, header, deschook);
+ } else {
+ char *by_env, *home, *eargv[3];
+ int j;
+
+ j = 0;
+ if ((by_env = getenv("TERMINFO")) != (char *)NULL)
+ eargv[j++] = by_env;
+ else
+ {
+ if ((home = getenv("HOME")) != (char *)NULL)
+ {
+ char personal[PATH_MAX];
+ struct stat sb;
+
+ (void) sprintf(personal, PRIVATE_INFO, home);
+ if (stat(personal, &sb) == 0
+ && (sb.st_mode & S_IFMT) == S_IFDIR)
+ eargv[j++] = personal;
+ }
+ eargv[j++] = TERMINFO;
+ }
+ eargv[j] = (char *)NULL;
+
+ code = typelist(j, eargv, header, deschook);
+ }
+
+ ExitProgram(code);
+}
+
+static void deschook(const char *cn, TERMTYPE *tp)
+/* display a description for the type */
+{
+ const char *desc;
+
+ if ((desc = strrchr(tp->term_names, '|')) == (char *)NULL)
+ desc = "(No description)";
+ else
+ ++desc;
+
+ (void) printf("%-10s\t%s\n", cn, desc);
+}
+
+static int typelist(int eargc, char *eargv[],
+ bool verbosity,
+ void (*hook)(const char *, TERMTYPE *tp))
+/* apply a function to each entry in given terminfo directories */
+{
+ int i;
+
+ for (i = 0; i < eargc; i++)
+ {
+ DIR *termdir;
+ struct dirent *subdir;
+
+ if ((termdir = opendir(eargv[i])) == (DIR *)NULL)
+ {
+ (void) fflush(stdout);
+ (void) fprintf(stderr,
+ "%s: can't open terminfo directory %s\n",
+ _nc_progname, eargv[i]);
+ return(EXIT_FAILURE);
+ }
+ else if (verbosity)
+ (void) printf("#\n#%s:\n#\n", eargv[i]);
+
+ while ((subdir = readdir(termdir)) != NULL)
+ {
+ size_t len = NAMLEN(subdir);
+ char buf[PATH_MAX];
+ char name_1[PATH_MAX];
+ DIR *entrydir;
+ struct dirent *entry;
+
+ strncpy(name_1, subdir->d_name, len)[len] = '\0';
+ if (!strcmp(name_1, ".")
+ || !strcmp(name_1, ".."))
+ continue;
+
+ (void) strcpy(buf, eargv[i]);
+ (void) strcat(buf, "/");
+ (void) strcat(buf, name_1);
+ (void) strcat(buf, "/");
+ chdir(buf);
+ entrydir = opendir(".");
+ while ((entry = readdir(entrydir)) != NULL)
+ {
+ char name_2[PATH_MAX];
+ TERMTYPE lterm;
+ char *cn;
+ int status;
+
+ len = NAMLEN(entry);
+ strncpy(name_2, entry->d_name, len)[len] = '\0';
+ if (!strcmp(name_2, ".")
+ || !strcmp(name_2, ".."))
+ continue;
+
+ status = _nc_read_file_entry(name_2, &lterm);
+ if (status <= 0)
+ {
+ (void) fflush(stdout);
+ (void) fprintf(stderr,
+ "toe: couldn't open terminfo file %s.\n",
+ name_2);
+ return(EXIT_FAILURE);
+ }
+
+ /* only visit things once, by primary name */
+ cn = _nc_first_name(lterm.term_names);
+ if (!strcmp(cn, name_2))
+ {
+ /* apply the selected hook function */
+ (*hook)(cn, &lterm);
+ }
+ if (lterm.term_names) {
+ free(lterm.term_names);
+ lterm.term_names = NULL;
+ }
+ if (lterm.str_table) {
+ free(lterm.str_table);
+ lterm.str_table = NULL;
+ }
+ }
+ closedir(entrydir);
+ }
+ closedir(termdir);
+ }
+
+ return(EXIT_SUCCESS);
+}
diff --git a/contrib/ncurses/progs/tput.c b/contrib/ncurses/progs/tput.c
new file mode 100644
index 000000000000..7a859f164111
--- /dev/null
+++ b/contrib/ncurses/progs/tput.c
@@ -0,0 +1,312 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * tput.c -- shellscript access to terminal capabilities
+ *
+ * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
+ * Ross Ridge's mytinfo package.
+ */
+
+#include <progs.priv.h>
+#ifndef PURE_TERMINFO
+#include <termsort.c>
+#endif
+
+MODULE_ID("$Id: tput.c,v 1.14 1999/07/31 21:18:29 Goran.Uddeborg Exp $")
+
+#define PUTS(s) fputs(s, stdout)
+#define PUTCHAR(c) putchar(c)
+#define FLUSH fflush(stdout)
+
+static char *prg_name;
+
+static void quit(int status, const char *fmt, ...)
+{
+va_list argp;
+
+ va_start(argp,fmt);
+ vfprintf (stderr, fmt, argp);
+ fprintf(stderr, "\n");
+ va_end(argp);
+ exit(status);
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
+ exit(EXIT_FAILURE);
+}
+
+static int tput(int argc, char *argv[])
+{
+char *name;
+char *s;
+int i, j, c;
+int reset, status;
+FILE *f;
+
+ reset = 0;
+ name = argv[0];
+ if (strcmp(name, "reset") == 0) {
+ reset = 1;
+ }
+ if (reset || strcmp(name, "init") == 0) {
+ if (init_prog != NULL) {
+ system(init_prog);
+ }
+ FLUSH;
+
+ if (reset && reset_1string != NULL) {
+ PUTS(reset_1string);
+ } else if (init_1string != NULL) {
+ PUTS(init_1string);
+ }
+ FLUSH;
+
+ if (reset && reset_2string != NULL) {
+ PUTS(reset_2string);
+ } else if (init_2string != NULL) {
+ PUTS(init_2string);
+ }
+ FLUSH;
+
+ if (set_lr_margin != NULL) {
+ PUTS(tparm(set_lr_margin, 0, columns - 1));
+ } else if (set_left_margin_parm != NULL
+ && set_right_margin_parm != NULL) {
+ PUTS(tparm(set_left_margin_parm, 0));
+ PUTS(tparm(set_right_margin_parm, columns - 1));
+ } else if (clear_margins != NULL && set_left_margin != NULL
+ && set_right_margin != NULL) {
+ PUTS(clear_margins);
+ if (carriage_return != NULL) {
+ PUTS(carriage_return);
+ } else {
+ PUTCHAR('\r');
+ }
+ PUTS(set_left_margin);
+ if (parm_right_cursor) {
+ PUTS(tparm(parm_right_cursor, columns - 1));
+ } else {
+ for(i = 0; i < columns - 1; i++) {
+ PUTCHAR(' ');
+ }
+ }
+ PUTS(set_right_margin);
+ if (carriage_return != NULL) {
+ PUTS(carriage_return);
+ } else {
+ PUTCHAR('\r');
+ }
+ }
+ FLUSH;
+
+ if (init_tabs != 8) {
+ if (clear_all_tabs != NULL && set_tab != NULL) {
+ for(i = 0; i < columns - 1; i += 8) {
+ if (parm_right_cursor) {
+ PUTS(tparm(parm_right_cursor, 8));
+ } else {
+ for(j = 0; j < 8; j++)
+ PUTCHAR(' ');
+ }
+ PUTS(set_tab);
+ }
+ FLUSH;
+ }
+ }
+
+ if (reset && reset_file != NULL) {
+ f = fopen(reset_file, "r");
+ if (f == NULL) {
+ quit(errno, "Can't open reset_file: '%s'", reset_file);
+ }
+ while((c = fgetc(f)) != EOF) {
+ PUTCHAR(c);
+ }
+ fclose(f);
+ } else if (init_file != NULL) {
+ f = fopen(init_file, "r");
+ if (f == NULL) {
+ quit(errno, "Can't open init_file: '%s'", init_file);
+ }
+ while((c = fgetc(f)) != EOF) {
+ PUTCHAR(c);
+ }
+ fclose(f);
+ }
+ FLUSH;
+
+ if (reset && reset_3string != NULL) {
+ PUTS(reset_3string);
+ } else if (init_2string != NULL) {
+ PUTS(init_2string);
+ }
+ FLUSH;
+ return 0;
+ }
+
+ if (strcmp(name, "longname") == 0) {
+ PUTS(longname());
+ return 0;
+ }
+
+#ifndef PURE_TERMINFO
+ {
+ const struct name_table_entry *np;
+
+ if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
+ switch(np->nte_type)
+ {
+ case BOOLEAN:
+ if (bool_from_termcap[np->nte_index])
+ name = boolnames[np->nte_index];
+ break;
+
+ case NUMBER:
+ if (num_from_termcap[np->nte_index])
+ name = numnames[np->nte_index];
+ break;
+
+ case STRING:
+ if (str_from_termcap[np->nte_index])
+ name = strnames[np->nte_index];
+ break;
+ }
+ }
+#endif
+
+ if ((status = tigetflag(name)) != -1)
+ return(status != 0);
+ else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
+ (void) printf("%d\n", status);
+ return(0);
+ }
+ else if ((s = tigetstr(name)) == CANCELLED_STRING)
+ quit(4, "%s: unknown terminfo capability '%s'", prg_name, name);
+ else if (s != (char *)NULL) {
+ if (argc > 1) {
+ int k;
+
+ /* Nasty hack time. The tparm function needs to see numeric
+ * parameters as numbers, not as pointers to their string
+ * representations
+ */
+
+ for (k = 1; k < argc; k++)
+ if (isdigit(argv[k][0])) {
+ long val = atol(argv[k]);
+ argv[k] = (char *)val;
+ }
+
+ s = tparm(s,argv[1],argv[2],argv[3],argv[4],
+ argv[5],argv[6],argv[7],argv[8],
+ argv[9]);
+ }
+
+ /* use putp() in order to perform padding */
+ putp(s);
+ return(0);
+ }
+ return(0);
+}
+
+int main(int argc, char **argv)
+{
+char *s, *term;
+int errret, cmdline = 1;
+int c;
+char buf[BUFSIZ];
+int errors = 0;
+
+ prg_name = argv[0];
+ s = strrchr(prg_name, '/');
+ if (s != NULL && *++s != '\0')
+ prg_name = s;
+
+ term = getenv("TERM");
+
+ while ((c = getopt (argc, argv, "ST:")) != EOF)
+ switch (c)
+ {
+ case 'S':
+ cmdline = 0;
+ break;
+ case 'T':
+ use_env(FALSE);
+ term = optarg;
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (cmdline && argc == 0) {
+ usage();
+ /* NOTREACHED */
+ }
+
+ if (term == NULL || *term == '\0')
+ quit(2, "No value for $TERM and no -T specified");
+
+ if (setupterm(term, STDOUT_FILENO, &errret) != OK && errret <= 0)
+ quit(3, "unknown terminal \"%s\"", term);
+
+ if (cmdline)
+ return tput(argc, argv);
+
+ while (fgets(buf, sizeof(buf), stdin) != (char *)NULL) {
+ char *argvec[16]; /* command, 9 parms, null, & slop */
+ int argnum = 0;
+ char *cp;
+
+ /* crack the argument list into a dope vector */
+ for (cp = buf; *cp; cp++) {
+ if (isspace(*cp))
+ *cp = '\0';
+ else if (cp == buf || cp[-1] == 0)
+ argvec[argnum++] = cp;
+ }
+ argvec[argnum] = (char *)NULL;
+
+ if (tput(argnum, argvec) != 0)
+ errors++;
+ }
+
+ return errors > 0;
+}
+
diff --git a/contrib/ncurses/progs/tset.c b/contrib/ncurses/progs/tset.c
new file mode 100644
index 000000000000..cef980ad9737
--- /dev/null
+++ b/contrib/ncurses/progs/tset.c
@@ -0,0 +1,1200 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 COPYRIGHT HOLDERS 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * tset.c - terminal initialization utility
+ *
+ * This code was mostly swiped from 4.4BSD tset, with some obsolescent
+ * cruft removed and substantial portions rewritten. A Regents of the
+ * University of California copyright applies to some portions of the
+ * code, and is reproduced below:
+ */
+/*-
+ * Copyright (c) 1980, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define __INTERNAL_CAPS_VISIBLE /* we need to see has_hardware_tabs */
+#include <progs.priv.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <termcap.h>
+#include <fcntl.h>
+
+#if HAVE_GETTTYNAM && HAVE_TTYENT_H
+#include <ttyent.h>
+#endif
+#ifdef NeXT
+char *ttyname(int fd);
+#endif
+
+/* this is just to stifle a missing-prototype warning */
+#ifdef linux
+# include <sys/ioctl.h>
+#endif
+
+#if NEED_PTEM_H
+/* they neglected to define struct winsize in termios.h -- it's only
+ in termio.h */
+#include <sys/stream.h>
+#include <sys/ptem.h>
+#endif
+
+#include <curses.h> /* for bool typedef */
+#include <dump_entry.h>
+
+MODULE_ID("$Id: tset.c,v 0.37 1999/03/14 12:30:02 tom Exp $")
+
+extern char **environ;
+
+#undef CTRL
+#define CTRL(x) ((x) & 0x1f)
+
+const char *_nc_progname = "tset";
+
+static TTY mode, oldmode;
+
+static int terasechar = -1; /* new erase character */
+static int intrchar = -1; /* new interrupt character */
+static int isreset; /* invoked as reset */
+static int tkillchar = -1; /* new kill character */
+static int tlines, tcolumns; /* window size */
+
+#define LOWERCASE(c) ((isalpha(c) && isupper(c)) ? tolower(c) : (c))
+
+static int
+CaselessCmp(const char *a, const char *b) /* strcasecmp isn't portable */
+{
+ while (*a && *b) {
+ int cmp = LOWERCASE(*a) - LOWERCASE(*b);
+ if (cmp != 0)
+ break;
+ a++, b++;
+ }
+ return LOWERCASE(*a) - LOWERCASE(*b);
+}
+
+#if !HAVE_STRDUP
+#define strdup _nc_strdup
+extern char *_nc_strdup(const char *);
+#endif /* not HAVE_STRDUP */
+
+static void
+err(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ (void)fprintf(stderr, "tset: ");
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ exit(EXIT_FAILURE);
+ /* NOTREACHED */
+}
+
+static void
+failed(const char *msg)
+{
+ char temp[BUFSIZ];
+ perror(strcat(strcpy(temp, "tset: "), msg));
+ exit(EXIT_FAILURE);
+ /* NOTREACHED */
+}
+
+static void
+cat(char *file)
+{
+ register int fd, nr, nw;
+ char buf[BUFSIZ];
+
+ if ((fd = open(file, O_RDONLY, 0)) < 0)
+ failed(file);
+
+ while ((nr = read(fd, buf, sizeof(buf))) > 0)
+ if ((nw = write(STDERR_FILENO, buf, (size_t)nr)) == -1)
+ failed("write to stderr");
+ if (nr != 0)
+ failed(file);
+ (void)close(fd);
+}
+
+static int
+outc(int c)
+{
+ return putc(c, stderr);
+}
+
+/* Prompt the user for a terminal type. */
+static const char *
+askuser(const char *dflt)
+{
+ static char answer[256];
+ char *p;
+
+ /* We can get recalled; if so, don't continue uselessly. */
+ if (feof(stdin) || ferror(stdin)) {
+ (void)fprintf(stderr, "\n");
+ exit(EXIT_FAILURE);
+ }
+ for (;;) {
+ if (dflt)
+ (void)fprintf(stderr, "Terminal type? [%s] ", dflt);
+ else
+ (void)fprintf(stderr, "Terminal type? ");
+ (void)fflush(stderr);
+
+ if (fgets(answer, sizeof(answer), stdin) == 0) {
+ if (dflt == 0) {
+ (void)fprintf(stderr, "\n");
+ exit(EXIT_FAILURE);
+ }
+ return (dflt);
+ }
+
+ if ((p = strchr(answer, '\n')) != 0)
+ *p = '\0';
+ if (answer[0])
+ return (answer);
+ if (dflt != 0)
+ return (dflt);
+ }
+}
+
+/**************************************************************************
+ *
+ * Mapping logic begins here
+ *
+ **************************************************************************/
+
+/* Baud rate conditionals for mapping. */
+#define GT 0x01
+#define EQ 0x02
+#define LT 0x04
+#define NOT 0x08
+#define GE (GT | EQ)
+#define LE (LT | EQ)
+
+typedef struct map {
+ struct map *next; /* Linked list of maps. */
+ const char *porttype; /* Port type, or "" for any. */
+ const char *type; /* Terminal type to select. */
+ int conditional; /* Baud rate conditionals bitmask. */
+ speed_t speed; /* Baud rate to compare against. */
+} MAP;
+
+static MAP *cur, *maplist;
+
+typedef struct speeds {
+ const char *string;
+ int speed;
+} SPEEDS;
+
+static const SPEEDS speeds[] = {
+ { "0", B0 },
+ { "50", B50 },
+ { "75", B75 },
+ { "110", B110 },
+ { "134", B134 },
+ { "134.5", B134 },
+ { "150", B150 },
+ { "200", B200 },
+ { "300", B300 },
+ { "600", B600 },
+ { "1200", B1200 },
+ { "1800", B1800 },
+ { "2400", B2400 },
+ { "4800", B4800 },
+ { "9600", B9600 },
+ { "19200", B19200 },
+ { "38400", B38400 },
+ { "19200", B19200 },
+ { "38400", B38400 },
+#ifdef B19200
+ { "19200", B19200 },
+#else
+#ifdef EXTA
+ { "19200", EXTA },
+#endif
+#endif
+#ifdef B38400
+ { "38400", B38400 },
+#else
+#ifdef EXTB
+ { "38400", EXTB },
+#endif
+#endif
+#ifdef B57600
+ { "57600", B57600 },
+#endif
+#ifdef B115200
+ { "115200", B115200 },
+#endif
+#ifdef B230400
+ { "230400", B230400 },
+#endif
+#ifdef B460800
+ { "460800", B460800 },
+#endif
+ { (char *)0, 0 }
+};
+
+static int
+tbaudrate(char *rate)
+{
+ const SPEEDS *sp;
+ int found = FALSE;
+
+ /* The baudrate number can be preceded by a 'B', which is ignored. */
+ if (*rate == 'B')
+ ++rate;
+
+ for (sp = speeds; sp->string; ++sp) {
+ if (!CaselessCmp(rate, sp->string)) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ err("unknown baud rate %s", rate);
+ return (sp->speed);
+}
+
+/*
+ * Syntax for -m:
+ * [port-type][test baudrate]:terminal-type
+ * The baud rate tests are: >, <, @, =, !
+ */
+static void
+add_mapping(const char *port, char *arg)
+{
+ MAP *mapp;
+ char *copy, *p;
+ const char *termp;
+ char *base = 0;
+
+ copy = strdup(arg);
+ mapp = malloc(sizeof(MAP));
+ if (copy == 0 || mapp == 0)
+ failed("malloc");
+ mapp->next = 0;
+ if (maplist == 0)
+ cur = maplist = mapp;
+ else {
+ cur->next = mapp;
+ cur = mapp;
+ }
+
+ mapp->porttype = arg;
+ mapp->conditional = 0;
+
+ arg = strpbrk(arg, "><@=!:");
+
+ if (arg == 0) { /* [?]term */
+ mapp->type = mapp->porttype;
+ mapp->porttype = 0;
+ goto done;
+ }
+
+ if (arg == mapp->porttype) /* [><@=! baud]:term */
+ termp = mapp->porttype = 0;
+ else
+ termp = base = arg;
+
+ for (;; ++arg) /* Optional conditionals. */
+ switch(*arg) {
+ case '<':
+ if (mapp->conditional & GT)
+ goto badmopt;
+ mapp->conditional |= LT;
+ break;
+ case '>':
+ if (mapp->conditional & LT)
+ goto badmopt;
+ mapp->conditional |= GT;
+ break;
+ case '@':
+ case '=': /* Not documented. */
+ mapp->conditional |= EQ;
+ break;
+ case '!':
+ mapp->conditional |= NOT;
+ break;
+ default:
+ goto next;
+ }
+
+next: if (*arg == ':') {
+ if (mapp->conditional)
+ goto badmopt;
+ ++arg;
+ } else { /* Optional baudrate. */
+ arg = strchr(p = arg, ':');
+ if (arg == 0)
+ goto badmopt;
+ *arg++ = '\0';
+ mapp->speed = tbaudrate(p);
+ }
+
+ if (arg == (char *)0) /* Non-optional type. */
+ goto badmopt;
+
+ mapp->type = arg;
+
+ /* Terminate porttype, if specified. */
+ if (termp != 0)
+ *base = '\0';
+
+ /* If a NOT conditional, reverse the test. */
+ if (mapp->conditional & NOT)
+ mapp->conditional = ~mapp->conditional & (EQ | GT | LT);
+
+ /* If user specified a port with an option flag, set it. */
+done: if (port) {
+ if (mapp->porttype)
+badmopt: err("illegal -m option format: %s", copy);
+ mapp->porttype = port;
+ }
+
+#ifdef MAPDEBUG
+ (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
+ (void)printf("type: %s\n", mapp->type);
+ (void)printf("conditional: ");
+ p = "";
+ if (mapp->conditional & GT) {
+ (void)printf("GT");
+ p = "/";
+ }
+ if (mapp->conditional & EQ) {
+ (void)printf("%sEQ", p);
+ p = "/";
+ }
+ if (mapp->conditional & LT)
+ (void)printf("%sLT", p);
+ (void)printf("\nspeed: %d\n", mapp->speed);
+#endif
+}
+
+/*
+ * Return the type of terminal to use for a port of type 'type', as specified
+ * by the first applicable mapping in 'map'. If no mappings apply, return
+ * 'type'.
+ */
+static const char *
+mapped(const char *type)
+{
+ MAP *mapp;
+ int match;
+
+ for (mapp = maplist; mapp; mapp = mapp->next)
+ if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) {
+ switch (mapp->conditional) {
+ case 0: /* No test specified. */
+ match = TRUE;
+ break;
+ case EQ:
+ match = (ospeed == mapp->speed);
+ break;
+ case GE:
+ match = (ospeed >= mapp->speed);
+ break;
+ case GT:
+ match = (ospeed > mapp->speed);
+ break;
+ case LE:
+ match = (ospeed <= mapp->speed);
+ break;
+ case LT:
+ match = (ospeed < mapp->speed);
+ break;
+ default:
+ match = FALSE;
+ }
+ if (match)
+ return (mapp->type);
+ }
+ /* No match found; return given type. */
+ return (type);
+}
+
+/**************************************************************************
+ *
+ * Entry fetching
+ *
+ **************************************************************************/
+
+/*
+ * Figure out what kind of terminal we're dealing with, and then read in
+ * its termcap entry.
+ */
+static const char *
+get_termcap_entry(char *userarg)
+{
+ int rval, errret;
+ char *p;
+ const char *ttype;
+#if HAVE_GETTTYNAM
+ struct ttyent *t;
+#else
+ FILE *fp;
+#endif
+ char *ttypath;
+
+ if (userarg) {
+ ttype = userarg;
+ goto found;
+ }
+
+ /* Try the environment. */
+ if ((ttype = getenv("TERM")) != 0)
+ goto map;
+
+ if ((ttypath = ttyname(STDERR_FILENO)) != 0) {
+ if ((p = strrchr(ttypath, '/')) != 0)
+ ++p;
+ else
+ p = ttypath;
+#if HAVE_GETTTYNAM
+ /*
+ * We have the 4.3BSD library call getttynam(3); that means
+ * there's an /etc/ttys to look up device-to-type mappings in.
+ * Try ttyname(3); check for dialup or other mapping.
+ */
+ if ((t = getttynam(p))) {
+ ttype = t->ty_type;
+ goto map;
+ }
+#else
+ if ((fp = fopen("/etc/ttytype", "r")) != 0
+ || (fp = fopen("/etc/ttys", "r")) != 0) {
+ char buffer[BUFSIZ];
+ char *s, *t, *d;
+
+ while (fgets(buffer, sizeof(buffer)-1, fp) != 0) {
+ for (s = buffer, t = d = 0; *s; s++) {
+ if (isspace(*s))
+ *s = '\0';
+ else if (t == 0)
+ t = s;
+ else if (d == 0 && s != buffer && s[-1] == '\0')
+ d = s;
+ }
+ if (t != 0 && d != 0 && !strcmp(d,p)) {
+ ttype = strdup(t);
+ fclose(fp);
+ goto map;
+ }
+ }
+ fclose(fp);
+ }
+#endif /* HAVE_GETTTYNAM */
+ }
+
+ /* If still undefined, use "unknown". */
+ ttype = "unknown";
+
+map: ttype = mapped(ttype);
+
+ /*
+ * If not a path, remove TERMCAP from the environment so we get a
+ * real entry from /etc/termcap. This prevents us from being fooled
+ * by out of date stuff in the environment.
+ */
+found: if ((p = getenv("TERMCAP")) != 0 && *p != '/') {
+ /* 'unsetenv("TERMCAP")' is not portable.
+ * The 'environ' array is better.
+ */
+ int n;
+ for (n = 0; environ[n] != 0; n++) {
+ if (!strncmp("TERMCAP=", environ[n], 8)) {
+ while ((environ[n] = environ[n+1]) != 0) {
+ n++;
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * ttype now contains a pointer to the type of the terminal.
+ * If the first character is '?', ask the user.
+ */
+ if (ttype[0] == '?') {
+ if (ttype[1] != '\0')
+ ttype = askuser(ttype + 1);
+ else
+ ttype = askuser(0);
+ }
+ /* Find the terminfo entry. If it doesn't exist, ask the user. */
+ while ((rval = setupterm((NCURSES_CONST char *)ttype, STDOUT_FILENO, &errret)) != OK) {
+ if (errret == 0) {
+ (void)fprintf(stderr, "tset: unknown terminal type %s\n",
+ ttype);
+ ttype = 0;
+ }
+ else {
+ (void)fprintf(stderr, "tset: can't initialize terminal type %s (error %d)\n", ttype, errret);
+ ttype = 0;
+ }
+ ttype = askuser(ttype);
+ }
+#if BROKEN_LINKER
+ tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */
+#endif
+ return (ttype);
+}
+
+/**************************************************************************
+ *
+ * Mode-setting logic
+ *
+ **************************************************************************/
+
+/* some BSD systems have these built in, some systems are missing
+ * one or more definitions. The safest solution is to override.
+ */
+#undef CEOF
+#undef CERASE
+#undef CINTR
+#undef CKILL
+#undef CLNEXT
+#undef CRPRNT
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CSUSP
+
+/* control-character defaults */
+#define CEOF CTRL('D')
+#define CERASE CTRL('H')
+#define CINTR 127 /* ^? */
+#define CKILL CTRL('U')
+#define CLNEXT CTRL('v')
+#define CRPRNT CTRL('r')
+#define CQUIT CTRL('\\')
+#define CSTART CTRL('Q')
+#define CSTOP CTRL('S')
+#define CSUSP CTRL('Z')
+
+#define CHK(val, dft) ((int)val <= 0 ? dft : val)
+
+static bool set_tabs (void);
+
+/*
+ * Reset the terminal mode bits to a sensible state. Very useful after
+ * a child program dies in raw mode.
+ */
+static void
+reset_mode(void)
+{
+#ifdef TERMIOS
+ tcgetattr(STDERR_FILENO, &mode);
+#else
+ stty(STDERR_FILENO,&mode);
+#endif
+
+#ifdef TERMIOS
+#if defined(VDISCARD) && defined(CDISCARD)
+ mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD);
+#endif
+ mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF);
+ mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE);
+#if defined(VFLUSH) && defined(CFLUSH)
+ mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH);
+#endif
+ mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR);
+ mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL);
+#if defined(VLNEXT) && defined(CLNEXT)
+ mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT);
+#endif
+ mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT);
+#if defined(VREPRINT) && defined(CRPRNT)
+ mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT);
+#endif
+#if defined(VSTART) && defined(CSTART)
+ mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART);
+#endif
+#if defined(VSTOP) && defined(CSTOP)
+ mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP);
+#endif
+#if defined(VSUSP) && defined(CSUSP)
+ mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP);
+#endif
+#if defined(VWERASE) && defined(CWERASE)
+ mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE);
+#endif
+
+ mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR
+#ifdef IUCLC
+ | IUCLC
+#endif
+#ifdef IXANY
+ | IXANY
+#endif
+ | IXOFF);
+
+ mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON
+#ifdef IMAXBEL
+ | IMAXBEL
+#endif
+ );
+
+ mode.c_oflag &= ~(0
+#ifdef OLCUC
+ | OLCUC
+#endif
+#ifdef OCRNL
+ | OCRNL
+#endif
+#ifdef ONOCR
+ | ONOCR
+#endif
+#ifdef ONLRET
+ | ONLRET
+#endif
+#ifdef OFILL
+ | OFILL
+#endif
+#ifdef OFDEL
+ | OFDEL
+#endif
+#ifdef NLDLY
+ | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY
+#endif
+ );
+
+ mode.c_oflag |= (OPOST
+#ifdef ONLCR
+ | ONLCR
+#endif
+ );
+
+ mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL);
+ mode.c_cflag |= (CS8 | CREAD);
+ mode.c_lflag &= ~(ECHONL | NOFLSH
+#ifdef TOSTOP
+ | TOSTOP
+#endif
+#ifdef ECHOPTR
+ | ECHOPRT
+#endif
+#ifdef XCASE
+ | XCASE
+#endif
+ );
+
+ mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK
+#ifdef ECHOCTL
+ | ECHOCTL
+#endif
+#ifdef ECHOKE
+ | ECHOKE
+#endif
+ );
+#endif
+
+#ifdef TERMIOS
+ tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
+#else
+ stty(STDERR_FILENO, &mode);
+#endif
+}
+
+/*
+ * Returns a "good" value for the erase character. This is loosely based on
+ * the BSD4.4 logic.
+ */
+static int
+default_erase(void)
+{
+ int result;
+
+ if (over_strike
+ && key_backspace != 0
+ && strlen(key_backspace) == 1)
+ result = key_backspace[0];
+ else
+ result = CERASE;
+
+ return result;
+}
+
+/*
+ * Update the values of the erase, interrupt, and kill characters in 'mode'.
+ *
+ * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase
+ * characters if they're unset, or if we specify them as options. This differs
+ * from BSD 4.4 tset, which always sets erase.
+ */
+static void
+set_control_chars(void)
+{
+#ifdef TERMIOS
+ if (mode.c_cc[VERASE] == 0 || terasechar >= 0)
+ mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase();
+
+ if (mode.c_cc[VINTR] == 0 || intrchar >= 0)
+ mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR;
+
+ if (mode.c_cc[VKILL] == 0 || tkillchar >= 0)
+ mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL;
+#endif
+}
+
+/*
+ * Set up various conversions in 'mode', including parity, tabs, returns,
+ * echo, and case, according to the termcap entry. If the program we're
+ * running was named with a leading upper-case character, map external
+ * uppercase to internal lowercase.
+ */
+static void
+set_conversions(void)
+{
+#ifdef __OBSOLETE__
+ /*
+ * Conversion logic for some *really* ancient terminal glitches,
+ * not supported in terminfo. Left here for succeeding generations
+ * to marvel at.
+ */
+ if (tgetflag("UC")) {
+#ifdef IUCLC
+ mode.c_iflag |= IUCLC;
+ mode.c_oflag |= OLCUC;
+#endif
+ } else if (tgetflag("LC")) {
+#ifdef IUCLC
+ mode.c_iflag &= ~IUCLC;
+ mode.c_oflag &= ~OLCUC;
+#endif
+ }
+ mode.c_iflag &= ~(PARMRK | INPCK);
+ mode.c_lflag |= ICANON;
+ if (tgetflag("EP")) {
+ mode.c_cflag |= PARENB;
+ mode.c_cflag &= ~PARODD;
+ }
+ if (tgetflag("OP")) {
+ mode.c_cflag |= PARENB;
+ mode.c_cflag |= PARODD;
+ }
+#endif /* __OBSOLETE__ */
+
+#ifdef TERMIOS
+#ifdef ONLCR
+ mode.c_oflag |= ONLCR;
+#endif
+ mode.c_iflag |= ICRNL;
+ mode.c_lflag |= ECHO;
+#ifdef OXTABS
+ mode.c_oflag |= OXTABS;
+#endif /* OXTABS */
+
+ /* test used to be tgetflag("NL") */
+ if (newline != (char *)0 && newline[0] == '\n' && !newline[1]) {
+ /* Newline, not linefeed. */
+#ifdef ONLCR
+ mode.c_oflag &= ~ONLCR;
+#endif
+ mode.c_iflag &= ~ICRNL;
+ }
+#ifdef __OBSOLETE__
+ if (tgetflag("HD")) /* Half duplex. */
+ mode.c_lflag &= ~ECHO;
+#endif /* __OBSOLETE__ */
+#ifdef OXTABS
+ /* test used to be tgetflag("pt") */
+ if (has_hardware_tabs) /* Print tabs. */
+ mode.c_oflag &= ~OXTABS;
+#endif /* OXTABS */
+ mode.c_lflag |= (ECHOE | ECHOK);
+#endif
+}
+
+/* Output startup string. */
+static void
+set_init(void)
+{
+ char *p;
+ bool settle;
+
+#ifdef __OBSOLETE__
+ if (pad_char != (char *)0) /* Get/set pad character. */
+ PC = pad_char[0];
+#endif /* OBSOLETE */
+
+#ifdef TAB3
+ if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
+ oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
+ tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode);
+ }
+#endif
+ settle = set_tabs();
+
+ if (isreset) {
+ if ((p = reset_1string) != 0) {
+ tputs(p, 0, outc);
+ settle = TRUE;
+ }
+ if ((p = reset_2string) != 0) {
+ tputs(p, 0, outc);
+ settle = TRUE;
+ }
+ /* What about rf, rs3, as per terminfo man page? */
+ /* also might be nice to send rmacs, rmul, rmm */
+ if ((p = reset_file) != 0
+ || (p = init_file) != 0) {
+ cat(p);
+ settle = TRUE;
+ }
+ }
+
+ if (settle) {
+ (void)putc('\r', stderr);
+ (void)fflush(stderr);
+ (void)napms(1000); /* Settle the terminal. */
+ }
+}
+
+/*
+ * Set the hardware tabs on the terminal, using the ct (clear all tabs),
+ * st (set one tab) and ch (horizontal cursor addressing) capabilities.
+ * This is done before if and is, so they can patch in case we blow this.
+ * Return TRUE if we set any tab stops, FALSE if not.
+ */
+static bool
+set_tabs()
+{
+ if (set_tab && clear_all_tabs) {
+ int c;
+
+ (void)putc('\r', stderr); /* Force to left margin. */
+ tputs(clear_all_tabs, 0, outc);
+
+ for (c = 8; c < tcolumns; c += 8) {
+ /* Get to the right column. In BSD tset, this
+ * used to try a bunch of half-clever things
+ * with cup and hpa, for an average saving of
+ * somewhat less than two character times per
+ * tab stop, less that .01 sec at 2400cps. We
+ * lost all this cruft because it seemed to be
+ * introducing some odd bugs.
+ * ----------12345678----------- */
+ (void)fputs(" ", stderr);
+ tputs(set_tab, 0, outc);
+ }
+ putc('\r', stderr);
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/**************************************************************************
+ *
+ * Main sequence
+ *
+ **************************************************************************/
+
+/*
+ * Tell the user if a control key has been changed from the default value.
+ */
+static void
+report(const char *name, int which, unsigned def)
+{
+#ifdef TERMIOS
+ unsigned older, newer;
+ char *p;
+
+ newer = mode.c_cc[which];
+ older = oldmode.c_cc[which];
+
+ if (older == newer && older == def)
+ return;
+
+ (void)fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
+
+ /*
+ * Check 'delete' before 'backspace', since the key_backspace value
+ * is ambiguous.
+ */
+ if (newer == 0177)
+ (void)fprintf(stderr, "delete.\n");
+ else if ((p = key_backspace) != 0
+ && newer == (unsigned char)p[0]
+ && p[1] == '\0')
+ (void)fprintf(stderr, "backspace.\n");
+ else if (newer < 040) {
+ newer ^= 0100;
+ (void)fprintf(stderr, "control-%c (^%c).\n", newer, newer);
+ } else
+ (void)fprintf(stderr, "%c.\n", newer);
+#endif
+}
+
+/*
+ * Convert the obsolete argument forms into something that getopt can handle.
+ * This means that -e, -i and -k get default arguments supplied for them.
+ */
+static void
+obsolete(char **argv)
+{
+ for (; *argv; ++argv) {
+ char *parm = argv[0];
+
+ if (parm[0] == '-' && parm[1] == '\0')
+ {
+ argv[0] = strdup("-q");
+ continue;
+ }
+
+ if ((parm[0] != '-')
+ || (argv[1] && argv[1][0] != '-')
+ || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k')
+ || (parm[2] != '\0'))
+ continue;
+ switch(argv[0][1]) {
+ case 'e':
+ argv[0] = strdup("-e^H");
+ break;
+ case 'i':
+ argv[0] = strdup("-i^C");
+ break;
+ case 'k':
+ argv[0] = strdup("-k^U");
+ break;
+ }
+ }
+}
+
+static void
+usage(const char* pname)
+{
+ (void)fprintf(stderr,
+"usage: %s [-IQrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n", pname);
+ exit(EXIT_FAILURE);
+}
+
+static char arg_to_char(void)
+{
+ return (optarg[0] == '^' && optarg[1] != '\0')
+ ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1]))
+ : optarg[0];
+}
+
+int
+main(int argc, char **argv)
+{
+#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
+ struct winsize win;
+#endif
+ int ch, noinit, noset, quiet, Sflag, sflag, showterm;
+ const char *p;
+ const char *ttype;
+
+#ifdef TERMIOS
+ if (tcgetattr(STDERR_FILENO, &mode) < 0)
+ failed("standard error");
+
+ oldmode = mode;
+ ospeed = cfgetospeed(&mode);
+#else
+ if (gtty(STDERR_FILENO, &mode) < 0)
+ failed("standard error");
+
+ oldmode = mode;
+ ospeed = mode.sg_ospeed;
+#endif
+
+ if ((p = strrchr(*argv, '/')) != 0)
+ ++p;
+ else
+ p = *argv;
+ if (!CaselessCmp(p, "reset")) {
+ isreset = 1;
+ reset_mode();
+ }
+
+ obsolete(argv);
+ noinit = noset = quiet = Sflag = sflag = showterm = 0;
+ while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrs")) != EOF) {
+ switch (ch) {
+ case 'q': /* display term only */
+ noset = 1;
+ break;
+ case 'a': /* OBSOLETE: map identifier to type */
+ add_mapping("arpanet", optarg);
+ break;
+ case 'd': /* OBSOLETE: map identifier to type */
+ add_mapping("dialup", optarg);
+ break;
+ case 'e': /* erase character */
+ terasechar = arg_to_char();
+ break;
+ case 'I': /* no initialization strings */
+ noinit = 1;
+ break;
+ case 'i': /* interrupt character */
+ intrchar = arg_to_char();
+ break;
+ case 'k': /* kill character */
+ tkillchar = arg_to_char();
+ break;
+ case 'm': /* map identifier to type */
+ add_mapping(0, optarg);
+ break;
+ case 'n': /* OBSOLETE: set new tty driver */
+ break;
+ case 'p': /* OBSOLETE: map identifier to type */
+ add_mapping("plugboard", optarg);
+ break;
+ case 'Q': /* don't output control key settings */
+ quiet = 1;
+ break;
+ case 'S': /* OBSOLETE: output TERM & TERMCAP */
+ Sflag = 1;
+ break;
+ case 'r': /* display term on stderr */
+ showterm = 1;
+ break;
+ case 's': /* output TERM set command */
+ sflag = 1;
+ break;
+ case '?':
+ default:
+ usage(*argv);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1)
+ usage(*argv);
+
+ ttype = get_termcap_entry(*argv);
+
+ if (!noset) {
+ tcolumns = columns;
+ tlines = lines;
+
+#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
+ /* Set window size */
+ (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win);
+ if (win.ws_row == 0 && win.ws_col == 0 &&
+ tlines > 0 && tcolumns > 0) {
+ win.ws_row = tlines;
+ win.ws_col = tcolumns;
+ (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win);
+ }
+#endif
+ set_control_chars();
+ set_conversions();
+
+ if (!noinit)
+ set_init();
+
+ /* Set the modes if they've changed. */
+ if (memcmp(&mode, &oldmode, sizeof(mode)))
+#ifdef TERMIOS
+ tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
+#else
+ stty(STDERR_FILENO, &mode);
+#endif
+ }
+
+ /* Get the terminal name from the entry. */
+ ttype = _nc_first_name(cur_term->type.term_names);
+
+ if (noset)
+ (void)printf("%s\n", ttype);
+ else {
+ if (showterm)
+ (void)fprintf(stderr, "Terminal type is %s.\n", ttype);
+ /*
+ * If erase, kill and interrupt characters could have been
+ * modified and not -Q, display the changes.
+ */
+ if (!quiet) {
+ report("Erase", VERASE, CERASE);
+ report("Kill", VKILL, CINTR);
+ report("Interrupt", VINTR, CKILL);
+ }
+ }
+
+ if (Sflag)
+ err("The -S option is not supported under terminfo.");
+
+ if (sflag) {
+ /*
+ * Figure out what shell we're using. A hack, we look for an
+ * environmental variable SHELL ending in "csh".
+ */
+ if ((p = getenv("SHELL")) != 0
+ && !strcmp(p + strlen(p) - 3, "csh"))
+ p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n";
+ else
+ p = "TERM=%s;\n";
+ (void) printf(p, ttype);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+/* tset.c ends here */