summaryrefslogtreecommitdiff
path: root/lib/libcurses/tinfo
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libcurses/tinfo')
-rw-r--r--lib/libcurses/tinfo/MKcaptab.awk66
-rw-r--r--lib/libcurses/tinfo/MKfallback.sh69
-rw-r--r--lib/libcurses/tinfo/MKnames.awk99
-rw-r--r--lib/libcurses/tinfo/access.c55
-rw-r--r--lib/libcurses/tinfo/add_tries.c126
-rw-r--r--lib/libcurses/tinfo/alloc_entry.c177
-rw-r--r--lib/libcurses/tinfo/captoinfo.c809
-rw-r--r--lib/libcurses/tinfo/comp_error.c134
-rw-r--r--lib/libcurses/tinfo/comp_expand.c183
-rw-r--r--lib/libcurses/tinfo/comp_hash.c334
-rw-r--r--lib/libcurses/tinfo/comp_parse.c539
-rw-r--r--lib/libcurses/tinfo/comp_scan.c756
-rw-r--r--lib/libcurses/tinfo/doalloc.c60
-rw-r--r--lib/libcurses/tinfo/getenv_num.c58
-rw-r--r--lib/libcurses/tinfo/home_terminfo.c64
-rw-r--r--lib/libcurses/tinfo/keys.list159
-rw-r--r--lib/libcurses/tinfo/lib_acs.c141
-rw-r--r--lib/libcurses/tinfo/lib_baudrate.c171
-rw-r--r--lib/libcurses/tinfo/lib_cur_term.c73
-rw-r--r--lib/libcurses/tinfo/lib_data.c86
-rw-r--r--lib/libcurses/tinfo/lib_has_cap.c65
-rw-r--r--lib/libcurses/tinfo/lib_kernel.c132
-rw-r--r--lib/libcurses/tinfo/lib_longname.c60
-rw-r--r--lib/libcurses/tinfo/lib_napms.c90
-rw-r--r--lib/libcurses/tinfo/lib_options.c291
-rw-r--r--lib/libcurses/tinfo/lib_print.c98
-rw-r--r--lib/libcurses/tinfo/lib_raw.c235
-rw-r--r--lib/libcurses/tinfo/lib_setup.c405
-rw-r--r--lib/libcurses/tinfo/lib_termcap.c194
-rw-r--r--lib/libcurses/tinfo/lib_termname.c48
-rw-r--r--lib/libcurses/tinfo/lib_ti.c97
-rw-r--r--lib/libcurses/tinfo/lib_tparm.c587
-rw-r--r--lib/libcurses/tinfo/lib_tputs.c245
-rw-r--r--lib/libcurses/tinfo/lib_ttyflags.c163
-rw-r--r--lib/libcurses/tinfo/make_keys.c136
-rw-r--r--lib/libcurses/tinfo/name_match.c87
-rw-r--r--lib/libcurses/tinfo/parse_entry.c924
-rw-r--r--lib/libcurses/tinfo/read_bsd_terminfo.c140
-rw-r--r--lib/libcurses/tinfo/read_entry.c362
-rw-r--r--lib/libcurses/tinfo/read_termcap.c1122
-rw-r--r--lib/libcurses/tinfo/setbuf.c137
-rw-r--r--lib/libcurses/tinfo/write_entry.c469
42 files changed, 10246 insertions, 0 deletions
diff --git a/lib/libcurses/tinfo/MKcaptab.awk b/lib/libcurses/tinfo/MKcaptab.awk
new file mode 100644
index 00000000000..2ea3236af3b
--- /dev/null
+++ b/lib/libcurses/tinfo/MKcaptab.awk
@@ -0,0 +1,66 @@
+#!/bin/sh
+# $OpenBSD: MKcaptab.awk,v 1.1 1999/01/18 19:10:12 millert Exp $
+# $From: MKcaptab.awk,v 1.10 1997/09/11 17:40:46 tom Exp $
+AWK=${1-awk}
+DATA=${2-../include/Caps}
+
+cat <<'EOF'
+/*
+ * comp_captab.c -- The names of the capabilities indexed via a hash
+ * table for the compiler.
+ *
+ */
+
+#include <ncurses_cfg.h>
+#include <tic.h>
+#include <term.h>
+
+EOF
+
+./make_hash 1 info <$DATA
+./make_hash 3 cap <$DATA
+
+cat <<'EOF'
+const struct alias _nc_capalias_table[] =
+{
+EOF
+
+$AWK <$DATA '
+$1 == "capalias" {
+ if ($3 == "IGNORE")
+ to = "(char *)NULL";
+ else
+ to = "\"" $3 "\"";
+ printf "\t{\"%s\", %s, \"%s\"},\t /* %s */\n",
+ $2, to, $4, $5
+ }
+'
+
+cat <<'EOF'
+ {(char *)NULL, (char *)NULL, (char *)NULL}
+};
+
+const struct alias _nc_infoalias_table[] =
+{
+EOF
+
+$AWK <$DATA '
+$1 == "infoalias" {
+ if ($3 == "IGNORE")
+ to = "(char *)NULL";
+ else
+ to = "\"" $3 "\"";
+ printf "\t{\"%s\", %s, \"%s\"},\t /* %s */\n",
+ $2, to, $4, $5
+ }
+'
+
+cat <<'EOF'
+ {(char *)NULL, (char *)NULL, (char *)NULL}
+};
+
+const struct name_table_entry *_nc_get_table(bool termcap)
+{
+ return termcap ? _nc_cap_table: _nc_info_table ;
+}
+EOF
diff --git a/lib/libcurses/tinfo/MKfallback.sh b/lib/libcurses/tinfo/MKfallback.sh
new file mode 100644
index 00000000000..d6631b2ca8a
--- /dev/null
+++ b/lib/libcurses/tinfo/MKfallback.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+# $OpenBSD: MKfallback.sh,v 1.1 1999/01/18 19:10:12 millert Exp $
+# $From: MKfallback.sh,v 1.8 1996/09/15 01:44:13 tom Exp $
+#
+# MKfallback.sh -- create fallback table for entry reads
+#
+# This script generates source code for a custom version of read_entry.c
+# that (instead of reading capabilities for an argument terminal type
+# from an on-disk terminfo tree) tries to match the type with one of a
+# specified list of types generated in.
+#
+cat <<EOF
+/*
+ * DO NOT EDIT THIS FILE BY HAND! It is generated by MKfallback.sh.
+ */
+
+#include <curses.priv.h>
+#include <term.h>
+
+EOF
+
+if [ "$*" ]
+then
+ cat <<EOF
+#include <tic.h>
+
+/* fallback entries for: $* */
+
+static const TERMTYPE fallbacks[$#] =
+{
+EOF
+ comma=""
+ for x in $*
+ do
+ echo "$comma /* $x */"
+ infocmp -e $x
+ comma=","
+ done
+
+ cat <<EOF
+};
+
+EOF
+fi
+
+cat <<EOF
+const TERMTYPE *_nc_fallback(const char *name GCC_UNUSED)
+{
+EOF
+
+if [ "$*" ]
+then
+ cat <<EOF
+ const TERMTYPE *tp;
+
+ for (tp = fallbacks;
+ tp < fallbacks + sizeof(fallbacks)/sizeof(TERMTYPE);
+ tp++)
+ if (_nc_name_match(tp->term_names, name, "|"))
+ return(tp);
+EOF
+else
+ echo " /* the fallback list is empty */";
+fi
+
+cat <<EOF
+ return((TERMTYPE *)0);
+}
+EOF
diff --git a/lib/libcurses/tinfo/MKnames.awk b/lib/libcurses/tinfo/MKnames.awk
new file mode 100644
index 00000000000..7f49c21b9f5
--- /dev/null
+++ b/lib/libcurses/tinfo/MKnames.awk
@@ -0,0 +1,99 @@
+# $OpenBSD
+# $From: MKnames.awk,v 1.10 1999/01/16 23:36:34 tom Exp $
+BEGIN {
+ print "/* This file was generated by MKnames.awk */" > "namehdr"
+ print "" > "namehdr"
+ print "#include <curses.priv.h>" > "namehdr"
+ print "" > "namehdr"
+ print "#define IT NCURSES_CONST char * const" > "namehdr"
+ print "" > "namehdr"
+ print "#if BROKEN_LINKER" > "namehdr"
+ print "#include <term.h>" > "namehdr"
+ print "#define DCL(it) static IT data##it[]" > "namehdr"
+ print "#else" > "namehdr"
+ print "#define DCL(it) IT it[]" > "namehdr"
+ print "#endif" > "namehdr"
+ print "" > "namehdr"
+ print "/*" > "boolnames"
+ print " * names.c - Arrays of capability names and codes" > "boolnames"
+ print " *" > "boolnames"
+ print " */" > "boolnames"
+ print "" > "boolnames"
+ print "DCL(boolnames) = {" > "boolnames"
+ print "DCL(boolfnames) = {" > "boolfnames"
+ print "DCL(boolcodes) = {" > "boolcodes"
+ print "DCL(numnames) = {" > "numnames"
+ print "DCL(numfnames) = {" > "numfnames"
+ print "DCL(numcodes) = {" > "numcodes"
+ print "DCL(strnames) = {" > "strnames"
+ print "DCL(strfnames) = {" > "strfnames"
+ print "DCL(strcodes) = {" > "strcodes"
+ }
+
+$1 ~ /^#/ {next;}
+
+$1 == "SKIPWARN" {next;}
+
+$3 == "bool" {
+ printf "\t\t\"%s\",\n", $2 > "boolnames"
+ printf "\t\t\"%s\",\n", $1 > "boolfnames"
+ printf "\t\t\"%s\",\n", $4 > "boolcodes"
+ }
+
+$3 == "num" {
+ printf "\t\t\"%s\",\n", $2 > "numnames"
+ printf "\t\t\"%s\",\n", $1 > "numfnames"
+ printf "\t\t\"%s\",\n", $4 > "numcodes"
+ }
+
+$3 == "str" {
+ printf "\t\t\"%s\",\n", $2 > "strnames"
+ printf "\t\t\"%s\",\n", $1 > "strfnames"
+ printf "\t\t\"%s\",\n", $4 > "strcodes"
+ }
+
+END {
+ print "\t\t(NCURSES_CONST char *)0," > "boolnames"
+ print "};" > "boolnames"
+ print "" > "boolnames"
+ print "\t\t(NCURSES_CONST char *)0," > "boolfnames"
+ print "};" > "boolfnames"
+ print "" > "boolfnames"
+ print "\t\t(NCURSES_CONST char *)0," > "boolcodes"
+ print "};" > "boolcodes"
+ print "" > "boolcodes"
+ print "\t\t(NCURSES_CONST char *)0," > "numnames"
+ print "};" > "numnames"
+ print "" > "numnames"
+ print "\t\t(NCURSES_CONST char *)0," > "numfnames"
+ print "};" > "numfnames"
+ print "" > "numfnames"
+ print "\t\t(NCURSES_CONST char *)0," > "numcodes"
+ print "};" > "numcodes"
+ print "" > "numcodes"
+ print "\t\t(NCURSES_CONST char *)0," > "strnames"
+ print "};" > "strnames"
+ print "" > "strnames"
+ print "\t\t(NCURSES_CONST char *)0," > "strfnames"
+ print "};" > "strfnames"
+ print "" > "strfnames"
+ print "\t\t(NCURSES_CONST char *)0," > "strcodes"
+ print "};" > "strcodes"
+ print "" > "strcodes"
+ print "#if BROKEN_LINKER" > "nameftr"
+ print "#define FIX(it) IT *_nc_##it(void) { return data##it; }" > "nameftr"
+ print "FIX(boolnames)" > "nameftr"
+ print "FIX(boolfnames)" > "nameftr"
+ print "FIX(numnames)" > "nameftr"
+ print "FIX(numfnames)" > "nameftr"
+ print "FIX(strnames)" > "nameftr"
+ print "FIX(strfnames)" > "nameftr"
+ print "#endif /* BROKEN_LINKER */" > "nameftr"
+ print "" > "codeftr"
+ print "#if BROKEN_LINKER" > "codeftr"
+ print "#define FIX(it) IT *_nc_##it(void) { return data##it; }" > "codeftr"
+ print "FIX(boolcodes)" > "codeftr"
+ print "FIX(numcodes)" > "codeftr"
+ print "FIX(strcodes)" > "codeftr"
+ print "#endif /* BROKEN_LINKER */" > "codeftr"
+ }
diff --git a/lib/libcurses/tinfo/access.c b/lib/libcurses/tinfo/access.c
new file mode 100644
index 00000000000..20ae2ed4773
--- /dev/null
+++ b/lib/libcurses/tinfo/access.c
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * 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> 1998 *
+ ****************************************************************************/
+
+
+#include <curses.priv.h>
+
+MODULE_ID("$From: access.c,v 1.1 1998/07/25 20:17:09 tom Exp $")
+
+int _nc_access(const char *path, int mode)
+{
+ if (access(path, mode) < 0) {
+ if ((mode & W_OK) != 0
+ && errno == ENOENT) {
+ char head[PATH_MAX];
+ char *leaf = strrchr(strcpy(head, path), '/');
+ if (leaf == 0)
+ leaf = head;
+ *leaf = '\0';
+ if (head == leaf)
+ (void)strcpy(head, ".");
+ return access(head, R_OK|W_OK|X_OK);
+ }
+ return -1;
+ }
+ return 0;
+}
diff --git a/lib/libcurses/tinfo/add_tries.c b/lib/libcurses/tinfo/add_tries.c
new file mode 100644
index 00000000000..31a6e6906ec
--- /dev/null
+++ b/lib/libcurses/tinfo/add_tries.c
@@ -0,0 +1,126 @@
+/* $OpenBSD: add_tries.c,v 1.1 1999/01/18 19:10:12 millert 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> 1998 *
+ ****************************************************************************/
+
+/*
+** add_tries.c
+**
+** Add keycode/string to tries-tree.
+**
+*/
+
+#include <curses.priv.h>
+
+MODULE_ID("$From: add_tries.c,v 1.1 1998/11/08 00:04:18 tom Exp $")
+
+#define SET_TRY(dst,src) if ((dst->ch = *src++) == 128) dst->ch = '\0'
+#define CMP_TRY(a,b) ((a)? (a == b) : (b == 128))
+
+void _nc_add_to_try(struct tries **tree, char *str, unsigned short code)
+{
+ static bool out_of_memory = FALSE;
+ struct tries *ptr, *savedptr;
+ unsigned char *txt = (unsigned char *)str;
+
+ if (txt == 0 || *txt == '\0' || out_of_memory || code == 0)
+ return;
+
+ if ((*tree) != 0) {
+ ptr = savedptr = (*tree);
+
+ for (;;) {
+ unsigned char cmp = *txt;
+
+ while (!CMP_TRY(ptr->ch, cmp)
+ && ptr->sibling != 0)
+ ptr = ptr->sibling;
+
+ if (CMP_TRY(ptr->ch, cmp)) {
+ if (*(++txt) == '\0') {
+ ptr->value = code;
+ return;
+ }
+ if (ptr->child != 0)
+ ptr = ptr->child;
+ else
+ break;
+ } else {
+ if ((ptr->sibling = typeCalloc(struct tries,1)) == 0) {
+ out_of_memory = TRUE;
+ return;
+ }
+
+ savedptr = ptr = ptr->sibling;
+ SET_TRY(ptr,txt);
+ ptr->value = 0;
+
+ break;
+ }
+ } /* end for (;;) */
+ } else { /* (*tree) == 0 :: First sequence to be added */
+ savedptr = ptr = (*tree) = typeCalloc(struct tries,1);
+
+ if (ptr == 0) {
+ out_of_memory = TRUE;
+ return;
+ }
+
+ SET_TRY(ptr,txt);
+ ptr->value = 0;
+ }
+
+ /* at this point, we are adding to the try. ptr->child == 0 */
+
+ while (*txt) {
+ ptr->child = typeCalloc(struct tries,1);
+
+ ptr = ptr->child;
+
+ if (ptr == 0) {
+ out_of_memory = TRUE;
+
+ while ((ptr = savedptr) != 0) {
+ savedptr = ptr->child;
+ free(ptr);
+ }
+
+ return;
+ }
+
+ SET_TRY(ptr,txt);
+ ptr->value = 0;
+ }
+
+ ptr->value = code;
+ return;
+}
diff --git a/lib/libcurses/tinfo/alloc_entry.c b/lib/libcurses/tinfo/alloc_entry.c
new file mode 100644
index 00000000000..49bb255f9a6
--- /dev/null
+++ b/lib/libcurses/tinfo/alloc_entry.c
@@ -0,0 +1,177 @@
+/* $OpenBSD: alloc_entry.c,v 1.1 1999/01/18 19:10:13 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * alloc_entry.c -- allocation functions for terminfo entries
+ *
+ * _nc_init_entry()
+ * _nc_save_str()
+ * _nc_merge_entry();
+ * _nc_wrap_entry();
+ *
+ */
+
+#include <curses.priv.h>
+
+#include <tic.h>
+#include <term.h>
+#include <term_entry.h>
+
+MODULE_ID("$From: alloc_entry.c,v 1.14 1998/07/04 23:17:42 tom Exp $")
+
+#define ABSENT_OFFSET -1
+#define CANCELLED_OFFSET -2
+
+#define MAX_STRTAB 4096 /* documented maximum entry size */
+
+static char stringbuf[MAX_STRTAB]; /* buffer for string capabilities */
+static size_t next_free; /* next free character in stringbuf */
+
+void _nc_init_entry(TERMTYPE *const tp)
+/* initialize a terminal type data block */
+{
+int i;
+
+ for (i=0; i < BOOLCOUNT; i++)
+ tp->Booleans[i] = FALSE; /* FIXME: why not ABSENT_BOOLEAN? */
+
+ for (i=0; i < NUMCOUNT; i++)
+ tp->Numbers[i] = ABSENT_NUMERIC;
+
+ for (i=0; i < STRCOUNT; i++)
+ tp->Strings[i] = ABSENT_STRING;
+
+ next_free = 0;
+}
+
+char *_nc_save_str(const char *const string)
+/* save a copy of string in the string buffer */
+{
+size_t old_next_free = next_free;
+size_t len = strlen(string) + 1;
+
+ if (next_free + len < MAX_STRTAB)
+ {
+ strcpy(&stringbuf[next_free], string);
+ DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
+ DEBUG(7, ("at location %d", (int) next_free));
+ next_free += len;
+ }
+ return(stringbuf + old_next_free);
+}
+
+void _nc_wrap_entry(ENTRY *const ep)
+/* copy the string parts to allocated storage, preserving pointers to it */
+{
+int offsets[STRCOUNT], useoffsets[MAX_USES];
+int i, n;
+
+ n = ep->tterm.term_names - stringbuf;
+ for (i=0; i < STRCOUNT; i++)
+ if (ep->tterm.Strings[i] == ABSENT_STRING)
+ offsets[i] = ABSENT_OFFSET;
+ else if (ep->tterm.Strings[i] == CANCELLED_STRING)
+ offsets[i] = CANCELLED_OFFSET;
+ else
+ offsets[i] = ep->tterm.Strings[i] - stringbuf;
+
+ for (i=0; i < ep->nuses; i++)
+ if (ep->uses[i].parent == (void *)0)
+ useoffsets[i] = ABSENT_OFFSET;
+ else
+ useoffsets[i] = (char *)(ep->uses[i].parent) - stringbuf;
+
+ if ((ep->tterm.str_table = (char *)malloc(next_free)) == (char *)0)
+ _nc_err_abort("Out of memory");
+ (void) memcpy(ep->tterm.str_table, stringbuf, next_free);
+
+ ep->tterm.term_names = ep->tterm.str_table + n;
+ for (i=0; i < STRCOUNT; i++)
+ if (offsets[i] == ABSENT_OFFSET)
+ ep->tterm.Strings[i] = ABSENT_STRING;
+ else if (offsets[i] == CANCELLED_OFFSET)
+ ep->tterm.Strings[i] = CANCELLED_STRING;
+ else
+ ep->tterm.Strings[i] = ep->tterm.str_table + offsets[i];
+
+ for (i=0; i < ep->nuses; i++)
+ if (useoffsets[i] == ABSENT_OFFSET)
+ ep->uses[i].parent = (void *)0;
+ else
+ ep->uses[i].parent = (char *)(ep->tterm.str_table + useoffsets[i]);
+}
+
+void _nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
+/* merge capabilities from `from' entry into `to' entry */
+{
+ int i;
+
+ for (i=0; i < BOOLCOUNT; i++)
+ {
+ int mergebool = from->Booleans[i];
+
+ if (mergebool == CANCELLED_BOOLEAN)
+ to->Booleans[i] = FALSE;
+ else if (mergebool == TRUE)
+ to->Booleans[i] = mergebool;
+ }
+
+ for (i=0; i < NUMCOUNT; i++)
+ {
+ int mergenum = from->Numbers[i];
+
+ if (mergenum == CANCELLED_NUMERIC)
+ to->Numbers[i] = ABSENT_NUMERIC;
+ else if (mergenum != ABSENT_NUMERIC)
+ to->Numbers[i] = mergenum;
+ }
+
+ /*
+ * Note: the copies of strings this makes don't have their own
+ * storage. This is OK right now, but will be a problem if we
+ * we ever want to deallocate entries.
+ */
+ for (i=0; i < STRCOUNT; i++)
+ {
+ char *mergestring = from->Strings[i];
+
+ if (mergestring == CANCELLED_STRING)
+ to->Strings[i] = ABSENT_STRING;
+ else if (mergestring != ABSENT_STRING)
+ to->Strings[i] = mergestring;
+ }
+}
+
diff --git a/lib/libcurses/tinfo/captoinfo.c b/lib/libcurses/tinfo/captoinfo.c
new file mode 100644
index 00000000000..dcdc4c4ca62
--- /dev/null
+++ b/lib/libcurses/tinfo/captoinfo.c
@@ -0,0 +1,809 @@
+/* $OpenBSD: captoinfo.c,v 1.1 1999/01/18 19:10:13 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+
+/*
+ * captoinfo.c --- conversion between termcap and terminfo formats
+ *
+ * The captoinfo() code was swiped from Ross Ridge's mytinfo package,
+ * adapted to fit ncurses by Eric S. Raymond <esr@snark.thyrsus.com>.
+ *
+ * There is just one entry point:
+ *
+ * char *captoinfo(n, s, parametrized)
+ *
+ * Convert value s for termcap string capability named n into terminfo
+ * format.
+ *
+ * This code recognizes all the standard 4.4BSD %-escapes:
+ *
+ * %% output `%'
+ * %d output value as in printf %d
+ * %2 output value as in printf %2d
+ * %3 output value as in printf %3d
+ * %. output value as in printf %c
+ * %+x add x to value, then do %.
+ * %>xy if value > x then add y, no output
+ * %r reverse order of two parameters, no output
+ * %i increment by one, no output
+ * %n exclusive-or all parameters with 0140 (Datamedia 2500)
+ * %B BCD (16*(value/10)) + (value%10), no output
+ * %D Reverse coding (value - 2*(value%16)), no output (Delta Data).
+ *
+ * Also, %02 and %03 are accepted as synonyms for %2 and %3.
+ *
+ * Besides all the standard termcap escapes, this translator understands
+ * the following extended escapes:
+ *
+ * used by GNU Emacs termcap libraries
+ * %a[+*-/=][cp]x GNU arithmetic.
+ * %m xor the first two parameters by 0177
+ * %b backup to previous parameter
+ * %f skip this parameter
+ *
+ * used by the University of Waterloo (MFCF) termcap libraries
+ * %-x subtract parameter FROM char x and output it as a char
+ * %ax add the character x to parameter
+ *
+ * If #define WATERLOO is on, also enable these translations:
+ *
+ * %sx subtract parameter FROM the character x
+ *
+ * By default, this Waterloo translations are not compiled in, because
+ * the Waterloo %s conflicts with the way terminfo uses %s in strings for
+ * function programming.
+ *
+ * Note the two definitions of %a: the GNU definition is translated if the
+ * characters after the 'a' are valid for it, otherwise the UW definition
+ * is translated.
+ */
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+#include <tic.h>
+
+MODULE_ID("$From: captoinfo.c,v 1.21 1998/05/30 23:32:15 Todd.Miller Exp $")
+
+#define MAX_PUSHED 16 /* max # args we can push onto the stack */
+#define MAX_ENTRY 2048 /* maximum chars in a translated capability */
+
+static int stack[MAX_PUSHED]; /* the stack */
+static int stackptr; /* the next empty place on the stack */
+static int onstack; /* the top of stack */
+static int seenm; /* seen a %m */
+static int seenn; /* seen a %n */
+static int seenr; /* seen a %r */
+static int param; /* current parameter */
+static char *dp; /* pointer to end of the converted string */
+
+static char *my_string;
+static size_t my_length;
+
+static char *init_string(void)
+/* initialize 'my_string', 'my_length' */
+{
+ if (my_string == 0)
+ my_string = malloc(my_length = 256);
+ if (my_string == 0)
+ _nc_err_abort("Out of memory");
+
+ *my_string = '\0';
+ return my_string;
+}
+
+static char *save_string(char *d, const char *const s)
+{
+ size_t have = (d - my_string);
+ size_t need = have + strlen(s) + 2;
+ if (need > my_length) {
+ my_string = realloc(my_string, my_length = (need + need));
+ if (my_string == 0)
+ _nc_err_abort("Out of memory");
+ d = my_string + have;
+ }
+ (void) strcpy(d, s);
+ return d + strlen(d);
+}
+
+static inline char *save_char(char *s, char c)
+{
+ static char temp[2];
+ temp[0] = c;
+ return save_string(s, temp);
+}
+
+static void push(void)
+/* push onstack on to the stack */
+{
+ if (stackptr > MAX_PUSHED)
+ _nc_warning("string too complex to convert");
+ else
+ stack[stackptr++] = onstack;
+}
+
+static void pop(void)
+/* pop the top of the stack into onstack */
+{
+ if (stackptr == 0) {
+ if (onstack == 0)
+ _nc_warning("I'm confused");
+ else
+ onstack = 0;
+ }
+ else
+ onstack = stack[--stackptr];
+ param++;
+}
+
+static int cvtchar(register const char *sp)
+/* convert a character to a terminfo push */
+{
+ unsigned char c = 0;
+ int len;
+
+ switch(*sp) {
+ case '\\':
+ switch(*++sp) {
+ case '\'':
+ case '$':
+ case '\\':
+ case '%':
+ c = *sp;
+ len = 2;
+ break;
+ case '\0':
+ c = '\\';
+ len = 1;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ len = 1;
+ while (isdigit(*sp))
+ {
+ c = 8 * c + (*sp++ - '0');
+ len++;
+ }
+ break;
+ default:
+ c = *sp;
+ len = 2;
+ break;
+ }
+ break;
+ case '^':
+ c = (*++sp & 0x1f);
+ len = 2;
+ break;
+ default:
+ c = *sp;
+ len = 1;
+ }
+ if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') {
+ *dp++ = '%'; *dp++ = '\''; *dp++ = c; *dp++ = '\'';
+ } else {
+ *dp++ = '%'; *dp++ = '{';
+ if (c > 99)
+ *dp++ = c / 100 + '0';
+ if (c > 9)
+ *dp++ = ((int)(c / 10)) % 10 + '0';
+ *dp++ = c % 10 + '0';
+ *dp++ = '}';
+ }
+ return len;
+}
+
+static void getparm(int parm, int n)
+/* push n copies of param on the terminfo stack if not already there */
+{
+ if (seenr) {
+ if (parm == 1)
+ parm = 2;
+ else if (parm == 2)
+ parm = 1;
+ }
+ if (onstack == parm) {
+ if (n > 1) {
+ _nc_warning("string may not be optimal");
+ *dp++ = '%'; *dp++ = 'P'; *dp++ = 'a';
+ while(n--) {
+ *dp++ = '%'; *dp++ = 'g'; *dp++ = 'a';
+ }
+ }
+ return;
+ }
+ if (onstack != 0)
+ push();
+
+ onstack = parm;
+
+ while(n--) { /* %p0 */
+ *dp++ = '%'; *dp++ = 'p'; *dp++ = '0' + parm;
+ }
+
+ if (seenn && parm < 3) { /* %{96}%^ */
+ *dp++ = '%'; *dp++ = '{'; *dp++ = '9'; *dp++ = '6'; *dp++ = '}';
+ *dp++ = '%'; *dp++ = '^';
+ }
+
+ if (seenm && parm < 3) { /* %{127}%^ */
+ *dp++ = '%'; *dp++ = '{'; *dp++ = '1'; *dp++ = '2'; *dp++ = '7';
+ *dp++ = '}'; *dp++ = '%'; *dp++ = '^';
+ }
+}
+
+char *_nc_captoinfo(
+/* convert a termcap string to terminfo format */
+register const char *cap, /* relevant terminfo capability index */
+register const char *s, /* string value of the capability */
+int const parametrized) /* do % translations if 1, pad translations if >=0 */
+{
+ static char line[MAX_ENTRY];
+ const char *capstart;
+
+ stackptr = 0;
+ onstack = 0;
+ seenm = 0;
+ seenn = 0;
+ seenr = 0;
+ param = 1;
+
+ dp = line;
+
+ /* skip the initial padding (if we haven't been told not to) */
+ capstart = 0;
+ if (s == 0)
+ s = "";
+ if (parametrized >= 0 && isdigit(*s))
+ for (capstart = s; ; s++)
+ if (!(isdigit(*s) || *s == '*' || *s == '.'))
+ break;
+
+ while(*s != '\0') {
+ switch(*s) {
+ case '%':
+ s++;
+ if (parametrized < 1) {
+ *dp++ = '%';
+ break;
+ }
+ switch(*s++) {
+ case '%': *dp++ = '%'; break;
+ case 'r':
+ if (seenr++ == 1) {
+ _nc_warning("saw %%r twice in %s", cap);
+ }
+ break;
+ case 'm':
+ if (seenm++ == 1) {
+ _nc_warning("saw %%m twice in %s", cap);
+ }
+ break;
+ case 'n':
+ if (seenn++ == 1) {
+ _nc_warning("saw %%n twice in %s", cap);
+ }
+ break;
+ case 'i': *dp++ = '%'; *dp++ = 'i'; break;
+ case '6':
+ case 'B':
+ getparm(param, 2);
+ /* %{6}%*%+ */
+ *dp++ = '%'; *dp++ = '{'; *dp++ = '6';
+ *dp++ = '}'; *dp++ = '%'; *dp++ = '*';
+ *dp++ = '%'; *dp++ = '+';
+ break;
+ case '8':
+ case 'D':
+ getparm(param, 2);
+ /* %{2}%*%- */
+ *dp++ = '%'; *dp++ = '{'; *dp++ = '2';
+ *dp++ = '}'; *dp++ = '%'; *dp++ = '*';
+ *dp++ = '%'; *dp++ = '-';
+ break;
+ case '>':
+ getparm(param, 2);
+ /* %?%{x}%>%t%{y}%+%; */
+ *dp++ = '%'; *dp++ = '?';
+ s += cvtchar(s);
+ *dp++ = '%'; *dp++ = '>';
+ *dp++ = '%'; *dp++ = 't';
+ s += cvtchar(s);
+ *dp++ = '%'; *dp++ = '+';
+ *dp++ = '%'; *dp++ = ';';
+ break;
+ case 'a':
+ if ((*s == '=' || *s == '+' || *s == '-'
+ || *s == '*' || *s == '/')
+ && (s[1] == 'p' || s[1] == 'c')
+ && s[2] != '\0') {
+ int l;
+ l = 2;
+ if (*s != '=')
+ getparm(param, 1);
+ if (s[1] == 'p') {
+ getparm(param + s[2] - '@', 1);
+ if (param != onstack) {
+ pop();
+ param--;
+ }
+ l++;
+ } else
+ l += cvtchar(s + 2);
+ switch(*s) {
+ case '+':
+ *dp++ = '%'; *dp++ = '+';
+ break;
+ case '-':
+ *dp++ = '%'; *dp++ = '-';
+ break;
+ case '*':
+ *dp++ = '%'; *dp++ = '*';
+ break;
+ case '/':
+ *dp++ = '%'; *dp++ = '/';
+ break;
+ case '=':
+ if (seenr) {
+ if (param == 1)
+ onstack = 2;
+ else if (param == 2)
+ onstack = 1;
+ else
+ onstack = param;
+ }
+ else
+ onstack = param;
+ break;
+ }
+ s += l;
+ break;
+ }
+ getparm(param, 1);
+ s += cvtchar(s);
+ *dp++ = '%'; *dp++ = '+';
+ break;
+ case '+':
+ getparm(param, 1);
+ s += cvtchar(s);
+ *dp++ = '%'; *dp++ = '+';
+ *dp++ = '%'; *dp++ = 'c';
+ pop();
+ break;
+ case 's':
+#ifdef WATERLOO
+ s += cvtchar(s);
+ getparm(param, 1);
+ *dp++ = '%'; *dp++ = '-';
+#else
+ getparm(param, 1);
+ *dp++ = '%'; *dp++ = 's';
+ pop();
+#endif /* WATERLOO */
+ break;
+ case '-':
+ s += cvtchar(s);
+ getparm(param, 1);
+ *dp++ = '%'; *dp++ = '-';
+ *dp++ = '%'; *dp++ = 'c';
+ pop();
+ break;
+ case '.':
+ getparm(param, 1);
+ *dp++ = '%'; *dp++ = 'c';
+ pop();
+ break;
+ case '0': /* not clear any of the historical termcaps did this */
+ if (*s == '3')
+ goto see03;
+ else if (*s != '2')
+ goto invalid;
+ /* FALLTHRU */
+ case '2':
+ getparm(param, 1);
+ *dp++ = '%'; /* *dp++ = '0'; */
+ *dp++ = '2'; *dp++ = 'd';
+ pop();
+ break;
+ case '3': see03:
+ getparm(param, 1);
+ *dp++ = '%'; /* *dp++ = '0'; */
+ *dp++ = '3'; *dp++ = 'd';
+ pop();
+ break;
+ case 'd':
+ getparm(param, 1);
+ *dp++ = '%'; *dp++ = 'd';
+ pop();
+ break;
+ case 'f':
+ param++;
+ break;
+ case 'b':
+ param--;
+ break;
+ case '\\':
+ *dp++ = '%';
+ *dp++ = '\\';
+ break;
+ default: invalid:
+ *dp++ = '%';
+ s--;
+ _nc_warning("unknown %% code %s in %s",
+ _tracechar(*s), cap);
+ break;
+ }
+ break;
+#ifdef REVISIBILIZE
+ case '\\':
+ *dp++ = *s++; *dp++ = *s++; break;
+ case '\n':
+ *dp++ = '\\'; *dp++ = 'n'; s++; break;
+ case '\t':
+ *dp++ = '\\'; *dp++ = 't'; s++; break;
+ case '\r':
+ *dp++ = '\\'; *dp++ = 'r'; s++; break;
+ case '\200':
+ *dp++ = '\\'; *dp++ = '0'; s++; break;
+ case '\f':
+ *dp++ = '\\'; *dp++ = 'f'; s++; break;
+ case '\b':
+ *dp++ = '\\'; *dp++ = 'b'; s++; break;
+ case ' ':
+ *dp++ = '\\'; *dp++ = 's'; s++; break;
+ case '^':
+ *dp++ = '\\'; *dp++ = '^'; s++; break;
+ case ':':
+ *dp++ = '\\'; *dp++ = ':'; s++; break;
+ case ',':
+ *dp++ = '\\'; *dp++ = ','; s++; break;
+ default:
+ if (*s == '\033') {
+ *dp++ = '\\';
+ *dp++ = 'E';
+ s++;
+ } else if (*s > 0 && *s < 32) {
+ *dp++ = '^';
+ *dp++ = *s + '@';
+ s++;
+ } else if (*s <= 0 || *s >= 127) {
+ *dp++ = '\\';
+ *dp++ = ((*s & 0300) >> 6) + '0';
+ *dp++ = ((*s & 0070) >> 3) + '0';
+ *dp++ = (*s & 0007) + '0';
+ s++;
+ } else
+ *dp++ = *s++;
+ break;
+#else
+ default:
+ *dp++ = *s++;
+ break;
+#endif
+ }
+ }
+
+ /*
+ * Now, if we stripped off some leading padding, add it at the end
+ * of the string as mandatory padding.
+ */
+ if (capstart)
+ {
+ *dp++ = '$';
+ *dp++ = '<';
+ for (s = capstart; ; s++)
+ if (isdigit(*s) || *s == '*' || *s == '.')
+ *dp++ = *s;
+ else
+ break;
+ *dp++ = '/';
+ *dp++ = '>';
+ }
+
+ *dp = '\0';
+ return(line);
+}
+
+/*
+ * Here are the capabilities infotocap assumes it can translate to:
+ *
+ * %% output `%'
+ * %d output value as in printf %d
+ * %2 output value as in printf %2d
+ * %3 output value as in printf %3d
+ * %. output value as in printf %c
+ * %+c add character c to value, then do %.
+ * %>xy if value > x then add y, no output
+ * %r reverse order of two parameters, no output
+ * %i increment by one, no output
+ * %n exclusive-or all parameters with 0140 (Datamedia 2500)
+ * %B BCD (16*(value/10)) + (value%10), no output
+ * %D Reverse coding (value - 2*(value%16)), no output (Delta Data).
+ * %m exclusive-or all parameters with 0177 (not in 4.4BSD)
+ */
+
+char *_nc_infotocap(
+/* convert a terminfo string to termcap format */
+register const char *cap GCC_UNUSED, /* relevant termcap capability index */
+register const char *str, /* string value of the capability */
+int const parametrized) /* do % translations if 1, pad translations if >=0 */
+{
+ int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0;
+ const char *padding;
+ const char *trimmed = 0;
+ char ch1 = 0, ch2 = 0;
+ char *bufptr = init_string();
+ char temp[256];
+
+ /* we may have to move some trailing mandatory padding up front */
+ padding = str + strlen(str) - 1;
+ if (*padding == '>' && *--padding == '/')
+ {
+ --padding;
+ while (isdigit(*padding) || *padding == '.' || *padding == '*')
+ padding--;
+ if (*padding == '<' && *--padding == '$')
+ trimmed = padding;
+ padding += 2;
+
+ while (isdigit(*padding) || *padding == '.' || *padding == '*')
+ bufptr = save_char(bufptr, *padding++);
+ }
+
+ for (; *str && str != trimmed; str++)
+ {
+ int c1, c2;
+ char *cp;
+
+ if (str[0] == '\\' && (str[1] == '^' || str[1] == ','))
+ {
+ bufptr = save_char(bufptr, *++str);
+ }
+ else if (str[0] == '$' && str[1] == '<') /* discard padding */
+ {
+ str += 2;
+ while (isdigit(*str) || *str == '.' || *str == '*' || *str == '/' || *str == '>')
+ str++;
+ --str;
+ }
+ else if (*str != '%' || (parametrized < 1))
+ bufptr = save_char(bufptr, *str);
+ else if (sscanf(str, "%%?%%{%d}%%>%%t%%{%d}%%+%%;", &c1,&c2) == 2)
+ {
+ str = strchr(str, ';');
+ (void) sprintf(temp, "%%>%s%s", unctrl(c1), unctrl(c2));
+ bufptr = save_string(bufptr, temp);
+ }
+ else if (sscanf(str, "%%?%%{%d}%%>%%t%%'%c'%%+%%;", &c1,&ch2) == 2)
+ {
+ str = strchr(str, ';');
+ (void) sprintf(temp, "%%>%s%c", unctrl(c1), ch2);
+ bufptr = save_string(bufptr, temp);
+ }
+ else if (sscanf(str, "%%?%%'%c'%%>%%t%%{%d}%%+%%;", &ch1,&c2) == 2)
+ {
+ str = strchr(str, ';');
+ (void) sprintf(temp, "%%>%c%c", ch1, c2);
+ bufptr = save_string(bufptr, temp);
+ }
+ else if (sscanf(str, "%%?%%'%c'%%>%%t%%'%c'%%+%%;", &ch1, &ch2) == 2)
+ {
+ str = strchr(str, ';');
+ (void) sprintf(temp, "%%>%c%c", ch1, ch2);
+ bufptr = save_string(bufptr, temp);
+ }
+ else if (strncmp(str, "%{6}%*%+", 8) == 0)
+ {
+ str += 7;
+ (void) sprintf(temp, "%%B");
+ bufptr = save_string(bufptr, temp);
+ }
+ else if ((sscanf(str, "%%{%d}%%+%%c", &c1) == 1
+ || sscanf(str, "%%'%c'%%+%%c", &ch1) == 1)
+ && (cp = strchr(str, '+')))
+ {
+ str = cp + 2;
+ bufptr = save_char(bufptr, '%');
+ bufptr = save_char(bufptr, '+');
+
+ if (ch1)
+ c1 = ch1;
+ if (is7bits(c1) && isprint(c1))
+ bufptr = save_char(bufptr, (char)c1);
+ else
+ {
+ if (c1 == (c1 & 0x1f)) /* iscntrl() returns T on 255 */
+ (void) strcpy(temp, unctrl(c1));
+ else
+ (void) sprintf(temp, "\\%03o", c1);
+ bufptr = save_string(bufptr, temp);
+ }
+ }
+ else if (strncmp(str, "%{2}%*%-", 8) == 0)
+ {
+ str += 7;
+ (void) sprintf(temp, "%%D");
+ bufptr = save_string(bufptr, temp);
+ }
+ else if (strncmp(str, "%{96}%^", 7) == 0)
+ {
+ str += 6;
+ if (saw_m++ == 0)
+ {
+ (void) sprintf(temp, "%%n");
+ bufptr = save_string(bufptr, temp);
+ }
+ }
+ else if (strncmp(str, "%{127}%^", 8) == 0)
+ {
+ str += 7;
+ if (saw_n++ == 0)
+ {
+ (void) sprintf(temp, "%%m");
+ bufptr = save_string(bufptr, temp);
+ }
+ }
+ else
+ {
+ str++;
+ switch (*str) {
+ case '%':
+ bufptr = save_char(bufptr, '%');
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ bufptr = save_char(bufptr, '%');
+ while (isdigit(*str))
+ bufptr = save_char(bufptr, *str++);
+ if (*str == 'd')
+ str++;
+ else
+ _nc_warning("numeric prefix is missing trailing d in %s",
+ cap);
+ --str;
+ break;
+
+ case 'd':
+ bufptr = save_char(bufptr, '%');
+ bufptr = save_char(bufptr, 'd');
+ break;
+
+ case 'c':
+ bufptr = save_char(bufptr, '%');
+ bufptr = save_char(bufptr, '.');
+ break;
+
+ /*
+ * %s isn't in termcap, but it's convenient to pass it through
+ * so we can represent things like terminfo pfkey strings in
+ * termcap notation.
+ */
+ case 's':
+ bufptr = save_char(bufptr, '%');
+ bufptr = save_char(bufptr, 's');
+ break;
+
+ case 'p':
+ str++;
+ if (*str == '1')
+ seenone = 1;
+ else if (*str == '2')
+ {
+ if (!seenone && !seentwo)
+ {
+ bufptr = save_char(bufptr, '%');
+ bufptr = save_char(bufptr, 'r');
+ seentwo++;
+ }
+ }
+ else if (*str >= '3')
+ return(0);
+ break;
+
+ case 'i':
+ bufptr = save_char(bufptr, '%');
+ bufptr = save_char(bufptr, 'i');
+ break;
+
+ default:
+ return(0);
+
+ } /* endswitch (*str) */
+ } /* endelse (*str == '%') */
+
+ if (*str == '\0')
+ break;
+
+ } /* endwhile (*str) */
+
+ return(my_string);
+}
+
+#ifdef MAIN
+
+int curr_line;
+
+int main(int argc, char *argv[])
+{
+ int c, tc = FALSE;
+
+ while ((c = getopt(argc, argv, "c")) != EOF)
+ switch (c)
+ {
+ case 'c':
+ tc = TRUE;
+ break;
+ }
+
+ curr_line = 0;
+ for (;;)
+ {
+ char buf[BUFSIZ];
+
+ ++curr_line;
+ if (fgets(buf, sizeof(buf), stdin) == 0)
+ break;
+ buf[strlen(buf) - 1] = '\0';
+ _nc_set_source(buf);
+
+ if (tc)
+ {
+ char *cp = _nc_infotocap("to termcap", buf, 1);
+
+ if (cp)
+ (void) fputs(cp, stdout);
+ }
+ else
+ (void) fputs(_nc_captoinfo("to terminfo", buf, 1), stdout);
+ (void) putchar('\n');
+ }
+ return(0);
+}
+#endif /* MAIN */
+
+/* captoinfo.c ends here */
+
diff --git a/lib/libcurses/tinfo/comp_error.c b/lib/libcurses/tinfo/comp_error.c
new file mode 100644
index 00000000000..2a5b115c7ad
--- /dev/null
+++ b/lib/libcurses/tinfo/comp_error.c
@@ -0,0 +1,134 @@
+/* $OpenBSD: comp_error.c,v 1.1 1999/01/18 19:10:13 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * comp_error.c -- Error message routines
+ *
+ */
+
+#include <curses.priv.h>
+
+#include <tic.h>
+
+MODULE_ID("$From: comp_error.c,v 1.16 1998/08/01 23:39:51 tom Exp $")
+
+bool _nc_suppress_warnings;
+int _nc_curr_line; /* current line # in input */
+int _nc_curr_col; /* current column # in input */
+
+static const char *sourcename;
+static char termtype[MAX_NAME_SIZE+1];
+
+void _nc_set_source(const char *const name)
+{
+ sourcename = name;
+}
+
+void _nc_set_type(const char *const name)
+{
+ if (name)
+ strlcpy( termtype, name, sizeof(termtype) );
+ else
+ termtype[0] = '\0';
+}
+
+void _nc_get_type(char *name)
+{
+ strcpy( name, termtype );
+}
+
+static inline void where_is_problem(void)
+{
+ fprintf (stderr, "\"%s\"", sourcename);
+ if (_nc_curr_line >= 0)
+ fprintf (stderr, ", line %d", _nc_curr_line);
+ if (_nc_curr_col >= 0)
+ fprintf (stderr, ", col %d", _nc_curr_col);
+ if (termtype[0])
+ fprintf (stderr, ", terminal '%s'", termtype);
+ fputc(':', stderr);
+ fputc(' ', stderr);
+}
+
+void _nc_warning(const char *const fmt, ...)
+{
+va_list argp;
+
+ if (_nc_suppress_warnings)
+ return;
+
+ where_is_problem();
+ va_start(argp,fmt);
+ vfprintf (stderr, fmt, argp);
+ fprintf (stderr, "\n");
+ va_end(argp);
+}
+
+
+void _nc_err_abort(const char *const fmt, ...)
+{
+va_list argp;
+
+ where_is_problem();
+ va_start(argp,fmt);
+ vfprintf (stderr, fmt, argp);
+ fprintf (stderr, "\n");
+ va_end(argp);
+ exit(EXIT_FAILURE);
+}
+
+
+void _nc_syserr_abort(const char *const fmt, ...)
+{
+va_list argp;
+
+ where_is_problem();
+ va_start(argp,fmt);
+ vfprintf (stderr, fmt, argp);
+ fprintf (stderr, "\n");
+ va_end(argp);
+
+ /* If we're debugging, try to show where the problem occurred - this
+ * will dump core.
+ */
+#if defined(TRACE) || !defined(NDEBUG)
+ abort();
+#else
+ /* Dumping core in production code is not a good idea.
+ */
+ exit(EXIT_FAILURE);
+#endif
+}
diff --git a/lib/libcurses/tinfo/comp_expand.c b/lib/libcurses/tinfo/comp_expand.c
new file mode 100644
index 00000000000..12c7113fb9d
--- /dev/null
+++ b/lib/libcurses/tinfo/comp_expand.c
@@ -0,0 +1,183 @@
+/* $OpenBSD: comp_expand.c,v 1.1 1999/01/18 19:10:13 millert 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> 1998 *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+#include <tic.h>
+
+MODULE_ID("$From: comp_expand.c,v 1.9 1998/09/26 13:41:40 tom Exp $")
+
+static int trailing_spaces(const char *src)
+{
+ while (*src == ' ')
+ src++;
+ return *src == 0;
+}
+
+/* this deals with differences over whether 0x7f and 0x80..0x9f are controls */
+#define CHAR_OF(s) (*(unsigned const char *)(s))
+#define REALCTL(s) (CHAR_OF(s) < 127 && iscntrl(CHAR_OF(s)))
+#define REALPRINT(s) (CHAR_OF(s) < 127 && isprint(CHAR_OF(s)))
+
+char *_nc_tic_expand(const char *srcp, bool tic_format, bool numbers)
+{
+static char * buffer;
+static size_t length;
+
+int bufp;
+const char *ptr, *str = VALID_STRING(srcp) ? srcp : "";
+bool islong = (strlen(str) > 3);
+size_t need = (2 + strlen(str)) * 4;
+int ch;
+
+ if (buffer == 0 || need > length) {
+ if ((buffer = (char *)_nc_doalloc(buffer, length = need)) == 0)
+ return 0;
+ }
+
+ bufp = 0;
+ ptr = str;
+ while ((ch = (*str & 0xff)) != 0) {
+ if (ch == '%' && REALPRINT(str+1)) {
+ buffer[bufp++] = *str++;
+ /*
+ * Though the character literals are more compact, most
+ * terminal descriptions use numbers and are not easy
+ * to read in character-literal form. This is the
+ * default option for tic/infocmp.
+ */
+ if (numbers
+ && str[0] == S_QUOTE
+ && str[1] != '\\'
+ && REALPRINT(str+1)
+ && str[2] == S_QUOTE) {
+ sprintf(buffer+bufp, "{%d}", str[1]);
+ bufp += strlen(buffer+bufp);
+ str += 2;
+ }
+ /*
+ * If we have a "%{number}", try to translate it into
+ * a "%'char'" form, since that will run a little faster
+ * when we're interpreting it. Also, having one form
+ * for the constant makes it simpler to compare terminal
+ * descriptions.
+ */
+ else if (!numbers
+ && str[0] == L_BRACE
+ && isdigit(str[1])) {
+ char *dst = 0;
+ long value = strtol(str+1, &dst, 0);
+ if (dst != 0
+ && *dst == R_BRACE
+ && value < 127
+ && value != '\\' /* FIXME */
+ && isprint((int)value)) {
+ ch = (int)value;
+ buffer[bufp++] = S_QUOTE;
+ if (ch == '\\'
+ || ch == S_QUOTE)
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = ch;
+ buffer[bufp++] = S_QUOTE;
+ str = dst;
+ } else {
+ buffer[bufp++] = *str;
+ }
+ } else {
+ buffer[bufp++] = *str;
+ }
+ }
+ else if (ch == 128) {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = '0';
+ }
+ else if (ch == '\033') {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = 'E';
+ }
+ else if (ch == '\\' && tic_format && (str == srcp || str[-1] != '^')) {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = '\\';
+ }
+ else if (ch == ' ' && tic_format && (str == srcp || trailing_spaces(str))) {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = 's';
+ }
+ else if ((ch == ',' || ch == ':' || ch == '^') && tic_format) {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = ch;
+ }
+ else if (REALPRINT(str) && (ch != ',' && ch != ':' && !(ch == '!' && !tic_format) && ch != '^'))
+ buffer[bufp++] = ch;
+#if 0 /* FIXME: this would be more readable (in fact the whole 'islong' logic should be removed) */
+ else if (ch == '\b') {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = 'b';
+ }
+ else if (ch == '\f') {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = 'f';
+ }
+ else if (ch == '\t' && islong) {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = 't';
+ }
+#endif
+ else if (ch == '\r' && (islong || (strlen(srcp) > 2 && str[1] == '\0'))) {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = 'r';
+ }
+ else if (ch == '\n' && islong) {
+ buffer[bufp++] = '\\';
+ buffer[bufp++] = 'n';
+ }
+#define UnCtl(c) ((c) + '@')
+ else if (REALCTL(str) && ch != '\\' && (!islong || isdigit(str[1])))
+ {
+ (void) sprintf(&buffer[bufp], "^%c", UnCtl(ch));
+ bufp += 2;
+ }
+ else
+ {
+ (void) sprintf(&buffer[bufp], "\\%03o", ch);
+ bufp += 4;
+ }
+
+ str++;
+ }
+
+ buffer[bufp] = '\0';
+ return(buffer);
+}
diff --git a/lib/libcurses/tinfo/comp_hash.c b/lib/libcurses/tinfo/comp_hash.c
new file mode 100644
index 00000000000..a2d7de5866c
--- /dev/null
+++ b/lib/libcurses/tinfo/comp_hash.c
@@ -0,0 +1,334 @@
+/* $OpenBSD: comp_hash.c,v 1.1 1999/01/18 19:10:14 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * comp_hash.c --- Routines to deal with the hashtable of capability
+ * names.
+ *
+ */
+
+#include <curses.priv.h>
+
+#include <tic.h>
+#include <hashsize.h>
+
+#ifdef MAIN_PROGRAM
+#include <ctype.h>
+#undef DEBUG
+#define DEBUG(level, params) /*nothing*/
+#endif
+
+MODULE_ID("$From: comp_hash.c,v 1.18 1998/08/22 18:01:18 tom Exp $")
+
+static int hash_function(const char *);
+
+/*
+ * _nc_make_hash_table()
+ *
+ * Takes the entries in table[] and hashes them into hash_table[]
+ * by name. There are CAPTABSIZE entries in table[] and HASHTABSIZE
+ * slots in hash_table[].
+ *
+ */
+
+#ifdef MAIN_PROGRAM
+static void _nc_make_hash_table(struct name_table_entry *table,
+ struct name_table_entry **hash_table)
+{
+int i;
+int hashvalue;
+int collisions = 0;
+
+ for (i = 0; i < CAPTABSIZE; i++) {
+ hashvalue = hash_function(table[i].nte_name);
+
+ if (hash_table[hashvalue] != (struct name_table_entry *) 0)
+ collisions++;
+
+ if (hash_table[hashvalue] != 0)
+ table[i].nte_link = (short)(hash_table[hashvalue] - table);
+ hash_table[hashvalue] = &table[i];
+ }
+
+ DEBUG(4, ("Hash table complete: %d collisions out of %d entries", collisions, CAPTABSIZE));
+}
+#endif
+
+
+/*
+ * int hash_function(string)
+ *
+ * Computes the hashing function on the given string.
+ *
+ * The current hash function is the sum of each consectutive pair
+ * of characters, taken as two-byte integers, mod Hashtabsize.
+ *
+ */
+
+static
+int
+hash_function(const char *string)
+{
+long sum = 0;
+
+ DEBUG(9, ("hashing %s", string));
+ while (*string) {
+ sum += (long)(*string + (*(string + 1) << 8));
+ string++;
+ }
+
+ DEBUG(9, ("sum is %ld", sum));
+ return (int)(sum % HASHTABSIZE);
+}
+
+
+/*
+ * struct name_table_entry *
+ * find_entry(string)
+ *
+ * Finds the entry for the given string in the hash table if present.
+ * Returns a pointer to the entry in the table or 0 if not found.
+ *
+ */
+
+#ifndef MAIN_PROGRAM
+struct name_table_entry const *
+_nc_find_entry(const char *string, const struct name_table_entry *const *hash_table)
+{
+int hashvalue;
+struct name_table_entry const *ptr;
+
+ hashvalue = hash_function(string);
+
+ if ((ptr = hash_table[hashvalue]) != 0) {
+ while (strcmp(ptr->nte_name, string) != 0) {
+ if (ptr->nte_link < 0)
+ return 0;
+ ptr = ptr->nte_link + hash_table[HASHTABSIZE];
+ }
+ }
+
+ return (ptr);
+}
+
+/*
+ * struct name_table_entry *
+ * find_type_entry(string, type, table)
+ *
+ * Finds the first entry for the given name with the given type in the
+ * given table if present (as distinct from find_entry, which finds the
+ * the last entry regardless of type). You can use this if you detect
+ * a name clash. It's slower, though. Returns a pointer to the entry
+ * in the table or 0 if not found.
+ */
+
+struct name_table_entry const *
+_nc_find_type_entry(const char *string,
+ int type,
+ const struct name_table_entry *table)
+{
+struct name_table_entry const *ptr;
+
+ for (ptr = table; ptr < table + CAPTABSIZE; ptr++) {
+ if (ptr->nte_type == type && strcmp(string, ptr->nte_name) == 0)
+ return(ptr);
+ }
+
+ return ((struct name_table_entry *)NULL);
+}
+#endif
+
+#ifdef MAIN_PROGRAM
+/*
+ * This filter reads from standard input a list of tab-delimited columns,
+ * (e.g., from Caps.filtered) computes the hash-value of a specified column and
+ * writes the hashed tables to standard output.
+ *
+ * By compiling the hash table at build time, we're able to make the entire
+ * set of terminfo and termcap tables readonly (and also provide some runtime
+ * performance enhancement).
+ */
+
+#if !HAVE_STRDUP
+static char *strdup (char *s)
+{
+ char *p;
+
+ p = malloc(strlen(s)+1);
+ if (p)
+ strcpy(p,s);
+ return(p);
+}
+#endif /* not HAVE_STRDUP */
+
+#define MAX_COLUMNS BUFSIZ /* this _has_ to be worst-case */
+
+static char **parse_columns(char *buffer)
+{
+ static char **list;
+
+ int col = 0;
+
+ if (list == 0 && (list = typeCalloc(char *, MAX_COLUMNS)) == 0)
+ return(0);
+
+ if (*buffer != '#') {
+ while (*buffer != '\0') {
+ char *s;
+ for (s = buffer; (*s != '\0') && !isspace(*s); s++)
+ /*EMPTY*/;
+ if (s != buffer) {
+ char mark = *s;
+ *s = '\0';
+ if ((s - buffer) > 1
+ && (*buffer == '"')
+ && (s[-1] == '"')) { /* strip the quotes */
+ buffer++;
+ s[-1] = '\0';
+ }
+ list[col] = buffer;
+ col++;
+ if (mark == '\0')
+ break;
+ while (*++s && isspace(*s))
+ /*EMPTY*/;
+ buffer = s;
+ } else
+ break;
+ }
+ }
+ return col ? list : 0;
+}
+
+int main(int argc, char **argv)
+{
+ struct name_table_entry *name_table = typeCalloc(struct name_table_entry, CAPTABSIZE);
+ struct name_table_entry **hash_table = typeCalloc(struct name_table_entry *, HASHTABSIZE);
+ const char *root_name = "";
+ int column = 0;
+ int n;
+ char buffer[BUFSIZ];
+
+ static const char * typenames[] = { "BOOLEAN", "NUMBER", "STRING" };
+
+ short BoolCount = 0;
+ short NumCount = 0;
+ short StrCount = 0;
+
+ /* The first argument is the column-number (starting with 0).
+ * The second is the root name of the tables to generate.
+ */
+ if (argc <= 2
+ || (column = atoi(argv[1])) <= 0
+ || (column >= MAX_COLUMNS)
+ || *(root_name = argv[2]) == 0) {
+ fprintf(stderr, "usage: make_hash column root_name\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Read the table into our arrays.
+ */
+ for (n = 0; (n < CAPTABSIZE) && fgets(buffer, BUFSIZ, stdin); ) {
+ char **list, *nlp = strchr(buffer, '\n');
+ if (nlp)
+ *nlp = '\0';
+ list = parse_columns(buffer);
+ if (list == 0) /* blank or comment */
+ continue;
+ name_table[n].nte_link = -1; /* end-of-hash */
+ name_table[n].nte_name = strdup(list[column]);
+ if (!strcmp(list[2], "bool")) {
+ name_table[n].nte_type = BOOLEAN;
+ name_table[n].nte_index = BoolCount++;
+ } else if (!strcmp(list[2], "num")) {
+ name_table[n].nte_type = NUMBER;
+ name_table[n].nte_index = NumCount++;
+ } else if (!strcmp(list[2], "str")) {
+ name_table[n].nte_type = STRING;
+ name_table[n].nte_index = StrCount++;
+ } else {
+ fprintf(stderr, "Unknown type: %s\n", list[2]);
+ exit(EXIT_FAILURE);
+ }
+ n++;
+ }
+ _nc_make_hash_table(name_table, hash_table);
+
+ /*
+ * Write the compiled tables to standard output
+ */
+ printf("static struct name_table_entry const _nc_%s_table[] =\n",
+ root_name);
+ printf("{\n");
+ for (n = 0; n < CAPTABSIZE; n++) {
+ sprintf(buffer, "\"%s\"",
+ name_table[n].nte_name);
+ printf("\t{ %15s,\t%10s,\t%3d, %3d }%c\n",
+ buffer,
+ typenames[name_table[n].nte_type],
+ name_table[n].nte_index,
+ name_table[n].nte_link,
+ n < CAPTABSIZE - 1 ? ',' : ' ');
+ }
+ printf("};\n\n");
+
+ printf("const struct name_table_entry * const _nc_%s_hash_table[%d] =\n",
+ root_name,
+ HASHTABSIZE+1);
+ printf("{\n");
+ for (n = 0; n < HASHTABSIZE; n++) {
+ if (hash_table[n] != 0) {
+ sprintf(buffer, "_nc_%s_table + %3ld",
+ root_name,
+ (long) (hash_table[n] - name_table));
+ } else {
+ strcpy(buffer, "0");
+ }
+ printf("\t%s,\n", buffer);
+ }
+ printf("\t_nc_%s_table\t/* base-of-table */\n", root_name);
+ printf("};\n\n");
+
+ printf("#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n",
+ BoolCount, NumCount, StrCount);
+ printf("#error\t--> term.h and comp_captab.c disagree about the <--\n");
+ printf("#error\t--> numbers of booleans, numbers and/or strings <--\n");
+ printf("#endif\n\n");
+
+ return EXIT_SUCCESS;
+}
+#endif
diff --git a/lib/libcurses/tinfo/comp_parse.c b/lib/libcurses/tinfo/comp_parse.c
new file mode 100644
index 00000000000..6416db292ae
--- /dev/null
+++ b/lib/libcurses/tinfo/comp_parse.c
@@ -0,0 +1,539 @@
+/* $OpenBSD: comp_parse.c,v 1.1 1999/01/18 19:10:14 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+
+/*
+ * comp_parse.c -- parser driver loop and use handling.
+ *
+ * _nc_read_entry_source(FILE *, literal, bool, bool (*hook)())
+ * _nc_resolve_uses(void)
+ * _nc_free_entries(void)
+ *
+ * Use this code by calling _nc_read_entry_source() on as many source
+ * files as you like (either terminfo or termcap syntax). If you
+ * want use-resolution, call _nc_resolve_uses(). To free the list
+ * storage, do _nc_free_entries().
+ *
+ */
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+
+#include <tic.h>
+#include <term.h>
+#include <term_entry.h>
+
+MODULE_ID("$From: comp_parse.c,v 1.23 1998/05/30 23:38:15 Todd.Miller Exp $")
+
+static void sanity_check(TERMTYPE *);
+
+/****************************************************************************
+ *
+ * Entry queue handling
+ *
+ ****************************************************************************/
+/*
+ * The entry list is a doubly linked list with NULLs terminating the lists:
+ *
+ * --------- --------- ---------
+ * | | | | | | offset
+ * |-------| |-------| |-------|
+ * | ----+-->| ----+-->| NULL | next
+ * |-------| |-------| |-------|
+ * | NULL |<--+---- |<--+---- | last
+ * --------- --------- ---------
+ * ^ ^
+ * | |
+ * | |
+ * _nc_head _nc_tail
+ */
+
+ENTRY *_nc_head, *_nc_tail;
+
+static void enqueue(ENTRY *ep)
+/* add an entry to the in-core list */
+{
+ ENTRY *newp = (ENTRY *)malloc(sizeof(ENTRY));
+
+ if (newp == NULL)
+ _nc_err_abort("Out of memory");
+
+ (void) memcpy(newp, ep, sizeof(ENTRY));
+
+ newp->last = _nc_tail;
+ _nc_tail = newp;
+
+ newp->next = (ENTRY *)NULL;
+ if (newp->last)
+ newp->last->next = newp;
+}
+
+void _nc_free_entries(ENTRY *head)
+/* free the allocated storage consumed by list entries */
+{
+ ENTRY *ep, *next;
+
+ for (ep = head; ep; ep = next)
+ {
+ /*
+ * This conditional lets us disconnect storage from the list.
+ * To do this, copy an entry out of the list, then null out
+ * the string-table member in the original and any use entries
+ * it references.
+ */
+ FreeIfNeeded(ep->tterm.str_table);
+
+ next = ep->next;
+
+ free(ep);
+ if (ep == _nc_head) _nc_head = 0;
+ if (ep == _nc_tail) _nc_tail = 0;
+ }
+}
+
+bool _nc_entry_match(char *n1, char *n2)
+/* do any of the aliases in a pair of terminal names match? */
+{
+ char *pstart, *qstart, *pend, *qend;
+ char nc1[MAX_NAME_SIZE+1], nc2[MAX_NAME_SIZE+1];
+ size_t n;
+
+ if (strchr(n1, '|') == NULL)
+ {
+ if ((n = strlcpy(nc1, n1, sizeof(nc1))) > sizeof(nc1) - 2)
+ n = sizeof(nc1) - 2;
+ nc1[n++] = '|';
+ nc1[n] = '\0';
+ n1 = nc1;
+ }
+
+ if (strchr(n2, '|') == NULL)
+ {
+ if ((n = strlcpy(nc2, n2, sizeof(nc2))) > sizeof(nc2) - 2)
+ n = sizeof(nc2) - 2;
+ nc2[n++] = '|';
+ nc2[n] = '\0';
+ n2 = nc2;
+ }
+
+ for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1)
+ for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1)
+ if ((pend-pstart == qend-qstart)
+ && memcmp(pstart, qstart, (size_t)(pend-pstart)) == 0)
+ return(TRUE);
+
+ return(FALSE);
+}
+
+/****************************************************************************
+ *
+ * Entry compiler and resolution logic
+ *
+ ****************************************************************************/
+
+void _nc_read_entry_source(FILE *fp, char *buf,
+ int literal, bool silent,
+ bool (*hook)(ENTRY *))
+/* slurp all entries in the given file into core */
+{
+ ENTRY thisentry;
+ bool oldsuppress = _nc_suppress_warnings;
+ int immediate = 0;
+
+ if (silent)
+ _nc_suppress_warnings = TRUE; /* shut the lexer up, too */
+
+ for (_nc_reset_input(fp, buf); _nc_parse_entry(&thisentry, literal, silent) != ERR; )
+ {
+ if (!isalnum(thisentry.tterm.term_names[0]))
+ _nc_err_abort("terminal names must start with letter or digit");
+
+ /*
+ * This can be used for immediate compilation of entries with no
+ * use references to disk, so as to avoid chewing up a lot of
+ * core when the resolution code could fetch entries off disk.
+ */
+ if (hook != NULLHOOK && (*hook)(&thisentry))
+ immediate++;
+ else
+ enqueue(&thisentry);
+ }
+
+ if (_nc_tail)
+ {
+ /* set up the head pointer */
+ for (_nc_head = _nc_tail; _nc_head->last; _nc_head = _nc_head->last)
+ continue;
+
+ DEBUG(1, ("head = %s", _nc_head->tterm.term_names));
+ DEBUG(1, ("tail = %s", _nc_tail->tterm.term_names));
+ }
+#ifdef TRACE
+ else if (!immediate)
+ DEBUG(1, ("no entries parsed"));
+#endif
+
+ _nc_suppress_warnings = oldsuppress;
+}
+
+int _nc_resolve_uses(void)
+/* try to resolve all use capabilities */
+{
+ ENTRY *qp, *rp, *lastread = NULL;
+ bool keepgoing;
+ int i, j, unresolved, total_unresolved, multiples;
+
+ DEBUG(2, ("RESOLUTION BEGINNING"));
+
+ /*
+ * Check for multiple occurrences of the same name.
+ */
+ multiples = 0;
+ for_entry_list(qp)
+ {
+ int matchcount = 0;
+
+ for_entry_list(rp)
+ if (qp > rp
+ && _nc_entry_match(qp->tterm.term_names, rp->tterm.term_names))
+ {
+ matchcount++;
+ if (matchcount == 1)
+ {
+ (void) fprintf(stderr, "Name collision between %s",
+ _nc_first_name(qp->tterm.term_names));
+ multiples++;
+ }
+ if (matchcount >= 1)
+ (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names));
+ }
+ if (matchcount >= 1)
+ (void) putc('\n', stderr);
+ }
+ if (multiples > 0)
+ return(FALSE);
+
+ DEBUG(2, ("NO MULTIPLE NAME OCCURRENCES"));
+
+ /*
+ * First resolution stage: replace names in use arrays with entry
+ * pointers. By doing this, we avoid having to do the same name
+ * match once for each time a use entry is itself unresolved.
+ */
+ total_unresolved = 0;
+ _nc_curr_col = -1;
+ for_entry_list(qp)
+ {
+ unresolved = 0;
+ for (i = 0; i < qp->nuses; i++)
+ {
+ bool foundit;
+ char *child = _nc_first_name(qp->tterm.term_names);
+ char *lookfor = (char *)(qp->uses[i].parent);
+ long lookline = qp->uses[i].line;
+
+ foundit = FALSE;
+
+ _nc_set_type(child);
+
+ /* first, try to resolve from in-core records */
+ for_entry_list(rp)
+ if (rp != qp
+ && _nc_name_match(rp->tterm.term_names, lookfor, "|"))
+ {
+ DEBUG(2, ("%s: resolving use=%s (in core)",
+ child, lookfor));
+
+ qp->uses[i].parent = rp;
+ foundit = TRUE;
+ }
+
+ /* if that didn't work, try to merge in a compiled entry */
+ if (!foundit)
+ {
+ TERMTYPE thisterm;
+ char filename[PATH_MAX];
+
+ if (_nc_read_entry(lookfor, filename, &thisterm) == 1)
+ {
+ DEBUG(2, ("%s: resolving use=%s (compiled)",
+ child, lookfor));
+
+ rp = (ENTRY *)malloc(sizeof(ENTRY));
+ if (rp == NULL)
+ _nc_err_abort("Out of memory");
+ memcpy(&rp->tterm, &thisterm, sizeof(TERMTYPE));
+ rp->nuses = 0;
+ rp->next = lastread;
+ lastread = rp;
+
+ qp->uses[i].parent = rp;
+ foundit = TRUE;
+ }
+ }
+
+ /* no good, mark this one unresolvable and complain */
+ if (!foundit)
+ {
+ unresolved++;
+ total_unresolved++;
+
+ _nc_curr_line = lookline;
+ _nc_warning("resolution of use=%s failed", lookfor);
+ qp->uses[i].parent = (ENTRY *)NULL;
+ }
+ }
+ }
+ if (total_unresolved)
+ {
+ /* free entries read in off disk */
+ _nc_free_entries(lastread);
+ return(FALSE);
+ }
+
+ DEBUG(2, ("NAME RESOLUTION COMPLETED OK"));
+
+ /*
+ * OK, at this point all (char *) references have been successfully
+ * replaced by (ENTRY *) pointers. Time to do the actual merges.
+ */
+ do {
+ TERMTYPE merged;
+
+ keepgoing = FALSE;
+
+ for_entry_list(qp)
+ if (qp->nuses > 0)
+ {
+ DEBUG(2, ("%s: attempting merge", _nc_first_name(qp->tterm.term_names)));
+ /*
+ * If any of the use entries we're looking for is
+ * incomplete, punt. We'll catch this entry on a
+ * subsequent pass.
+ */
+ for (i = 0; i < qp->nuses; i++)
+ if (((ENTRY *)qp->uses[i].parent)->nuses)
+ {
+ DEBUG(2, ("%s: use entry %d unresolved",
+ _nc_first_name(qp->tterm.term_names), i));
+ goto incomplete;
+ }
+
+ /*
+ * First, make sure there's no garbage in the merge block.
+ * as a side effect, copy into the merged entry the name
+ * field and string table pointer.
+ */
+ memcpy(&merged, &qp->tterm, sizeof(TERMTYPE));
+
+ /*
+ * Now merge in each use entry in the proper
+ * (reverse) order.
+ */
+ for (; qp->nuses; qp->nuses--)
+ _nc_merge_entry(&merged,
+ &((ENTRY *)qp->uses[qp->nuses-1].parent)->tterm);
+
+ /*
+ * Now merge in the original entry.
+ */
+ _nc_merge_entry(&merged, &qp->tterm);
+
+ /*
+ * Replace the original entry with the merged one.
+ */
+ memcpy(&qp->tterm, &merged, sizeof(TERMTYPE));
+
+ /*
+ * We know every entry is resolvable because name resolution
+ * didn't bomb. So go back for another pass.
+ */
+ /* FALLTHRU */
+ incomplete:
+ keepgoing = TRUE;
+ }
+ } while
+ (keepgoing);
+
+ DEBUG(2, ("MERGES COMPLETED OK"));
+
+ /*
+ * The exit condition of the loop above is such that all entries
+ * must now be resolved. Now handle cancellations. In a resolved
+ * entry there should be no cancellation markers.
+ */
+ for_entry_list(qp)
+ {
+ for (j = 0; j < BOOLCOUNT; j++)
+ if (qp->tterm.Booleans[j] == CANCELLED_BOOLEAN)
+ qp->tterm.Booleans[j] = FALSE;
+ for (j = 0; j < NUMCOUNT; j++)
+ if (qp->tterm.Numbers[j] == CANCELLED_NUMERIC)
+ qp->tterm.Numbers[j] = ABSENT_NUMERIC;
+ for (j = 0; j < STRCOUNT; j++)
+ if (qp->tterm.Strings[j] == CANCELLED_STRING)
+ qp->tterm.Strings[j] = ABSENT_STRING;
+ }
+
+ /*
+ * We'd like to free entries read in off disk at this point, but can't.
+ * The merge_entry() code doesn't copy the strings in the use entries,
+ * it just aliases them. If this ever changes, do a
+ * free_entries(lastread) here.
+ */
+
+ DEBUG(2, ("RESOLUTION FINISHED"));
+
+ _nc_curr_col = -1;
+ for_entry_list(qp)
+ {
+ _nc_curr_line = qp->startline;
+ _nc_set_type(_nc_first_name(qp->tterm.term_names));
+ sanity_check(&qp->tterm);
+ }
+
+ DEBUG(2, ("SANITY CHECK FINISHED"));
+
+ return(TRUE);
+}
+
+/*
+ * 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->
+
+/*
+ * Note that WANTED and PRESENT are not simple inverses! If a capability
+ * has been explicitly cancelled, it's not considered WANTED.
+ */
+#define WANTED(s) ((s) == ABSENT_STRING)
+#define PRESENT(s) (((s) != ABSENT_STRING) && ((s) != CANCELLED_STRING))
+
+#define ANDMISSING(p,q) \
+ {if (PRESENT(p) && !PRESENT(q)) _nc_warning(#p " but no " #q);}
+
+#define PAIRED(p,q) \
+ { \
+ if (PRESENT(q) && !PRESENT(p)) \
+ _nc_warning(#q " but no " #p); \
+ if (PRESENT(p) && !PRESENT(q)) \
+ _nc_warning(#p " but no " #q); \
+ }
+
+static void sanity_check(TERMTYPE *tp)
+{
+#ifdef __UNUSED__ /* this casts too wide a net */
+ bool terminal_entry = !strchr(tp->term_names, '+');
+#endif
+
+ if (!PRESENT(exit_attribute_mode))
+ {
+#ifdef __UNUSED__ /* this casts too wide a net */
+ if (terminal_entry &&
+ (PRESENT(set_attributes)
+ || PRESENT(enter_standout_mode)
+ || PRESENT(enter_underline_mode)
+ || PRESENT(enter_blink_mode)
+ || PRESENT(enter_bold_mode)
+ || PRESENT(enter_dim_mode)
+ || PRESENT(enter_secure_mode)
+ || PRESENT(enter_protected_mode)
+ || PRESENT(enter_reverse_mode)))
+ _nc_warning("no exit_attribute_mode");
+#endif /* __UNUSED__ */
+ PAIRED(enter_standout_mode, exit_standout_mode)
+ PAIRED(enter_underline_mode, exit_underline_mode)
+ }
+
+ /* listed in structure-member order of first argument */
+#ifdef __UNUSED__
+ ANDMISSING(cursor_invisible, cursor_normal)
+ ANDMISSING(cursor_visible, cursor_normal)
+#endif /* __UNUSED__ */
+ PAIRED(enter_alt_charset_mode, exit_alt_charset_mode)
+ ANDMISSING(enter_alt_charset_mode, acs_chars)
+ ANDMISSING(exit_alt_charset_mode, acs_chars)
+ ANDMISSING(enter_blink_mode, exit_attribute_mode)
+ ANDMISSING(enter_bold_mode, exit_attribute_mode)
+ PAIRED(exit_ca_mode, enter_ca_mode)
+ PAIRED(enter_delete_mode, exit_delete_mode)
+ ANDMISSING(enter_dim_mode, exit_attribute_mode)
+ PAIRED(enter_insert_mode, exit_insert_mode)
+ ANDMISSING(enter_secure_mode, exit_attribute_mode)
+ ANDMISSING(enter_protected_mode, exit_attribute_mode)
+ ANDMISSING(enter_reverse_mode, exit_attribute_mode)
+ PAIRED(from_status_line, to_status_line)
+ PAIRED(meta_off, meta_on)
+
+ PAIRED(prtr_on, prtr_off)
+ PAIRED(save_cursor, restore_cursor)
+ PAIRED(enter_xon_mode, exit_xon_mode)
+ PAIRED(enter_am_mode, exit_am_mode)
+ ANDMISSING(label_off, label_on)
+ PAIRED(display_clock, remove_clock)
+ ANDMISSING(set_color_pair, initialize_pair)
+
+ /* Some checks that we should make, but don't want to confuse people
+ * with. Put those under the tic -v option so we can still get them.
+ */
+ if (_nc_tracing) {
+
+ /*
+ * 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 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");
+ }
+ }
+#undef PAIRED
+#undef ANDMISSING
+}
diff --git a/lib/libcurses/tinfo/comp_scan.c b/lib/libcurses/tinfo/comp_scan.c
new file mode 100644
index 00000000000..0c9012c835d
--- /dev/null
+++ b/lib/libcurses/tinfo/comp_scan.c
@@ -0,0 +1,756 @@
+/****************************************************************************
+ * 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> *
+ ****************************************************************************/
+
+/*
+ * comp_scan.c --- Lexical scanner for terminfo compiler.
+ *
+ * _nc_reset_input()
+ * _nc_get_token()
+ * _nc_panic_mode()
+ * int _nc_syntax;
+ * int _nc_curr_line;
+ * long _nc_curr_file_pos;
+ * long _nc_comment_start;
+ * long _nc_comment_end;
+ */
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+#include <tic.h>
+
+MODULE_ID("$From: comp_scan.c,v 1.34 1998/11/01 00:56:39 tom Exp $")
+
+/*
+ * Maximum length of string capability we'll accept before raising an error.
+ * Yes, there is a real capability in /etc/termcap this long, an "is".
+ */
+#define MAXCAPLEN 600
+
+#define iswhite(ch) (ch == ' ' || ch == '\t')
+
+int _nc_syntax; /* termcap or terminfo? */
+long _nc_curr_file_pos; /* file offset of current line */
+long _nc_comment_start; /* start of comment range before name */
+long _nc_comment_end; /* end of comment range before name */
+long _nc_start_line; /* start line of current entry */
+
+/*****************************************************************************
+ *
+ * Token-grabbing machinery
+ *
+ *****************************************************************************/
+
+static bool first_column; /* See 'next_char()' below */
+static char separator; /* capability separator */
+static int pushtype; /* type of pushback token */
+static char pushname[MAX_NAME_SIZE+1];
+
+static int last_char(void);
+static int next_char(void);
+static long stream_pos(void);
+static bool end_of_stream(void);
+static void push_back(char c);
+
+/* Assume we may be looking at a termcap-style continuation */
+static inline int eat_escaped_newline(int ch)
+{
+ if (ch == '\\')
+ while ((ch = next_char()) == '\n' || iswhite(ch))
+ continue;
+ return ch;
+}
+
+/*
+ * int
+ * get_token()
+ *
+ * Scans the input for the next token, storing the specifics in the
+ * global structure 'curr_token' and returning one of the following:
+ *
+ * NAMES A line beginning in column 1. 'name'
+ * will be set to point to everything up to but
+ * not including the first separator on the line.
+ * BOOLEAN An entry consisting of a name followed by
+ * a separator. 'name' will be set to point to
+ * the name of the capability.
+ * NUMBER An entry of the form
+ * name#digits,
+ * 'name' will be set to point to the capability
+ * name and 'valnumber' to the number given.
+ * STRING An entry of the form
+ * name=characters,
+ * 'name' is set to the capability name and
+ * 'valstring' to the string of characters, with
+ * input translations done.
+ * CANCEL An entry of the form
+ * name@,
+ * 'name' is set to the capability name and
+ * 'valnumber' to -1.
+ * EOF The end of the file has been reached.
+ *
+ * A `separator' is either a comma or a semicolon, depending on whether
+ * we are in termcap or terminfo mode.
+ *
+ */
+
+int _nc_get_token(void)
+{
+static const char terminfo_punct[] = "@%&*!#";
+long number;
+int type;
+int ch;
+char * numchk;
+char numbuf[80];
+unsigned found;
+static char buffer[MAX_ENTRY_SIZE];
+char *ptr;
+int dot_flag = FALSE;
+long token_start;
+
+ if (pushtype != NO_PUSHBACK)
+ {
+ int retval = pushtype;
+
+ _nc_set_type(pushname);
+ DEBUG(3, ("pushed-back token: `%s', class %d",
+ _nc_curr_token.tk_name, pushtype));
+
+ pushtype = NO_PUSHBACK;
+ pushname[0] = '\0';
+
+ /* currtok wasn't altered by _nc_push_token() */
+ return(retval);
+ }
+
+ if (end_of_stream())
+ return(EOF);
+
+start_token:
+ token_start = stream_pos();
+ while ((ch = next_char()) == '\n' || iswhite(ch))
+ continue;
+
+ ch = eat_escaped_newline(ch);
+
+ if (ch == EOF)
+ type = EOF;
+ else {
+ /* if this is a termcap entry, skip a leading separator */
+ if (separator == ':' && ch == ':')
+ ch = next_char();
+
+ if (ch == '.') {
+ dot_flag = TRUE;
+ DEBUG(8, ("dot-flag set"));
+
+ while ((ch = next_char())=='.' || iswhite(ch))
+ continue;
+ }
+
+ if (ch == EOF) {
+ type = EOF;
+ goto end_of_token;
+ }
+
+ /* have to make some punctuation chars legal for terminfo */
+ if (!isalnum(ch) && !strchr(terminfo_punct, (char)ch)) {
+ _nc_warning("Illegal character (expected alphanumeric or %s) - %s",
+ terminfo_punct, _tracechar((chtype)ch));
+ _nc_panic_mode(separator);
+ goto start_token;
+ }
+
+ ptr = buffer;
+ *(ptr++) = ch;
+
+ if (first_column) {
+ char *desc;
+
+ _nc_comment_start = token_start;
+ _nc_comment_end = _nc_curr_file_pos;
+ _nc_start_line = _nc_curr_line;
+
+ _nc_syntax = ERR;
+ while ((ch = next_char()) != '\n')
+ {
+ if (ch == EOF)
+ _nc_err_abort("premature EOF");
+ else if (ch == ':' && last_char() != ',')
+ {
+ _nc_syntax = SYN_TERMCAP;
+ separator = ':';
+ break;
+ }
+ else if (ch == ',')
+ {
+ _nc_syntax = SYN_TERMINFO;
+ separator = ',';
+ /*
+ * Fall-through here is not an accident.
+ * The idea is that if we see a comma, we
+ * figure this is terminfo unless we
+ * subsequently run into a colon -- but
+ * we don't stop looking for that colon until
+ * hitting a newline. This allows commas to
+ * be embedded in description fields of
+ * either syntax.
+ */
+ /* FALLTHRU */
+ }
+ else
+ ch = eat_escaped_newline(ch);
+
+ *ptr++ = ch;
+ }
+ ptr[0] = '\0';
+ if (_nc_syntax == ERR)
+ {
+ /*
+ * Grrr...what we ought to do here is barf,
+ * complaining that the entry is malformed.
+ * But because a couple of name fields in the
+ * 8.2 termcap file end with |\, we just have
+ * to assume it's termcap syntax.
+ */
+ _nc_syntax = SYN_TERMCAP;
+ separator = ':';
+ }
+ else if (_nc_syntax == SYN_TERMINFO)
+ {
+ /* throw away trailing /, *$/ */
+ for (--ptr; iswhite(*ptr) || *ptr == ','; ptr--)
+ continue;
+ ptr[1] = '\0';
+ }
+
+ /*
+ * This is the soonest we have the terminal name
+ * fetched. Set up for following warning messages.
+ */
+ ptr = strchr(buffer, '|');
+ if (ptr == (char *)NULL)
+ ptr = buffer + strlen(buffer);
+ ch = *ptr;
+ *ptr = '\0';
+ _nc_set_type(buffer);
+ *ptr = ch;
+
+ /*
+ * Compute the boundary between the aliases and the
+ * description field for syntax-checking purposes.
+ */
+ desc = strrchr(buffer, '|');
+ if (desc) {
+ if (*desc == '\0')
+ _nc_warning("empty longname field");
+ else if (strchr(desc, ' ') == (char *)NULL)
+ _nc_warning("older tic versions may treat the description field as an alias");
+ }
+ if (!desc)
+ desc = buffer + strlen(buffer);
+
+ /*
+ * Whitespace in a name field other than the long name
+ * can confuse rdist and some termcap tools. Slashes
+ * are a no-no. Other special characters can be
+ * dangerous due to shell expansion.
+ */
+ for (ptr = buffer; ptr < desc; ptr++)
+ {
+ if (isspace(*ptr))
+ {
+ _nc_warning("whitespace in name or alias field");
+ break;
+ }
+ else if (*ptr == '/')
+ {
+ _nc_warning("slashes aren't allowed in names or aliases");
+ break;
+ }
+ else if (strchr("$[]!*?", *ptr))
+ {
+ _nc_warning("dubious character `%c' in name or alias field", *ptr);
+ break;
+ }
+ }
+
+ ptr = buffer;
+
+ _nc_curr_token.tk_name = buffer;
+ type = NAMES;
+ } else {
+ while ((ch = next_char()) != EOF) {
+ if (!isalnum(ch)) {
+ if (_nc_syntax == SYN_TERMINFO) {
+ if (ch != '_')
+ break;
+ } else { /* allow ';' for "k;" */
+ if (ch != ';')
+ break;
+ }
+ }
+ *(ptr++) = ch;
+ }
+
+ *ptr++ = '\0';
+ switch (ch) {
+ case ',':
+ case ':':
+ if (ch != separator)
+ _nc_err_abort("Separator inconsistent with syntax");
+ _nc_curr_token.tk_name = buffer;
+ type = BOOLEAN;
+ break;
+ case '@':
+ if ((ch = next_char()) != separator)
+ _nc_warning("Missing separator after `%s', have %s",
+ buffer, _tracechar((chtype)ch));
+ _nc_curr_token.tk_name = buffer;
+ type = CANCEL;
+ break;
+
+ case '#':
+ found = 0;
+ while (isalnum(ch = next_char())) {
+ numbuf[found++] = ch;
+ if (found >= sizeof(numbuf)-1)
+ break;
+ }
+ numbuf[found] = '\0';
+ number = strtol(numbuf, &numchk, 0);
+ if (numchk == numbuf)
+ _nc_warning("no value given for `%s'", buffer);
+ if ((*numchk != '\0') || (ch != separator))
+ _nc_warning("Missing separator");
+ _nc_curr_token.tk_name = buffer;
+ _nc_curr_token.tk_valnumber = number;
+ type = NUMBER;
+ break;
+
+ case '=':
+ ch = _nc_trans_string(ptr);
+ if (ch != separator)
+ _nc_warning("Missing separator");
+ _nc_curr_token.tk_name = buffer;
+ _nc_curr_token.tk_valstring = ptr;
+ type = STRING;
+ break;
+
+ case EOF:
+ type = EOF;
+ break;
+ default:
+ /* just to get rid of the compiler warning */
+ type = UNDEF;
+ _nc_warning("Illegal character - %s",
+ _tracechar((chtype)ch));
+ }
+ } /* end else (first_column == FALSE) */
+ } /* end else (ch != EOF) */
+
+end_of_token:
+
+#ifdef TRACE
+ if (dot_flag == TRUE)
+ DEBUG(8, ("Commented out "));
+
+ if (_nc_tracing & TRACE_IEVENT)
+ {
+ fprintf(stderr, "Token: ");
+ switch (type)
+ {
+ case BOOLEAN:
+ fprintf(stderr, "Boolean; name='%s'\n",
+ _nc_curr_token.tk_name);
+ break;
+
+ case NUMBER:
+ fprintf(stderr, "Number; name='%s', value=%d\n",
+ _nc_curr_token.tk_name,
+ _nc_curr_token.tk_valnumber);
+ break;
+
+ case STRING:
+ fprintf(stderr, "String; name='%s', value=%s\n",
+ _nc_curr_token.tk_name,
+ _nc_visbuf(_nc_curr_token.tk_valstring));
+ break;
+
+ case CANCEL:
+ fprintf(stderr, "Cancel; name='%s'\n",
+ _nc_curr_token.tk_name);
+ break;
+
+ case NAMES:
+
+ fprintf(stderr, "Names; value='%s'\n",
+ _nc_curr_token.tk_name);
+ break;
+
+ case EOF:
+ fprintf(stderr, "End of file\n");
+ break;
+
+ default:
+ _nc_warning("Bad token type");
+ }
+ }
+#endif
+
+ if (dot_flag == TRUE) /* if commented out, use the next one */
+ type = _nc_get_token();
+
+ DEBUG(3, ("token: `%s', class %d", _nc_curr_token.tk_name, type));
+
+ return(type);
+}
+
+/*
+ * char
+ * trans_string(ptr)
+ *
+ * Reads characters using next_char() until encountering a separator, nl,
+ * or end-of-file. The returned value is the character which caused
+ * reading to stop. The following translations are done on the input:
+ *
+ * ^X goes to ctrl-X (i.e. X & 037)
+ * {\E,\n,\r,\b,\t,\f} go to
+ * {ESCAPE,newline,carriage-return,backspace,tab,formfeed}
+ * {\^,\\} go to {carat,backslash}
+ * \ddd (for ddd = up to three octal digits) goes to the character ddd
+ *
+ * \e == \E
+ * \0 == \200
+ *
+ */
+
+char
+_nc_trans_string(char *ptr)
+{
+int count = 0;
+int number;
+int i, c;
+chtype ch, last_ch = '\0';
+bool ignored = FALSE;
+
+ while ((ch = c = next_char()) != (chtype)separator && c != EOF) {
+ if ((_nc_syntax == SYN_TERMCAP) && c == '\n')
+ break;
+ if (ch == '^' && last_ch != '%') {
+ ch = c = next_char();
+ if (c == EOF)
+ _nc_err_abort("Premature EOF");
+
+ if (! (is7bits(ch) && isprint(ch))) {
+ _nc_warning("Illegal ^ character - %s",
+ _tracechar((unsigned char)ch));
+ }
+ if (ch == '?') {
+ *(ptr++) = '\177';
+ } else {
+ if ((ch &= 037) == 0)
+ ch = 128;
+ *(ptr++) = (char)(ch);
+ }
+ }
+ else if (ch == '\\') {
+ ch = c = next_char();
+ if (c == EOF)
+ _nc_err_abort("Premature EOF");
+
+ if (ch >= '0' && ch <= '7') {
+ number = ch - '0';
+ for (i=0; i < 2; i++) {
+ ch = c = next_char();
+ if (c == EOF)
+ _nc_err_abort("Premature EOF");
+
+ if (c < '0' || c > '7') {
+ if (isdigit(c)) {
+ _nc_warning("Non-octal digit `%c' in \\ sequence", c);
+ /* allow the digit; it'll do less harm */
+ } else {
+ push_back((char)c);
+ break;
+ }
+ }
+
+ number = number * 8 + c - '0';
+ }
+
+ if (number == 0)
+ number = 0200;
+ *(ptr++) = (char) number;
+ } else {
+ switch (c) {
+ case 'E':
+ case 'e': *(ptr++) = '\033'; break;
+
+ case 'a': *(ptr++) = '\007'; break;
+
+ case 'l':
+ case 'n': *(ptr++) = '\n'; break;
+
+ case 'r': *(ptr++) = '\r'; break;
+
+ case 'b': *(ptr++) = '\010'; break;
+
+ case 's': *(ptr++) = ' '; break;
+
+ case 'f': *(ptr++) = '\014'; break;
+
+ case 't': *(ptr++) = '\t'; break;
+
+ case '\\': *(ptr++) = '\\'; break;
+
+ case '^': *(ptr++) = '^'; break;
+
+ case ',': *(ptr++) = ','; break;
+
+ case ':': *(ptr++) = ':'; break;
+
+ case '\n':
+ continue;
+
+ default:
+ _nc_warning("Illegal character %s in \\ sequence",
+ _tracechar((unsigned char)ch));
+ *(ptr++) = (char)ch;
+ } /* endswitch (ch) */
+ } /* endelse (ch < '0' || ch > '7') */
+ } /* end else if (ch == '\\') */
+ else if (ch == '\n' && (_nc_syntax == SYN_TERMINFO)) {
+ /* newlines embedded in a terminfo string are ignored */
+ ignored = TRUE;
+ } else {
+ *(ptr++) = (char)ch;
+ }
+
+ if (!ignored) {
+ last_ch = ch;
+ count ++;
+ }
+ ignored = FALSE;
+
+ if (count > MAXCAPLEN)
+ _nc_warning("Very long string found. Missing separator?");
+ } /* end while */
+
+ *ptr = '\0';
+
+ return(ch);
+}
+
+/*
+ * _nc_push_token()
+ *
+ * Push a token of given type so that it will be reread by the next
+ * get_token() call.
+ */
+
+void _nc_push_token(int tokclass)
+{
+ /*
+ * This implementation is kind of bogus, it will fail if we ever do
+ * more than one pushback at a time between get_token() calls. It
+ * relies on the fact that curr_tok is static storage that nothing
+ * but get_token() touches.
+ */
+ pushtype = tokclass;
+ _nc_get_type(pushname);
+
+ DEBUG(3, ("pushing token: `%s', class %d",
+ _nc_curr_token.tk_name, pushtype));
+}
+
+/*
+ * Panic mode error recovery - skip everything until a "ch" is found.
+ */
+void _nc_panic_mode(char ch)
+{
+ int c;
+
+ for (;;) {
+ c = next_char();
+ if (c == ch)
+ return;
+ if (c == EOF)
+ return;
+ }
+}
+
+/*****************************************************************************
+ *
+ * Character-stream handling
+ *
+ *****************************************************************************/
+
+#define LEXBUFSIZ 1024
+
+static char *bufptr; /* otherwise, the input buffer pointer */
+static char *bufstart; /* start of buffer so we can compute offsets */
+static FILE *yyin; /* scanner's input file descriptor */
+
+/*
+ * _nc_reset_input()
+ *
+ * Resets the input-reading routines. Used on initialization,
+ * or after a seek has been done. Exactly one argument must be
+ * non-null.
+ */
+
+void _nc_reset_input(FILE *fp, char *buf)
+{
+ pushtype = NO_PUSHBACK;
+ pushname[0] = '\0';
+ yyin = fp;
+ bufstart = bufptr = buf;
+ _nc_curr_file_pos = 0L;
+ if (fp != 0)
+ _nc_curr_line = 0;
+ _nc_curr_col = 0;
+}
+
+/*
+ * int last_char()
+ *
+ * Returns the final nonblank character on the current input buffer
+ */
+static int
+last_char(void)
+{
+ size_t len = strlen(bufptr);
+ while (len--) {
+ if (!isspace(bufptr[len]))
+ return bufptr[len];
+ }
+ return 0;
+}
+
+/*
+ * int next_char()
+ *
+ * Returns the next character in the input stream. Comments and leading
+ * white space are stripped.
+ *
+ * The global state variable 'firstcolumn' is set TRUE if the character
+ * returned is from the first column of the input line.
+ *
+ * The global variable _nc_curr_line is incremented for each new line.
+ * The global variable _nc_curr_file_pos is set to the file offset of the
+ * beginning of each line.
+ */
+
+static int
+next_char(void)
+{
+ if (!yyin)
+ {
+ if (*bufptr == '\0')
+ return(EOF);
+ if (*bufptr == '\n') {
+ _nc_curr_line++;
+ _nc_curr_col = 0;
+ }
+ }
+ else if (!bufptr || !*bufptr)
+ {
+ /*
+ * In theory this could be recoded to do its I/O one
+ * character at a time, saving the buffer space. In
+ * practice, this turns out to be quite hard to get
+ * completely right. Try it and see. If you succeed,
+ * don't forget to hack push_back() correspondingly.
+ */
+ static char line[LEXBUFSIZ];
+ size_t len;
+
+ do {
+ _nc_curr_file_pos = ftell(yyin);
+
+ if ((bufstart = fgets(line, LEXBUFSIZ, yyin)) != NULL) {
+ _nc_curr_line++;
+ _nc_curr_col = 0;
+ }
+ bufptr = bufstart;
+ } while
+ (bufstart != NULL && line[0] == '#');
+
+ if (bufstart == NULL)
+ return (EOF);
+
+ while (iswhite(*bufptr))
+ bufptr++;
+
+ /*
+ * Treat a trailing <cr><lf> the same as a <newline> so we can read
+ * files on OS/2, etc.
+ */
+ if ((len = strlen(bufptr)) > 1) {
+ if (bufptr[len-1] == '\n'
+ && bufptr[len-2] == '\r') {
+ bufptr[len-2] = '\n';
+ bufptr[len-1] = '\0';
+ }
+ }
+ }
+
+ first_column = (bufptr == bufstart);
+
+ _nc_curr_col++;
+ return(*bufptr++);
+}
+
+static void push_back(char c)
+/* push a character back onto the input stream */
+{
+ if (bufptr == bufstart)
+ _nc_syserr_abort("Can't backspace off beginning of line");
+ *--bufptr = c;
+}
+
+static long stream_pos(void)
+/* return our current character position in the input stream */
+{
+ return (yyin ? ftell(yyin) : (bufptr ? bufptr - bufstart : 0));
+}
+
+static bool end_of_stream(void)
+/* are we at end of input? */
+{
+ return ((yyin ? feof(yyin) : (bufptr && *bufptr == '\0'))
+ ? TRUE : FALSE);
+}
+
+/* comp_scan.c ends here */
diff --git a/lib/libcurses/tinfo/doalloc.c b/lib/libcurses/tinfo/doalloc.c
new file mode 100644
index 00000000000..a4d293e77ec
--- /dev/null
+++ b/lib/libcurses/tinfo/doalloc.c
@@ -0,0 +1,60 @@
+/* $OpenBSD: doalloc.c,v 1.1 1999/01/18 19:10:15 millert 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> 1998 *
+ ****************************************************************************/
+
+
+/*
+ * Wrapper for malloc/realloc. Standard implementations allow realloc with
+ * a null pointer, but older libraries may not (e.g., SunOS).
+ *
+ * Also if realloc fails, we discard the old memory to avoid leaks.
+ */
+
+#include <curses.priv.h>
+
+MODULE_ID("$From: doalloc.c,v 1.2 1998/08/18 22:52:39 Hans-Joachim.Widmaier Exp $")
+
+void *_nc_doalloc(void *oldp, size_t amount)
+{
+ void *newp;
+
+ if (oldp != 0) {
+ if ((newp = realloc(oldp, amount)) == 0) {
+ free(oldp);
+ errno = ENOMEM; /* just in case 'free' reset */
+ }
+ } else {
+ newp = malloc(amount);
+ }
+ return newp;
+}
diff --git a/lib/libcurses/tinfo/getenv_num.c b/lib/libcurses/tinfo/getenv_num.c
new file mode 100644
index 00000000000..21e48bdbafe
--- /dev/null
+++ b/lib/libcurses/tinfo/getenv_num.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: getenv_num.c,v 1.1 1999/01/18 19:10:15 millert 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> 1998 *
+ ****************************************************************************/
+
+/*
+ * getenv_num.c -- obtain a number from the environment
+ */
+
+#include <curses.priv.h>
+
+MODULE_ID("$From: getenv_num.c,v 1.1 1998/09/19 21:30:23 tom Exp $")
+
+int
+_nc_getenv_num(const char *name)
+{
+ char *dst = 0;
+ char *src = getenv(name);
+ long value;
+
+ if ((src == 0)
+ || (value = strtol(src, &dst, 0)) < 0
+ || (dst == src)
+ || (*dst != '\0')
+ || (int)value < value)
+ value = -1;
+
+ return (int) value;
+}
diff --git a/lib/libcurses/tinfo/home_terminfo.c b/lib/libcurses/tinfo/home_terminfo.c
new file mode 100644
index 00000000000..be4feaf927f
--- /dev/null
+++ b/lib/libcurses/tinfo/home_terminfo.c
@@ -0,0 +1,64 @@
+/* $OpenBSD: home_terminfo.c,v 1.1 1999/01/18 19:10:15 millert 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> 1998 *
+ ****************************************************************************/
+
+/*
+ * home_terminfo.c -- return the $HOME/.terminfo string, expanded
+ */
+
+#include <curses.priv.h>
+#include <tic.h>
+
+MODULE_ID("$From: home_terminfo.c,v 1.1 1998/09/19 21:25:03 tom Exp $")
+
+#define my_length (strlen(home) + sizeof(PRIVATE_INFO))
+
+/* ncurses extension...fall back on user's private directory */
+
+char *
+_nc_home_terminfo(void)
+{
+ char *home;
+ static char *temp = 0;
+
+ if (temp == 0) {
+ if ((home = getenv("HOME")) != 0
+ && my_length <= PATH_MAX) {
+ temp = malloc(my_length);
+ if (temp == 0)
+ _nc_err_abort("Out of memory");
+ (void) sprintf(temp, PRIVATE_INFO, home);
+ }
+ }
+ return temp;
+}
diff --git a/lib/libcurses/tinfo/keys.list b/lib/libcurses/tinfo/keys.list
new file mode 100644
index 00000000000..078c4747aa5
--- /dev/null
+++ b/lib/libcurses/tinfo/keys.list
@@ -0,0 +1,159 @@
+# $OpenBSD: keys.list,v 1.1 1999/01/18 19:10:15 millert Exp $
+# $From: keys.list,v 1.5 1997/10/25 21:05:24 tom Exp $
+# The first column is the #define symbol that is in curses.h
+# The second column is the term.h symbol, for terminfo
+# Not all keycodes have corresponding terminfo capabilities.
+KEY_A1 key_a1
+KEY_A3 key_a3
+KEY_B2 key_b2
+KEY_BACKSPACE key_backspace
+KEY_BEG key_beg
+KEY_BREAK
+KEY_BTAB key_btab
+KEY_C1 key_c1
+KEY_C3 key_c3
+KEY_CANCEL key_cancel
+KEY_CATAB key_catab
+KEY_CLEAR key_clear
+KEY_CLOSE key_close
+KEY_COMMAND key_command
+KEY_COPY key_copy
+KEY_CREATE key_create
+KEY_CTAB key_ctab
+KEY_DC key_dc
+KEY_DL key_dl
+KEY_DOWN key_down
+KEY_EIC key_eic
+KEY_END key_end
+KEY_ENTER key_enter
+KEY_EOL key_eol
+KEY_EOS key_eos
+KEY_EXIT key_exit
+KEY_F(0) key_f0
+KEY_F(1) key_f1
+KEY_F(10) key_f10
+KEY_F(11) key_f11
+KEY_F(12) key_f12
+KEY_F(13) key_f13
+KEY_F(14) key_f14
+KEY_F(15) key_f15
+KEY_F(16) key_f16
+KEY_F(17) key_f17
+KEY_F(18) key_f18
+KEY_F(19) key_f19
+KEY_F(2) key_f2
+KEY_F(20) key_f20
+KEY_F(21) key_f21
+KEY_F(22) key_f22
+KEY_F(23) key_f23
+KEY_F(24) key_f24
+KEY_F(25) key_f25
+KEY_F(26) key_f26
+KEY_F(27) key_f27
+KEY_F(28) key_f28
+KEY_F(29) key_f29
+KEY_F(3) key_f3
+KEY_F(30) key_f30
+KEY_F(31) key_f31
+KEY_F(32) key_f32
+KEY_F(33) key_f33
+KEY_F(34) key_f34
+KEY_F(35) key_f35
+KEY_F(36) key_f36
+KEY_F(37) key_f37
+KEY_F(38) key_f38
+KEY_F(39) key_f39
+KEY_F(4) key_f4
+KEY_F(40) key_f40
+KEY_F(41) key_f41
+KEY_F(42) key_f42
+KEY_F(43) key_f43
+KEY_F(44) key_f44
+KEY_F(45) key_f45
+KEY_F(46) key_f46
+KEY_F(47) key_f47
+KEY_F(48) key_f48
+KEY_F(49) key_f49
+KEY_F(5) key_f5
+KEY_F(50) key_f50
+KEY_F(51) key_f51
+KEY_F(52) key_f52
+KEY_F(53) key_f53
+KEY_F(54) key_f54
+KEY_F(55) key_f55
+KEY_F(56) key_f56
+KEY_F(57) key_f57
+KEY_F(58) key_f58
+KEY_F(59) key_f59
+KEY_F(6) key_f6
+KEY_F(60) key_f60
+KEY_F(61) key_f61
+KEY_F(62) key_f62
+KEY_F(63) key_f63
+KEY_F(7) key_f7
+KEY_F(8) key_f8
+KEY_F(9) key_f9
+KEY_FIND key_find
+KEY_HELP key_help
+KEY_HOME key_home
+KEY_IC key_ic
+KEY_IL key_il
+KEY_LEFT key_left
+KEY_LL key_ll
+KEY_MARK key_mark
+KEY_MESSAGE key_message
+KEY_MOUSE key_mouse
+KEY_MOVE key_move
+KEY_NEXT key_next
+KEY_NPAGE key_npage
+KEY_OPEN key_open
+KEY_OPTIONS key_options
+KEY_PPAGE key_ppage
+KEY_PREVIOUS key_previous
+KEY_PRINT key_print
+KEY_REDO key_redo
+KEY_REFERENCE key_reference
+KEY_REFRESH key_refresh
+KEY_REPLACE key_replace
+KEY_RESET
+KEY_RESIZE
+KEY_RESTART key_restart
+KEY_RESUME key_resume
+KEY_RIGHT key_right
+KEY_SAVE key_save
+KEY_SBEG key_sbeg
+KEY_SCANCEL key_scancel
+KEY_SCOMMAND key_scommand
+KEY_SCOPY key_scopy
+KEY_SCREATE key_screate
+KEY_SDC key_sdc
+KEY_SDL key_sdl
+KEY_SELECT key_select
+KEY_SEND key_send
+KEY_SEOL key_seol
+KEY_SEXIT key_sexit
+KEY_SF key_sf
+KEY_SFIND key_sfind
+KEY_SHELP key_shelp
+KEY_SHOME key_shome
+KEY_SIC key_sic
+KEY_SLEFT key_sleft
+KEY_SMESSAGE key_smessage
+KEY_SMOVE key_smove
+KEY_SNEXT key_snext
+KEY_SOPTIONS key_soptions
+KEY_SPREVIOUS key_sprevious
+KEY_SPRINT key_sprint
+KEY_SR key_sr
+KEY_SREDO key_sredo
+KEY_SREPLACE key_sreplace
+KEY_SRESET
+KEY_SRIGHT key_sright
+KEY_SRSUME key_srsume
+KEY_SSAVE key_ssave
+KEY_SSUSPEND key_ssuspend
+KEY_STAB key_stab
+KEY_SUNDO key_sundo
+KEY_SUSPEND key_suspend
+KEY_UNDO key_undo
+KEY_UP key_up
diff --git a/lib/libcurses/tinfo/lib_acs.c b/lib/libcurses/tinfo/lib_acs.c
new file mode 100644
index 00000000000..ffbd078af01
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_acs.c
@@ -0,0 +1,141 @@
+/* $OpenBSD: lib_acs.c,v 1.1 1999/01/18 19:10:16 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+
+#include <curses.priv.h>
+#include <term.h> /* ena_acs, acs_chars */
+
+MODULE_ID("$From: lib_acs.c,v 1.14 1999/01/02 22:37:49 tom Exp $")
+
+chtype acs_map[ACS_LEN];
+
+void init_acs(void)
+{
+ T(("initializing ACS map"));
+
+ /*
+ * Initializations for a UNIX-like multi-terminal environment. Use
+ * ASCII chars and count on the terminfo description to do better.
+ */
+ ACS_ULCORNER = '+'; /* should be upper left corner */
+ ACS_LLCORNER = '+'; /* should be lower left corner */
+ ACS_URCORNER = '+'; /* should be upper right corner */
+ ACS_LRCORNER = '+'; /* should be lower right corner */
+ ACS_RTEE = '+'; /* should be tee pointing left */
+ ACS_LTEE = '+'; /* should be tee pointing right */
+ ACS_BTEE = '+'; /* should be tee pointing up */
+ ACS_TTEE = '+'; /* should be tee pointing down */
+ ACS_HLINE = '-'; /* should be horizontal line */
+ ACS_VLINE = '|'; /* should be vertical line */
+ ACS_PLUS = '+'; /* should be large plus or crossover */
+ ACS_S1 = '~'; /* should be scan line 1 */
+ ACS_S9 = '_'; /* should be scan line 9 */
+ ACS_DIAMOND = '+'; /* should be diamond */
+ ACS_CKBOARD = ':'; /* should be checker board (stipple) */
+ ACS_DEGREE = '\''; /* should be degree symbol */
+ ACS_PLMINUS = '#'; /* should be plus/minus */
+ ACS_BULLET = 'o'; /* should be bullet */
+ ACS_LARROW = '<'; /* should be arrow pointing left */
+ ACS_RARROW = '>'; /* should be arrow pointing right */
+ ACS_DARROW = 'v'; /* should be arrow pointing down */
+ ACS_UARROW = '^'; /* should be arrow pointing up */
+ ACS_BOARD = '#'; /* should be board of squares */
+ ACS_LANTERN = '#'; /* should be lantern symbol */
+ ACS_BLOCK = '#'; /* should be solid square block */
+ /* these defaults were invented for ncurses */
+ ACS_S3 = '-'; /* should be scan line 3 */
+ ACS_S7 = '-'; /* should be scan line 7 */
+ ACS_LEQUAL = '<'; /* should be less-than-or-equal-to */
+ ACS_GEQUAL = '>'; /* should be greater-than-or-equal-to */
+ ACS_PI = '*'; /* should be greek pi */
+ ACS_NEQUAL = '!'; /* should be not-equal */
+ ACS_STERLING = 'f'; /* should be pound-sterling symbol */
+
+ if (ena_acs != NULL)
+ {
+ TPUTS_TRACE("ena_acs");
+ putp(ena_acs);
+ }
+
+#define ALTCHAR(c) ((chtype)(((unsigned char)(c)) | A_ALTCHARSET))
+
+ if (acs_chars != NULL) {
+ size_t i = 0;
+ size_t length = strlen(acs_chars);
+
+ while (i < length)
+ switch (acs_chars[i]) {
+ case 'l':case 'm':case 'k':case 'j':
+ case 'u':case 't':case 'v':case 'w':
+ case 'q':case 'x':case 'n':case 'o':
+ case 's':case '`':case 'a':case 'f':
+ case 'g':case '~':case ',':case '+':
+ case '.':case '-':case 'h':case 'i':
+ case '0':case 'p':case 'r':case 'y':
+ case 'z':case '{':case '|':case '}':
+ acs_map[(unsigned int)acs_chars[i]] =
+ ALTCHAR(acs_chars[i+1]);
+ i++;
+ /* FALLTHRU */
+ default:
+ i++;
+ break;
+ }
+ }
+#ifdef TRACE
+ /* Show the equivalent mapping, noting if it does not match the
+ * given attribute, whether by re-ordering or duplication.
+ */
+ if (_nc_tracing & TRACE_CALLS) {
+ size_t n, m;
+ char show[SIZEOF(acs_map) + 1];
+ for (n = 1, m = 0; n < SIZEOF(acs_map); n++) {
+ if (acs_map[n] != 0) {
+ show[m++] = (char)n;
+ show[m++] = TextOf(acs_map[n]);
+ }
+ }
+ show[m] = 0;
+ _tracef("%s acs_chars %s",
+ (acs_chars == NULL)
+ ? "NULL"
+ : (strcmp(acs_chars, show)
+ ? "DIFF"
+ : "SAME"),
+ _nc_visbuf(show));
+ }
+#endif /* TRACE */
+}
diff --git a/lib/libcurses/tinfo/lib_baudrate.c b/lib/libcurses/tinfo/lib_baudrate.c
new file mode 100644
index 00000000000..97b5eb7c5be
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_baudrate.c
@@ -0,0 +1,171 @@
+/* $OpenBSD: lib_baudrate.c,v 1.1 1999/01/18 19:10:16 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * lib_baudrate.c
+ *
+ */
+
+#include <curses.priv.h>
+#include <term.h> /* cur_term, pad_char */
+#include <termcap.h> /* ospeed */
+
+MODULE_ID("$From: lib_baudrate.c,v 1.14 1999/01/03 01:31:45 tom Exp $")
+
+/*
+ * int
+ * baudrate()
+ *
+ * Returns the current terminal's baud rate.
+ *
+ */
+
+struct speed {
+ speed_t s;
+ int sp;
+};
+
+static struct speed const speeds[] = {
+ {B0, 0},
+ {B50, 50},
+ {B75, 75},
+ {B110, 110},
+ {B134, 134},
+ {B150, 150},
+ {B200, 200},
+ {B300, 300},
+ {B600, 600},
+ {B1200, 1200},
+ {B1800, 1800},
+ {B2400, 2400},
+ {B4800, 4800},
+ {B9600, 9600},
+#ifdef B19200
+ {B19200, 19200},
+#else
+#ifdef EXTA
+ {EXTA, 19200},
+#endif
+#endif
+#ifdef B38400
+ {B38400, 38400},
+#else
+#ifdef EXTB
+ {EXTB, 38400},
+#endif
+#endif
+#ifdef B57600
+ {B57600, 57600},
+#endif
+#ifdef B115200
+ {B115200, 115200},
+#endif
+#ifdef B230400
+ {B230400, 230400},
+#endif
+#ifdef B460800
+ {B460800, 460800},
+#endif
+};
+
+int _nc_baudrate(int OSpeed)
+{
+ int result = ERR;
+ unsigned i;
+
+ if (OSpeed >= 0) {
+ for (i = 0; i < SIZEOF(speeds); i++) {
+ if (speeds[i].s == (speed_t)OSpeed) {
+ result = speeds[i].sp;
+ break;
+ }
+ }
+ }
+ return (result);
+}
+
+
+int _nc_ospeed(int BaudRate)
+{
+ speed_t result = 1;
+ unsigned i;
+
+ if (BaudRate >= 0) {
+ for (i = 0; i < SIZEOF(speeds); i++) {
+ if (speeds[i].sp == BaudRate) {
+ result = speeds[i].s;
+ break;
+ }
+ }
+ }
+ return (result);
+}
+
+int
+baudrate(void)
+{
+int result;
+
+ T((T_CALLED("baudrate()")));
+
+ /*
+ * In debugging, allow the environment symbol to override when we're
+ * redirecting to a file, so we can construct repeatable test-cases
+ * that take into account costs that depend on baudrate.
+ */
+#ifdef TRACE
+ if (SP && !isatty(fileno(SP->_ofp))
+ && getenv("BAUDRATE") != 0) {
+ int ret;
+ if ((ret = _nc_getenv_num("BAUDRATE")) <= 0)
+ ret = 9600;
+ ospeed = _nc_ospeed(ret);
+ returnCode(ret);
+ }
+ else
+#endif
+
+#ifdef TERMIOS
+ ospeed = cfgetospeed(&cur_term->Nttyb);
+#else
+ ospeed = cur_term->Nttyb.sg_ospeed;
+#endif
+ result = _nc_baudrate(ospeed);
+ if (cur_term != 0)
+ cur_term->_baudrate = result;
+
+ returnCode(result);
+}
diff --git a/lib/libcurses/tinfo/lib_cur_term.c b/lib/libcurses/tinfo/lib_cur_term.c
new file mode 100644
index 00000000000..0429da48316
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_cur_term.c
@@ -0,0 +1,73 @@
+/* $OpenBSD: lib_cur_term.c,v 1.1 1999/01/18 19:10:17 millert 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> 1997 *
+ ****************************************************************************/
+/*
+ * Module that "owns" the 'cur_term' variable:
+ *
+ * TERMINAL *set_curterm(TERMINAL *)
+ * int del_curterm(TERMINAL *)
+ */
+
+#include <curses.priv.h>
+#include <term.h> /* TTY, cur_term */
+#include <termcap.h> /* ospeed */
+
+MODULE_ID("$From: lib_cur_term.c,v 1.6 1999/01/10 00:48:44 tom Exp $")
+
+TERMINAL *cur_term;
+
+TERMINAL *set_curterm(TERMINAL *term)
+{
+ TERMINAL *oldterm = cur_term;
+
+ if ((cur_term = term) != 0) {
+ ospeed = _nc_ospeed(cur_term->_baudrate);
+ PC = (pad_char != NULL) ? pad_char[0] : 0;
+ }
+ return oldterm;
+}
+
+int del_curterm(TERMINAL *term)
+{
+ T((T_CALLED("del_curterm(%p)"), term));
+
+ if (term != 0) {
+ FreeIfNeeded(term->type.str_table);
+ FreeIfNeeded(term->type.term_names);
+ free(term);
+ if (term == cur_term)
+ cur_term = 0;
+ returnCode(OK);
+ }
+ returnCode(ERR);
+}
diff --git a/lib/libcurses/tinfo/lib_data.c b/lib/libcurses/tinfo/lib_data.c
new file mode 100644
index 00000000000..9fad1c97b3e
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_data.c
@@ -0,0 +1,86 @@
+/* $OpenBSD: lib_data.c,v 1.1 1999/01/18 19:10:17 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+/*
+** lib_data.c
+**
+** Common data that may/may not be allocated, but is referenced globally
+**
+*/
+
+#include <curses.priv.h>
+
+MODULE_ID("$From: lib_data.c,v 1.13 1998/02/11 12:14:00 tom Exp $")
+
+/*
+ * OS/2's native linker complains if we don't initialize public data when
+ * constructing a dll (reported by J.J.G.Ripoll).
+ */
+WINDOW *stdscr = 0;
+WINDOW *curscr = 0;
+WINDOW *newscr = 0;
+
+SCREEN *_nc_screen_chain = 0;
+
+/*
+ * The variable 'SP' will be defined as a function on systems that cannot link
+ * data-only modules, since it is used in a lot of places within ncurses and we
+ * cannot guarantee that any application will use any particular function. We
+ * put the WINDOW variables in this module, because it appears that any
+ * application that uses them will also use 'SP'.
+ *
+ * This module intentionally does not reference other ncurses modules, to avoid
+ * module coupling that increases the size of the executable.
+ */
+#if BROKEN_LINKER
+static SCREEN *my_screen;
+
+SCREEN *_nc_screen(void)
+{
+ return my_screen;
+}
+
+int _nc_alloc_screen(void)
+{
+ return ((my_screen = typeCalloc(SCREEN, 1)) != 0);
+}
+
+void _nc_set_screen(SCREEN *sp)
+{
+ my_screen = sp;
+}
+#else
+SCREEN *SP;
+#endif
diff --git a/lib/libcurses/tinfo/lib_has_cap.c b/lib/libcurses/tinfo/lib_has_cap.c
new file mode 100644
index 00000000000..de5ebb5c133
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_has_cap.c
@@ -0,0 +1,65 @@
+/* $OpenBSD: lib_has_cap.c,v 1.1 1999/01/18 19:10:17 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+** lib_has_cap.c
+**
+** The routines to query terminal capabilities
+**
+*/
+
+#include <curses.priv.h>
+
+#include <term.h>
+
+MODULE_ID("$From: lib_has_cap.c,v 1.1 1998/10/23 15:32:21 tom Exp $")
+
+bool has_ic(void)
+{
+ T((T_CALLED("has_ic()")));
+ returnCode(cur_term &&
+ (insert_character || parm_ich
+ || (enter_insert_mode && exit_insert_mode))
+ && (delete_character || parm_dch));
+}
+
+bool has_il(void)
+{
+ T((T_CALLED("has_il()")));
+ returnCode(cur_term
+ && (insert_line || parm_insert_line)
+ && (delete_line || parm_delete_line));
+}
diff --git a/lib/libcurses/tinfo/lib_kernel.c b/lib/libcurses/tinfo/lib_kernel.c
new file mode 100644
index 00000000000..16cb06afe9d
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_kernel.c
@@ -0,0 +1,132 @@
+/* $OpenBSD: lib_kernel.c,v 1.1 1999/01/18 19:10:17 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * lib_kernel.c
+ *
+ * Misc. low-level routines:
+ * erasechar()
+ * killchar()
+ * flushinp()
+ *
+ * The baudrate() and delay_output() functions could logically live here,
+ * but are in other modules to reduce the static-link size of programs
+ * that use only these facilities.
+ */
+
+#include <curses.priv.h>
+#include <term.h> /* cur_term */
+
+MODULE_ID("$From: lib_kernel.c,v 1.19 1998/12/20 00:18:45 tom Exp $")
+
+/*
+ * erasechar()
+ *
+ * Return erase character as given in cur_term->Ottyb.
+ *
+ */
+
+char
+erasechar(void)
+{
+ T((T_CALLED("erasechar()")));
+
+ if (cur_term != 0) {
+#ifdef TERMIOS
+ returnCode(cur_term->Ottyb.c_cc[VERASE]);
+#else
+ returnCode(cur_term->Ottyb.sg_erase);
+#endif
+ }
+ returnCode(ERR);
+}
+
+
+
+/*
+ * killchar()
+ *
+ * Return kill character as given in cur_term->Ottyb.
+ *
+ */
+
+char
+killchar(void)
+{
+ T((T_CALLED("killchar()")));
+
+ if (cur_term != 0) {
+#ifdef TERMIOS
+ returnCode(cur_term->Ottyb.c_cc[VKILL]);
+#else
+ returnCode(cur_term->Ottyb.sg_kill);
+#endif
+ }
+ returnCode(ERR);
+}
+
+
+
+/*
+ * flushinp()
+ *
+ * Flush any input on cur_term->Filedes
+ *
+ */
+
+int flushinp(void)
+{
+ T((T_CALLED("flushinp()")));
+
+ if (cur_term != 0) {
+#ifdef TERMIOS
+ tcflush(cur_term->Filedes, TCIFLUSH);
+#else
+ errno = 0;
+ do {
+ ioctl(cur_term->Filedes, TIOCFLUSH, 0);
+ } while
+ (errno == EINTR);
+#endif
+ if (SP) {
+ SP->_fifohead = -1;
+ SP->_fifotail = 0;
+ SP->_fifopeek = 0;
+ }
+ returnCode(OK);
+ }
+ returnCode(ERR);
+}
diff --git a/lib/libcurses/tinfo/lib_longname.c b/lib/libcurses/tinfo/lib_longname.c
new file mode 100644
index 00000000000..558453a69bb
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_longname.c
@@ -0,0 +1,60 @@
+/* $OpenBSD: lib_longname.c,v 1.1 1999/01/18 19:10:18 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+** lib_longname.c
+**
+** The routine longname().
+**
+*/
+
+#include <curses.priv.h>
+
+MODULE_ID("$From: lib_longname.c,v 1.7 1999/01/03 01:47:45 tom Exp $")
+
+char *
+longname(void)
+{
+char *ptr;
+
+ T((T_CALLED("longname()")));
+
+ for (ptr = ttytype + strlen(ttytype); ptr > ttytype; ptr--)
+ if (*ptr == '|')
+ returnPtr(ptr + 1);
+
+ returnPtr(ttytype);
+}
diff --git a/lib/libcurses/tinfo/lib_napms.c b/lib/libcurses/tinfo/lib_napms.c
new file mode 100644
index 00000000000..d5dd07be396
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_napms.c
@@ -0,0 +1,90 @@
+/* $OpenBSD: lib_napms.c,v 1.1 1999/01/18 19:10:18 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * lib_napms.c
+ *
+ * The routine napms.
+ *
+ */
+
+#include <curses.priv.h>
+
+#if USE_FUNC_POLL
+#include <stropts.h>
+#include <poll.h>
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#elif HAVE_SELECT
+#if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT
+#include <sys/time.h>
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#endif
+
+MODULE_ID("$From: lib_napms.c,v 1.4 1998/02/13 10:24:54 jbuhler Exp $")
+
+int napms(int ms)
+{
+ T((T_CALLED("napms(%d)"), ms));
+
+#if HAVE_NANOSLEEP
+ {
+ struct timespec ts;
+ ts.tv_sec = ms / 1000;
+ ts.tv_nsec = (ms % 1000) * 1000000;
+ nanosleep(&ts, NULL);
+ }
+#elif HAVE_USLEEP
+ usleep(1000*(unsigned)ms);
+#elif USE_FUNC_POLL
+ {
+ struct pollfd fds[1];
+ poll(fds, 0, ms);
+ }
+#elif HAVE_SELECT
+ {
+ struct timeval tval;
+ tval.tv_sec = ms / 1000;
+ tval.tv_usec = (ms % 1000) * 1000;
+ select(0, NULL, NULL, NULL, &tval);
+ }
+#endif
+ returnCode(OK);
+}
diff --git a/lib/libcurses/tinfo/lib_options.c b/lib/libcurses/tinfo/lib_options.c
new file mode 100644
index 00000000000..3ab600ab653
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_options.c
@@ -0,0 +1,291 @@
+/* $OpenBSD: lib_options.c,v 1.1 1999/01/18 19:10:18 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+** lib_options.c
+**
+** The routines to handle option setting.
+**
+*/
+
+#include <curses.priv.h>
+
+#include <term.h> /* keypad_xmit, keypad_local, meta_on, meta_off */
+ /* cursor_visible,cursor_normal,cursor_invisible */
+
+MODULE_ID("$From: lib_options.c,v 1.32 1998/12/19 23:09:50 tom Exp $")
+
+int idlok(WINDOW *win, bool flag)
+{
+ T((T_CALLED("idlok(%p,%d)"), win, flag));
+
+ if (win) {
+ _nc_idlok = win->_idlok = flag && (has_il() || change_scroll_region);
+ returnCode(OK);
+ }
+ else
+ returnCode(ERR);
+}
+
+
+void idcok(WINDOW *win, bool flag)
+{
+ T((T_CALLED("idcok(%p,%d)"), win, flag));
+
+ if (win)
+ _nc_idcok = win->_idcok = flag && has_ic();
+
+ returnVoid;
+}
+
+int halfdelay(int t)
+{
+ T((T_CALLED("halfdelay(%d)"), t));
+
+ if (t < 1 || t > 255)
+ returnCode(ERR);
+
+ cbreak();
+ SP->_cbreak = t+1;
+ returnCode(OK);
+}
+
+int nodelay(WINDOW *win, bool flag)
+{
+ T((T_CALLED("nodelay(%p,%d)"), win, flag));
+
+ if (win) {
+ if (flag == TRUE)
+ win->_delay = 0;
+ else win->_delay = -1;
+ returnCode(OK);
+ }
+ else
+ returnCode(ERR);
+}
+
+int notimeout(WINDOW *win, bool f)
+{
+ T((T_CALLED("notimout(%p,%d)"), win, f));
+
+ if (win) {
+ win->_notimeout = f;
+ returnCode(OK);
+ }
+ else
+ returnCode(ERR);
+}
+
+void wtimeout(WINDOW *win, int delay)
+{
+ T((T_CALLED("wtimeout(%p,%d)"), win, delay));
+
+ if (win) {
+ win->_delay = delay;
+ }
+}
+
+int keypad(WINDOW *win, bool flag)
+{
+ T((T_CALLED("keypad(%p,%d)"), win, flag));
+
+ if (win) {
+ win->_use_keypad = flag;
+ returnCode(_nc_keypad(flag));
+ }
+ else
+ returnCode(ERR);
+}
+
+
+int meta(WINDOW *win GCC_UNUSED, bool flag)
+{
+ /* Ok, we stay relaxed and don't signal an error if win is NULL */
+ T((T_CALLED("meta(%p,%d)"), win, flag));
+
+ SP->_use_meta = flag;
+
+ if (flag && meta_on)
+ {
+ TPUTS_TRACE("meta_on");
+ putp(meta_on);
+ }
+ else if (! flag && meta_off)
+ {
+ TPUTS_TRACE("meta_off");
+ putp(meta_off);
+ }
+ returnCode(OK);
+}
+
+/* curs_set() moved here to narrow the kernel interface */
+
+int curs_set(int vis)
+{
+int cursor = SP->_cursor;
+
+ T((T_CALLED("curs_set(%d)"), vis));
+
+ if (vis < 0 || vis > 2)
+ returnCode(ERR);
+
+ if (vis == cursor)
+ returnCode(cursor);
+
+ switch(vis) {
+ case 2:
+ if (cursor_visible)
+ {
+ TPUTS_TRACE("cursor_visible");
+ putp(cursor_visible);
+ }
+ else
+ returnCode(ERR);
+ break;
+ case 1:
+ if (cursor_normal)
+ {
+ TPUTS_TRACE("cursor_normal");
+ putp(cursor_normal);
+ }
+ else
+ returnCode(ERR);
+ break;
+ case 0:
+ if (cursor_invisible)
+ {
+ TPUTS_TRACE("cursor_invisible");
+ putp(cursor_invisible);
+ }
+ else
+ returnCode(ERR);
+ break;
+ }
+ SP->_cursor = vis;
+ (void) fflush(SP->_ofp);
+
+ returnCode(cursor==-1 ? 1 : cursor);
+}
+
+int typeahead(int fd)
+{
+ T((T_CALLED("typeahead(%d)"), fd));
+ SP->_checkfd = fd;
+ returnCode(OK);
+}
+
+/*
+** has_key()
+**
+** Return TRUE if the current terminal has the given key
+**
+*/
+
+#ifdef NCURSES_EXT_FUNCS
+static int has_key_internal(int keycode, struct tries *tp)
+{
+ if (tp == 0)
+ return(FALSE);
+ else if (tp->value == keycode)
+ return(TRUE);
+ else
+ return(has_key_internal(keycode, tp->child)
+ || has_key_internal(keycode, tp->sibling));
+}
+
+int has_key(int keycode)
+{
+ T((T_CALLED("has_key(%d)"), keycode));
+ returnCode(has_key_internal(keycode, SP->_keytry));
+}
+#endif /* NCURSES_EXT_FUNCS */
+
+/*
+** init_keytry()
+**
+** Construct the try for the current terminal's keypad keys.
+**
+*/
+
+static void init_keytry(void)
+{
+/* LINT_PREPRO
+#if 0*/
+#include <keys.tries>
+/* LINT_PREPRO
+#endif*/
+ size_t n;
+
+ /* The SP->_keytry value is initialized in newterm(), where the SP
+ * structure is created, because we can not tell where keypad() or
+ * mouse_activate() (which will call keyok()) are first called.
+ */
+
+ for (n = 0; n < SIZEOF(table); n++)
+ if (table[n].offset < STRCOUNT)
+ _nc_add_to_try(&(SP->_keytry),
+ CUR Strings[table[n].offset],
+ table[n].code);
+}
+
+/* Turn the keypad on/off
+ *
+ * Note: we flush the output because changing this mode causes some terminals
+ * to emit different escape sequences for cursor and keypad keys. If we don't
+ * flush, then the next wgetch may get the escape sequence that corresponds to
+ * the terminal state _before_ switching modes.
+ */
+int _nc_keypad(bool flag)
+{
+ if (flag && keypad_xmit)
+ {
+ TPUTS_TRACE("keypad_xmit");
+ putp(keypad_xmit);
+ (void) fflush(SP->_ofp);
+ }
+ else if (! flag && keypad_local)
+ {
+ TPUTS_TRACE("keypad_local");
+ putp(keypad_local);
+ (void) fflush(SP->_ofp);
+ }
+
+ if (!SP->_tried) {
+ init_keytry();
+ SP->_tried = TRUE;
+ }
+ return(OK);
+}
diff --git a/lib/libcurses/tinfo/lib_print.c b/lib/libcurses/tinfo/lib_print.c
new file mode 100644
index 00000000000..2d872a665ed
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_print.c
@@ -0,0 +1,98 @@
+/* $OpenBSD: lib_print.c,v 1.1 1999/01/18 19:10:19 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+#include <curses.priv.h>
+
+#include <term.h>
+
+MODULE_ID("$From: lib_print.c,v 1.10 1998/10/13 14:47:53 Alexander.V.Lukyanov Exp $")
+
+int mcprint(char *data, int len)
+/* ship binary character data to the printer via mc4/mc5/mc5p */
+{
+ char *mybuf, *switchon;
+ size_t onsize, offsize, res;
+
+ errno = 0;
+ if (!cur_term || (!prtr_non && (!prtr_on || !prtr_off)))
+ {
+ errno = ENODEV;
+ return(ERR);
+ }
+
+ if (prtr_non)
+ {
+ switchon = tparm(prtr_non, len);
+ onsize = strlen(switchon);
+ offsize = 0;
+ }
+ else
+ {
+ switchon = prtr_on;
+ onsize = strlen(prtr_on);
+ offsize = strlen(prtr_off);
+ }
+
+ if ((mybuf = malloc(onsize + len + offsize + 1)) == (char *)NULL)
+ {
+ errno = ENOMEM;
+ return(ERR);
+ }
+
+ (void) strcpy(mybuf, switchon);
+ memcpy(mybuf + onsize, data, len);
+ if (offsize)
+ (void) strcpy(mybuf + onsize + len, prtr_off);
+
+ /*
+ * We're relying on the atomicity of UNIX writes here. The
+ * danger is that output from a refresh() might get interspersed
+ * with the printer data after the write call returns but before the
+ * data has actually been shipped to the terminal. If the write(2)
+ * operation is truly atomic we're protected from this.
+ */
+ res = write(cur_term->Filedes, mybuf, onsize + len + offsize);
+
+ /*
+ * By giving up our scheduler slot here we increase the odds that the
+ * kernel will ship the contiguous clist items from the last write
+ * immediately.
+ */
+ (void) sleep(0);
+
+ free(mybuf);
+ return(res);
+}
diff --git a/lib/libcurses/tinfo/lib_raw.c b/lib/libcurses/tinfo/lib_raw.c
new file mode 100644
index 00000000000..a9280a57edb
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_raw.c
@@ -0,0 +1,235 @@
+/* $OpenBSD: lib_raw.c,v 1.1 1999/01/18 19:10:19 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * raw.c
+ *
+ * Routines:
+ * raw()
+ * cbreak()
+ * noraw()
+ * nocbreak()
+ * qiflush()
+ * noqiflush()
+ * intrflush()
+ *
+ */
+
+#include <curses.priv.h>
+#include <term.h> /* cur_term */
+
+MODULE_ID("$From: lib_raw.c,v 1.2 1998/12/20 00:42:58 tom Exp $")
+
+#if defined(SVR4_TERMIO) && !defined(_POSIX_SOURCE)
+#define _POSIX_SOURCE
+#endif
+
+#if HAVE_SYS_TERMIO_H
+#include <sys/termio.h> /* needed for ISC */
+#endif
+
+#ifdef __EMX__
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#define COOKED_INPUT (IXON|BRKINT|PARMRK)
+
+#ifdef TRACE
+#define BEFORE(N) if (_nc_tracing&TRACE_BITS) _tracef("%s before bits: %s", N, _nc_tracebits())
+#define AFTER(N) if (_nc_tracing&TRACE_BITS) _tracef("%s after bits: %s", N, _nc_tracebits())
+#else
+#define BEFORE(s)
+#define AFTER(s)
+#endif /* TRACE */
+
+int raw(void)
+{
+ T((T_CALLED("raw()")));
+ if (SP != 0 && cur_term != 0) {
+
+ SP->_raw = TRUE;
+ SP->_cbreak = TRUE;
+
+#ifdef __EMX__
+ setmode(SP->_ifd, O_BINARY);
+#endif
+
+#ifdef TERMIOS
+ BEFORE("raw");
+ cur_term->Nttyb.c_lflag &= ~(ICANON|ISIG);
+ cur_term->Nttyb.c_iflag &= ~(COOKED_INPUT);
+ cur_term->Nttyb.c_cc[VMIN] = 1;
+ cur_term->Nttyb.c_cc[VTIME] = 0;
+ AFTER("raw");
+#else
+ cur_term->Nttyb.sg_flags |= RAW;
+#endif
+ returnCode(_nc_set_tty_mode(&cur_term->Nttyb));
+ }
+ returnCode(ERR);
+}
+
+int cbreak(void)
+{
+ T((T_CALLED("cbreak()")));
+
+ SP->_cbreak = TRUE;
+
+#ifdef __EMX__
+ setmode(SP->_ifd, O_BINARY);
+#endif
+
+#ifdef TERMIOS
+ BEFORE("cbreak");
+ cur_term->Nttyb.c_lflag &= ~ICANON;
+ cur_term->Nttyb.c_iflag &= ~ICRNL;
+ cur_term->Nttyb.c_lflag |= ISIG;
+ cur_term->Nttyb.c_cc[VMIN] = 1;
+ cur_term->Nttyb.c_cc[VTIME] = 0;
+ AFTER("cbreak");
+#else
+ cur_term->Nttyb.sg_flags |= CBREAK;
+#endif
+ returnCode(_nc_set_tty_mode( &cur_term->Nttyb));
+}
+
+void qiflush(void)
+{
+ T((T_CALLED("qiflush()")));
+
+ /*
+ * Note: this implementation may be wrong. See the comment under
+ * intrflush().
+ */
+
+#ifdef TERMIOS
+ BEFORE("qiflush");
+ cur_term->Nttyb.c_lflag &= ~(NOFLSH);
+ AFTER("qiflush");
+ (void)_nc_set_tty_mode( &cur_term->Nttyb);
+ returnVoid;
+#endif
+}
+
+
+int noraw(void)
+{
+ T((T_CALLED("noraw()")));
+
+ SP->_raw = FALSE;
+ SP->_cbreak = FALSE;
+
+#ifdef __EMX__
+ setmode(SP->_ifd, O_TEXT);
+#endif
+
+#ifdef TERMIOS
+ BEFORE("noraw");
+ cur_term->Nttyb.c_lflag |= ISIG|ICANON;
+ cur_term->Nttyb.c_iflag |= COOKED_INPUT;
+ AFTER("noraw");
+#else
+ cur_term->Nttyb.sg_flags &= ~(RAW|CBREAK);
+#endif
+ returnCode(_nc_set_tty_mode( &cur_term->Nttyb));
+}
+
+
+int nocbreak(void)
+{
+ T((T_CALLED("nocbreak()")));
+
+ SP->_cbreak = FALSE;
+
+#ifdef __EMX__
+ setmode(SP->_ifd, O_TEXT);
+#endif
+
+#ifdef TERMIOS
+ BEFORE("nocbreak");
+ cur_term->Nttyb.c_lflag |= ICANON;
+ cur_term->Nttyb.c_iflag |= ICRNL;
+ AFTER("nocbreak");
+#else
+ cur_term->Nttyb.sg_flags &= ~CBREAK;
+#endif
+ returnCode(_nc_set_tty_mode( &cur_term->Nttyb));
+}
+
+void noqiflush(void)
+{
+ T((T_CALLED("noqiflush()")));
+
+ /*
+ * Note: this implementation may be wrong. See the comment under
+ * intrflush().
+ */
+
+#ifdef TERMIOS
+ BEFORE("noqiflush");
+ cur_term->Nttyb.c_lflag |= NOFLSH;
+ AFTER("noqiflush");
+ (void)_nc_set_tty_mode( &cur_term->Nttyb);
+ returnVoid;
+#endif
+}
+
+int intrflush(WINDOW *win GCC_UNUSED, bool flag)
+{
+ T((T_CALLED("intrflush(%d)"), flag));
+
+ /*
+ * This call does the same thing as the qiflush()/noqiflush()
+ * pair. We know for certain that SVr3 intrflush() tweaks the
+ * NOFLSH bit; on the other hand, the match (in the SVr4 man
+ * pages) between the language describing NOFLSH in termio(7)
+ * and the language describing qiflush()/noqiflush() in
+ * curs_inopts(3x) is too exact to be coincidence.
+ */
+
+#ifdef TERMIOS
+ BEFORE("intrflush");
+ if (flag)
+ cur_term->Nttyb.c_lflag &= ~(NOFLSH);
+ else
+ cur_term->Nttyb.c_lflag |= (NOFLSH);
+ AFTER("intrflush");
+ returnCode(_nc_set_tty_mode( &cur_term->Nttyb));
+#else
+ returnCode(ERR);
+#endif
+}
diff --git a/lib/libcurses/tinfo/lib_setup.c b/lib/libcurses/tinfo/lib_setup.c
new file mode 100644
index 00000000000..289309d4f65
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_setup.c
@@ -0,0 +1,405 @@
+/* $OpenBSD: lib_setup.c,v 1.1 1999/01/18 19:10:19 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * Terminal setup routines common to termcap and terminfo:
+ *
+ * use_env(bool)
+ * setupterm(char *, int, int *)
+ */
+
+#include <curses.priv.h>
+#include <tic.h> /* for MAX_NAME_SIZE */
+
+#if defined(SVR4_TERMIO) && !defined(_POSIX_SOURCE)
+#define _POSIX_SOURCE
+#endif
+
+#include <term.h> /* lines, columns, cur_term */
+
+MODULE_ID("$From: lib_setup.c,v 1.48 1999/01/02 23:11:56 tom Exp $")
+
+/****************************************************************************
+ *
+ * Terminal size computation
+ *
+ ****************************************************************************/
+
+#if HAVE_SIZECHANGE
+# if !defined(sun) || !TERMIOS
+# if HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+# endif
+# endif
+#endif
+
+#if NEED_PTEM_H
+ /* On SCO, they neglected to define struct winsize in termios.h -- it's only
+ * in termio.h and ptem.h (the former conflicts with other definitions).
+ */
+# include <sys/stream.h>
+# include <sys/ptem.h>
+#endif
+
+/*
+ * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
+ * Solaris, IRIX) define TIOCGWINSZ and struct winsize.
+ */
+#ifdef TIOCGSIZE
+# define IOCTL_WINSIZE TIOCGSIZE
+# define STRUCT_WINSIZE struct ttysize
+# define WINSIZE_ROWS(n) (int)n.ts_lines
+# define WINSIZE_COLS(n) (int)n.ts_cols
+#else
+# ifdef TIOCGWINSZ
+# define IOCTL_WINSIZE TIOCGWINSZ
+# define STRUCT_WINSIZE struct winsize
+# define WINSIZE_ROWS(n) (int)n.ws_row
+# define WINSIZE_COLS(n) (int)n.ws_col
+# endif
+#endif
+
+static int _use_env = TRUE;
+
+static void do_prototype(void);
+
+void use_env(bool f)
+{
+ _use_env = f;
+}
+
+int LINES, COLS, TABSIZE;
+
+static void _nc_get_screensize(int *linep, int *colp)
+/* Obtain lines/columns values from the environment and/or terminfo entry */
+{
+ /* figure out the size of the screen */
+ T(("screen size: terminfo lines = %d columns = %d", lines, columns));
+
+ if (!_use_env)
+ {
+ *linep = (int)lines;
+ *colp = (int)columns;
+ }
+ else /* usually want to query LINES and COLUMNS from environment */
+ {
+ int value;
+
+ *linep = *colp = 0;
+
+ /* first, look for environment variables */
+ if ((value = _nc_getenv_num("LINES")) > 0) {
+ *linep = value;
+ }
+ if ((value = _nc_getenv_num("COLUMNS")) > 0) {
+ *colp = value;
+ }
+ T(("screen size: environment LINES = %d COLUMNS = %d",*linep,*colp));
+
+#ifdef __EMX__
+ if (*linep <= 0 || *colp <= 0)
+ {
+ int screendata[2];
+ _scrsize(screendata);
+ *colp = screendata[0];
+ *linep = screendata[1];
+ T(("EMX screen size: environment LINES = %d COLUMNS = %d",*linep,*colp));
+ }
+#endif
+#if HAVE_SIZECHANGE
+ /* if that didn't work, maybe we can try asking the OS */
+ if (*linep <= 0 || *colp <= 0)
+ {
+ if (isatty(cur_term->Filedes))
+ {
+ STRUCT_WINSIZE size;
+
+ errno = 0;
+ do {
+ if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) < 0
+ && errno != EINTR)
+ goto failure;
+ } while
+ (errno == EINTR);
+
+ /*
+ * Solaris lets users override either dimension with an
+ * environment variable.
+ */
+ if (*linep <= 0)
+ *linep = WINSIZE_ROWS(size);
+ if (*colp <= 0)
+ *colp = WINSIZE_COLS(size);
+ }
+ /* FALLTHRU */
+ failure:;
+ }
+#endif /* HAVE_SIZECHANGE */
+
+ /* if we can't get dynamic info about the size, use static */
+ if (*linep <= 0 || *colp <= 0)
+ if (lines > 0 && columns > 0)
+ {
+ *linep = (int)lines;
+ *colp = (int)columns;
+ }
+
+ /* the ultimate fallback, assume fixed 24x80 size */
+ if (*linep <= 0 || *colp <= 0)
+ {
+ *linep = 24;
+ *colp = 80;
+ }
+
+ /*
+ * Put the derived values back in the screen-size caps, so
+ * tigetnum() and tgetnum() will do the right thing.
+ */
+ lines = (short)(*linep);
+ columns = (short)(*colp);
+ }
+
+ T(("screen size is %dx%d", *linep, *colp));
+
+ if (init_tabs != -1)
+ TABSIZE = (int)init_tabs;
+ else
+ TABSIZE = 8;
+ T(("TABSIZE = %d", TABSIZE));
+
+}
+
+#if USE_SIZECHANGE
+void _nc_update_screensize(void)
+{
+ int my_lines, my_cols;
+
+ _nc_get_screensize(&my_lines, &my_cols);
+ if (SP != 0 && SP->_resize != 0)
+ SP->_resize(my_lines, my_cols);
+}
+#endif
+
+/****************************************************************************
+ *
+ * Terminal setup
+ *
+ ****************************************************************************/
+
+#define ret_error(code, fmt, arg) if (errret) {\
+ *errret = code;\
+ returnCode(ERR);\
+ } else {\
+ fprintf(stderr, fmt, arg);\
+ exit(EXIT_FAILURE);\
+ }
+
+#define ret_error0(code, msg) if (errret) {\
+ *errret = code;\
+ returnCode(ERR);\
+ } else {\
+ fprintf(stderr, msg);\
+ exit(EXIT_FAILURE);\
+ }
+
+#if USE_DATABASE
+static int grab_entry(const char *const tn, TERMTYPE *const tp)
+/* return 1 if entry found, 0 if not found, -1 if database not accessible */
+{
+ char filename[PATH_MAX];
+ int status = 0;
+ int _nc_read_bsd_terminfo_entry(const char *, TERMTYPE *); /* XXX */
+
+#ifdef __OpenBSD__
+ status = _nc_read_bsd_terminfo_entry(tn, tp);
+#endif /* __OpenBSD__ */
+
+ if (status != 1 && (status = _nc_read_entry(tn, filename, tp)) != 1) {
+
+#ifndef PURE_TERMINFO
+ /*
+ * Try falling back on the termcap file.
+ * Note: allowing this call links the entire terminfo/termcap
+ * compiler into the startup code. It's preferable to build a
+ * real terminfo database and use that.
+ */
+ status = _nc_read_termcap_entry(tn, tp);
+#endif /* PURE_TERMINFO */
+
+ }
+
+ /*
+ * If we have an entry, force all of the cancelled strings to null
+ * pointers so we don't have to test them in the rest of the library.
+ * (The terminfo compiler bypasses this logic, since it must know if
+ * a string is cancelled, for merging entries).
+ */
+ if (status == 1) {
+ unsigned n;
+ for (n = 0; n < BOOLCOUNT; n++)
+ if (!VALID_BOOLEAN(tp->Booleans[n]))
+ tp->Booleans[n] = FALSE;
+ for (n = 0; n < STRCOUNT; n++)
+ if (tp->Strings[n] == CANCELLED_STRING)
+ tp->Strings[n] = ABSENT_STRING;
+ }
+ return(status);
+}
+#endif
+
+char ttytype[NAMESIZE];
+
+/*
+ * setupterm(termname, Filedes, errret)
+ *
+ * Find and read the appropriate object file for the terminal
+ * Make cur_term point to the structure.
+ *
+ */
+
+int setupterm(NCURSES_CONST char *tname, int Filedes, int *errret)
+{
+struct term *term_ptr;
+int status;
+
+ T((T_CALLED("setupterm(\"%s\",%d,%p)"), tname, Filedes, errret));
+
+ if (tname == 0) {
+ tname = getenv("TERM");
+ if (tname == 0 || *tname == '\0') {
+ ret_error0(-1, "TERM environment variable not set.\n");
+ }
+ }
+ if (strlen(tname) > MAX_NAME_SIZE) {
+ ret_error(-1, "TERM environment must be <= %d characters.\n",
+ MAX_NAME_SIZE);
+ }
+
+ T(("your terminal name is %s", tname));
+
+ term_ptr = typeCalloc(TERMINAL, 1);
+
+ if (term_ptr == 0) {
+ ret_error0(-1, "Not enough memory to create terminal structure.\n") ;
+ }
+#if USE_DATABASE
+ status = grab_entry(tname, &term_ptr->type);
+#else
+ status = 0;
+#endif
+
+ /* try fallback list if entry on disk */
+ if (status != 1)
+ {
+ const TERMTYPE *fallback = _nc_fallback(tname);
+
+ if (fallback)
+ {
+ memcpy(&term_ptr->type, fallback, sizeof(TERMTYPE));
+ status = 1;
+ }
+ }
+
+ if (status == -1)
+ {
+ ret_error0(-1, "terminals database is inaccessible\n");
+ }
+ else if (status == 0)
+ {
+ ret_error(0, "'%s': unknown terminal type.\n", tname);
+ }
+
+ set_curterm(term_ptr);
+
+ if (command_character && getenv("CC"))
+ do_prototype();
+
+ strlcpy(ttytype, cur_term->type.term_names, NAMESIZE);
+
+ /*
+ * Allow output redirection. This is what SVr3 does.
+ * If stdout is directed to a file, screen updates go
+ * to standard error.
+ */
+ if (Filedes == STDOUT_FILENO && !isatty(Filedes))
+ Filedes = STDERR_FILENO;
+ cur_term->Filedes = Filedes;
+
+ _nc_get_screensize(&LINES, &COLS);
+
+ if (errret)
+ *errret = 1;
+
+ T((T_CREATE("screen %s %dx%d"), tname, LINES, COLS));
+
+ if (generic_type) {
+ ret_error(0, "'%s': I need something more specific.\n", tname);
+ }
+ if (hard_copy) {
+ ret_error(1, "'%s': I can't handle hardcopy terminals.\n", tname);
+ }
+ returnCode(OK);
+}
+
+/*
+** do_prototype()
+**
+** Take the real command character out of the CC environment variable
+** and substitute it in for the prototype given in 'command_character'.
+**
+*/
+
+static void
+do_prototype(void)
+{
+int i, j;
+char CC;
+char proto;
+char *tmp;
+
+ tmp = getenv("CC");
+ CC = *tmp;
+ proto = *command_character;
+
+ for (i=0; i < STRCOUNT; i++) {
+ j = 0;
+ while (cur_term->type.Strings[i][j]) {
+ if (cur_term->type.Strings[i][j] == proto)
+ cur_term->type.Strings[i][j] = CC;
+ j++;
+ }
+ }
+}
diff --git a/lib/libcurses/tinfo/lib_termcap.c b/lib/libcurses/tinfo/lib_termcap.c
new file mode 100644
index 00000000000..e50b4a622da
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_termcap.c
@@ -0,0 +1,194 @@
+/* $OpenBSD: lib_termcap.c,v 1.1 1999/01/18 19:10:19 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+
+#include <termcap.h>
+#include <tic.h>
+
+#define __INTERNAL_CAPS_VISIBLE
+#include <term.h>
+
+MODULE_ID("$From: lib_termcap.c,v 1.25 1999/01/10 00:48:11 tom Exp $")
+
+/*
+ some of the code in here was contributed by:
+ Magnus Bengtsson, d6mbeng@dtek.chalmers.se
+*/
+
+char *UP;
+char *BC;
+
+/***************************************************************************
+ *
+ * tgetent(bufp, term)
+ *
+ * In termcap, this function reads in the entry for terminal `term' into the
+ * buffer pointed to by bufp. It must be called before any of the functions
+ * below are called.
+ * In this terminfo emulation, tgetent() simply calls setupterm() (which
+ * does a bit more than tgetent() in termcap does), and returns its return
+ * value (1 if successful, 0 if no terminal with the given name could be
+ * found, or -1 if no terminal descriptions have been installed on the
+ * system). The bufp argument is ignored.
+ *
+ ***************************************************************************/
+
+int tgetent(char *bufp GCC_UNUSED, const char *name)
+{
+int errcode;
+
+ T((T_CALLED("tgetent()")));
+
+ setupterm((NCURSES_CONST char *)name, STDOUT_FILENO, &errcode);
+
+ if (errcode == 1) {
+
+ if (cursor_left)
+ if ((backspaces_with_bs = !strcmp(cursor_left, "\b")) == 0)
+ backspace_if_not_bs = cursor_left;
+
+ /* we're required to export these */
+ if (pad_char != NULL)
+ PC = pad_char[0];
+ if (cursor_up != NULL)
+ UP = cursor_up;
+ if (backspace_if_not_bs != NULL)
+ BC = backspace_if_not_bs;
+
+ (void) baudrate(); /* sets ospeed as a side-effect */
+
+/* LINT_PREPRO
+#if 0*/
+#include <capdefaults.c>
+/* LINT_PREPRO
+#endif*/
+
+ }
+ returnCode(errcode);
+}
+
+/***************************************************************************
+ *
+ * tgetflag(str)
+ *
+ * Look up boolean termcap capability str and return its value (TRUE=1 if
+ * present, FALSE=0 if not).
+ *
+ ***************************************************************************/
+
+int tgetflag(NCURSES_CONST char *id)
+{
+int i;
+
+ T((T_CALLED("tgetflag(%s)"), id));
+ if (cur_term != 0) {
+ for (i = 0; i < BOOLCOUNT; i++) {
+ if (!strncmp(id, boolcodes[i], 2)) {
+ /* setupterm forces invalid booleans to false */
+ returnCode(cur_term->type.Booleans[i]);
+ }
+ }
+ }
+ returnCode(0); /* Solaris does this */
+}
+
+/***************************************************************************
+ *
+ * tgetnum(str)
+ *
+ * Look up numeric termcap capability str and return its value, or -1 if
+ * not given.
+ *
+ ***************************************************************************/
+
+int tgetnum(NCURSES_CONST char *id)
+{
+int i;
+
+ T((T_CALLED("tgetnum(%s)"), id));
+ if (cur_term != 0) {
+ for (i = 0; i < NUMCOUNT; i++) {
+ if (!strncmp(id, numcodes[i], 2)) {
+ if (!VALID_NUMERIC(cur_term->type.Numbers[i]))
+ return -1;
+ returnCode(cur_term->type.Numbers[i]);
+ }
+ }
+ }
+ returnCode(ERR);
+}
+
+/***************************************************************************
+ *
+ * tgetstr(str, area)
+ *
+ * Look up string termcap capability str and return a pointer to its value,
+ * or NULL if not given.
+ *
+ ***************************************************************************/
+
+char *tgetstr(NCURSES_CONST char *id, char **area GCC_UNUSED)
+{
+int i;
+
+ T((T_CALLED("tgetstr(%s,%p)"), id, area));
+ if (cur_term != 0) {
+ for (i = 0; i < STRCOUNT; i++) {
+ T(("trying %s", strcodes[i]));
+ if (!strncmp(id, strcodes[i], 2)) {
+ T(("found match : %s", _nc_visbuf(cur_term->type.Strings[i])));
+ /* setupterm forces cancelled strings to null */
+ returnPtr(cur_term->type.Strings[i]);
+ }
+ }
+ }
+ returnPtr(NULL);
+}
+
+/*
+ * char *
+ * tgoto(string, x, y)
+ *
+ * Retained solely for upward compatibility. Note the intentional
+ * reversing of the last two arguments.
+ *
+ */
+
+char *tgoto(const char *string, int x, int y)
+{
+ T((T_CALLED("tgoto(%s,%d,%d)"), string, x, y));
+ returnPtr(tparm((NCURSES_CONST char *)string, y, x));
+}
diff --git a/lib/libcurses/tinfo/lib_termname.c b/lib/libcurses/tinfo/lib_termname.c
new file mode 100644
index 00000000000..dc4e69e2907
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_termname.c
@@ -0,0 +1,48 @@
+/* $OpenBSD: lib_termname.c,v 1.1 1999/01/18 19:10:20 millert 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. *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+#include <tic.h> /* for MAX_ALIAS */
+
+MODULE_ID("$From: lib_termname.c,v 1.1 1998/12/19 23:07:43 tom Exp $")
+
+char *termname(void)
+{
+char *term = getenv("TERM");
+static char ret[MAX_ALIAS+1];
+
+ T(("termname() called"));
+
+ if (term != 0) {
+ (void) strncpy(ret, term, sizeof(ret) - 1);
+ term = ret;
+ }
+ return term;
+}
diff --git a/lib/libcurses/tinfo/lib_ti.c b/lib/libcurses/tinfo/lib_ti.c
new file mode 100644
index 00000000000..6d2d792df6e
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_ti.c
@@ -0,0 +1,97 @@
+/* $OpenBSD: lib_ti.c,v 1.1 1999/01/18 19:10:20 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+#include <curses.priv.h>
+
+#include <term.h>
+#include <tic.h>
+
+MODULE_ID("$From: lib_ti.c,v 1.13 1999/01/03 01:44:27 tom Exp $")
+
+int tigetflag(NCURSES_CONST char *str)
+{
+int i;
+
+ T((T_CALLED("tigetflag(%s)"), str));
+
+ if (cur_term != 0) {
+ for (i = 0; i < BOOLCOUNT; i++) {
+ if (!strcmp(str, boolnames[i])) {
+ /* setupterm forces invalid booleans to false */
+ returnCode(cur_term->type.Booleans[i]);
+ }
+ }
+ }
+
+ returnCode(ABSENT_BOOLEAN);
+}
+
+int tigetnum(NCURSES_CONST char *str)
+{
+int i;
+
+ T((T_CALLED("tigetnum(%s)"), str));
+
+ if (cur_term != 0) {
+ for (i = 0; i < NUMCOUNT; i++) {
+ if (!strcmp(str, numnames[i])) {
+ if (!VALID_NUMERIC(cur_term->type.Numbers[i]))
+ return -1;
+ returnCode(cur_term->type.Numbers[i]);
+ }
+ }
+ }
+
+ returnCode(CANCELLED_NUMERIC); /* Solaris returns a -1 instead */
+}
+
+char *tigetstr(NCURSES_CONST char *str)
+{
+int i;
+
+ T((T_CALLED("tigetstr(%s)"), str));
+
+ if (cur_term != 0) {
+ for (i = 0; i < STRCOUNT; i++) {
+ if (!strcmp(str, strnames[i])) {
+ /* setupterm forces cancelled strings to null */
+ returnPtr(cur_term->type.Strings[i]);
+ }
+ }
+ }
+
+ returnPtr(CANCELLED_STRING);
+}
diff --git a/lib/libcurses/tinfo/lib_tparm.c b/lib/libcurses/tinfo/lib_tparm.c
new file mode 100644
index 00000000000..87fad7291c7
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_tparm.c
@@ -0,0 +1,587 @@
+/* $OpenBSD: lib_tparm.c,v 1.1 1999/01/18 19:10:20 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * tparm.c
+ *
+ */
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+#include <term.h>
+#include <tic.h>
+
+MODULE_ID("$From: lib_tparm.c,v 1.37 1999/01/02 22:38:25 tom Exp $")
+
+/*
+ * char *
+ * tparm(string, ...)
+ *
+ * Substitute the given parameters into the given string by the following
+ * rules (taken from terminfo(5)):
+ *
+ * Cursor addressing and other strings requiring parame-
+ * ters in the terminal are described by a parameterized string
+ * capability, with like escapes %x in it. For example, to
+ * address the cursor, the cup capability is given, using two
+ * parameters: the row and column to address to. (Rows and
+ * columns are numbered from zero and refer to the physical
+ * screen visible to the user, not to any unseen memory.) If
+ * the terminal has memory relative cursor addressing, that can
+ * be indicated by
+ *
+ * The parameter mechanism uses a stack and special %
+ * codes to manipulate it. Typically a sequence will push one
+ * of the parameters onto the stack and then print it in some
+ * format. Often more complex operations are necessary.
+ *
+ * The % encodings have the following meanings:
+ *
+ * %% outputs `%'
+ * %c print pop() like %c in printf()
+ * %s print pop() like %s in printf()
+ * %[[:]flags][width[.precision]][doxXs]
+ * as in printf, flags are [-+#] and space
+ *
+ * %p[1-9] push ith parm
+ * %P[a-z] set dynamic variable [a-z] to pop()
+ * %g[a-z] get dynamic variable [a-z] and push it
+ * %P[A-Z] set static variable [A-Z] to pop()
+ * %g[A-Z] get static variable [A-Z] and push it
+ * %l push strlen(pop)
+ * %'c' push char constant c
+ * %{nn} push integer constant nn
+ *
+ * %+ %- %* %/ %m
+ * arithmetic (%m is mod): push(pop() op pop())
+ * %& %| %^ bit operations: push(pop() op pop())
+ * %= %> %< logical operations: push(pop() op pop())
+ * %A %O logical and & or operations for conditionals
+ * %! %~ unary operations push(op pop())
+ * %i add 1 to first two parms (for ANSI terminals)
+ *
+ * %? expr %t thenpart %e elsepart %;
+ * if-then-else, %e elsepart is optional.
+ * else-if's are possible ala Algol 68:
+ * %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
+ *
+ * For those of the above operators which are binary and not commutative,
+ * the stack works in the usual way, with
+ * %gx %gy %m
+ * resulting in x mod y, not the reverse.
+ */
+
+#define STACKSIZE 20
+
+typedef union {
+ unsigned int num;
+ char *str;
+} stack_frame;
+
+static stack_frame stack[STACKSIZE];
+static int stack_ptr;
+#ifdef TRACE
+static const char *tname;
+#endif /* TRACE */
+
+static char *out_buff;
+static size_t out_size;
+static size_t out_used;
+
+#if NO_LEAKS
+void _nc_free_tparm(void)
+{
+ if (out_buff != 0) {
+ FreeAndNull(out_buff);
+ out_size = 0;
+ out_used = 0;
+ }
+}
+#endif
+
+static void really_get_space(size_t need)
+{
+ out_size = need * 2;
+ out_buff = (char *)_nc_doalloc(out_buff, out_size);
+ if (out_buff == 0)
+ _nc_err_abort("Out of memory");
+}
+
+static inline void get_space(size_t need)
+{
+ need += out_used;
+ if (need > out_size)
+ really_get_space(need);
+}
+
+static inline void save_text(const char *fmt, char *s, int len)
+{
+ size_t s_len = strlen(s);
+ if (len > (int)s_len)
+ s_len = len;
+
+ get_space(s_len + 1);
+
+ (void)sprintf(out_buff+out_used, fmt, s);
+ out_used += strlen(out_buff+out_used);
+}
+
+static inline void save_number(const char *fmt, int number, int len)
+{
+ if (len < 30)
+ len = 30; /* actually log10(MAX_INT)+1 */
+
+ get_space(len + 1);
+
+ (void)sprintf(out_buff+out_used, fmt, number);
+ out_used += strlen(out_buff+out_used);
+}
+
+static inline void save_char(int c)
+{
+ if (c == 0)
+ c = 0200;
+ get_space(1);
+ out_buff[out_used++] = c;
+}
+
+static inline void npush(int x)
+{
+ if (stack_ptr < STACKSIZE) {
+ stack[stack_ptr].num = x;
+ stack_ptr++;
+ }
+}
+
+static inline int npop(void)
+{
+ return (stack_ptr > 0 ? stack[--stack_ptr].num : 0);
+}
+
+static inline char *spop(void)
+{
+ static char dummy[] = ""; /* avoid const-cast */
+ return (stack_ptr > 0 ? stack[--stack_ptr].str : dummy);
+}
+
+static inline const char *parse_format(const char *s, char *format, int *len)
+{
+ bool done = FALSE;
+ bool allowminus = FALSE;
+ bool dot = FALSE;
+ int prec = 0;
+ int width = 0;
+
+ *len = 0;
+ *format++ = '%';
+ while (*s != '\0' && !done) {
+ switch (*s) {
+ case 'c': /* FALLTHRU */
+ case 'd': /* FALLTHRU */
+ case 'o': /* FALLTHRU */
+ case 'x': /* FALLTHRU */
+ case 'X': /* FALLTHRU */
+ case 's':
+ *format++ = *s;
+ done = TRUE;
+ break;
+ case '.':
+ *format++ = *s++;
+ dot = TRUE;
+ break;
+ case '#':
+ *format++ = *s++;
+ break;
+ case ' ':
+ *format++ = *s++;
+ break;
+ case ':':
+ s++;
+ allowminus = TRUE;
+ break;
+ case '-':
+ if (allowminus) {
+ *format++ = *s++;
+ } else {
+ done = TRUE;
+ }
+ break;
+ default:
+ if (isdigit(*s)) {
+ if (dot)
+ prec = (prec * 10) + (*s - '0');
+ else
+ width = (width * 10) + (*s - '0');
+ *format++ = *s++;
+ } else {
+ done = TRUE;
+ }
+ }
+ }
+ *format = '\0';
+ /* return maximum string length in print */
+ *len = (prec > width) ? prec : width;
+ return s;
+}
+
+#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
+#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
+
+static inline char *tparam_internal(const char *string, va_list ap)
+{
+#define NUM_VARS 26
+int param[9];
+int popcount;
+int number;
+int len;
+int level;
+int x, y;
+int i;
+register const char *cp;
+static size_t len_fmt;
+static char *format;
+static int dynamic_var[NUM_VARS];
+static int static_vars[NUM_VARS];
+
+ out_used = 0;
+ if (string == NULL)
+ return NULL;
+
+ /*
+ * Find the highest parameter-number referred to in the format string.
+ * Use this value to limit the number of arguments copied from the
+ * variable-length argument list.
+ */
+ for (cp = string, popcount = number = 0; *cp != '\0'; cp++) {
+ if (cp[0] == '%' && cp[1] != '\0') {
+ switch (cp[1]) {
+ case '%':
+ cp++;
+ break;
+ case 'i':
+ if (popcount < 2)
+ popcount = 2;
+ break;
+ case 'p':
+ cp++;
+ if (cp[1] >= '1' && cp[1] <= '9') {
+ int c = cp[1] - '0';
+ if (c > popcount)
+ popcount = c;
+ }
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'd': case 'c': case 's':
+ ++number;
+ break;
+ }
+ }
+ }
+ if ((size_t)(cp - string) > len_fmt) {
+ len_fmt = (cp - string) + len_fmt + 2;
+ if ((format = _nc_doalloc(format, len_fmt)) == 0)
+ return 0;
+ }
+
+ if (number > 9) number = 9;
+ for (i = 0; i < max(popcount, number); i++) {
+ /*
+ * FIXME: potential loss here if sizeof(int) != sizeof(char *).
+ * A few caps (such as plab_norm) have string-valued parms.
+ */
+ param[i] = va_arg(ap, int);
+ }
+
+ /*
+ * This is a termcap compatibility hack. If there are no explicit pop
+ * operations in the string, load the stack in such a way that
+ * successive pops will grab successive parameters. That will make
+ * the expansion of (for example) \E[%d;%dH work correctly in termcap
+ * style, which means tparam() will expand termcap strings OK.
+ */
+ stack_ptr = 0;
+ if (popcount == 0) {
+ popcount = number;
+ for (i = number - 1; i >= 0; i--)
+ npush(param[i]);
+ }
+
+#ifdef TRACE
+ if (_nc_tracing & TRACE_CALLS) {
+ for (i = 0; i < popcount; i++)
+ save_number(", %d", param[i], 0);
+ _tracef(T_CALLED("%s(%s%s)"), tname, _nc_visbuf(string), out_buff);
+ out_used = 0;
+ }
+#endif /* TRACE */
+
+ while (*string) {
+ if (*string != '%') {
+ save_char(*string);
+ } else {
+ string++;
+ string = parse_format(string, format, &len);
+ switch (*string) {
+ default:
+ break;
+ case '%':
+ save_char('%');
+ break;
+
+ case 'd': /* FALLTHRU */
+ case 'o': /* FALLTHRU */
+ case 'x': /* FALLTHRU */
+ case 'X': /* FALLTHRU */
+ case 'c':
+ save_number(format, npop(), len);
+ break;
+
+ case 'l':
+ save_number("%d", strlen(spop()), 0);
+ break;
+
+ case 's':
+ save_text(format, spop(), len);
+ break;
+
+ case 'p':
+ string++;
+ if (*string >= '1' && *string <= '9')
+ npush(param[*string - '1']);
+ break;
+
+ case 'P':
+ string++;
+ if (isUPPER(*string)) {
+ i = (*string - 'A');
+ static_vars[i] = npop();
+ } else if (isLOWER(*string)) {
+ i = (*string - 'a');
+ dynamic_var[i] = npop();
+ }
+ break;
+
+ case 'g':
+ string++;
+ if (isUPPER(*string)) {
+ i = (*string - 'A');
+ npush(static_vars[i]);
+ } else if (isLOWER(*string)) {
+ i = (*string - 'a');
+ npush(dynamic_var[i]);
+ }
+ break;
+
+ case S_QUOTE:
+ string++;
+ npush(*string);
+ string++;
+ break;
+
+ case L_BRACE:
+ number = 0;
+ string++;
+ while (*string >= '0' && *string <= '9') {
+ number = number * 10 + *string - '0';
+ string++;
+ }
+ npush(number);
+ break;
+
+ case '+':
+ npush(npop() + npop());
+ break;
+
+ case '-':
+ y = npop();
+ x = npop();
+ npush(x - y);
+ break;
+
+ case '*':
+ npush(npop() * npop());
+ break;
+
+ case '/':
+ y = npop();
+ x = npop();
+ npush(x / y);
+ break;
+
+ case 'm':
+ y = npop();
+ x = npop();
+ npush(x % y);
+ break;
+
+ case 'A':
+ npush(npop() && npop());
+ break;
+
+ case 'O':
+ npush(npop() || npop());
+ break;
+
+ case '&':
+ npush(npop() & npop());
+ break;
+
+ case '|':
+ npush(npop() | npop());
+ break;
+
+ case '^':
+ npush(npop() ^ npop());
+ break;
+
+ case '=':
+ y = npop();
+ x = npop();
+ npush(x == y);
+ break;
+
+ case '<':
+ y = npop();
+ x = npop();
+ npush(x < y);
+ break;
+
+ case '>':
+ y = npop();
+ x = npop();
+ npush(x > y);
+ break;
+
+ case '!':
+ npush(! npop());
+ break;
+
+ case '~':
+ npush(~ npop());
+ break;
+
+ case 'i':
+ param[0]++;
+ param[1]++;
+ break;
+
+ case '?':
+ break;
+
+ case 't':
+ x = npop();
+ if (!x) {
+ /* scan forward for %e or %; at level zero */
+ string++;
+ level = 0;
+ while (*string) {
+ if (*string == '%') {
+ string++;
+ if (*string == '?')
+ level++;
+ else if (*string == ';') {
+ if (level > 0)
+ level--;
+ else
+ break;
+ }
+ else if (*string == 'e' && level == 0)
+ break;
+ }
+
+ if (*string)
+ string++;
+ }
+ }
+ break;
+
+ case 'e':
+ /* scan forward for a %; at level zero */
+ string++;
+ level = 0;
+ while (*string) {
+ if (*string == '%') {
+ string++;
+ if (*string == '?')
+ level++;
+ else if (*string == ';') {
+ if (level > 0)
+ level--;
+ else
+ break;
+ }
+ }
+
+ if (*string)
+ string++;
+ }
+ break;
+
+ case ';':
+ break;
+
+ } /* endswitch (*string) */
+ } /* endelse (*string == '%') */
+
+ if (*string == '\0')
+ break;
+
+ string++;
+ } /* endwhile (*string) */
+
+ if (out_buff == 0 && (out_buff = calloc(1,1)) == NULL)
+ return(NULL);
+ out_buff[out_used] = '\0';
+
+ T((T_RETURN("%s"), _nc_visbuf(out_buff)));
+ return(out_buff);
+}
+
+char *tparm(NCURSES_CONST char *string, ...)
+{
+va_list ap;
+char *result;
+
+ va_start(ap, string);
+#ifdef TRACE
+ tname = "tparm";
+#endif /* TRACE */
+ result = tparam_internal(string, ap);
+ va_end(ap);
+ return result;
+}
diff --git a/lib/libcurses/tinfo/lib_tputs.c b/lib/libcurses/tinfo/lib_tputs.c
new file mode 100644
index 00000000000..e4c778332df
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_tputs.c
@@ -0,0 +1,245 @@
+/* $OpenBSD: lib_tputs.c,v 1.1 1999/01/18 19:10:20 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * tputs.c
+ * delay_output()
+ * _nc_outch()
+ * tputs()
+ *
+ */
+
+#include <curses.priv.h>
+#include <ctype.h>
+#include <term.h> /* padding_baud_rate, xon_xoff */
+#include <termcap.h> /* ospeed */
+#include <tic.h>
+
+MODULE_ID("$From: lib_tputs.c,v 1.38 1999/01/10 00:57:41 tom Exp $")
+
+#define OUTPUT ((SP != 0) ? SP->_ofp : stdout)
+
+char PC; /* used by termcap library */
+speed_t ospeed; /* used by termcap library */
+
+int _nc_nulls_sent; /* used by 'tack' program */
+
+static int (*my_outch)(int c) = _nc_outch;
+
+int delay_output(int ms)
+{
+ T((T_CALLED("delay_output(%d)"), ms));
+
+ if (no_pad_char)
+ napms(ms);
+ else {
+ register int nullcount;
+
+ nullcount = (ms * _nc_baudrate(ospeed)) / 10000;
+ for (_nc_nulls_sent += nullcount; nullcount > 0; nullcount--)
+ my_outch(PC);
+ if (my_outch == _nc_outch)
+ (void) fflush(OUTPUT);
+ }
+
+ returnCode(OK);
+}
+
+int _nc_outch(int ch)
+{
+#ifdef TRACE
+ _nc_outchars++;
+#endif /* TRACE */
+
+ putc(ch, OUTPUT);
+ return OK;
+}
+
+int putp(const char *string)
+{
+ return tputs(string, 1, _nc_outch);
+}
+
+int tputs(const char *string, int affcnt, int (*outc)(int))
+{
+bool always_delay;
+bool normal_delay;
+int number;
+#ifdef BSD_TPUTS
+int trailpad;
+#endif /* BSD_TPUTS */
+
+#ifdef TRACE
+char addrbuf[32];
+
+ if (_nc_tracing & TRACE_TPUTS)
+ {
+ if (outc == _nc_outch)
+ (void) strcpy(addrbuf, "_nc_outch");
+ else
+ (void) sprintf(addrbuf, "%p", outc);
+ if (_nc_tputs_trace) {
+ TR(TRACE_MAXIMUM, ("tputs(%s = %s, %d, %s) called", _nc_tputs_trace, _nc_visbuf(string), affcnt, addrbuf));
+ }
+ else {
+ TR(TRACE_MAXIMUM, ("tputs(%s, %d, %s) called", _nc_visbuf(string), affcnt, addrbuf));
+ }
+ _nc_tputs_trace = (char *)NULL;
+ }
+#endif /* TRACE */
+
+ if (string == ABSENT_STRING || string == CANCELLED_STRING)
+ return ERR;
+
+ if (cur_term == 0) {
+ always_delay = FALSE;
+ normal_delay = TRUE;
+ } else {
+ always_delay = (string == bell) || (string == flash_screen);
+ normal_delay =
+ !xon_xoff
+ && padding_baud_rate
+#ifdef NCURSES_NO_PADDING
+ && (SP == 0 || !(SP->_no_padding))
+#endif
+ && (_nc_baudrate(ospeed) >= padding_baud_rate);
+ }
+
+#ifdef BSD_TPUTS
+ /*
+ * This ugly kluge deals with the fact that some ancient BSD programs
+ * (like nethack) actually do the likes of tputs("50") to get delays.
+ */
+ trailpad = 0;
+ if (isdigit(*string)) {
+ while (isdigit(*string)) {
+ trailpad = trailpad * 10 + (*string - '0');
+ string++;
+ }
+ trailpad *= 10;
+ if (*string == '.') {
+ string++;
+ if (isdigit(*string)) {
+ trailpad += (*string - '0');
+ string++;
+ }
+ while (isdigit(*string))
+ string++;
+ }
+
+ if (*string == '*') {
+ trailpad *= affcnt;
+ string++;
+ }
+ }
+#endif /* BSD_TPUTS */
+
+ my_outch = outc; /* redirect delay_output() */
+ while (*string) {
+ if (*string != '$')
+ (*outc)(*string);
+ else {
+ string++;
+ if (*string != '<') {
+ (*outc)('$');
+ if (*string)
+ (*outc)(*string);
+ } else {
+ bool mandatory;
+
+ string++;
+ if ((!isdigit(*string) && *string != '.') || !strchr(string, '>')) {
+ (*outc)('$');
+ (*outc)('<');
+ continue;
+ }
+
+ number = 0;
+ while (isdigit(*string)) {
+ number = number * 10 + (*string - '0');
+ string++;
+ }
+ number *= 10;
+ if (*string == '.') {
+ string++;
+ if (isdigit(*string)) {
+ number += (*string - '0');
+ string++;
+ }
+ while (isdigit(*string))
+ string++;
+ }
+
+ mandatory = FALSE;
+ while (*string == '*' || *string == '/')
+ {
+ if (*string == '*') {
+ number *= affcnt;
+ string++;
+ }
+ else /* if (*string == '/') */ {
+ mandatory = TRUE;
+ string++;
+ }
+ }
+
+ if (number > 0
+ && (always_delay
+ || normal_delay
+ || mandatory))
+ delay_output(number/10);
+
+ } /* endelse (*string == '<') */
+ } /* endelse (*string == '$') */
+
+ if (*string == '\0')
+ break;
+
+ string++;
+ }
+
+#ifdef BSD_TPUTS
+ /*
+ * Emit any BSD-style prefix padding that we've accumulated now.
+ */
+ if (trailpad > 0
+ && (always_delay || normal_delay))
+ delay_output(trailpad/10);
+#endif /* BSD_TPUTS */
+
+ my_outch = _nc_outch;
+ return OK;
+}
diff --git a/lib/libcurses/tinfo/lib_ttyflags.c b/lib/libcurses/tinfo/lib_ttyflags.c
new file mode 100644
index 00000000000..f3b875c3bd4
--- /dev/null
+++ b/lib/libcurses/tinfo/lib_ttyflags.c
@@ -0,0 +1,163 @@
+/* $OpenBSD: lib_ttyflags.c,v 1.1 1999/01/18 19:10:21 millert 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. *
+ ****************************************************************************/
+
+/*
+ * def_prog_mode()
+ * def_shell_mode()
+ * reset_prog_mode()
+ * reset_shell_mode()
+ * savetty()
+ * resetty()
+ */
+
+#include <curses.priv.h>
+#include <term.h> /* cur_term */
+
+MODULE_ID("$From: lib_ttyflags.c,v 1.1 1998/12/20 00:49:19 tom Exp $")
+
+#undef tabs
+
+#ifdef TAB3
+# define tabs TAB3
+#else
+# ifdef XTABS
+# define tabs XTABS
+# else
+# ifdef OXTABS
+# define tabs OXTABS
+# else
+# define tabs 0
+# endif
+# endif
+#endif
+
+int _nc_get_tty_mode(TTY *buf)
+{
+ if (cur_term == 0
+ || GET_TTY(cur_term->Filedes, buf) != 0)
+ return(ERR);
+ return (OK);
+}
+
+int _nc_set_tty_mode(TTY *buf)
+{
+ if (cur_term == 0
+ || SET_TTY(cur_term->Filedes, buf) != 0)
+ return(ERR);
+ return (OK);
+}
+
+int def_shell_mode(void)
+{
+ T((T_CALLED("def_shell_mode()")));
+
+ /*
+ * Turn off the XTABS bit in the tty structure if it was on. If XTABS
+ * was on, remove the tab and backtab capabilities.
+ */
+
+ if (_nc_get_tty_mode(&cur_term->Ottyb) != OK)
+ returnCode(ERR);
+#ifdef TERMIOS
+ if (cur_term->Ottyb.c_oflag & tabs)
+ tab = back_tab = NULL;
+#else
+ if (cur_term->Ottyb.sg_flags & XTABS)
+ tab = back_tab = NULL;
+#endif
+ returnCode(OK);
+}
+
+int def_prog_mode(void)
+{
+ T((T_CALLED("def_prog_mode()")));
+
+ if (_nc_get_tty_mode(&cur_term->Nttyb) != OK)
+ returnCode(ERR);
+#ifdef TERMIOS
+ cur_term->Nttyb.c_oflag &= ~tabs;
+#else
+ cur_term->Nttyb.sg_flags &= ~XTABS;
+#endif
+ returnCode(OK);
+}
+
+int reset_prog_mode(void)
+{
+ T((T_CALLED("reset_prog_mode()")));
+
+ if (cur_term != 0) {
+ _nc_set_tty_mode(&cur_term->Nttyb);
+ if (SP) {
+ if (stdscr && stdscr->_use_keypad)
+ _nc_keypad(TRUE);
+ NC_BUFFERED(TRUE);
+ }
+ returnCode(OK);
+ }
+ returnCode(ERR);
+}
+
+int reset_shell_mode(void)
+{
+ T((T_CALLED("reset_shell_mode()")));
+
+ if (cur_term != 0) {
+ if (SP)
+ {
+ _nc_keypad(FALSE);
+ fflush(SP->_ofp);
+ NC_BUFFERED(FALSE);
+ }
+ returnCode(_nc_set_tty_mode(&cur_term->Ottyb));
+ }
+ returnCode(ERR);
+}
+
+/*
+** savetty() and resetty()
+**
+*/
+
+static TTY buf;
+
+int savetty(void)
+{
+ T((T_CALLED("savetty()")));
+
+ returnCode(_nc_get_tty_mode(&buf));
+}
+
+int resetty(void)
+{
+ T((T_CALLED("resetty()")));
+
+ returnCode(_nc_set_tty_mode(&buf));
+}
diff --git a/lib/libcurses/tinfo/make_keys.c b/lib/libcurses/tinfo/make_keys.c
new file mode 100644
index 00000000000..70617a42519
--- /dev/null
+++ b/lib/libcurses/tinfo/make_keys.c
@@ -0,0 +1,136 @@
+/* $OpenBSD: make_keys.c,v 1.1 1999/01/18 19:10:21 millert 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> 1997 *
+ ****************************************************************************/
+
+/*
+ * This replaces an awk script which translated keys.list into keys.tries by
+ * making the output show the indices into the TERMTYPE Strings array. Doing
+ * it that way lets us cut down on the size of the init_keytry() function.
+ */
+#include <curses.priv.h>
+
+MODULE_ID("$From: make_keys.c,v 1.4 1998/02/11 12:13:57 tom Exp $")
+
+#include <names.c>
+
+#define UNKNOWN (SIZEOF(strnames) + SIZEOF(strfnames))
+
+static size_t lookup(const char *name)
+{
+ size_t n;
+ bool found = FALSE;
+ for (n = 0; strnames[n] != 0; n++) {
+ if (!strcmp(name, strnames[n])) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found) {
+ for (n = 0; strfnames[n] != 0; n++) {
+ if (!strcmp(name, strfnames[n])) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ return found ? n : UNKNOWN;
+}
+
+static void make_keys(FILE *ifp, FILE *ofp)
+{
+ char buffer[BUFSIZ];
+ char from[BUFSIZ];
+ char to[BUFSIZ];
+ int maxlen = 16;
+
+ while (fgets(buffer, sizeof(buffer), ifp) != 0) {
+ if (*buffer == '#')
+ continue;
+ if (sscanf(buffer, "%s %s", to, from) == 2) {
+ int code = lookup(from);
+ if (code == UNKNOWN)
+ continue;
+ if ((int)strlen(from) > maxlen)
+ maxlen = strlen(from);
+ fprintf(ofp, "\t{ %4d, %-*.*s },\t/* %s */\n",
+ code,
+ maxlen, maxlen,
+ to,
+ from);
+ }
+ }
+}
+
+static void write_list(FILE *ofp, const char **list)
+{
+ while (*list != 0)
+ fprintf(ofp, "%s\n", *list++);
+}
+
+int main(int argc, char *argv[])
+{
+ static const char *prefix[] = {
+ "#ifndef NCU_KEYS_H",
+ "#define NCU_KEYS_H 1",
+ "",
+ "/* This file was generated by MAKE_KEYS */",
+ "",
+ "static const struct {",
+ "\tunsigned offset;",
+ "\tchtype code;",
+ "} table[] = {",
+ 0
+ };
+ static const char *suffix[] = {
+ "};",
+ "",
+ "#endif /* NCU_KEYS_H */",
+ 0
+ };
+
+ write_list(stdout, prefix);
+ if (argc > 1) {
+ int n;
+ for (n = 1; n < argc; n++) {
+ FILE *fp = fopen(argv[n], "r");
+ if (fp != 0) {
+ make_keys(fp, stdout);
+ fclose(fp);
+ }
+ }
+ } else {
+ make_keys(stdin, stdout);
+ }
+ write_list(stdout, suffix);
+ return EXIT_SUCCESS;
+}
diff --git a/lib/libcurses/tinfo/name_match.c b/lib/libcurses/tinfo/name_match.c
new file mode 100644
index 00000000000..814e780a4d4
--- /dev/null
+++ b/lib/libcurses/tinfo/name_match.c
@@ -0,0 +1,87 @@
+/* $OpenBSD: name_match.c,v 1.1 1999/01/18 19:10:21 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+#include <term.h>
+#include <tic.h>
+
+MODULE_ID("$From: name_match.c,v 1.7 1998/09/19 20:27:49 Todd.Miller Exp $")
+
+/*
+ * _nc_first_name(char *names)
+ *
+ * Extract the primary name from a compiled entry.
+ */
+
+char *_nc_first_name(const char *const sp)
+/* get the first name from the given name list */
+{
+ static char buf[MAX_NAME_SIZE+1];
+ register char *cp;
+
+ (void) strlcpy(buf, sp, sizeof(buf));
+
+ cp = strchr(buf, '|');
+ if (cp)
+ *cp = '\0';
+
+ return(buf);
+}
+
+/*
+ * int _nc_name_match(namelist, name, delim)
+ *
+ * Is the given name matched in namelist?
+ */
+
+int _nc_name_match(const char *const namelst, const char *const name, const char *const delim)
+/* microtune this, it occurs in several critical loops */
+{
+char namecopy[MAX_ENTRY_SIZE]; /* this may get called on a TERMCAP value */
+register char *cp;
+
+ if (namelst == 0)
+ return(FALSE);
+ (void) strlcpy (namecopy, namelst, sizeof(namecopy));
+ if ((cp = strtok(namecopy, delim)) != 0) {
+ do {
+ /* avoid strcmp() function-call cost if possible */
+ if (cp[0] == name[0] && strcmp(cp, name) == 0)
+ return(TRUE);
+ } while
+ ((cp = strtok((char *)0, delim)) != 0);
+ }
+ return(FALSE);
+}
diff --git a/lib/libcurses/tinfo/parse_entry.c b/lib/libcurses/tinfo/parse_entry.c
new file mode 100644
index 00000000000..ed44a9840d7
--- /dev/null
+++ b/lib/libcurses/tinfo/parse_entry.c
@@ -0,0 +1,924 @@
+/* $OpenBSD: parse_entry.c,v 1.1 1999/01/18 19:10:21 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * parse_entry.c -- compile one terminfo or termcap entry
+ *
+ * Get an exact in-core representation of an entry. Don't
+ * try to resolve use or tc capabilities, that is someone
+ * else's job. Depends on the lexical analyzer to get tokens
+ * from the input stream.
+ */
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+#include <tic.h>
+#define __INTERNAL_CAPS_VISIBLE
+#include <term.h>
+#include <term_entry.h>
+
+MODULE_ID("$From: parse_entry.c,v 1.24 1998/07/04 23:08:38 tom Exp $")
+
+#ifdef LINT
+static short const parametrized[] = { 0 };
+#else
+#include <parametrized.h>
+#endif
+
+struct token _nc_curr_token;
+
+static void postprocess_termcap(TERMTYPE *, bool);
+static void postprocess_terminfo(TERMTYPE *);
+static struct name_table_entry const * lookup_fullname(const char *name);
+
+/*
+ * int
+ * _nc_parse_entry(entry, literal, silent)
+ *
+ * Compile one entry. Doesn't try to resolve use or tc capabilities.
+ *
+ * found-forward-use = FALSE
+ * re-initialise internal arrays
+ * get_token();
+ * if the token was not a name in column 1, complain and die
+ * save names in entry's string table
+ * while (get_token() is not EOF and not NAMES)
+ * check for existance and type-correctness
+ * enter cap into structure
+ * if STRING
+ * save string in entry's string table
+ * push back token
+ */
+
+int _nc_parse_entry(struct entry *entryp, int literal, bool silent)
+{
+ int token_type;
+ struct name_table_entry const *entry_ptr;
+ char *ptr, namecpy[MAX_NAME_SIZE+1];
+
+ token_type = _nc_get_token();
+
+ if (token_type == EOF)
+ return(EOF);
+ if (token_type != NAMES)
+ _nc_err_abort("Entry does not start with terminal names in column one");
+
+ _nc_init_entry(&entryp->tterm);
+
+ entryp->cstart = _nc_comment_start;
+ entryp->cend = _nc_comment_end;
+ entryp->startline = _nc_start_line;
+ DEBUG(2, ("Comment range is %ld to %ld", entryp->cstart, entryp->cend));
+
+ /* junk the 2-character termcap name, if present */
+ ptr = _nc_curr_token.tk_name;
+ if (ptr[2] == '|')
+ {
+ ptr = _nc_curr_token.tk_name + 3;
+ _nc_curr_token.tk_name[2] = '\0';
+ }
+
+ entryp->tterm.str_table = entryp->tterm.term_names = _nc_save_str(ptr);
+
+ DEBUG(1, ("Starting '%s'", ptr));
+
+ /*
+ * We do this because the one-token lookahead in the parse loop
+ * results in the terminal type getting prematurely set to correspond
+ * to that of the next entry.
+ */
+ _nc_set_type(_nc_first_name(entryp->tterm.term_names));
+
+ /* check for overly-long names and aliases */
+ (void) strlcpy(namecpy, entryp->tterm.term_names, sizeof(namecpy));
+ if ((ptr = strrchr(namecpy, '|')) != (char *)0)
+ *ptr = '\0';
+ ptr = strtok(namecpy, "|");
+ if (strlen(ptr) > MAX_ALIAS)
+ _nc_warning("primary name may be too long");
+ while ((ptr = strtok((char *)0, "|")) != (char *)0)
+ if (strlen(ptr) > MAX_ALIAS)
+ _nc_warning("alias `%s' may be too long", ptr);
+
+ entryp->nuses = 0;
+
+ for (token_type = _nc_get_token();
+ token_type != EOF && token_type != NAMES;
+ token_type = _nc_get_token())
+ {
+ if (strcmp(_nc_curr_token.tk_name, "use") == 0
+ || strcmp(_nc_curr_token.tk_name, "tc") == 0) {
+ entryp->uses[entryp->nuses].parent = (void *)_nc_save_str(_nc_curr_token.tk_valstring);
+ entryp->uses[entryp->nuses].line = _nc_curr_line;
+ entryp->nuses++;
+ } else {
+ /* normal token lookup */
+ entry_ptr = _nc_find_entry(_nc_curr_token.tk_name,
+ _nc_syntax ? _nc_cap_hash_table : _nc_info_hash_table);
+
+ /*
+ * Our kluge to handle aliasing. The reason it's done
+ * this ugly way, with a linear search, is so the hashing
+ * machinery doesn't have to be made really complicated
+ * (also we get better warnings this way). No point in
+ * making this case fast, aliased caps aren't common now
+ * and will get rarer.
+ */
+ if (entry_ptr == NOTFOUND)
+ {
+ const struct alias *ap;
+
+ if (_nc_syntax == SYN_TERMCAP)
+ {
+ for (ap = _nc_capalias_table; ap->from; ap++)
+ if (strcmp(ap->from, _nc_curr_token.tk_name) == 0)
+ {
+ if (ap->to == (char *)0)
+ {
+ _nc_warning("%s (%s termcap extension) ignored",
+ ap->from, ap->source);
+ goto nexttok;
+ }
+
+ entry_ptr = _nc_find_entry(ap->to, _nc_cap_hash_table);
+ if (entry_ptr && !silent)
+ _nc_warning("%s (%s termcap extension) aliased to %s", ap->from, ap->source, ap->to);
+ break;
+ }
+ }
+ else /* if (_nc_syntax == SYN_TERMINFO) */
+ {
+ for (ap = _nc_infoalias_table; ap->from; ap++)
+ if (strcmp(ap->from, _nc_curr_token.tk_name) == 0)
+ {
+ if (ap->to == (char *)0)
+ {
+ _nc_warning("%s (%s terminfo extension) ignored",
+ ap->from, ap->source);
+ goto nexttok;
+ }
+
+ entry_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);
+ if (entry_ptr && !silent)
+ _nc_warning("%s (%s terminfo extension) aliased to %s", ap->from, ap->source, ap->to);
+ break;
+ }
+
+ /* last chance: a full-name */
+ if (entry_ptr == NOTFOUND) {
+ entry_ptr = lookup_fullname(_nc_curr_token.tk_name);
+ }
+ }
+ }
+
+ /* can't find this cap name, not even as an alias */
+ if (entry_ptr == NOTFOUND) {
+ if (!silent)
+ _nc_warning("unknown capability '%s'",
+ _nc_curr_token.tk_name);
+ continue;
+ }
+
+ /* deal with bad type/value combinations. */
+ if (token_type != CANCEL && entry_ptr->nte_type != token_type)
+ {
+ /*
+ * Nasty special cases here handle situations in which type
+ * information can resolve name clashes. Normal lookup
+ * finds the last instance in the capability table of a
+ * given name, regardless of type. find_type_entry looks
+ * for a first matching instance with given type. So as
+ * long as all ambiguous names occur in pairs of distinct
+ * type, this will do the job.
+ */
+
+ /* tell max_attributes from arrow_key_map */
+ if (token_type == NUMBER && !strcmp("ma", _nc_curr_token.tk_name))
+ entry_ptr = _nc_find_type_entry("ma", NUMBER,
+ _nc_get_table(_nc_syntax != 0));
+
+ /* map terminfo's string MT to MT */
+ else if (token_type==STRING &&!strcmp("MT",_nc_curr_token.tk_name))
+ entry_ptr = _nc_find_type_entry("MT", STRING,
+ _nc_get_table(_nc_syntax != 0));
+
+ /* treat strings without following "=" as empty strings */
+ else if (token_type==BOOLEAN && entry_ptr->nte_type==STRING)
+ token_type = STRING;
+ /* we couldn't recover; skip this token */
+ else
+ {
+ if (!silent)
+ {
+ const char *type_name;
+ switch (entry_ptr->nte_type)
+ {
+ case BOOLEAN:
+ type_name = "boolean";
+ break;
+ case STRING:
+ type_name = "string";
+ break;
+ case NUMBER:
+ type_name = "numeric";
+ break;
+ default:
+ type_name = "unknown";
+ break;
+ }
+ _nc_warning("wrong type used for %s capability '%s'",
+ type_name, _nc_curr_token.tk_name);
+ }
+ continue;
+ }
+ }
+
+ /* now we know that the type/value combination is OK */
+ switch (token_type) {
+ case CANCEL:
+ switch (entry_ptr->nte_type) {
+ case BOOLEAN:
+ entryp->tterm.Booleans[entry_ptr->nte_index] = CANCELLED_BOOLEAN;
+ break;
+
+ case NUMBER:
+ entryp->tterm.Numbers[entry_ptr->nte_index] = CANCELLED_NUMERIC;
+ break;
+
+ case STRING:
+ entryp->tterm.Strings[entry_ptr->nte_index] = CANCELLED_STRING;
+ break;
+ }
+ break;
+
+ case BOOLEAN:
+ entryp->tterm.Booleans[entry_ptr->nte_index] = TRUE;
+ break;
+
+ case NUMBER:
+ entryp->tterm.Numbers[entry_ptr->nte_index] =
+ _nc_curr_token.tk_valnumber;
+ break;
+
+ case STRING:
+ ptr = _nc_curr_token.tk_valstring;
+ if (_nc_syntax==SYN_TERMCAP)
+ ptr = _nc_captoinfo(_nc_curr_token.tk_name,
+ ptr,
+ parametrized[entry_ptr->nte_index]);
+ entryp->tterm.Strings[entry_ptr->nte_index] = _nc_save_str(ptr);
+ break;
+
+ default:
+ if (!silent)
+ _nc_warning("unknown token type");
+ _nc_panic_mode((_nc_syntax==SYN_TERMCAP) ? ':' : ',');
+ continue;
+ }
+ } /* end else cur_token.name != "use" */
+ nexttok:
+ continue; /* cannot have a label w/o statement */
+ } /* endwhile (not EOF and not NAMES) */
+
+ _nc_push_token(token_type);
+ _nc_set_type(_nc_first_name(entryp->tterm.term_names));
+
+ /*
+ * Try to deduce as much as possible from extension capabilities
+ * (this includes obsolete BSD capabilities). Sigh...it would be more
+ * space-efficient to call this after use resolution, but it has
+ * to be done before entry allocation is wrapped up.
+ */
+ if (!literal) {
+ if (_nc_syntax == SYN_TERMCAP)
+ {
+ bool has_base_entry = FALSE;
+ int i;
+
+ /*
+ * Don't insert defaults if this is a `+' entry meant only
+ * for inclusion in other entries (not sure termcap ever
+ * had these, actually).
+ */
+ if (strchr(entryp->tterm.term_names, '+'))
+ has_base_entry = TRUE;
+ else
+ /*
+ * Otherwise, look for a base entry that will already
+ * have picked up defaults via translation.
+ */
+ for (i = 0; i < entryp->nuses; i++)
+ if (!strchr(entryp->uses[i].parent, '+'))
+ has_base_entry = TRUE;
+
+ postprocess_termcap(&entryp->tterm, has_base_entry);
+ }
+ else
+ postprocess_terminfo(&entryp->tterm);
+ }
+ _nc_wrap_entry(entryp);
+
+ return(OK);
+}
+
+int _nc_capcmp(const char *s, const char *t)
+/* compare two string capabilities, stripping out padding */
+{
+ if (!s && !t)
+ return(0);
+ else if (!s || !t)
+ return(1);
+
+ for (;;)
+ {
+ if (s[0] == '$' && s[1] == '<')
+ {
+ for (s += 2; ; s++)
+ if (!(isdigit(*s) || *s=='.' || *s=='*' || *s=='/' || *s=='>'))
+ break;
+ }
+
+ if (t[0] == '$' && t[1] == '<')
+ {
+ for (t += 2; ; t++)
+ if (!(isdigit(*t) || *t=='.' || *t=='*' || *t=='/' || *t=='>'))
+ break;
+ }
+
+ /* we've now pushed s and t past any padding they were pointing at */
+
+ if (*s == '\0' && *t == '\0')
+ return(0);
+
+ if (*s != *t)
+ return(*t - *s);
+
+ /* else *s == *t but one is not NUL, so continue */
+ s++, t++;
+ }
+}
+
+/*
+ * The ko capability, if present, consists of a comma-separated capability
+ * list. For each capability, we may assume there is a keycap that sends the
+ * string which is the value of that capability.
+ */
+typedef struct {const char *from; const char *to;} assoc;
+static assoc const ko_xlate[] =
+{
+ {"al", "kil1"}, /* insert line key -> KEY_IL */
+ {"bt", "kcbt"}, /* back tab -> KEY_BTAB */
+ {"cd", "ked"}, /* clear-to-eos key -> KEY_EOL */
+ {"ce", "kel"}, /* clear-to-eol key -> KEY_EOS */
+ {"cl", "kclr"}, /* clear key -> KEY_CLEAR */
+ {"ct", "tbc"}, /* clear all tabs -> KEY_CATAB */
+ {"dc", "kdch1"}, /* delete char -> KEY_DC */
+ {"dl", "kdl1"}, /* delete line -> KEY_DL */
+ {"do", "kcud1"}, /* down key -> KEY_DOWN */
+ {"ei", "krmir"}, /* exit insert key -> KEY_EIC */
+ {"ho", "khome"}, /* home key -> KEY_HOME */
+ {"ic", "kich1"}, /* insert char key -> KEY_IC */
+ {"im", "kIC"}, /* insert-mode key -> KEY_SIC */
+ {"le", "kcub1"}, /* le key -> KEY_LEFT */
+ {"nd", "kcuf1"}, /* nd key -> KEY_RIGHT */
+ {"nl", "kent"}, /* new line key -> KEY_ENTER */
+ {"st", "khts"}, /* set-tab key -> KEY_STAB */
+ {"ta", CANCELLED_STRING},
+ {"up", "kcuu1"}, /* up-arrow key -> KEY_UP */
+ {(char *)0, (char *)0},
+};
+
+/*
+ * This routine fills in string caps that either had defaults under
+ * termcap or can be manufactured from obsolete termcap capabilities.
+ * It was lifted from Ross Ridge's mytinfo package.
+ */
+
+static const char C_CR[] = "\r";
+static const char C_LF[] = "\n";
+static const char C_BS[] = "\b";
+static const char C_HT[] = "\t";
+
+/*
+ * Note that WANTED and PRESENT are not simple inverses! If a capability
+ * has been explicitly cancelled, it's not considered WANTED.
+ */
+#define WANTED(s) ((s) == ABSENT_STRING)
+#define PRESENT(s) (((s) != ABSENT_STRING) && ((s) != CANCELLED_STRING))
+
+/*
+ * 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 postprocess_termcap(TERMTYPE *tp, bool has_base)
+{
+ char buf[MAX_LINE * 2 + 2];
+
+ /*
+ * TERMCAP DEFAULTS AND OBSOLETE-CAPABILITY TRANSLATIONS
+ *
+ * This first part of the code is the functional inverse of the
+ * fragment in capdefaults.c.
+ * ----------------------------------------------------------------------
+ */
+
+ /* if there was a tc entry, assume we picked up defaults via that */
+ if (!has_base)
+ {
+ if (WANTED(init_3string) && termcap_init2)
+ init_3string = _nc_save_str(termcap_init2);
+
+ if (WANTED(reset_2string) && termcap_reset)
+ reset_2string = _nc_save_str(termcap_reset);
+
+ if (WANTED(carriage_return)) {
+ if (carriage_return_delay > 0) {
+ sprintf(buf, "%s$<%d>", C_CR, carriage_return_delay);
+ carriage_return = _nc_save_str(buf);
+ } else
+ carriage_return = _nc_save_str(C_CR);
+ }
+ if (WANTED(cursor_left)) {
+ if (backspace_delay > 0) {
+ sprintf(buf, "%s$<%d>", C_BS, backspace_delay);
+ cursor_left = _nc_save_str(buf);
+ } else if (backspaces_with_bs == 1)
+ cursor_left = _nc_save_str(C_BS);
+ else if (PRESENT(backspace_if_not_bs))
+ cursor_left = backspace_if_not_bs;
+ }
+ /* vi doesn't use "do", but it does seems to use nl (or '\n') instead */
+ if (WANTED(cursor_down)) {
+ if (PRESENT(linefeed_if_not_lf))
+ cursor_down = linefeed_if_not_lf;
+ else if (linefeed_is_newline != 1) {
+ if (new_line_delay > 0) {
+ sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
+ cursor_down = _nc_save_str(buf);
+ } else
+ cursor_down = _nc_save_str(C_LF);
+ }
+ }
+ if (WANTED(scroll_forward) && crt_no_scrolling != 1) {
+ if (PRESENT(linefeed_if_not_lf))
+ cursor_down = linefeed_if_not_lf;
+ else if (linefeed_is_newline != 1) {
+ if (new_line_delay > 0) {
+ sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
+ scroll_forward = _nc_save_str(buf);
+ } else
+ scroll_forward = _nc_save_str(C_LF);
+ }
+ }
+ if (WANTED(newline)) {
+ if (linefeed_is_newline == 1) {
+ if (new_line_delay > 0) {
+ sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
+ newline = _nc_save_str(buf);
+ } else
+ newline = _nc_save_str(C_LF);
+ } else if (PRESENT(carriage_return) && PRESENT(scroll_forward)) {
+ strlcpy(buf, carriage_return, MAX_LINE+1);
+ strlcat(buf, scroll_forward, MAX_LINE+1);
+ newline = _nc_save_str(buf);
+ } else if (PRESENT(carriage_return) && PRESENT(cursor_down)) {
+ strlcpy(buf, carriage_return, MAX_LINE+1);
+ strlcat(buf, cursor_down, MAX_LINE+1);
+ newline = _nc_save_str(buf);
+ }
+ }
+ }
+
+ /*
+ * Inverse of capdefaults.c code ends here.
+ * ----------------------------------------------------------------------
+ *
+ * TERMCAP-TO TERMINFO MAPPINGS FOR SOURCE TRANSLATION
+ *
+ * These translations will *not* be inverted by tgetent().
+ */
+
+ if (!has_base)
+ {
+ /*
+ * We wait until now to decide if we've got a working cr because even
+ * one that doesn't work can be used for newline. Unfortunately the
+ * space allocated for it is wasted.
+ */
+ if (return_does_clr_eol == 1 || no_correctly_working_cr == 1)
+ carriage_return = ABSENT_STRING;
+
+ /*
+ * Supposedly most termcap entries have ta now and '\t' is no longer a
+ * default, but it doesn't seem to be true...
+ */
+ if (WANTED(tab)) {
+ if (horizontal_tab_delay > 0) {
+ sprintf(buf, "%s$<%d>", C_HT, horizontal_tab_delay);
+ tab = _nc_save_str(buf);
+ } else
+ tab = _nc_save_str(C_HT);
+ }
+ if (init_tabs == ABSENT_NUMERIC && has_hardware_tabs == TRUE)
+ init_tabs = 8;
+
+ /*
+ * Assume we can beep with ^G unless we're given bl@.
+ */
+ if (WANTED(bell))
+ bell = _nc_save_str("\007");
+ }
+
+ /*
+ * Translate the old termcap :pt: capability to it#8 + ht=\t
+ */
+ if (has_hardware_tabs == TRUE) {
+ if (init_tabs != 8 && init_tabs != ABSENT_NUMERIC)
+ _nc_warning("hardware tabs with a width other than 8: %d", init_tabs);
+ else
+ {
+ if (tab && _nc_capcmp(tab, C_HT))
+ _nc_warning("hardware tabs with a non-^I tab string %s",
+ _nc_visbuf(tab));
+ else
+ {
+ if (WANTED(tab))
+ tab = _nc_save_str(C_HT);
+ init_tabs = 8;
+ }
+ }
+ }
+ /*
+ * Now translate the ko capability, if there is one. This
+ * isn't from mytinfo...
+ */
+ if (PRESENT(other_non_function_keys))
+ {
+ char *dp, *cp = strtok(other_non_function_keys, ",");
+ struct name_table_entry const *from_ptr;
+ struct name_table_entry const *to_ptr;
+ assoc const *ap;
+ char buf2[MAX_TERMINFO_LENGTH];
+ bool foundim;
+
+ /* we're going to use this for a special case later */
+ dp = strchr(other_non_function_keys, 'i');
+ foundim = dp && dp[1] == 'm';
+
+ /* look at each comma-separated capability in the ko string... */
+ do {
+ for (ap = ko_xlate; ap->from; ap++)
+ if (strcmp(ap->from, cp) == 0)
+ break;
+ if (!ap->to)
+ {
+ _nc_warning("unknown capability `%s' in ko string", cp);
+ continue;
+ }
+ else if (ap->to == CANCELLED_STRING) /* ignore it */
+ continue;
+
+ /* now we know we found a match in ko_table, so... */
+
+ from_ptr = _nc_find_entry(ap->from, _nc_cap_hash_table);
+ to_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);
+
+ if (!from_ptr || !to_ptr) /* should never happen! */
+ _nc_err_abort("ko translation table is invalid, I give up");
+
+ if (WANTED(tp->Strings[from_ptr->nte_index]))
+ {
+ _nc_warning("no value for ko capability %s", ap->from);
+ continue;
+ }
+
+ if (tp->Strings[to_ptr->nte_index])
+ {
+ /* There's no point in warning about it if it's the same
+ * string; that's just an inefficiency.
+ */
+ if (strcmp(
+ tp->Strings[from_ptr->nte_index],
+ tp->Strings[to_ptr->nte_index]) != 0)
+ _nc_warning("%s (%s) already has an explicit value %s, ignoring ko",
+ ap->to, ap->from,
+ _nc_visbuf(tp->Strings[to_ptr->nte_index]) );
+ continue;
+ }
+
+ /*
+ * The magic moment -- copy the mapped key string over,
+ * stripping out padding.
+ */
+ dp = buf2;
+ for (cp = tp->Strings[from_ptr->nte_index]; *cp; cp++)
+ {
+ if (cp[0] == '$' && cp[1] == '<')
+ {
+ while (*cp && *cp != '>')
+ if (!*cp)
+ break;
+ else
+ ++cp;
+ }
+ else
+ *dp++ = *cp;
+ }
+ *dp++ = '\0';
+
+ tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
+ } while
+ ((cp = strtok((char *)0, ",")) != 0);
+
+ /*
+ * Note: ko=im and ko=ic both want to grab the `Insert'
+ * keycap. There's a kich1 but no ksmir, so the ic capability
+ * got mapped to kich1 and im to kIC to avoid a collision.
+ * If the description has im but not ic, hack kIC back to kich1.
+ */
+ if (foundim && WANTED(key_ic) && key_sic)
+ {
+ key_ic = key_sic;
+ key_sic = ABSENT_STRING;
+ }
+ }
+
+ if (!hard_copy)
+ {
+ if (WANTED(key_backspace))
+ key_backspace = _nc_save_str(C_BS);
+ if (WANTED(key_left))
+ key_left = _nc_save_str(C_BS);
+ if (WANTED(key_down))
+ key_down = _nc_save_str(C_LF);
+ }
+
+ /*
+ * Translate XENIX forms characters.
+ */
+ if (PRESENT(acs_ulcorner) ||
+ PRESENT(acs_llcorner) ||
+ PRESENT(acs_urcorner) ||
+ PRESENT(acs_lrcorner) ||
+ PRESENT(acs_ltee) ||
+ PRESENT(acs_rtee) ||
+ PRESENT(acs_btee) ||
+ PRESENT(acs_ttee) ||
+ PRESENT(acs_hline) ||
+ PRESENT(acs_vline) ||
+ PRESENT(acs_plus))
+ {
+ char buf2[MAX_TERMCAP_LENGTH], *bp = buf2;
+
+ if (acs_chars)
+ {
+ (void)strcpy(bp, acs_chars);
+ bp += strlen(bp);
+ }
+
+ if (acs_ulcorner && acs_ulcorner[1] == '\0')
+ {
+ *bp++ = 'l';
+ *bp++ = *acs_ulcorner;
+ }
+ if (acs_llcorner && acs_llcorner[1] == '\0')
+ {
+ *bp++ = 'm';
+ *bp++ = *acs_llcorner;
+ }
+ if (acs_urcorner && acs_urcorner[1] == '\0')
+ {
+ *bp++ = 'k';
+ *bp++ = *acs_urcorner;
+ }
+ if (acs_lrcorner && acs_lrcorner[1] == '\0')
+ {
+ *bp++ = 'j';
+ *bp++ = *acs_lrcorner;
+ }
+ if (acs_ltee && acs_ltee[1] == '\0')
+ {
+ *bp++ = 't';
+ *bp++ = *acs_ltee;
+ }
+ if (acs_rtee && acs_rtee[1] == '\0')
+ {
+ *bp++ = 'u';
+ *bp++ = *acs_rtee;
+ }
+ if (acs_btee && acs_btee[1] == '\0')
+ {
+ *bp++ = 'v';
+ *bp++ = *acs_btee;
+ }
+ if (acs_ttee && acs_ttee[1] == '\0')
+ {
+ *bp++ = 'w';
+ *bp++ = *acs_ttee;
+ }
+ if (acs_hline && acs_hline[1] == '\0')
+ {
+ *bp++ = 'q';
+ *bp++ = *acs_hline;
+ }
+ if (acs_vline && acs_vline[1] == '\0')
+ {
+ *bp++ = 'x';
+ *bp++ = *acs_vline;
+ }
+ if (acs_plus)
+ {
+ *bp++ = 'n';
+ strcpy(bp, acs_plus);
+ bp = buf2 + strlen(buf2);
+ }
+
+ if (bp != buf2)
+ {
+ *bp++ = '\0';
+ acs_chars = _nc_save_str(buf2);
+ _nc_warning("acsc string synthesized from XENIX capabilities");
+ }
+ }
+ else if (acs_chars == 0
+ && enter_alt_charset_mode != 0
+ && exit_alt_charset_mode != 0)
+ {
+ acs_chars = _nc_save_str("``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~");
+ }
+}
+
+static
+void postprocess_terminfo(TERMTYPE *tp)
+{
+ /*
+ * TERMINFO-TO-TERMINFO MAPPINGS FOR SOURCE TRANSLATION
+ * ----------------------------------------------------------------------
+ */
+
+ /*
+ * Translate AIX forms characters.
+ */
+ if (PRESENT(box_chars_1))
+ {
+ char buf2[MAX_TERMCAP_LENGTH], *bp = buf2;
+
+ if (acs_chars)
+ {
+ (void)strcpy(bp, acs_chars);
+ bp += strlen(bp);
+ }
+
+ if (box_chars_1[0]) /* ACS_ULCORNER */
+ {
+ *bp++ = 'l';
+ *bp++ = box_chars_1[0];
+ }
+ if (box_chars_1[1]) /* ACS_HLINE */
+ {
+ *bp++ = 'q';
+ *bp++ = box_chars_1[1];
+ }
+ if (box_chars_1[2]) /* ACS_URCORNER */
+ {
+ *bp++ = 'k';
+ *bp++ = box_chars_1[2];
+ }
+ if (box_chars_1[3]) /* ACS_VLINE */
+ {
+ *bp++ = 'x';
+ *bp++ = box_chars_1[3];
+ }
+ if (box_chars_1[4]) /* ACS_LRCORNER */
+ {
+ *bp++ = 'j';
+ *bp++ = box_chars_1[4];
+ }
+ if (box_chars_1[5]) /* ACS_LLCORNER */
+ {
+ *bp++ = 'm';
+ *bp++ = box_chars_1[5];
+ }
+ if (box_chars_1[6]) /* ACS_TTEE */
+ {
+ *bp++ = 'w';
+ *bp++ = box_chars_1[6];
+ }
+ if (box_chars_1[7]) /* ACS_RTEE */
+ {
+ *bp++ = 'u';
+ *bp++ = box_chars_1[7];
+ }
+ if (box_chars_1[8]) /* ACS_BTEE */
+ {
+ *bp++ = 'v';
+ *bp++ = box_chars_1[8];
+ }
+ if (box_chars_1[9]) /* ACS_LTEE */
+ {
+ *bp++ = 't';
+ *bp++ = box_chars_1[9];
+ }
+ if (box_chars_1[10]) /* ACS_PLUS */
+ {
+ *bp++ = 'n';
+ *bp++ = box_chars_1[10];
+ }
+
+ if (bp != buf2)
+ {
+ *bp++ = '\0';
+ acs_chars = _nc_save_str(buf2);
+ _nc_warning("acsc string synthesized from AIX capabilities");
+ box_chars_1 = ABSENT_STRING;
+ }
+ }
+ /*
+ * ----------------------------------------------------------------------
+ */
+}
+
+/*
+ * Do a linear search through the terminfo tables to find a given full-name.
+ * We don't expect to do this often, so there's no hashing function.
+ *
+ * In effect, this scans through the 3 lists of full-names, and looks them
+ * up in _nc_info_table, which is organized so that the nte_index fields are
+ * sorted, but the nte_type fields are not necessarily grouped together.
+ */
+static
+struct name_table_entry const * lookup_fullname(const char *find)
+{
+ int state = -1;
+
+ for (;;) {
+ int count = 0;
+ NCURSES_CONST char *const *names;
+
+ switch (++state) {
+ case BOOLEAN:
+ names = boolfnames;
+ break;
+ case STRING:
+ names = strfnames;
+ break;
+ case NUMBER:
+ names = numfnames;
+ break;
+ default:
+ return NOTFOUND;
+ }
+
+ for (count = 0; names[count] != 0; count++) {
+ if (!strcmp(names[count], find)) {
+ struct name_table_entry const *entry_ptr = _nc_get_table(FALSE);
+ while (entry_ptr->nte_type != state
+ || entry_ptr->nte_index != count)
+ entry_ptr++;
+ return entry_ptr;
+ }
+ }
+ }
+}
+
+/* parse_entry.c ends here */
diff --git a/lib/libcurses/tinfo/read_bsd_terminfo.c b/lib/libcurses/tinfo/read_bsd_terminfo.c
new file mode 100644
index 00000000000..4e6c6fb1425
--- /dev/null
+++ b/lib/libcurses/tinfo/read_bsd_terminfo.c
@@ -0,0 +1,140 @@
+/* $OpenBSD: read_bsd_terminfo.c,v 1.1 1999/01/18 19:10:22 millert Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
+ * 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 SigmaSoft, Th. Lockert.
+ * 4. The name of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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 AUTHORS 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.
+ */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: read_bsd_terminfo.c,v 1.1 1999/01/18 19:10:22 millert Exp $";
+#endif
+
+#include <curses.priv.h>
+#include <tic.h>
+#include <term.h> /* lines, columns, cur_term */
+#include <term_entry.h>
+
+#define PVECSIZ 32
+#define _PATH_TERMINFO "/usr/share/misc/terminfo"
+
+/*
+ * Look up ``tn'' in the BSD terminfo.db file and fill in ``tp''
+ * with the info we find there.
+ * Returns 1 on success, 0 on failure.
+ */
+int
+_nc_read_bsd_terminfo_entry(tn, tp)
+ const char *tn;
+ TERMTYPE *const tp;
+{
+ char *p;
+ char *dummy;
+ char **fname;
+ int i;
+ char envterm[PATH_MAX]; /* local copy of $TERMINFO */
+ char hometerm[PATH_MAX]; /* local copy of $HOME/.terminfo */
+ char *pathvec[PVECSIZ]; /* to point to names in pathbuf */
+ char namecpy[MAX_NAME_SIZE+1];
+ long num;
+ size_t len;
+
+ fname = pathvec;
+ /* $TERMINFO may hold a path to a terminfo file */
+ if (!issetugid() && (p = getenv("TERMINFO")) != NULL) {
+ len = strlcpy(envterm, p, sizeof(envterm));
+ if (len < sizeof(envterm))
+ *fname++ = envterm;
+ }
+
+ /* Also check $HOME/.terminfo if it exists */
+ if (!issetugid() && (p = getenv("HOME")) != NULL) {
+ len = snprintf(hometerm, sizeof(hometerm), "%s/.terminfo", p);
+ if (len < sizeof(hometerm))
+ *fname++ = hometerm;
+ }
+
+ /* Finally we check the system terminfo file and mark the end of vector */
+ *fname++ = _PATH_TERMINFO;
+ *fname = (char *) 0;
+
+ (void) cgetset(NULL);
+ dummy = NULL;
+ i = cgetent(&dummy, pathvec, (char *)tn);
+
+ if (i == 0) {
+ _nc_init_entry(tp);
+
+ /* Set terminal name(s) */
+ if ((p = strchr(dummy, ':')) != NULL)
+ *p = '\0';
+ if ((tp->str_table = tp->term_names = strdup(dummy)) == NULL)
+ return (0);
+ _nc_set_type(_nc_first_name(tp->term_names));
+ if (p)
+ *p = ':';
+
+ /* Truncate overly-long names and aliases */
+ (void)strlcpy(namecpy, tp->term_names, sizeof(namecpy));
+ if ((p = strrchr(namecpy, '|')) != (char *)NULL)
+ *p = '\0';
+ p = strtok(namecpy, "|");
+ if (strlen(p) > MAX_ALIAS)
+ _nc_warning("primary name may be too long");
+ while ((p = strtok((char *)NULL, "|")) != (char *)NULL)
+ if (strlen(p) > MAX_ALIAS)
+ _nc_warning("alias `%s' may be too long", p);
+
+ /* Copy capabilities */
+ for (i = 0 ; i < BOOLCOUNT ; i++) {
+ if (cgetcap(dummy, (char *)boolnames[i], ':') == NULL)
+ tp->Booleans[i] = FALSE;
+ else
+ tp->Booleans[i] = TRUE;
+ }
+ for (i = 0 ; i < NUMCOUNT ; i++) {
+ if (cgetnum(dummy, (char *)numnames[i], &num) < 0)
+ tp->Numbers[i] = 0;
+ else
+ tp->Numbers[i] = (int)num;
+ }
+ for (i = 0 ; i < STRCOUNT ; i++) {
+ if (cgetstr(dummy, (char *)strnames[i], &p) < 0)
+ tp->Strings[i] = NULL;
+ else
+ tp->Strings[i] = p;
+ }
+ i = 0;
+ }
+
+ /* We are done with the returned getcap buffer now; free it */
+ if (dummy)
+ free(dummy);
+
+ return ((i == 0));
+}
diff --git a/lib/libcurses/tinfo/read_entry.c b/lib/libcurses/tinfo/read_entry.c
new file mode 100644
index 00000000000..9ebf0779912
--- /dev/null
+++ b/lib/libcurses/tinfo/read_entry.c
@@ -0,0 +1,362 @@
+/* $OpenBSD: read_entry.c,v 1.1 1999/01/18 19:10:22 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+
+/*
+ * read_entry.c -- Routine for reading in a compiled terminfo file
+ *
+ */
+
+#include <curses.priv.h>
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <term.h>
+#include <tic.h>
+
+MODULE_ID("$From: read_entry.c,v 1.47 1998/12/20 02:51:50 tom Exp $")
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/*
+ * int
+ * _nc_read_file_entry(filename, ptr)
+ *
+ * Read the compiled terminfo entry in the given file into the
+ * structure pointed to by ptr, allocating space for the string
+ * table.
+ */
+
+#undef BYTE
+#define BYTE(p,n) (unsigned char)((p)[n])
+
+#define IS_NEG1(p) ((BYTE(p,0) == 0377) && (BYTE(p,1) == 0377))
+#define IS_NEG2(p) ((BYTE(p,0) == 0376) && (BYTE(p,1) == 0377))
+#define LOW_MSB(p) (BYTE(p,0) + 256*BYTE(p,1))
+
+static bool have_tic_directory = FALSE;
+static bool keep_tic_directory = FALSE;
+
+/*
+ * Record the "official" location of the terminfo directory, according to
+ * the place where we're writing to, or the normal default, if not.
+ */
+const char *_nc_tic_dir(const char *path)
+{
+ static const char *result = TERMINFO;
+
+ if (!keep_tic_directory) {
+ if (path != 0) {
+ result = path;
+ have_tic_directory = TRUE;
+ } else if (!have_tic_directory) {
+ char *envp;
+ if (!issetugid() && (envp = getenv("TERMINFO")) != 0)
+ return _nc_tic_dir(envp);
+ }
+ }
+ return result;
+}
+
+/*
+ * Special fix to prevent the terminfo directory from being moved after tic
+ * has chdir'd to it. If we let it be changed, then if $TERMINFO has a
+ * relative path, we'll lose track of the actual directory.
+ */
+void _nc_keep_tic_dir(const char *path)
+{
+ _nc_tic_dir(path);
+ keep_tic_directory = TRUE;
+}
+
+int _nc_read_file_entry(const char *const filename, TERMTYPE *ptr)
+/* return 1 if read, 0 if not found or garbled */
+{
+ int name_size, bool_count, num_count, str_count, str_size;
+ int i, fd, numread;
+ char buf[MAX_ENTRY_SIZE];
+
+ if (_nc_access(filename, R_OK) < 0
+ || (fd = open(filename, O_RDONLY|O_BINARY)) < 0) {
+ T(("cannot open terminfo %s (errno=%d)", filename, errno));
+ return(0);
+ }
+
+ T(("read terminfo %s", filename));
+
+ /* grab the header */
+ (void) read(fd, buf, 12);
+ if (LOW_MSB(buf) != MAGIC)
+ {
+ close(fd);
+ return(0);
+ }
+ name_size = LOW_MSB(buf + 2);
+ bool_count = LOW_MSB(buf + 4);
+ num_count = LOW_MSB(buf + 6);
+ str_count = LOW_MSB(buf + 8);
+ str_size = LOW_MSB(buf + 10);
+
+ if (str_size)
+ {
+ /* try to allocate space for the string table */
+ ptr->str_table = malloc((unsigned)str_size);
+ if (ptr->str_table == 0)
+ {
+ close(fd);
+ return(0);
+ }
+ }
+ else
+ str_count = 0;
+
+ /* grab the name */
+ read(fd, buf, min(MAX_NAME_SIZE, (unsigned)name_size));
+ buf[MAX_NAME_SIZE] = '\0';
+ ptr->term_names = calloc(strlen(buf) + 1, sizeof(char));
+ if (ptr->term_names == NULL) {
+ if (str_size)
+ free(ptr->str_table);
+ close(fd);
+ return(0);
+ }
+ (void) strcpy(ptr->term_names, buf);
+ if (name_size > MAX_NAME_SIZE)
+ lseek(fd, (off_t) (name_size - MAX_NAME_SIZE), 1);
+
+ /* grab the booleans */
+ read(fd, ptr->Booleans, min(BOOLCOUNT, (unsigned)bool_count));
+ if (bool_count > BOOLCOUNT)
+ lseek(fd, (off_t) (bool_count - BOOLCOUNT), 1);
+ else
+ for (i=bool_count; i < BOOLCOUNT; i++)
+ ptr->Booleans[i] = 0;
+
+ /*
+ * If booleans end on an odd byte, skip it. The machine they
+ * originally wrote terminfo on must have been a 16-bit
+ * word-oriented machine that would trap out if you tried a
+ * word access off a 2-byte boundary.
+ */
+ if ((name_size + bool_count) % 2 != 0)
+ read(fd, buf, 1);
+
+ /* grab the numbers */
+ (void) read(fd, buf, min(NUMCOUNT*2, (unsigned)num_count*2));
+ for (i = 0; i < min(num_count, NUMCOUNT); i++)
+ {
+ if (IS_NEG1(buf + 2*i))
+ ptr->Numbers[i] = ABSENT_NUMERIC;
+ else if (IS_NEG2(buf + 2*i))
+ ptr->Numbers[i] = CANCELLED_NUMERIC;
+ else
+ ptr->Numbers[i] = LOW_MSB(buf + 2*i);
+ }
+ if (num_count > NUMCOUNT)
+ lseek(fd, (off_t) (2 * (num_count - NUMCOUNT)), 1);
+ else
+ for (i=num_count; i < NUMCOUNT; i++)
+ ptr->Numbers[i] = ABSENT_NUMERIC;
+
+ if (str_count)
+ {
+ if (str_count*2 >= MAX_ENTRY_SIZE)
+ {
+ close(fd);
+ return(0);
+ }
+ /* grab the string offsets */
+ numread = read(fd, buf, (unsigned)(str_count*2));
+ if (numread < str_count*2)
+ {
+ close(fd);
+ return(0);
+ }
+ for (i = 0; i < numread/2; i++)
+ {
+ if (i >= STRCOUNT)
+ break;
+ if (IS_NEG1(buf + 2*i))
+ ptr->Strings[i] = ABSENT_STRING;
+ else if (IS_NEG2(buf + 2*i))
+ ptr->Strings[i] = CANCELLED_STRING;
+ else if (LOW_MSB(buf + 2*i) > str_size)
+ ptr->Strings[i] = ABSENT_STRING;
+ else
+ ptr->Strings[i] = (LOW_MSB(buf+2*i) + ptr->str_table);
+ }
+ }
+
+ if (str_count > STRCOUNT)
+ lseek(fd, (off_t) (2 * (str_count - STRCOUNT)), 1);
+ else
+ for (i = str_count; i < STRCOUNT; i++)
+ ptr->Strings[i] = ABSENT_STRING;
+
+ if (str_size)
+ {
+ /* finally, grab the string table itself */
+ numread = read(fd, ptr->str_table, (unsigned)str_size);
+ if (numread != str_size)
+ {
+ close(fd);
+ return(0);
+ }
+ }
+
+ /* make sure all strings are NUL terminated */
+ for (i = str_count; i < STRCOUNT; i++) {
+ char *p;
+
+ if (VALID_STRING(ptr->Strings[i])) {
+ for (p = ptr->Strings[i]; p <= ptr->str_table + str_size; p++)
+ if (*p == '\0')
+ break;
+ /* if there is no NUL, ignore the string */
+ if (p > ptr->str_table + str_size)
+ ptr->Strings[i] = ABSENT_STRING;
+ }
+ }
+
+ close(fd);
+ return(1);
+}
+
+/*
+ * Build a terminfo pathname and try to read the data. Returns 1 on success,
+ * 0 on failure.
+ */
+static int _nc_read_tic_entry(char *const filename,
+ const char *const dir, const char *ttn, TERMTYPE *const tp)
+{
+/* maximum safe length of terminfo root directory name */
+#define MAX_TPATH (PATH_MAX - MAX_ALIAS - 6)
+
+ if (strlen(dir) > MAX_TPATH)
+ return 0;
+ (void) sprintf(filename, "%s/%s", dir, ttn);
+ return _nc_read_file_entry(filename, tp);
+}
+
+/*
+ * Process the list of :-separated directories, looking for the terminal type.
+ * We don't use strtok because it does not show us empty tokens.
+ */
+static int _nc_read_terminfo_dirs(const char *dirs, char *const filename, const char *const ttn, TERMTYPE *const tp)
+{
+ char *list, *a;
+ const char *b;
+ int code = 0;
+
+ /* we'll modify the argument, so we must copy */
+ if ((b = a = list = malloc(strlen(dirs) + 1)) == NULL)
+ return(0);
+ (void) strcpy(list, dirs);
+
+ for (;;) {
+ int c = *a;
+ if (c == 0 || c == ':') {
+ *a = 0;
+ if ((b + 1) >= a)
+ b = TERMINFO;
+ if (_nc_read_tic_entry(filename, b, ttn, tp) == 1) {
+ code = 1;
+ break;
+ }
+ b = a + 1;
+ if (c == 0)
+ break;
+ }
+ a++;
+ }
+
+ free(list);
+ return(code);
+}
+
+/*
+ * _nc_read_entry(char *tn, char *filename, TERMTYPE *tp)
+ *
+ * Find and read the compiled entry for a given terminal type,
+ * if it exists. We take pains here to make sure no combination
+ * of environment variables and terminal type name can be used to
+ * overrun the file buffer.
+ */
+
+int _nc_read_entry(const char *const tn, char *const filename, TERMTYPE *const tp)
+{
+char *envp;
+char ttn[MAX_ALIAS + 3];
+
+ /* truncate the terminal name to prevent dangerous buffer airline */
+ (void) sprintf(ttn, "%c/%.*s", *tn, MAX_ALIAS, tn);
+
+ /* This is System V behavior, in conjunction with our requirements for
+ * writing terminfo entries.
+ */
+ if (have_tic_directory
+ && _nc_read_tic_entry(filename, _nc_tic_dir(0), ttn, tp) == 1)
+ return 1;
+
+ if (!issetugid() && (envp = getenv("TERMINFO")) != 0
+ && _nc_read_tic_entry(filename, _nc_tic_dir(envp), ttn, tp) == 1)
+ return 1;
+
+ if (!issetugid() && (envp = _nc_home_terminfo()) != 0) {
+ if (_nc_read_tic_entry(filename, envp, ttn, tp) == 1) {
+ return(1);
+ }
+ }
+
+ /* this is an ncurses extension */
+ if (!issetugid() && (envp = getenv("TERMINFO_DIRS")) != 0)
+ return _nc_read_terminfo_dirs(envp, filename, ttn, tp);
+
+ /* Try the system directory. Note that the TERMINFO_DIRS value, if
+ * defined by the configure script, begins with a ":", which will be
+ * interpreted as TERMINFO.
+ */
+#ifdef TERMINFO_DIRS
+ return _nc_read_terminfo_dirs(TERMINFO_DIRS, filename, ttn, tp);
+#else
+ return _nc_read_tic_entry(filename, TERMINFO, ttn, tp);
+#endif
+}
+
diff --git a/lib/libcurses/tinfo/read_termcap.c b/lib/libcurses/tinfo/read_termcap.c
new file mode 100644
index 00000000000..de240b648f3
--- /dev/null
+++ b/lib/libcurses/tinfo/read_termcap.c
@@ -0,0 +1,1122 @@
+/* $OpenBSD: read_termcap.c,v 1.1 1999/01/18 19:10:22 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+/*
+ * Termcap compatibility support
+ *
+ * If your OS integrator didn't install a terminfo database, you can call
+ * _nc_read_termcap_entry() to support reading and translating capabilities
+ * from the system termcap file. This is a kludge; it will bulk up and slow
+ * down every program that uses ncurses, and translated termcap entries cannot
+ * use full terminfo capabilities. Don't use it unless you absolutely have to;
+ * instead, get your system people to run tic(1) from root on the terminfo
+ * master included with ncurses to translate it into a terminfo database.
+ *
+ * If USE_GETCAP is enabled, we use what is effectively a copy of the 4.4BSD
+ * getcap code to fetch entries. There are disadvantages to this; mainly that
+ * getcap(3) does its own resolution, meaning that entries read in in this way
+ * can't reference the terminfo tree. The only thing it buys is faster startup
+ * time, getcap(3) is much faster than our tic parser.
+ */
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+#include <term.h>
+#include <tic.h>
+#include <term_entry.h>
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+MODULE_ID("$From: read_termcap.c,v 1.37 1998/09/19 21:42:14 tom Exp $")
+
+#ifndef PURE_TERMINFO
+
+#ifdef __EMX__
+#define is_pathname(s) ((((s) != 0) && ((s)[0] == '/')) \
+ || (((s)[0] != 0) && ((s)[1] == ':')))
+#else
+#define is_pathname(s) ((s) != 0 && (s)[0] == '/')
+#endif
+
+#define TC_SUCCESS 0
+#define TC_UNRESOLVED -1
+#define TC_NOT_FOUND -2
+#define TC_SYS_ERR -3
+#define TC_REF_LOOP -4
+
+#if USE_GETCAP
+
+#if HAVE_BSD_CGETENT
+#define _nc_cgetcap cgetcap
+#define _nc_cgetent(buf, oline, db_array, name) cgetent(buf, db_array, name)
+#define _nc_cgetmatch cgetmatch
+#define _nc_cgetset cgetset
+#else
+static int _nc_cgetmatch(char *, const char *);
+static int _nc_getent(char **, unsigned int *, int *, int, char **, int, const char *, int, char *);
+static int _nc_nfcmp(const char *, char *);
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Casey Leedom of Lawrence Livermore National Laboratory.
+ *
+ * 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 acknowledgment:
+ * 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.
+ */
+
+/* static char sccsid[] = "@(#)getcap.c 8.3 (Berkeley) 3/25/94"; */
+
+#define BFRAG 1024
+#define BSIZE 1024
+#define ESC ('[' & 037) /* ASCII ESC */
+#define MAX_RECURSION 32 /* maximum getent recursion */
+#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */
+
+#define RECOK (char)0
+#define TCERR (char)1
+#define SHADOW (char)2
+
+static size_t topreclen; /* toprec length */
+static char *toprec; /* Additional record specified by cgetset() */
+static int gottoprec; /* Flag indicating retrieval of toprecord */
+
+/*
+ * Cgetset() allows the addition of a user specified buffer to be added to the
+ * database array, in effect "pushing" the buffer on top of the virtual
+ * database. 0 is returned on success, -1 on failure.
+ */
+static int
+_nc_cgetset(const char *ent)
+{
+ if (ent == 0) {
+ FreeIfNeeded(toprec);
+ toprec = 0;
+ topreclen = 0;
+ return (0);
+ }
+ topreclen = strlen(ent);
+ if ((toprec = malloc (topreclen + 1)) == 0) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ gottoprec = 0;
+ (void)strcpy(toprec, ent);
+ return (0);
+}
+
+/*
+ * Cgetcap searches the capability record buf for the capability cap with type
+ * `type'. A pointer to the value of cap is returned on success, 0 if the
+ * requested capability couldn't be found.
+ *
+ * Specifying a type of ':' means that nothing should follow cap (:cap:). In
+ * this case a pointer to the terminating ':' or NUL will be returned if cap is
+ * found.
+ *
+ * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator)
+ * return 0.
+ */
+static char *
+_nc_cgetcap(char *buf, const char *cap, int type)
+{
+ register const char *cp;
+ register char *bp;
+
+ bp = buf;
+ for (;;) {
+ /*
+ * Skip past the current capability field - it's either the
+ * name field if this is the first time through the loop, or
+ * the remainder of a field whose name failed to match cap.
+ */
+ for (;;) {
+ if (*bp == '\0')
+ return (0);
+ else if (*bp++ == ':')
+ break;
+ }
+
+ /*
+ * Try to match (cap, type) in buf.
+ */
+ for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++)
+ continue;
+ if (*cp != '\0')
+ continue;
+ if (*bp == '@')
+ return (0);
+ if (type == ':') {
+ if (*bp != '\0' && *bp != ':')
+ continue;
+ return(bp);
+ }
+ if (*bp != type)
+ continue;
+ bp++;
+ return (*bp == '@' ? 0 : bp);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Cgetent extracts the capability record name from the NULL terminated file
+ * array db_array and returns a pointer to a malloc'd copy of it in buf. Buf
+ * must be retained through all subsequent calls to cgetcap, cgetnum, cgetflag,
+ * and cgetstr, but may then be freed.
+ *
+ * Returns:
+ *
+ * positive # on success (i.e., the index in db_array)
+ * TC_UNRESOLVED if we had too many recurrences to resolve
+ * TC_NOT_FOUND if the requested record couldn't be found
+ * TC_SYS_ERR if a system error was encountered (e.g.,couldn't open a file)
+ * TC_REF_LOOP if a potential reference loop is detected
+ */
+static int
+_nc_cgetent(char **buf, int *oline, char **db_array, const char *name)
+{
+ unsigned int dummy;
+
+ return (_nc_getent(buf, &dummy, oline, 0, db_array, -1, name, 0, 0));
+}
+
+/*
+ * Getent implements the functions of cgetent. If fd is non-negative,
+ * *db_array has already been opened and fd is the open file descriptor. We
+ * do this to save time and avoid using up file descriptors for tc=
+ * recursions.
+ *
+ * Getent returns the same success/failure codes as cgetent. On success, a
+ * pointer to a malloc'd capability record with all tc= capabilities fully
+ * expanded and its length (not including trailing ASCII NUL) are left in
+ * *cap and *len.
+ *
+ * Basic algorithm:
+ * + Allocate memory incrementally as needed in chunks of size BFRAG
+ * for capability buffer.
+ * + Recurse for each tc=name and interpolate result. Stop when all
+ * names interpolated, a name can't be found, or depth exceeds
+ * MAX_RECURSION.
+ */
+#define DOALLOC(size) (char *)_nc_doalloc(record, size)
+static int
+_nc_getent(
+ char **cap, /* termcap-content */
+ unsigned int *len, /* length, needed for recursion */
+ int *beginning, /* line-number at match */
+ int in_array, /* index in 'db_array[] */
+ char **db_array, /* list of files to search */
+ int fd,
+ const char *name,
+ int depth,
+ char *nfield)
+{
+ register char *r_end, *rp;
+ int myfd = FALSE;
+ char *record = 0;
+ int tc_not_resolved;
+ int current;
+ int lineno;
+
+ /*
+ * Return with ``loop detected'' error if we've recurred more than
+ * MAX_RECURSION times.
+ */
+ if (depth > MAX_RECURSION)
+ return (TC_REF_LOOP);
+
+ /*
+ * Check if we have a top record from cgetset().
+ */
+ if (depth == 0 && toprec != 0 && _nc_cgetmatch(toprec, name) == 0) {
+ if ((record = DOALLOC(topreclen + BFRAG)) == 0) {
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ (void)strcpy(record, toprec);
+ rp = record + topreclen + 1;
+ r_end = rp + BFRAG;
+ current = in_array;
+ } else {
+ int foundit;
+
+ /*
+ * Allocate first chunk of memory.
+ */
+ if ((record = DOALLOC(BFRAG)) == 0) {
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ rp = r_end = record + BFRAG;
+ foundit = FALSE;
+
+ /*
+ * Loop through database array until finding the record.
+ */
+ for (current = in_array; db_array[current] != 0; current++) {
+ int eof = FALSE;
+
+ /*
+ * Open database if not already open.
+ */
+ if (fd >= 0) {
+ (void)lseek(fd, (off_t)0, SEEK_SET);
+ } else if ((_nc_access(db_array[current], R_OK) < 0)
+ || (fd = open(db_array[current], O_RDONLY, 0)) < 0) {
+ /* No error on unfound file. */
+ if (errno == ENOENT)
+ continue;
+ free(record);
+ return (TC_SYS_ERR);
+ } else {
+ myfd = TRUE;
+ }
+ lineno = 0;
+
+ /*
+ * Find the requested capability record ...
+ */
+ {
+ char buf[2048];
+ register char *b_end = buf;
+ register char *bp = buf;
+ register int c;
+
+ /*
+ * Loop invariants:
+ * There is always room for one more character in record.
+ * R_end always points just past end of record.
+ * Rp always points just past last character in record.
+ * B_end always points just past last character in buf.
+ * Bp always points at next character in buf.
+ */
+
+ for (;;) {
+ int first = lineno + 1;
+
+ /*
+ * Read in a line implementing (\, newline)
+ * line continuation.
+ */
+ rp = record;
+ for (;;) {
+ if (bp >= b_end) {
+ int n;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n <= 0) {
+ if (myfd)
+ (void)close(fd);
+ if (n < 0) {
+ free(record);
+ return (TC_SYS_ERR);
+ }
+ fd = -1;
+ eof = TRUE;
+ break;
+ }
+ b_end = buf+n;
+ bp = buf;
+ }
+
+ c = *bp++;
+ if (c == '\n') {
+ lineno++;
+ if (rp == record || *(rp-1) != '\\')
+ break;
+ }
+ *rp++ = c;
+
+ /*
+ * Enforce loop invariant: if no room
+ * left in record buffer, try to get
+ * some more.
+ */
+ if (rp >= r_end) {
+ unsigned int pos;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + BFRAG;
+ record = DOALLOC(newsize);
+ if (record == 0) {
+ if (myfd)
+ (void)close(fd);
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
+ }
+ }
+ /* loop invariant lets us do this */
+ *rp++ = '\0';
+
+ /*
+ * If encountered eof check next file.
+ */
+ if (eof)
+ break;
+
+ /*
+ * Toss blank lines and comments.
+ */
+ if (*record == '\0' || *record == '#')
+ continue;
+
+ /*
+ * See if this is the record we want ...
+ */
+ if (_nc_cgetmatch(record, name) == 0
+ && (nfield == 0
+ || !_nc_nfcmp(nfield, record))) {
+ foundit = TRUE;
+ *beginning = first;
+ break; /* found it! */
+ }
+ }
+ }
+ if (foundit)
+ break;
+ }
+
+ if (!foundit)
+ return (TC_NOT_FOUND);
+ }
+
+ /*
+ * Got the capability record, but now we have to expand all tc=name
+ * references in it ...
+ */
+ {
+ register char *newicap, *s;
+ register int newilen;
+ unsigned int ilen;
+ int diff, iret, tclen, oline;
+ char *icap, *scan, *tc, *tcstart, *tcend;
+
+ /*
+ * Loop invariants:
+ * There is room for one more character in record.
+ * R_end points just past end of record.
+ * Rp points just past last character in record.
+ * Scan points at remainder of record that needs to be
+ * scanned for tc=name constructs.
+ */
+ scan = record;
+ tc_not_resolved = FALSE;
+ for (;;) {
+ if ((tc = _nc_cgetcap(scan, "tc", '=')) == 0)
+ break;
+
+ /*
+ * Find end of tc=name and stomp on the trailing `:'
+ * (if present) so we can use it to call ourselves.
+ */
+ s = tc;
+ while (*s != '\0') {
+ if (*s++ == ':') {
+ *(s - 1) = '\0';
+ break;
+ }
+ }
+ tcstart = tc - 3;
+ tclen = s - tcstart;
+ tcend = s;
+
+ iret = _nc_getent(&icap, &ilen, &oline, current, db_array, fd, tc, depth+1, 0);
+ newicap = icap; /* Put into a register. */
+ newilen = ilen;
+ if (iret != TC_SUCCESS) {
+ /* an error */
+ if (iret < TC_NOT_FOUND) {
+ if (myfd)
+ (void)close(fd);
+ free(record);
+ return (iret);
+ }
+ if (iret == TC_UNRESOLVED)
+ tc_not_resolved = TRUE;
+ /* couldn't resolve tc */
+ if (iret == TC_NOT_FOUND) {
+ *(s - 1) = ':';
+ scan = s - 1;
+ tc_not_resolved = TRUE;
+ continue;
+ }
+ }
+
+ /* not interested in name field of tc'ed record */
+ s = newicap;
+ while (*s != '\0' && *s++ != ':')
+ ;
+ newilen -= s - newicap;
+ newicap = s;
+
+ /* make sure interpolated record is `:'-terminated */
+ s += newilen;
+ if (*(s-1) != ':') {
+ *s = ':'; /* overwrite NUL with : */
+ newilen++;
+ }
+
+ /*
+ * Make sure there's enough room to insert the
+ * new record.
+ */
+ diff = newilen - tclen;
+ if (diff >= r_end - rp) {
+ unsigned int pos, tcpos, tcposend;
+ size_t newsize;
+
+ pos = rp - record;
+ newsize = r_end - record + diff + BFRAG;
+ tcpos = tcstart - record;
+ tcposend = tcend - record;
+ record = DOALLOC(newsize);
+ if (record == 0) {
+ if (myfd)
+ (void)close(fd);
+ free(icap);
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ r_end = record + newsize;
+ rp = record + pos;
+ tcstart = record + tcpos;
+ tcend = record + tcposend;
+ }
+
+ /*
+ * Insert tc'ed record into our record.
+ */
+ s = tcstart + newilen;
+ memmove(s, tcend, (size_t)(rp - tcend));
+ memmove(tcstart, newicap, (size_t)newilen);
+ rp += diff;
+ free(icap);
+
+ /*
+ * Start scan on `:' so next cgetcap works properly
+ * (cgetcap always skips first field).
+ */
+ scan = s-1;
+ }
+ }
+
+ /*
+ * Close file (if we opened it), give back any extra memory, and
+ * return capability, length and success.
+ */
+ if (myfd)
+ (void)close(fd);
+ *len = rp - record - 1; /* don't count NUL */
+ if (r_end > rp) {
+ if ((record = DOALLOC((size_t)(rp - record))) == 0) {
+ errno = ENOMEM;
+ return (TC_SYS_ERR);
+ }
+ }
+
+ *cap = record;
+ if (tc_not_resolved)
+ return (TC_UNRESOLVED);
+ return (current);
+}
+
+/*
+ * Cgetmatch will return 0 if name is one of the names of the capability
+ * record buf, -1 if not.
+ */
+static int
+_nc_cgetmatch(char *buf, const char *name)
+{
+ register const char *np;
+ register char *bp;
+
+ /*
+ * Start search at beginning of record.
+ */
+ bp = buf;
+ for (;;) {
+ /*
+ * Try to match a record name.
+ */
+ np = name;
+ for (;;) {
+ if (*np == '\0') {
+ if (*bp == '|' || *bp == ':' || *bp == '\0')
+ return (0);
+ else
+ break;
+ } else if (*bp++ != *np++) {
+ break;
+ }
+ }
+
+ /*
+ * Match failed, skip to next name in record.
+ */
+ bp--; /* a '|' or ':' may have stopped the match */
+ for (;;) {
+ if (*bp == '\0' || *bp == ':')
+ return (-1); /* match failed totally */
+ else if (*bp++ == '|')
+ break; /* found next name */
+ }
+ }
+}
+
+/*
+ * Compare name field of record.
+ */
+static int
+_nc_nfcmp(const char *nf, char *rec)
+{
+ char *cp, tmp;
+ int ret;
+
+ for (cp = rec; *cp != ':'; cp++)
+ ;
+
+ tmp = *(cp + 1);
+ *(cp + 1) = '\0';
+ ret = strcmp(nf, rec);
+ *(cp + 1) = tmp;
+
+ return (ret);
+}
+#endif /* HAVE_BSD_CGETENT */
+
+/*
+ * Since ncurses provides its own 'tgetent()', we cannot use the native one.
+ * So we reproduce the logic to get down to cgetent() -- or our cut-down
+ * version of that -- to circumvent the problem of configuring against the
+ * termcap library.
+ */
+#define USE_BSD_TGETENT 1
+
+#if USE_BSD_TGETENT
+/*
+ * Copyright (c) 1980, 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 acknowledgment:
+ * 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.
+ */
+
+/* static char sccsid[] = "@(#)termcap.c 8.1 (Berkeley) 6/4/93" */
+
+#define PBUFSIZ 512 /* max length of filename path */
+#define PVECSIZ 32 /* max number of names in path */
+#define TBUFSIZ (2048*2)
+
+static char *tbuf;
+
+/*
+ * On entry, srcp points to a non ':' character which is the beginning of the
+ * token, if any. We'll try to return a string that doesn't end with a ':'.
+ */
+static char *
+get_tc_token(char **srcp, int *endp)
+{
+ int ch;
+ bool found = FALSE;
+ char *s, *base;
+ char *tok = 0;
+
+ *endp = TRUE;
+ for (s = base = *srcp; *s != '\0'; ) {
+ ch = *s++;
+ if (ch == '\\') {
+ if (*s == '\0') {
+ break;
+ } else if (*s++ == '\n') {
+ while (isspace(*s))
+ s++;
+ } else {
+ found = TRUE;
+ }
+ } else if (ch == ':') {
+ if (found) {
+ tok = base;
+ s[-1] = '\0';
+ *srcp = s;
+ *endp = FALSE;
+ break;
+ }
+ base = s;
+ } else if (isgraph(ch)) {
+ found = TRUE;
+ }
+ }
+
+ /* malformed entry may end without a ':' */
+ if (tok == 0 && found) {
+ tok = base;
+ }
+
+ return tok;
+}
+
+static char *
+copy_tc_token(char *dst, const char *src, size_t len)
+{
+ int ch;
+
+ while ((ch = *src++) != '\0') {
+ if (ch == '\\' && *src == '\n') {
+ while (isspace(*src))
+ src++;
+ continue;
+ }
+ if (--len == 0) {
+ dst = 0;
+ break;
+ }
+ *dst++ = ch;
+ }
+ return dst;
+}
+
+/*
+ * Get an entry for terminal name in buffer bp from the termcap file.
+ */
+static int
+_nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
+{
+ static char *the_source;
+
+ register char *p;
+ register char *cp;
+ char *dummy;
+ char **fname;
+ char *home;
+ int i;
+ char pathbuf[PBUFSIZ]; /* holds raw path of filenames */
+ char *pathvec[PVECSIZ]; /* to point to names in pathbuf */
+ char **pvec; /* holds usable tail of path vector */
+ char *termpath;
+
+ fname = pathvec;
+ pvec = pathvec;
+ tbuf = bp;
+ p = pathbuf;
+ cp = getenv("TERMCAP");
+
+ /*
+ * TERMCAP can have one of two things in it. It can be the name of a
+ * file to use instead of /etc/termcap. In this case it better start
+ * with a "/". Or it can be an entry to use so we don't have to read
+ * the file. In this case it has to already have the newlines crunched
+ * out. If TERMCAP does not hold a file name then a path of names is
+ * searched instead. The path is found in the TERMPATH variable, or
+ * becomes "$HOME/.termcap /etc/termcap" if no TERMPATH exists.
+ */
+#define MY_PATH_DEF "/etc/termcap /usr/share/misc/termcap"
+ if (issetugid())
+ strlcpy(pathbuf, MY_PATH_DEF, PBUFSIZ);
+ else if (!is_pathname(cp)) { /* no TERMCAP or it holds an entry */
+ if ((termpath = getenv("TERMPATH")) != 0) {
+ strlcpy(pathbuf, termpath, PBUFSIZ);
+ } else {
+ if ((home = getenv("HOME")) != 0 &&
+ strlen(home) < PBUFSIZ) { /* setup path */
+ p += strlen(home); /* path, looking in */
+ strcpy(pathbuf, home); /* $HOME first */
+ *p++ = '/';
+ } /* if no $HOME look in current directory */
+ strlcpy(p, ".termcap " MY_PATH_DEF,
+ (size_t)(PBUFSIZ - (p - pathbuf)));
+ }
+ }
+ else /* user-defined name in TERMCAP */
+ strlcpy(pathbuf, cp, PBUFSIZ); /* still can be tokenized */
+
+ *fname++ = pathbuf; /* tokenize path into vector of names */
+ while (*++p) {
+ if (*p == ' ' || *p == ':') {
+ *p = '\0';
+ while (*++p)
+ if (*p != ' ' && *p != ':')
+ break;
+ if (*p == '\0')
+ break;
+ *fname++ = p;
+ if (fname >= pathvec + PVECSIZ) {
+ fname--;
+ break;
+ }
+ }
+ }
+ *fname = 0; /* mark end of vector */
+ if (is_pathname(cp)) {
+ if (_nc_cgetset(cp) < 0) {
+ return(TC_SYS_ERR);
+ }
+ }
+
+ i = _nc_cgetent(&dummy, lineno, pathvec, name);
+
+ /* ncurses' termcap-parsing routines cannot handle multiple adjacent
+ * empty fields, and mistakenly use the last valid cap entry instead of
+ * the first (breaks tc= includes)
+ */
+ if (i >= 0) {
+ char *pd, *ps, *tok;
+ int endflag = FALSE;
+ char *list[1023];
+ size_t n, count = 0;
+
+ pd = bp;
+ ps = dummy;
+ while (!endflag && (tok = get_tc_token(&ps, &endflag)) != 0) {
+ bool ignore = FALSE;
+
+ for (n = 1; n < count; n++) {
+ char *s = list[n];
+ if (s[0] == tok[0]
+ && s[1] == tok[1]) {
+ ignore = TRUE;
+ break;
+ }
+ }
+ if (ignore != TRUE) {
+ list[count++] = tok;
+ pd = copy_tc_token(pd, tok, TBUFSIZ - (2+pd-bp));
+ if (pd == 0) {
+ i = -1;
+ break;
+ }
+ *pd++ = ':';
+ *pd = '\0';
+ }
+ }
+ }
+
+ FreeIfNeeded(dummy);
+ FreeIfNeeded(the_source);
+ the_source = 0;
+
+ /* This is not related to the BSD cgetent(), but to fake up a suitable
+ * filename for ncurses' error reporting. (If we are not using BSD
+ * cgetent, then it is the actual filename).
+ */
+ if (i >= 0) {
+ the_source = malloc(strlen(pathvec[i]) + 1);
+ if (the_source != 0)
+ *sourcename = strcpy(the_source, pathvec[i]);
+ }
+
+ return(i);
+}
+#endif /* USE_BSD_TGETENT */
+#endif /* USE_GETCAP */
+
+#define MAXPATHS 32
+
+/*
+ * Add a filename to the list in 'termpaths[]', checking that we really have
+ * a right to open the file.
+ */
+#if !USE_GETCAP
+static int add_tc(char *termpaths[], char *path, int count)
+{
+ if (count < MAXPATHS
+ && _nc_access(path, R_OK) == 0)
+ termpaths[count++] = path;
+ termpaths[count] = 0;
+ return count;
+}
+#define ADD_TC(path, count) filecount = add_tc(termpaths, path, count)
+#endif /* !USE_GETCAP */
+
+int _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
+{
+ int found = FALSE;
+ ENTRY *ep;
+#if USE_GETCAP_CACHE
+ char cwd_buf[PATH_MAX];
+#endif
+#if USE_GETCAP
+ char tc[TBUFSIZ];
+ static char *source;
+ static int lineno;
+
+ /* we're using getcap(3) */
+ if (_nc_tgetent(tc, &source, &lineno, tn) < 0)
+ return (ERR);
+
+ _nc_curr_line = lineno;
+ _nc_set_source(source);
+ _nc_read_entry_source((FILE *)0, tc, FALSE, FALSE, NULLHOOK);
+#else
+ /*
+ * Here is what the 4.4BSD termcap(3) page prescribes:
+ *
+ * It will look in the environment for a TERMCAP variable. If found,
+ * and the value does not begin with a slash, and the terminal type
+ * name is the same as the environment string TERM, the TERMCAP string
+ * is used instead of reading a termcap file. If it does begin with a
+ * slash, the string is used as a path name of the termcap file to
+ * search. If TERMCAP does not begin with a slash and name is
+ * different from TERM, tgetent() searches the files $HOME/.termcap and
+ * /usr/share/misc/termcap, in that order, unless the environment
+ * variable TERMPATH exists, in which case it specifies a list of file
+ * pathnames (separated by spaces or colons) to be searched instead.
+ *
+ * It goes on to state:
+ *
+ * Whenever multiple files are searched and a tc field occurs in the
+ * requested entry, the entry it names must be found in the same file
+ * or one of the succeeding files.
+ *
+ * However, this restriction is relaxed in ncurses; tc references to
+ * previous files are permitted.
+ *
+ * This routine returns 1 if an entry is found, 0 if not found, and -1
+ * if the database is not accessible.
+ */
+ FILE *fp;
+ char *tc, *termpaths[MAXPATHS];
+ int filecount = 0;
+ bool use_buffer = FALSE;
+ char tc_buf[1024];
+ char pathbuf[PATH_MAX];
+
+ termpaths[filecount] = 0;
+ if ((tc = getenv("TERMCAP")) != 0 && (!issetugid() || !is_pathname(tc)))
+ {
+ if (is_pathname(tc)) /* interpret as a filename */
+ {
+ ADD_TC(tc, 0);
+ }
+ else if (_nc_name_match(tc, tn, "|:")) /* treat as a capability file */
+ {
+ use_buffer = TRUE;
+ (void) sprintf(tc_buf, "%.*s\n", (int)sizeof(tc_buf)-2, tc);
+ }
+ else if ((tc = getenv("TERMPATH")) != 0)
+ {
+ char *cp;
+
+ for (cp = tc; *cp; cp++)
+ {
+ if (*cp == ':')
+ *cp = '\0';
+ else if (cp == tc || cp[-1] == '\0')
+ {
+ ADD_TC(cp, filecount);
+ }
+ }
+ }
+ }
+ else /* normal case */
+ {
+ char envhome[PATH_MAX], *h;
+
+ filecount = 0;
+
+ /*
+ * Probably /etc/termcap is a symlink to /usr/share/misc/termcap.
+ * Avoid reading the same file twice.
+ */
+ if (_nc_access("/etc/termcap", F_OK) == 0)
+ ADD_TC("/etc/termcap", filecount);
+ else
+ ADD_TC("/usr/share/misc/termcap", filecount);
+
+#define PRIVATE_CAP "%s/.termcap"
+
+ if (!issetugid() && (h = getenv("HOME")) != NULL
+ && (strlen(h) + sizeof(PRIVATE_CAP)) < PATH_MAX)
+ {
+ /* user's .termcap, if any, should override it */
+ (void) strcpy(envhome, h);
+ (void) sprintf(pathbuf, PRIVATE_CAP, envhome);
+ ADD_TC(pathbuf, filecount);
+ }
+ }
+
+ /* parse the sources */
+ if (use_buffer)
+ {
+ _nc_set_source("TERMCAP");
+
+ /*
+ * We don't suppress warning messages here. The presumption is
+ * that since it's just a single entry, they won't be a pain.
+ */
+ _nc_read_entry_source((FILE *)0, tc_buf, FALSE, FALSE, NULLHOOK);
+ } else {
+ int i;
+
+ for (i = 0; i < filecount; i++) {
+
+ T(("Looking for %s in %s", tn, termpaths[i]));
+ if ((fp = fopen(termpaths[i], "r")) != (FILE *)0)
+ {
+ _nc_set_source(termpaths[i]);
+
+ /*
+ * Suppress warning messages. Otherwise you
+ * get 400 lines of crap from archaic termcap
+ * files as ncurses complains about all the
+ * obsolete capabilities.
+ */
+ _nc_read_entry_source(fp, (char*)0, FALSE, TRUE, NULLHOOK);
+
+ (void) fclose(fp);
+ }
+ }
+ }
+#endif /* USE_GETCAP */
+
+ if (_nc_head == 0)
+ return(ERR);
+
+ /* resolve all use references */
+ _nc_resolve_uses();
+
+ /* find a terminal matching tn, if we can */
+#if USE_GETCAP_CACHE
+ if (getcwd(cwd_buf, sizeof(cwd_buf)) != 0)
+ {
+ _nc_set_writedir((char *)0); /* note: this does a chdir */
+#endif
+ for_entry_list(ep) {
+ if (_nc_name_match(ep->tterm.term_names, tn, "|:"))
+ {
+ /*
+ * Make a local copy of the terminal
+ * capabilities. Free all entry storage except
+ * the string table for the loaded type (which
+ * we disconnected from the list by NULLing out
+ * ep->tterm.str_table above).
+ */
+ memcpy(tp, &ep->tterm, sizeof(TERMTYPE));
+ ep->tterm.str_table = (char *)0;
+
+ /*
+ * OK, now try to write the type to user's
+ * terminfo directory. Next time he loads
+ * this, it will come through terminfo.
+ *
+ * Advantage: Second and subsequent fetches of
+ * this entry will be very fast.
+ *
+ * Disadvantage: After the first time a
+ * termcap type is loaded by its user, editing
+ * it in the /etc/termcap file, or in TERMCAP,
+ * or in a local ~/.termcap, will be
+ * ineffective unless the terminfo entry is
+ * explicitly removed.
+ */
+#if USE_GETCAP_CACHE
+ (void) _nc_write_entry(tp);
+#endif
+ found = TRUE;
+ break;
+ }
+ }
+#if USE_GETCAP_CACHE
+ chdir(cwd_buf);
+ }
+#endif
+
+ _nc_free_entries(_nc_head);
+ return(found);
+}
+#else
+extern void _nc_read_termcap(void);
+ void _nc_read_termcap(void) { }
+#endif /* PURE_TERMINFO */
diff --git a/lib/libcurses/tinfo/setbuf.c b/lib/libcurses/tinfo/setbuf.c
new file mode 100644
index 00000000000..03a8c896ba0
--- /dev/null
+++ b/lib/libcurses/tinfo/setbuf.c
@@ -0,0 +1,137 @@
+/* $OpenBSD: setbuf.c,v 1.1 1999/01/18 19:10:22 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+
+/*
+** setbuf.c
+**
+** Support for set_term(), reset_shell_mode(), reset_prog_mode().
+**
+*/
+
+#include <curses.priv.h>
+
+MODULE_ID("$From: setbuf.c,v 1.2 1998/12/13 03:48:09 tom Exp $")
+
+/*
+ * If the output file descriptor is connected to a tty (the typical case) it
+ * will probably be line-buffered. Keith Bostic pointed out that we don't want
+ * this; it hoses people running over networks by forcing out a bunch of small
+ * packets instead of one big one, so screen updates on ptys look jerky.
+ * Restore block buffering to prevent this minor lossage.
+ *
+ * The buffer size is a compromise. Ideally we'd like a buffer that can hold
+ * the maximum possible update size (the whole screen plus cup commands to
+ * change lines as it's painted). On a 66-line xterm this can become
+ * excessive. So we min it with the amount of data we think we can get through
+ * two Ethernet packets (maximum packet size - 100 for TCP/IP overhead).
+ *
+ * Why two ethernet packets? It used to be one, on the theory that said
+ * packets define the maximum size of atomic update. But that's less than the
+ * 2000 chars on a 25 x 80 screen, and we don't want local updates to flicker
+ * either. Two packet lengths will handle up to a 35 x 80 screen.
+ *
+ * The magic '6' is the estimated length of the end-of-line cup sequence to go
+ * to the next line. It's generous. We used to mess with the buffering in
+ * init_mvcur() after cost computation, but that lost the sequences emitted by
+ * init_acs() in setupscreen().
+ *
+ * "The setvbuf function may be used only after the stream pointed to by stream
+ * has been associated with an open file and before any other operation is
+ * performed on the stream." (ISO 7.9.5.6.)
+ *
+ * Grrrr...
+ *
+ * On a lighter note, many implementations do in fact allow an application to
+ * reset the buffering after it has been written to. We try to do this because
+ * otherwise we leave stdout in buffered mode after endwin() is called. (This
+ * also happens with SVr4 curses).
+ *
+ * There are pros/cons:
+ *
+ * con:
+ * There is no guarantee that we can reestablish buffering once we've
+ * dropped it.
+ *
+ * We _may_ lose data if the implementation does not coordinate this with
+ * fflush.
+ *
+ * pro:
+ * An implementation is more likely to refuse to change the buffering than
+ * to do it in one of the ways mentioned above.
+ *
+ * The alternative is to have the application try to change buffering
+ * itself, which is certainly no improvement.
+ *
+ * Just in case it does not work well on a particular system, the calls to
+ * change buffering are all via the macro NC_BUFFERED.
+ */
+void _nc_set_buffer(FILE *ofp, bool buffered)
+{
+ /* optional optimization hack -- do before any output to ofp */
+#if HAVE_SETVBUF || HAVE_SETBUFFER
+ unsigned buf_len;
+ char *buf_ptr;
+
+ if (getenv("NCURSES_NO_SETBUF") != 0)
+ return;
+
+ fflush(ofp);
+ if ((SP->_buffered = buffered) != 0) {
+ buf_len = min(LINES * (COLS + 6), 2800);
+ if ((buf_ptr = SP->_setbuf) == 0) {
+ if ((buf_ptr = malloc(buf_len)) == NULL)
+ return;
+ SP->_setbuf = buf_ptr;
+ /* Don't try to free this! */
+ }
+ } else {
+ buf_len = 0;
+ buf_ptr = 0;
+ }
+
+#if HAVE_SETVBUF
+#ifdef SETVBUF_REVERSED /* pre-svr3? */
+ (void) setvbuf(ofp, buf_ptr, buf_len, buf_len ? _IOFBF : _IOLBF);
+#else
+ (void) setvbuf(ofp, buf_ptr, buf_len ? _IOFBF : _IOLBF, buf_len);
+#endif
+#elif HAVE_SETBUFFER
+ (void) setbuffer(ofp, buf_ptr, (int)buf_len);
+#endif
+
+#endif /* HAVE_SETVBUF || HAVE_SETBUFFER */
+}
diff --git a/lib/libcurses/tinfo/write_entry.c b/lib/libcurses/tinfo/write_entry.c
new file mode 100644
index 00000000000..22c20151790
--- /dev/null
+++ b/lib/libcurses/tinfo/write_entry.c
@@ -0,0 +1,469 @@
+/* $OpenBSD: write_entry.c,v 1.1 1999/01/18 19:10:23 millert 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: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ ****************************************************************************/
+
+
+
+/*
+ * write_entry.c -- write a terminfo structure onto the file system
+ */
+
+#include <curses.priv.h>
+
+#include <sys/stat.h>
+
+#include <tic.h>
+#include <term.h>
+#include <term_entry.h>
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR)
+#endif
+
+MODULE_ID("$From: write_entry.c,v 1.34 1998/12/20 02:49:27 tom Exp $")
+
+static int total_written;
+
+static int write_object(FILE *, TERMTYPE *);
+
+static void write_file(char *filename, TERMTYPE *tp)
+{
+ FILE *fp = (_nc_access(filename, W_OK) == 0) ? fopen(filename, "wb") : 0;
+ if (fp == 0) {
+ perror(filename);
+ _nc_syserr_abort("can't open %s/%s", _nc_tic_dir(0), filename);
+ }
+ DEBUG(1, ("Created %s", filename));
+
+ if (write_object(fp, tp) == ERR) {
+ _nc_syserr_abort("error writing %s/%s", _nc_tic_dir(0), filename);
+ }
+ fclose(fp);
+}
+
+/*
+ * make_directory(char *path)
+ *
+ * Make a directory if it doesn't exist.
+ */
+static int make_directory(const char *path)
+{
+int rc;
+struct stat statbuf;
+char fullpath[PATH_MAX];
+const char *destination = _nc_tic_dir(0);
+
+ if (path == destination || *path == '/') {
+ if (strlen(path) + 1 > sizeof(fullpath))
+ return(-1);
+ (void)strcpy(fullpath, path);
+ } else {
+ if (strlen(destination) + strlen(path) + 2 > sizeof(fullpath))
+ return(-1);
+ (void)sprintf(fullpath, "%s/%s", destination, path);
+ }
+
+ if ((rc = stat(path, &statbuf)) < 0) {
+ rc = mkdir(path, 0777);
+ } else {
+ if (_nc_access(path, R_OK|W_OK|X_OK) < 0) {
+ rc = -1; /* permission denied */
+ } else if (!(S_ISDIR(statbuf.st_mode))) {
+ rc = -1; /* not a directory */
+ }
+ }
+ return rc;
+}
+
+void _nc_set_writedir(char *dir)
+/* set the write directory for compiled entries */
+{
+ const char *destination;
+ char actual[PATH_MAX];
+
+ if (dir != 0)
+ (void) _nc_tic_dir(dir);
+ else if (getenv("TERMINFO") != NULL)
+ (void) _nc_tic_dir(getenv("TERMINFO"));
+
+ destination = _nc_tic_dir(0);
+ if (make_directory(destination) < 0)
+ {
+ char *home = _nc_home_terminfo();
+
+ if (home != 0) {
+
+ if (make_directory(destination) < 0)
+ _nc_err_abort("%s: permission denied (errno %d)",
+ destination, errno);
+
+ destination = home;
+ }
+ }
+
+ /*
+ * Note: because of this code, this logic should be exercised
+ * *once only* per run.
+ */
+ if (chdir(_nc_tic_dir(destination)) < 0
+ || getcwd(actual, sizeof(actual)) == 0)
+ _nc_err_abort("%s: not a directory", destination);
+ _nc_keep_tic_dir(strcpy(malloc(strlen(actual)+1), actual));
+}
+
+/*
+ * check_writeable(char code)
+ *
+ * Miscellaneous initialisations
+ *
+ * Check for access rights to destination directories
+ * Create any directories which don't exist.
+ * Note: there's no reason to return the result of make_directory(), since
+ * this function is called only in instances where that has to succeed.
+ *
+ */
+
+static void check_writeable(int code)
+{
+static const char dirnames[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+static bool verified[sizeof(dirnames)];
+
+char dir[2];
+char *s;
+
+ if (code == 0 || (s = strchr(dirnames, code)) == 0)
+ _nc_err_abort("Illegal terminfo subdirectory \"%c\"", code);
+
+ if (verified[s-dirnames])
+ return;
+
+ dir[0] = code;
+ dir[1] = '\0';
+ if (make_directory(dir) < 0) {
+ _nc_err_abort("%s/%s: permission denied", _nc_tic_dir(0), dir);
+ }
+
+ verified[s-dirnames] = TRUE;
+}
+
+/*
+ * _nc_write_entry()
+ *
+ * Save the compiled version of a description in the filesystem.
+ *
+ * make a copy of the name-list
+ * break it up into first-name and all-but-last-name
+ * creat(first-name)
+ * write object information to first-name
+ * close(first-name)
+ * for each name in all-but-last-name
+ * link to first-name
+ *
+ * Using 'time()' to obtain a reference for file timestamps is unreliable,
+ * e.g., with NFS, because the filesystem may have a different time
+ * reference. We check for pre-existence of links by latching the first
+ * timestamp from a file that we create.
+ *
+ * The _nc_warning() calls will report a correct line number only if
+ * _nc_curr_line is properly set before the write_entry() call.
+ */
+
+void _nc_write_entry(TERMTYPE *const tp)
+{
+struct stat statbuf;
+char name_list[MAX_TERMINFO_LENGTH];
+char *first_name, *other_names;
+char *ptr;
+char filename[PATH_MAX];
+char linkname[PATH_MAX];
+#if USE_SYMLINKS
+char symlinkname[PATH_MAX];
+#endif /* USE_SYMLINKS */
+static int call_count;
+static time_t start_time; /* time at start of writes */
+
+ if (call_count++ == 0) {
+ start_time = 0;
+ }
+
+ (void) strcpy(name_list, tp->term_names);
+ DEBUG(7, ("Name list = '%s'", name_list));
+
+ first_name = name_list;
+
+ ptr = &name_list[strlen(name_list) - 1];
+ other_names = ptr + 1;
+
+ while (ptr > name_list && *ptr != '|')
+ ptr--;
+
+ if (ptr != name_list) {
+ *ptr = '\0';
+
+ for (ptr = name_list; *ptr != '\0' && *ptr != '|'; ptr++)
+ continue;
+
+ if (*ptr == '\0')
+ other_names = ptr;
+ else {
+ *ptr = '\0';
+ other_names = ptr + 1;
+ }
+ }
+
+ DEBUG(7, ("First name = '%s'", first_name));
+ DEBUG(7, ("Other names = '%s'", other_names));
+
+ _nc_set_type(first_name);
+
+ if (strlen(first_name) > sizeof(filename)-3)
+ _nc_warning("terminal name too long.");
+
+ sprintf(filename, "%c/%s", first_name[0], first_name);
+
+ /*
+ * Has this primary name been written since the first call to
+ * write_entry()? If so, the newer write will step on the older,
+ * so warn the user.
+ */
+ if (start_time > 0 &&
+ stat(filename, &statbuf) >= 0
+ && statbuf.st_mtime >= start_time)
+ {
+ _nc_warning("name multiply defined.");
+ }
+
+ check_writeable(first_name[0]);
+ write_file(filename, tp);
+
+ if (start_time == 0) {
+ if (stat(filename, &statbuf) < 0
+ || (start_time = statbuf.st_mtime) == 0) {
+ _nc_syserr_abort("error obtaining time from %s/%s",
+ _nc_tic_dir(0), filename);
+ }
+ }
+ while (*other_names != '\0') {
+ ptr = other_names++;
+ while (*other_names != '|' && *other_names != '\0')
+ other_names++;
+
+ if (*other_names != '\0')
+ *(other_names++) = '\0';
+
+ if (strlen(ptr) > sizeof(linkname)-3) {
+ _nc_warning("terminal alias %s too long.", ptr);
+ continue;
+ }
+ if (strchr(ptr, '/') != 0) {
+ _nc_warning("cannot link alias %s.", ptr);
+ continue;
+ }
+
+ check_writeable(ptr[0]);
+ sprintf(linkname, "%c/%s", ptr[0], ptr);
+
+ if (strcmp(filename, linkname) == 0) {
+ _nc_warning("self-synonym ignored");
+ }
+ else if (stat(linkname, &statbuf) >= 0 &&
+ statbuf.st_mtime < start_time)
+ {
+ _nc_warning("alias %s multiply defined.", ptr);
+ }
+ else if (_nc_access(linkname, W_OK) == 0)
+#if HAVE_LINK
+ {
+ int code;
+#if USE_SYMLINKS
+ strcpy(symlinkname, "../");
+ strncat(symlinkname, filename, sizeof(symlinkname) - 4);
+ symlinkname[sizeof(symlinkname) - 1] = '\0';
+#endif /* USE_SYMLINKS */
+#if HAVE_REMOVE
+ code = remove(linkname);
+#else
+ code = unlink(linkname);
+#endif
+ if (code != 0 && errno == ENOENT)
+ code = 0;
+#if USE_SYMLINKS
+ if (symlink(symlinkname, linkname) < 0)
+#else
+ if (link(filename, linkname) < 0)
+#endif /* USE_SYMLINKS */
+ {
+ /*
+ * If there wasn't anything there, and we cannot
+ * link to the target because it is the same as the
+ * target, then the source must be on a filesystem
+ * that uses caseless filenames, such as Win32, etc.
+ */
+ if (code == 0 && errno == EEXIST)
+ _nc_warning("can't link %s to %s", filename, linkname);
+ else if (code == 0 && errno == EPERM)
+ write_file(linkname, tp);
+ else
+ _nc_syserr_abort("can't link %s to %s", filename, linkname);
+ }
+ else
+ {
+ DEBUG(1, ("Linked %s", linkname));
+ }
+ }
+#else /* just make copies */
+ write_file(linkname, tp);
+#endif /* HAVE_LINK */
+ }
+}
+
+#undef LITTLE_ENDIAN /* BSD/OS defines this as a feature macro */
+#define HI(x) ((x) / 256)
+#define LO(x) ((x) % 256)
+#define LITTLE_ENDIAN(p, x) (p)[0] = LO(x), (p)[1] = HI(x)
+
+static int write_object(FILE *fp, TERMTYPE *tp)
+{
+char *namelist;
+size_t namelen, boolmax, nummax, strmax;
+char zero = '\0';
+size_t i;
+short nextfree;
+short offsets[STRCOUNT];
+unsigned char buf[MAX_ENTRY_SIZE];
+
+ namelist = tp->term_names;
+ namelen = strlen(namelist) + 1;
+
+ boolmax = 0;
+ for (i = 0; i < BOOLWRITE; i++)
+ if (tp->Booleans[i])
+ boolmax = i+1;
+
+ nummax = 0;
+ for (i = 0; i < NUMWRITE; i++)
+ if (tp->Numbers[i] != ABSENT_NUMERIC)
+ nummax = i+1;
+
+ strmax = 0;
+ for (i = 0; i < STRWRITE; i++)
+ if (tp->Strings[i] != ABSENT_STRING)
+ strmax = i+1;
+
+ nextfree = 0;
+ for (i = 0; i < strmax; i++)
+ if (tp->Strings[i] == ABSENT_STRING)
+ offsets[i] = -1;
+ else if (tp->Strings[i] == CANCELLED_STRING)
+ offsets[i] = -2;
+ else
+ {
+ offsets[i] = nextfree;
+ nextfree += strlen(tp->Strings[i]) + 1;
+ }
+
+ /* fill in the header */
+ LITTLE_ENDIAN(buf, MAGIC);
+ LITTLE_ENDIAN(buf+2, min(namelen, MAX_NAME_SIZE + 1));
+ LITTLE_ENDIAN(buf+4, boolmax);
+ LITTLE_ENDIAN(buf+6, nummax);
+ LITTLE_ENDIAN(buf+8, strmax);
+ LITTLE_ENDIAN(buf+10, nextfree);
+
+ /* write out the header */
+ if (fwrite(buf, 12, 1, fp) != 1
+ || fwrite(namelist, sizeof(char), (size_t)namelen, fp) != namelen
+ || fwrite(tp->Booleans, sizeof(char), (size_t)boolmax, fp) != boolmax)
+ return(ERR);
+
+ /* the even-boundary padding byte */
+ if ((namelen+boolmax) % 2 != 0 && fwrite(&zero, sizeof(char), 1, fp) != 1)
+ return(ERR);
+
+#ifdef SHOWOFFSET
+ (void) fprintf(stderr, "Numerics begin at %04lx\n", ftell(fp));
+#endif /* SHOWOFFSET */
+
+ /* the numerics */
+ for (i = 0; i < nummax; i++)
+ {
+ if (tp->Numbers[i] == -1) /* HI/LO won't work */
+ buf[2*i] = buf[2*i + 1] = 0377;
+ else if (tp->Numbers[i] == -2) /* HI/LO won't work */
+ buf[2*i] = 0376, buf[2*i + 1] = 0377;
+ else
+ LITTLE_ENDIAN(buf + 2*i, tp->Numbers[i]);
+ }
+ if (fwrite(buf, 2, (size_t)nummax, fp) != nummax)
+ return(ERR);
+
+#ifdef SHOWOFFSET
+ (void) fprintf(stderr, "String offets begin at %04lx\n", ftell(fp));
+#endif /* SHOWOFFSET */
+
+ /* the string offsets */
+ for (i = 0; i < strmax; i++)
+ if (offsets[i] == -1) /* HI/LO won't work */
+ buf[2*i] = buf[2*i + 1] = 0377;
+ else if (offsets[i] == -2) /* HI/LO won't work */
+ {
+ buf[2*i] = 0376;
+ buf[2*i + 1] = 0377;
+ }
+ else
+ LITTLE_ENDIAN(buf + 2*i, offsets[i]);
+ if (fwrite(buf, 2, (size_t)strmax, fp) != strmax)
+ return(ERR);
+
+#ifdef SHOWOFFSET
+ (void) fprintf(stderr, "String table begins at %04lx\n", ftell(fp));
+#endif /* SHOWOFFSET */
+
+ /* the strings */
+ for (i = 0; i < strmax; i++)
+ if (tp->Strings[i] != ABSENT_STRING && tp->Strings[i] != CANCELLED_STRING)
+ if (fwrite(tp->Strings[i], sizeof(char), strlen(tp->Strings[i]) + 1, fp) != strlen(tp->Strings[i]) + 1)
+ return(ERR);
+
+ total_written++;
+ return(OK);
+}
+
+/*
+ * Returns the total number of entries written by this process
+ */
+int _nc_tic_written(void)
+{
+ return total_written;
+}