Update to ncurses-6.0

Change-Id: I98ab2ea8a5e13cca9f8b7cf6277b9b14a4da4299
diff --git a/ncurses/tinfo/MKcaptab.sh b/ncurses/tinfo/MKcaptab.sh
index 98c04e8..20c94a6 100755
--- a/ncurses/tinfo/MKcaptab.sh
+++ b/ncurses/tinfo/MKcaptab.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 ##############################################################################
-# Copyright (c) 2007 Free Software Foundation, Inc.                          #
+# Copyright (c) 2007-2010,2011 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"), #
@@ -26,12 +26,19 @@
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
-# $Id: MKcaptab.sh,v 1.8 2007/08/12 13:13:51 tom Exp $
+# $Id: MKcaptab.sh,v 1.14 2011/10/22 16:34:50 tom Exp $
 AWK=${1-awk}
 OPT1=${2-0}
 OPT2=${3-tinfo/MKcaptab.awk}
 DATA=${4-../include/Caps}
 
+cat <<EOF
+/*
+ * generated by $0
+ */
+
+EOF
+
 cat <<'EOF'
 /*
  *	comp_captab.c -- The names of the capabilities indexed via a hash
@@ -48,7 +55,7 @@
 ./make_hash 1 info $OPT1 <$DATA
 ./make_hash 3 cap  $OPT1 <$DATA
 
-$AWK -f $OPT2 bigstrings=$OPT1 tablename=capalias <$DATA 
+$AWK -f $OPT2 bigstrings=$OPT1 tablename=capalias <$DATA
 
 $AWK -f $OPT2 bigstrings=$OPT1 tablename=infoalias <$DATA
 
@@ -58,7 +65,7 @@
 static void
 next_string(const char *strings, unsigned *offset)
 {
-	*offset += strlen(strings + *offset) + 1;
+    *offset += (unsigned) strlen(strings + *offset) + 1;
 }
 
 static const struct name_table_entry *
@@ -66,21 +73,21 @@
 		const name_table_data *source,
 		const char *strings)
 {
-	if (*actual == 0) {
-		*actual = typeCalloc(struct name_table_entry, CAPTABSIZE);
-		if (*actual != 0) {
-			unsigned n;
-			unsigned len = 0;
-			for (n = 0; n < CAPTABSIZE; ++n) {
-				(*actual)[n].nte_name = strings + len;
-				(*actual)[n].nte_type = source[n].nte_type;
-				(*actual)[n].nte_index = source[n].nte_index;
-				(*actual)[n].nte_link = source[n].nte_link;
-				next_string(strings, &len);
-			}
-		}
+    if (*actual == 0) {
+	*actual = typeCalloc(struct name_table_entry, CAPTABSIZE);
+	if (*actual != 0) {
+	    unsigned n;
+	    unsigned len = 0;
+	    for (n = 0; n < CAPTABSIZE; ++n) {
+		(*actual)[n].nte_name = strings + len;
+		(*actual)[n].nte_type = source[n].nte_type;
+		(*actual)[n].nte_index = source[n].nte_index;
+		(*actual)[n].nte_link = source[n].nte_link;
+		next_string(strings, &len);
+	    }
 	}
-	return *actual;
+    }
+    return *actual;
 }
 
 #define add_alias(field) \\
@@ -92,20 +99,20 @@
 _nc_build_alias(struct alias **actual,
 		const alias_table_data *source,
 		const char *strings,
-		unsigned tablesize)
+		size_t tablesize)
 {
-	if (*actual == 0) {
-		*actual = typeCalloc(struct alias, tablesize + 1);
-		if (*actual != 0) {
-			unsigned n;
-			for (n = 0; n < tablesize; ++n) {
-				add_alias(from);
-				add_alias(to);
-				add_alias(source);
-			}
-		}
+    if (*actual == 0) {
+	*actual = typeCalloc(struct alias, tablesize + 1);
+	if (*actual != 0) {
+	    size_t n;
+	    for (n = 0; n < tablesize; ++n) {
+		add_alias(from);
+		add_alias(to);
+		add_alias(source);
+	    }
 	}
-	return *actual;
+    }
+    return *actual;
 }
 
 #define build_names(root) _nc_build_names(&_nc_##root##_table, \\
@@ -122,27 +129,82 @@
 
 NCURSES_EXPORT(const struct name_table_entry *) _nc_get_table (bool termcap)
 {
-	return termcap ? build_names(cap) : build_names(info) ;
+    return termcap ? build_names(cap) : build_names(info) ;
 }
 
-NCURSES_EXPORT(const short *) _nc_get_hash_table (bool termcap)
+/* entrypoint used by tack (do not alter) */
+NCURSES_EXPORT(const HashValue *) _nc_get_hash_table (bool termcap)
 {
-	return termcap ? _nc_cap_hash_table: _nc_info_hash_table ;
+    return termcap ? _nc_cap_hash_table: _nc_info_hash_table ;
 }
 
 NCURSES_EXPORT(const struct alias *) _nc_get_alias_table (bool termcap)
 {
-	return termcap ? build_alias(cap) : build_alias(info) ;
+    return termcap ? build_alias(cap) : build_alias(info) ;
+}
+
+static HashValue
+info_hash(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 (HashValue) (sum % HASHTABSIZE);
+}
+
+#define TCAP_LEN 2		/* only 1- or 2-character names are used */
+
+static HashValue
+tcap_hash(const char *string)
+{
+    char temp[TCAP_LEN + 1];
+    int limit = 0;
+
+    while (*string) {
+	temp[limit++] = *string++;
+	if (limit >= TCAP_LEN)
+	    break;
+    }
+    temp[limit] = '\0';
+    return info_hash(temp);
+}
+
+static int
+compare_tcap_names(const char *a, const char *b)
+{
+    return !strncmp(a, b, (size_t) TCAP_LEN);
+}
+
+static int
+compare_info_names(const char *a, const char *b)
+{
+    return !strcmp(a, b);
+}
+
+static const HashData hash_data[2] = {
+    { HASHTABSIZE, _nc_info_hash_table, info_hash, compare_info_names },
+    { HASHTABSIZE, _nc_cap_hash_table, tcap_hash, compare_tcap_names }
+};
+
+NCURSES_EXPORT(const HashData *) _nc_get_hash_info (bool termcap)
+{
+    return &hash_data[(termcap != FALSE)];
 }
 
 #if NO_LEAKS
 NCURSES_EXPORT(void) _nc_comp_captab_leaks(void)
 {
 #if $OPT1
-	FreeIfNeeded(_nc_cap_table);
-	FreeIfNeeded(_nc_info_table);
-	FreeIfNeeded(_nc_capalias_table);
-	FreeIfNeeded(_nc_infoalias_table);
+    FreeIfNeeded(_nc_cap_table);
+    FreeIfNeeded(_nc_info_table);
+    FreeIfNeeded(_nc_capalias_table);
+    FreeIfNeeded(_nc_infoalias_table);
 #endif
 }
 #endif /* NO_LEAKS */
diff --git a/ncurses/tinfo/MKcodes.awk b/ncurses/tinfo/MKcodes.awk
index b9ba636..97e5131 100644
--- a/ncurses/tinfo/MKcodes.awk
+++ b/ncurses/tinfo/MKcodes.awk
@@ -1,5 +1,5 @@
 ##############################################################################
-# Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.                #
+# Copyright (c) 1998-2009,2010 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"), #
@@ -25,7 +25,7 @@
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
-# $Id: MKcodes.awk,v 1.5 2008/06/28 23:13:25 tom Exp $
+# $Id: MKcodes.awk,v 1.9 2010/01/23 17:57:43 tom Exp $
 function large_item(value) {
 	result = sprintf("%d,", offset);
 	offset = offset + length(value) + 1;
@@ -101,8 +101,6 @@
 		print  ""
 		print  "#if BROKEN_LINKER || USE_REENTRANT"
 		print  ""
-		print  "#include <term.h>"
-		print  ""
 		if (bigstrings) {
 			printf "static const char _nc_code_blob[] = \n"
 			printf "%s;\n", bigstr;
@@ -117,28 +115,39 @@
 			print  "		if ((*value = typeCalloc(NCURSES_CONST char *, size + 1)) != 0) {"
 			print  "			unsigned n;"
 			print  "			for (n = 0; n < size; ++n) {"
-			print  "				(*value)[n] = _nc_code_blob + offsets[n];"
+			print  "				(*value)[n] = (NCURSES_CONST char *) _nc_code_blob + offsets[n];"
 			print  "			}"
 			print  "		}"
 			print  "	}"
 			print  "	return *value;"
 			print  "}"
 			print  ""
-			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return alloc_array(&ptr_##it, _nc_offset_##it, SIZEOF(_nc_offset_##it)); }"
+			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API NCURSES_PUBLIC_VAR(it)(void) { return alloc_array(&ptr_##it, _nc_offset_##it, SIZEOF(_nc_offset_##it)); }"
 		} else {
 			print  "#define DCL(it) static IT data##it[]"
 			print  ""
 			print_strings("boolcodes", small_boolcodes);
 			print_strings("numcodes", small_numcodes);
 			print_strings("strcodes", small_strcodes);
-			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return data##it; }"
+			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API NCURSES_PUBLIC_VAR(it)(void) { return data##it; }"
 		}
 		print  ""
+		print  "/* remove public definition which conflicts with FIX() */"
+		print  "#undef boolcodes"
+		print  "#undef numcodes"
+		print  "#undef strcodes"
+		print  ""
+		print  "/* add local definition */"
 		print  "FIX(boolcodes)"
 		print  "FIX(numcodes)"
 		print  "FIX(strcodes)"
 		print  ""
+		print  "/* restore the public definition */"
+		print  ""
 		print  "#define FREE_FIX(it) if (ptr_##it) { FreeAndNull(ptr_##it); }"
+		print  "#define boolcodes  NCURSES_PUBLIC_VAR(boolcodes())"
+		print  "#define numcodes   NCURSES_PUBLIC_VAR(numcodes())"
+		print  "#define strcodes   NCURSES_PUBLIC_VAR(strcodes())"
 		print  ""
 		print  "#if NO_LEAKS"
 		print  "NCURSES_EXPORT(void)"
diff --git a/ncurses/tinfo/MKfallback.sh b/ncurses/tinfo/MKfallback.sh
index 9feab35..11f1d2e 100755
--- a/ncurses/tinfo/MKfallback.sh
+++ b/ncurses/tinfo/MKfallback.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 ##############################################################################
-# Copyright (c) 1998-2001,2006 Free Software Foundation, Inc.                #
+# Copyright (c) 1998-2009,2010 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"), #
@@ -26,7 +26,7 @@
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
-# $Id: MKfallback.sh,v 1.13 2006/07/15 16:54:20 tom Exp $
+# $Id: MKfallback.sh,v 1.15 2010/08/07 20:32:34 tom Exp $
 #
 # MKfallback.sh -- create fallback table for entry reads
 #
@@ -42,6 +42,17 @@
 terminfo_src=$1
 shift
 
+tic_path=$1
+shift
+
+case $tic_path in #(vi
+/*)
+	tic_head=`echo "$tic_path" | sed -e 's,/[^/]*$,,'`
+	PATH=$tic_head:$PATH
+	export PATH
+	;;
+esac
+
 if test $# != 0 ; then
 	tmp_info=tmp_info
 	echo creating temporary terminfo directory... >&2
@@ -52,7 +63,7 @@
 	TERMINFO_DIRS=$TERMINFO:$terminfo_dir
 	export TERMINFO_DIRS
 
-	tic -x $terminfo_src >&2
+	$tic_path -x $terminfo_src >&2
 else
 	tmp_info=
 fi
@@ -63,7 +74,6 @@
  */
 
 #include <curses.priv.h>
-#include <term.h>
 
 EOF
 
diff --git a/ncurses/tinfo/MKnames.awk b/ncurses/tinfo/MKnames.awk
index 7e50744..7685d18 100644
--- a/ncurses/tinfo/MKnames.awk
+++ b/ncurses/tinfo/MKnames.awk
@@ -1,5 +1,5 @@
 ##############################################################################
-# Copyright (c) 2007,2008 Free Software Foundation, Inc.                     #
+# Copyright (c) 2007-2008,2009 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"), #
@@ -25,7 +25,7 @@
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
-# $Id: MKnames.awk,v 1.20 2008/10/11 21:07:56 tom Exp $
+# $Id: MKnames.awk,v 1.22 2009/03/21 21:03:39 tom Exp $
 function large_item(value) {
 	result = sprintf("%d,", offset);
 	offset = offset + length(value) + 1;
@@ -107,8 +107,6 @@
 		print  ""
 		print  "#if BROKEN_LINKER || USE_REENTRANT"
 		print  ""
-		print  "#include <term.h>"
-		print  ""
 		if (bigstrings) {
 			printf "static const char _nc_name_blob[] = \n"
 			printf "%s;\n", bigstr;
@@ -133,7 +131,7 @@
 			print  "	return *value;"
 			print  "}"
 			print  ""
-			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return alloc_array(&ptr_##it, _nc_offset_##it, SIZEOF(_nc_offset_##it)); }"
+			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API NCURSES_PUBLIC_VAR(it)(void) { return alloc_array(&ptr_##it, _nc_offset_##it, SIZEOF(_nc_offset_##it)); }"
 		} else {
 			print  "#define DCL(it) static IT data##it[]"
 			print  ""
@@ -143,9 +141,18 @@
 			print_strings("numfnames", small_numfnames);
 			print_strings("strnames", small_strnames);
 			print_strings("strfnames", small_strfnames);
-			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return data##it; }"
+			print  "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API NCURSES_PUBLIC_VAR(it)(void) { return data##it; }"
 		}
 		print  ""
+		print  "/* remove public definition which conflicts with FIX() */"
+		print  "#undef boolnames"
+		print  "#undef boolfnames"
+		print  "#undef numnames"
+		print  "#undef numfnames"
+		print  "#undef strnames"
+		print  "#undef strfnames"
+		print  ""
+		print  "/* add local definition */"
 		print  "FIX(boolnames)"
 		print  "FIX(boolfnames)"
 		print  "FIX(numnames)"
@@ -153,6 +160,13 @@
 		print  "FIX(strnames)"
 		print  "FIX(strfnames)"
 		print  ""
+		print  "/* restore the public definition */"
+		print  "#define boolnames  NCURSES_PUBLIC_VAR(boolnames())"
+		print  "#define boolfnames NCURSES_PUBLIC_VAR(boolfnames())"
+		print  "#define numnames   NCURSES_PUBLIC_VAR(numnames())"
+		print  "#define numfnames  NCURSES_PUBLIC_VAR(numfnames())"
+		print  "#define strnames   NCURSES_PUBLIC_VAR(strnames())"
+		print  "#define strfnames  NCURSES_PUBLIC_VAR(strfnames())"
 		print  ""
 		print  "#define FREE_FIX(it) if (ptr_##it) { FreeAndNull(ptr_##it); }"
 		print  ""
diff --git a/ncurses/tinfo/access.c b/ncurses/tinfo/access.c
index ce8ccda..d987687 100644
--- a/ncurses/tinfo/access.c
+++ b/ncurses/tinfo/access.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2012 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            *
@@ -33,12 +33,18 @@
 #include <curses.priv.h>
 
 #include <ctype.h>
-#include <sys/stat.h>
 
 #include <tic.h>
-#include <nc_alloc.h>
 
-MODULE_ID("$Id: access.c,v 1.14 2007/11/18 00:57:53 tom Exp $")
+MODULE_ID("$Id: access.c,v 1.23 2012/09/01 19:21:29 tom Exp $")
+
+#ifdef __TANDEM
+#define ROOT_UID 65535
+#endif
+
+#ifndef ROOT_UID
+#define ROOT_UID 0
+#endif
 
 #define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
 
@@ -54,7 +60,7 @@
     result = temp;
 #if !MIXEDCASE_FILENAMES
     for (s = result; *s != '\0'; ++s) {
-	*s = LOWERCASE(*s);
+	*s = (char) LOWERCASE(*s);
     }
 #endif
 #if defined(PROG_EXT)
@@ -97,7 +103,7 @@
 	test = path;
     else
 	test++;
-    return (test - path);
+    return (unsigned) (test - path);
 }
 
 NCURSES_EXPORT(char *)
@@ -109,24 +115,33 @@
 NCURSES_EXPORT(int)
 _nc_access(const char *path, int mode)
 {
-    if (access(path, mode) < 0) {
+    int result;
+
+    if (path == 0) {
+	result = -1;
+    } else if (access(path, mode) < 0) {
 	if ((mode & W_OK) != 0
 	    && errno == ENOENT
 	    && strlen(path) < PATH_MAX) {
 	    char head[PATH_MAX];
-	    char *leaf = _nc_basename(strcpy(head, path));
+	    char *leaf;
 
+	    _nc_STRCPY(head, path, sizeof(head));
+	    leaf = _nc_basename(head);
 	    if (leaf == 0)
 		leaf = head;
 	    *leaf = '\0';
 	    if (head == leaf)
-		(void) strcpy(head, ".");
+		_nc_STRCPY(head, ".", sizeof(head));
 
-	    return access(head, R_OK | W_OK | X_OK);
+	    result = access(head, R_OK | W_OK | X_OK);
+	} else {
+	    result = -1;
 	}
-	return -1;
+    } else {
+	result = 0;
     }
-    return 0;
+    return result;
 }
 
 NCURSES_EXPORT(bool)
@@ -136,7 +151,7 @@
     struct stat sb;
 
     if (stat(path, &sb) == 0
-	&& (sb.st_mode & S_IFMT) == S_IFDIR) {
+	&& S_ISDIR(sb.st_mode)) {
 	result = TRUE;
     }
     return result;
@@ -149,7 +164,7 @@
     struct stat sb;
 
     if (stat(path, &sb) == 0
-	&& (sb.st_mode & S_IFMT) == S_IFREG) {
+	&& S_ISREG(sb.st_mode)) {
 	result = TRUE;
     }
     return result;
@@ -171,6 +186,7 @@
 	|| getgid() != getegid())
 	return FALSE;
 #endif
-    return getuid() != 0 && geteuid() != 0;	/* ...finally, disallow root */
+    /* ...finally, disallow root */
+    return (getuid() != ROOT_UID) && (geteuid() != ROOT_UID);
 }
 #endif
diff --git a/ncurses/tinfo/add_tries.c b/ncurses/tinfo/add_tries.c
index 455d142..29a1a60 100644
--- a/ncurses/tinfo/add_tries.c
+++ b/ncurses/tinfo/add_tries.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2009,2010 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            *
@@ -39,7 +39,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: add_tries.c,v 1.8 2006/12/30 23:15:26 tom Exp $")
+MODULE_ID("$Id: add_tries.c,v 1.10 2010/12/19 01:31:14 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))
@@ -50,7 +50,8 @@
     TRIES *ptr, *savedptr;
     unsigned const char *txt = (unsigned const char *) str;
 
-    T((T_CALLED("_nc_add_to_try(%p, %s, %u)"), *tree, _nc_visbuf(str), code));
+    T((T_CALLED("_nc_add_to_try(%p, %s, %u)"),
+       (void *) *tree, _nc_visbuf(str), code));
     if (txt == 0 || *txt == '\0' || code == 0)
 	returnCode(ERR);
 
@@ -66,7 +67,7 @@
 
 	    if (CMP_TRY(ptr->ch, cmp)) {
 		if (*(++txt) == '\0') {
-		    ptr->value = code;
+		    ptr->value = (unsigned short) code;
 		    returnCode(OK);
 		}
 		if (ptr->child != 0)
@@ -115,6 +116,6 @@
 	ptr->value = 0;
     }
 
-    ptr->value = code;
+    ptr->value = (unsigned short) code;
     returnCode(OK);
 }
diff --git a/ncurses/tinfo/alloc_entry.c b/ncurses/tinfo/alloc_entry.c
index 4638e99..14ea391 100644
--- a/ncurses/tinfo/alloc_entry.c
+++ b/ncurses/tinfo/alloc_entry.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -46,9 +46,8 @@
 #include <curses.priv.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: alloc_entry.c,v 1.48 2008/08/16 16:25:31 tom Exp $")
+MODULE_ID("$Id: alloc_entry.c,v 1.58 2013/08/17 19:20:38 tom Exp $")
 
 #define ABSENT_OFFSET    -1
 #define CANCELLED_OFFSET -2
@@ -62,43 +61,21 @@
 _nc_init_entry(TERMTYPE *const tp)
 /* initialize a terminal type data block */
 {
-    unsigned i;
-
 #if NO_LEAKS
-    if (tp == 0 && stringbuf != 0) {
-	FreeAndNull(stringbuf);
+    if (tp == 0) {
+	if (stringbuf != 0) {
+	    FreeAndNull(stringbuf);
+	}
 	return;
     }
 #endif
 
     if (stringbuf == 0)
-	stringbuf = (char *) malloc(MAX_STRTAB);
-
-#if NCURSES_XNAMES
-    tp->num_Booleans = BOOLCOUNT;
-    tp->num_Numbers = NUMCOUNT;
-    tp->num_Strings = STRCOUNT;
-    tp->ext_Booleans = 0;
-    tp->ext_Numbers = 0;
-    tp->ext_Strings = 0;
-#endif
-    if (tp->Booleans == 0)
-	tp->Booleans = typeMalloc(NCURSES_SBOOL, BOOLCOUNT);
-    if (tp->Numbers == 0)
-	tp->Numbers = typeMalloc(short, NUMCOUNT);
-    if (tp->Strings == 0)
-	tp->Strings = typeMalloc(char *, STRCOUNT);
-
-    for_each_boolean(i, tp)
-	tp->Booleans[i] = FALSE;
-
-    for_each_number(i, tp)
-	tp->Numbers[i] = ABSENT_NUMERIC;
-
-    for_each_string(i, tp)
-	tp->Strings[i] = ABSENT_STRING;
+	TYPE_MALLOC(char, (size_t) MAX_STRTAB, stringbuf);
 
     next_free = 0;
+
+    _nc_init_termtype(tp);
 }
 
 NCURSES_EXPORT(ENTRY *)
@@ -130,13 +107,13 @@
 	    result = (stringbuf + next_free - 1);
 	}
     } else if (next_free + len < MAX_STRTAB) {
-	strcpy(&stringbuf[next_free], string);
+	_nc_STRCPY(&stringbuf[next_free], string, MAX_STRTAB);
 	DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
 	DEBUG(7, ("at location %d", (int) next_free));
 	next_free += len;
 	result = (stringbuf + old_next_free);
     } else {
-	_nc_warning("Too much data, some is lost");
+	_nc_warning("Too much data, some is lost: %s", string);
     }
     return result;
 }
@@ -181,7 +158,7 @@
 	    } else if (tp->Strings[i] == CANCELLED_STRING) {
 		offsets[i] = CANCELLED_OFFSET;
 	    } else {
-		offsets[i] = tp->Strings[i] - stringbuf;
+		offsets[i] = (int) (tp->Strings[i] - stringbuf);
 	    }
 	}
     }
@@ -190,11 +167,10 @@
 	if (ep->uses[i].name == 0)
 	    useoffsets[i] = ABSENT_OFFSET;
 	else
-	    useoffsets[i] = ep->uses[i].name - stringbuf;
+	    useoffsets[i] = (int) (ep->uses[i].name - stringbuf);
     }
 
-    if ((tp->str_table = typeMalloc(char, next_free)) == (char *) 0)
-	  _nc_err_abort(MSG_NO_MEMORY);
+    TYPE_MALLOC(char, next_free, tp->str_table);
     (void) memcpy(tp->str_table, stringbuf, next_free);
 
     tp->term_names = tp->str_table + n;
@@ -214,17 +190,19 @@
     if (!copy_strings) {
 	if ((n = (unsigned) NUM_EXT_NAMES(tp)) != 0) {
 	    if (n < SIZEOF(offsets)) {
-		unsigned length = 0;
+		size_t length = 0;
+		size_t offset;
 		for (i = 0; i < n; i++) {
 		    length += strlen(tp->ext_Names[i]) + 1;
-		    offsets[i] = tp->ext_Names[i] - stringbuf;
+		    offsets[i] = (int) (tp->ext_Names[i] - stringbuf);
 		}
-		if ((tp->ext_str_table = typeMalloc(char, length)) == 0)
-		      _nc_err_abort(MSG_NO_MEMORY);
-		for (i = 0, length = 0; i < n; i++) {
-		    tp->ext_Names[i] = tp->ext_str_table + length;
-		    strcpy(tp->ext_Names[i], stringbuf + offsets[i]);
-		    length += strlen(tp->ext_Names[i]) + 1;
+		TYPE_MALLOC(char, length, tp->ext_str_table);
+		for (i = 0, offset = 0; i < n; i++) {
+		    tp->ext_Names[i] = tp->ext_str_table + offset;
+		    _nc_STRCPY(tp->ext_Names[i],
+			       stringbuf + offsets[i],
+			       length - offset);
+		    offset += strlen(tp->ext_Names[i]) + 1;
 		}
 	    }
 	}
diff --git a/ncurses/tinfo/alloc_ttype.c b/ncurses/tinfo/alloc_ttype.c
index b2b06d1..35c92dd 100644
--- a/ncurses/tinfo/alloc_ttype.c
+++ b/ncurses/tinfo/alloc_ttype.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1999-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1999-2012,2013 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            *
@@ -41,9 +41,8 @@
 #include <curses.priv.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: alloc_ttype.c,v 1.17 2008/10/12 16:12:00 tom Exp $")
+MODULE_ID("$Id: alloc_ttype.c,v 1.27 2013/06/08 16:54:50 tom Exp $")
 
 #if NCURSES_XNAMES
 /*
@@ -91,6 +90,9 @@
     return FALSE;
 }
 
+#define EXTEND_NUM(num, ext) \
+	to->num = (unsigned short) (to->num + (ext - to->ext))
+
 static void
 realign_data(TERMTYPE *to, char **ext_Names,
 	     int ext_Booleans,
@@ -101,8 +103,8 @@
     int limit = (to->ext_Booleans + to->ext_Numbers + to->ext_Strings);
 
     if (to->ext_Booleans != ext_Booleans) {
-	to->num_Booleans += (ext_Booleans - to->ext_Booleans);
-	to->Booleans = typeRealloc(NCURSES_SBOOL, to->num_Booleans, to->Booleans);
+	EXTEND_NUM(num_Booleans, ext_Booleans);
+	TYPE_REALLOC(NCURSES_SBOOL, to->num_Booleans, to->Booleans);
 	for (n = to->ext_Booleans - 1,
 	     m = ext_Booleans - 1,
 	     base = to->num_Booleans - (m + 1); m >= 0; m--) {
@@ -112,11 +114,12 @@
 		to->Booleans[base + m] = FALSE;
 	    }
 	}
-	to->ext_Booleans = ext_Booleans;
+	to->ext_Booleans = UShort(ext_Booleans);
     }
+
     if (to->ext_Numbers != ext_Numbers) {
-	to->num_Numbers += (ext_Numbers - to->ext_Numbers);
-	to->Numbers = typeRealloc(short, to->num_Numbers, to->Numbers);
+	EXTEND_NUM(num_Numbers, ext_Numbers);
+	TYPE_REALLOC(short, to->num_Numbers, to->Numbers);
 	for (n = to->ext_Numbers - 1,
 	     m = ext_Numbers - 1,
 	     base = to->num_Numbers - (m + 1); m >= 0; m--) {
@@ -126,11 +129,11 @@
 		to->Numbers[base + m] = ABSENT_NUMERIC;
 	    }
 	}
-	to->ext_Numbers = ext_Numbers;
+	to->ext_Numbers = UShort(ext_Numbers);
     }
     if (to->ext_Strings != ext_Strings) {
-	to->num_Strings += (ext_Strings - to->ext_Strings);
-	to->Strings = typeRealloc(char *, to->num_Strings, to->Strings);
+	EXTEND_NUM(num_Strings, ext_Strings);
+	TYPE_REALLOC(char *, to->num_Strings, to->Strings);
 	for (n = to->ext_Strings - 1,
 	     m = ext_Strings - 1,
 	     base = to->num_Strings - (m + 1); m >= 0; m--) {
@@ -140,17 +143,17 @@
 		to->Strings[base + m] = ABSENT_STRING;
 	    }
 	}
-	to->ext_Strings = ext_Strings;
+	to->ext_Strings = UShort(ext_Strings);
     }
 }
 
 /*
  * Returns the first index in ext_Names[] for the given token-type
  */
-static int
+static unsigned
 _nc_first_ext_name(TERMTYPE *tp, int token_type)
 {
-    int first;
+    unsigned first;
 
     switch (token_type) {
     case BOOLEAN:
@@ -160,7 +163,7 @@
 	first = tp->ext_Booleans;
 	break;
     case STRING:
-	first = tp->ext_Booleans + tp->ext_Numbers;
+	first = (unsigned) (tp->ext_Booleans + tp->ext_Numbers);
 	break;
     default:
 	first = 0;
@@ -172,17 +175,17 @@
 /*
  * Returns the last index in ext_Names[] for the given token-type
  */
-static int
+static unsigned
 _nc_last_ext_name(TERMTYPE *tp, int token_type)
 {
-    int last;
+    unsigned last;
 
     switch (token_type) {
     case BOOLEAN:
 	last = tp->ext_Booleans;
 	break;
     case NUMBER:
-	last = tp->ext_Booleans + tp->ext_Numbers;
+	last = (unsigned) (tp->ext_Booleans + tp->ext_Numbers);
 	break;
     default:
     case STRING:
@@ -204,7 +207,7 @@
 
     for (j = first; j < last; j++) {
 	if (!strcmp(name, tp->ext_Names[j])) {
-	    return j;
+	    return (int) j;
 	}
     }
     return -1;
@@ -244,7 +247,7 @@
     int first, last;
 
     if ((first = _nc_find_ext_name(tp, name, token_type)) >= 0) {
-	last = NUM_EXT_NAMES(tp) - 1;
+	last = (int) NUM_EXT_NAMES(tp) - 1;
 	for (j = first; j < last; j++) {
 	    tp->ext_Names[j] = tp->ext_Names[j + 1];
 	}
@@ -254,22 +257,22 @@
 	    last = tp->num_Booleans - 1;
 	    for (j = first; j < last; j++)
 		tp->Booleans[j] = tp->Booleans[j + 1];
-	    tp->ext_Booleans -= 1;
-	    tp->num_Booleans -= 1;
+	    tp->ext_Booleans--;
+	    tp->num_Booleans--;
 	    break;
 	case NUMBER:
 	    last = tp->num_Numbers - 1;
 	    for (j = first; j < last; j++)
 		tp->Numbers[j] = tp->Numbers[j + 1];
-	    tp->ext_Numbers -= 1;
-	    tp->num_Numbers -= 1;
+	    tp->ext_Numbers--;
+	    tp->num_Numbers--;
 	    break;
 	case STRING:
 	    last = tp->num_Strings - 1;
 	    for (j = first; j < last; j++)
 		tp->Strings[j] = tp->Strings[j + 1];
-	    tp->ext_Strings -= 1;
-	    tp->num_Strings -= 1;
+	    tp->ext_Strings--;
+	    tp->num_Strings--;
 	    break;
 	}
 	return TRUE;
@@ -299,36 +302,36 @@
 	}
     }
 
-    tp->ext_Names = typeRealloc(char *, total, tp->ext_Names);
+    TYPE_REALLOC(char *, total, tp->ext_Names);
     for (k = total - 1; k > j; k--)
 	tp->ext_Names[k] = tp->ext_Names[k - 1];
     tp->ext_Names[j] = name;
-    j = _nc_ext_data_index(tp, (int) j, token_type);
+    j = (unsigned) _nc_ext_data_index(tp, (int) j, token_type);
 
     switch (token_type) {
     case BOOLEAN:
-	tp->ext_Booleans += 1;
-	tp->num_Booleans += 1;
-	tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
-	for (k = tp->num_Booleans - 1; k > j; k--)
+	tp->ext_Booleans++;
+	tp->num_Booleans++;
+	TYPE_REALLOC(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
+	for (k = (unsigned) (tp->num_Booleans - 1); k > j; k--)
 	    tp->Booleans[k] = tp->Booleans[k - 1];
 	break;
     case NUMBER:
-	tp->ext_Numbers += 1;
-	tp->num_Numbers += 1;
-	tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers);
-	for (k = tp->num_Numbers - 1; k > j; k--)
+	tp->ext_Numbers++;
+	tp->num_Numbers++;
+	TYPE_REALLOC(short, tp->num_Numbers, tp->Numbers);
+	for (k = (unsigned) (tp->num_Numbers - 1); k > j; k--)
 	    tp->Numbers[k] = tp->Numbers[k - 1];
 	break;
     case STRING:
-	tp->ext_Strings += 1;
-	tp->num_Strings += 1;
-	tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings);
-	for (k = tp->num_Strings - 1; k > j; k--)
+	tp->ext_Strings++;
+	tp->num_Strings++;
+	TYPE_REALLOC(char *, tp->num_Strings, tp->Strings);
+	for (k = (unsigned) (tp->num_Strings - 1); k > j; k--)
 	    tp->Strings[k] = tp->Strings[k - 1];
 	break;
     }
-    return j;
+    return (int) j;
 }
 
 /*
@@ -345,10 +348,10 @@
 
     for (j = first; j < last;) {
 	char *name = to->ext_Names[j];
-	unsigned j_str = to->num_Strings - first - to->ext_Strings;
+	int j_str = to->num_Strings - first - to->ext_Strings;
 
 	if (to->Strings[j + j_str] == CANCELLED_STRING) {
-	    if ((k = _nc_find_ext_name(from, to->ext_Names[j], BOOLEAN)) >= 0) {
+	    if (_nc_find_ext_name(from, to->ext_Names[j], BOOLEAN) >= 0) {
 		if (_nc_del_ext_name(to, name, STRING)
 		    || _nc_del_ext_name(to, name, NUMBER)) {
 		    k = _nc_ins_ext_name(to, name, BOOLEAN);
@@ -356,8 +359,7 @@
 		} else {
 		    j++;
 		}
-	    } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],
-					      NUMBER)) >= 0) {
+	    } else if (_nc_find_ext_name(from, to->ext_Names[j], NUMBER) >= 0) {
 		if (_nc_del_ext_name(to, name, STRING)
 		    || _nc_del_ext_name(to, name, BOOLEAN)) {
 		    k = _nc_ins_ext_name(to, name, NUMBER);
@@ -365,8 +367,7 @@
 		} else {
 		    j++;
 		}
-	    } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],
-					      STRING)) >= 0) {
+	    } else if (_nc_find_ext_name(from, to->ext_Names[j], STRING) >= 0) {
 		if (_nc_del_ext_name(to, name, NUMBER)
 		    || _nc_del_ext_name(to, name, BOOLEAN)) {
 		    k = _nc_ins_ext_name(to, name, STRING);
@@ -386,8 +387,8 @@
 NCURSES_EXPORT(void)
 _nc_align_termtype(TERMTYPE *to, TERMTYPE *from)
 {
-    int na = NUM_EXT_NAMES(to);
-    int nb = NUM_EXT_NAMES(from);
+    int na = (int) NUM_EXT_NAMES(to);
+    int nb = (int) NUM_EXT_NAMES(from);
     int n;
     bool same;
     char **ext_Names;
@@ -417,7 +418,7 @@
 	 * into it, updating to's counts for booleans, etc.  Fortunately we do
 	 * this only for the terminfo compiler (tic) and comparer (infocmp).
 	 */
-	ext_Names = typeMalloc(char *, na + nb);
+	TYPE_MALLOC(char *, (size_t)(na + nb), ext_Names);
 
 	if (to->ext_Strings && (from->ext_Booleans + from->ext_Numbers))
 	    adjust_cancels(to, from);
@@ -461,8 +462,8 @@
 	if (nb != (ext_Booleans + ext_Numbers + ext_Strings)) {
 	    nb = (ext_Booleans + ext_Numbers + ext_Strings);
 	    realign_data(from, ext_Names, ext_Booleans, ext_Numbers, ext_Strings);
-	    from->ext_Names = typeRealloc(char *, nb, from->ext_Names);
-	    memcpy(from->ext_Names, ext_Names, sizeof(char *) * nb);
+	    TYPE_REALLOC(char *, (size_t) nb, from->ext_Names);
+	    memcpy(from->ext_Names, ext_Names, sizeof(char *) * (size_t) nb);
 	    DEBUG(2, ("realigned %d extended names for '%s' (from)",
 		      NUM_EXT_NAMES(from), from->term_names));
 	}
@@ -473,22 +474,27 @@
 #endif
 
 NCURSES_EXPORT(void)
-_nc_copy_termtype(TERMTYPE *dst, TERMTYPE *src)
+_nc_copy_termtype(TERMTYPE *dst, const TERMTYPE *src)
 {
+#if NCURSES_XNAMES
     unsigned i;
+#endif
 
     *dst = *src;		/* ...to copy the sizes and string-tables */
-    dst->Booleans = typeMalloc(NCURSES_SBOOL, NUM_BOOLEANS(dst));
-    dst->Numbers = typeMalloc(short, NUM_NUMBERS(dst));
-    dst->Strings = typeMalloc(char *, NUM_STRINGS(dst));
 
-    /* FIXME: use memcpy for these and similar loops */
-    for_each_boolean(i, dst)
-	dst->Booleans[i] = src->Booleans[i];
-    for_each_number(i, dst)
-	dst->Numbers[i] = src->Numbers[i];
-    for_each_string(i, dst)
-	dst->Strings[i] = src->Strings[i];
+    TYPE_MALLOC(NCURSES_SBOOL, NUM_BOOLEANS(dst), dst->Booleans);
+    TYPE_MALLOC(short, NUM_NUMBERS(dst), dst->Numbers);
+    TYPE_MALLOC(char *, NUM_STRINGS(dst), dst->Strings);
+
+    memcpy(dst->Booleans,
+	   src->Booleans,
+	   NUM_BOOLEANS(dst) * sizeof(dst->Booleans[0]));
+    memcpy(dst->Numbers,
+	   src->Numbers,
+	   NUM_NUMBERS(dst) * sizeof(dst->Numbers[0]));
+    memcpy(dst->Strings,
+	   src->Strings,
+	   NUM_STRINGS(dst) * sizeof(dst->Strings[0]));
 
     /* FIXME: we probably should also copy str_table and ext_str_table,
      * but tic and infocmp are not written to exploit that (yet).
@@ -496,11 +502,10 @@
 
 #if NCURSES_XNAMES
     if ((i = NUM_EXT_NAMES(src)) != 0) {
-	dst->ext_Names = typeMalloc(char *, i);
+	TYPE_MALLOC(char *, i, dst->ext_Names);
 	memcpy(dst->ext_Names, src->ext_Names, i * sizeof(char *));
     } else {
 	dst->ext_Names = 0;
     }
 #endif
-
 }
diff --git a/ncurses/tinfo/captoinfo.c b/ncurses/tinfo/captoinfo.c
index 93300c1..e02e622 100644
--- a/ncurses/tinfo/captoinfo.c
+++ b/ncurses/tinfo/captoinfo.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2012 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            *
@@ -93,7 +93,7 @@
 #include <ctype.h>
 #include <tic.h>
 
-MODULE_ID("$Id: captoinfo.c,v 1.52 2008/08/16 19:24:51 tom Exp $")
+MODULE_ID("$Id: captoinfo.c,v 1.77 2012/12/30 00:50:40 tom Exp $")
 
 #define MAX_PUSHED	16	/* max # args we can push onto the stack */
 
@@ -114,9 +114,7 @@
 /* initialize 'my_string', 'my_length' */
 {
     if (my_string == 0)
-	my_string = typeMalloc(char, my_length = 256);
-    if (my_string == 0)
-	_nc_err_abort(MSG_NO_MEMORY);
+	TYPE_MALLOC(char, my_length = 256, my_string);
 
     *my_string = '\0';
     return my_string;
@@ -125,15 +123,15 @@
 static char *
 save_string(char *d, const char *const s)
 {
-    size_t have = (d - my_string);
+    size_t have = (size_t) (d - my_string);
     size_t need = have + strlen(s) + 2;
     if (need > my_length) {
-	my_string = (char *) realloc(my_string, my_length = (need + need));
+	my_string = (char *) _nc_doalloc(my_string, my_length = (need + need));
 	if (my_string == 0)
 	    _nc_err_abort(MSG_NO_MEMORY);
 	d = my_string + have;
     }
-    (void) strcpy(d, s);
+    _nc_STRCPY(d, s, my_length - have);
     return d + strlen(d);
 }
 
@@ -196,7 +194,7 @@
 	case '3':
 	    len = 1;
 	    while (isdigit(UChar(*sp))) {
-		c = 8 * c + (*sp++ - '0');
+		c = (unsigned char) (8 * c + (*sp++ - '0'));
 		len++;
 	    }
 	    break;
@@ -207,7 +205,7 @@
 	}
 	break;
     case '^':
-	c = (*++sp & 0x1f);
+	c = (unsigned char) (*++sp & 0x1f);
 	len = 2;
 	break;
     default:
@@ -240,6 +238,12 @@
 	else if (parm == 2)
 	    parm = 1;
     }
+
+    while (n--) {
+	dp = save_string(dp, "%p");
+	dp = save_char(dp, '0' + parm);
+    }
+
     if (onstack == parm) {
 	if (n > 1) {
 	    _nc_warning("string may not be optimal");
@@ -255,11 +259,6 @@
 
     onstack = parm;
 
-    while (n--) {
-	dp = save_string(dp, "%p");
-	dp = save_char(dp, '0' + parm);
-    }
-
     if (seenn && parm < 3) {
 	dp = save_string(dp, "%{96}%^");
     }
@@ -469,73 +468,9 @@
 		break;
 	    }
 	    break;
-#ifdef REVISIBILIZE
-	case '\\':
-	    dp = save_char(dp, *s++);
-	    dp = save_char(dp, *s++);
-	    break;
-	case '\n':
-	    dp = save_string(dp, "\\n");
-	    s++;
-	    break;
-	case '\t':
-	    dp = save_string(dp, "\\t");
-	    s++;
-	    break;
-	case '\r':
-	    dp = save_string(dp, "\\r");
-	    s++;
-	    break;
-	case '\200':
-	    dp = save_string(dp, "\\0");
-	    s++;
-	    break;
-	case '\f':
-	    dp = save_string(dp, "\\f");
-	    s++;
-	    break;
-	case '\b':
-	    dp = save_string(dp, "\\b");
-	    s++;
-	    break;
-	case ' ':
-	    dp = save_string(dp, "\\s");
-	    s++;
-	    break;
-	case '^':
-	    dp = save_string(dp, "\\^");
-	    s++;
-	    break;
-	case ':':
-	    dp = save_string(dp, "\\:");
-	    s++;
-	    break;
-	case ',':
-	    dp = save_string(dp, "\\,");
-	    s++;
-	    break;
-	default:
-	    if (*s == '\033') {
-		dp = save_string(dp, "\\E");
-		s++;
-	    } else if (*s > 0 && *s < 32) {
-		dp = save_char(dp, '^');
-		dp = save_char(dp, *s + '@');
-		s++;
-	    } else if (*s <= 0 || *s >= 127) {
-		dp = save_char(dp, '\\');
-		dp = save_char(dp, ((*s & 0300) >> 6) + '0');
-		dp = save_char(dp, ((*s & 0070) >> 3) + '0');
-		dp = save_char(dp, (*s & 0007) + '0');
-		s++;
-	    } else
-		dp = save_char(dp, *s++);
-	    break;
-#else
 	default:
 	    dp = save_char(dp, *s++);
 	    break;
-#endif
 	}
     }
 
@@ -578,7 +513,7 @@
 	{
 	    char buffer[80];
 	    int tst;
-	    sprintf(buffer, fmt, ch1, ch2);
+	    _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) fmt, ch1, ch2);
 	    tst = strlen(buffer) - 1;
 	    assert(len == tst);
 	}
@@ -597,10 +532,13 @@
 	    bufptr = save_char(bufptr, '\\');
 	bufptr = save_char(bufptr, c1);
     } else {
-	if (c1 == (c1 & 0x1f))	/* iscntrl() returns T on 255 */
-	    (void) strcpy(temp, unctrl((chtype) c1));
-	else
-	    (void) sprintf(temp, "\\%03o", c1);
+	if (c1 == (c1 & 0x1f)) {	/* iscntrl() returns T on 255 */
+	    _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
+			"%.20s", unctrl((chtype) c1));
+	} else {
+	    _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
+			"\\%03o", c1);
+	}
 	bufptr = save_string(bufptr, temp);
     }
     return bufptr;
@@ -643,15 +581,18 @@
     int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0;
     const char *padding;
     const char *trimmed = 0;
+    int in0, in1, in2;
     char ch1 = 0, ch2 = 0;
     char *bufptr = init_string();
+    char octal[4];
     int len;
     bool syntax_error = FALSE;
 
     /* we may have to move some trailing mandatory padding up front */
     padding = str + strlen(str) - 1;
-    if (padding > str && *padding == '>' && *--padding == '/') {
-	--padding;
+    if (padding > str && *padding == '>') {
+	if (*--padding == '/')
+	    --padding;
 	while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*')
 	    padding--;
 	if (padding > str && *padding == '<' && *--padding == '$')
@@ -662,12 +603,95 @@
 	    bufptr = save_char(bufptr, *padding++);
     }
 
-    for (; *str && str != trimmed; str++) {
+    for (; *str && ((trimmed == 0) || (str < trimmed)); str++) {
 	int c1, c2;
 	char *cp = 0;
 
-	if (str[0] == '\\' && (str[1] == '^' || str[1] == ',')) {
-	    bufptr = save_char(bufptr, *++str);
+	if (str[0] == '^') {
+	    if (str[1] == '\0' || (str + 1) == trimmed) {
+		bufptr = save_string(bufptr, "\\136");
+		++str;
+	    } else {
+		bufptr = save_char(bufptr, *str++);
+		bufptr = save_char(bufptr, *str);
+	    }
+	} else if (str[0] == '\\') {
+	    if (str[1] == '\0' || (str + 1) == trimmed) {
+		bufptr = save_string(bufptr, "\\134");
+		++str;
+	    } else if (str[1] == '^') {
+		bufptr = save_string(bufptr, "\\136");
+		++str;
+	    } else if (str[1] == ',') {
+		bufptr = save_char(bufptr, *++str);
+	    } else {
+		int xx1, xx2;
+
+		bufptr = save_char(bufptr, *str++);
+		xx1 = *str;
+		if (_nc_strict_bsd) {
+		    if (isdigit(UChar(xx1))) {
+			int pad = 0;
+
+			if (!isdigit(UChar(str[1])))
+			    pad = 2;
+			else if (str[1] && !isdigit(UChar(str[2])))
+			    pad = 1;
+
+			/*
+			 * Test for "\0", "\00" or "\000" and transform those
+			 * into "\200".
+			 */
+			if (xx1 == '0'
+			    && ((pad == 2) || (str[1] == '0'))
+			    && ((pad >= 1) || (str[2] == '0'))) {
+			    xx2 = '2';
+			} else {
+			    xx2 = '0';
+			    pad = 0;	/* FIXME - optionally pad to 3 digits */
+			}
+			while (pad-- > 0) {
+			    bufptr = save_char(bufptr, xx2);
+			    xx2 = '0';
+			}
+		    } else if (strchr("E\\nrtbf", xx1) == 0) {
+			switch (xx1) {
+			case 'e':
+			    xx1 = 'E';
+			    break;
+			case 'l':
+			    xx1 = 'n';
+			    break;
+			case 's':
+			    bufptr = save_char(bufptr, '0');
+			    bufptr = save_char(bufptr, '4');
+			    xx1 = '0';
+			    break;
+			case ':':
+			    /*
+			     * Note: termcap documentation claims that ":"
+			     * must be escaped as "\072", however the
+			     * documentation is incorrect - read the code.
+			     * The replacement does not work reliably,
+			     * so the advice is not helpful.
+			     */
+			    bufptr = save_char(bufptr, '0');
+			    bufptr = save_char(bufptr, '7');
+			    xx1 = '2';
+			    break;
+			default:
+			    /* should not happen, but handle this anyway */
+			    _nc_SPRINTF(octal, _nc_SLIMIT(sizeof(octal))
+					"%03o", UChar(xx1));
+			    bufptr = save_char(bufptr, octal[0]);
+			    bufptr = save_char(bufptr, octal[1]);
+			    xx1 = octal[2];
+			    break;
+			}
+		    }
+		}
+		bufptr = save_char(bufptr, xx1);
+	    }
 	} else if (str[0] == '$' && str[1] == '<') {	/* discard padding */
 	    str += 2;
 	    while (isdigit(UChar(*str))
@@ -677,6 +701,20 @@
 		   || *str == '>')
 		str++;
 	    --str;
+	} else if (sscanf(str,
+			  "[%%?%%p1%%{8}%%<%%t%d%%p1%%d%%e%%p1%%{16}%%<%%t%d%%p1%%{8}%%-%%d%%e%d;5;%%p1%%d%%;m",
+			  &in0, &in1, &in2) == 3
+		   && ((in0 == 4 && in1 == 10 && in2 == 48)
+		       || (in0 == 3 && in1 == 9 && in2 == 38))) {
+	    /* dumb-down an optimized case from xterm-256color for termcap */
+	    if ((str = strstr(str, ";m")) == 0)
+		break;		/* cannot happen */
+	    ++str;
+	    if (in2 == 48) {
+		bufptr = save_string(bufptr, "[48;5;%dm");
+	    } else {
+		bufptr = save_string(bufptr, "[38;5;%dm");
+	    }
 	} else if (str[0] == '%' && str[1] == '%') {	/* escaped '%' */
 	    bufptr = save_string(bufptr, "%%");
 	    ++str;
@@ -687,13 +725,13 @@
 	    bufptr = save_tc_inequality(bufptr, c1, c2);
 	} else if (sscanf(str, "%%?%%{%d}%%>%%t%%'%c'%%+%%;", &c1, &ch2) == 2) {
 	    str = strchr(str, ';');
-	    bufptr = save_tc_inequality(bufptr, c1, c2);
+	    bufptr = save_tc_inequality(bufptr, c1, ch2);
 	} else if (sscanf(str, "%%?%%'%c'%%>%%t%%{%d}%%+%%;", &ch1, &c2) == 2) {
 	    str = strchr(str, ';');
-	    bufptr = save_tc_inequality(bufptr, c1, c2);
+	    bufptr = save_tc_inequality(bufptr, ch1, c2);
 	} else if (sscanf(str, "%%?%%'%c'%%>%%t%%'%c'%%+%%;", &ch1, &ch2) == 2) {
 	    str = strchr(str, ';');
-	    bufptr = save_tc_inequality(bufptr, c1, c2);
+	    bufptr = save_tc_inequality(bufptr, ch1, ch2);
 	} else if ((len = bcd_expression(str)) != 0) {
 	    str += len;
 	    bufptr = save_string(bufptr, "%B");
@@ -708,15 +746,15 @@
 	    bufptr = save_tc_char(bufptr, c1);
 	}
 	/* FIXME: this "works" for 'delta' */
-	else if (strncmp(str, "%{2}%*%-", 8) == 0) {
+	else if (strncmp(str, "%{2}%*%-", (size_t) 8) == 0) {
 	    str += 7;
 	    bufptr = save_string(bufptr, "%D");
-	} else if (strncmp(str, "%{96}%^", 7) == 0) {
+	} else if (strncmp(str, "%{96}%^", (size_t) 7) == 0) {
 	    str += 6;
 	    if (saw_m++ == 0) {
 		bufptr = save_string(bufptr, "%n");
 	    }
-	} else if (strncmp(str, "%{127}%^", 8) == 0) {
+	} else if (strncmp(str, "%{127}%^", (size_t) 8) == 0) {
 	    str += 7;
 	    if (saw_n++ == 0) {
 		bufptr = save_string(bufptr, "%m");
@@ -739,8 +777,25 @@
 	    case '8':
 	    case '9':
 		bufptr = save_char(bufptr, '%');
-		while (isdigit(UChar(*str)))
-		    bufptr = save_char(bufptr, *str++);
+		ch1 = 0;
+		ch2 = 0;
+		while (isdigit(UChar(*str))) {
+		    ch2 = ch1;
+		    ch1 = *str++;
+		    if (_nc_strict_bsd) {
+			if (ch1 > '3')
+			    return 0;
+		    } else {
+			bufptr = save_char(bufptr, ch1);
+		    }
+		}
+		if (_nc_strict_bsd) {
+		    if (ch2 != 0 && ch2 != '0')
+			return 0;
+		    if (ch1 < '2')
+			ch1 = 'd';
+		    bufptr = save_char(bufptr, ch1);
+		}
 		if (strchr("doxX.", *str)) {
 		    if (*str != 'd')	/* termcap doesn't have octal, hex */
 			return 0;
@@ -761,6 +816,8 @@
 		 * termcap notation.
 		 */
 	    case 's':
+		if (_nc_strict_bsd)
+		    return 0;
 		bufptr = save_string(bufptr, "%s");
 		break;
 
@@ -793,7 +850,7 @@
 	 * but that may not be the end of the string.
 	 */
 	assert(str != 0);
-	if (*str == '\0')
+	if (str == 0 || *str == '\0')
 	    break;
 
     }				/* endwhile (*str) */
diff --git a/ncurses/tinfo/comp_error.c b/ncurses/tinfo/comp_error.c
index 56c362a..ff0acc7 100644
--- a/ncurses/tinfo/comp_error.c
+++ b/ncurses/tinfo/comp_error.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2005,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2012 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            *
@@ -41,7 +41,7 @@
 
 #include <tic.h>
 
-MODULE_ID("$Id: comp_error.c,v 1.31 2007/04/21 23:38:32 tom Exp $")
+MODULE_ID("$Id: comp_error.c,v 1.36 2012/02/22 22:34:31 tom Exp $")
 
 NCURSES_EXPORT_VAR(bool) _nc_suppress_warnings = FALSE;
 NCURSES_EXPORT_VAR(int) _nc_curr_line = 0; /* current line # in input */
@@ -59,7 +59,8 @@
 NCURSES_EXPORT(void)
 _nc_set_source(const char *const name)
 {
-    SourceName = name;
+    FreeIfNeeded(SourceName);
+    SourceName = strdup(name);
 }
 
 NCURSES_EXPORT(void)
@@ -70,7 +71,7 @@
     if (TermType != 0) {
 	TermType[0] = '\0';
 	if (name)
-	    strncat(TermType, name, MAX_NAME_SIZE);
+	    strncat(TermType, name, (size_t) MAX_NAME_SIZE);
     }
 }
 
@@ -84,7 +85,7 @@
     }
 #endif
     if (name != 0)
-	strcpy(name, TermType != 0 ? TermType : "");
+	_nc_STRCPY(name, TermType != 0 ? TermType : "", MAX_NAME_SIZE);
 }
 
 static NCURSES_INLINE void
@@ -151,3 +152,12 @@
     exit(EXIT_FAILURE);
 #endif
 }
+
+#if NO_LEAKS
+NCURSES_EXPORT(void)
+_nc_comp_error_leaks(void)
+{
+    FreeAndNull(SourceName);
+    FreeAndNull(TermType);
+}
+#endif
diff --git a/ncurses/tinfo/comp_expand.c b/ncurses/tinfo/comp_expand.c
index 6e79a92..2ab06eb 100644
--- a/ncurses/tinfo/comp_expand.c
+++ b/ncurses/tinfo/comp_expand.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2012 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            *
@@ -35,7 +35,7 @@
 #include <ctype.h>
 #include <tic.h>
 
-MODULE_ID("$Id: comp_expand.c,v 1.20 2008/08/16 19:29:42 tom Exp $")
+MODULE_ID("$Id: comp_expand.c,v 1.25 2012/03/24 18:37:17 tom Exp $")
 
 static int
 trailing_spaces(const char *src)
@@ -49,6 +49,8 @@
 #define REALCTL(s) (UChar(*(s)) < 127 && iscntrl(UChar(*(s))))
 #define REALPRINT(s) (UChar(*(s)) < 127 && isprint(UChar(*(s))))
 
+#define P_LIMIT(p) (length - (size_t)(p))
+
 NCURSES_EXPORT(char *)
 _nc_tic_expand(const char *srcp, bool tic_format, int numbers)
 {
@@ -61,15 +63,15 @@
     size_t need = (2 + strlen(str)) * 4;
     int ch;
 
-#if NO_LEAKS
     if (srcp == 0) {
+#if NO_LEAKS
 	if (buffer != 0) {
 	    FreeAndNull(buffer);
 	    length = 0;
 	}
+#endif
 	return 0;
     }
-#endif
     if (buffer == 0 || need > length) {
 	if ((buffer = typeRealloc(char, length = need, buffer)) == 0)
 	      return 0;
@@ -90,8 +92,9 @@
 		    && str[1] != '\\'
 		    && REALPRINT(str + 1)
 		    && str[2] == S_QUOTE) {
-		    sprintf(buffer + bufp, "{%d}", str[1]);
-		    bufp += strlen(buffer + bufp);
+		    _nc_SPRINTF(buffer + bufp, _nc_SLIMIT(P_LIMIT(bufp))
+				"{%d}", str[1]);
+		    bufp += (int) strlen(buffer + bufp);
 		    str += 2;
 		} else {
 		    buffer[bufp++] = *str;
@@ -177,10 +180,12 @@
 #define UnCtl(c) ((c) + '@')
 	else if (REALCTL(str) && ch != '\\'
 		 && (!islong || isdigit(UChar(str[1])))) {
-	    (void) sprintf(&buffer[bufp], "^%c", UnCtl(ch));
+	    _nc_SPRINTF(&buffer[bufp], _nc_SLIMIT(P_LIMIT(bufp))
+			"^%c", UnCtl(ch));
 	    bufp += 2;
 	} else {
-	    (void) sprintf(&buffer[bufp], "\\%03o", ch);
+	    _nc_SPRINTF(&buffer[bufp], _nc_SLIMIT(P_LIMIT(bufp))
+			"\\%03o", ch);
 	    bufp += 4;
 	}
 
diff --git a/ncurses/tinfo/comp_hash.c b/ncurses/tinfo/comp_hash.c
index b7fbd06..959c6e1 100644
--- a/ncurses/tinfo/comp_hash.c
+++ b/ncurses/tinfo/comp_hash.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2009 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            *
@@ -44,110 +44,36 @@
 #include <tic.h>
 #include <hashsize.h>
 
-#ifdef MAIN_PROGRAM
-#include <ctype.h>
-#undef  DEBUG
-#define DEBUG(level, params)	/*nothing */
-#endif
-
-MODULE_ID("$Id: comp_hash.c,v 1.36 2008/08/16 17:06:53 tom Exp $")
-
-static int hash_function(const char *);
+MODULE_ID("$Id: comp_hash.c,v 1.48 2009/08/08 17:36:21 tom Exp $")
 
 /*
- *	_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[].
- *
+ * 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.
  */
-
-#ifdef MAIN_PROGRAM
-
-#undef MODULE_ID
-#define MODULE_ID(id)		/*nothing */
-#include <tinfo/doalloc.c>
-
-static void
-_nc_make_hash_table(struct name_table_entry *table,
-		    short *hash_table)
-{
-    short i;
-    int hashvalue;
-    int collisions = 0;
-
-    for (i = 0; i < HASHTABSIZE; i++) {
-	hash_table[i] = -1;
-    }
-    for (i = 0; i < CAPTABSIZE; i++) {
-	hashvalue = hash_function(table[i].nte_name);
-
-	if (hash_table[hashvalue] >= 0)
-	    collisions++;
-
-	if (hash_table[hashvalue] != 0)
-	    table[i].nte_link = hash_table[hashvalue];
-	hash_table[hashvalue] = 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
+/* entrypoint used by tack (do not alter) */
 NCURSES_EXPORT(struct name_table_entry const *)
 _nc_find_entry(const char *string,
-	       const short *hash_table)
+	       const HashValue * hash_table)
 {
+    bool termcap = (hash_table != _nc_get_hash_table(FALSE));
+    const HashData *data = _nc_get_hash_info(termcap);
     int hashvalue;
     struct name_table_entry const *ptr = 0;
     struct name_table_entry const *real_table;
 
-    hashvalue = hash_function(string);
+    hashvalue = data->hash_of(string);
 
-    if (hash_table[hashvalue] >= 0) {
-	real_table = _nc_get_table(hash_table != _nc_get_hash_table(FALSE));
-	ptr = real_table + hash_table[hashvalue];
-	while (strcmp(ptr->nte_name, string) != 0) {
-	    if (ptr->nte_link < 0)
-		return 0;
-	    ptr = real_table + (ptr->nte_link + hash_table[HASHTABSIZE]);
+    if (data->table_data[hashvalue] >= 0) {
+
+	real_table = _nc_get_table(termcap);
+	ptr = real_table + data->table_data[hashvalue];
+	while (!data->compare_names(ptr->nte_name, string)) {
+	    if (ptr->nte_link < 0) {
+		ptr = 0;
+		break;
+	    }
+	    ptr = real_table + (ptr->nte_link
+				+ data->table_data[data->table_size]);
 	}
     }
 
@@ -155,216 +81,34 @@
 }
 
 /*
- *	struct name_table_entry *
- *	find_type_entry(string, type, table)
+ * Finds the entry for the given name with the given type in the given table if
+ * present (as distinct from _nc_find_entry, which finds the last entry
+ * regardless of type).
  *
- *	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.
+ * Returns a pointer to the entry in the table or 0 if not found.
  */
-
 NCURSES_EXPORT(struct name_table_entry const *)
 _nc_find_type_entry(const char *string,
 		    int type,
-		    const struct name_table_entry *table)
+		    bool termcap)
 {
-    struct name_table_entry const *ptr;
+    struct name_table_entry const *ptr = NULL;
+    const HashData *data = _nc_get_hash_info(termcap);
+    int hashvalue = data->hash_of(string);
 
-    for (ptr = table; ptr < table + CAPTABSIZE; ptr++) {
-	if (ptr->nte_type == type && strcmp(string, ptr->nte_name) == 0)
-	    return (ptr);
-    }
+    if (data->table_data[hashvalue] >= 0) {
+	const struct name_table_entry *const table = _nc_get_table(termcap);
 
-    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).
- */
-
-#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(UChar(*s)); s++)
-		/*EMPTY */ ;
-	    if (s != buffer) {
-		char mark = *s;
-		*s = '\0';
-		if ((s - buffer) > 1
-		    && (*buffer == '"')
-		    && (s[-1] == '"')) {	/* strip the quotes */
-		    assert(s > buffer + 1);
-		    s[-1] = '\0';
-		    buffer++;
-		}
-		list[col] = buffer;
-		col++;
-		if (mark == '\0')
-		    break;
-		while (*++s && isspace(UChar(*s)))
-		    /*EMPTY */ ;
-		buffer = s;
-	    } else
+	ptr = table + data->table_data[hashvalue];
+	while (ptr->nte_type != type
+	       || !data->compare_names(ptr->nte_name, string)) {
+	    if (ptr->nte_link < 0) {
+		ptr = 0;
 		break;
-	}
-    }
-    return col ? list : 0;
-}
-
-int
-main(int argc, char **argv)
-{
-    struct name_table_entry *name_table = typeCalloc(struct
-						     name_table_entry, CAPTABSIZE);
-    short *hash_table = typeCalloc(short, HASHTABSIZE);
-    const char *root_name = "";
-    int column = 0;
-    int bigstring = 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 <= 3
-	|| (column = atoi(argv[1])) <= 0
-	|| (column >= MAX_COLUMNS)
-	|| *(root_name = argv[2]) == 0
-	|| (bigstring = atoi(argv[3])) < 0
-	|| name_table == 0
-	|| hash_table == 0) {
-	fprintf(stderr, "usage: make_hash column root_name bigstring\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
-     */
-    if (bigstring) {
-	int len = 0;
-	int nxt;
-
-	printf("static const char %s_names_text[] = \\\n", root_name);
-	for (n = 0; n < CAPTABSIZE; n++) {
-	    nxt = (int) strlen(name_table[n].nte_name) + 5;
-	    if (nxt + len > 72) {
-		printf("\\\n");
-		len = 0;
 	    }
-	    printf("\"%s\\0\" ", name_table[n].nte_name);
-	    len += nxt;
+	    ptr = table + (ptr->nte_link + data->table_data[data->table_size]);
 	}
-	printf(";\n\n");
-
-	len = 0;
-	printf("static name_table_data const %s_names_data[] =\n",
-	       root_name);
-	printf("{\n");
-	for (n = 0; n < CAPTABSIZE; n++) {
-	    printf("\t{ %15d,\t%10s,\t%3d, %3d }%c\n",
-		   len,
-		   typenames[name_table[n].nte_type],
-		   name_table[n].nte_index,
-		   name_table[n].nte_link,
-		   n < CAPTABSIZE - 1 ? ',' : ' ');
-	    len += (int) strlen(name_table[n].nte_name) + 1;
-	}
-	printf("};\n\n");
-	printf("static struct name_table_entry *_nc_%s_table = 0;\n\n", root_name);
-    } else {
-
-	printf("static struct name_table_entry %s _nc_%s_table[] =\n",
-	       bigstring ? "" : "const",
-	       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("static const short _nc_%s_hash_table[%d] =\n",
-	   root_name,
-	   HASHTABSIZE + 1);
-    printf("{\n");
-    for (n = 0; n < HASHTABSIZE; n++) {
-	printf("\t%3d,\n", hash_table[n]);
-    }
-    printf("\t0\t/* base-of-table */\n");
-    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");
-
-    free(hash_table);
-    return EXIT_SUCCESS;
+    return ptr;
 }
-#endif
diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c
index 3325a0d..82a61a5 100644
--- a/ncurses/tinfo/comp_parse.c
+++ b/ncurses/tinfo/comp_parse.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -35,15 +35,10 @@
 /*
  *	comp_parse.c -- parser driver loop and use handling.
  *
- *	_nc_read_entry_source(FILE *, literal, bool, bool (*hook)())
- *	_nc_resolve_uses2(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_uses2().  To free the list
  *	storage, do _nc_free_entries().
- *
  */
 
 #include <curses.priv.h>
@@ -51,9 +46,8 @@
 #include <ctype.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: comp_parse.c,v 1.69 2008/08/16 21:58:16 tom Exp $")
+MODULE_ID("$Id: comp_parse.c,v 1.90 2013/08/31 15:22:31 tom Exp $")
 
 static void sanity_check2(TERMTYPE *, bool);
 NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2;
@@ -62,6 +56,8 @@
 static void sanity_check(TERMTYPE *);
 NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype) (TERMTYPE *) = sanity_check;
 
+static void fixup_acsc(TERMTYPE *, int);
+
 static void
 enqueue(ENTRY * ep)
 /* add an entry to the in-core list */
@@ -87,31 +83,125 @@
 	if (len > MAX_NAME_SIZE)
 	    len = MAX_NAME_SIZE;
 	(void) strncpy(dst, src, len);
-	(void) strcpy(dst + len, "|");
+	_nc_STRCPY(dst + len, "|", MAX_NAME_SIZE);
 	src = dst;
     }
     return src;
 }
+#define ForceBar(dst, src) ((strchr(src, '|') == 0) ? force_bar(dst, src) : src)
 
-NCURSES_EXPORT(bool)
-_nc_entry_match(char *n1, char *n2)
-/* do any of the aliases in a pair of terminal names match? */
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+static char *
+skip_index(char *name)
+{
+    char *bar = strchr(name, '|');
+
+    if (bar != 0 && (bar - name) == 2)
+	name = bar + 1;
+
+    return name;
+}
+#endif
+
+static bool
+check_collisions(char *n1, char *n2, int counter)
 {
     char *pstart, *qstart, *pend, *qend;
-    char nc1[MAX_NAME_SIZE + 2], nc2[MAX_NAME_SIZE + 2];
+    char nc1[MAX_NAME_SIZE + 2];
+    char nc2[MAX_NAME_SIZE + 2];
 
-    n1 = force_bar(nc1, n1);
-    n2 = force_bar(nc2, n2);
+    n1 = ForceBar(nc1, n1);
+    n2 = ForceBar(nc2, n2);
 
-    for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1)
-	for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1)
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+    if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) {
+	n1 = skip_index(n1);
+	n2 = skip_index(n2);
+    }
+#endif
+
+    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)
+		&& memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) {
+		if (counter > 0)
+		    (void) fprintf(stderr, "Name collision '%.*s' between\n",
+				   (int) (pend - pstart), pstart);
 		return (TRUE);
+	    }
+	}
+    }
 
     return (FALSE);
 }
 
+static char *
+next_name(char *name)
+{
+    if (*name != '\0')
+	++name;
+    return name;
+}
+
+static char *
+name_ending(char *name)
+{
+    if (*name == '\0') {
+	name = 0;
+    } else {
+	while (*name != '\0' && *name != '|')
+	    ++name;
+    }
+    return name;
+}
+
+/*
+ * Essentially, find the conflict reported in check_collisions() and remove
+ * it from the second name, unless that happens to be the last alias.
+ */
+static bool
+remove_collision(char *n1, char *n2)
+{
+    char *p2 = n2;
+    char *pstart, *qstart, *pend, *qend;
+    bool removed = FALSE;
+
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+    if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) {
+	n1 = skip_index(n1);
+	p2 = n2 = skip_index(n2);
+    }
+#endif
+
+    for (pstart = n1; (pend = name_ending(pstart)); pstart = next_name(pend)) {
+	for (qstart = n2; (qend = name_ending(qstart)); qstart = next_name(qend)) {
+	    if ((pend - pstart == qend - qstart)
+		&& memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) {
+		if (qstart != p2 || *qend == '|') {
+		    if (*qend == '|')
+			++qend;
+		    while ((*qstart++ = *qend++) != '\0') ;
+		    fprintf(stderr, "...now\t%s\n", p2);
+		} else {
+		    fprintf(stderr, "Cannot remove alias '%.*s'\n",
+			    (int) (qend - qstart), qstart);
+		}
+		removed = TRUE;
+		break;
+	    }
+	}
+    }
+
+    return removed;
+}
+
+/* do any of the aliases in a pair of terminal names match? */
+NCURSES_EXPORT(bool)
+_nc_entry_match(char *n1, char *n2)
+{
+    return check_collisions(n1, n2, 0);
+}
+
 /****************************************************************************
  *
  * Entry compiler and resolution logic
@@ -197,19 +287,19 @@
 
 	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++;
+		&& check_collisions(qp->tterm.term_names,
+				    rp->tterm.term_names,
+				    matchcount + 1)) {
+		if (!matchcount++) {
+		    (void) fprintf(stderr, "\t%s\n", rp->tterm.term_names);
 		}
-		if (matchcount >= 1)
-		    (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names));
+		(void) fprintf(stderr, "and\t%s\n", qp->tterm.term_names);
+		if (!remove_collision(rp->tterm.term_names,
+				      qp->tterm.term_names)) {
+		    ++multiples;
+		}
 	    }
 	}
-	if (matchcount >= 1)
-	    (void) putc('\n', stderr);
     }
     if (multiples > 0)
 	return (FALSE);
@@ -255,9 +345,7 @@
 		    DEBUG(2, ("%s: resolving use=%s (compiled)",
 			      child, lookfor));
 
-		    rp = typeMalloc(ENTRY, 1);
-		    if (rp == 0)
-			_nc_err_abort(MSG_NO_MEMORY);
+		    TYPE_MALLOC(ENTRY, 1, rp);
 		    rp->tterm = thisterm;
 		    rp->nuses = 0;
 		    rp->next = lastread;
@@ -273,7 +361,7 @@
 		unresolved++;
 		total_unresolved++;
 
-		_nc_curr_line = lookline;
+		_nc_curr_line = (int) lookline;
 		_nc_warning("resolution of use=%s failed", lookfor);
 		qp->uses[i].link = 0;
 	    }
@@ -375,9 +463,36 @@
 	if (_nc_check_termtype != 0) {
 	    _nc_curr_col = -1;
 	    for_entry_list(qp) {
-		_nc_curr_line = qp->startline;
+		_nc_curr_line = (int) qp->startline;
 		_nc_set_type(_nc_first_name(qp->tterm.term_names));
-		_nc_check_termtype2(&qp->tterm, literal);
+		/*
+		 * tic overrides this function pointer to provide more verbose
+		 * checking.
+		 */
+		if (_nc_check_termtype2 != sanity_check2) {
+		    SCREEN *save_SP = SP;
+		    SCREEN fake_sp;
+		    TERMINAL fake_tm;
+		    TERMINAL *save_tm = cur_term;
+
+		    /*
+		     * Setup so that tic can use ordinary terminfo interface
+		     * to obtain capability information.
+		     */
+		    memset(&fake_sp, 0, sizeof(fake_sp));
+		    memset(&fake_tm, 0, sizeof(fake_tm));
+		    fake_sp._term = &fake_tm;
+		    fake_tm.type = qp->tterm;
+		    _nc_set_screen(&fake_sp);
+		    set_curterm(&fake_tm);
+
+		    _nc_check_termtype2(&qp->tterm, literal);
+
+		    _nc_set_screen(save_SP);
+		    set_curterm(save_tm);
+		} else {
+		    fixup_acsc(&qp->tterm, literal);
+		}
 	    }
 	    DEBUG(2, ("SANITY CHECK FINISHED"));
 	}
@@ -402,6 +517,17 @@
 #define CUR tp->
 
 static void
+fixup_acsc(TERMTYPE *tp, int literal)
+{
+    if (!literal) {
+	if (acs_chars == 0
+	    && enter_alt_charset_mode != 0
+	    && exit_alt_charset_mode != 0)
+	    acs_chars = strdup(VT_ACSC);
+    }
+}
+
+static void
 sanity_check2(TERMTYPE *tp, bool literal)
 {
     if (!PRESENT(exit_attribute_mode)) {
@@ -421,16 +547,14 @@
 #endif /* __UNUSED__ */
 	PAIRED(enter_standout_mode, exit_standout_mode);
 	PAIRED(enter_underline_mode, exit_underline_mode);
+	PAIRED(enter_italics_mode, exit_italics_mode);
     }
 
     /* we do this check/fix in postprocess_termcap(), but some packagers
      * prefer to bypass it...
      */
     if (!literal) {
-	if (acs_chars == 0
-	    && enter_alt_charset_mode != 0
-	    && exit_alt_charset_mode != 0)
-	    acs_chars = strdup(VT_ACSC);
+	fixup_acsc(tp, literal);
 	ANDMISSING(enter_alt_charset_mode, acs_chars);
 	ANDMISSING(exit_alt_charset_mode, acs_chars);
     }
@@ -473,7 +597,6 @@
 {
     _nc_alloc_entry_leaks();
     _nc_captoinfo_leaks();
-    _nc_comp_captab_leaks();
     _nc_comp_scan_leaks();
 #if BROKEN_LINKER || USE_REENTRANT
     _nc_names_leaks();
diff --git a/ncurses/tinfo/comp_scan.c b/ncurses/tinfo/comp_scan.c
index 5ad750f..fe6e8e7 100644
--- a/ncurses/tinfo/comp_scan.c
+++ b/ncurses/tinfo/comp_scan.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -48,10 +48,9 @@
 #include <curses.priv.h>
 
 #include <ctype.h>
-#include <term_entry.h>
 #include <tic.h>
 
-MODULE_ID("$Id: comp_scan.c,v 1.83 2008/08/16 19:22:55 tom Exp $")
+MODULE_ID("$Id: comp_scan.c,v 1.102 2013/11/16 19:57:50 tom Exp $")
 
 /*
  * Maximum length of string capability we'll accept before raising an error.
@@ -61,19 +60,14 @@
 
 #define iswhite(ch)	(ch == ' '  ||  ch == '\t')
 
-NCURSES_EXPORT_VAR(int)
-_nc_syntax = 0;			/* termcap or terminfo? */
-NCURSES_EXPORT_VAR(long)
-_nc_curr_file_pos = 0;		/* file offset of current line */
-NCURSES_EXPORT_VAR(long)
-_nc_comment_start = 0;		/* start of comment range before name */
-NCURSES_EXPORT_VAR(long)
-_nc_comment_end = 0;		/* end of comment range before name */
-NCURSES_EXPORT_VAR(long)
-_nc_start_line = 0;		/* start line of current entry */
+NCURSES_EXPORT_VAR (int) _nc_syntax = 0;         /* termcap or terminfo? */
+NCURSES_EXPORT_VAR (int) _nc_strict_bsd = 1;  /* ncurses extended termcap? */
+NCURSES_EXPORT_VAR (long) _nc_curr_file_pos = 0; /* file offset of current line */
+NCURSES_EXPORT_VAR (long) _nc_comment_start = 0; /* start of comment range before name */
+NCURSES_EXPORT_VAR (long) _nc_comment_end = 0;   /* end of comment range before name */
+NCURSES_EXPORT_VAR (long) _nc_start_line = 0;    /* start line of current entry */
 
-NCURSES_EXPORT_VAR(struct token)
-_nc_curr_token =
+NCURSES_EXPORT_VAR (struct token) _nc_curr_token =
 {
     0, 0, 0
 };
@@ -91,8 +85,7 @@
 static char *pushname;
 
 #if NCURSES_EXT_FUNCS
-NCURSES_EXPORT_VAR(bool)
-_nc_disable_period = FALSE;	/* used by tic -a option */
+NCURSES_EXPORT_VAR (bool) _nc_disable_period = FALSE; /* used by tic -a option */
 #endif
 
 /*****************************************************************************
@@ -135,14 +128,19 @@
  *	Returns the final nonblank character on the current input buffer
  */
 static int
-last_char(void)
+last_char(int from_end)
 {
     size_t len = strlen(bufptr);
+    int result = 0;
+
     while (len--) {
-	if (!isspace(UChar(bufptr[len])))
-	    return bufptr[len];
+	if (!isspace(UChar(bufptr[len]))) {
+	    if (from_end < (int) len)
+		result = bufptr[(int) len - from_end];
+	    break;
+	}
     }
-    return 0;
+    return result;
 }
 
 /*
@@ -203,7 +201,8 @@
 		    result = typeRealloc(char, allocated, result);
 		    if (result == 0)
 			return (EOF);
-		    bufstart = result;
+		    if (bufstart)
+			bufstart = result;
 		}
 		if (used == 0)
 		    _nc_curr_file_pos = ftell(yyin);
@@ -211,12 +210,16 @@
 		if (fgets(result + used, (int) (allocated - used), yyin) != 0) {
 		    bufstart = result;
 		    if (used == 0) {
+			if (_nc_curr_line == 0
+			    && IS_TIC_MAGIC(result)) {
+			    _nc_err_abort("This is a compiled terminal description, not a source");
+			}
 			_nc_curr_line++;
 			_nc_curr_col = 0;
 		    }
 		} else {
 		    if (used != 0)
-			strcat(result, "\n");
+			_nc_STRCAT(result, "\n", allocated);
 		}
 		if ((bufptr = bufstart) != 0) {
 		    used = strlen(bufptr);
@@ -260,12 +263,12 @@
 }
 
 static void
-push_back(char c)
+push_back(int c)
 /* push a character back onto the input stream */
 {
     if (bufptr == bufstart)
 	_nc_syserr_abort("Can't backspace off beginning of line");
-    *--bufptr = c;
+    *--bufptr = (char) c;
     _nc_curr_col--;
 }
 
@@ -303,6 +306,8 @@
 	*tok_ptr++ = (char) ch; \
 	*tok_ptr = '\0'
 
+static char *tok_buf;
+
 /*
  *	int
  *	get_token()
@@ -340,15 +345,14 @@
 _nc_get_token(bool silent)
 {
     static const char terminfo_punct[] = "@%&*!#";
-    static char *tok_buf;
 
-    char *after_list;
-    char *after_name;
+    char *after_name;		/* after primary name */
+    char *after_list;		/* after primary and alias list */
     char *numchk;
     char *tok_ptr;
     char *s;
     char numbuf[80];
-    int ch;
+    int ch, c0, c1;
     int dot_flag = FALSE;
     int type;
     long number;
@@ -376,11 +380,10 @@
 
     if (end_of_stream()) {
 	yyin = 0;
-	next_char();		/* frees its allocated memory */
+	(void) next_char();	/* frees its allocated memory */
 	if (tok_buf != 0) {
 	    if (_nc_curr_token.tk_name == tok_buf)
 		_nc_curr_token.tk_name = 0;
-	    FreeAndNull(tok_buf);
 	}
 	return (EOF);
     }
@@ -394,6 +397,7 @@
     }
 
     ch = eat_escaped_newline(ch);
+    _nc_curr_token.tk_valstring = 0;
 
 #ifdef TRACE
     old_line = _nc_curr_line;
@@ -428,10 +432,10 @@
 #if NCURSES_EXT_FUNCS
 	    && !(ch == '.' && _nc_disable_period)
 #endif
-	    && !strchr(terminfo_punct, (char) ch)) {
+	    && ((strchr) (terminfo_punct, (char) ch) == 0)) {
 	    if (!silent)
 		_nc_warning("Illegal character (expected alphanumeric or %s) - '%s'",
-			    terminfo_punct, unctrl((chtype) ch));
+			    terminfo_punct, unctrl(UChar(ch)));
 	    _nc_panic_mode(separator);
 	    goto start_token;
 	}
@@ -461,7 +465,7 @@
 		    after_list = tok_ptr;
 		    if (after_name == 0)
 			after_name = tok_ptr;
-		} else if (ch == ':' && last_char() != ',') {
+		} else if (ch == ':' && last_char(0) != ',') {
 		    _nc_syntax = SYN_TERMCAP;
 		    separator = ':';
 		    break;
@@ -475,19 +479,70 @@
 		    if (after_name == 0)
 			break;
 		    /*
-		     * If we see a comma, we assume this is terminfo unless we
-		     * subsequently run into a colon.  But we don't stop
-		     * looking for a colon until hitting a newline.  This
-		     * allows commas to be embedded in description fields of
-		     * either syntax.
+		     * We saw a comma, but are not entirely sure this is
+		     * terminfo format, since we can still be parsing the
+		     * description field (for either syntax).
+		     *
+		     * A properly formatted termcap line ends with either a
+		     * colon, or a backslash after a colon.  It is possible
+		     * to have a backslash in the middle of a capability, but
+		     * then there would be no leading whitespace on the next
+		     * line - something we want to discourage.
 		     */
+		    c0 = last_char(0);
+		    c1 = last_char(1);
+		    if (c1 != ':' && c0 != '\\' && c0 != ':') {
+			bool capability = FALSE;
+
+			/*
+			 * Since it is not termcap, assume the line is terminfo
+			 * format.  However, the comma can be embedded in a
+			 * description field.  It also can be a separator
+			 * between a description field and a capability.
+			 *
+			 * Improve the guess by checking if the next word after
+			 * the comma does not look like a capability.  In that
+			 * case, extend the description past the comma.
+			 */
+			for (s = bufptr; isspace(UChar(*s)); ++s) {
+			    ;
+			}
+			if (islower(UChar(*s))) {
+			    char *name = s;
+			    while (isalnum(UChar(*s))) {
+				++s;
+			    }
+			    if (*s == '#' || *s == '=' || *s == '@') {
+				/*
+				 * Checking solely with syntax allows us to
+				 * support extended capabilities with string
+				 * values.
+				 */
+				capability = TRUE;
+			    } else if (*s == ',') {
+				c0 = *s;
+				*s = '\0';
+				/*
+				 * Otherwise, we can handle predefined boolean
+				 * capabilities, still aided by syntax.
+				 */
+				if (_nc_find_entry(name,
+						   _nc_get_hash_table(FALSE))) {
+				    capability = TRUE;
+				}
+				*s = (char) c0;
+			    }
+			}
+			if (capability) {
+			    break;
+			}
+		    }
 		} else
 		    ch = eat_escaped_newline(ch);
 
 		if (OkToAdd()) {
 		    AddCh(ch);
 		} else {
-		    ch = EOF;
 		    break;
 		}
 	    }
@@ -596,7 +651,7 @@
 	    case '@':
 		if ((ch = next_char()) != separator && !silent)
 		    _nc_warning("Missing separator after `%s', have %s",
-				tok_buf, unctrl((chtype) ch));
+				tok_buf, unctrl(UChar(ch)));
 		_nc_curr_token.tk_name = tok_buf;
 		type = CANCEL;
 		break;
@@ -617,7 +672,7 @@
 			_nc_warning("Missing separator");
 		}
 		_nc_curr_token.tk_name = tok_buf;
-		_nc_curr_token.tk_valnumber = number;
+		_nc_curr_token.tk_valnumber = (int) number;
 		type = NUMBER;
 		break;
 
@@ -637,7 +692,7 @@
 		/* just to get rid of the compiler warning */
 		type = UNDEF;
 		if (!silent)
-		    _nc_warning("Illegal character - '%s'", unctrl((chtype) ch));
+		    _nc_warning("Illegal character - '%s'", unctrl(UChar(ch)));
 	    }
 	}			/* end else (first_column == FALSE) */
     }				/* end else (ch != EOF) */
@@ -730,57 +785,62 @@
     int count = 0;
     int number = 0;
     int i, c;
-    chtype ch, last_ch = '\0';
+    int last_ch = '\0';
     bool ignored = FALSE;
     bool long_warning = FALSE;
 
-    while ((ch = c = next_char()) != (chtype) separator && c != EOF) {
+    while ((c = next_char()) != separator && c != EOF) {
 	if (ptr >= (last - 1)) {
 	    if (c != EOF) {
 		while ((c = next_char()) != separator && c != EOF) {
 		    ;
 		}
-		ch = c;
 	    }
 	    break;
 	}
 	if ((_nc_syntax == SYN_TERMCAP) && c == '\n')
 	    break;
-	if (ch == '^' && last_ch != '%') {
-	    ch = c = next_char();
+	if (c == '^' && last_ch != '%') {
+	    c = next_char();
 	    if (c == EOF)
 		_nc_err_abort(MSG_NO_INPUTS);
 
-	    if (!(is7bits(ch) && isprint(ch))) {
-		_nc_warning("Illegal ^ character - '%s'", unctrl(ch));
+	    if (!(is7bits(c) && isprint(c))) {
+		_nc_warning("Illegal ^ character - '%s'", unctrl(UChar(c)));
 	    }
-	    if (ch == '?') {
+	    if (c == '?' && (_nc_syntax != SYN_TERMCAP)) {
 		*(ptr++) = '\177';
 		if (_nc_tracing)
 		    _nc_warning("Allow ^? as synonym for \\177");
 	    } else {
-		if ((ch &= 037) == 0)
-		    ch = 128;
-		*(ptr++) = (char) (ch);
+		if ((c &= 037) == 0)
+		    c = 128;
+		*(ptr++) = (char) (c);
 	    }
-	} else if (ch == '\\') {
-	    ch = c = next_char();
+	} else if (c == '\\') {
+	    bool strict_bsd = ((_nc_syntax == SYN_TERMCAP) && _nc_strict_bsd);
+
+	    c = next_char();
 	    if (c == EOF)
 		_nc_err_abort(MSG_NO_INPUTS);
 
-	    if (ch >= '0' && ch <= '7') {
-		number = ch - '0';
+#define isoctal(c) ((c) >= '0' && (c) <= '7')
+
+	    if (isoctal(c) || (strict_bsd && isdigit(c))) {
+		number = c - '0';
 		for (i = 0; i < 2; i++) {
-		    ch = c = next_char();
+		    c = next_char();
 		    if (c == EOF)
 			_nc_err_abort(MSG_NO_INPUTS);
 
-		    if (c < '0' || c > '7') {
+		    if (!isoctal(c)) {
 			if (isdigit(c)) {
-			    _nc_warning("Non-octal digit `%c' in \\ sequence", c);
-			    /* allow the digit; it'll do less harm */
+			    if (!strict_bsd) {
+				_nc_warning("Non-octal digit `%c' in \\ sequence", c);
+				/* allow the digit; it'll do less harm */
+			    }
 			} else {
-			    push_back((char) c);
+			    push_back(c);
 			    break;
 			}
 		    }
@@ -788,21 +848,16 @@
 		    number = number * 8 + c - '0';
 		}
 
-		if (number == 0)
+		number = UChar(number);
+		if (number == 0 && !strict_bsd)
 		    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;
@@ -815,10 +870,6 @@
 		    *(ptr++) = '\010';
 		    break;
 
-		case 's':
-		    *(ptr++) = ' ';
-		    break;
-
 		case 'f':
 		    *(ptr++) = '\014';
 		    break;
@@ -839,40 +890,57 @@
 		    *(ptr++) = ',';
 		    break;
 
-		case ':':
-		    *(ptr++) = ':';
-		    break;
-
 		case '\n':
 		    continue;
 
 		default:
-		    _nc_warning("Illegal character '%s' in \\ sequence",
-				unctrl(ch));
+		    if ((_nc_syntax == SYN_TERMINFO) || !_nc_strict_bsd) {
+			switch (c) {
+			case 'a':
+			    c = '\007';
+			    break;
+			case 'e':
+			    c = '\033';
+			    break;
+			case 'l':
+			    c = '\n';
+			    break;
+			case 's':
+			    c = ' ';
+			    break;
+			case ':':
+			    c = ':';
+			    break;
+			default:
+			    _nc_warning("Illegal character '%s' in \\ sequence",
+					unctrl(UChar(c)));
+			    break;
+			}
+		    }
 		    /* FALLTHRU */
 		case '|':
-		    *(ptr++) = (char) ch;
-		}		/* endswitch (ch) */
-	    }			/* endelse (ch < '0' ||  ch > '7') */
+		    *(ptr++) = (char) c;
+		}		/* endswitch (c) */
+	    }			/* endelse (c < '0' ||  c > '7') */
 	}
-	/* end else if (ch == '\\') */
-	else if (ch == '\n' && (_nc_syntax == SYN_TERMINFO)) {
+	/* end else if (c == '\\') */
+	else if (c == '\n' && (_nc_syntax == SYN_TERMINFO)) {
 	    /*
 	     * Newlines embedded in a terminfo string are ignored, provided
 	     * that the next line begins with whitespace.
 	     */
 	    ignored = TRUE;
 	} else {
-	    *(ptr++) = (char) ch;
+	    *(ptr++) = (char) c;
 	}
 
 	if (!ignored) {
 	    if (_nc_curr_col <= 1) {
-		push_back((char) ch);
-		ch = '\n';
+		push_back(c);
+		c = '\n';
 		break;
 	    }
-	    last_ch = ch;
+	    last_ch = c;
 	    count++;
 	}
 	ignored = FALSE;
@@ -885,7 +953,7 @@
 
     *ptr = '\0';
 
-    return (ch);
+    return (c);
 }
 
 /*
@@ -940,5 +1008,8 @@
     if (pushname != 0) {
 	FreeAndNull(pushname);
     }
+    if (tok_buf != 0) {
+	FreeAndNull(tok_buf);
+    }
 }
 #endif
diff --git a/ncurses/tinfo/db_iterator.c b/ncurses/tinfo/db_iterator.c
index fdc2bb0..94a4082 100644
--- a/ncurses/tinfo/db_iterator.c
+++ b/ncurses/tinfo/db_iterator.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2006,2007 Free Software Foundation, Inc.                   *
+ * Copyright (c) 2006-2013,2014 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            *
@@ -36,13 +36,142 @@
 
 #include <curses.priv.h>
 
+#include <time.h>
 #include <tic.h>
 
-MODULE_ID("$Id: db_iterator.c,v 1.6 2007/04/22 00:00:26 tom Exp $")
+#if USE_HASHED_DB
+#include <hashed_db.h>
+#endif
+
+MODULE_ID("$Id: db_iterator.c,v 1.39 2014/11/01 14:47:00 tom Exp $")
 
 #define HaveTicDirectory _nc_globals.have_tic_directory
 #define KeepTicDirectory _nc_globals.keep_tic_directory
 #define TicDirectory     _nc_globals.tic_directory
+#define my_blob          _nc_globals.dbd_blob
+#define my_list          _nc_globals.dbd_list
+#define my_size          _nc_globals.dbd_size
+#define my_time          _nc_globals.dbd_time
+#define my_vars          _nc_globals.dbd_vars
+
+static void
+add_to_blob(const char *text, size_t limit)
+{
+    (void) limit;
+
+    if (*text != '\0') {
+	char *last = my_blob + strlen(my_blob);
+	if (last != my_blob)
+	    *last++ = NCURSES_PATHSEP;
+	_nc_STRCPY(last, text, limit);
+    }
+}
+
+static bool
+check_existence(const char *name, struct stat *sb)
+{
+    bool result = FALSE;
+
+    if (stat(name, sb) == 0
+	&& (S_ISDIR(sb->st_mode) || S_ISREG(sb->st_mode))) {
+	result = TRUE;
+    }
+#if USE_HASHED_DB
+    else if (strlen(name) < PATH_MAX - sizeof(DBM_SUFFIX)) {
+	char temp[PATH_MAX];
+	_nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp)) "%s%s", name, DBM_SUFFIX);
+	if (stat(temp, sb) == 0 && S_ISREG(sb->st_mode)) {
+	    result = TRUE;
+	}
+    }
+#endif
+    return result;
+}
+
+/*
+ * Store the latest value of an environment variable in my_vars[] so we can
+ * detect if one changes, invalidating the cached search-list.
+ */
+static bool
+update_getenv(const char *name, DBDIRS which)
+{
+    bool result = FALSE;
+
+    if (which < dbdLAST) {
+	char *value;
+
+	if ((value = getenv(name)) == 0 || (value = strdup(value)) == 0) {
+	    ;
+	} else if (my_vars[which].name == 0 || strcmp(my_vars[which].name, name)) {
+	    FreeIfNeeded(my_vars[which].value);
+	    my_vars[which].name = name;
+	    my_vars[which].value = value;
+	    result = TRUE;
+	} else if ((my_vars[which].value != 0) ^ (value != 0)) {
+	    FreeIfNeeded(my_vars[which].value);
+	    my_vars[which].value = value;
+	    result = TRUE;
+	} else if (value != 0 && strcmp(value, my_vars[which].value)) {
+	    FreeIfNeeded(my_vars[which].value);
+	    my_vars[which].value = value;
+	    result = TRUE;
+	} else {
+	    free(value);
+	}
+    }
+    return result;
+}
+
+static char *
+cache_getenv(const char *name, DBDIRS which)
+{
+    char *result = 0;
+
+    (void) update_getenv(name, which);
+    if (which < dbdLAST) {
+	result = my_vars[which].value;
+    }
+    return result;
+}
+
+/*
+ * The cache expires if at least a second has passed since the initial lookup,
+ * or if one of the environment variables changed.
+ *
+ * Only a few applications use multiple lookups of terminal entries, seems that
+ * aside from bulk I/O such as tic and toe, that leaves interactive programs
+ * which should not be modifying the terminal databases in a way that would
+ * invalidate the search-list.
+ *
+ * The "1-second" is to allow for user-directed changes outside the program.
+ */
+static bool
+cache_expired(void)
+{
+    bool result = FALSE;
+    time_t now = time((time_t *) 0);
+
+    if (now > my_time) {
+	result = TRUE;
+    } else {
+	DBDIRS n;
+	for (n = (DBDIRS) 0; n < dbdLAST; ++n) {
+	    if (my_vars[n].name != 0
+		&& update_getenv(my_vars[n].name, n)) {
+		result = TRUE;
+		break;
+	    }
+	}
+    }
+    return result;
+}
+
+static void
+free_cache(void)
+{
+    FreeAndNull(my_blob);
+    FreeAndNull(my_list);
+}
 
 /*
  * Record the "official" location of the terminfo directory, according to
@@ -51,17 +180,20 @@
 NCURSES_EXPORT(const char *)
 _nc_tic_dir(const char *path)
 {
+    T(("_nc_tic_dir %s", NonNull(path)));
     if (!KeepTicDirectory) {
 	if (path != 0) {
 	    TicDirectory = path;
 	    HaveTicDirectory = TRUE;
-	} else if (!HaveTicDirectory && use_terminfo_vars()) {
-	    char *envp;
-	    if ((envp = getenv("TERMINFO")) != 0)
-		return _nc_tic_dir(envp);
+	} else if (HaveTicDirectory == 0) {
+	    if (use_terminfo_vars()) {
+		const char *envp;
+		if ((envp = getenv("TERMINFO")) != 0)
+		    return _nc_tic_dir(envp);
+	    }
 	}
     }
-    return TicDirectory;
+    return TicDirectory ? TicDirectory : TERMINFO;
 }
 
 /*
@@ -77,62 +209,16 @@
 }
 
 /*
- * Process the list of :-separated directories, looking for the terminal type.
- * We don't use strtok because it does not show us empty tokens.
- */
-#define ThisDbList	_nc_globals.dbi_list
-#define ThisDbSize	_nc_globals.dbi_size
-
-/*
  * Cleanup.
  */
 NCURSES_EXPORT(void)
 _nc_last_db(void)
 {
-    if (ThisDbList != 0) {
-	FreeAndNull(ThisDbList);
+    if (my_blob != 0 && cache_expired()) {
+	free_cache();
     }
-    ThisDbSize = 0;
 }
 
-/* The TERMINFO_DIRS value, if defined by the configure script, begins with a
- * ":", which will be interpreted as TERMINFO.
- */
-static const char *
-next_list_item(const char *source, int *offset)
-{
-    if (source != 0) {
-	FreeIfNeeded(ThisDbList);
-	ThisDbList = strdup(source);
-	ThisDbSize = strlen(source);
-    }
-
-    if (ThisDbList != 0 && ThisDbSize && *offset < ThisDbSize) {
-	static char system_db[] = TERMINFO;
-	char *result = ThisDbList + *offset;
-	char *marker = strchr(result, NCURSES_PATHSEP);
-
-	/*
-	 * Put a null on the marker if a separator was found.  Set the offset
-	 * to the next position after the marker so we can call this function
-	 * again, using the data at the offset.
-	 */
-	if (marker == 0) {
-	    *offset += strlen(result) + 1;
-	    marker = result + *offset;
-	} else {
-	    *marker++ = 0;
-	    *offset = marker - ThisDbList;
-	}
-	if (*result == 0 && result != (ThisDbList + ThisDbSize))
-	    result = system_db;
-	return result;
-    }
-    return 0;
-}
-
-#define NEXT_DBD(var, offset) next_list_item((*offset == 0) ? var : 0, offset)
-
 /*
  * This is a simple iterator which allows the caller to step through the
  * possible locations for a terminfo directory.  ncurses uses this to find
@@ -142,84 +228,186 @@
 _nc_next_db(DBDIRS * state, int *offset)
 {
     const char *result;
-    char *envp;
 
-    while (*state < dbdLAST) {
-	DBDIRS next = (DBDIRS) ((int) (*state) + 1);
-
+    (void) offset;
+    if ((int) *state < my_size
+	&& my_list != 0
+	&& my_list[*state] != 0) {
+	result = my_list[*state];
+	(*state)++;
+    } else {
 	result = 0;
-
-	switch (*state) {
-	case dbdTIC:
-	    if (HaveTicDirectory)
-		result = _nc_tic_dir(0);
-	    break;
-#if USE_DATABASE
-	case dbdEnvOnce:
-	    if (use_terminfo_vars()) {
-		if ((envp = getenv("TERMINFO")) != 0)
-		    result = _nc_tic_dir(envp);
-	    }
-	    break;
-	case dbdHome:
-	    if (use_terminfo_vars()) {
-		result = _nc_home_terminfo();
-	    }
-	    break;
-	case dbdEnvList:
-	    if (use_terminfo_vars()) {
-		if ((result = NEXT_DBD(getenv("TERMINFO_DIRS"), offset)) != 0)
-		    next = *state;
-	    }
-	    break;
-	case dbdCfgList:
-#ifdef TERMINFO_DIRS
-	    if ((result = NEXT_DBD(TERMINFO_DIRS, offset)) != 0)
-		next = *state;
-#endif
-	    break;
-	case dbdCfgOnce:
-#ifndef TERMINFO_DIRS
-	    result = TERMINFO;
-#endif
-	    break;
-#endif /* USE_DATABASE */
-#if USE_TERMCAP
-	case dbdEnvOnce2:
-	    if (use_terminfo_vars()) {
-		if ((envp = getenv("TERMCAP")) != 0)
-		    result = _nc_tic_dir(envp);
-	    }
-	    break;
-	case dbdEnvList2:
-	    if (use_terminfo_vars()) {
-		if ((result = NEXT_DBD(getenv("TERMPATH"), offset)) != 0)
-		    next = *state;
-	    }
-	    break;
-	case dbdCfgList2:
-	    if ((result = NEXT_DBD(TERMPATH, offset)) != 0)
-		next = *state;
-	    break;
-#endif /* USE_TERMCAP */
-	case dbdLAST:
-	    break;
-	}
-	if (*state != next) {
-	    *state = next;
-	    *offset = 0;
-	    _nc_last_db();
-	}
-	if (result != 0) {
-	    return result;
-	}
     }
-    return 0;
+    if (result != 0) {
+	T(("_nc_next_db %d %s", *state, result));
+    }
+    return result;
 }
 
 NCURSES_EXPORT(void)
 _nc_first_db(DBDIRS * state, int *offset)
 {
+    bool cache_has_expired = FALSE;
     *state = dbdTIC;
     *offset = 0;
+
+    T(("_nc_first_db"));
+
+    /* build a blob containing all of the strings we will use for a lookup
+     * table.
+     */
+    if (my_blob == 0 || (cache_has_expired = cache_expired())) {
+	size_t blobsize = 0;
+	const char *values[dbdLAST];
+	struct stat *my_stat;
+	int j, k;
+
+	if (cache_has_expired)
+	    free_cache();
+
+	for (j = 0; j < dbdLAST; ++j)
+	    values[j] = 0;
+
+	/*
+	 * This is the first item in the list, and is used only when tic is
+	 * writing to the database, as a performance improvement.
+	 */
+	values[dbdTIC] = TicDirectory;
+
+#if NCURSES_USE_DATABASE
+#ifdef TERMINFO_DIRS
+	values[dbdCfgList] = TERMINFO_DIRS;
+#endif
+#ifdef TERMINFO
+	values[dbdCfgOnce] = TERMINFO;
+#endif
+#endif
+
+#if NCURSES_USE_TERMCAP
+	values[dbdCfgList2] = TERMPATH;
+#endif
+
+	if (use_terminfo_vars()) {
+#if NCURSES_USE_DATABASE
+	    values[dbdEnvOnce] = cache_getenv("TERMINFO", dbdEnvOnce);
+	    values[dbdHome] = _nc_home_terminfo();
+	    (void) cache_getenv("HOME", dbdHome);
+	    values[dbdEnvList] = cache_getenv("TERMINFO_DIRS", dbdEnvList);
+
+#endif
+#if NCURSES_USE_TERMCAP
+	    values[dbdEnvOnce2] = cache_getenv("TERMCAP", dbdEnvOnce2);
+	    /* only use $TERMCAP if it is an absolute path */
+	    if (values[dbdEnvOnce2] != 0
+		&& *values[dbdEnvOnce2] != '/') {
+		values[dbdEnvOnce2] = 0;
+	    }
+	    values[dbdEnvList2] = cache_getenv("TERMPATH", dbdEnvList2);
+#endif /* NCURSES_USE_TERMCAP */
+	}
+
+	for (j = 0; j < dbdLAST; ++j) {
+	    if (values[j] == 0)
+		values[j] = "";
+	    blobsize += 2 + strlen(values[j]);
+	}
+
+	my_blob = malloc(blobsize);
+	if (my_blob != 0) {
+	    *my_blob = '\0';
+	    for (j = 0; j < dbdLAST; ++j) {
+		add_to_blob(values[j], blobsize);
+	    }
+
+	    /* Now, build an array which will be pointers to the distinct
+	     * strings in the blob.
+	     */
+	    blobsize = 2;
+	    for (j = 0; my_blob[j] != '\0'; ++j) {
+		if (my_blob[j] == NCURSES_PATHSEP)
+		    ++blobsize;
+	    }
+	    my_list = typeCalloc(char *, blobsize);
+	    my_stat = typeCalloc(struct stat, blobsize);
+	    if (my_list != 0 && my_stat != 0) {
+		k = 0;
+		my_list[k++] = my_blob;
+		for (j = 0; my_blob[j] != '\0'; ++j) {
+		    if (my_blob[j] == NCURSES_PATHSEP) {
+			my_blob[j] = '\0';
+			my_list[k++] = &my_blob[j + 1];
+		    }
+		}
+
+		/*
+		 * Eliminate duplicates from the list.
+		 */
+		for (j = 0; my_list[j] != 0; ++j) {
+#ifdef TERMINFO
+		    if (*my_list[j] == '\0')
+			my_list[j] = strdup(TERMINFO);
+#endif
+		    for (k = 0; k < j; ++k) {
+			if (!strcmp(my_list[j], my_list[k])) {
+			    k = j - 1;
+			    while ((my_list[j] = my_list[j + 1]) != 0) {
+				++j;
+			    }
+			    j = k;
+			    break;
+			}
+		    }
+		}
+
+		/*
+		 * Eliminate non-existent databases, and those that happen to
+		 * be symlinked to another location.
+		 */
+		for (j = 0; my_list[j] != 0; ++j) {
+		    bool found = check_existence(my_list[j], &my_stat[j]);
+#if HAVE_LINK
+		    if (found) {
+			for (k = 0; k < j; ++k) {
+			    if (my_stat[j].st_dev == my_stat[k].st_dev
+				&& my_stat[j].st_ino == my_stat[k].st_ino) {
+				found = FALSE;
+				break;
+			    }
+			}
+		    }
+#endif
+		    if (!found) {
+			k = j;
+			while ((my_list[k] = my_list[k + 1]) != 0) {
+			    ++k;
+			}
+			--j;
+		    }
+		}
+		my_size = j;
+		my_time = time((time_t *) 0);
+	    } else {
+		FreeAndNull(my_blob);
+	    }
+	    free(my_stat);
+	}
+    }
 }
+
+#if NO_LEAKS
+void
+_nc_db_iterator_leaks(void)
+{
+    DBDIRS which;
+
+    if (my_blob != 0)
+	FreeAndNull(my_blob);
+    if (my_list != 0)
+	FreeAndNull(my_list);
+    for (which = 0; (int) which < dbdLAST; ++which) {
+	my_vars[which].name = 0;
+	FreeIfNeeded(my_vars[which].value);
+	my_vars[which].value = 0;
+    }
+}
+#endif
diff --git a/ncurses/tinfo/doalloc.c b/ncurses/tinfo/doalloc.c
index fe2a009..7c502b0 100644
--- a/ncurses/tinfo/doalloc.c
+++ b/ncurses/tinfo/doalloc.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc.                   *
+ * Copyright (c) 1998-2000,2012 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            *
@@ -39,7 +39,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: doalloc.c,v 1.8 2002/08/31 21:48:11 Philippe.Blain Exp $")
+MODULE_ID("$Id: doalloc.c,v 1.11 2012/11/03 19:27:41 tom Exp $")
 
 NCURSES_EXPORT(void *)
 _nc_doalloc(void *oldp, size_t amount)
@@ -56,20 +56,3 @@
     }
     return newp;
 }
-
-#if !HAVE_STRDUP
-NCURSES_EXPORT(char *)
-_nc_strdup(const char *src)
-{
-    char *dst;
-    if (src != 0) {
-	dst = typeMalloc(char, strlen(src) + 1);
-	if (dst != 0) {
-	    (void) strcpy(dst, src);
-	}
-    } else {
-	dst = 0;
-    }
-    return dst;
-}
-#endif
diff --git a/ncurses/tinfo/entries.c b/ncurses/tinfo/entries.c
index cf2a833..e84033d 100644
--- a/ncurses/tinfo/entries.c
+++ b/ncurses/tinfo/entries.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2006-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 2006-2011,2012 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            *
@@ -28,6 +28,7 @@
 
 /****************************************************************************
  *  Author: Thomas E. Dickey                                                *
+ *     and: Juergen Pfeifer                                                 *
  ****************************************************************************/
 
 #include <curses.priv.h>
@@ -35,9 +36,8 @@
 #include <ctype.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: entries.c,v 1.8 2008/09/27 13:11:10 tom Exp $")
+MODULE_ID("$Id: entries.c,v 1.21 2012/05/05 20:33:44 tom Exp $")
 
 /****************************************************************************
  *
@@ -96,6 +96,9 @@
 	    if (last != 0) {
 		last->next = ep->next;
 	    }
+	    if (ep->next != 0) {
+		ep->next->last = last;
+	    }
 	    if (ep == _nc_head) {
 		_nc_head = ep->next;
 	    }
@@ -119,18 +122,32 @@
 #if NO_LEAKS
     _nc_free_tparm();
     _nc_tgetent_leaks();
+
+    if (TerminalOf(CURRENT_SCREEN) != 0) {
+	del_curterm(TerminalOf(CURRENT_SCREEN));
+    }
+
+    _nc_comp_captab_leaks();
     _nc_free_entries(_nc_head);
     _nc_get_type(0);
     _nc_first_name(0);
+    _nc_db_iterator_leaks();
     _nc_keyname_leaks();
 #if BROKEN_LINKER || USE_REENTRANT
     _nc_names_leaks();
     _nc_codes_leaks();
     FreeIfNeeded(_nc_prescreen.real_acs_map);
 #endif
+    _nc_comp_error_leaks();
 
     if ((s = _nc_home_terminfo()) != 0)
 	free(s);
+
+#ifdef TRACE
+    trace(0);
+    _nc_trace_buf(-1, (size_t) 0);
+#endif
+
 #endif /* NO_LEAKS */
     returnVoid;
 }
diff --git a/ncurses/tinfo/free_ttype.c b/ncurses/tinfo/free_ttype.c
index fa0fff1..ad056ba 100644
--- a/ncurses/tinfo/free_ttype.c
+++ b/ncurses/tinfo/free_ttype.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1999-2005,2006 Free Software Foundation, Inc.              *
+ * Copyright (c) 1999-2010,2011 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            *
@@ -41,9 +41,8 @@
 #include <curses.priv.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: free_ttype.c,v 1.13 2006/06/25 10:46:02 tom Exp $")
+MODULE_ID("$Id: free_ttype.c,v 1.15 2011/02/06 01:08:31 tom Exp $")
 
 NCURSES_EXPORT(void)
 _nc_free_termtype(TERMTYPE *ptr)
@@ -70,6 +69,7 @@
 {
     int oldflag = _nc_user_definable;
 
+    START_TRACE();
     T((T_CALLED("use_extended_names(%d)"), flag));
     _nc_user_definable = flag;
     returnBool(oldflag);
diff --git a/ncurses/tinfo/getenv_num.c b/ncurses/tinfo/getenv_num.c
index a90cc08..d5e35cb 100644
--- a/ncurses/tinfo/getenv_num.c
+++ b/ncurses/tinfo/getenv_num.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc.                   *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -36,7 +36,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: getenv_num.c,v 1.3 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: getenv_num.c,v 1.6 2013/09/28 20:25:08 tom Exp $")
 
 NCURSES_EXPORT(int)
 _nc_getenv_num(const char *name)
@@ -54,3 +54,20 @@
 
     return (int) value;
 }
+
+NCURSES_EXPORT(void)
+_nc_setenv_num(const char *name, int value)
+{
+    if (name != 0 && value >= 0) {
+	char buffer[128];
+#if HAVE_SETENV
+	_nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) "%d", value);
+	setenv(name, buffer, 1);
+#elif HAVE_PUTENV
+	char *s;
+	_nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) "%s=%d", name, value);
+	if ((s = strdup(buffer)) != 0)
+	    putenv(s);
+#endif
+    }
+}
diff --git a/ncurses/tinfo/hashed_db.c b/ncurses/tinfo/hashed_db.c
index 3fc04ea..b594205 100644
--- a/ncurses/tinfo/hashed_db.c
+++ b/ncurses/tinfo/hashed_db.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2006 Free Software Foundation, Inc.                        *
+ * Copyright (c) 2006-2011,2013 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            *
@@ -27,7 +27,7 @@
  ****************************************************************************/
 
 /****************************************************************************
- *  Author: Thomas E. Dickey                        2006                    *
+ *  Author: Thomas E. Dickey                        2006-on                 *
  ****************************************************************************/
 
 #include <curses.priv.h>
@@ -36,12 +36,81 @@
 
 #if USE_HASHED_DB
 
-MODULE_ID("$Id: hashed_db.c,v 1.13 2006/08/19 19:48:38 tom Exp $")
+MODULE_ID("$Id: hashed_db.c,v 1.17 2013/12/15 00:33:01 tom Exp $")
 
 #if HASHED_DB_API >= 2
 static DBC *cursor;
 #endif
 
+typedef struct _myconn {
+    struct _myconn *next;
+    DB *db;
+    char *path;
+    bool modify;
+} MYCONN;
+
+static MYCONN *connections;
+
+static void
+cleanup(void)
+{
+    while (connections != 0) {
+	_nc_db_close(connections->db);
+    }
+}
+
+static DB *
+find_connection(const char *path, bool modify)
+{
+    DB *result = 0;
+    MYCONN *p;
+
+    for (p = connections; p != 0; p = p->next) {
+	if (!strcmp(p->path, path) && p->modify == modify) {
+	    result = p->db;
+	    break;
+	}
+    }
+
+    return result;
+}
+
+static void
+drop_connection(DB * db)
+{
+    MYCONN *p, *q;
+
+    for (p = connections, q = 0; p != 0; q = p, p = p->next) {
+	if (p->db == db) {
+	    if (q != 0)
+		q->next = p->next;
+	    else
+		connections = p->next;
+	    free(p->path);
+	    free(p);
+	    break;
+	}
+    }
+}
+
+static void
+make_connection(DB * db, const char *path, bool modify)
+{
+    MYCONN *p = typeCalloc(MYCONN, 1);
+
+    if (p != 0) {
+	p->db = db;
+	p->path = strdup(path);
+	p->modify = modify;
+	if (p->path != 0) {
+	    p->next = connections;
+	    connections = p;
+	} else {
+	    free(p);
+	}
+    }
+}
+
 /*
  * Open the database.
  */
@@ -49,49 +118,60 @@
 _nc_db_open(const char *path, bool modify)
 {
     DB *result = 0;
-
-#if HASHED_DB_API >= 4
-    db_create(&result, NULL, 0);
-    result->open(result,
-		 NULL,
-		 path,
-		 NULL,
-		 DB_HASH,
-		 modify ? DB_CREATE : DB_RDONLY,
-		 0644);
-#elif HASHED_DB_API >= 3
-    db_create(&result, NULL, 0);
-    result->open(result,
-		 path,
-		 NULL,
-		 DB_HASH,
-		 modify ? DB_CREATE : DB_RDONLY,
-		 0644);
-#elif HASHED_DB_API >= 2
     int code;
 
-    if ((code = db_open(path,
-			DB_HASH,
-			modify ? DB_CREATE : DB_RDONLY,
-			0644,
-			(DB_ENV *) 0,
-			(DB_INFO *) 0,
-			&result)) != 0) {
-	T(("cannot open %s: %s", path, strerror(code)));
-	result = 0;
-    } else {
-	T(("opened %s", path));
-    }
+    if (connections == 0)
+	atexit(cleanup);
+
+    if ((result = find_connection(path, modify)) == 0) {
+
+#if HASHED_DB_API >= 4
+	db_create(&result, NULL, 0);
+	if ((code = result->open(result,
+				 NULL,
+				 path,
+				 NULL,
+				 DB_HASH,
+				 modify ? DB_CREATE : DB_RDONLY,
+				 0644)) != 0) {
+	    result = 0;
+	}
+#elif HASHED_DB_API >= 3
+	db_create(&result, NULL, 0);
+	if ((code = result->open(result,
+				 path,
+				 NULL,
+				 DB_HASH,
+				 modify ? DB_CREATE : DB_RDONLY,
+				 0644)) != 0) {
+	    result = 0;
+	}
+#elif HASHED_DB_API >= 2
+	if ((code = db_open(path,
+			    DB_HASH,
+			    modify ? DB_CREATE : DB_RDONLY,
+			    0644,
+			    (DB_ENV *) 0,
+			    (DB_INFO *) 0,
+			    &result)) != 0) {
+	    result = 0;
+	}
 #else
-    result = dbopen(path,
-		    modify ? (O_CREAT | O_RDWR) : O_RDONLY,
-		    0644,
-		    DB_HASH,
-		    NULL);
-    if (result != 0) {
-	T(("opened %s", path));
-    }
+	if ((result = dbopen(path,
+			     modify ? (O_CREAT | O_RDWR) : O_RDONLY,
+			     0644,
+			     DB_HASH,
+			     NULL)) == 0) {
+	    code = errno;
+	}
 #endif
+	if (result != 0) {
+	    make_connection(result, path, modify);
+	    T(("opened %s", path));
+	} else {
+	    T(("cannot open %s: %s", path, strerror(code)));
+	}
+    }
     return result;
 }
 
@@ -103,6 +183,7 @@
 {
     int result;
 
+    drop_connection(db);
 #if HASHED_DB_API >= 2
     result = db->close(db, 0);
 #else
@@ -205,7 +286,7 @@
 _nc_db_have_index(DBT * key, DBT * data, char **buffer, int *size)
 {
     bool result = FALSE;
-    int used = data->size - 1;
+    int used = (int) data->size - 1;
     char *have = (char *) data->data;
 
     (void) key;
@@ -228,7 +309,7 @@
 _nc_db_have_data(DBT * key, DBT * data, char **buffer, int *size)
 {
     bool result = FALSE;
-    int used = data->size - 1;
+    int used = (int) data->size - 1;
     char *have = (char *) data->data;
 
     if (*have++ == 0) {
diff --git a/ncurses/tinfo/home_terminfo.c b/ncurses/tinfo/home_terminfo.c
index 4521c4a..e77f71c 100644
--- a/ncurses/tinfo/home_terminfo.c
+++ b/ncurses/tinfo/home_terminfo.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2010,2012 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            *
@@ -37,7 +37,7 @@
 #include <curses.priv.h>
 #include <tic.h>
 
-MODULE_ID("$Id: home_terminfo.c,v 1.11 2008/08/03 23:43:11 tom Exp $")
+MODULE_ID("$Id: home_terminfo.c,v 1.15 2012/10/27 21:49:14 tom Exp $")
 
 /* ncurses extension...fall back on user's private directory */
 
@@ -53,11 +53,9 @@
     if (use_terminfo_vars()) {
 	if (MyBuffer == 0) {
 	    if ((home = getenv("HOME")) != 0) {
-		unsigned want = (strlen(home) + sizeof(PRIVATE_INFO));
-		MyBuffer = typeMalloc(char, want);
-		if (MyBuffer == 0)
-		    _nc_err_abort(MSG_NO_MEMORY);
-		(void) sprintf(MyBuffer, PRIVATE_INFO, home);
+		size_t want = (strlen(home) + sizeof(PRIVATE_INFO));
+		TYPE_MALLOC(char, want, MyBuffer);
+		_nc_SPRINTF(MyBuffer, _nc_SLIMIT(want) PRIVATE_INFO, home);
 	    }
 	}
 	result = MyBuffer;
diff --git a/ncurses/tinfo/init_keytry.c b/ncurses/tinfo/init_keytry.c
index 2f6fe4f..ea47b38 100644
--- a/ncurses/tinfo/init_keytry.c
+++ b/ncurses/tinfo/init_keytry.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1999-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1999-2009,2010 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            *
@@ -27,16 +27,9 @@
  ****************************************************************************/
 
 #include <curses.priv.h>
-
-#include <term.h>
-/* keypad_xmit, keypad_local, meta_on, meta_off */
-/* cursor_visible,cursor_normal,cursor_invisible */
-
 #include <tic.h>		/* struct tinfo_fkeys */
 
-#include <term_entry.h>
-
-MODULE_ID("$Id: init_keytry.c,v 1.12 2008/05/24 21:44:51 tom Exp $")
+MODULE_ID("$Id: init_keytry.c,v 1.17 2010/04/24 22:29:56 tom Exp $")
 
 /*
 **      _nc_init_keytry()
@@ -50,7 +43,7 @@
  * than cur_term.
  */
 #undef CUR
-#define CUR (sp->_term)->type.
+#define CUR SP_TERMTYPE
 
 #if	BROKEN_LINKER
 #undef	_nc_tinfo_fkeys
@@ -73,7 +66,7 @@
 NCURSES_EXPORT(void)
 _nc_init_keytry(SCREEN *sp)
 {
-    size_t n;
+    unsigned n;
 
     /* The sp->_keytry value is initialized in newterm(), where the sp
      * structure is created, because we can not tell where keypad() or
@@ -97,12 +90,13 @@
 	{
 	    TERMTYPE *tp = &(sp->_term->type);
 	    for (n = STRCOUNT; n < NUM_STRINGS(tp); ++n) {
-		const char *name = ExtStrname(tp, n, strnames);
+		const char *name = ExtStrname(tp, (int) n, strnames);
 		char *value = tp->Strings[n];
 		if (name != 0
 		    && *name == 'k'
 		    && value != 0
-		    && key_defined(value) == 0) {
+		    && NCURSES_SP_NAME(key_defined) (NCURSES_SP_ARGx
+						     value) == 0) {
 		    (void) _nc_add_to_try(&(sp->_keytry),
 					  value,
 					  n - STRCOUNT + KEY_MAX);
diff --git a/ncurses/tinfo/lib_acs.c b/ncurses/tinfo/lib_acs.c
index 919e472..69a1851 100644
--- a/ncurses/tinfo/lib_acs.c
+++ b/ncurses/tinfo/lib_acs.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2013,2014 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            *
@@ -30,17 +30,21 @@
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2008                    *
  ****************************************************************************/
 
 #include <curses.priv.h>
-#include <term.h>		/* ena_acs, acs_chars */
 
-MODULE_ID("$Id: lib_acs.c,v 1.36 2008/08/16 19:22:55 tom Exp $")
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
+
+MODULE_ID("$Id: lib_acs.c,v 1.45 2014/03/08 20:32:59 tom Exp $")
 
 #if BROKEN_LINKER || USE_REENTRANT
 #define MyBuffer _nc_prescreen.real_acs_map
-NCURSES_EXPORT_VAR(chtype *)
-_nc_acs_map(void)
+NCURSES_EXPORT(chtype *)
+NCURSES_PUBLIC_VAR(acs_map) (void)
 {
     if (MyBuffer == 0)
 	MyBuffer = typeCalloc(chtype, ACS_LEN);
@@ -48,17 +52,35 @@
 }
 #undef MyBuffer
 #else
-NCURSES_EXPORT_VAR(chtype) acs_map[ACS_LEN] =
+NCURSES_EXPORT_VAR (chtype) acs_map[ACS_LEN] =
 {
     0
 };
 #endif
 
+#ifdef USE_TERM_DRIVER
+NCURSES_EXPORT(chtype)
+NCURSES_SP_NAME(_nc_acs_char) (NCURSES_SP_DCLx int c)
+{
+    chtype *map;
+    if (c < 0 || c >= ACS_LEN)
+	return (chtype) 0;
+    map = (SP_PARM != 0) ? SP_PARM->_acs_map :
+#if BROKEN_LINKER || USE_REENTRANT
+	_nc_prescreen.real_acs_map
+#else
+	acs_map
+#endif
+	;
+    return map[c];
+}
+#endif /* USE_TERM_DRIVER */
+
 NCURSES_EXPORT(void)
-_nc_init_acs(void)
+NCURSES_SP_NAME(_nc_init_acs) (NCURSES_SP_DCL0)
 {
     chtype *fake_map = acs_map;
-    chtype *real_map = SP != 0 ? SP->_acs_map : fake_map;
+    chtype *real_map = SP_PARM != 0 ? SP_PARM->_acs_map : fake_map;
     int j;
 
     T(("initializing ACS map"));
@@ -71,9 +93,9 @@
     if (real_map != fake_map) {
 	for (j = 1; j < ACS_LEN; ++j) {
 	    real_map[j] = 0;
-	    fake_map[j] = A_ALTCHARSET | j;
-	    if (SP)
-		SP->_screen_acs_map[j] = FALSE;
+	    fake_map[j] = A_ALTCHARSET | (chtype) j;
+	    if (SP_PARM)
+		SP_PARM->_screen_acs_map[j] = FALSE;
 	}
     } else {
 	for (j = 1; j < ACS_LEN; ++j) {
@@ -118,10 +140,36 @@
     real_map['{'] = '*';	/* should be greek pi */
     real_map['|'] = '!';	/* should be not-equal */
     real_map['}'] = 'f';	/* should be pound-sterling symbol */
+    /* thick-line-drawing */
+    real_map['L'] = '+';	/* upper left corner */
+    real_map['M'] = '+';	/* lower left corner */
+    real_map['K'] = '+';	/* upper right corner */
+    real_map['J'] = '+';	/* lower right corner */
+    real_map['T'] = '+';	/* tee pointing left */
+    real_map['U'] = '+';	/* tee pointing right */
+    real_map['V'] = '+';	/* tee pointing up */
+    real_map['W'] = '+';	/* tee pointing down */
+    real_map['Q'] = '-';	/* horizontal line */
+    real_map['X'] = '|';	/* vertical line */
+    real_map['N'] = '+';	/* large plus or crossover */
+    /* double-line-drawing */
+    real_map['C'] = '+';	/* upper left corner */
+    real_map['D'] = '+';	/* lower left corner */
+    real_map['B'] = '+';	/* upper right corner */
+    real_map['A'] = '+';	/* lower right corner */
+    real_map['G'] = '+';	/* tee pointing left */
+    real_map['F'] = '+';	/* tee pointing right */
+    real_map['H'] = '+';	/* tee pointing up */
+    real_map['I'] = '+';	/* tee pointing down */
+    real_map['R'] = '-';	/* horizontal line */
+    real_map['Y'] = '|';	/* vertical line */
+    real_map['E'] = '+';	/* large plus or crossover */
 
+#ifdef USE_TERM_DRIVER
+    CallDriver_2(SP_PARM, td_initacs, real_map, fake_map);
+#else
     if (ena_acs != NULL) {
-	TPUTS_TRACE("ena_acs");
-	putp(ena_acs);
+	NCURSES_PUTP2("ena_acs", ena_acs);
     }
 #if NCURSES_EXT_FUNCS
     /*
@@ -140,7 +188,7 @@
 	size_t i;
 	for (i = 1; i < ACS_LEN; ++i) {
 	    if (real_map[i] == 0) {
-		real_map[i] = i;
+		real_map[i] = (chtype) i;
 		if (real_map != fake_map) {
 		    if (SP != 0)
 			SP->_screen_acs_map[i] = TRUE;
@@ -191,4 +239,13 @@
 	_nc_unlock_global(tracef);
     }
 #endif /* TRACE */
+#endif
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(void)
+_nc_init_acs(void)
+{
+    NCURSES_SP_NAME(_nc_init_acs) (CURRENT_SCREEN);
+}
+#endif
diff --git a/ncurses/tinfo/lib_baudrate.c b/ncurses/tinfo/lib_baudrate.c
index b9cdfda..1cf5505 100644
--- a/ncurses/tinfo/lib_baudrate.c
+++ b/ncurses/tinfo/lib_baudrate.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2014,2015 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            *
@@ -38,7 +38,6 @@
  */
 
 #include <curses.priv.h>
-#include <term.h>		/* cur_term, pad_char */
 #include <termcap.h>		/* ospeed */
 #if defined(__FreeBSD__)
 #include <sys/param.h>
@@ -50,7 +49,7 @@
  * of the indices up to B115200 fit nicely in a 'short', allowing us to retain
  * ospeed's type for compatibility.
  */
-#if (defined(__FreeBSD__) && (__FreeBSD_version < 700000)) || defined(__NetBSD__) || defined(__OpenBSD__)
+#if NCURSES_OSPEED_COMPAT && ((defined(__FreeBSD__) && (__FreeBSD_version < 700000)) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__))
 #undef B0
 #undef B50
 #undef B75
@@ -80,7 +79,7 @@
 #undef USE_OLD_TTY
 #endif /* USE_OLD_TTY */
 
-MODULE_ID("$Id: lib_baudrate.c,v 1.27 2008/06/28 15:19:24 tom Exp $")
+MODULE_ID("$Id: lib_baudrate.c,v 1.37 2015/06/14 00:34:12 tom Exp $")
 
 /*
  *	int
@@ -91,54 +90,55 @@
  */
 
 struct speed {
-    int s;			/* value for 'ospeed' is an index */
+    NCURSES_OSPEED s;		/* values for 'ospeed' */
     int sp;			/* the actual speed */
 };
 
+#define DATA(number) { B##number, number }
+
 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},
+    DATA(0),
+    DATA(50),
+    DATA(75),
+    DATA(110),
+    DATA(134),
+    DATA(150),
+    DATA(200),
+    DATA(300),
+    DATA(600),
+    DATA(1200),
+    DATA(1800),
+    DATA(2400),
+    DATA(4800),
+    DATA(9600),
 #ifdef B19200
-    {B19200, 19200},
-#else
-#ifdef EXTA
+    DATA(19200),
+#elif defined(EXTA)
     {EXTA, 19200},
 #endif
-#endif
 #ifdef B38400
-    {B38400, 38400},
-#else
-#ifdef EXTB
+    DATA(38400),
+#elif defined(EXTB)
     {EXTB, 38400},
 #endif
-#endif
 #ifdef B57600
-    {B57600, 57600},
+    DATA(57600),
 #endif
+    /* ifdef to prevent overflow when OLD_TTY is not available */
+#if !(NCURSES_OSPEED_COMPAT && defined(__FreeBSD__) && (__FreeBSD_version > 700000))
 #ifdef B115200
-    {B115200, 115200},
+    DATA(115200),
 #endif
 #ifdef B230400
-    {B230400, 230400},
+    DATA(230400),
 #endif
 #ifdef B460800
-    {B460800, 460800},
+    DATA(460800),
 #endif
 #ifdef B921600
-    {B921600, 921600},
+    DATA(921600),
+#endif
 #endif
 };
 
@@ -161,14 +161,14 @@
     if (result == ERR) {
 	if (OSpeed >= 0) {
 	    for (i = 0; i < SIZEOF(speeds); i++) {
-		if (speeds[i].s == OSpeed) {
+		if ((int) speeds[i].s == OSpeed) {
 		    result = speeds[i].sp;
 		    break;
 		}
 	    }
 	}
 #if !USE_REENTRANT
-	if (OSpeed == last_OSpeed) {
+	if (OSpeed != last_OSpeed) {
 	    last_OSpeed = OSpeed;
 	    last_baudrate = result;
 	}
@@ -195,11 +195,11 @@
 }
 
 NCURSES_EXPORT(int)
-baudrate(void)
+NCURSES_SP_NAME(baudrate) (NCURSES_SP_DCL0)
 {
     int result;
 
-    T((T_CALLED("baudrate()")));
+    T((T_CALLED("baudrate(%p)"), (void *) SP_PARM));
 
     /*
      * In debugging, allow the environment symbol to override when we're
@@ -207,32 +207,41 @@
      * that take into account costs that depend on baudrate.
      */
 #ifdef TRACE
-    if (!isatty(fileno(SP ? SP->_ofp : stdout))
+    if (IsValidTIScreen(SP_PARM)
+	&& !NC_ISATTY(fileno(SP_PARM ? SP_PARM->_ofp : stdout))
 	&& getenv("BAUDRATE") != 0) {
 	int ret;
 	if ((ret = _nc_getenv_num("BAUDRATE")) <= 0)
 	    ret = 9600;
-	ospeed = _nc_ospeed(ret);
+	ospeed = (NCURSES_OSPEED) _nc_ospeed(ret);
 	returnCode(ret);
     }
 #endif
 
-    if (cur_term != 0) {
+    if (IsValidTIScreen(SP_PARM)) {
 #ifdef USE_OLD_TTY
-	result = cfgetospeed(&cur_term->Nttyb);
-	ospeed = _nc_ospeed(result);
+	result = (int) cfgetospeed(&(TerminalOf(SP_PARM)->Nttyb));
+	ospeed = (NCURSES_OSPEED) _nc_ospeed(result);
 #else /* !USE_OLD_TTY */
 #ifdef TERMIOS
-	ospeed = cfgetospeed(&cur_term->Nttyb);
+	ospeed = (NCURSES_OSPEED) cfgetospeed(&(TerminalOf(SP_PARM)->Nttyb));
 #else
-	ospeed = cur_term->Nttyb.sg_ospeed;
+	ospeed = (NCURSES_OSPEED) TerminalOf(SP_PARM)->Nttyb.sg_ospeed;
 #endif
 	result = _nc_baudrate(ospeed);
 #endif
-	cur_term->_baudrate = result;
+	TerminalOf(SP_PARM)->_baudrate = result;
     } else {
 	result = ERR;
     }
 
     returnCode(result);
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+baudrate(void)
+{
+    return NCURSES_SP_NAME(baudrate) (CURRENT_SCREEN);
+}
+#endif
diff --git a/ncurses/tinfo/lib_cur_term.c b/ncurses/tinfo/lib_cur_term.c
index 626578d..9941d13 100644
--- a/ncurses/tinfo/lib_cur_term.c
+++ b/ncurses/tinfo/lib_cur_term.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2003,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2013,2014 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            *
@@ -37,69 +37,139 @@
  */
 
 #include <curses.priv.h>
-#include <term_entry.h>		/* TTY, cur_term */
 #include <termcap.h>		/* ospeed */
 
-MODULE_ID("$Id: lib_cur_term.c,v 1.18 2008/08/16 19:22:55 tom Exp $")
+MODULE_ID("$Id: lib_cur_term.c,v 1.33 2014/03/08 20:32:59 tom Exp $")
 
 #undef CUR
 #define CUR termp->type.
 
-#if BROKEN_LINKER || USE_REENTRANT
+#if USE_REENTRANT
+
+NCURSES_EXPORT(TERMINAL *)
+NCURSES_SP_NAME(_nc_get_cur_term) (NCURSES_SP_DCL0)
+{
+    return ((0 != TerminalOf(SP_PARM)) ? TerminalOf(SP_PARM) : CurTerm);
+}
+
+#if NCURSES_SP_FUNCS
+
+NCURSES_EXPORT(TERMINAL *)
+_nc_get_cur_term(void)
+{
+    return NCURSES_SP_NAME(_nc_get_cur_term) (CURRENT_SCREEN);
+}
+#endif
+
 NCURSES_EXPORT(TERMINAL *)
 NCURSES_PUBLIC_VAR(cur_term) (void)
 {
-    return (SP != 0 && SP->_term != 0) ? SP->_term : _nc_prescreen._cur_term;
+#if NCURSES_SP_FUNCS
+    return NCURSES_SP_NAME(_nc_get_cur_term) (CURRENT_SCREEN);
+#else
+    return NCURSES_SP_NAME(_nc_get_cur_term) (NCURSES_SP_ARG);
+#endif
 }
+
 #else
 NCURSES_EXPORT_VAR(TERMINAL *) cur_term = 0;
 #endif
 
 NCURSES_EXPORT(TERMINAL *)
-set_curterm(TERMINAL * termp)
+NCURSES_SP_NAME(set_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
 {
     TERMINAL *oldterm;
 
-    T((T_CALLED("set_curterm(%p)"), termp));
+    T((T_CALLED("set_curterm(%p)"), (void *) termp));
 
     _nc_lock_global(curses);
     oldterm = cur_term;
-    if (SP)
-	SP->_term = termp;
-#if BROKEN_LINKER || USE_REENTRANT
-    _nc_prescreen._cur_term = termp;
+    if (SP_PARM)
+	SP_PARM->_term = termp;
+#if USE_REENTRANT
+    CurTerm = termp;
 #else
     cur_term = termp;
 #endif
     if (termp != 0) {
-	ospeed = _nc_ospeed(termp->_baudrate);
+#ifdef USE_TERM_DRIVER
+	TERMINAL_CONTROL_BLOCK *TCB = (TERMINAL_CONTROL_BLOCK *) termp;
+	ospeed = (NCURSES_OSPEED) _nc_ospeed(termp->_baudrate);
+	if (TCB->drv->isTerminfo && termp->type.Strings) {
+	    PC = (char) ((pad_char != NULL) ? pad_char[0] : 0);
+	}
+	TCB->csp = SP_PARM;
+#else
+	ospeed = (NCURSES_OSPEED) _nc_ospeed(termp->_baudrate);
 	if (termp->type.Strings) {
 	    PC = (char) ((pad_char != NULL) ? pad_char[0] : 0);
 	}
+#endif
     }
     _nc_unlock_global(curses);
 
-    T((T_RETURN("%p"), oldterm));
+    T((T_RETURN("%p"), (void *) oldterm));
     return (oldterm);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(TERMINAL *)
+set_curterm(TERMINAL * termp)
+{
+    return NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN, termp);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(del_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
+{
+    int rc = ERR;
+
+    T((T_CALLED("del_curterm(%p, %p)"), (void *) SP_PARM, (void *) termp));
+
+    if (termp != 0) {
+#ifdef USE_TERM_DRIVER
+	TERMINAL_CONTROL_BLOCK *TCB = (TERMINAL_CONTROL_BLOCK *) termp;
+#endif
+	TERMINAL *cur = (
+#if USE_REENTRANT
+			    NCURSES_SP_NAME(_nc_get_cur_term) (NCURSES_SP_ARG)
+#else
+			    cur_term
+#endif
+	);
+
+	_nc_free_termtype(&(termp->type));
+	if (termp == cur)
+	    NCURSES_SP_NAME(set_curterm) (NCURSES_SP_ARGx 0);
+
+	FreeIfNeeded(termp->_termname);
+#if USE_HOME_TERMINFO
+	if (_nc_globals.home_terminfo != 0) {
+	    FreeAndNull(_nc_globals.home_terminfo);
+	}
+#endif
+#ifdef USE_TERM_DRIVER
+	if (TCB->drv)
+	    TCB->drv->td_release(TCB);
+#endif
+	free(termp);
+
+	rc = OK;
+    }
+    returnCode(rc);
+}
+
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 del_curterm(TERMINAL * termp)
 {
     int rc = ERR;
 
-    T((T_CALLED("del_curterm(%p)"), termp));
-
     _nc_lock_global(curses);
-    if (termp != 0) {
-	_nc_free_termtype(&(termp->type));
-	FreeIfNeeded(termp->_termname);
-	free(termp);
-	if (termp == cur_term)
-	    set_curterm(0);
-	rc = OK;
-    }
+    rc = NCURSES_SP_NAME(del_curterm) (CURRENT_SCREEN, termp);
     _nc_unlock_global(curses);
 
-    returnCode(rc);
+    return (rc);
 }
+#endif
diff --git a/ncurses/tinfo/lib_data.c b/ncurses/tinfo/lib_data.c
index e84209d..06b6f88 100644
--- a/ncurses/tinfo/lib_data.c
+++ b/ncurses/tinfo/lib_data.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -30,6 +30,7 @@
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                                                 *
  ****************************************************************************/
 
 /*
@@ -41,7 +42,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_data.c,v 1.52 2008/08/23 22:16:15 tom Exp $")
+MODULE_ID("$Id: lib_data.c,v 1.66 2013/08/24 17:28:24 tom Exp $")
 
 /*
  * OS/2's native linker complains if we don't initialize public data when
@@ -51,17 +52,17 @@
 NCURSES_EXPORT(WINDOW *)
 NCURSES_PUBLIC_VAR(stdscr) (void)
 {
-    return SP ? SP->_stdscr : 0;
+    return CURRENT_SCREEN ? StdScreen(CURRENT_SCREEN) : 0;
 }
 NCURSES_EXPORT(WINDOW *)
 NCURSES_PUBLIC_VAR(curscr) (void)
 {
-    return SP ? SP->_curscr : 0;
+    return CURRENT_SCREEN ? CurScreen(CURRENT_SCREEN) : 0;
 }
 NCURSES_EXPORT(WINDOW *)
 NCURSES_PUBLIC_VAR(newscr) (void)
 {
-    return SP ? SP->_newscr : 0;
+    return CURRENT_SCREEN ? NewScreen(CURRENT_SCREEN) : 0;
 }
 #else
 NCURSES_EXPORT_VAR(WINDOW *) stdscr = 0;
@@ -93,7 +94,7 @@
 NCURSES_EXPORT(int)
 _nc_alloc_screen(void)
 {
-    return ((my_screen = typeCalloc(SCREEN, 1)) != 0);
+    return ((my_screen = _nc_alloc_screen_sp()) != 0);
 }
 
 NCURSES_EXPORT(void)
@@ -103,6 +104,7 @@
 }
 
 #else
+
 NCURSES_EXPORT_VAR(SCREEN *) SP = NULL; /* Some linkers require initialized data... */
 #endif
 /* *INDENT-OFF* */
@@ -112,6 +114,7 @@
 #define TGETENT_0s { TGETENT_0, TGETENT_0, TGETENT_0, TGETENT_0 }
 
 NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
+    0,				/* have_sigtstp */
     0,				/* have_sigwinch */
     0,				/* cleanup_nested */
 
@@ -123,13 +126,14 @@
 
     FALSE,			/* have_tic_directory */
     FALSE,			/* keep_tic_directory */
-    TERMINFO,			/* tic_directory */
+    0,				/* tic_directory */
 
     NULL,			/* dbi_list */
     0,				/* dbi_size */
 
     NULL,			/* first_name */
     NULL,			/* keyname_table */
+    0,				/* init_keyname */
 
     0,				/* slk_format */
 
@@ -140,7 +144,15 @@
     0,				/* tgetent_index */
     0,				/* tgetent_sequence */
 
+    0,				/* dbd_blob */
+    0,				/* dbd_list */
+    0,				/* dbd_size */
+    0,				/* dbd_time */
+    { { 0, 0 } },		/* dbd_vars */
+
+#ifndef USE_SP_WINDOWLIST
     0,				/* _nc_windowlist */
+#endif
 
 #if USE_HOME_TERMINFO
     NULL,			/* home_terminfo */
@@ -151,6 +163,10 @@
     0,				/* safeprint_rows */
 #endif
 
+#ifdef USE_TERM_DRIVER
+    0,				/* term_driver */
+#endif
+
 #ifdef TRACE
     FALSE,			/* init_trace */
     CHARS_0s,			/* trace_fname */
@@ -174,7 +190,9 @@
     { CHARS_0s, CHARS_0s },	/* traceatr_color_buf */
     0,				/* traceatr_color_sel */
     -1,				/* traceatr_color_last */
-
+#if !defined(USE_PTHREADS) && USE_REENTRANT
+    0,				/* nested_tracef */
+#endif
 #endif /* TRACE */
 #ifdef USE_PTHREADS
     PTHREAD_MUTEX_INITIALIZER,	/* mutex_curses */
@@ -183,6 +201,9 @@
     0,				/* nested_tracef */
     0,				/* use_pthreads */
 #endif
+#if USE_PTHREADS_EINTR
+    0,				/* read_thread */
+#endif
 };
 
 #define STACK_FRAME_0	{ { 0 }, 0 }
@@ -196,8 +217,10 @@
     TRUE,			/* use_env */
     FALSE,			/* filter_mode */
     A_NORMAL,			/* previous_attr */
+#ifndef USE_SP_RIPOFF
     RIPOFF_0s,			/* ripoff */
     NULL,			/* rsp */
+#endif
     {				/* tparm_state */
 #ifdef TRACE
 	NULL,			/* tname */
@@ -221,19 +244,39 @@
 #if NCURSES_NO_PADDING
     FALSE,			/* flag to set if padding disabled  */
 #endif
+    0,				/* _outch */
 #if BROKEN_LINKER || USE_REENTRANT
     NULL,			/* real_acs_map */
     0,				/* LINES */
     0,				/* COLS */
+    8,				/* TABSIZE */
+    1000,			/* ESCDELAY */
     0,				/* cur_term */
 #ifdef TRACE
     0L,				/* _outchars */
     NULL,			/* _tputs_trace */
 #endif
 #endif
+    FALSE,			/* use_tioctl */
 };
 /* *INDENT-ON* */
 
+/*
+ * wgetch() and other functions with a WINDOW* parameter may use a SCREEN*
+ * internally, and it is useful to allow those to be invoked without switching
+ * SCREEN's, e.g., for multi-threaded applications.
+ */
+NCURSES_EXPORT(SCREEN *)
+_nc_screen_of(WINDOW *win)
+{
+    SCREEN *sp = 0;
+
+    if (win != 0) {
+	sp = WINDOW_EXT(win, screen);
+    }
+    return (sp);
+}
+
 /******************************************************************************/
 #ifdef USE_PTHREADS
 static void
@@ -314,7 +357,9 @@
 	return 0;
     return pthread_mutex_unlock(obj);
 }
+#endif /* USE_PTHREADS */
 
+#if defined(USE_PTHREADS) || USE_PTHREADS_EINTR
 #if USE_WEAK_SYMBOLS
 /*
  * NB: sigprocmask(2) is global but pthread_sigmask(3p)
diff --git a/ncurses/tinfo/lib_has_cap.c b/ncurses/tinfo/lib_has_cap.c
index 0dc66bd..17e59d5 100644
--- a/ncurses/tinfo/lib_has_cap.c
+++ b/ncurses/tinfo/lib_has_cap.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2000,2003 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2009,2013 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            *
@@ -30,6 +30,7 @@
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-2003               *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -41,25 +42,53 @@
 
 #include <curses.priv.h>
 
-#include <term.h>
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
 
-MODULE_ID("$Id: lib_has_cap.c,v 1.4 2003/10/25 19:43:55 tom Exp $")
+MODULE_ID("$Id: lib_has_cap.c,v 1.10 2013/11/16 19:57:22 tom Exp $")
 
 NCURSES_EXPORT(bool)
+NCURSES_SP_NAME(has_ic) (NCURSES_SP_DCL0)
+{
+    bool code = FALSE;
+
+    T((T_CALLED("has_ic(%p)"), (void *) SP_PARM));
+
+    if (HasTInfoTerminal(SP_PARM)) {
+	code = ((insert_character || parm_ich
+		 || (enter_insert_mode && exit_insert_mode))
+		&& (delete_character || parm_dch)) ? TRUE : FALSE;
+    }
+
+    returnCode(code);
+}
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(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));
+    return NCURSES_SP_NAME(has_ic) (CURRENT_SCREEN);
+}
+#endif
+
+NCURSES_EXPORT(bool)
+NCURSES_SP_NAME(has_il) (NCURSES_SP_DCL0)
+{
+    bool code = FALSE;
+    T((T_CALLED("has_il(%p)"), (void *) SP_PARM));
+    if (HasTInfoTerminal(SP_PARM)) {
+	code = ((insert_line || parm_insert_line)
+		&& (delete_line || parm_delete_line)) ? TRUE : FALSE;
+    }
+
+    returnCode(code);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(bool)
 has_il(void)
 {
-    T((T_CALLED("has_il()")));
-    returnCode(cur_term
-	       && (insert_line || parm_insert_line)
-	       && (delete_line || parm_delete_line));
+    return NCURSES_SP_NAME(has_il) (CURRENT_SCREEN);
 }
+#endif
diff --git a/ncurses/tinfo/lib_kernel.c b/ncurses/tinfo/lib_kernel.c
index 89dc1e8..37f7084 100644
--- a/ncurses/tinfo/lib_kernel.c
+++ b/ncurses/tinfo/lib_kernel.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2003,2004 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2009,2010 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            *
@@ -29,7 +29,8 @@
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
- *     and: Thomas E. Dickey 2002                                           *
+ *     and: Thomas E. Dickey                        2002                    *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -46,9 +47,8 @@
  */
 
 #include <curses.priv.h>
-#include <term.h>		/* cur_term */
 
-MODULE_ID("$Id: lib_kernel.c,v 1.24 2004/05/08 17:11:21 tom Exp $")
+MODULE_ID("$Id: lib_kernel.c,v 1.31 2010/12/19 01:21:19 tom Exp $")
 
 static int
 _nc_vdisable(void)
@@ -59,7 +59,7 @@
 #endif
 #if defined(_PC_VDISABLE)
     if (value == -1) {
-	value = fpathconf(0, _PC_VDISABLE);
+	value = (int) fpathconf(0, _PC_VDISABLE);
 	if (value == -1) {
 	    value = 0377;
 	}
@@ -79,23 +79,33 @@
  */
 
 NCURSES_EXPORT(char)
-erasechar(void)
+NCURSES_SP_NAME(erasechar) (NCURSES_SP_DCL0)
 {
     int result = ERR;
-    T((T_CALLED("erasechar()")));
+    TERMINAL *termp = TerminalOf(SP_PARM);
 
-    if (cur_term != 0) {
+    T((T_CALLED("erasechar(%p)"), (void *) SP_PARM));
+
+    if (termp != 0) {
 #ifdef TERMIOS
-	result = cur_term->Ottyb.c_cc[VERASE];
+	result = termp->Ottyb.c_cc[VERASE];
 	if (result == _nc_vdisable())
 	    result = ERR;
 #else
-	result = cur_term->Ottyb.sg_erase;
+	result = termp->Ottyb.sg_erase;
 #endif
     }
-    returnCode(result);
+    returnChar((char) result);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(char)
+erasechar(void)
+{
+    return NCURSES_SP_NAME(erasechar) (CURRENT_SCREEN);
+}
+#endif
+
 /*
  *	killchar()
  *
@@ -104,23 +114,33 @@
  */
 
 NCURSES_EXPORT(char)
-killchar(void)
+NCURSES_SP_NAME(killchar) (NCURSES_SP_DCL0)
 {
     int result = ERR;
-    T((T_CALLED("killchar()")));
+    TERMINAL *termp = TerminalOf(SP_PARM);
 
-    if (cur_term != 0) {
+    T((T_CALLED("killchar(%p)"), (void *) SP_PARM));
+
+    if (termp != 0) {
 #ifdef TERMIOS
-	result = cur_term->Ottyb.c_cc[VKILL];
+	result = termp->Ottyb.c_cc[VKILL];
 	if (result == _nc_vdisable())
 	    result = ERR;
 #else
-	result = cur_term->Ottyb.sg_kill;
+	result = termp->Ottyb.sg_kill;
 #endif
     }
-    returnCode(result);
+    returnChar((char) result);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(char)
+killchar(void)
+{
+    return NCURSES_SP_NAME(killchar) (CURRENT_SCREEN);
+}
+#endif
+
 /*
  *	flushinp()
  *
@@ -129,26 +149,36 @@
  */
 
 NCURSES_EXPORT(int)
-flushinp(void)
+NCURSES_SP_NAME(flushinp) (NCURSES_SP_DCL0)
 {
-    T((T_CALLED("flushinp()")));
+    TERMINAL *termp = TerminalOf(SP_PARM);
 
-    if (cur_term != 0) {
+    T((T_CALLED("flushinp(%p)"), (void *) SP_PARM));
+
+    if (termp != 0) {
 #ifdef TERMIOS
-	tcflush(cur_term->Filedes, TCIFLUSH);
+	tcflush(termp->Filedes, TCIFLUSH);
 #else
 	errno = 0;
 	do {
-	    ioctl(cur_term->Filedes, TIOCFLUSH, 0);
+	    ioctl(termp->Filedes, TIOCFLUSH, 0);
 	} while
 	    (errno == EINTR);
 #endif
-	if (SP) {
-	    SP->_fifohead = -1;
-	    SP->_fifotail = 0;
-	    SP->_fifopeek = 0;
+	if (SP_PARM) {
+	    SP_PARM->_fifohead = -1;
+	    SP_PARM->_fifotail = 0;
+	    SP_PARM->_fifopeek = 0;
 	}
 	returnCode(OK);
     }
     returnCode(ERR);
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+flushinp(void)
+{
+    return NCURSES_SP_NAME(flushinp) (CURRENT_SCREEN);
+}
+#endif
diff --git a/ncurses/tinfo/lib_longname.c b/ncurses/tinfo/lib_longname.c
index 1301ee5..fa231b8 100644
--- a/ncurses/tinfo/lib_longname.c
+++ b/ncurses/tinfo/lib_longname.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc.                   *
+ * Copyright (c) 1998-2010,2015 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            *
@@ -29,6 +29,8 @@
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -40,7 +42,48 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_longname.c,v 1.9 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_longname.c,v 1.13 2015/07/25 20:08:14 tom Exp $")
+
+#if USE_REENTRANT
+NCURSES_EXPORT(char *)
+NCURSES_SP_NAME(longname) (NCURSES_SP_DCL0)
+{
+    static char empty[] =
+    {'\0'};
+    char *ptr;
+
+    T((T_CALLED("longname(%p)"), (void *) SP_PARM));
+
+    if (SP_PARM) {
+	for (ptr = SP_PARM->_ttytype + strlen(SP_PARM->_ttytype);
+	     ptr > SP_PARM->_ttytype;
+	     ptr--)
+	    if (*ptr == '|')
+		returnPtr(ptr + 1);
+	returnPtr(SP_PARM->_ttytype);
+    }
+    return empty;
+}
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(char *)
+longname(void)
+{
+    return NCURSES_SP_NAME(longname) (CURRENT_SCREEN);
+}
+#endif
+
+#else
+
+/* a dummy entrypoint is simpler than generating a conditional in curses.h */
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(char *)
+NCURSES_SP_NAME(longname) (NCURSES_SP_DCL0)
+{
+    (void) SP_PARM;
+    return longname();
+}
+#endif
 
 NCURSES_EXPORT(char *)
 longname(void)
@@ -49,9 +92,11 @@
 
     T((T_CALLED("longname()")));
 
-    for (ptr = ttytype + strlen(ttytype); ptr > ttytype; ptr--)
+    for (ptr = ttytype + strlen(ttytype);
+	 ptr > ttytype;
+	 ptr--)
 	if (*ptr == '|')
 	    returnPtr(ptr + 1);
-
     returnPtr(ttytype);
 }
+#endif
diff --git a/ncurses/tinfo/lib_napms.c b/ncurses/tinfo/lib_napms.c
index 417b3b4..df17363 100644
--- a/ncurses/tinfo/lib_napms.c
+++ b/ncurses/tinfo/lib_napms.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2014 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            *
@@ -29,6 +29,8 @@
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -49,13 +51,21 @@
 #endif
 #endif
 
-MODULE_ID("$Id: lib_napms.c,v 1.17 2008/05/03 21:34:13 tom Exp $")
+MODULE_ID("$Id: lib_napms.c,v 1.24 2014/03/08 20:32:59 tom Exp $")
 
 NCURSES_EXPORT(int)
-napms(int ms)
+NCURSES_SP_NAME(napms) (NCURSES_SP_DCLx int ms)
 {
     T((T_CALLED("napms(%d)"), ms));
 
+#ifdef USE_TERM_DRIVER
+    if (HasTerminal(SP_PARM)) {
+	CallDriver_1(SP_PARM, td_nap, ms);
+    }
+#else /* !USE_TERM_DRIVER */
+#if NCURSES_SP_FUNCS
+    (void) sp;
+#endif
 #if HAVE_NANOSLEEP
     {
 	struct timespec request, remaining;
@@ -69,6 +79,15 @@
 #else
     _nc_timed_wait(0, 0, ms, (int *) 0 EVENTLIST_2nd(0));
 #endif
+#endif /* !USE_TERM_DRIVER */
 
     returnCode(OK);
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+napms(int ms)
+{
+    return NCURSES_SP_NAME(napms) (CURRENT_SCREEN, ms);
+}
+#endif
diff --git a/ncurses/tinfo/lib_options.c b/ncurses/tinfo/lib_options.c
index f3b1485..b736d5f 100644
--- a/ncurses/tinfo/lib_options.c
+++ b/ncurses/tinfo/lib_options.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2013,2014 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            *
@@ -30,6 +30,7 @@
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -41,53 +42,71 @@
 
 #include <curses.priv.h>
 
-#include <term.h>
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
 
-MODULE_ID("$Id: lib_options.c,v 1.58 2008/08/16 21:20:48 Werner.Fink Exp $")
-
-static int _nc_curs_set(SCREEN *, int);
-static int _nc_meta(SCREEN *, bool);
+MODULE_ID("$Id: lib_options.c,v 1.78 2014/09/27 21:55:24 tom Exp $")
 
 NCURSES_EXPORT(int)
 idlok(WINDOW *win, bool flag)
 {
-    T((T_CALLED("idlok(%p,%d)"), win, flag));
+    int res = ERR;
+    T((T_CALLED("idlok(%p,%d)"), (void *) win, flag));
 
     if (win) {
-	_nc_idlok = win->_idlok = (flag && (has_il() || change_scroll_region));
-	returnCode(OK);
-    } else
-	returnCode(ERR);
+	SCREEN *sp = _nc_screen_of(win);
+	if (sp != 0
+#ifdef USE_TERM_DRIVER
+	    && IsTermInfo(sp)
+#endif
+	    ) {
+	    sp->_nc_sp_idlok =
+		win->_idlok = (flag && (NCURSES_SP_NAME(has_il) (NCURSES_SP_ARG)
+					|| change_scroll_region));
+	    res = OK;
+	}
+    }
+    returnCode(res);
 }
 
 NCURSES_EXPORT(void)
 idcok(WINDOW *win, bool flag)
 {
-    T((T_CALLED("idcok(%p,%d)"), win, flag));
+    T((T_CALLED("idcok(%p,%d)"), (void *) win, flag));
 
-    if (win)
-	_nc_idcok = win->_idcok = (flag && has_ic());
-
+    if (win) {
+	SCREEN *sp = _nc_screen_of(win);
+	sp->_nc_sp_idcok = win->_idcok = (flag && NCURSES_SP_NAME(has_ic) (NCURSES_SP_ARG));
+    }
     returnVoid;
 }
 
 NCURSES_EXPORT(int)
-halfdelay(int t)
+NCURSES_SP_NAME(halfdelay) (NCURSES_SP_DCLx int t)
 {
-    T((T_CALLED("halfdelay(%d)"), t));
+    T((T_CALLED("halfdelay(%p,%d)"), (void *) SP_PARM, t));
 
-    if (t < 1 || t > 255 || SP == 0)
+    if (t < 1 || t > 255 || !IsValidTIScreen(SP_PARM))
 	returnCode(ERR);
 
-    cbreak();
-    SP->_cbreak = t + 1;
+    NCURSES_SP_NAME(cbreak) (NCURSES_SP_ARG);
+    SP_PARM->_cbreak = t + 1;
     returnCode(OK);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+halfdelay(int t)
+{
+    return NCURSES_SP_NAME(halfdelay) (CURRENT_SCREEN, t);
+}
+#endif
+
 NCURSES_EXPORT(int)
 nodelay(WINDOW *win, bool flag)
 {
-    T((T_CALLED("nodelay(%p,%d)"), win, flag));
+    T((T_CALLED("nodelay(%p,%d)"), (void *) win, flag));
 
     if (win) {
 	if (flag == TRUE)
@@ -102,7 +121,7 @@
 NCURSES_EXPORT(int)
 notimeout(WINDOW *win, bool f)
 {
-    T((T_CALLED("notimeout(%p,%d)"), win, f));
+    T((T_CALLED("notimeout(%p,%d)"), (void *) win, f));
 
     if (win) {
 	win->_notimeout = f;
@@ -114,7 +133,7 @@
 NCURSES_EXPORT(void)
 wtimeout(WINDOW *win, int delay)
 {
-    T((T_CALLED("wtimeout(%p,%d)"), win, delay));
+    T((T_CALLED("wtimeout(%p,%d)"), (void *) win, delay));
 
     if (win) {
 	win->_delay = delay;
@@ -125,11 +144,11 @@
 NCURSES_EXPORT(int)
 keypad(WINDOW *win, bool flag)
 {
-    T((T_CALLED("keypad(%p,%d)"), win, flag));
+    T((T_CALLED("keypad(%p,%d)"), (void *) win, flag));
 
     if (win) {
 	win->_use_keypad = flag;
-	returnCode(_nc_keypad(SP, flag));
+	returnCode(_nc_keypad(_nc_screen_of(win), flag));
     } else
 	returnCode(ERR);
 }
@@ -137,38 +156,107 @@
 NCURSES_EXPORT(int)
 meta(WINDOW *win GCC_UNUSED, bool flag)
 {
-    int result;
+    int result = ERR;
+    SCREEN *sp = (win == 0) ? CURRENT_SCREEN : _nc_screen_of(win);
 
     /* Ok, we stay relaxed and don't signal an error if win is NULL */
-    T((T_CALLED("meta(%p,%d)"), win, flag));
-    result = _nc_meta(SP, flag);
+    T((T_CALLED("meta(%p,%d)"), (void *) win, flag));
+
+    /* Ok, we stay relaxed and don't signal an error if win is NULL */
+
+    if (sp != 0) {
+	sp->_use_meta = flag;
+#ifdef USE_TERM_DRIVER
+	if (IsTermInfo(sp)) {
+	    if (flag) {
+		NCURSES_PUTP2("meta_on", meta_on);
+	    } else {
+		NCURSES_PUTP2("meta_off", meta_off);
+	    }
+	}
+#else
+	if (flag) {
+	    NCURSES_PUTP2("meta_on", meta_on);
+	} else {
+	    NCURSES_PUTP2("meta_off", meta_off);
+	}
+#endif
+	result = OK;
+    }
     returnCode(result);
 }
 
 /* curs_set() moved here to narrow the kernel interface */
 
 NCURSES_EXPORT(int)
-curs_set(int vis)
+NCURSES_SP_NAME(curs_set) (NCURSES_SP_DCLx int vis)
 {
-    int result;
+    int code = ERR;
+    T((T_CALLED("curs_set(%p,%d)"), (void *) SP_PARM, vis));
 
-    T((T_CALLED("curs_set(%d)"), vis));
-    result = _nc_curs_set(SP, vis);
-    returnCode(result);
+    if (SP_PARM != 0 && vis >= 0 && vis <= 2) {
+	int cursor = SP_PARM->_cursor;
+	if (vis == cursor) {
+	    code = cursor;
+	} else {
+#ifdef USE_TERM_DRIVER
+	    code = CallDriver_1(SP_PARM, td_cursorSet, vis);
+#else
+	    if (IsTermInfo(SP_PARM)) {
+		switch (vis) {
+		case 2:
+		    code = NCURSES_PUTP2_FLUSH("cursor_visible",
+					       cursor_visible);
+		    break;
+		case 1:
+		    code = NCURSES_PUTP2_FLUSH("cursor_normal",
+					       cursor_normal);
+		    break;
+		case 0:
+		    code = NCURSES_PUTP2_FLUSH("cursor_invisible",
+					       cursor_invisible);
+		    break;
+		}
+	    } else {
+		code = ERR;
+	    }
+#endif
+	    if (code != ERR)
+		code = (cursor == -1 ? 1 : cursor);
+	    SP_PARM->_cursor = vis;
+	}
+    }
+    returnCode(code);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
-typeahead(int fd)
+curs_set(int vis)
 {
-    T((T_CALLED("typeahead(%d)"), fd));
-    if (SP != 0) {
-	SP->_checkfd = fd;
+    return (NCURSES_SP_NAME(curs_set) (CURRENT_SCREEN, vis));
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(typeahead) (NCURSES_SP_DCLx int fd)
+{
+    T((T_CALLED("typeahead(%p, %d)"), (void *) SP_PARM, fd));
+    if (IsValidTIScreen(SP_PARM)) {
+	SP_PARM->_checkfd = fd;
 	returnCode(OK);
     } else {
 	returnCode(ERR);
     }
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+typeahead(int fd)
+{
+    return NCURSES_SP_NAME(typeahead) (CURRENT_SCREEN, fd);
+}
+#endif
+
 /*
 **      has_key()
 **
@@ -189,43 +277,50 @@
 		|| has_key_internal(keycode, tp->sibling));
 }
 
+#ifdef USE_TERM_DRIVER
+NCURSES_EXPORT(int)
+TINFO_HAS_KEY(SCREEN *sp, int keycode)
+{
+    return IsValidTIScreen(sp) ?
+	has_key_internal(keycode, sp->_keytry) : 0;
+}
+#else
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(has_key) (NCURSES_SP_DCLx int keycode)
+{
+    T((T_CALLED("has_key(%p,%d)"), (void *) SP_PARM, keycode));
+    returnCode(SP != 0 ? has_key_internal(keycode, SP_PARM->_keytry) : FALSE);
+}
+
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 has_key(int keycode)
 {
-    T((T_CALLED("has_key(%d)"), keycode));
-    returnCode(SP != 0 ? has_key_internal(keycode, SP->_keytry) : FALSE);
+    return NCURSES_SP_NAME(has_key) (CURRENT_SCREEN, keycode);
 }
+#endif
+#endif
 #endif /* NCURSES_EXT_FUNCS */
 
-/*
- * Internal entrypoints use SCREEN* parameter to obtain capabilities rather
- * than cur_term.
- */
-#undef CUR
-#define CUR (sp->_term)->type.
-
-static int
-_nc_putp(const char *name GCC_UNUSED, const char *value)
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(_nc_putp_flush) (NCURSES_SP_DCLx
+				 const char *name, const char *value)
 {
-    int rc = ERR;
-
-    if (value) {
-	TPUTS_TRACE(name);
-	rc = putp(value);
-    }
-    return rc;
-}
-
-static int
-_nc_putp_flush(const char *name, const char *value)
-{
-    int rc = _nc_putp(name, value);
+    int rc = NCURSES_PUTP2(name, value);
     if (rc != ERR) {
 	_nc_flush();
     }
     return rc;
 }
 
+#if 0 && NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+_nc_putp_flush(const char *name, const char *value)
+{
+    return NCURSES_SP_NAME(_nc_putp_flush) (CURRENT_SCREEN, name, value);
+}
+#endif
+
 /* Turn the keypad on/off
  *
  * Note:  we flush the output because changing this mode causes some terminals
@@ -234,7 +329,7 @@
  * the terminal state _before_ switching modes.
  */
 NCURSES_EXPORT(int)
-_nc_keypad(SCREEN *sp, bool flag)
+_nc_keypad(SCREEN *sp, int flag)
 {
     int rc = ERR;
 
@@ -245,12 +340,12 @@
 	 * has wgetch() reading in more than one thread.  putp() and below
 	 * may use SP explicitly.
 	 */
-	if (_nc_use_pthreads && sp != SP) {
+	if (_nc_use_pthreads && sp != CURRENT_SCREEN) {
 	    SCREEN *save_sp;
 
 	    /* cannot use use_screen(), since that is not in tinfo library */
 	    _nc_lock_global(curses);
-	    save_sp = SP;
+	    save_sp = CURRENT_SCREEN;
 	    _nc_set_screen(sp);
 	    rc = _nc_keypad(sp, flag);
 	    _nc_set_screen(save_sp);
@@ -258,10 +353,15 @@
 	} else
 #endif
 	{
+#ifdef USE_TERM_DRIVER
+	    rc = CallDriver_1(sp, td_kpad, flag);
+	    if (rc == OK)
+		sp->_keypad_on = flag;
+#else
 	    if (flag) {
-		(void) _nc_putp_flush("keypad_xmit", keypad_xmit);
+		(void) NCURSES_PUTP2_FLUSH("keypad_xmit", keypad_xmit);
 	    } else if (!flag && keypad_local) {
-		(void) _nc_putp_flush("keypad_local", keypad_local);
+		(void) NCURSES_PUTP2_FLUSH("keypad_local", keypad_local);
 	    }
 
 	    if (flag && !sp->_tried) {
@@ -270,58 +370,8 @@
 	    }
 	    sp->_keypad_on = flag;
 	    rc = OK;
+#endif
 	}
     }
     return (rc);
 }
-
-static int
-_nc_curs_set(SCREEN *sp, int vis)
-{
-    int result = ERR;
-
-    T((T_CALLED("curs_set(%d)"), vis));
-    if (sp != 0 && vis >= 0 && vis <= 2) {
-	int cursor = sp->_cursor;
-
-	if (vis == cursor) {
-	    result = cursor;
-	} else {
-	    switch (vis) {
-	    case 2:
-		result = _nc_putp_flush("cursor_visible", cursor_visible);
-		break;
-	    case 1:
-		result = _nc_putp_flush("cursor_normal", cursor_normal);
-		break;
-	    case 0:
-		result = _nc_putp_flush("cursor_invisible", cursor_invisible);
-		break;
-	    }
-	    if (result != ERR)
-		result = (cursor == -1 ? 1 : cursor);
-	    sp->_cursor = vis;
-	}
-    }
-    returnCode(result);
-}
-
-static int
-_nc_meta(SCREEN *sp, bool flag)
-{
-    int result = ERR;
-
-    /* Ok, we stay relaxed and don't signal an error if win is NULL */
-
-    if (SP != 0) {
-	SP->_use_meta = flag;
-
-	if (flag) {
-	    _nc_putp("meta_on", meta_on);
-	} else {
-	    _nc_putp("meta_off", meta_off);
-	}
-	result = OK;
-    }
-    return result;
-}
diff --git a/ncurses/tinfo/lib_print.c b/ncurses/tinfo/lib_print.c
index 975b46d..0dab4d4 100644
--- a/ncurses/tinfo/lib_print.c
+++ b/ncurses/tinfo/lib_print.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2002,2006 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2012 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            *
@@ -29,23 +29,31 @@
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                                                 *
  ****************************************************************************/
 
 #include <curses.priv.h>
 
-#include <term.h>
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
 
-MODULE_ID("$Id: lib_print.c,v 1.16 2006/11/26 00:26:34 tom Exp $")
+MODULE_ID("$Id: lib_print.c,v 1.23 2012/02/22 22:34:31 tom Exp $")
 
 NCURSES_EXPORT(int)
-mcprint(char *data, int len)
+NCURSES_SP_NAME(mcprint) (NCURSES_SP_DCLx char *data, int len)
 /* ship binary character data to the printer via mc4/mc5/mc5p */
 {
+    int result;
     char *mybuf, *switchon;
-    size_t onsize, offsize, res;
+    size_t onsize, offsize;
+    size_t need;
 
     errno = 0;
-    if (!cur_term || (!prtr_non && (!prtr_on || !prtr_off))) {
+    if (!HasTInfoTerminal(SP_PARM)
+	|| len <= 0
+	|| (!prtr_non && (!prtr_on || !prtr_off))) {
 	errno = ENODEV;
 	return (ERR);
     }
@@ -60,16 +68,18 @@
 	offsize = strlen(prtr_off);
     }
 
+    need = onsize + (size_t) len + offsize;
+
     if (switchon == 0
-	|| (mybuf = typeMalloc(char, onsize + len + offsize + 1)) == 0) {
+	|| (mybuf = typeMalloc(char, need + 1)) == 0) {
 	errno = ENOMEM;
 	return (ERR);
     }
 
-    (void) strcpy(mybuf, switchon);
-    memcpy(mybuf + onsize, data, (unsigned) len);
+    _nc_STRCPY(mybuf, switchon, need);
+    memcpy(mybuf + onsize, data, (size_t) len);
     if (offsize)
-	(void) strcpy(mybuf + onsize + len, prtr_off);
+	_nc_STRCPY(mybuf + onsize + len, prtr_off, need);
 
     /*
      * We're relying on the atomicity of UNIX writes here.  The
@@ -78,15 +88,24 @@
      * 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);
+    result = (int) write(TerminalOf(SP_PARM)->Filedes, mybuf, need);
 
     /*
      * 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.
      */
+#ifndef __MINGW32__
     (void) sleep(0);
-
+#endif
     free(mybuf);
-    return (res);
+    return (result);
 }
+
+#if NCURSES_SP_FUNCS && !defined(USE_TERM_DRIVER)
+NCURSES_EXPORT(int)
+mcprint(char *data, int len)
+{
+    return NCURSES_SP_NAME(mcprint) (CURRENT_SCREEN, data, len);
+}
+#endif
diff --git a/ncurses/tinfo/lib_raw.c b/ncurses/tinfo/lib_raw.c
index 58e7188..928692b 100644
--- a/ncurses/tinfo/lib_raw.c
+++ b/ncurses/tinfo/lib_raw.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2002,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2012 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            *
@@ -29,7 +29,8 @@
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
- *     and: Thomas E. Dickey 1998 on                                        *
+ *     and: Thomas E. Dickey                        1998-on                 *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -47,13 +48,8 @@
  */
 
 #include <curses.priv.h>
-#include <term.h>		/* cur_term */
 
-MODULE_ID("$Id: lib_raw.c,v 1.14 2007/09/29 21:50:22 tom Exp $")
-
-#if SVR4_TERMIO && !defined(_POSIX_SOURCE)
-#define _POSIX_SOURCE
-#endif
+MODULE_ID("$Id: lib_raw.c,v 1.21 2012/01/21 19:21:29 KO.Myung-Hun Exp $")
 
 #if HAVE_SYS_TERMIO_H
 #include <sys/termio.h>		/* needed for ISC */
@@ -61,11 +57,16 @@
 
 #ifdef __EMX__
 #include <io.h>
-#define _nc_setmode(mode) setmode(SP->_ifd, mode)
+#define _nc_setmode(mode) setmode(SP_PARM->_ifd, mode)
 #else
 #define _nc_setmode(mode)	/* nothing */
 #endif
 
+#if USE_KLIBC_KBD
+#define INCL_KBD
+#include <os2.h>
+#endif
+
 #define COOKED_INPUT	(IXON|BRKINT|PARMRK)
 
 #ifdef TRACE
@@ -77,188 +78,257 @@
 #endif /* TRACE */
 
 NCURSES_EXPORT(int)
-raw(void)
+NCURSES_SP_NAME(raw) (NCURSES_SP_DCL0)
 {
     int result = ERR;
+    TERMINAL *termp;
 
-    T((T_CALLED("raw()")));
-
-    if (SP != 0 && cur_term != 0) {
+    T((T_CALLED("raw(%p)"), (void *) SP_PARM));
+    if ((termp = TerminalOf(SP_PARM)) != 0) {
 	TTY buf;
 
 	BEFORE("raw");
 	_nc_setmode(O_BINARY);
 
-	buf = cur_term->Nttyb;
+	buf = termp->Nttyb;
 #ifdef TERMIOS
-	buf.c_lflag &= ~(ICANON | ISIG | IEXTEN);
-	buf.c_iflag &= ~(COOKED_INPUT);
+	buf.c_lflag &= (unsigned) ~(ICANON | ISIG | IEXTEN);
+	buf.c_iflag &= (unsigned) ~(COOKED_INPUT);
 	buf.c_cc[VMIN] = 1;
 	buf.c_cc[VTIME] = 0;
 #else
 	buf.sg_flags |= RAW;
 #endif
-	if ((result = _nc_set_tty_mode(&buf)) == OK) {
-	    SP->_raw = TRUE;
-	    SP->_cbreak = 1;
-	    cur_term->Nttyb = buf;
+	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
+	if (result == OK) {
+#if USE_KLIBC_KBD
+	    KBDINFO kbdinfo;
+
+	    kbdinfo.cb = sizeof(kbdinfo);
+	    KbdGetStatus(&kbdinfo, 0);
+
+	    kbdinfo.cb = sizeof(kbdinfo);
+	    kbdinfo.fsMask &= ~KEYBOARD_ASCII_MODE;
+	    kbdinfo.fsMask |= KEYBOARD_BINARY_MODE;
+	    KbdSetStatus(&kbdinfo, 0);
+#endif
+	    SP_PARM->_raw = TRUE;
+	    SP_PARM->_cbreak = 1;
+	    termp->Nttyb = buf;
 	}
 	AFTER("raw");
     }
     returnCode(result);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
-cbreak(void)
+raw(void)
+{
+    return NCURSES_SP_NAME(raw) (CURRENT_SCREEN);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(cbreak) (NCURSES_SP_DCL0)
 {
     int result = ERR;
+    TERMINAL *termp;
 
-    T((T_CALLED("cbreak()")));
-
-    if (SP != 0 && cur_term != 0) {
+    T((T_CALLED("cbreak(%p)"), (void *) SP_PARM));
+    if ((termp = TerminalOf(SP_PARM)) != 0) {
 	TTY buf;
 
 	BEFORE("cbreak");
 	_nc_setmode(O_BINARY);
 
-	buf = cur_term->Nttyb;
+	buf = termp->Nttyb;
 #ifdef TERMIOS
-	buf.c_lflag &= ~ICANON;
-	buf.c_iflag &= ~ICRNL;
+	buf.c_lflag &= (unsigned) ~ICANON;
+	buf.c_iflag &= (unsigned) ~ICRNL;
 	buf.c_lflag |= ISIG;
 	buf.c_cc[VMIN] = 1;
 	buf.c_cc[VTIME] = 0;
 #else
 	buf.sg_flags |= CBREAK;
 #endif
-	if ((result = _nc_set_tty_mode(&buf)) == OK) {
-	    SP->_cbreak = 1;
-	    cur_term->Nttyb = buf;
+	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
+	if (result == OK) {
+	    SP_PARM->_cbreak = 1;
+	    termp->Nttyb = buf;
 	}
 	AFTER("cbreak");
     }
     returnCode(result);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+cbreak(void)
+{
+    return NCURSES_SP_NAME(cbreak) (CURRENT_SCREEN);
+}
+#endif
+
 /*
  * Note:
  * this implementation may be wrong.  See the comment under intrflush().
  */
 NCURSES_EXPORT(void)
-qiflush(void)
+NCURSES_SP_NAME(qiflush) (NCURSES_SP_DCL0)
 {
     int result = ERR;
+    TERMINAL *termp;
 
-    T((T_CALLED("qiflush()")));
-
-    if (cur_term != 0) {
+    T((T_CALLED("qiflush(%p)"), (void *) SP_PARM));
+    if ((termp = TerminalOf(SP_PARM)) != 0) {
 	TTY buf;
 
 	BEFORE("qiflush");
-	buf = cur_term->Nttyb;
+	buf = termp->Nttyb;
 #ifdef TERMIOS
-	buf.c_lflag &= ~(NOFLSH);
-	result = _nc_set_tty_mode(&buf);
+	buf.c_lflag &= (unsigned) ~(NOFLSH);
+	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
 #else
 	/* FIXME */
 #endif
 	if (result == OK)
-	    cur_term->Nttyb = buf;
+	    termp->Nttyb = buf;
 	AFTER("qiflush");
     }
     returnVoid;
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(void)
+qiflush(void)
+{
+    NCURSES_SP_NAME(qiflush) (CURRENT_SCREEN);
+}
+#endif
+
 NCURSES_EXPORT(int)
-noraw(void)
+NCURSES_SP_NAME(noraw) (NCURSES_SP_DCL0)
 {
     int result = ERR;
+    TERMINAL *termp;
 
-    T((T_CALLED("noraw()")));
-
-    if (SP != 0 && cur_term != 0) {
+    T((T_CALLED("noraw(%p)"), (void *) SP_PARM));
+    if ((termp = TerminalOf(SP_PARM)) != 0) {
 	TTY buf;
 
 	BEFORE("noraw");
 	_nc_setmode(O_TEXT);
 
-	buf = cur_term->Nttyb;
+	buf = termp->Nttyb;
 #ifdef TERMIOS
 	buf.c_lflag |= ISIG | ICANON |
-	    (cur_term->Ottyb.c_lflag & IEXTEN);
+	    (termp->Ottyb.c_lflag & IEXTEN);
 	buf.c_iflag |= COOKED_INPUT;
 #else
 	buf.sg_flags &= ~(RAW | CBREAK);
 #endif
-	if ((result = _nc_set_tty_mode(&buf)) == OK) {
-	    SP->_raw = FALSE;
-	    SP->_cbreak = 0;
-	    cur_term->Nttyb = buf;
+	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
+	if (result == OK) {
+#if USE_KLIBC_KBD
+	    KBDINFO kbdinfo;
+
+	    kbdinfo.cb = sizeof(kbdinfo);
+	    KbdGetStatus(&kbdinfo, 0);
+
+	    kbdinfo.cb = sizeof(kbdinfo);
+	    kbdinfo.fsMask &= ~KEYBOARD_BINARY_MODE;
+	    kbdinfo.fsMask |= KEYBOARD_ASCII_MODE;
+	    KbdSetStatus(&kbdinfo, 0);
+#endif
+	    SP_PARM->_raw = FALSE;
+	    SP_PARM->_cbreak = 0;
+	    termp->Nttyb = buf;
 	}
 	AFTER("noraw");
     }
     returnCode(result);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
-nocbreak(void)
+noraw(void)
+{
+    return NCURSES_SP_NAME(noraw) (CURRENT_SCREEN);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(nocbreak) (NCURSES_SP_DCL0)
 {
     int result = ERR;
+    TERMINAL *termp;
 
-    T((T_CALLED("nocbreak()")));
-
-    if (SP != 0 && cur_term != 0) {
+    T((T_CALLED("nocbreak(%p)"), (void *) SP_PARM));
+    if ((termp = TerminalOf(SP_PARM)) != 0) {
 	TTY buf;
 
 	BEFORE("nocbreak");
 	_nc_setmode(O_TEXT);
 
-	buf = cur_term->Nttyb;
+	buf = termp->Nttyb;
 #ifdef TERMIOS
 	buf.c_lflag |= ICANON;
 	buf.c_iflag |= ICRNL;
 #else
 	buf.sg_flags &= ~CBREAK;
 #endif
-	if ((result = _nc_set_tty_mode(&buf)) == OK) {
-	    SP->_cbreak = 0;
-	    cur_term->Nttyb = buf;
+	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
+	if (result == OK) {
+	    SP_PARM->_cbreak = 0;
+	    termp->Nttyb = buf;
 	}
 	AFTER("nocbreak");
     }
     returnCode(result);
 }
 
-/*
- * Note:
- * this implementation may be wrong.  See the comment under intrflush().
- */
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+nocbreak(void)
+{
+    return NCURSES_SP_NAME(nocbreak) (CURRENT_SCREEN);
+}
+#endif
+
 NCURSES_EXPORT(void)
-noqiflush(void)
+NCURSES_SP_NAME(noqiflush) (NCURSES_SP_DCL0)
 {
     int result = ERR;
+    TERMINAL *termp;
 
-    T((T_CALLED("noqiflush()")));
-
-    if (cur_term != 0) {
+    T((T_CALLED("noqiflush(%p)"), (void *) SP_PARM));
+    if ((termp = TerminalOf(SP_PARM)) != 0) {
 	TTY buf;
 
 	BEFORE("noqiflush");
-	buf = cur_term->Nttyb;
+	buf = termp->Nttyb;
 #ifdef TERMIOS
 	buf.c_lflag |= NOFLSH;
-	result = _nc_set_tty_mode(&buf);
+	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
 #else
 	/* FIXME */
 #endif
-	if (result == OK) {
-	    cur_term->Nttyb = buf;
-	}
+	if (result == OK)
+	    termp->Nttyb = buf;
 	AFTER("noqiflush");
     }
     returnVoid;
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(void)
+noqiflush(void)
+{
+    NCURSES_SP_NAME(noqiflush) (CURRENT_SCREEN);
+}
+#endif
+
 /*
  * 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,
@@ -267,30 +337,41 @@
  * curs_inopts(3x) is too exact to be coincidence.
  */
 NCURSES_EXPORT(int)
-intrflush(WINDOW *win GCC_UNUSED, bool flag)
+NCURSES_SP_NAME(intrflush) (NCURSES_SP_DCLx WINDOW *win GCC_UNUSED, bool flag)
 {
     int result = ERR;
+    TERMINAL *termp;
 
-    T((T_CALLED("intrflush(%d)"), flag));
+    T((T_CALLED("intrflush(%p,%d)"), (void *) SP_PARM, flag));
+    if (SP_PARM == 0)
+	returnCode(ERR);
 
-    if (cur_term != 0) {
+    if ((termp = TerminalOf(SP_PARM)) != 0) {
 	TTY buf;
 
 	BEFORE("intrflush");
-	buf = cur_term->Nttyb;
+	buf = termp->Nttyb;
 #ifdef TERMIOS
 	if (flag)
-	    buf.c_lflag &= ~(NOFLSH);
+	    buf.c_lflag &= (unsigned) ~(NOFLSH);
 	else
 	    buf.c_lflag |= (NOFLSH);
-	result = _nc_set_tty_mode(&buf);
+	result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
 #else
 	/* FIXME */
 #endif
 	if (result == OK) {
-	    cur_term->Nttyb = buf;
+	    termp->Nttyb = buf;
 	}
 	AFTER("intrflush");
     }
     returnCode(result);
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+intrflush(WINDOW *win GCC_UNUSED, bool flag)
+{
+    return NCURSES_SP_NAME(intrflush) (CURRENT_SCREEN, win, flag);
+}
+#endif
diff --git a/ncurses/tinfo/lib_setup.c b/ncurses/tinfo/lib_setup.c
index 8cfaf12..0a0a1f5 100644
--- a/ncurses/tinfo/lib_setup.c
+++ b/ncurses/tinfo/lib_setup.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2014,2015 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            *
@@ -30,30 +30,25 @@
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
  * Terminal setup routines common to termcap and terminfo:
  *
  *		use_env(bool)
+ *		use_tioctl(bool)
  *		setupterm(char *, int, int *)
  */
 
 #include <curses.priv.h>
 #include <tic.h>		/* for MAX_NAME_SIZE */
-#include <term_entry.h>
-
-#if SVR4_TERMIO && !defined(_POSIX_SOURCE)
-#define _POSIX_SOURCE
-#endif
 
 #if HAVE_LOCALE_H
 #include <locale.h>
 #endif
 
-#include <term.h>		/* lines, columns, cur_term */
-
-MODULE_ID("$Id: lib_setup.c,v 1.111 2008/08/03 22:42:33 tom Exp $")
+MODULE_ID("$Id: lib_setup.c,v 1.164 2015/06/27 18:10:55 tom Exp $")
 
 /****************************************************************************
  *
@@ -109,61 +104,96 @@
  * Wrap global variables in this module.
  */
 #if USE_REENTRANT
+
 NCURSES_EXPORT(char *)
 NCURSES_PUBLIC_VAR(ttytype) (void)
 {
     static char empty[] = "";
-    return cur_term ? cur_term->type.term_names : empty;
+    char *result = empty;
+
+#if NCURSES_SP_FUNCS
+    if (CURRENT_SCREEN) {
+	TERMINAL *termp = TerminalOf(CURRENT_SCREEN);
+	if (termp != 0) {
+	    result = termp->type.term_names;
+	}
+    }
+#else
+    if (cur_term != 0) {
+	result = cur_term->type.term_names;
+    }
+#endif
+    return result;
 }
+
 NCURSES_EXPORT(int *)
-_nc_ptr_Lines(void)
+_nc_ptr_Lines(SCREEN *sp)
 {
-    return ptrLines();
+    return ptrLines(sp);
 }
+
 NCURSES_EXPORT(int)
 NCURSES_PUBLIC_VAR(LINES) (void)
 {
-    return *_nc_ptr_Lines();
+    return *_nc_ptr_Lines(CURRENT_SCREEN);
 }
+
 NCURSES_EXPORT(int *)
-_nc_ptr_Cols(void)
+_nc_ptr_Cols(SCREEN *sp)
 {
-    return ptrCols();
+    return ptrCols(sp);
 }
+
 NCURSES_EXPORT(int)
 NCURSES_PUBLIC_VAR(COLS) (void)
 {
-    return *_nc_ptr_Cols();
+    return *_nc_ptr_Cols(CURRENT_SCREEN);
 }
+
+NCURSES_EXPORT(int *)
+_nc_ptr_Tabsize(SCREEN *sp)
+{
+    return ptrTabsize(sp);
+}
+
 NCURSES_EXPORT(int)
 NCURSES_PUBLIC_VAR(TABSIZE) (void)
 {
-    return SP ? SP->_TABSIZE : 8;
+    return *_nc_ptr_Tabsize(CURRENT_SCREEN);
 }
 #else
 NCURSES_EXPORT_VAR(char) ttytype[NAMESIZE] = "";
 NCURSES_EXPORT_VAR(int) LINES = 0;
 NCURSES_EXPORT_VAR(int) COLS = 0;
-NCURSES_EXPORT_VAR(int) TABSIZE = 0;
+NCURSES_EXPORT_VAR(int) TABSIZE = 8;
 #endif
 
 #if NCURSES_EXT_FUNCS
 NCURSES_EXPORT(int)
-set_tabsize(int value)
+NCURSES_SP_NAME(set_tabsize) (NCURSES_SP_DCLx int value)
 {
     int code = OK;
 #if USE_REENTRANT
-    if (SP) {
-	SP->_TABSIZE = value;
+    if (SP_PARM) {
+	SP_PARM->_TABSIZE = value;
     } else {
 	code = ERR;
     }
 #else
+    (void) SP_PARM;
     TABSIZE = value;
 #endif
     return code;
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+set_tabsize(int value)
+{
+    return NCURSES_SP_NAME(set_tabsize) (CURRENT_SCREEN, value);
+}
 #endif
+#endif /* NCURSES_EXT_FUNCS */
 
 #if USE_SIGWINCH
 /*
@@ -188,78 +218,157 @@
 #endif
 
 NCURSES_EXPORT(void)
+NCURSES_SP_NAME(use_env) (NCURSES_SP_DCLx bool f)
+{
+    T((T_CALLED("use_env(%p,%d)"), (void *) SP_PARM, (int) f));
+#if NCURSES_SP_FUNCS
+    START_TRACE();
+    if (IsPreScreen(SP_PARM)) {
+	SP_PARM->_use_env = f;
+    }
+#else
+    _nc_prescreen.use_env = f;
+#endif
+    returnVoid;
+}
+
+NCURSES_EXPORT(void)
+NCURSES_SP_NAME(use_tioctl) (NCURSES_SP_DCLx bool f)
+{
+    T((T_CALLED("use_tioctl(%p,%d)"), (void *) SP_PARM, (int) f));
+#if NCURSES_SP_FUNCS
+    START_TRACE();
+    if (IsPreScreen(SP_PARM)) {
+	SP_PARM->_use_tioctl = f;
+    }
+#else
+    _nc_prescreen.use_tioctl = f;
+#endif
+    returnVoid;
+}
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(void)
 use_env(bool f)
 {
-    T((T_CALLED("use_env()")));
+    T((T_CALLED("use_env(%d)"), (int) f));
+    START_TRACE();
     _nc_prescreen.use_env = f;
     returnVoid;
 }
 
 NCURSES_EXPORT(void)
-_nc_get_screensize(SCREEN *sp, int *linep, int *colp)
+use_tioctl(bool f)
+{
+    T((T_CALLED("use_tioctl(%d)"), (int) f));
+    START_TRACE();
+    _nc_prescreen.use_tioctl = f;
+    returnVoid;
+}
+#endif
+
+NCURSES_EXPORT(void)
+_nc_get_screensize(SCREEN *sp,
+#ifdef USE_TERM_DRIVER
+		   TERMINAL * termp,
+#endif
+		   int *linep, int *colp)
 /* Obtain lines/columns values from the environment and/or terminfo entry */
 {
+#ifdef USE_TERM_DRIVER
+    TERMINAL_CONTROL_BLOCK *TCB;
+    int my_tabsize;
+
+    assert(termp != 0 && linep != 0 && colp != 0);
+    TCB = (TERMINAL_CONTROL_BLOCK *) termp;
+
+    my_tabsize = TCB->info.tabsize;
+    TCB->drv->td_size(TCB, linep, colp);
+
+#if USE_REENTRANT
+    if (sp != 0) {
+	sp->_TABSIZE = my_tabsize;
+    }
+#else
+    (void) sp;
+    TABSIZE = my_tabsize;
+#endif
+    T(("TABSIZE = %d", my_tabsize));
+#else /* !USE_TERM_DRIVER */
     TERMINAL *termp = cur_term;
     int my_tabsize;
 
     /* figure out the size of the screen */
     T(("screen size: terminfo lines = %d columns = %d", lines, columns));
 
-    if (!_nc_prescreen.use_env) {
-	*linep = (int) lines;
-	*colp = (int) columns;
-    } else {			/* usually want to query LINES and COLUMNS from environment */
+    *linep = (int) lines;
+    *colp = (int) columns;
+
+    if (_nc_prescreen.use_env || _nc_prescreen.use_tioctl) {
 	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];
+	    *linep = ((sp != 0 && sp->_filtered)
+		      ? 1
+		      : 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;
+	/* try asking the OS */
+	if (NC_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 = (sp != 0 && sp->_filtered) ? 1 : WINSIZE_ROWS(size);
-		if (*colp <= 0)
+	    errno = 0;
+	    do {
+		if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) >= 0) {
+		    *linep = ((sp != 0 && sp->_filtered)
+			      ? 1
+			      : WINSIZE_ROWS(size));
 		    *colp = WINSIZE_COLS(size);
-	    }
-	    /* FALLTHRU */
-	  failure:;
+		    T(("SYS screen size: environment LINES = %d COLUMNS = %d",
+		       *linep, *colp));
+		    break;
+		}
+	    } while
+		(errno == EINTR);
 	}
 #endif /* HAVE_SIZECHANGE */
 
+	if (_nc_prescreen.use_env) {
+	    if (_nc_prescreen.use_tioctl) {
+		/*
+		 * If environment variables are used, update them.
+		 */
+		if ((sp == 0 || !sp->_filtered) && _nc_getenv_num("LINES") > 0) {
+		    _nc_setenv_num("LINES", *linep);
+		}
+		if (_nc_getenv_num("COLUMNS") > 0) {
+		    _nc_setenv_num("COLUMNS", *colp);
+		}
+	    }
+
+	    /*
+	     * Finally, look for environment variables.
+	     *
+	     * Solaris lets users override either dimension with an environment
+	     * variable.
+	     */
+	    if ((value = _nc_getenv_num("LINES")) > 0) {
+		*linep = value;
+		T(("screen size: environment LINES = %d", *linep));
+	    }
+	    if ((value = _nc_getenv_num("COLUMNS")) > 0) {
+		*colp = value;
+		T(("screen size: environment COLUMNS = %d", *colp));
+	    }
+	}
+
 	/* if we can't get dynamic info about the size, use static */
 	if (*linep <= 0) {
 	    *linep = (int) lines;
@@ -298,29 +407,43 @@
     TABSIZE = my_tabsize;
 #endif
     T(("TABSIZE = %d", TABSIZE));
+#endif /* USE_TERM_DRIVER */
 }
 
 #if USE_SIZECHANGE
 NCURSES_EXPORT(void)
 _nc_update_screensize(SCREEN *sp)
 {
-    TERMINAL *termp = cur_term;
-    int old_lines = lines;
     int new_lines;
-    int old_cols = columns;
     int new_cols;
 
-    _nc_get_screensize(sp, &new_lines, &new_cols);
+#ifdef USE_TERM_DRIVER
+    int old_lines;
+    int old_cols;
+
+    assert(sp != 0);
+
+    CallDriver_2(sp, td_getsize, &old_lines, &old_cols);
+
+#else
+    TERMINAL *termp = cur_term;
+    int old_lines = lines;
+    int old_cols = columns;
+#endif
+
+    TINFO_GET_SIZE(sp, sp->_term, &new_lines, &new_cols);
 
     /*
      * See is_term_resized() and resizeterm().
      * We're doing it this way because those functions belong to the upper
      * ncurses library, while this resides in the lower terminfo library.
      */
-    if (sp != 0
-	&& sp->_resize != 0) {
-	if ((new_lines != old_lines) || (new_cols != old_cols))
-	    sp->_resize(new_lines, new_cols);
+    if (sp != 0 && sp->_resize != 0) {
+	if ((new_lines != old_lines) || (new_cols != old_cols)) {
+	    sp->_resize(NCURSES_SP_ARGx new_lines, new_cols);
+	} else if (sp->_sig_winch && (sp->_ungetch != 0)) {
+	    sp->_ungetch(SP_PARM, KEY_RESIZE);	/* so application can know this */
+	}
 	sp->_sig_winch = FALSE;
     }
 }
@@ -332,29 +455,13 @@
  *
  ****************************************************************************/
 
-#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 || USE_TERMCAP
+#if NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP
 /*
  * Return 1 if entry found, 0 if not found, -1 if database not accessible,
  * just like tgetent().
  */
-static int
-grab_entry(const char *const tn, TERMTYPE *const tp)
+int
+_nc_setup_tinfo(const char *const tn, TERMTYPE *const tp)
 {
     char filename[PATH_MAX];
     int status = _nc_read_entry(tn, filename, tp);
@@ -381,28 +488,27 @@
 #endif
 
 /*
-**	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(TERMINAL * termp)
+void
+_nc_tinfo_cmdch(TERMINAL * termp, int proto)
 {
     unsigned i;
     char CC;
-    char proto;
     char *tmp;
 
-    if ((tmp = getenv("CC")) != 0) {
-	if ((CC = *tmp) != 0) {
-	    proto = *command_character;
-
-	    for_each_string(i, &(termp->type)) {
-		for (tmp = termp->type.Strings[i]; *tmp; tmp++) {
-		    if (*tmp == proto)
-			*tmp = CC;
-		}
+    /*
+     * Only use the character if the string is a single character,
+     * since it is fairly common for developers to set the C compiler
+     * name as an environment variable - using the same symbol.
+     */
+    if ((tmp = getenv("CC")) != 0 && strlen(tmp) == 1) {
+	CC = *tmp;
+	for_each_string(i, &(termp->type)) {
+	    for (tmp = termp->type.Strings[i]; tmp && *tmp; tmp++) {
+		if (UChar(*tmp) == proto)
+		    *tmp = CC;
 	    }
 	}
     }
@@ -439,7 +545,9 @@
 _nc_unicode_locale(void)
 {
     int result = 0;
-#if HAVE_LANGINFO_CODESET
+#if defined(__MINGW32__) && USE_WIDEC_SUPPORT
+    result = 1;
+#elif HAVE_LANGINFO_CODESET
     char *env = nl_langinfo(CODESET);
     result = !strcmp(env, "UTF-8");
     T(("_nc_unicode_locale(%s) ->%d", env, result));
@@ -465,44 +573,74 @@
 NCURSES_EXPORT(int)
 _nc_locale_breaks_acs(TERMINAL * termp)
 {
-    char *env;
+    const char *env_name = "NCURSES_NO_UTF8_ACS";
+    const char *env;
+    int value;
+    int result = 0;
 
-    if ((env = getenv("NCURSES_NO_UTF8_ACS")) != 0) {
-	return atoi(env);
+    T((T_CALLED("_nc_locale_breaks_acs:%d"), result));
+    if (getenv(env_name) != 0) {
+	result = _nc_getenv_num(env_name);
+    } else if ((value = tigetnum("U8")) >= 0) {
+	result = value;		/* use extension feature */
     } else if ((env = getenv("TERM")) != 0) {
-	if (strstr(env, "linux"))
-	    return 1;		/* always broken */
-	if (strstr(env, "screen") != 0
-	    && ((env = getenv("TERMCAP")) != 0
-		&& strstr(env, "screen") != 0)
-	    && strstr(env, "hhII00") != 0) {
+	if (strstr(env, "linux")) {
+	    result = 1;		/* always broken */
+	} else if (strstr(env, "screen") != 0
+		   && ((env = getenv("TERMCAP")) != 0
+		       && strstr(env, "screen") != 0)
+		   && strstr(env, "hhII00") != 0) {
 	    if (CONTROL_N(enter_alt_charset_mode) ||
 		CONTROL_O(enter_alt_charset_mode) ||
 		CONTROL_N(set_attributes) ||
-		CONTROL_O(set_attributes))
-		return 1;
+		CONTROL_O(set_attributes)) {
+		result = 1;
+	    }
 	}
     }
-    return 0;
+    returnCode(result);
 }
 
-/*
- * This entrypoint is called from tgetent() to allow a special case of reusing
- * the same TERMINAL data (see comment).
- */
 NCURSES_EXPORT(int)
-_nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse)
+TINFO_SETUP_TERM(TERMINAL ** tp,
+		 NCURSES_CONST char *tname,
+		 int Filedes,
+		 int *errret,
+		 int reuse)
 {
-    TERMINAL *termp;
+#ifdef USE_TERM_DRIVER
+    TERMINAL_CONTROL_BLOCK *TCB = 0;
+#else
     int status;
+#endif
+    TERMINAL *termp;
+    SCREEN *sp = 0;
+    int code = ERR;
 
     START_TRACE();
-    T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret));
+
+#ifdef USE_TERM_DRIVER
+    T((T_CALLED("_nc_setupterm_ex(%p,%s,%d,%p)"),
+       (void *) tp, _nc_visbuf(tname), Filedes, (void *) errret));
+
+    if (tp == 0) {
+	ret_error0(TGETENT_ERR,
+		   "Invalid parameter, internal error.\n");
+    } else
+	termp = *tp;
+#else
+    termp = cur_term;
+    T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, (void *) errret));
+#endif
 
     if (tname == 0) {
 	tname = getenv("TERM");
 	if (tname == 0 || *tname == '\0') {
+#ifdef USE_TERM_DRIVER
+	    tname = "unknown";
+#else
 	    ret_error0(TGETENT_ERR, "TERM environment variable not set.\n");
+#endif
 	}
     }
 
@@ -518,7 +656,7 @@
      * 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))
+    if (Filedes == STDOUT_FILENO && !NC_ISATTY(Filedes))
 	Filedes = STDERR_FILENO;
 
     /*
@@ -538,22 +676,42 @@
      * properly with this feature).
      */
     if (reuse
-	&& (termp = cur_term) != 0
+	&& (termp != 0)
 	&& termp->Filedes == Filedes
 	&& termp->_termname != 0
 	&& !strcmp(termp->_termname, tname)
 	&& _nc_name_match(termp->type.term_names, tname, "|")) {
 	T(("reusing existing terminal information and mode-settings"));
+	code = OK;
+#ifdef USE_TERM_DRIVER
+	TCB = (TERMINAL_CONTROL_BLOCK *) termp;
+#endif
     } else {
-
+#ifdef USE_TERM_DRIVER
+	TERMINAL_CONTROL_BLOCK *my_tcb;
+	my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1);
+	termp = &(my_tcb->term);
+#else
 	termp = typeCalloc(TERMINAL, 1);
-
+#endif
 	if (termp == 0) {
 	    ret_error0(TGETENT_ERR,
 		       "Not enough memory to create terminal structure.\n");
 	}
-#if USE_DATABASE || USE_TERMCAP
-	status = grab_entry(tname, &termp->type);
+#ifdef USE_TERM_DRIVER
+	INIT_TERM_DRIVER();
+	TCB = (TERMINAL_CONTROL_BLOCK *) termp;
+	code = _nc_globals.term_driver(TCB, tname, errret);
+	if (code == OK) {
+	    termp->Filedes = (short) Filedes;
+	    termp->_termname = strdup(tname);
+	} else {
+	    ret_error0(errret ? *errret : TGETENT_ERR,
+		       "Could not find any driver to handle this terminal.\n");
+	}
+#else
+#if NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP
+	status = _nc_setup_tinfo(tname, &termp->type);
 #else
 	status = TGETENT_NO;
 #endif
@@ -563,7 +721,7 @@
 	    const TERMTYPE *fallback = _nc_fallback(tname);
 
 	    if (fallback) {
-		termp->type = *fallback;
+		_nc_copy_termtype(&(termp->type), fallback);
 		status = TGETENT_YES;
 	    }
 	}
@@ -573,21 +731,21 @@
 	    if (status == TGETENT_ERR) {
 		ret_error0(status, "terminals database is inaccessible\n");
 	    } else if (status == TGETENT_NO) {
-		ret_error(status, "'%s': unknown terminal type.\n", tname);
+		ret_error1(status, "unknown terminal type.\n", tname);
 	    }
 	}
 #if !USE_REENTRANT
-	strncpy(ttytype, termp->type.term_names, NAMESIZE - 1);
+	strncpy(ttytype, termp->type.term_names, (size_t) (NAMESIZE - 1));
 	ttytype[NAMESIZE - 1] = '\0';
 #endif
 
-	termp->Filedes = Filedes;
+	termp->Filedes = (short) Filedes;
 	termp->_termname = strdup(tname);
 
 	set_curterm(termp);
 
-	if (command_character && getenv("CC"))
-	    do_prototype(termp);
+	if (command_character)
+	    _nc_tinfo_cmdch(termp, UChar(*command_character));
 
 	/*
 	 * If an application calls setupterm() rather than initscr() or
@@ -595,29 +753,109 @@
 	 * _nc_setupscreen().  Do it now anyway, so we can initialize the
 	 * baudrate.
 	 */
-	if (isatty(Filedes)) {
+	if (NC_ISATTY(Filedes)) {
 	    def_prog_mode();
 	    baudrate();
 	}
+	code = OK;
+#endif
     }
 
+#ifdef USE_TERM_DRIVER
+    *tp = termp;
+    NCURSES_SP_NAME(set_curterm) (sp, termp);
+    TCB->drv->td_init(TCB);
+#else
+    sp = SP;
+#endif
+
     /*
      * We should always check the screensize, just in case.
      */
-    _nc_get_screensize(SP, ptrLines(), ptrCols());
+    TINFO_GET_SIZE(sp, termp, ptrLines(sp), ptrCols(sp));
 
     if (errret)
 	*errret = TGETENT_YES;
 
+#ifndef USE_TERM_DRIVER
     if (generic_type) {
-	ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname);
+	/*
+	 * BSD 4.3's termcap contains mis-typed "gn" for wy99.  Do a sanity
+	 * check before giving up.
+	 */
+	if ((VALID_STRING(cursor_address)
+	     || (VALID_STRING(cursor_down) && VALID_STRING(cursor_home)))
+	    && VALID_STRING(clear_screen)) {
+	    ret_error1(TGETENT_YES, "terminal is not really generic.\n", tname);
+	} else {
+	    del_curterm(termp);
+	    ret_error1(TGETENT_NO, "I need something more specific.\n", tname);
+	}
+    } else if (hard_copy) {
+	ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname);
     }
-    if (hard_copy) {
-	ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname);
-    }
-    returnCode(OK);
+#endif
+    returnCode(code);
 }
 
+#if NCURSES_SP_FUNCS
+/*
+ * In case of handling multiple screens, we need to have a screen before
+ * initialization in setupscreen takes place.  This is to extend the substitute
+ * for some of the stuff in _nc_prescreen, especially for slk and ripoff
+ * handling which should be done per screen.
+ */
+NCURSES_EXPORT(SCREEN *)
+new_prescr(void)
+{
+    static SCREEN *sp;
+
+    START_TRACE();
+    T((T_CALLED("new_prescr()")));
+
+    if (sp == 0) {
+	sp = _nc_alloc_screen_sp();
+	if (sp != 0) {
+	    sp->rsp = sp->rippedoff;
+	    sp->_filtered = _nc_prescreen.filter_mode;
+	    sp->_use_env = _nc_prescreen.use_env;
+#if NCURSES_NO_PADDING
+	    sp->_no_padding = _nc_prescreen._no_padding;
+#endif
+	    sp->slk_format = 0;
+	    sp->_slk = 0;
+	    sp->_prescreen = TRUE;
+	    SP_PRE_INIT(sp);
+#if USE_REENTRANT
+	    sp->_TABSIZE = _nc_prescreen._TABSIZE;
+	    sp->_ESCDELAY = _nc_prescreen._ESCDELAY;
+#endif
+	}
+    }
+    returnSP(sp);
+}
+#endif
+
+#ifdef USE_TERM_DRIVER
+/*
+ * This entrypoint is called from tgetent() to allow a special case of reusing
+ * the same TERMINAL data (see comment).
+ */
+NCURSES_EXPORT(int)
+_nc_setupterm(NCURSES_CONST char *tname,
+	      int Filedes,
+	      int *errret,
+	      int reuse)
+{
+    int res;
+    TERMINAL *termp = 0;
+    res = TINFO_SETUP_TERM(&termp, tname, Filedes, errret, reuse);
+    if (ERR != res)
+	NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN_PRE, termp);
+    return res;
+}
+#endif
+
 /*
  *	setupterm(termname, Filedes, errret)
  *
@@ -627,5 +865,6 @@
 NCURSES_EXPORT(int)
 setupterm(NCURSES_CONST char *tname, int Filedes, int *errret)
 {
+    START_TRACE();
     return _nc_setupterm(tname, Filedes, errret, FALSE);
 }
diff --git a/ncurses/tinfo/lib_termcap.c b/ncurses/tinfo/lib_termcap.c
index 2d245ff..fdfc494 100644
--- a/ncurses/tinfo/lib_termcap.c
+++ b/ncurses/tinfo/lib_termcap.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -30,6 +30,7 @@
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                                                 *
  *                                                                          *
  * some of the code in here was contributed by:                             *
  * Magnus Bengtsson, d6mbeng@dtek.chalmers.se (Nov'93)                      *
@@ -43,9 +44,11 @@
 #include <tic.h>
 #include <ctype.h>
 
-#include <term_entry.h>
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
 
-MODULE_ID("$Id: lib_termcap.c,v 1.63 2008/08/16 19:22:55 tom Exp $")
+MODULE_ID("$Id: lib_termcap.c,v 1.80 2013/06/08 16:48:47 tom Exp $")
 
 NCURSES_EXPORT_VAR(char *) UP = 0;
 NCURSES_EXPORT_VAR(char *) BC = 0;
@@ -60,6 +63,15 @@
 #define LAST_USE MyCache[CacheInx].last_used
 #define LAST_SEQ MyCache[CacheInx].sequence
 
+/*
+ * Termcap names are matched only using the first two bytes.
+ * Ignore any extended names longer than two bytes, to avoid problems
+ * with legacy code which passes in parameters whose use is long forgotten.
+ */
+#define ValidCap(cap) (((cap)[0] != '\0') && ((cap)[1] != '\0'))
+#define SameCap(a,b)  (((a)[0] == (b)[0]) && ((a)[1] == (b)[1]))
+#define ValidExt(ext) (ValidCap(ext) && (ext)[2] == '\0')
+
 /***************************************************************************
  *
  * tgetent(bufp, term)
@@ -76,16 +88,26 @@
  ***************************************************************************/
 
 NCURSES_EXPORT(int)
-tgetent(char *bufp, const char *name)
+NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
 {
-    int errcode;
+    int rc = ERR;
     int n;
     bool found_cache = FALSE;
+#ifdef USE_TERM_DRIVER
+    TERMINAL *termp = 0;
+#endif
 
     START_TRACE();
     T((T_CALLED("tgetent()")));
 
-    _nc_setupterm((NCURSES_CONST char *) name, STDOUT_FILENO, &errcode, TRUE);
+    TINFO_SETUP_TERM(&termp, (NCURSES_CONST char *) name,
+		     STDOUT_FILENO, &rc, TRUE);
+
+#ifdef USE_TERM_DRIVER
+    if (termp == 0 ||
+	!((TERMINAL_CONTROL_BLOCK *) termp)->drv->isTerminfo)
+	returnCode(rc);
+#endif
 
     /*
      * In general we cannot tell if the fixed sgr0 is still used by the
@@ -109,9 +131,9 @@
 	    /*
 	     * Also free the terminfo data that we loaded (much bigger leak).
 	     */
-	    if (LAST_TRM != 0 && LAST_TRM != cur_term) {
+	    if (LAST_TRM != 0 && LAST_TRM != TerminalOf(SP_PARM)) {
 		TERMINAL *trm = LAST_TRM;
-		del_curterm(LAST_TRM);
+		NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx LAST_TRM);
 		for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx)
 		    if (LAST_TRM == trm)
 			LAST_TRM = 0;
@@ -131,7 +153,7 @@
 	}
 	CacheInx = best;
     }
-    LAST_TRM = cur_term;
+    LAST_TRM = TerminalOf(SP_PARM);
     LAST_SEQ = ++CacheSeq;
 
     PC = 0;
@@ -139,7 +161,7 @@
     BC = 0;
     FIX_SGR0 = 0;		/* don't free it - application may still use */
 
-    if (errcode == 1) {
+    if (rc == 1) {
 
 	if (cursor_left)
 	    if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
@@ -153,7 +175,7 @@
 	if (backspace_if_not_bs != NULL)
 	    BC = backspace_if_not_bs;
 
-	if ((FIX_SGR0 = _nc_trim_sgr0(&(cur_term->type))) != 0) {
+	if ((FIX_SGR0 = _nc_trim_sgr0(&(TerminalOf(SP_PARM)->type))) != 0) {
 	    if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
 		if (FIX_SGR0 != exit_attribute_mode) {
 		    free(FIX_SGR0);
@@ -164,8 +186,8 @@
 	LAST_BUF = bufp;
 	LAST_USE = TRUE;
 
-	SetNoPadding(SP);
-	(void) baudrate();	/* sets ospeed as a side-effect */
+	SetNoPadding(SP_PARM);
+	(void) NCURSES_SP_NAME(baudrate) (NCURSES_SP_ARG);	/* sets ospeed as a side-effect */
 
 /* LINT_PREPRO
 #if 0*/
@@ -174,9 +196,30 @@
 #endif*/
 
     }
-    returnCode(errcode);
+    returnCode(rc);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+tgetent(char *bufp, const char *name)
+{
+    return NCURSES_SP_NAME(tgetent) (CURRENT_SCREEN, bufp, name);
+}
+#endif
+
+#if 0
+static bool
+same_tcname(const char *a, const char *b)
+{
+    bool code = SameCap(a, b);
+    fprintf(stderr, "compare(%s,%s) %s\n", a, b, code ? "same" : "diff");
+    return code;
+}
+
+#else
+#define same_tcname(a,b) SameCap(a,b)
+#endif
+
 /***************************************************************************
  *
  * tgetflag(str)
@@ -187,24 +230,48 @@
  ***************************************************************************/
 
 NCURSES_EXPORT(int)
-tgetflag(NCURSES_CONST char *id)
+NCURSES_SP_NAME(tgetflag) (NCURSES_SP_DCLx NCURSES_CONST char *id)
 {
-    unsigned i;
+    int result = 0;		/* Solaris returns zero for missing flag */
+    int j = -1;
 
-    T((T_CALLED("tgetflag(%s)"), id));
-    if (cur_term != 0) {
-	TERMTYPE *tp = &(cur_term->type);
-	for_each_boolean(i, tp) {
-	    const char *capname = ExtBoolname(tp, i, boolcodes);
-	    if (!strncmp(id, capname, 2)) {
-		/* setupterm forces invalid booleans to false */
-		returnCode(tp->Booleans[i]);
+    T((T_CALLED("tgetflag(%p, %s)"), (void *) SP_PARM, id));
+    if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
+	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+	struct name_table_entry const *entry_ptr;
+
+	entry_ptr = _nc_find_type_entry(id, BOOLEAN, TRUE);
+	if (entry_ptr != 0) {
+	    j = entry_ptr->nte_index;
+	}
+#if NCURSES_XNAMES
+	else {
+	    int i;
+	    for_each_ext_boolean(i, tp) {
+		const char *capname = ExtBoolname(tp, i, boolcodes);
+		if (same_tcname(id, capname) && ValidExt(capname)) {
+		    j = i;
+		    break;
+		}
 	    }
 	}
+#endif
+	if (j >= 0) {
+	    /* note: setupterm forces invalid booleans to false */
+	    result = tp->Booleans[j];
+	}
     }
-    returnCode(0);		/* Solaris does this */
+    returnCode(result);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+tgetflag(NCURSES_CONST char *id)
+{
+    return NCURSES_SP_NAME(tgetflag) (CURRENT_SCREEN, id);
+}
+#endif
+
 /***************************************************************************
  *
  * tgetnum(str)
@@ -215,25 +282,48 @@
  ***************************************************************************/
 
 NCURSES_EXPORT(int)
-tgetnum(NCURSES_CONST char *id)
+NCURSES_SP_NAME(tgetnum) (NCURSES_SP_DCLx NCURSES_CONST char *id)
 {
-    unsigned i;
+    int result = ABSENT_NUMERIC;
+    int j = -1;
 
-    T((T_CALLED("tgetnum(%s)"), id));
-    if (cur_term != 0) {
-	TERMTYPE *tp = &(cur_term->type);
-	for_each_number(i, tp) {
-	    const char *capname = ExtNumname(tp, i, numcodes);
-	    if (!strncmp(id, capname, 2)) {
-		if (!VALID_NUMERIC(tp->Numbers[i]))
-		    returnCode(ABSENT_NUMERIC);
-		returnCode(tp->Numbers[i]);
+    T((T_CALLED("tgetnum(%p, %s)"), (void *) SP_PARM, id));
+    if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
+	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+	struct name_table_entry const *entry_ptr;
+
+	entry_ptr = _nc_find_type_entry(id, NUMBER, TRUE);
+	if (entry_ptr != 0) {
+	    j = entry_ptr->nte_index;
+	}
+#if NCURSES_XNAMES
+	else {
+	    int i;
+	    for_each_ext_number(i, tp) {
+		const char *capname = ExtNumname(tp, i, numcodes);
+		if (same_tcname(id, capname) && ValidExt(capname)) {
+		    j = i;
+		    break;
+		}
 	    }
 	}
+#endif
+	if (j >= 0) {
+	    if (VALID_NUMERIC(tp->Numbers[j]))
+		result = tp->Numbers[j];
+	}
     }
-    returnCode(ABSENT_NUMERIC);
+    returnCode(result);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+tgetnum(NCURSES_CONST char *id)
+{
+    return NCURSES_SP_NAME(tgetnum) (CURRENT_SCREEN, id);
+}
+#endif
+
 /***************************************************************************
  *
  * tgetstr(str, area)
@@ -244,40 +334,62 @@
  ***************************************************************************/
 
 NCURSES_EXPORT(char *)
-tgetstr(NCURSES_CONST char *id, char **area)
+NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx NCURSES_CONST char *id, char **area)
 {
-    unsigned i;
     char *result = NULL;
+    int j = -1;
 
-    T((T_CALLED("tgetstr(%s,%p)"), id, area));
-    if (cur_term != 0) {
-	TERMTYPE *tp = &(cur_term->type);
-	for_each_string(i, tp) {
-	    const char *capname = ExtStrname(tp, i, strcodes);
-	    if (!strncmp(id, capname, 2)) {
-		result = tp->Strings[i];
-		TR(TRACE_DATABASE, ("found match : %s", _nc_visbuf(result)));
-		/* setupterm forces canceled strings to null */
-		if (VALID_STRING(result)) {
-		    if (result == exit_attribute_mode
-			&& FIX_SGR0 != 0) {
-			result = FIX_SGR0;
-			TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result)));
-		    }
-		    if (area != 0
-			&& *area != 0) {
-			(void) strcpy(*area, result);
-			result = *area;
-			*area += strlen(*area) + 1;
-		    }
+    T((T_CALLED("tgetstr(%s,%p)"), id, (void *) area));
+    if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
+	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+	struct name_table_entry const *entry_ptr;
+
+	entry_ptr = _nc_find_type_entry(id, STRING, TRUE);
+	if (entry_ptr != 0) {
+	    j = entry_ptr->nte_index;
+	}
+#if NCURSES_XNAMES
+	else {
+	    int i;
+	    for_each_ext_string(i, tp) {
+		const char *capname = ExtStrname(tp, i, strcodes);
+		if (same_tcname(id, capname) && ValidExt(capname)) {
+		    j = i;
+		    break;
 		}
-		break;
+	    }
+	}
+#endif
+	if (j >= 0) {
+	    result = tp->Strings[j];
+	    TR(TRACE_DATABASE, ("found match %d: %s", j, _nc_visbuf(result)));
+	    /* setupterm forces canceled strings to null */
+	    if (VALID_STRING(result)) {
+		if (result == exit_attribute_mode
+		    && FIX_SGR0 != 0) {
+		    result = FIX_SGR0;
+		    TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result)));
+		}
+		if (area != 0
+		    && *area != 0) {
+		    _nc_STRCPY(*area, result, 1024);
+		    result = *area;
+		    *area += strlen(*area) + 1;
+		}
 	    }
 	}
     }
     returnPtr(result);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(char *)
+tgetstr(NCURSES_CONST char *id, char **area)
+{
+    return NCURSES_SP_NAME(tgetstr) (CURRENT_SCREEN, id, area);
+}
+#endif
+
 #if NO_LEAKS
 NCURSES_EXPORT(void)
 _nc_tgetent_leaks(void)
diff --git a/ncurses/tinfo/lib_termname.c b/ncurses/tinfo/lib_termname.c
index 713d0be..e3f6827 100644
--- a/ncurses/tinfo/lib_termname.c
+++ b/ncurses/tinfo/lib_termname.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2001,2003 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2003,2009 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            *
@@ -28,17 +28,31 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_termname.c,v 1.8 2003/12/27 18:23:01 tom Exp $")
+MODULE_ID("$Id: lib_termname.c,v 1.12 2009/10/24 21:56:58 tom Exp $")
 
 NCURSES_EXPORT(char *)
-termname(void)
+NCURSES_SP_NAME(termname) (NCURSES_SP_DCL0)
 {
     char *name = 0;
 
-    T((T_CALLED("termname()")));
+    T((T_CALLED("termname(%p)"), (void *) SP_PARM));
 
+#if NCURSES_SP_FUNCS
+    if (TerminalOf(SP_PARM) != 0) {
+	name = TerminalOf(SP_PARM)->_termname;
+    }
+#else
     if (cur_term != 0)
 	name = cur_term->_termname;
+#endif
 
     returnPtr(name);
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(char *)
+termname(void)
+{
+    return NCURSES_SP_NAME(termname) (CURRENT_SCREEN);
+}
+#endif
diff --git a/ncurses/tinfo/lib_tgoto.c b/ncurses/tinfo/lib_tgoto.c
index e07f464..31daf44 100644
--- a/ncurses/tinfo/lib_tgoto.c
+++ b/ncurses/tinfo/lib_tgoto.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2000-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 2000-2008,2012 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            *
@@ -35,7 +35,7 @@
 #include <ctype.h>
 #include <termcap.h>
 
-MODULE_ID("$Id: lib_tgoto.c,v 1.13 2008/08/16 19:29:32 tom Exp $")
+MODULE_ID("$Id: lib_tgoto.c,v 1.16 2012/02/24 02:08:08 tom Exp $")
 
 #if !PURE_TERMINFO
 static bool
@@ -159,7 +159,8 @@
 		break;
 	    }
 	    if (fmt != 0) {
-		sprintf(result + used, fmt, *value++);
+		_nc_SPRINTF(result + used, _nc_SLIMIT(length - used)
+			    fmt, *value++);
 		used += strlen(result + used);
 		fmt = 0;
 	    }
@@ -174,7 +175,7 @@
     }
     if (result != 0) {
 	if (need_BC) {
-	    strcpy(result + used, BC);
+	    _nc_STRCPY(result + used, BC, length - used);
 	    used += strlen(BC);
 	}
 	result[used] = '\0';
diff --git a/ncurses/tinfo/lib_ti.c b/ncurses/tinfo/lib_ti.c
index df460f9..e9ae746 100644
--- a/ncurses/tinfo/lib_ti.c
+++ b/ncurses/tinfo/lib_ti.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2000,2003 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2010,2013 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            *
@@ -29,75 +29,159 @@
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ *     and: Thomas E. Dickey                        1996-on                 *
  ****************************************************************************/
 
 #include <curses.priv.h>
 
-#include <term_entry.h>
 #include <tic.h>
 
-MODULE_ID("$Id: lib_ti.c,v 1.23 2003/05/24 21:10:28 tom Exp $")
+MODULE_ID("$Id: lib_ti.c,v 1.30 2013/06/08 16:55:05 tom Exp $")
 
+#if 0
+static bool
+same_name(const char *a, const char *b)
+{
+    fprintf(stderr, "compare(%s,%s)\n", a, b);
+    return !strcmp(a, b);
+}
+#else
+#define same_name(a,b) !strcmp(a,b)
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(tigetflag) (NCURSES_SP_DCLx NCURSES_CONST char *str)
+{
+    int result = ABSENT_BOOLEAN;
+    int j = -1;
+
+    T((T_CALLED("tigetflag(%p, %s)"), (void *) SP_PARM, str));
+
+    if (HasTInfoTerminal(SP_PARM)) {
+	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+	struct name_table_entry const *entry_ptr;
+
+	entry_ptr = _nc_find_type_entry(str, BOOLEAN, FALSE);
+	if (entry_ptr != 0) {
+	    j = entry_ptr->nte_index;
+	}
+#if NCURSES_XNAMES
+	else {
+	    int i;
+	    for_each_ext_boolean(i, tp) {
+		const char *capname = ExtBoolname(tp, i, boolnames);
+		if (same_name(str, capname)) {
+		    j = i;
+		    break;
+		}
+	    }
+	}
+#endif
+	if (j >= 0) {
+	    /* note: setupterm forces invalid booleans to false */
+	    result = tp->Booleans[j];
+	}
+    }
+
+    returnCode(result);
+}
+
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 tigetflag(NCURSES_CONST char *str)
 {
-    unsigned i;
+    return NCURSES_SP_NAME(tigetflag) (CURRENT_SCREEN, str);
+}
+#endif
 
-    T((T_CALLED("tigetflag(%s)"), str));
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(tigetnum) (NCURSES_SP_DCLx NCURSES_CONST char *str)
+{
+    int j = -1;
+    int result = CANCELLED_NUMERIC;	/* Solaris returns a -1 on error */
 
-    if (cur_term != 0) {
-	TERMTYPE *tp = &(cur_term->type);
-	for_each_boolean(i, tp) {
-	    const char *capname = ExtBoolname(tp, i, boolnames);
-	    if (!strcmp(str, capname)) {
-		/* setupterm forces invalid booleans to false */
-		returnCode(tp->Booleans[i]);
+    T((T_CALLED("tigetnum(%p, %s)"), (void *) SP_PARM, str));
+
+    if (HasTInfoTerminal(SP_PARM)) {
+	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+	struct name_table_entry const *entry_ptr;
+
+	entry_ptr = _nc_find_type_entry(str, NUMBER, FALSE);
+	if (entry_ptr != 0) {
+	    j = entry_ptr->nte_index;
+	}
+#if NCURSES_XNAMES
+	else {
+	    int i;
+	    for_each_ext_number(i, tp) {
+		const char *capname = ExtNumname(tp, i, numnames);
+		if (same_name(str, capname)) {
+		    j = i;
+		    break;
+		}
 	    }
 	}
+#endif
+	if (j >= 0) {
+	    if (VALID_NUMERIC(tp->Numbers[j]))
+		result = tp->Numbers[j];
+	    else
+		result = ABSENT_NUMERIC;
+	}
     }
 
-    returnCode(ABSENT_BOOLEAN);
+    returnCode(result);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 tigetnum(NCURSES_CONST char *str)
 {
-    unsigned i;
+    return NCURSES_SP_NAME(tigetnum) (CURRENT_SCREEN, str);
+}
+#endif
 
-    T((T_CALLED("tigetnum(%s)"), str));
+NCURSES_EXPORT(char *)
+NCURSES_SP_NAME(tigetstr) (NCURSES_SP_DCLx NCURSES_CONST char *str)
+{
+    char *result = CANCELLED_STRING;
+    int j = -1;
 
-    if (cur_term != 0) {
-	TERMTYPE *tp = &(cur_term->type);
-	for_each_number(i, tp) {
-	    const char *capname = ExtNumname(tp, i, numnames);
-	    if (!strcmp(str, capname)) {
-		if (!VALID_NUMERIC(tp->Numbers[i]))
-		    returnCode(ABSENT_NUMERIC);
-		returnCode(tp->Numbers[i]);
+    T((T_CALLED("tigetstr(%p, %s)"), (void *) SP_PARM, str));
+
+    if (HasTInfoTerminal(SP_PARM)) {
+	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+	struct name_table_entry const *entry_ptr;
+
+	entry_ptr = _nc_find_type_entry(str, STRING, FALSE);
+	if (entry_ptr != 0) {
+	    j = entry_ptr->nte_index;
+	}
+#if NCURSES_XNAMES
+	else {
+	    int i;
+	    for_each_ext_string(i, tp) {
+		const char *capname = ExtStrname(tp, i, strnames);
+		if (same_name(str, capname)) {
+		    j = i;
+		    break;
+		}
 	    }
 	}
+#endif
+	if (j >= 0) {
+	    /* note: setupterm forces cancelled strings to null */
+	    result = tp->Strings[j];
+	}
     }
 
-    returnCode(CANCELLED_NUMERIC);	/* Solaris returns a -1 instead */
+    returnPtr(result);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(char *)
 tigetstr(NCURSES_CONST char *str)
 {
-    unsigned i;
-
-    T((T_CALLED("tigetstr(%s)"), str));
-
-    if (cur_term != 0) {
-	TERMTYPE *tp = &(cur_term->type);
-	for_each_string(i, tp) {
-	    const char *capname = ExtStrname(tp, i, strnames);
-	    if (!strcmp(str, capname)) {
-		/* setupterm forces cancelled strings to null */
-		returnPtr(tp->Strings[i]);
-	    }
-	}
-    }
-
-    returnPtr(CANCELLED_STRING);
+    return NCURSES_SP_NAME(tigetstr) (CURRENT_SCREEN, str);
 }
+#endif
diff --git a/ncurses/tinfo/lib_tparm.c b/ncurses/tinfo/lib_tparm.c
index ba2a840..4f18859 100644
--- a/ncurses/tinfo/lib_tparm.c
+++ b/ncurses/tinfo/lib_tparm.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2014,2015 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            *
@@ -40,10 +40,9 @@
 #include <curses.priv.h>
 
 #include <ctype.h>
-#include <term.h>
 #include <tic.h>
 
-MODULE_ID("$Id: lib_tparm.c,v 1.76 2008/08/16 19:22:55 tom Exp $")
+MODULE_ID("$Id: lib_tparm.c,v 1.94 2015/07/17 01:03:35 tom Exp $")
 
 /*
  *	char *
@@ -54,7 +53,7 @@
  *
  *	     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
+ *	capability, with escapes like %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
@@ -108,6 +107,7 @@
 NCURSES_EXPORT_VAR(int) _nc_tparm_err = 0;
 
 #define TPS(var) _nc_prescreen.tparm_state.var
+#define popcount _nc_popcount	/* workaround for NetBSD 6.0 defect */
 
 #if NO_LEAKS
 NCURSES_EXPORT(void)
@@ -129,9 +129,7 @@
     need += TPS(out_used);
     if (need > TPS(out_size)) {
 	TPS(out_size) = need * 2;
-	TPS(out_buff) = typeRealloc(char, TPS(out_size), TPS(out_buff));
-	if (TPS(out_buff) == 0)
-	    _nc_err_abort(MSG_NO_MEMORY);
+	TYPE_REALLOC(char, TPS(out_size), TPS(out_buff));
     }
 }
 
@@ -140,11 +138,13 @@
 {
     size_t s_len = strlen(s);
     if (len > (int) s_len)
-	s_len = len;
+	s_len = (size_t) len;
 
     get_space(s_len + 1);
 
-    (void) sprintf(TPS(out_buff) + TPS(out_used), fmt, s);
+    _nc_SPRINTF(TPS(out_buff) + TPS(out_used),
+		_nc_SLIMIT(TPS(out_size) - TPS(out_used))
+		fmt, s);
     TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used));
 }
 
@@ -154,9 +154,11 @@
     if (len < 30)
 	len = 30;		/* actually log10(MAX_INT)+1 */
 
-    get_space((unsigned) len + 1);
+    get_space((size_t) len + 1);
 
-    (void) sprintf(TPS(out_buff) + TPS(out_used), fmt, number);
+    _nc_SPRINTF(TPS(out_buff) + TPS(out_used),
+		_nc_SLIMIT(TPS(out_size) - TPS(out_used))
+		fmt, number);
     TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used));
 }
 
@@ -165,7 +167,7 @@
 {
     if (c == 0)
 	c = 0200;
-    get_space(1);
+    get_space((size_t) 1);
     TPS(out_buff)[TPS(out_used)++] = (char) c;
 }
 
@@ -251,6 +253,9 @@
 	    case 'x':		/* FALLTHRU */
 	    case 'X':		/* FALLTHRU */
 	    case 's':
+#ifdef EXP_XTERM_1005
+	    case 'u':
+#endif
 		*format++ = *s;
 		done = TRUE;
 		break;
@@ -370,6 +375,9 @@
 	    case 'x':		/* FALLTHRU */
 	    case 'X':		/* FALLTHRU */
 	    case 'c':		/* FALLTHRU */
+#ifdef EXP_XTERM_1005
+	    case 'u':
+#endif
 		if (lastpop <= 0)
 		    number++;
 		lastpop = -1;
@@ -451,18 +459,21 @@
 }
 
 static NCURSES_INLINE char *
-tparam_internal(const char *string, va_list ap)
+tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
 {
     char *p_is_s[NUM_PARM];
     TPARM_ARG param[NUM_PARM];
-    int popcount;
+    int popcount = 0;
     int number;
+    int num_args;
     int len;
     int level;
     int x, y;
     int i;
     const char *cp = string;
     size_t len2;
+    bool termcap_hack;
+    bool incremented_two;
 
     if (cp == NULL)
 	return NULL;
@@ -479,7 +490,15 @@
     if (TPS(fmt_buff) == 0)
 	return NULL;
 
-    for (i = 0; i < max(popcount, number); i++) {
+    incremented_two = FALSE;
+
+    if (number > NUM_PARM)
+	number = NUM_PARM;
+    if (popcount > NUM_PARM)
+	popcount = NUM_PARM;
+    num_args = max(popcount, number);
+
+    for (i = 0; i < num_args; i++) {
 	/*
 	 * A few caps (such as plab_norm) have string-valued parms.
 	 * We'll have to assume that the caller knows the difference, since
@@ -489,8 +508,11 @@
 	 */
 	if (p_is_s[i] != 0) {
 	    p_is_s[i] = va_arg(ap, char *);
-	} else {
+	    param[i] = 0;
+	} else if (use_TPARM_ARG) {
 	    param[i] = va_arg(ap, TPARM_ARG);
+	} else {
+	    param[i] = (TPARM_ARG) va_arg(ap, int);
 	}
     }
 
@@ -502,22 +524,24 @@
      * style, which means tparam() will expand termcap strings OK.
      */
     TPS(stack_ptr) = 0;
+    termcap_hack = FALSE;
     if (popcount == 0) {
+	termcap_hack = TRUE;
 	popcount = number;
 	for (i = number - 1; i >= 0; i--) {
 	    if (p_is_s[i])
 		spush(p_is_s[i]);
 	    else
-		npush(param[i]);
+		npush((int) param[i]);
 	}
     }
 #ifdef TRACE
     if (USE_TRACEF(TRACE_CALLS)) {
-	for (i = 0; i < popcount; i++) {
+	for (i = 0; i < num_args; i++) {
 	    if (p_is_s[i] != 0)
 		save_text(", %s", _nc_visbuf(p_is_s[i]), 0);
 	    else
-		save_number(", %d", param[i], 0);
+		save_number(", %d", (int) param[i], 0);
 	}
 	_tracef(T_CALLED("%s(%s%s)"), TPS(tname), _nc_visbuf(cp), TPS(out_buff));
 	TPS(out_used) = 0;
@@ -549,8 +573,22 @@
 		save_char(npop());
 		break;
 
+#ifdef EXP_XTERM_1005
+	    case 'u':
+		{
+		    unsigned char target[10];
+		    unsigned source = (unsigned) npop();
+		    int rc = _nc_conv_to_utf8(target, source, (unsigned)
+					      sizeof(target));
+		    int n;
+		    for (n = 0; n < rc; ++n) {
+			save_char(target[n]);
+		    }
+		}
+		break;
+#endif
 	    case 'l':
-		save_number("%d", (int) strlen(spop()), 0);
+		npush((int) strlen(spop()));
 		break;
 
 	    case 's':
@@ -561,10 +599,11 @@
 		cp++;
 		i = (UChar(*cp) - '1');
 		if (i >= 0 && i < NUM_PARM) {
-		    if (p_is_s[i])
+		    if (p_is_s[i]) {
 			spush(p_is_s[i]);
-		    else
-			npush(param[i]);
+		    } else {
+			npush((int) param[i]);
+		    }
 		}
 		break;
 
@@ -633,11 +672,15 @@
 		break;
 
 	    case 'A':
-		npush(npop() && npop());
+		y = npop();
+		x = npop();
+		npush(y && x);
 		break;
 
 	    case 'O':
-		npush(npop() || npop());
+		y = npop();
+		x = npop();
+		npush(y || x);
 		break;
 
 	    case '&':
@@ -679,10 +722,26 @@
 		break;
 
 	    case 'i':
-		if (p_is_s[0] == 0)
-		    param[0]++;
-		if (p_is_s[1] == 0)
-		    param[1]++;
+		/*
+		 * Increment the first two parameters -- if they are numbers
+		 * rather than strings.  As a side effect, assign into the
+		 * stack; if this is termcap, then the stack was populated
+		 * using the termcap hack above rather than via the terminfo
+		 * 'p' case.
+		 */
+		if (!incremented_two) {
+		    incremented_two = TRUE;
+		    if (p_is_s[0] == 0) {
+			param[0]++;
+			if (termcap_hack)
+			    TPS(stack)[0].data.num = (int) param[0];
+		    }
+		    if (p_is_s[1] == 0) {
+			param[1]++;
+			if (termcap_hack)
+			    TPS(stack)[1].data.num = (int) param[1];
+		    }
+		}
 		break;
 
 	    case '?':
@@ -748,7 +807,7 @@
 	cp++;
     }				/* endwhile (*cp) */
 
-    get_space(1);
+    get_space((size_t) 1);
     TPS(out_buff)[TPS(out_used)] = '\0';
 
     T((T_RETURN("%s"), _nc_visbuf(TPS(out_buff))));
@@ -772,7 +831,7 @@
 #ifdef TRACE
     TPS(tname) = "tparm";
 #endif /* TRACE */
-    result = tparam_internal(string, ap);
+    result = tparam_internal(TRUE, string, ap);
     va_end(ap);
     return result;
 }
@@ -793,3 +852,19 @@
     return tparm_varargs(string, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 }
 #endif /* NCURSES_TPARM_VARARGS */
+
+NCURSES_EXPORT(char *)
+tiparm(const char *string,...)
+{
+    va_list ap;
+    char *result;
+
+    _nc_tparm_err = 0;
+    va_start(ap, string);
+#ifdef TRACE
+    TPS(tname) = "tiparm";
+#endif /* TRACE */
+    result = tparam_internal(FALSE, string, ap);
+    va_end(ap);
+    return result;
+}
diff --git a/ncurses/tinfo/lib_tputs.c b/ncurses/tinfo/lib_tputs.c
index a8b7276..09cbbc2 100644
--- a/ncurses/tinfo/lib_tputs.c
+++ b/ncurses/tinfo/lib_tputs.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2013,2015 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            *
@@ -30,6 +30,7 @@
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2009                    *
  ****************************************************************************/
 
 /*
@@ -41,12 +42,16 @@
  */
 
 #include <curses.priv.h>
+
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
+
 #include <ctype.h>
-#include <term.h>		/* padding_baud_rate, xon_xoff */
 #include <termcap.h>		/* ospeed */
 #include <tic.h>
 
-MODULE_ID("$Id: lib_tputs.c,v 1.66 2008/06/28 13:12:15 tom Exp $")
+MODULE_ID("$Id: lib_tputs.c,v 1.96 2015/01/03 23:51:23 tom Exp $")
 
 NCURSES_EXPORT_VAR(char) PC = 0;              /* used by termcap library */
 NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed = 0;        /* used by termcap library */
@@ -69,63 +74,195 @@
 }
 #endif
 
-static int (*my_outch) (int c) = _nc_outch;
+#if NCURSES_SP_FUNCS
+#define SetOutCh(func) if (SP_PARM) SP_PARM->_outch = func; else _nc_prescreen._outch = func
+#define GetOutCh()     (SP_PARM ? SP_PARM->_outch : _nc_prescreen._outch)
+#else
+#define SetOutCh(func) static_outch = func
+#define GetOutCh()     static_outch
+static NCURSES_SP_OUTC static_outch = NCURSES_SP_NAME(_nc_outch);
+#endif
 
 NCURSES_EXPORT(int)
-delay_output(int ms)
+NCURSES_SP_NAME(delay_output) (NCURSES_SP_DCLx int ms)
 {
-    T((T_CALLED("delay_output(%d)"), ms));
+    T((T_CALLED("delay_output(%p,%d)"), (void *) SP_PARM, ms));
+
+    if (!HasTInfoTerminal(SP_PARM))
+	returnCode(ERR);
 
     if (no_pad_char) {
-	_nc_flush();
+	NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
 	napms(ms);
     } else {
+	NCURSES_SP_OUTC my_outch = GetOutCh();
 	register int nullcount;
 
 	nullcount = (ms * _nc_baudrate(ospeed)) / (BAUDBYTE * 1000);
 	for (_nc_nulls_sent += nullcount; nullcount > 0; nullcount--)
-	    my_outch(PC);
-	if (my_outch == _nc_outch)
-	    _nc_flush();
+	    my_outch(NCURSES_SP_ARGx PC);
+	if (my_outch == NCURSES_SP_NAME(_nc_outch))
+	    NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
     }
 
     returnCode(OK);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+delay_output(int ms)
+{
+    return NCURSES_SP_NAME(delay_output) (CURRENT_SCREEN, ms);
+}
+#endif
+
+NCURSES_EXPORT(void)
+NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_DCL0)
+{
+    if (SP_PARM != 0 && SP_PARM->_ofd >= 0) {
+	if (SP_PARM->out_inuse) {
+	    char *buf = SP_PARM->out_buffer;
+	    size_t amount = SP->out_inuse;
+	    ssize_t res;
+
+	    SP->out_inuse = 0;
+	    while (amount) {
+		res = write(SP_PARM->_ofd, buf, amount);
+
+		if (res > 0) {
+		    /* if the write was incomplete, try again */
+		    amount -= (size_t) res;
+		    buf += res;
+		} else if (errno == EAGAIN) {
+		    continue;
+		} else if (errno == EINTR) {
+		    continue;
+		} else {
+		    break;	/* an error we can not recover from */
+		}
+	    }
+	}
+    }
+}
+
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(void)
 _nc_flush(void)
 {
-    (void) fflush(NC_OUTPUT);
+    NCURSES_SP_NAME(_nc_flush) (CURRENT_SCREEN);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(_nc_outch) (NCURSES_SP_DCLx int ch)
+{
+    int rc = OK;
+
+    COUNT_OUTCHARS(1);
+
+    if (HasTInfoTerminal(SP_PARM)
+	&& SP_PARM != 0) {
+	if (SP_PARM->out_buffer != 0) {
+	    if (SP_PARM->out_inuse + 1 >= SP_PARM->out_limit)
+		NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
+	    SP_PARM->out_buffer[SP_PARM->out_inuse++] = (char) ch;
+	} else {
+	    char tmp = (char) ch;
+	    /*
+	     * POSIX says write() is safe in a signal handler, but the
+	     * buffered I/O is not.
+	     */
+	    if (write(fileno(NC_OUTPUT(SP_PARM)), &tmp, (size_t) 1) == -1)
+		rc = ERR;
+	}
+    } else {
+	char tmp = (char) ch;
+	if (write(fileno(stdout), &tmp, (size_t) 1) == -1)
+	    rc = ERR;
+    }
+    return rc;
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 _nc_outch(int ch)
 {
-    COUNT_OUTCHARS(1);
+    return NCURSES_SP_NAME(_nc_outch) (CURRENT_SCREEN, ch);
+}
+#endif
 
-    if (SP != 0
-	&& SP->_cleanup) {
-	char tmp = ch;
-	/*
-	 * POSIX says write() is safe in a signal handler, but the
-	 * buffered I/O is not.
-	 */
-	write(fileno(NC_OUTPUT), &tmp, 1);
-    } else {
-	putc(ch, NC_OUTPUT);
-    }
-    return OK;
+/*
+ * This is used for the putp special case.
+ */
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(_nc_putchar) (NCURSES_SP_DCLx int ch)
+{
+    (void) SP_PARM;
+    return putchar(ch);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+_nc_putchar(int ch)
+{
+    return putchar(ch);
+}
+#endif
+
+/*
+ * putp is special - per documentation it calls tputs with putchar as the
+ * parameter for outputting characters.  This means that it uses stdio, which
+ * is not signal-safe.  Applications call this entrypoint; we do not call it
+ * from within the library.
+ */
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(putp) (NCURSES_SP_DCLx const char *string)
+{
+    return NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
+				   string, 1, NCURSES_SP_NAME(_nc_putchar));
+}
+
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 putp(const char *string)
 {
-    return tputs(string, 1, _nc_outch);
+    return NCURSES_SP_NAME(putp) (CURRENT_SCREEN, string);
+}
+#endif
+
+/*
+ * Use these entrypoints rather than "putp" within the library.
+ */
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_DCLx
+			   const char *name GCC_UNUSED,
+			   const char *string)
+{
+    int rc = ERR;
+
+    if (string != 0) {
+	TPUTS_TRACE(name);
+	rc = NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
+				     string, 1, NCURSES_SP_NAME(_nc_outch));
+    }
+    return rc;
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
-tputs(const char *string, int affcnt, int (*outc) (int))
+_nc_putp(const char *name, const char *string)
 {
+    return NCURSES_SP_NAME(_nc_putp) (CURRENT_SCREEN, name, string);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(tputs) (NCURSES_SP_DCLx
+			const char *string,
+			int affcnt,
+			NCURSES_SP_OUTC outc)
+{
+    NCURSES_SP_OUTC my_outch = GetOutCh();
     bool always_delay;
     bool normal_delay;
     int number;
@@ -137,10 +274,10 @@
     char addrbuf[32];
 
     if (USE_TRACEF(TRACE_TPUTS)) {
-	if (outc == _nc_outch)
-	    (void) strcpy(addrbuf, "_nc_outch");
+	if (outc == NCURSES_SP_NAME(_nc_outch))
+	    _nc_STRCPY(addrbuf, "_nc_outch", sizeof(addrbuf));
 	else
-	    (void) sprintf(addrbuf, "%p", outc);
+	    _nc_SPRINTF(addrbuf, _nc_SLIMIT(sizeof(addrbuf)) "%p", outc);
 	if (_nc_tputs_trace) {
 	    _tracef("tputs(%s = %s, %d, %s) called", _nc_tputs_trace,
 		    _nc_visbuf(string), affcnt, addrbuf);
@@ -152,10 +289,19 @@
     }
 #endif /* TRACE */
 
+    if (SP_PARM != 0 && !HasTInfoTerminal(SP_PARM))
+	return ERR;
+
     if (!VALID_STRING(string))
 	return ERR;
 
-    if (cur_term == 0) {
+    if (
+#if NCURSES_SP_FUNCS
+	   (SP_PARM != 0 && SP_PARM->_term == 0)
+#else
+	   cur_term == 0
+#endif
+	) {
 	always_delay = FALSE;
 	normal_delay = TRUE;
     } else {
@@ -164,7 +310,7 @@
 	    !xon_xoff
 	    && padding_baud_rate
 #if NCURSES_NO_PADDING
-	    && !GetNoPadding(SP)
+	    && !GetNoPadding(SP_PARM)
 #endif
 	    && (_nc_baudrate(ospeed) >= padding_baud_rate);
     }
@@ -198,24 +344,24 @@
     }
 #endif /* BSD_TPUTS */
 
-    my_outch = outc;		/* redirect delay_output() */
+    SetOutCh(outc);		/* redirect delay_output() */
     while (*string) {
 	if (*string != '$')
-	    (*outc) (*string);
+	    (*outc) (NCURSES_SP_ARGx *string);
 	else {
 	    string++;
 	    if (*string != '<') {
-		(*outc) ('$');
+		(*outc) (NCURSES_SP_ARGx '$');
 		if (*string)
-		    (*outc) (*string);
+		    (*outc) (NCURSES_SP_ARGx *string);
 	    } else {
 		bool mandatory;
 
 		string++;
 		if ((!isdigit(UChar(*string)) && *string != '.')
 		    || !strchr(string, '>')) {
-		    (*outc) ('$');
-		    (*outc) ('<');
+		    (*outc) (NCURSES_SP_ARGx '$');
+		    (*outc) (NCURSES_SP_ARGx '<');
 		    continue;
 		}
 
@@ -250,7 +396,7 @@
 		    && (always_delay
 			|| normal_delay
 			|| mandatory))
-		    delay_output(number / 10);
+		    NCURSES_SP_NAME(delay_output) (NCURSES_SP_ARGx number / 10);
 
 	    }			/* endelse (*string == '<') */
 	}			/* endelse (*string == '$') */
@@ -270,6 +416,25 @@
 	delay_output(trailpad / 10);
 #endif /* BSD_TPUTS */
 
-    my_outch = _nc_outch;
+    SetOutCh(my_outch);
     return OK;
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+_nc_outc_wrapper(SCREEN *sp, int c)
+{
+    if (0 == sp) {
+	return (ERR);
+    } else {
+	return sp->jump(c);
+    }
+}
+
+NCURSES_EXPORT(int)
+tputs(const char *string, int affcnt, int (*outc) (int))
+{
+    SetSafeOutcWrapper(outc);
+    return NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx string, affcnt, _nc_outc_wrapper);
+}
+#endif
diff --git a/ncurses/tinfo/lib_ttyflags.c b/ncurses/tinfo/lib_ttyflags.c
index a2b38a3..43bed35 100644
--- a/ncurses/tinfo/lib_ttyflags.c
+++ b/ncurses/tinfo/lib_ttyflags.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2014 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            *
@@ -36,159 +36,248 @@
  */
 
 #include <curses.priv.h>
-#include <term.h>		/* cur_term */
 
-MODULE_ID("$Id: lib_ttyflags.c,v 1.18 2008/08/03 22:10:44 tom Exp $")
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
+
+MODULE_ID("$Id: lib_ttyflags.c,v 1.30 2014/04/26 18:47:20 juergen Exp $")
 
 NCURSES_EXPORT(int)
-_nc_get_tty_mode(TTY * buf)
+NCURSES_SP_NAME(_nc_get_tty_mode) (NCURSES_SP_DCLx TTY * buf)
 {
     int result = OK;
 
-    if (buf == 0) {
+    if (buf == 0 || SP_PARM == 0) {
 	result = ERR;
     } else {
-	if (cur_term == 0) {
+	TERMINAL *termp = TerminalOf(SP_PARM);
+
+	if (0 == termp) {
 	    result = ERR;
 	} else {
+#ifdef USE_TERM_DRIVER
+	    result = CallDriver_2(SP_PARM, td_sgmode, FALSE, buf);
+#else
 	    for (;;) {
-		if (GET_TTY(cur_term->Filedes, buf) != 0) {
+		if (GET_TTY(termp->Filedes, buf) != 0) {
 		    if (errno == EINTR)
 			continue;
 		    result = ERR;
 		}
 		break;
 	    }
+#endif
 	}
 
 	if (result == ERR)
 	    memset(buf, 0, sizeof(*buf));
 
 	TR(TRACE_BITS, ("_nc_get_tty_mode(%d): %s",
-			cur_term ? cur_term->Filedes : -1,
+			termp ? termp->Filedes : -1,
 			_nc_trace_ttymode(buf)));
     }
     return (result);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
-_nc_set_tty_mode(TTY * buf)
+_nc_get_tty_mode(TTY * buf)
+{
+    return NCURSES_SP_NAME(_nc_get_tty_mode) (CURRENT_SCREEN, buf);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_DCLx TTY * buf)
 {
     int result = OK;
 
-    if (buf == 0) {
+    if (buf == 0 || SP_PARM == 0) {
 	result = ERR;
     } else {
-	if (cur_term == 0) {
+	TERMINAL *termp = TerminalOf(SP_PARM);
+
+	if (0 == termp) {
 	    result = ERR;
 	} else {
+#ifdef USE_TERM_DRIVER
+	    result = CallDriver_2(SP_PARM, td_sgmode, TRUE, buf);
+#else
 	    for (;;) {
-		if (SET_TTY(cur_term->Filedes, buf) != 0) {
+		if ((SET_TTY(termp->Filedes, buf) != 0)
+#if USE_KLIBC_KBD
+		    && !NC_ISATTY(termp->Filedes)
+#endif
+		    ) {
 		    if (errno == EINTR)
 			continue;
-		    if ((errno == ENOTTY) && (SP != 0))
-			SP->_notty = TRUE;
+		    if ((errno == ENOTTY) && (SP_PARM != 0))
+			SP_PARM->_notty = TRUE;
 		    result = ERR;
 		}
 		break;
 	    }
+#endif
 	}
 	TR(TRACE_BITS, ("_nc_set_tty_mode(%d): %s",
-			cur_term ? cur_term->Filedes : -1,
+			termp ? termp->Filedes : -1,
 			_nc_trace_ttymode(buf)));
     }
     return (result);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
-def_shell_mode(void)
+_nc_set_tty_mode(TTY * buf)
+{
+    return NCURSES_SP_NAME(_nc_set_tty_mode) (CURRENT_SCREEN, buf);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_DCL0)
 {
     int rc = ERR;
+    TERMINAL *termp = TerminalOf(SP_PARM);
 
-    T((T_CALLED("def_shell_mode()")));
+    T((T_CALLED("def_shell_mode(%p)"), (void *) SP_PARM));
 
-    if (cur_term != 0) {
+    if (termp != 0) {
+#ifdef USE_TERM_DRIVER
+	rc = CallDriver_2(SP_PARM, td_mode, FALSE, TRUE);
+#else
 	/*
 	 * If XTABS was on, remove the tab and backtab capabilities.
 	 */
-	if (_nc_get_tty_mode(&cur_term->Ottyb) == OK) {
+	if (_nc_get_tty_mode(&termp->Ottyb) == OK) {
 #ifdef TERMIOS
-	    if (cur_term->Ottyb.c_oflag & OFLAGS_TABS)
+	    if (termp->Ottyb.c_oflag & OFLAGS_TABS)
 		tab = back_tab = NULL;
 #else
-	    if (cur_term->Ottyb.sg_flags & XTABS)
+	    if (termp->Ottyb.sg_flags & XTABS)
 		tab = back_tab = NULL;
 #endif
 	    rc = OK;
 	}
+#endif
     }
     returnCode(rc);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
-def_prog_mode(void)
+def_shell_mode(void)
+{
+    return NCURSES_SP_NAME(def_shell_mode) (CURRENT_SCREEN);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_DCL0)
 {
     int rc = ERR;
+    TERMINAL *termp = TerminalOf(SP_PARM);
 
-    T((T_CALLED("def_prog_mode()")));
+    T((T_CALLED("def_prog_mode(%p)"), (void *) SP_PARM));
 
-    if (cur_term != 0) {
+    if (termp != 0) {
+#ifdef USE_TERM_DRIVER
+	rc = CallDriver_2(SP_PARM, td_mode, TRUE, TRUE);
+#else
 	/*
 	 * Turn off the XTABS bit in the tty structure if it was on.
 	 */
-	if (_nc_get_tty_mode(&cur_term->Nttyb) == OK) {
+	if (_nc_get_tty_mode(&termp->Nttyb) == OK) {
 #ifdef TERMIOS
-	    cur_term->Nttyb.c_oflag &= ~OFLAGS_TABS;
+	    termp->Nttyb.c_oflag &= (unsigned) (~OFLAGS_TABS);
 #else
-	    cur_term->Nttyb.sg_flags &= ~XTABS;
+	    termp->Nttyb.sg_flags &= (unsigned) (~XTABS);
 #endif
 	    rc = OK;
 	}
+#endif
     }
     returnCode(rc);
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+def_prog_mode(void)
+{
+    return NCURSES_SP_NAME(def_prog_mode) (CURRENT_SCREEN);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(reset_prog_mode) (NCURSES_SP_DCL0)
+{
+    int rc = ERR;
+    TERMINAL *termp = TerminalOf(SP_PARM);
+
+    T((T_CALLED("reset_prog_mode(%p)"), (void *) SP_PARM));
+
+    if (termp != 0) {
+#ifdef USE_TERM_DRIVER
+	rc = CallDriver_2(SP_PARM, td_mode, TRUE, FALSE);
+#else
+	if (_nc_set_tty_mode(&termp->Nttyb) == OK) {
+	    if (SP_PARM) {
+		if (SP_PARM->_keypad_on)
+		    _nc_keypad(SP_PARM, TRUE);
+	    }
+	    rc = OK;
+	}
+#endif
+    }
+    returnCode(rc);
+}
+
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 reset_prog_mode(void)
 {
-    T((T_CALLED("reset_prog_mode()")));
+    return NCURSES_SP_NAME(reset_prog_mode) (CURRENT_SCREEN);
+}
+#endif
 
-    if (cur_term != 0) {
-	if (_nc_set_tty_mode(&cur_term->Nttyb) == OK) {
-	    if (SP) {
-		if (SP->_keypad_on)
-		    _nc_keypad(SP, TRUE);
-		NC_BUFFERED(TRUE);
-	    }
-	    returnCode(OK);
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(reset_shell_mode) (NCURSES_SP_DCL0)
+{
+    int rc = ERR;
+    TERMINAL *termp = TerminalOf(SP_PARM);
+
+    T((T_CALLED("reset_shell_mode(%p)"), (void *) SP_PARM));
+
+    if (termp != 0) {
+#ifdef USE_TERM_DRIVER
+	rc = CallDriver_2(SP_PARM, td_mode, FALSE, FALSE);
+#else
+	if (SP_PARM) {
+	    _nc_keypad(SP_PARM, FALSE);
+	    _nc_flush();
 	}
+	rc = _nc_set_tty_mode(&termp->Ottyb);
+#endif
     }
-    returnCode(ERR);
+    returnCode(rc);
 }
 
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 reset_shell_mode(void)
 {
-    T((T_CALLED("reset_shell_mode()")));
-
-    if (cur_term != 0) {
-	if (SP) {
-	    _nc_keypad(SP, FALSE);
-	    _nc_flush();
-	    NC_BUFFERED(FALSE);
-	}
-	returnCode(_nc_set_tty_mode(&cur_term->Ottyb));
-    }
-    returnCode(ERR);
+    return NCURSES_SP_NAME(reset_shell_mode) (CURRENT_SCREEN);
 }
+#endif
 
 static TTY *
-saved_tty(void)
+saved_tty(NCURSES_SP_DCL0)
 {
     TTY *result = 0;
 
-    if (SP != 0) {
-	result = &(SP->_saved_tty);
+    if (SP_PARM != 0) {
+	result = (TTY *) & (SP_PARM->_saved_tty);
     } else {
 	if (_nc_prescreen.saved_tty == 0) {
 	    _nc_prescreen.saved_tty = typeCalloc(TTY, 1);
@@ -204,17 +293,31 @@
 */
 
 NCURSES_EXPORT(int)
-savetty(void)
+NCURSES_SP_NAME(savetty) (NCURSES_SP_DCL0)
 {
-    T((T_CALLED("savetty()")));
-
-    returnCode(_nc_get_tty_mode(saved_tty()));
+    T((T_CALLED("savetty(%p)"), (void *) SP_PARM));
+    returnCode(NCURSES_SP_NAME(_nc_get_tty_mode) (NCURSES_SP_ARGx saved_tty(NCURSES_SP_ARG)));
 }
 
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(int)
+savetty(void)
+{
+    return NCURSES_SP_NAME(savetty) (CURRENT_SCREEN);
+}
+#endif
+
+NCURSES_EXPORT(int)
+NCURSES_SP_NAME(resetty) (NCURSES_SP_DCL0)
+{
+    T((T_CALLED("resetty(%p)"), (void *) SP_PARM));
+    returnCode(NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx saved_tty(NCURSES_SP_ARG)));
+}
+
+#if NCURSES_SP_FUNCS
 NCURSES_EXPORT(int)
 resetty(void)
 {
-    T((T_CALLED("resetty()")));
-
-    returnCode(_nc_set_tty_mode(saved_tty()));
+    return NCURSES_SP_NAME(resetty) (CURRENT_SCREEN);
 }
+#endif
diff --git a/ncurses/tinfo/make_hash.c b/ncurses/tinfo/make_hash.c
new file mode 100644
index 0000000..37ac765
--- /dev/null
+++ b/ncurses/tinfo/make_hash.c
@@ -0,0 +1,330 @@
+/****************************************************************************
+ * Copyright (c) 1998-2012,2013 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>                         *
+ *     and: Thomas E. Dickey                        1996-on                 *
+ ****************************************************************************/
+
+/*
+ *	make_hash.c --- build-time program for constructing comp_captab.c
+ *
+ */
+
+#include <build.priv.h>
+
+#include <tic.h>
+#include <hashsize.h>
+
+#include <ctype.h>
+
+MODULE_ID("$Id: make_hash.c,v 1.13 2013/09/28 20:55:47 tom Exp $")
+
+/*
+ *	_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[].
+ *
+ */
+
+#undef MODULE_ID
+#define MODULE_ID(id)		/*nothing */
+#include <tinfo/doalloc.c>
+
+static void
+failed(const char *s)
+{
+    perror(s);
+    exit(EXIT_FAILURE);
+}
+
+static char *
+strmalloc(char *s)
+{
+    size_t need = strlen(s) + 1;
+    char *result = malloc(need);
+    if (result == 0)
+	failed("strmalloc");
+    _nc_STRCPY(result, s, need);
+    return result;
+}
+
+/*
+ *	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;
+
+    while (*string) {
+	sum += (long) (*string + (*(string + 1) << 8));
+	string++;
+    }
+
+    return (int) (sum % HASHTABSIZE);
+}
+
+static void
+_nc_make_hash_table(struct name_table_entry *table,
+		    HashValue * hash_table)
+{
+    short i;
+    int hashvalue;
+    int collisions = 0;
+
+    for (i = 0; i < HASHTABSIZE; i++) {
+	hash_table[i] = -1;
+    }
+    for (i = 0; i < CAPTABSIZE; i++) {
+	hashvalue = hash_function(table[i].nte_name);
+
+	if (hash_table[hashvalue] >= 0)
+	    collisions++;
+
+	if (hash_table[hashvalue] != 0)
+	    table[i].nte_link = hash_table[hashvalue];
+	hash_table[hashvalue] = i;
+    }
+
+    printf("/* %d collisions out of %d entries */\n", collisions, CAPTABSIZE);
+}
+
+/*
+ * 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).
+ */
+
+#define MAX_COLUMNS BUFSIZ	/* this _has_ to be worst-case */
+
+static int
+count_columns(char **list)
+{
+    int result = 0;
+    if (list != 0) {
+	while (*list++) {
+	    ++result;
+	}
+    }
+    return result;
+}
+
+static char **
+parse_columns(char *buffer)
+{
+    static char **list;
+
+    int col = 0;
+
+    if (list == 0 && (list = typeCalloc(char *, (MAX_COLUMNS + 1))) == 0)
+	  return (0);
+
+    if (*buffer != '#') {
+	while (*buffer != '\0') {
+	    char *s;
+	    for (s = buffer; (*s != '\0') && !isspace(UChar(*s)); s++)
+		/*EMPTY */ ;
+	    if (s != buffer) {
+		char mark = *s;
+		*s = '\0';
+		if ((s - buffer) > 1
+		    && (*buffer == '"')
+		    && (s[-1] == '"')) {	/* strip the quotes */
+		    assert(s > buffer + 1);
+		    s[-1] = '\0';
+		    buffer++;
+		}
+		list[col] = buffer;
+		col++;
+		if (mark == '\0')
+		    break;
+		while (*++s && isspace(UChar(*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);
+    HashValue *hash_table = typeCalloc(HashValue, HASHTABSIZE);
+    const char *root_name = "";
+    int column = 0;
+    int bigstring = 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 <= 3
+	|| (column = atoi(argv[1])) <= 0
+	|| (column >= MAX_COLUMNS)
+	|| *(root_name = argv[2]) == 0
+	|| (bigstring = atoi(argv[3])) < 0
+	|| name_table == 0
+	|| hash_table == 0) {
+	fprintf(stderr, "usage: make_hash column root_name bigstring\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;
+	if (column > count_columns(list)) {
+	    fprintf(stderr, "expected %d columns, have %d:\n%s\n",
+		    column,
+		    count_columns(list),
+		    buffer);
+	    exit(EXIT_FAILURE);
+	}
+	name_table[n].nte_link = -1;	/* end-of-hash */
+	name_table[n].nte_name = strmalloc(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
+     */
+    if (bigstring) {
+	int len = 0;
+	int nxt;
+
+	printf("static const char %s_names_text[] = \\\n", root_name);
+	for (n = 0; n < CAPTABSIZE; n++) {
+	    nxt = (int) strlen(name_table[n].nte_name) + 5;
+	    if (nxt + len > 72) {
+		printf("\\\n");
+		len = 0;
+	    }
+	    printf("\"%s\\0\" ", name_table[n].nte_name);
+	    len += nxt;
+	}
+	printf(";\n\n");
+
+	len = 0;
+	printf("static name_table_data const %s_names_data[] =\n",
+	       root_name);
+	printf("{\n");
+	for (n = 0; n < CAPTABSIZE; n++) {
+	    printf("\t{ %15d,\t%10s,\t%3d, %3d }%c\n",
+		   len,
+		   typenames[name_table[n].nte_type],
+		   name_table[n].nte_index,
+		   name_table[n].nte_link,
+		   n < CAPTABSIZE - 1 ? ',' : ' ');
+	    len += (int) strlen(name_table[n].nte_name) + 1;
+	}
+	printf("};\n\n");
+	printf("static struct name_table_entry *_nc_%s_table = 0;\n\n", root_name);
+    } else {
+
+	printf("static struct name_table_entry const _nc_%s_table[] =\n",
+	       root_name);
+	printf("{\n");
+	for (n = 0; n < CAPTABSIZE; n++) {
+	    _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(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("static const HashValue _nc_%s_hash_table[%d] =\n",
+	   root_name,
+	   HASHTABSIZE + 1);
+    printf("{\n");
+    for (n = 0; n < HASHTABSIZE; n++) {
+	printf("\t%3d,\n", hash_table[n]);
+    }
+    printf("\t0\t/* base-of-table */\n");
+    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");
+
+    free(hash_table);
+    return EXIT_SUCCESS;
+}
diff --git a/ncurses/tinfo/make_keys.c b/ncurses/tinfo/make_keys.c
index c084f87..fa0c2f2 100644
--- a/ncurses/tinfo/make_keys.c
+++ b/ncurses/tinfo/make_keys.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2015 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            *
@@ -37,18 +37,33 @@
  */
 
 #define USE_TERMLIB 1
-#include <curses.priv.h>
+#include <build.priv.h>
 
-MODULE_ID("$Id: make_keys.c,v 1.14 2008/08/03 21:57:22 tom Exp $")
+MODULE_ID("$Id: make_keys.c,v 1.21 2015/07/16 01:10:03 tom Exp $")
 
 #include <names.c>
 
-#define UNKNOWN (SIZEOF(strnames) + SIZEOF(strfnames))
+static unsigned
+unknown(void)
+{
+    static unsigned result = 0;
 
-static size_t
+    if (result == 0) {
+	unsigned n;
+	for (n = 0; strnames[n] != 0; n++) {
+	    ++result;
+	}
+	for (n = 0; strfnames[n] != 0; n++) {
+	    ++result;
+	}
+    }
+    return result;
+}
+
+static unsigned
 lookup(const char *name)
 {
-    size_t n;
+    unsigned n;
     bool found = FALSE;
     for (n = 0; strnames[n] != 0; n++) {
 	if (!strcmp(name, strnames[n])) {
@@ -64,7 +79,7 @@
 	    }
 	}
     }
-    return found ? n : UNKNOWN;
+    return found ? n : unknown();
 }
 
 static void
@@ -73,10 +88,11 @@
     char buffer[BUFSIZ];
     char from[256];
     char to[256];
-    int maxlen = 16;
+    unsigned ignore = unknown();
+    unsigned maxlen = 16;
     int scanned;
 
-    while (fgets(buffer, sizeof(buffer), ifp) != 0) {
+    while (fgets(buffer, (int) sizeof(buffer), ifp) != 0) {
 	if (*buffer == '#')
 	    continue;
 
@@ -85,14 +101,14 @@
 
 	scanned = sscanf(buffer, "%255s %255s", to, from);
 	if (scanned == 2) {
-	    int code = lookup(from);
-	    if (code == UNKNOWN)
+	    unsigned code = lookup(from);
+	    if (code == ignore)
 		continue;
-	    if ((int) strlen(from) > maxlen)
-		maxlen = strlen(from);
-	    fprintf(ofp, "\t{ %4d, %-*.*s },\t/* %s */\n",
+	    if (strlen(from) > maxlen)
+		maxlen = (unsigned) strlen(from);
+	    fprintf(ofp, "\t{ %4u, %-*.*s },\t/* %s */\n",
 		    code,
-		    maxlen, maxlen,
+		    (int) maxlen, (int) maxlen,
 		    to,
 		    from);
 	}
diff --git a/ncurses/tinfo/name_match.c b/ncurses/tinfo/name_match.c
index d576901..c648535 100644
--- a/ncurses/tinfo/name_match.c
+++ b/ncurses/tinfo/name_match.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1999-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1999-2012,2013 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            *
@@ -31,28 +31,40 @@
  ****************************************************************************/
 
 #include <curses.priv.h>
-#include <term.h>
 #include <tic.h>
 
-MODULE_ID("$Id: name_match.c,v 1.17 2008/08/03 19:49:33 tom Exp $")
+MODULE_ID("$Id: name_match.c,v 1.23 2013/05/25 20:20:08 tom Exp $")
 
-/*
- *	_nc_first_name(char *names)
- *
- *	Extract the primary name from a compiled entry.
- */
 #define FirstName _nc_globals.first_name
 
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+static const char *
+skip_index(const char *name)
+{
+    if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) {
+	const char *bar = strchr(name, '|');
+	if (bar != 0 && (bar - name) == 2)
+	    name = bar + 1;
+    }
+    return name;
+}
+#endif
+
+/*
+ * Get the primary name from the given name list.  For terminfo, this is the
+ * first name.  For termcap, this may be the second name, if the first one
+ * happens to be two characters.
+ */
 NCURSES_EXPORT(char *)
 _nc_first_name(const char *const sp)
-/* get the first name from the given name list */
 {
     unsigned n;
 
 #if NO_LEAKS
     if (sp == 0) {
-	if (FirstName != 0)
+	if (FirstName != 0) {
 	    FreeAndNull(FirstName);
+	}
     } else
 #endif
     {
@@ -60,8 +72,12 @@
 	    FirstName = typeMalloc(char, MAX_NAME_SIZE + 1);
 
 	if (FirstName != 0) {
+	    const char *src = sp;
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+	    src = skip_index(sp);
+#endif
 	    for (n = 0; n < MAX_NAME_SIZE; n++) {
-		if ((FirstName[n] = sp[n]) == '\0'
+		if ((FirstName[n] = src[n]) == '\0'
 		    || (FirstName[n] == '|'))
 		    break;
 	    }
@@ -72,11 +88,8 @@
 }
 
 /*
- *	int _nc_name_match(namelist, name, delim)
- *
- *	Is the given name matched in namelist?
+ * Is the given name matched in namelist?
  */
-
 NCURSES_EXPORT(int)
 _nc_name_match(const char *const namelst, const char *const name, const char *const delim)
 {
diff --git a/ncurses/tinfo/obsolete.c b/ncurses/tinfo/obsolete.c
new file mode 100644
index 0000000..63476dc
--- /dev/null
+++ b/ncurses/tinfo/obsolete.c
@@ -0,0 +1,239 @@
+/****************************************************************************
+ * Copyright (c) 2013,2014 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                        2013-on                 *
+ ****************************************************************************/
+
+/*
+**	Support for obsolete/unusual features.
+*/
+
+#include <curses.priv.h>
+
+MODULE_ID("$Id: obsolete.c,v 1.3 2014/10/11 02:39:35 tom Exp $")
+
+/*
+ * Obsolete entrypoint retained for binary compatbility.
+ */
+NCURSES_EXPORT(void)
+NCURSES_SP_NAME(_nc_set_buffer) (NCURSES_SP_DCLx FILE *ofp, int buffered)
+{
+#if NCURSES_SP_FUNCS
+    (void) SP_PARM;
+#endif
+    (void) ofp;
+    (void) buffered;
+}
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(void)
+_nc_set_buffer(FILE *ofp, int buffered)
+{
+    NCURSES_SP_NAME(_nc_set_buffer) (CURRENT_SCREEN, ofp, buffered);
+}
+#endif
+
+#if !HAVE_STRDUP
+NCURSES_EXPORT(char *)
+_nc_strdup(const char *s)
+{
+    char *result = 0;
+    if (s != 0) {
+	size_t need = strlen(s);
+	result = malloc(need + 1);
+	if (result != 0) {
+	    strcpy(result, s);
+	}
+    }
+    return result;
+}
+#endif
+
+#if USE_MY_MEMMOVE
+#define DST ((char *)s1)
+#define SRC ((const char *)s2)
+NCURSES_EXPORT(void *)
+_nc_memmove(void *s1, const void *s2, size_t n)
+{
+    if (n != 0) {
+	if ((DST + n > SRC) && (SRC + n > DST)) {
+	    static char *bfr;
+	    static size_t length;
+	    register size_t j;
+	    if (length < n) {
+		length = (n * 3) / 2;
+		bfr = typeRealloc(char, length, bfr);
+	    }
+	    for (j = 0; j < n; j++)
+		bfr[j] = SRC[j];
+	    s2 = bfr;
+	}
+	while (n-- != 0)
+	    DST[n] = SRC[n];
+    }
+    return s1;
+}
+#endif /* USE_MY_MEMMOVE */
+
+#ifdef EXP_XTERM_1005
+NCURSES_EXPORT(int)
+_nc_conv_to_utf8(unsigned char *target, unsigned source, unsigned limit)
+{
+#define CH(n) UChar((source) >> ((n) * 8))
+    int rc = 0;
+
+    if (source <= 0x0000007f)
+	rc = 1;
+    else if (source <= 0x000007ff)
+	rc = 2;
+    else if (source <= 0x0000ffff)
+	rc = 3;
+    else if (source <= 0x001fffff)
+	rc = 4;
+    else if (source <= 0x03ffffff)
+	rc = 5;
+    else			/* (source <= 0x7fffffff) */
+	rc = 6;
+
+    if ((unsigned) rc > limit) {	/* whatever it is, we cannot decode it */
+	rc = 0;
+    }
+
+    if (target != 0) {
+	switch (rc) {
+	case 1:
+	    target[0] = CH(0);
+	    break;
+
+	case 2:
+	    target[1] = UChar(0x80 | (CH(0) & 0x3f));
+	    target[0] = UChar(0xc0 | (CH(0) >> 6) | ((CH(1) & 0x07) << 2));
+	    break;
+
+	case 3:
+	    target[2] = UChar(0x80 | (CH(0) & 0x3f));
+	    target[1] = UChar(0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
+	    target[0] = UChar(0xe0 | ((int) (CH(1) & 0xf0) >> 4));
+	    break;
+
+	case 4:
+	    target[3] = UChar(0x80 | (CH(0) & 0x3f));
+	    target[2] = UChar(0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
+	    target[1] = UChar(0x80 |
+			      ((int) (CH(1) & 0xf0) >> 4) |
+			      ((int) (CH(2) & 0x03) << 4));
+	    target[0] = UChar(0xf0 | ((int) (CH(2) & 0x1f) >> 2));
+	    break;
+
+	case 5:
+	    target[4] = UChar(0x80 | (CH(0) & 0x3f));
+	    target[3] = UChar(0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
+	    target[2] = UChar(0x80 |
+			      ((int) (CH(1) & 0xf0) >> 4) |
+			      ((int) (CH(2) & 0x03) << 4));
+	    target[1] = UChar(0x80 | (CH(2) >> 2));
+	    target[0] = UChar(0xf8 | (CH(3) & 0x03));
+	    break;
+
+	case 6:
+	    target[5] = UChar(0x80 | (CH(0) & 0x3f));
+	    target[4] = UChar(0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
+	    target[3] = UChar(0x80 | (CH(1) >> 4) | ((CH(2) & 0x03) << 4));
+	    target[2] = UChar(0x80 | (CH(2) >> 2));
+	    target[1] = UChar(0x80 | (CH(3) & 0x3f));
+	    target[0] = UChar(0xfc | ((int) (CH(3) & 0x40) >> 6));
+	    break;
+	}
+    }
+
+    return rc;			/* number of bytes needed in target */
+#undef CH
+}
+
+NCURSES_EXPORT(int)
+_nc_conv_to_utf32(unsigned *target, const char *source, unsigned limit)
+{
+#define CH(n) UChar((*target) >> ((n) * 8))
+    int rc = 0;
+    int j;
+    unsigned mask = 0;
+
+    /*
+     * Find the number of bytes we will need from the source.
+     */
+    if ((*source & 0x80) == 0) {
+	rc = 1;
+	mask = (unsigned) *source;
+    } else if ((*source & 0xe0) == 0xc0) {
+	rc = 2;
+	mask = (unsigned) (*source & 0x1f);
+    } else if ((*source & 0xf0) == 0xe0) {
+	rc = 3;
+	mask = (unsigned) (*source & 0x0f);
+    } else if ((*source & 0xf8) == 0xf0) {
+	rc = 4;
+	mask = (unsigned) (*source & 0x07);
+    } else if ((*source & 0xfc) == 0xf8) {
+	rc = 5;
+	mask = (unsigned) (*source & 0x03);
+    } else if ((*source & 0xfe) == 0xfc) {
+	rc = 6;
+	mask = (unsigned) (*source & 0x01);
+    }
+
+    if ((unsigned) rc > limit) {	/* whatever it is, we cannot decode it */
+	rc = 0;
+    }
+
+    /*
+     * sanity-check.
+     */
+    if (rc > 1) {
+	for (j = 1; j < rc; j++) {
+	    if ((source[j] & 0xc0) != 0x80)
+		break;
+	}
+	if (j != rc) {
+	    rc = 0;
+	}
+    }
+
+    if (target != 0) {
+	int shift = 0;
+	*target = 0;
+	for (j = 1; j < rc; j++) {
+	    *target |= (unsigned) (source[rc - j] & 0x3f) << shift;
+	    shift += 6;
+	}
+	*target |= mask << shift;
+    }
+    return rc;
+#undef CH
+}
+#endif /* EXP_XTERM_1005 */
diff --git a/ncurses/tinfo/parse_entry.c b/ncurses/tinfo/parse_entry.c
index cf7a5f4..0dc1414 100644
--- a/ncurses/tinfo/parse_entry.c
+++ b/ncurses/tinfo/parse_entry.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2011,2012 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            *
@@ -46,9 +46,8 @@
 
 #include <ctype.h>
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: parse_entry.c,v 1.69 2008/08/16 21:52:03 tom Exp $")
+MODULE_ID("$Id: parse_entry.c,v 1.80 2015/04/04 14:18:38 tom Exp $")
 
 #ifdef LINT
 static short const parametrized[] =
@@ -84,13 +83,13 @@
     case NUMBER:
 	first = tp->ext_Booleans;
 	last = tp->ext_Numbers + first;
-	offset = tp->ext_Booleans + tp->ext_Numbers;
+	offset = (unsigned) (tp->ext_Booleans + tp->ext_Numbers);
 	tindex = tp->num_Numbers;
 	break;
     case STRING:
-	first = tp->ext_Booleans + tp->ext_Numbers;
+	first = (unsigned) (tp->ext_Booleans + tp->ext_Numbers);
 	last = tp->ext_Strings + first;
-	offset = tp->ext_Booleans + tp->ext_Numbers + tp->ext_Strings;
+	offset = (unsigned) (tp->ext_Booleans + tp->ext_Numbers + tp->ext_Strings);
 	tindex = tp->num_Strings;
 	break;
     case CANCEL:
@@ -137,32 +136,36 @@
 	    break;
 	}
     }
+
+#define for_each_value(max) \
+	for (last = (unsigned) (max - 1); last > tindex; last--)
+
     if (!found) {
 	switch (token_type) {
 	case BOOLEAN:
-	    tp->ext_Booleans += 1;
-	    tp->num_Booleans += 1;
-	    tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
-	    for (last = tp->num_Booleans - 1; last > tindex; last--)
+	    tp->ext_Booleans++;
+	    tp->num_Booleans++;
+	    TYPE_REALLOC(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
+	    for_each_value(tp->num_Booleans)
 		tp->Booleans[last] = tp->Booleans[last - 1];
 	    break;
 	case NUMBER:
-	    tp->ext_Numbers += 1;
-	    tp->num_Numbers += 1;
-	    tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers);
-	    for (last = tp->num_Numbers - 1; last > tindex; last--)
+	    tp->ext_Numbers++;
+	    tp->num_Numbers++;
+	    TYPE_REALLOC(short, tp->num_Numbers, tp->Numbers);
+	    for_each_value(tp->num_Numbers)
 		tp->Numbers[last] = tp->Numbers[last - 1];
 	    break;
 	case STRING:
-	    tp->ext_Strings += 1;
-	    tp->num_Strings += 1;
-	    tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings);
-	    for (last = tp->num_Strings - 1; last > tindex; last--)
+	    tp->ext_Strings++;
+	    tp->num_Strings++;
+	    TYPE_REALLOC(char *, tp->num_Strings, tp->Strings);
+	    for_each_value(tp->num_Strings)
 		tp->Strings[last] = tp->Strings[last - 1];
 	    break;
 	}
 	actual = NUM_EXT_NAMES(tp);
-	tp->ext_Names = typeRealloc(char *, actual, tp->ext_Names);
+	TYPE_REALLOC(char *, actual, tp->ext_Names);
 	while (--actual > offset)
 	    tp->ext_Names[actual] = tp->ext_Names[actual - 1];
 	tp->ext_Names[offset] = _nc_save_str(name);
@@ -170,7 +173,7 @@
 
     temp.nte_name = tp->ext_Names[offset];
     temp.nte_type = token_type;
-    temp.nte_index = tindex;
+    temp.nte_index = (short) tindex;
     temp.nte_link = -1;
 
     return &temp;
@@ -200,6 +203,8 @@
  	{ bad_tc_usage = TRUE; \
 	 _nc_warning("Legacy termcap allows only a trailing tc= clause"); }
 
+#define MAX_NUMBER 0x7fff	/* positive shorts only */
+
 NCURSES_EXPORT(int)
 _nc_parse_entry(struct entry *entryp, int literal, bool silent)
 {
@@ -379,16 +384,14 @@
 		    && !strcmp("ma", _nc_curr_token.tk_name)) {
 		    /* tell max_attributes from arrow_key_map */
 		    entry_ptr = _nc_find_type_entry("ma", NUMBER,
-						    _nc_get_table(_nc_syntax
-								  != 0));
+						    _nc_syntax != 0);
 		    assert(entry_ptr != 0);
 
 		} else if (token_type == STRING
 			   && !strcmp("MT", _nc_curr_token.tk_name)) {
 		    /* map terminfo's string MT to MT */
 		    entry_ptr = _nc_find_type_entry("MT", STRING,
-						    _nc_get_table(_nc_syntax
-								  != 0));
+						    _nc_syntax != 0);
 		    assert(entry_ptr != 0);
 
 		} else if (token_type == BOOLEAN
@@ -443,8 +446,12 @@
 		break;
 
 	    case NUMBER:
-		entryp->tterm.Numbers[entry_ptr->nte_index] =
-		    _nc_curr_token.tk_valnumber;
+		if (_nc_curr_token.tk_valnumber > MAX_NUMBER) {
+		    entryp->tterm.Numbers[entry_ptr->nte_index] = MAX_NUMBER;
+		} else {
+		    entryp->tterm.Numbers[entry_ptr->nte_index] =
+			(short) _nc_curr_token.tk_valnumber;
+		}
 		break;
 
 	    case STRING:
@@ -510,9 +517,9 @@
 _nc_capcmp(const char *s, const char *t)
 /* compare two string capabilities, stripping out padding */
 {
-    if (!s && !t)
+    if (!VALID_STRING(s) && !VALID_STRING(t))
 	return (0);
-    else if (!s || !t)
+    else if (!VALID_STRING(s) || !VALID_STRING(t))
 	return (1);
 
     for (;;) {
@@ -574,32 +581,32 @@
  * list.  For each capability, we may assume there is a keycap that sends the
  * string which is the value of that capability.
  */
+#define DATA(from, to) { { from }, { to } }
 typedef struct {
-    const char *from;
-    const char *to;
+    const char from[3];
+    const char to[6];
 } 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},
+    DATA("al", "kil1"),		/* insert line key  -> KEY_IL    */
+    DATA("bt", "kcbt"),		/* back tab         -> KEY_BTAB  */
+    DATA("cd", "ked"),		/* clear-to-eos key -> KEY_EOL   */
+    DATA("ce", "kel"),		/* clear-to-eol key -> KEY_EOS   */
+    DATA("cl", "kclr"),		/* clear key        -> KEY_CLEAR */
+    DATA("ct", "tbc"),		/* clear all tabs   -> KEY_CATAB */
+    DATA("dc", "kdch1"),	/* delete char      -> KEY_DC    */
+    DATA("dl", "kdl1"),		/* delete line      -> KEY_DL    */
+    DATA("do", "kcud1"),	/* down key         -> KEY_DOWN  */
+    DATA("ei", "krmir"),	/* exit insert key  -> KEY_EIC   */
+    DATA("ho", "khome"),	/* home key         -> KEY_HOME  */
+    DATA("ic", "kich1"),	/* insert char key  -> KEY_IC    */
+    DATA("im", "kIC"),		/* insert-mode key  -> KEY_SIC   */
+    DATA("le", "kcub1"),	/* le key           -> KEY_LEFT  */
+    DATA("nd", "kcuf1"),	/* nd key           -> KEY_RIGHT */
+    DATA("nl", "kent"),		/* new line key     -> KEY_ENTER */
+    DATA("st", "khts"),		/* set-tab key      -> KEY_STAB  */
+    DATA("ta", ""),
+    DATA("up", "kcuu1"),	/* up-arrow key     -> KEY_UP    */
 };
 
 /*
@@ -653,27 +660,30 @@
 
 	if (WANTED(carriage_return)) {
 	    if (carriage_return_delay > 0) {
-		sprintf(buf, "%s$<%d>", C_CR, carriage_return_delay);
+		_nc_SPRINTF(buf, _nc_SLIMIT(sizeof(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);
+		_nc_SPRINTF(buf, _nc_SLIMIT(sizeof(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 */
+	/* vi doesn't use "do", but it does seem 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);
+		    _nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf))
+				"%s$<%d>", C_LF, new_line_delay);
 		    cursor_down = _nc_save_str(buf);
 		} else
 		    cursor_down = _nc_save_str(C_LF);
@@ -684,7 +694,8 @@
 		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);
+		    _nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf))
+				"%s$<%d>", C_LF, new_line_delay);
 		    scroll_forward = _nc_save_str(buf);
 		} else
 		    scroll_forward = _nc_save_str(C_LF);
@@ -693,7 +704,8 @@
 	if (WANTED(newline)) {
 	    if (linefeed_is_newline == 1) {
 		if (new_line_delay > 0) {
-		    sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
+		    _nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf))
+				"%s$<%d>", C_LF, new_line_delay);
 		    newline = _nc_save_str(buf);
 		} else
 		    newline = _nc_save_str(C_LF);
@@ -735,7 +747,8 @@
 	 */
 	if (WANTED(tab)) {
 	    if (horizontal_tab_delay > 0) {
-		sprintf(buf, "%s$<%d>", C_HT, horizontal_tab_delay);
+		_nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf))
+			    "%s$<%d>", C_HT, horizontal_tab_delay);
 		tab = _nc_save_str(buf);
 	    } else
 		tab = _nc_save_str(C_HT);
@@ -772,11 +785,10 @@
      * isn't from mytinfo...
      */
     if (PRESENT(other_non_function_keys)) {
-	char *base = other_non_function_keys;
+	char *base;
 	char *bp, *cp, *dp;
 	struct name_table_entry const *from_ptr;
 	struct name_table_entry const *to_ptr;
-	assoc const *ap;
 	char buf2[MAX_TERMINFO_LENGTH];
 	bool foundim;
 
@@ -788,18 +800,22 @@
 	for (base = other_non_function_keys;
 	     (cp = strchr(base, ',')) != 0;
 	     base = cp + 1) {
-	    size_t len = cp - base;
+	    size_t len = (unsigned) (cp - base);
+	    size_t n;
+	    assoc const *ap = 0;
 
-	    for (ap = ko_xlate; ap->from; ap++) {
-		if (len == strlen(ap->from)
-		    && strncmp(ap->from, base, len) == 0)
+	    for (n = 0; n < SIZEOF(ko_xlate); ++n) {
+		if (len == strlen(ko_xlate[n].from)
+		    && strncmp(ko_xlate[n].from, base, len) == 0) {
+		    ap = ko_xlate + n;
 		    break;
+		}
 	    }
-	    if (!(ap->from && ap->to)) {
+	    if (ap == 0) {
 		_nc_warning("unknown capability `%.*s' in ko string",
 			    (int) len, base);
 		continue;
-	    } else if (ap->to == CANCELLED_STRING)	/* ignore it */
+	    } else if (ap->to[0] == '\0')	/* ignore it */
 		continue;
 
 	    /* now we know we found a match in ko_table, so... */
@@ -840,7 +856,7 @@
 		} else
 		    *dp++ = *bp;
 	    }
-	    *dp++ = '\0';
+	    *dp = '\0';
 
 	    tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
 	}
diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c
index b4ea61c..81fdc46 100644
--- a/ncurses/tinfo/read_entry.c
+++ b/ncurses/tinfo/read_entry.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2014,2015 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            *
@@ -40,13 +40,14 @@
 #include <hashed_db.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: read_entry.c,v 1.102 2008/08/03 19:33:04 tom Exp $")
+MODULE_ID("$Id: read_entry.c,v 1.129 2015/06/27 16:16:40 tom Exp $")
 
 #define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts))
 
-#if USE_DATABASE
+#define MyNumber(n) (short) LOW_MSB(n)
+
+#if NCURSES_USE_DATABASE
 static void
 convert_shorts(char *buf, short *Numbers, int count)
 {
@@ -57,7 +58,7 @@
 	else if (IS_NEG2(buf + 2 * i))
 	    Numbers[i] = CANCELLED_NUMERIC;
 	else
-	    Numbers[i] = LOW_MSB(buf + 2 * i);
+	    Numbers[i] = MyNumber(buf + 2 * i);
 	TR(TRACE_DATABASE, ("get Numbers[%d]=%d", i, Numbers[i]));
     }
 }
@@ -73,10 +74,10 @@
 	    Strings[i] = ABSENT_STRING;
 	} else if (IS_NEG2(buf + 2 * i)) {
 	    Strings[i] = CANCELLED_STRING;
-	} else if ((int) LOW_MSB(buf + 2 * i) > size) {
+	} else if (MyNumber(buf + 2 * i) > size) {
 	    Strings[i] = ABSENT_STRING;
 	} else {
-	    Strings[i] = (LOW_MSB(buf + 2 * i) + table);
+	    Strings[i] = (MyNumber(buf + 2 * i) + table);
 	    TR(TRACE_DATABASE, ("Strings[%d] = %s", i, _nc_visbuf(Strings[i])));
 	}
 
@@ -99,31 +100,81 @@
 
     if (have > 0) {
 	if ((int) want > have)
-	    want = have;
-	memcpy(dst, src + *offset, want);
-	*offset += want;
+	    want = (unsigned) have;
+	memcpy(dst, src + *offset, (size_t) want);
+	*offset += (int) want;
     } else {
 	want = 0;
     }
     return (int) want;
 }
 
-#define Read(buf, count) fake_read(buffer, &offset, limit, buf, count)
+#define Read(buf, count) fake_read(buffer, &offset, limit, (char *) buf, (unsigned) count)
 
 #define read_shorts(buf, count) \
-	(Read(buf, (unsigned) (count)*2) == (int) (count)*2)
+	(Read(buf, (count)*2) == (int) (count)*2)
 
 #define even_boundary(value) \
     if ((value) % 2 != 0) Read(buf, 1)
+#endif
 
+NCURSES_EXPORT(void)
+_nc_init_termtype(TERMTYPE *const tp)
+{
+    unsigned i;
+
+#if NCURSES_XNAMES
+    tp->num_Booleans = BOOLCOUNT;
+    tp->num_Numbers = NUMCOUNT;
+    tp->num_Strings = STRCOUNT;
+    tp->ext_Booleans = 0;
+    tp->ext_Numbers = 0;
+    tp->ext_Strings = 0;
+#endif
+    if (tp->Booleans == 0)
+	TYPE_MALLOC(NCURSES_SBOOL, BOOLCOUNT, tp->Booleans);
+    if (tp->Numbers == 0)
+	TYPE_MALLOC(short, NUMCOUNT, tp->Numbers);
+    if (tp->Strings == 0)
+	TYPE_MALLOC(char *, STRCOUNT, tp->Strings);
+
+    for_each_boolean(i, tp)
+	tp->Booleans[i] = FALSE;
+
+    for_each_number(i, tp)
+	tp->Numbers[i] = ABSENT_NUMERIC;
+
+    for_each_string(i, tp)
+	tp->Strings[i] = ABSENT_STRING;
+}
+
+#if NCURSES_USE_DATABASE
+#if NCURSES_XNAMES
+static bool
+valid_shorts(char *buffer, int limit)
+{
+    bool result = FALSE;
+    int n;
+    for (n = 0; n < limit; ++n) {
+	if (MyNumber(buffer + (n * 2)) > 0) {
+	    result = TRUE;
+	    break;
+	}
+    }
+    return result;
+}
+#endif
+
+/*
+ * Return TGETENT_YES if read, TGETENT_NO if not found or garbled.
+ */
 NCURSES_EXPORT(int)
 _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
-/* return 1 if read, 0 if not found or garbled */
 {
     int offset = 0;
     int name_size, bool_count, num_count, str_count, str_size;
     int i;
-    char buf[MAX_ENTRY_SIZE + 1];
+    char buf[MAX_ENTRY_SIZE + 2];
     char *string_table;
     unsigned want, have;
 
@@ -137,11 +188,11 @@
 	return (TGETENT_NO);
     }
 
-    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);
+    name_size = MyNumber(buf + 2);
+    bool_count = MyNumber(buf + 4);
+    num_count = MyNumber(buf + 6);
+    str_count = MyNumber(buf + 8);
+    str_size = MyNumber(buf + 10);
 
     TR(TRACE_DATABASE,
        ("TERMTYPE name_size=%d, bool=%d/%d, num=%d/%d str=%d/%d(%d)",
@@ -155,10 +206,10 @@
 	return (TGETENT_NO);
     }
 
-    want = str_size + name_size + 1;
+    want = (unsigned) (str_size + name_size + 1);
     if (str_size) {
 	/* try to allocate space for the string table */
-	if (str_count * 2 >= (int) sizeof(buf)
+	if (str_count * 2 >= MAX_ENTRY_SIZE
 	    || (string_table = typeMalloc(char, want)) == 0) {
 	    return (TGETENT_NO);
 	}
@@ -173,14 +224,14 @@
     want = min(MAX_NAME_SIZE, (unsigned) name_size);
     ptr->str_table = string_table;
     ptr->term_names = string_table;
-    if ((have = Read(ptr->term_names, want)) != want) {
-	memset(ptr->term_names + have, 0, want - have);
+    if ((have = (unsigned) Read(ptr->term_names, want)) != want) {
+	memset(ptr->term_names + have, 0, (size_t) (want - have));
     }
     ptr->term_names[want] = '\0';
     string_table += (want + 1);
 
     if (have > MAX_NAME_SIZE)
-	offset = (have - MAX_NAME_SIZE);
+	offset = (int) (have - MAX_NAME_SIZE);
 
     /* grab the booleans */
     if ((ptr->Booleans = TYPE_CALLOC(NCURSES_SBOOL,
@@ -204,8 +255,9 @@
     }
     convert_shorts(buf, ptr->Numbers, num_count);
 
-    if ((ptr->Strings = TYPE_CALLOC(char *, max(STRCOUNT, str_count))) == 0)
-	  return (TGETENT_NO);
+    if ((ptr->Strings = TYPE_CALLOC(char *, max(STRCOUNT, str_count))) == 0) {
+	return (TGETENT_NO);
+    }
 
     if (str_count) {
 	/* grab the string offsets */
@@ -213,8 +265,9 @@
 	    return (TGETENT_NO);
 	}
 	/* finally, grab the string table itself */
-	if (Read(string_table, (unsigned) str_size) != str_size)
+	if (Read(string_table, (unsigned) str_size) != str_size) {
 	    return (TGETENT_NO);
+	}
 	convert_strings(buf, ptr->Strings, str_count, str_size, string_table);
     }
 #if NCURSES_XNAMES
@@ -228,32 +281,33 @@
      */
     even_boundary(str_size);
     TR(TRACE_DATABASE, ("READ extended_header @%d", offset));
-    if (_nc_user_definable && read_shorts(buf, 5)) {
-	int ext_bool_count = LOW_MSB(buf + 0);
-	int ext_num_count = LOW_MSB(buf + 2);
-	int ext_str_count = LOW_MSB(buf + 4);
-	int ext_str_size = LOW_MSB(buf + 6);
-	int ext_str_limit = LOW_MSB(buf + 8);
-	unsigned need = (ext_bool_count + ext_num_count + ext_str_count);
+    if (_nc_user_definable && read_shorts(buf, 5) && valid_shorts(buf, 5)) {
+	int ext_bool_count = MyNumber(buf + 0);
+	int ext_num_count = MyNumber(buf + 2);
+	int ext_str_count = MyNumber(buf + 4);
+	int ext_str_size = MyNumber(buf + 6);
+	int ext_str_limit = MyNumber(buf + 8);
+	unsigned need = (unsigned) (ext_bool_count + ext_num_count + ext_str_count);
 	int base = 0;
 
-	if (need >= sizeof(buf)
-	    || ext_str_size >= (int) sizeof(buf)
-	    || ext_str_limit >= (int) sizeof(buf)
+	if (need >= (MAX_ENTRY_SIZE / 2)
+	    || ext_str_size >= MAX_ENTRY_SIZE
+	    || ext_str_limit >= MAX_ENTRY_SIZE
 	    || ext_bool_count < 0
 	    || ext_num_count < 0
 	    || ext_str_count < 0
 	    || ext_str_size < 0
-	    || ext_str_limit < 0)
+	    || ext_str_limit < 0) {
 	    return (TGETENT_NO);
+	}
 
-	ptr->num_Booleans = BOOLCOUNT + ext_bool_count;
-	ptr->num_Numbers = NUMCOUNT + ext_num_count;
-	ptr->num_Strings = STRCOUNT + ext_str_count;
+	ptr->num_Booleans = UShort(BOOLCOUNT + ext_bool_count);
+	ptr->num_Numbers = UShort(NUMCOUNT + ext_num_count);
+	ptr->num_Strings = UShort(STRCOUNT + ext_str_count);
 
-	ptr->Booleans = typeRealloc(NCURSES_SBOOL, ptr->num_Booleans, ptr->Booleans);
-	ptr->Numbers = typeRealloc(short, ptr->num_Numbers, ptr->Numbers);
-	ptr->Strings = typeRealloc(char *, ptr->num_Strings, ptr->Strings);
+	TYPE_REALLOC(NCURSES_SBOOL, ptr->num_Booleans, ptr->Booleans);
+	TYPE_REALLOC(short, ptr->num_Numbers, ptr->Numbers);
+	TYPE_REALLOC(char *, ptr->num_Strings, ptr->Strings);
 
 	TR(TRACE_DATABASE, ("extended header is %d/%d/%d(%d:%d)",
 			    ext_bool_count, ext_num_count, ext_str_count,
@@ -261,39 +315,48 @@
 
 	TR(TRACE_DATABASE, ("READ %d extended-booleans @%d",
 			    ext_bool_count, offset));
-	if ((ptr->ext_Booleans = ext_bool_count) != 0) {
+	if ((ptr->ext_Booleans = UShort(ext_bool_count)) != 0) {
 	    if (Read(ptr->Booleans + BOOLCOUNT, (unsigned)
-		     ext_bool_count) != ext_bool_count)
+		     ext_bool_count) != ext_bool_count) {
 		return (TGETENT_NO);
+	    }
 	}
 	even_boundary(ext_bool_count);
 
 	TR(TRACE_DATABASE, ("READ %d extended-numbers @%d",
 			    ext_num_count, offset));
-	if ((ptr->ext_Numbers = ext_num_count) != 0) {
-	    if (!read_shorts(buf, ext_num_count))
+	if ((ptr->ext_Numbers = UShort(ext_num_count)) != 0) {
+	    if (!read_shorts(buf, ext_num_count)) {
 		return (TGETENT_NO);
+	    }
 	    TR(TRACE_DATABASE, ("Before converting extended-numbers"));
 	    convert_shorts(buf, ptr->Numbers + NUMCOUNT, ext_num_count);
 	}
 
 	TR(TRACE_DATABASE, ("READ extended-offsets @%d", offset));
-	if ((ext_str_count || need)
-	    && !read_shorts(buf, ext_str_count + need))
+	if ((unsigned) (ext_str_count + (int) need) >= (MAX_ENTRY_SIZE / 2)) {
 	    return (TGETENT_NO);
+	}
+	if ((ext_str_count || need)
+	    && !read_shorts(buf, ext_str_count + (int) need)) {
+	    return (TGETENT_NO);
+	}
 
 	TR(TRACE_DATABASE, ("READ %d bytes of extended-strings @%d",
 			    ext_str_limit, offset));
 
 	if (ext_str_limit) {
-	    if ((ptr->ext_str_table = typeMalloc(char, ext_str_limit)) == 0)
-		  return (TGETENT_NO);
-	    if (Read(ptr->ext_str_table, (unsigned) ext_str_limit) != ext_str_limit)
+	    ptr->ext_str_table = typeMalloc(char, (size_t) ext_str_limit);
+	    if (ptr->ext_str_table == 0) {
 		return (TGETENT_NO);
+	    }
+	    if (Read(ptr->ext_str_table, (unsigned) ext_str_limit) != ext_str_limit) {
+		return (TGETENT_NO);
+	    }
 	    TR(TRACE_DATABASE, ("first extended-string is %s", _nc_visbuf(ptr->ext_str_table)));
 	}
 
-	if ((ptr->ext_Strings = ext_str_count) != 0) {
+	if ((ptr->ext_Strings = UShort(ext_str_count)) != 0) {
 	    TR(TRACE_DATABASE,
 	       ("Before computing extended-string capabilities str_count=%d, ext_str_count=%d",
 		str_count, ext_str_count));
@@ -305,7 +368,7 @@
 				    _nc_visbuf(ptr->Strings[i + str_count])));
 		ptr->Strings[i + STRCOUNT] = ptr->Strings[i + str_count];
 		if (VALID_STRING(ptr->Strings[i + STRCOUNT]))
-		    base += (strlen(ptr->Strings[i + STRCOUNT]) + 1);
+		    base += (int) (strlen(ptr->Strings[i + STRCOUNT]) + 1);
 		TR(TRACE_DATABASE, ("... to    [%d] %s",
 				    i + STRCOUNT,
 				    _nc_visbuf(ptr->Strings[i + STRCOUNT])));
@@ -313,10 +376,12 @@
 	}
 
 	if (need) {
-	    if (ext_str_count >= (MAX_ENTRY_SIZE * 2))
-		  return (TGETENT_NO);
-	    if ((ptr->ext_Names = TYPE_CALLOC(char *, need)) == 0)
-		  return (TGETENT_NO);
+	    if (ext_str_count >= (MAX_ENTRY_SIZE / 2)) {
+		return (TGETENT_NO);
+	    }
+	    if ((ptr->ext_Names = TYPE_CALLOC(char *, need)) == 0) {
+		return (TGETENT_NO);
+	    }
 	    TR(TRACE_DATABASE,
 	       ("ext_NAMES starting @%d in extended_strings, first = %s",
 		base, _nc_visbuf(ptr->ext_str_table + base)));
@@ -326,17 +391,18 @@
 			    ext_str_limit, ptr->ext_str_table + base);
 	}
 
-	T(("...done reading terminfo bool %d(%d) num %d(%d) str %d(%d)",
-	   ptr->num_Booleans, ptr->ext_Booleans,
-	   ptr->num_Numbers, ptr->ext_Numbers,
-	   ptr->num_Strings, ptr->ext_Strings));
+	TR(TRACE_DATABASE,
+	   ("...done reading terminfo bool %d(%d) num %d(%d) str %d(%d)",
+	    ptr->num_Booleans, ptr->ext_Booleans,
+	    ptr->num_Numbers, ptr->ext_Numbers,
+	    ptr->num_Strings, ptr->ext_Strings));
 
 	TR(TRACE_DATABASE, ("extend: num_Booleans:%d", ptr->num_Booleans));
     } else
 #endif /* NCURSES_XNAMES */
     {
-	T(("...done reading terminfo bool %d num %d str %d",
-	   bool_count, num_count, str_count));
+	TR(TRACE_DATABASE, ("...done reading terminfo bool %d num %d str %d",
+			    bool_count, num_count, str_count));
 #if NCURSES_XNAMES
 	TR(TRACE_DATABASE, ("normal: num_Booleans:%d", ptr->num_Booleans));
 #endif
@@ -364,30 +430,84 @@
 _nc_read_file_entry(const char *const filename, TERMTYPE *ptr)
 /* return 1 if read, 0 if not found or garbled */
 {
-    int code, fd = -1;
+    FILE *fp = 0;
+    int code;
     int limit;
     char buffer[MAX_ENTRY_SIZE + 1];
 
     if (_nc_access(filename, R_OK) < 0
-	|| (fd = open(filename, O_RDONLY | O_BINARY)) < 0) {
-	T(("cannot open terminfo %s (errno=%d)", filename, errno));
+	|| (fp = fopen(filename, "rb")) == 0) {
+	TR(TRACE_DATABASE, ("cannot open terminfo %s (errno=%d)", filename, errno));
 	code = TGETENT_NO;
     } else {
-	if ((limit = read(fd, buffer, sizeof(buffer))) > 0) {
+	if ((limit = (int) fread(buffer, sizeof(char), sizeof(buffer), fp))
+	    > 0) {
 
-	    T(("read terminfo %s", filename));
+	    TR(TRACE_DATABASE, ("read terminfo %s", filename));
 	    if ((code = _nc_read_termtype(ptr, buffer, limit)) == TGETENT_NO) {
 		_nc_free_termtype(ptr);
 	    }
 	} else {
 	    code = TGETENT_NO;
 	}
-	close(fd);
+	fclose(fp);
     }
 
     return (code);
 }
 
+#if USE_HASHED_DB
+/*
+ * Return if if we can build the filename of a ".db" file.
+ */
+static bool
+make_db_filename(char *filename, unsigned limit, const char *const path)
+{
+    static const char suffix[] = DBM_SUFFIX;
+
+    size_t lens = sizeof(suffix) - 1;
+    size_t size = strlen(path);
+    size_t test = lens + size;
+    bool result = FALSE;
+
+    if (test < limit) {
+	if (size >= lens
+	    && !strcmp(path + size - lens, suffix))
+	    _nc_STRCPY(filename, path, limit);
+	else
+	    _nc_SPRINTF(filename, _nc_SLIMIT(limit) "%s%s", path, suffix);
+	result = TRUE;
+    }
+    return result;
+}
+#endif
+
+/*
+ * Return true if we can build the name of a filesystem entry.
+ */
+static bool
+make_dir_filename(char *filename,
+		  unsigned limit,
+		  const char *const path,
+		  const char *name)
+{
+    bool result = FALSE;
+
+#if NCURSES_USE_TERMCAP
+    if (_nc_is_dir_path(path))
+#endif
+    {
+	unsigned need = (unsigned) (LEAF_LEN + 3 + strlen(path) + strlen(name));
+
+	if (need <= limit) {
+	    _nc_SPRINTF(filename, _nc_SLIMIT(limit)
+			"%s/" LEAF_FMT "/%s", path, *name, name);
+	    result = TRUE;
+	}
+    }
+    return result;
+}
+
 /*
  * Build a terminfo pathname and try to read the data.  Returns TGETENT_YES on
  * success, TGETENT_NO on failure.
@@ -399,107 +519,82 @@
 		   const char *name,
 		   TERMTYPE *const tp)
 {
-    int result = TGETENT_NO;
+    int code = TGETENT_NO;
 
-    /*
-     * If we are looking in a directory, assume the entry is a file under that,
-     * according to the normal rules.
-     *
-     * FIXME - add caseless-filename fixup.
-     */
-    if (_nc_is_dir_path(path)) {
-	unsigned need = 4 + strlen(path) + strlen(name);
-
-	if (need <= limit) {
-	    (void) sprintf(filename, "%s/" LEAF_FMT "/%s", path, *name, name);
-	    result = _nc_read_file_entry(filename, tp);
-	}
-    }
 #if USE_HASHED_DB
-    else {
-	static const char suffix[] = DBM_SUFFIX;
-	DB *capdbp;
-	unsigned lens = sizeof(suffix) - 1;
-	unsigned size = strlen(path);
-	unsigned need = lens + size;
+    DB *capdbp;
 
-	if (need <= limit) {
-	    if (size >= lens
-		&& !strcmp(path + size - lens, suffix))
-		(void) strcpy(filename, path);
-	    else
-		(void) sprintf(filename, "%s%s", path, suffix);
+    if (make_db_filename(filename, limit, path)
+	&& (capdbp = _nc_db_open(filename, FALSE)) != 0) {
+
+	DBT key, data;
+	int reccnt = 0;
+	char *save = strdup(name);
+
+	memset(&key, 0, sizeof(key));
+	key.data = save;
+	key.size = strlen(save);
+
+	/*
+	 * This lookup could return termcap data, which we do not want.  We are
+	 * looking for compiled (binary) terminfo data.
+	 *
+	 * cgetent uses a two-level lookup.  On the first it uses the given
+	 * name to return a record containing only the aliases for an entry. 
+	 * On the second (using that list of aliases as a key), it returns the
+	 * content of the terminal description.  We expect second lookup to
+	 * return data beginning with the same set of aliases.
+	 *
+	 * For compiled terminfo, the list of aliases in the second case will
+	 * be null-terminated.  A termcap entry will not be, and will run on
+	 * into the description.  So we can easily distinguish between the two
+	 * (source/binary) by checking the lengths.
+	 */
+	while (_nc_db_get(capdbp, &key, &data) == 0) {
+	    int used = (int) data.size - 1;
+	    char *have = (char *) data.data;
+
+	    if (*have++ == 0) {
+		if (data.size > key.size
+		    && IS_TIC_MAGIC(have)) {
+		    code = _nc_read_termtype(tp, have, used);
+		    if (code == TGETENT_NO) {
+			_nc_free_termtype(tp);
+		    }
+		}
+		break;
+	    }
 
 	    /*
-	     * It would be nice to optimize the dbopen/close activity, as
-	     * done in the cgetent implementation for tc= clauses.  However,
-	     * since we support multiple database locations, we cannot do
-	     * that.
+	     * Just in case we have a corrupt database, do not waste time with
+	     * it.
 	     */
-	    if ((capdbp = _nc_db_open(filename, FALSE)) != 0) {
-		DBT key, data;
-		int reccnt = 0;
-		char *save = strdup(name);
+	    if (++reccnt >= 3)
+		break;
 
-		memset(&key, 0, sizeof(key));
-		key.data = save;
-		key.size = strlen(save);
-
-		/*
-		 * This lookup could return termcap data, which we do not want. 
-		 * We are looking for compiled (binary) terminfo data.
-		 *
-		 * cgetent uses a two-level lookup.  On the first it uses the
-		 * given name to return a record containing only the aliases
-		 * for an entry.  On the second (using that list of aliases as
-		 * a key), it returns the content of the terminal description. 
-		 * We expect second lookup to return data beginning with the
-		 * same set of aliases.
-		 *
-		 * For compiled terminfo, the list of aliases in the second
-		 * case will be null-terminated.  A termcap entry will not be,
-		 * and will run on into the description.  So we can easily
-		 * distinguish between the two (source/binary) by checking the
-		 * lengths.
-		 */
-		while (_nc_db_get(capdbp, &key, &data) == 0) {
-		    int used = data.size - 1;
-		    char *have = (char *) data.data;
-
-		    if (*have++ == 0) {
-			if (data.size > key.size
-			    && IS_TIC_MAGIC(have)) {
-			    result = _nc_read_termtype(tp, have, used);
-			    if (result == TGETENT_NO) {
-				_nc_free_termtype(tp);
-			    }
-			}
-			break;
-		    }
-
-		    /*
-		     * Just in case we have a corrupt database, do not waste
-		     * time with it.
-		     */
-		    if (++reccnt >= 3)
-			break;
-
-		    /*
-		     * Prepare for the second level.
-		     */
-		    key.data = have;
-		    key.size = used;
-		}
-
-		_nc_db_close(capdbp);
-		free(save);
-	    }
+	    /*
+	     * Prepare for the second level.
+	     */
+	    key.data = have;
+	    key.size = used;
 	}
+
+	free(save);
+    } else			/* may be either filesystem or flat file */
+#endif
+    if (make_dir_filename(filename, limit, path, name)) {
+	code = _nc_read_file_entry(filename, tp);
+    }
+#if NCURSES_USE_TERMCAP
+    else if (code != TGETENT_YES) {
+	code = _nc_read_termcap_entry(name, tp);
+	_nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
+		    "%.*s", PATH_MAX - 1, _nc_get_source());
     }
 #endif
-    return result;
+    return code;
 }
-#endif /* USE_DATABASE */
+#endif /* NCURSES_USE_DATABASE */
 
 /*
  *	_nc_read_entry(char *name, char *filename, TERMTYPE *tp)
@@ -515,30 +610,36 @@
 {
     int code = TGETENT_NO;
 
+    _nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
+		"%.*s", PATH_MAX - 1, name);
+
     if (strlen(name) == 0
 	|| strcmp(name, ".") == 0
 	|| strcmp(name, "..") == 0
 	|| _nc_pathlast(name) != 0
 	|| strchr(name, NCURSES_PATHSEP) != 0) {
-	T(("illegal or missing entry name '%s'", name));
+	TR(TRACE_DATABASE, ("illegal or missing entry name '%s'", name));
     } else {
-#if USE_DATABASE
-	DBDIRS state = dbdTIC;
-	int offset = 0;
+#if NCURSES_USE_DATABASE
+	DBDIRS state;
+	int offset;
 	const char *path;
 
+	_nc_first_db(&state, &offset);
+	code = TGETENT_ERR;
 	while ((path = _nc_next_db(&state, &offset)) != 0) {
+	    TR(TRACE_DATABASE, ("_nc_read_tic_entry path=%s, name=%s", path, name));
 	    code = _nc_read_tic_entry(filename, PATH_MAX, path, name, tp);
 	    if (code == TGETENT_YES) {
 		_nc_last_db();
 		break;
 	    }
 	}
-#endif
-#if USE_TERMCAP
+#elif NCURSES_USE_TERMCAP
 	if (code != TGETENT_YES) {
 	    code = _nc_read_termcap_entry(name, tp);
-	    sprintf(filename, "%.*s", PATH_MAX - 1, _nc_get_source());
+	    _nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
+			"%.*s", PATH_MAX - 1, _nc_get_source());
 	}
 #endif
     }
diff --git a/ncurses/tinfo/read_termcap.c b/ncurses/tinfo/read_termcap.c
index d94d1a4..6bfb23c 100644
--- a/ncurses/tinfo/read_termcap.c
+++ b/ncurses/tinfo/read_termcap.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -54,11 +54,9 @@
 
 #include <ctype.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: read_termcap.c,v 1.71 2006/07/29 12:06:51 tom Exp $")
+MODULE_ID("$Id: read_termcap.c,v 1.89 2013/12/15 00:32:43 tom Exp $")
 
 #if !PURE_TERMINFO
 
@@ -75,10 +73,19 @@
 
     if (!use_terminfo_vars() || (result = getenv("TERMPATH")) == 0)
 	result = TERMPATH;
-    T(("TERMPATH is %s", result));
+    TR(TRACE_DATABASE, ("TERMPATH is %s", result));
     return result;
 }
 
+/*
+ * Note:
+ * getcap(), cgetent(), etc., are BSD functions.  A copy of those was added to
+ * this file in November 1995, derived from the BSD4.4 Lite sources.
+ *
+ * The initial adaptation uses 518 lines from that source.
+ * The current source (in 2009) uses 183 lines of BSD4.4 Lite (441 ignoring
+ * whitespace).
+ */
 #if USE_GETCAP
 
 #if HAVE_BSD_CGETENT
@@ -107,11 +114,7 @@
  * 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
+ * 3. 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.
  *
@@ -158,7 +161,7 @@
 	return (-1);
     }
     gottoprec = 0;
-    (void) strcpy(toprec, ent);
+    _nc_STRCPY(toprec, ent, topreclen);
     return (0);
 }
 
@@ -291,7 +294,7 @@
 	    errno = ENOMEM;
 	    return (TC_SYS_ERR);
 	}
-	(void) strcpy(record, toprec);
+	_nc_STRCPY(record, toprec, topreclen + BFRAG);
 	rp = record + topreclen + 1;
 	r_end = rp + BFRAG;
 	current = in_array;
@@ -380,7 +383,14 @@
 			c = *bp++;
 			if (c == '\n') {
 			    lineno++;
-			    if (rp == record || *(rp - 1) != '\\')
+			    /*
+			     * Unlike BSD 4.3, this ignores a backslash at the
+			     * end of a comment-line.  That makes it consistent
+			     * with the rest of ncurses -TD
+			     */
+			    if (rp == record
+				|| *record == '#'
+				|| *(rp - 1) != '\\')
 				break;
 			}
 			*rp++ = c;
@@ -438,8 +448,10 @@
 		break;
 	}
 
-	if (!foundit)
+	if (!foundit) {
+	    free(record);
 	    return (TC_NOT_FOUND);
+	}
     }
 
     /*
@@ -451,7 +463,7 @@
 	register int newilen;
 	unsigned ilen;
 	int diff, iret, tclen, oline;
-	char *icap, *scan, *tc, *tcstart, *tcend;
+	char *icap = 0, *scan, *tc, *tcstart, *tcend;
 
 	/*
 	 * Loop invariants:
@@ -464,8 +476,9 @@
 	scan = record;
 	tc_not_resolved = FALSE;
 	for (;;) {
-	    if ((tc = _nc_cgetcap(scan, "tc", '=')) == 0)
+	    if ((tc = _nc_cgetcap(scan, "tc", '=')) == 0) {
 		break;
+	    }
 
 	    /*
 	     * Find end of tc=name and stomp on the trailing `:'
@@ -482,6 +495,7 @@
 	    tclen = s - tcstart;
 	    tcend = s;
 
+	    icap = 0;
 	    iret = _nc_getent(&icap, &ilen, &oline, current, db_array, fd,
 			      tc, depth + 1, 0);
 	    newicap = icap;	/* Put into a register. */
@@ -492,12 +506,13 @@
 		    if (myfd)
 			(void) close(fd);
 		    free(record);
+		    FreeIfNeeded(icap);
 		    return (iret);
 		}
-		if (iret == TC_UNRESOLVED)
+		if (iret == TC_UNRESOLVED) {
 		    tc_not_resolved = TRUE;
-		/* couldn't resolve tc */
-		if (iret == TC_NOT_FOUND) {
+		    /* couldn't resolve tc */
+		} else if (iret == TC_NOT_FOUND) {
 		    *(s - 1) = ':';
 		    scan = s - 1;
 		    tc_not_resolved = TRUE;
@@ -577,8 +592,9 @@
     }
 
     *cap = record;
-    if (tc_not_resolved)
+    if (tc_not_resolved) {
 	return (TC_UNRESOLVED);
+    }
     return (current);
 }
 
@@ -693,8 +709,6 @@
 #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 ':'.
@@ -756,7 +770,7 @@
 	    dst = 0;
 	    break;
 	}
-	*dst++ = ch;
+	*dst++ = (char) ch;
     }
     return dst;
 }
@@ -772,18 +786,16 @@
     register char *p;
     register char *cp;
     char *dummy = NULL;
-    char **fname;
+    CGETENT_CONST 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 */
+    CGETENT_CONST char *pathvec[PVECSIZ];	/* point to names in pathbuf */
     NCURSES_CONST char *termpath;
     string_desc desc;
 
+    *lineno = 1;
     fname = pathvec;
-    pvec = pathvec;
-    tbuf = bp;
     p = pathbuf;
     cp = use_terminfo_vars()? getenv("TERMCAP") : NULL;
 
@@ -808,10 +820,11 @@
 	    if ((home = getenv("HOME")) != 0 && *home != '\0'
 		&& strchr(home, ' ') == 0
 		&& strlen(home) < sizeof(temp) - 10) {	/* setup path */
-		sprintf(temp, "%s/", home);	/* $HOME first */
+		_nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
+			    "%s/", home);	/* $HOME first */
 	    }
 	    /* if no $HOME look in current directory */
-	    strcat(temp, ".termcap");
+	    _nc_STRCAT(temp, ".termcap", sizeof(temp));
 	    _nc_safe_strcat(&desc, temp);
 	    _nc_safe_strcat(&desc, " ");
 	    _nc_safe_strcat(&desc, get_termpath());
@@ -837,6 +850,9 @@
 	}
     }
     *fname = 0;			/* mark end of vector */
+#if !HAVE_BSD_CGETENT
+    (void) _nc_cgetset(0);
+#endif
     if (_nc_is_abs_path(cp)) {
 	if (_nc_cgetset(cp) < 0) {
 	    return (TC_SYS_ERR);
@@ -849,6 +865,7 @@
      * empty fields, and mistakenly use the last valid cap entry instead of
      * the first (breaks tc= includes)
      */
+    *bp = '\0';
     if (i >= 0) {
 	char *pd, *ps, *tok;
 	int endflag = FALSE;
@@ -870,7 +887,7 @@
 	    }
 	    if (ignore != TRUE) {
 		list[count++] = tok;
-		pd = copy_tc_token(pd, tok, TBUFSIZ - (2 + pd - bp));
+		pd = copy_tc_token(pd, tok, (size_t) (TBUFSIZ - (2 + pd - bp)));
 		if (pd == 0) {
 		    i = -1;
 		    break;
@@ -928,7 +945,7 @@
     if (count < MAXPATHS
 	&& _nc_access(path, R_OK) == 0) {
 	termpaths[count++] = path;
-	T(("Adding termpath %s", path));
+	TR(TRACE_DATABASE, ("Adding termpath %s", path));
     }
     termpaths[count] = 0;
     if (save != 0)
@@ -952,13 +969,13 @@
     static char *source;
     static int lineno;
 
-    T(("read termcap entry for %s", tn));
+    TR(TRACE_DATABASE, ("read termcap entry for %s", tn));
 
     if (strlen(tn) == 0
 	|| strcmp(tn, ".") == 0
 	|| strcmp(tn, "..") == 0
 	|| _nc_pathlast(tn) != 0) {
-	T(("illegal or missing entry name '%s'", tn));
+	TR(TRACE_DATABASE, ("illegal or missing entry name '%s'", tn));
 	return TGETENT_NO;
     }
 
@@ -976,7 +993,7 @@
 	_nc_curr_line = lineno;
 	_nc_set_source(source);
     }
-    _nc_read_entry_source((FILE *) 0, tc, FALSE, FALSE, NULLHOOK);
+    _nc_read_entry_source((FILE *) 0, tc, FALSE, TRUE, NULLHOOK);
 #else
     /*
      * Here is what the 4.4BSD termcap(3) page prescribes:
@@ -1023,7 +1040,9 @@
 	    normal = FALSE;
 	} 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);
+	    _nc_SPRINTF(tc_buf,
+			_nc_SLIMIT(sizeof(tc_buf))
+			"%.*s\n", (int) sizeof(tc_buf) - 2, tc);
 	    normal = FALSE;
 	}
     }
@@ -1045,8 +1064,9 @@
 	if (use_terminfo_vars() && (h = getenv("HOME")) != NULL && *h != '\0'
 	    && (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);
+	    _nc_STRCPY(envhome, h, sizeof(envhome));
+	    _nc_SPRINTF(pathbuf, _nc_SLIMIT(sizeof(pathbuf))
+			PRIVATE_CAP, envhome);
 	    ADD_TC(pathbuf, filecount);
 	}
     }
@@ -1059,7 +1079,7 @@
     for (j = 0; j < filecount; j++) {
 	bool omit = FALSE;
 	if (stat(termpaths[j], &test_stat[j]) != 0
-	    || (test_stat[j].st_mode & S_IFMT) != S_IFREG) {
+	    || !S_ISREG(test_stat[j].st_mode)) {
 	    omit = TRUE;
 	} else {
 	    for (k = 0; k < j; k++) {
@@ -1071,7 +1091,7 @@
 	    }
 	}
 	if (omit) {
-	    T(("Path %s is a duplicate", termpaths[j]));
+	    TR(TRACE_DATABASE, ("Path %s is a duplicate", termpaths[j]));
 	    for (k = j + 1; k < filecount; k++) {
 		termpaths[k - 1] = termpaths[k];
 		test_stat[k - 1] = test_stat[k];
@@ -1096,7 +1116,7 @@
 
 	for (i = 0; i < filecount; i++) {
 
-	    T(("Looking for %s in %s", tn, termpaths[i]));
+	    TR(TRACE_DATABASE, ("Looking for %s in %s", tn, termpaths[i]));
 	    if (_nc_access(termpaths[i], R_OK) == 0
 		&& (fp = fopen(termpaths[i], "r")) != (FILE *) 0) {
 		_nc_set_source(termpaths[i]);
@@ -1134,8 +1154,7 @@
 		 * from the list.
 		 */
 		*tp = ep->tterm;
-		_nc_delink_entry(_nc_head, &(ep->tterm));
-		free(ep);
+		_nc_free_entry(_nc_head, &(ep->tterm));
 
 		/*
 		 * OK, now try to write the type to user's terminfo directory. 
diff --git a/ncurses/tinfo/setbuf.c b/ncurses/tinfo/setbuf.c
deleted file mode 100644
index ba910e8..0000000
--- a/ncurses/tinfo/setbuf.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
- * Copyright (c) 1998-2003,2007 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("$Id: setbuf.c,v 1.13 2007/05/12 19:04:02 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.  Some implementations
- * do indeed get confused by changing setbuf on/off, and will overrun the
- * buffer.  So we disable this by default (there may yet be a workaround).
- */
-NCURSES_EXPORT(void)
-_nc_set_buffer(FILE *ofp, bool buffered)
-{
-    /* optional optimization hack -- do before any output to ofp */
-#if HAVE_SETVBUF || HAVE_SETBUFFER
-    if (SP->_buffered != buffered) {
-	unsigned buf_len;
-	char *buf_ptr;
-
-	if (getenv("NCURSES_NO_SETBUF") != 0)
-	    return;
-
-	fflush(ofp);
-#ifdef __DJGPP__
-	setmode(ofp, O_BINARY);
-#endif
-	if (buffered != 0) {
-	    buf_len = min(LINES * (COLS + 6), 2800);
-	    if ((buf_ptr = SP->_setbuf) == 0) {
-		if ((buf_ptr = typeMalloc(char, buf_len)) == NULL)
-		      return;
-		SP->_setbuf = buf_ptr;
-		/* Don't try to free this! */
-	    }
-#if !USE_SETBUF_0
-	    else
-		return;
-#endif
-	} else {
-#if !USE_SETBUF_0
-	    return;
-#else
-	    buf_len = 0;
-	    buf_ptr = 0;
-#endif
-	}
-
-#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
-
-	SP->_buffered = buffered;
-    }
-#endif /* HAVE_SETVBUF || HAVE_SETBUFFER */
-}
diff --git a/ncurses/tinfo/strings.c b/ncurses/tinfo/strings.c
index 78cd2ef..393d8e7 100644
--- a/ncurses/tinfo/strings.c
+++ b/ncurses/tinfo/strings.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2000-2003,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 2000-2007,2012 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            *
@@ -36,7 +36,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: strings.c,v 1.6 2007/08/11 17:12:17 tom Exp $")
+MODULE_ID("$Id: strings.c,v 1.8 2012/02/22 22:34:31 tom Exp $")
 
 /****************************************************************************
  * Useful string functions (especially for mvcur)
@@ -110,7 +110,7 @@
 
 	if (len < dst->s_size) {
 	    if (dst->s_tail != 0) {
-		strcpy(dst->s_tail, src);
+		_nc_STRCPY(dst->s_tail, src, dst->s_size);
 		dst->s_tail += len;
 	    }
 	    dst->s_size -= len;
@@ -131,7 +131,7 @@
 
 	if (len < dst->s_size) {
 	    if (dst->s_head != 0) {
-		strcpy(dst->s_head, src);
+		_nc_STRCPY(dst->s_head, src, dst->s_size);
 		dst->s_tail = dst->s_head + len;
 	    }
 	    dst->s_size = dst->s_init - len;
diff --git a/ncurses/tinfo/tinfo_driver.c b/ncurses/tinfo/tinfo_driver.c
new file mode 100644
index 0000000..c6a1c22
--- /dev/null
+++ b/ncurses/tinfo/tinfo_driver.c
@@ -0,0 +1,1384 @@
+/****************************************************************************
+ * Copyright (c) 2008-2014,2015 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: Juergen Pfeifer                                                 *
+ *                                                                          *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+#define CUR ((TERMINAL*)TCB)->type.
+#include <tic.h>
+
+#if HAVE_NANOSLEEP
+#include <time.h>
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>		/* needed for MacOS X DP3 */
+#endif
+#endif
+
+#if HAVE_SIZECHANGE
+# if !defined(sun) || !TERMIOS
+#  if HAVE_SYS_IOCTL_H
+#   include <sys/ioctl.h>
+#  endif
+# endif
+#endif
+
+MODULE_ID("$Id: tinfo_driver.c,v 1.40 2015/06/27 01:20:41 tom Exp $")
+
+/*
+ * 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
+
+/*
+ * These should be screen structure members.  They need to be globals for
+ * historical reasons.  So we assign them in start_color() and also in
+ * set_term()'s screen-switching logic.
+ */
+#if USE_REENTRANT
+NCURSES_EXPORT(int)
+NCURSES_PUBLIC_VAR(COLOR_PAIRS) (void)
+{
+    return CURRENT_SCREEN ? CURRENT_SCREEN->_pair_count : -1;
+}
+NCURSES_EXPORT(int)
+NCURSES_PUBLIC_VAR(COLORS) (void)
+{
+    return CURRENT_SCREEN ? CURRENT_SCREEN->_color_count : -1;
+}
+#else
+NCURSES_EXPORT_VAR(int) COLOR_PAIRS = 0;
+NCURSES_EXPORT_VAR(int) COLORS = 0;
+#endif
+
+#define TCBMAGIC NCDRV_MAGIC(NCDRV_TINFO)
+#define AssertTCB() assert(TCB!=0 && TCB->magic==TCBMAGIC)
+#define SetSP() assert(TCB->csp!=0); sp = TCB->csp; (void) sp
+
+/*
+ * This routine needs to do all the work to make curscr look
+ * like newscr.
+ */
+static int
+drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    AssertTCB();
+    return TINFO_DOUPDATE(TCB->csp);
+}
+
+static const char *
+drv_Name(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    (void) TCB;
+    return "tinfo";
+}
+
+#undef SETUP_FAIL
+#define SETUP_FAIL FALSE
+
+static bool
+drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
+{
+    bool result = FALSE;
+    int status;
+    TERMINAL *termp;
+    SCREEN *sp;
+
+    START_TRACE();
+    T((T_CALLED("tinfo::drv_CanHandle(%p)"), TCB));
+
+    assert(TCB != 0 && tname != 0);
+    termp = (TERMINAL *) TCB;
+    sp = TCB->csp;
+    TCB->magic = TCBMAGIC;
+
+#if (NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP)
+    status = _nc_setup_tinfo(tname, &termp->type);
+#else
+    status = TGETENT_NO;
+#endif
+
+    /* try fallback list if entry on disk */
+    if (status != TGETENT_YES) {
+	const TERMTYPE *fallback = _nc_fallback(tname);
+
+	if (fallback) {
+	    termp->type = *fallback;
+	    status = TGETENT_YES;
+	}
+    }
+
+    if (status != TGETENT_YES) {
+	NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx termp);
+	if (status == TGETENT_ERR) {
+	    ret_error0(status, "terminals database is inaccessible\n");
+	} else if (status == TGETENT_NO) {
+	    ret_error1(status, "unknown terminal type.\n", tname);
+	}
+    }
+    result = TRUE;
+#if !USE_REENTRANT
+    strncpy(ttytype, termp->type.term_names, (size_t) NAMESIZE - 1);
+    ttytype[NAMESIZE - 1] = '\0';
+#endif
+
+    if (command_character)
+	_nc_tinfo_cmdch(termp, *command_character);
+
+    if (generic_type) {
+	/*
+	 * BSD 4.3's termcap contains mis-typed "gn" for wy99.  Do a sanity
+	 * check before giving up.
+	 */
+	if ((VALID_STRING(cursor_address)
+	     || (VALID_STRING(cursor_down) && VALID_STRING(cursor_home)))
+	    && VALID_STRING(clear_screen)) {
+	    ret_error1(TGETENT_YES, "terminal is not really generic.\n", tname);
+	} else {
+	    ret_error1(TGETENT_NO, "I need something more specific.\n", tname);
+	}
+    }
+    if (hard_copy) {
+	ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname);
+    }
+
+    returnBool(result);
+}
+
+static int
+drv_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB, int beepFlag)
+{
+    SCREEN *sp;
+    int res = ERR;
+
+    AssertTCB();
+    SetSP();
+
+    /* FIXME: should make sure that we are not in altchar mode */
+    if (beepFlag) {
+	if (bell) {
+	    res = NCURSES_PUTP2("bell", bell);
+	    NCURSES_SP_NAME(_nc_flush) (sp);
+	} else if (flash_screen) {
+	    res = NCURSES_PUTP2("flash_screen", flash_screen);
+	    NCURSES_SP_NAME(_nc_flush) (sp);
+	}
+    } else {
+	if (flash_screen) {
+	    res = NCURSES_PUTP2("flash_screen", flash_screen);
+	    NCURSES_SP_NAME(_nc_flush) (sp);
+	} else if (bell) {
+	    res = NCURSES_PUTP2("bell", bell);
+	    NCURSES_SP_NAME(_nc_flush) (sp);
+	}
+    }
+    return res;
+}
+
+/*
+ * SVr4 curses is known to interchange color codes (1,4) and (3,6), possibly
+ * to maintain compatibility with a pre-ANSI scheme.  The same scheme is
+ * also used in the FreeBSD syscons.
+ */
+static int
+toggled_colors(int c)
+{
+    if (c < 16) {
+	static const int table[] =
+	{0, 4, 2, 6, 1, 5, 3, 7,
+	 8, 12, 10, 14, 9, 13, 11, 15};
+	c = table[c];
+    }
+    return c;
+}
+
+static int
+drv_print(TERMINAL_CONTROL_BLOCK * TCB, char *data, int len)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+#if NCURSES_EXT_FUNCS
+    return NCURSES_SP_NAME(mcprint) (TCB->csp, data, len);
+#else
+    return ERR;
+#endif
+}
+
+static int
+drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB, int fg, int bg)
+{
+    SCREEN *sp;
+    int code = ERR;
+
+    AssertTCB();
+    SetSP();
+
+    if (sp != 0 && orig_pair && orig_colors && (initialize_pair != 0)) {
+#if NCURSES_EXT_FUNCS
+	sp->_default_color = isDefaultColor(fg) || isDefaultColor(bg);
+	sp->_has_sgr_39_49 = (NCURSES_SP_NAME(tigetflag) (NCURSES_SP_ARGx
+							  "AX")
+			      == TRUE);
+	sp->_default_fg = isDefaultColor(fg) ? COLOR_DEFAULT : (fg & C_MASK);
+	sp->_default_bg = isDefaultColor(bg) ? COLOR_DEFAULT : (bg & C_MASK);
+	if (sp->_color_pairs != 0) {
+	    bool save = sp->_default_color;
+	    sp->_default_color = TRUE;
+	    NCURSES_SP_NAME(init_pair) (NCURSES_SP_ARGx
+					0,
+					(short)fg,
+					(short)bg);
+	    sp->_default_color = save;
+	}
+#endif
+	code = OK;
+    }
+    return (code);
+}
+
+static void
+drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
+	     int fore,
+	     int color,
+	     NCURSES_SP_OUTC outc)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    if (fore) {
+	if (set_a_foreground) {
+	    TPUTS_TRACE("set_a_foreground");
+	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
+				    TPARM_1(set_a_foreground, color), 1, outc);
+	} else {
+	    TPUTS_TRACE("set_foreground");
+	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
+				    TPARM_1(set_foreground,
+					    toggled_colors(color)), 1, outc);
+	}
+    } else {
+	if (set_a_background) {
+	    TPUTS_TRACE("set_a_background");
+	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
+				    TPARM_1(set_a_background, color), 1, outc);
+	} else {
+	    TPUTS_TRACE("set_background");
+	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
+				    TPARM_1(set_background,
+					    toggled_colors(color)), 1, outc);
+	}
+    }
+}
+
+static bool
+drv_rescol(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    bool result = FALSE;
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    if (orig_pair != 0) {
+	NCURSES_PUTP2("orig_pair", orig_pair);
+	result = TRUE;
+    }
+    return result;
+}
+
+static bool
+drv_rescolors(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    int result = FALSE;
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    if (orig_colors != 0) {
+	NCURSES_PUTP2("orig_colors", orig_colors);
+	result = TRUE;
+    }
+    return result;
+}
+
+static int
+drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *linep, int *colp)
+{
+    SCREEN *sp;
+    bool useEnv = TRUE;
+    bool useTioctl = TRUE;
+
+    AssertTCB();
+    sp = TCB->csp;		/* can be null here */
+
+    if (sp) {
+	useEnv = sp->_use_env;
+	useTioctl = sp->_use_tioctl;
+    } else {
+	useEnv = _nc_prescreen.use_env;
+	useTioctl = _nc_prescreen.use_tioctl;
+    }
+
+    /* figure out the size of the screen */
+    T(("screen size: terminfo lines = %d columns = %d", lines, columns));
+
+    *linep = (int) lines;
+    *colp = (int) columns;
+
+    if (useEnv || useTioctl) {
+	int value;
+
+#ifdef __EMX__
+	{
+	    int screendata[2];
+	    _scrsize(screendata);
+	    *colp = screendata[0];
+	    *linep = ((sp != 0 && sp->_filtered)
+		      ? 1
+		      : screendata[1]);
+	    T(("EMX screen size: environment LINES = %d COLUMNS = %d",
+	       *linep, *colp));
+	}
+#endif
+#if HAVE_SIZECHANGE
+	/* try asking the OS */
+	{
+	    TERMINAL *termp = (TERMINAL *) TCB;
+	    if (NC_ISATTY(termp->Filedes)) {
+		STRUCT_WINSIZE size;
+
+		errno = 0;
+		do {
+		    if (ioctl(termp->Filedes, IOCTL_WINSIZE, &size) >= 0) {
+			*linep = ((sp != 0 && sp->_filtered)
+				  ? 1
+				  : WINSIZE_ROWS(size));
+			*colp = WINSIZE_COLS(size);
+			T(("SYS screen size: environment LINES = %d COLUMNS = %d",
+			   *linep, *colp));
+			break;
+		    }
+		} while
+		    (errno == EINTR);
+	    }
+	}
+#endif /* HAVE_SIZECHANGE */
+
+	if (useEnv) {
+	    if (useTioctl) {
+		/*
+		 * If environment variables are used, update them.
+		 */
+		if ((sp == 0 || !sp->_filtered) && _nc_getenv_num("LINES") > 0) {
+		    _nc_setenv_num("LINES", *linep);
+		}
+		if (_nc_getenv_num("COLUMNS") > 0) {
+		    _nc_setenv_num("COLUMNS", *colp);
+		}
+	    }
+
+	    /*
+	     * Finally, look for environment variables.
+	     *
+	     * Solaris lets users override either dimension with an environment
+	     * variable.
+	     */
+	    if ((value = _nc_getenv_num("LINES")) > 0) {
+		*linep = value;
+		T(("screen size: environment LINES = %d", *linep));
+	    }
+	    if ((value = _nc_getenv_num("COLUMNS")) > 0) {
+		*colp = value;
+		T(("screen size: environment COLUMNS = %d", *colp));
+	    }
+	}
+
+	/* if we can't get dynamic info about the size, use static */
+	if (*linep <= 0) {
+	    *linep = (int) lines;
+	}
+	if (*colp <= 0) {
+	    *colp = (int) columns;
+	}
+
+	/* the ultimate fallback, assume fixed 24x80 size */
+	if (*linep <= 0) {
+	    *linep = 24;
+	}
+	if (*colp <= 0) {
+	    *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));
+    return OK;
+}
+
+static int
+drv_getsize(TERMINAL_CONTROL_BLOCK * TCB, int *l, int *c)
+{
+    AssertTCB();
+    assert(l != 0 && c != 0);
+    *l = lines;
+    *c = columns;
+    return OK;
+}
+
+static int
+drv_setsize(TERMINAL_CONTROL_BLOCK * TCB, int l, int c)
+{
+    AssertTCB();
+    lines = (short) l;
+    columns = (short) c;
+    return OK;
+}
+
+static int
+drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf)
+{
+    SCREEN *sp = TCB->csp;
+    TERMINAL *_term = (TERMINAL *) TCB;
+    int result = OK;
+
+    AssertTCB();
+    if (setFlag) {
+	for (;;) {
+	    if (SET_TTY(_term->Filedes, buf) != 0) {
+		if (errno == EINTR)
+		    continue;
+		if (errno == ENOTTY) {
+		    if (sp)
+			sp->_notty = TRUE;
+		}
+		result = ERR;
+	    }
+	    break;
+	}
+    } else {
+	for (;;) {
+	    if (GET_TTY(_term->Filedes, buf) != 0) {
+		if (errno == EINTR)
+		    continue;
+		result = ERR;
+	    }
+	    break;
+	}
+    }
+    return result;
+}
+
+static int
+drv_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag)
+{
+    SCREEN *sp;
+    TERMINAL *_term = (TERMINAL *) TCB;
+    int code = ERR;
+
+    AssertTCB();
+    sp = TCB->csp;
+
+    if (progFlag)		/* prog mode */
+    {
+	if (defFlag) {
+	    /* def_prog_mode */
+	    /*
+	     * Turn off the XTABS bit in the tty structure if it was on.
+	     */
+	    if ((drv_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
+#ifdef TERMIOS
+		_term->Nttyb.c_oflag &= (unsigned) ~OFLAGS_TABS;
+#else
+		_term->Nttyb.sg_flags &= (unsigned) ~XTABS;
+#endif
+		code = OK;
+	    }
+	} else {
+	    /* reset_prog_mode */
+	    if (drv_sgmode(TCB, TRUE, &(_term->Nttyb)) == OK) {
+		if (sp) {
+		    if (sp->_keypad_on)
+			_nc_keypad(sp, TRUE);
+		}
+		code = OK;
+	    }
+	}
+    } else {			/* shell mode */
+	if (defFlag) {
+	    /* def_shell_mode */
+	    /*
+	     * If XTABS was on, remove the tab and backtab capabilities.
+	     */
+	    if (drv_sgmode(TCB, FALSE, &(_term->Ottyb)) == OK) {
+#ifdef TERMIOS
+		if (_term->Ottyb.c_oflag & OFLAGS_TABS)
+		    tab = back_tab = NULL;
+#else
+		if (_term->Ottyb.sg_flags & XTABS)
+		    tab = back_tab = NULL;
+#endif
+		code = OK;
+	    }
+	} else {
+	    /* reset_shell_mode */
+	    if (sp) {
+		_nc_keypad(sp, FALSE);
+		NCURSES_SP_NAME(_nc_flush) (sp);
+	    }
+	    code = drv_sgmode(TCB, TRUE, &(_term->Ottyb));
+	}
+    }
+    return (code);
+}
+
+static void
+drv_wrap(SCREEN *sp)
+{
+    if (sp) {
+	sp->_mouse_wrap(sp);
+	NCURSES_SP_NAME(_nc_screen_wrap) (sp);
+	NCURSES_SP_NAME(_nc_mvcur_wrap) (sp);	/* wrap up cursor addressing */
+    }
+}
+
+static void
+drv_release(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED)
+{
+}
+
+#  define SGR0_TEST(mode) (mode != 0) && (exit_attribute_mode == 0 || strcmp(mode, exit_attribute_mode))
+
+static void
+drv_screen_init(SCREEN *sp)
+{
+    TERMINAL_CONTROL_BLOCK *TCB = TCBOf(sp);
+
+    AssertTCB();
+
+    /*
+     * Check for mismatched graphic-rendition capabilities.  Most SVr4
+     * terminfo trees contain entries that have rmul or rmso equated to
+     * sgr0 (Solaris curses copes with those entries).  We do this only
+     * for curses, since many termcap applications assume that
+     * smso/rmso and smul/rmul are paired, and will not function
+     * properly if we remove rmso or rmul.  Curses applications
+     * shouldn't be looking at this detail.
+     */
+    sp->_use_rmso = SGR0_TEST(exit_standout_mode);
+    sp->_use_rmul = SGR0_TEST(exit_underline_mode);
+
+    /*
+     * Check whether we can optimize scrolling under dumb terminals in
+     * case we do not have any of these capabilities, scrolling
+     * optimization will be useless.
+     */
+    sp->_scrolling = ((scroll_forward && scroll_reverse) ||
+		      ((parm_rindex ||
+			parm_insert_line ||
+			insert_line) &&
+		       (parm_index ||
+			parm_delete_line ||
+			delete_line)));
+
+    NCURSES_SP_NAME(baudrate) (sp);
+
+    NCURSES_SP_NAME(_nc_mvcur_init) (sp);
+    /* initialize terminal to a sane state */
+    NCURSES_SP_NAME(_nc_screen_init) (sp);
+}
+
+static void
+drv_init(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    TERMINAL *trm;
+
+    AssertTCB();
+
+    trm = (TERMINAL *) TCB;
+
+    TCB->info.initcolor = VALID_STRING(initialize_color);
+    TCB->info.canchange = can_change;
+    TCB->info.hascolor = ((VALID_NUMERIC(max_colors) && VALID_NUMERIC(max_pairs)
+			   && (((set_foreground != NULL)
+				&& (set_background != NULL))
+			       || ((set_a_foreground != NULL)
+				   && (set_a_background != NULL))
+			       || set_color_pair)) ? TRUE : FALSE);
+
+    TCB->info.caninit = !(exit_ca_mode && non_rev_rmcup);
+
+    TCB->info.maxpairs = VALID_NUMERIC(max_pairs) ? max_pairs : 0;
+    TCB->info.maxcolors = VALID_NUMERIC(max_colors) ? max_colors : 0;
+    TCB->info.numlabels = VALID_NUMERIC(num_labels) ? num_labels : 0;
+    TCB->info.labelwidth = VALID_NUMERIC(label_width) ? label_width : 0;
+    TCB->info.labelheight = VALID_NUMERIC(label_height) ? label_height : 0;
+    TCB->info.nocolorvideo = VALID_NUMERIC(no_color_video) ? no_color_video
+	: 0;
+    TCB->info.tabsize = VALID_NUMERIC(init_tabs) ? (int) init_tabs : 8;
+
+    TCB->info.defaultPalette = hue_lightness_saturation ? _nc_hls_palette : _nc_cga_palette;
+
+    /*
+     * If an application calls setupterm() rather than initscr() or
+     * newterm(), we will not have the def_prog_mode() call in
+     * _nc_setupscreen().  Do it now anyway, so we can initialize the
+     * baudrate.
+     */
+    if (NC_ISATTY(trm->Filedes)) {
+	TCB->drv->td_mode(TCB, TRUE, TRUE);
+    }
+}
+
+#define MAX_PALETTE	8
+#define InPalette(n)	((n) >= 0 && (n) < MAX_PALETTE)
+
+static void
+drv_initpair(TERMINAL_CONTROL_BLOCK * TCB, int pair, int f, int b)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    if ((initialize_pair != NULL) && InPalette(f) && InPalette(b)) {
+	const color_t *tp = InfoOf(sp).defaultPalette;
+
+	TR(TRACE_ATTRS,
+	   ("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)",
+	    pair,
+	    tp[f].red, tp[f].green, tp[f].blue,
+	    tp[b].red, tp[b].green, tp[b].blue));
+
+	NCURSES_PUTP2("initialize_pair",
+		      TPARM_7(initialize_pair,
+			      pair,
+			      tp[f].red, tp[f].green, tp[f].blue,
+			      tp[b].red, tp[b].green, tp[b].blue));
+    }
+}
+
+static int
+default_fg(SCREEN *sp)
+{
+#if NCURSES_EXT_FUNCS
+    return (sp != 0) ? sp->_default_fg : COLOR_WHITE;
+#else
+    return COLOR_WHITE;
+#endif
+}
+
+static int
+default_bg(SCREEN *sp)
+{
+#if NCURSES_EXT_FUNCS
+    return sp != 0 ? sp->_default_bg : COLOR_BLACK;
+#else
+    return COLOR_BLACK;
+#endif
+}
+
+static void
+drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
+	      int color, int r, int g, int b)
+{
+    SCREEN *sp = TCB->csp;
+
+    AssertTCB();
+    if (initialize_color != NULL) {
+	NCURSES_PUTP2("initialize_color",
+		      TPARM_4(initialize_color, color, r, g, b));
+    }
+}
+
+static void
+drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
+	     int old_pair,
+	     int pair,
+	     int reverse,
+	     NCURSES_SP_OUTC outc)
+{
+    SCREEN *sp = TCB->csp;
+    NCURSES_COLOR_T fg = COLOR_DEFAULT;
+    NCURSES_COLOR_T bg = COLOR_DEFAULT;
+    NCURSES_COLOR_T old_fg, old_bg;
+
+    AssertTCB();
+    if (sp == 0)
+	return;
+
+    if (pair < 0 || pair >= COLOR_PAIRS) {
+	return;
+    } else if (pair != 0) {
+	if (set_color_pair) {
+	    TPUTS_TRACE("set_color_pair");
+	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
+				    TPARM_1(set_color_pair, pair), 1, outc);
+	    return;
+	} else if (sp != 0) {
+	    NCURSES_SP_NAME(pair_content) (NCURSES_SP_ARGx
+					   (short) pair,
+					   &fg,
+					   &bg);
+	}
+    }
+
+    if (old_pair >= 0
+	&& sp != 0
+	&& NCURSES_SP_NAME(pair_content) (NCURSES_SP_ARGx
+					  (short) old_pair,
+					  &old_fg,
+					  &old_bg) !=ERR) {
+	if ((isDefaultColor(fg) && !isDefaultColor(old_fg))
+	    || (isDefaultColor(bg) && !isDefaultColor(old_bg))) {
+#if NCURSES_EXT_FUNCS
+	    /*
+	     * A minor optimization - but extension.  If "AX" is specified in
+	     * the terminal description, treat it as screen's indicator of ECMA
+	     * SGR 39 and SGR 49, and assume the two sequences are independent.
+	     */
+	    if (sp->_has_sgr_39_49
+		&& isDefaultColor(old_bg)
+		&& !isDefaultColor(old_fg)) {
+		NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx "\033[39m", 1, outc);
+	    } else if (sp->_has_sgr_39_49
+		       && isDefaultColor(old_fg)
+		       && !isDefaultColor(old_bg)) {
+		NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx "\033[49m", 1, outc);
+	    } else
+#endif
+		drv_rescol(TCB);
+	}
+    } else {
+	drv_rescol(TCB);
+	if (old_pair < 0)
+	    return;
+    }
+
+#if NCURSES_EXT_FUNCS
+    if (isDefaultColor(fg))
+	fg = (NCURSES_COLOR_T) default_fg(sp);
+    if (isDefaultColor(bg))
+	bg = (NCURSES_COLOR_T) default_bg(sp);
+#endif
+
+    if (reverse) {
+	NCURSES_COLOR_T xx = fg;
+	fg = bg;
+	bg = xx;
+    }
+
+    TR(TRACE_ATTRS, ("setting colors: pair = %d, fg = %d, bg = %d", pair,
+		     fg, bg));
+
+    if (!isDefaultColor(fg)) {
+	drv_setcolor(TCB, TRUE, fg, outc);
+    }
+    if (!isDefaultColor(bg)) {
+	drv_setcolor(TCB, FALSE, bg, outc);
+    }
+}
+
+#define xterm_kmous "\033[M"
+static void
+init_xterm_mouse(SCREEN *sp)
+{
+    sp->_mouse_type = M_XTERM;
+    sp->_mouse_xtermcap = NCURSES_SP_NAME(tigetstr) (NCURSES_SP_ARGx "XM");
+    if (!VALID_STRING(sp->_mouse_xtermcap))
+	sp->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;";
+}
+
+static void
+drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    /* we know how to recognize mouse events under "xterm" */
+    if (sp != 0) {
+	if (key_mouse != 0) {
+	    if (!strcmp(key_mouse, xterm_kmous)
+		|| strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) {
+		init_xterm_mouse(sp);
+	    }
+	} else if (strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) {
+	    if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK)
+		init_xterm_mouse(sp);
+	}
+    }
+}
+
+static int
+drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB,
+	      int delay
+	      EVENTLIST_2nd(_nc_eventlist * evl))
+{
+    int rc = 0;
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+#if USE_SYSMOUSE
+    if ((sp->_mouse_type == M_SYSMOUSE)
+	&& (sp->_sysmouse_head < sp->_sysmouse_tail)) {
+	rc = TW_MOUSE;
+    } else
+#endif
+    {
+	rc = TCBOf(sp)->drv->td_twait(TCBOf(sp),
+				      TWAIT_MASK,
+				      delay,
+				      (int *) 0
+				      EVENTLIST_2nd(evl));
+#if USE_SYSMOUSE
+	if ((sp->_mouse_type == M_SYSMOUSE)
+	    && (sp->_sysmouse_head < sp->_sysmouse_tail)
+	    && (rc == 0)
+	    && (errno == EINTR)) {
+	    rc |= TW_MOUSE;
+	}
+#endif
+    }
+    return rc;
+}
+
+static int
+drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB, int yold, int xold, int ynew, int xnew)
+{
+    SCREEN *sp = TCB->csp;
+    AssertTCB();
+    return NCURSES_SP_NAME(_nc_mvcur) (sp, yold, xold, ynew, xnew);
+}
+
+static void
+drv_hwlabel(TERMINAL_CONTROL_BLOCK * TCB, int labnum, char *text)
+{
+    SCREEN *sp = TCB->csp;
+
+    AssertTCB();
+    if (labnum > 0 && labnum <= num_labels) {
+	NCURSES_PUTP2("plab_norm",
+		      TPARM_2(plab_norm, labnum, text));
+    }
+}
+
+static void
+drv_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB, int OnFlag)
+{
+    SCREEN *sp = TCB->csp;
+
+    AssertTCB();
+    if (OnFlag) {
+	NCURSES_PUTP2("label_on", label_on);
+    } else {
+	NCURSES_PUTP2("label_off", label_off);
+    }
+}
+
+static chtype
+drv_conattr(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    SCREEN *sp = TCB->csp;
+    chtype attrs = A_NORMAL;
+
+    AssertTCB();
+    if (enter_alt_charset_mode)
+	attrs |= A_ALTCHARSET;
+
+    if (enter_blink_mode)
+	attrs |= A_BLINK;
+
+    if (enter_bold_mode)
+	attrs |= A_BOLD;
+
+    if (enter_dim_mode)
+	attrs |= A_DIM;
+
+    if (enter_reverse_mode)
+	attrs |= A_REVERSE;
+
+    if (enter_standout_mode)
+	attrs |= A_STANDOUT;
+
+    if (enter_protected_mode)
+	attrs |= A_PROTECT;
+
+    if (enter_secure_mode)
+	attrs |= A_INVIS;
+
+    if (enter_underline_mode)
+	attrs |= A_UNDERLINE;
+
+    if (sp && sp->_coloron)
+	attrs |= A_COLOR;
+
+#if USE_ITALIC
+    if (enter_italics_mode)
+	attrs |= A_ITALIC;
+#endif
+
+    return (attrs);
+}
+
+static void
+drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB)
+{
+    AssertTCB();
+
+    clear_screen = 0;
+    cursor_down = parm_down_cursor = 0;
+    cursor_address = 0;
+    cursor_up = parm_up_cursor = 0;
+    row_address = 0;
+    cursor_home = carriage_return;
+}
+
+static void
+drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *real_map, chtype *fake_map)
+{
+    SCREEN *sp = TCB->csp;
+
+    AssertTCB();
+    assert(sp != 0);
+    if (ena_acs != NULL) {
+	NCURSES_PUTP2("ena_acs", ena_acs);
+    }
+#if NCURSES_EXT_FUNCS
+    /*
+     * Linux console "supports" the "PC ROM" character set by the coincidence
+     * that smpch/rmpch and smacs/rmacs have the same values.  ncurses has
+     * no codepage support (see SCO Merge for an example).  Outside of the
+     * values defined in acsc, there are no definitions for the "PC ROM"
+     * character set (assumed by some applications to be codepage 437), but we
+     * allow those applications to use those codepoints.
+     *
+     * test/blue.c uses this feature.
+     */
+#define PCH_KLUDGE(a,b) (a != 0 && b != 0 && !strcmp(a,b))
+    if (PCH_KLUDGE(enter_pc_charset_mode, enter_alt_charset_mode) &&
+	PCH_KLUDGE(exit_pc_charset_mode, exit_alt_charset_mode)) {
+	size_t i;
+	for (i = 1; i < ACS_LEN; ++i) {
+	    if (real_map[i] == 0) {
+		real_map[i] = (chtype) i;
+		if (real_map != fake_map) {
+		    if (sp != 0)
+			sp->_screen_acs_map[i] = TRUE;
+		}
+	    }
+	}
+    }
+#endif
+
+    if (acs_chars != NULL) {
+	size_t i = 0;
+	size_t length = strlen(acs_chars);
+
+	while (i + 1 < length) {
+	    if (acs_chars[i] != 0 && UChar(acs_chars[i]) < ACS_LEN) {
+		real_map[UChar(acs_chars[i])] = UChar(acs_chars[i + 1]) | A_ALTCHARSET;
+		if (sp != 0)
+		    sp->_screen_acs_map[UChar(acs_chars[i])] = TRUE;
+	    }
+	    i += 2;
+	}
+    }
+#ifdef TRACE
+    /* Show the equivalent mapping, noting if it does not match the
+     * given attribute, whether by re-ordering or duplication.
+     */
+    if (USE_TRACEF(TRACE_CALLS)) {
+	size_t n, m;
+	char show[ACS_LEN * 2 + 1];
+	for (n = 1, m = 0; n < ACS_LEN; n++) {
+	    if (real_map[n] != 0) {
+		show[m++] = (char) n;
+		show[m++] = (char) ChCharOf(real_map[n]);
+	    }
+	}
+	show[m] = 0;
+	if (acs_chars == NULL || strcmp(acs_chars, show))
+	    _tracef("%s acs_chars %s",
+		    (acs_chars == NULL) ? "NULL" : "READ",
+		    _nc_visbuf(acs_chars));
+	_tracef("%s acs_chars %s",
+		(acs_chars == NULL)
+		? "NULL"
+		: (strcmp(acs_chars, show)
+		   ? "DIFF"
+		   : "SAME"),
+		_nc_visbuf(show));
+
+	_nc_unlock_global(tracef);
+    }
+#endif /* TRACE */
+}
+
+#define ENSURE_TINFO(sp) (TCBOf(sp)->drv->isTerminfo)
+
+NCURSES_EXPORT(void)
+_nc_cookie_init(SCREEN *sp)
+{
+    bool support_cookies = USE_XMC_SUPPORT;
+    TERMINAL_CONTROL_BLOCK *TCB = (TERMINAL_CONTROL_BLOCK *) (sp->_term);
+
+    if (sp == 0 || !ENSURE_TINFO(sp))
+	return;
+
+#if USE_XMC_SUPPORT
+    /*
+     * If we have no magic-cookie support compiled-in, or if it is suppressed
+     * in the environment, reset the support-flag.
+     */
+    if (magic_cookie_glitch >= 0) {
+	if (getenv("NCURSES_NO_MAGIC_COOKIE") != 0) {
+	    support_cookies = FALSE;
+	}
+    }
+#endif
+
+    if (!support_cookies && magic_cookie_glitch >= 0) {
+	T(("will disable attributes to work w/o magic cookies"));
+    }
+
+    if (magic_cookie_glitch > 0) {	/* tvi, wyse */
+
+	sp->_xmc_triggers = sp->_ok_attributes & XMC_CONFLICT;
+#if 0
+	/*
+	 * We "should" treat colors as an attribute.  The wyse350 (and its
+	 * clones) appear to be the only ones that have both colors and magic
+	 * cookies.
+	 */
+	if (has_colors()) {
+	    sp->_xmc_triggers |= A_COLOR;
+	}
+#endif
+	sp->_xmc_suppress = sp->_xmc_triggers & (chtype) ~(A_BOLD);
+
+	T(("magic cookie attributes %s", _traceattr(sp->_xmc_suppress)));
+	/*
+	 * Supporting line-drawing may be possible.  But make the regular
+	 * video attributes work first.
+	 */
+	acs_chars = ABSENT_STRING;
+	ena_acs = ABSENT_STRING;
+	enter_alt_charset_mode = ABSENT_STRING;
+	exit_alt_charset_mode = ABSENT_STRING;
+#if USE_XMC_SUPPORT
+	/*
+	 * To keep the cookie support simple, suppress all of the optimization
+	 * hooks except for clear_screen and the cursor addressing.
+	 */
+	if (support_cookies) {
+	    clr_eol = ABSENT_STRING;
+	    clr_eos = ABSENT_STRING;
+	    set_attributes = ABSENT_STRING;
+	}
+#endif
+    } else if (magic_cookie_glitch == 0) {	/* hpterm */
+    }
+
+    /*
+     * If magic cookies are not supported, cancel the strings that set
+     * video attributes.
+     */
+    if (!support_cookies && magic_cookie_glitch >= 0) {
+	magic_cookie_glitch = ABSENT_NUMERIC;
+	set_attributes = ABSENT_STRING;
+	enter_blink_mode = ABSENT_STRING;
+	enter_bold_mode = ABSENT_STRING;
+	enter_dim_mode = ABSENT_STRING;
+	enter_reverse_mode = ABSENT_STRING;
+	enter_standout_mode = ABSENT_STRING;
+	enter_underline_mode = ABSENT_STRING;
+    }
+
+    /* initialize normal acs before wide, since we use mapping in the latter */
+#if !USE_WIDEC_SUPPORT
+    if (_nc_unicode_locale() && _nc_locale_breaks_acs(sp->_term)) {
+	acs_chars = NULL;
+	ena_acs = NULL;
+	enter_alt_charset_mode = NULL;
+	exit_alt_charset_mode = NULL;
+	set_attributes = NULL;
+    }
+#endif
+}
+
+static int
+drv_twait(TERMINAL_CONTROL_BLOCK * TCB,
+	  int mode,
+	  int milliseconds,
+	  int *timeleft
+	  EVENTLIST_2nd(_nc_eventlist * evl))
+{
+    SCREEN *sp;
+
+    AssertTCB();
+    SetSP();
+
+    return _nc_timed_wait(sp, mode, milliseconds, timeleft EVENTLIST_2nd(evl));
+}
+
+static int
+drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
+{
+    SCREEN *sp;
+    unsigned char c2 = 0;
+    int n;
+
+    AssertTCB();
+    assert(buf);
+    SetSP();
+
+# if USE_PTHREADS_EINTR
+    if ((pthread_self) && (pthread_kill) && (pthread_equal))
+	_nc_globals.read_thread = pthread_self();
+# endif
+    n = (int) read(sp->_ifd, &c2, (size_t) 1);
+#if USE_PTHREADS_EINTR
+    _nc_globals.read_thread = 0;
+#endif
+    *buf = (int) c2;
+    return n;
+}
+
+static int
+drv_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms)
+{
+#if HAVE_NANOSLEEP
+    {
+	struct timespec request, remaining;
+	request.tv_sec = ms / 1000;
+	request.tv_nsec = (ms % 1000) * 1000000;
+	while (nanosleep(&request, &remaining) == -1
+	       && errno == EINTR) {
+	    request = remaining;
+	}
+    }
+#else
+    _nc_timed_wait(0, 0, ms, (int *) 0 EVENTLIST_2nd(0));
+#endif
+    return OK;
+}
+
+static int
+__nc_putp(SCREEN *sp, const char *name GCC_UNUSED, const char *value)
+{
+    int rc = ERR;
+
+    if (value) {
+	rc = NCURSES_PUTP2(name, value);
+    }
+    return rc;
+}
+
+static int
+__nc_putp_flush(SCREEN *sp, const char *name, const char *value)
+{
+    int rc = __nc_putp(sp, name, value);
+    if (rc != ERR) {
+	NCURSES_SP_NAME(_nc_flush) (sp);
+    }
+    return rc;
+}
+
+static int
+drv_kpad(TERMINAL_CONTROL_BLOCK * TCB, int flag)
+{
+    int ret = ERR;
+    SCREEN *sp;
+
+    AssertTCB();
+
+    sp = TCB->csp;
+
+    if (sp) {
+	if (flag) {
+	    (void) __nc_putp_flush(sp, "keypad_xmit", keypad_xmit);
+	} else if (!flag && keypad_local) {
+	    (void) __nc_putp_flush(sp, "keypad_local", keypad_local);
+	}
+	if (flag && !sp->_tried) {
+	    _nc_init_keytry(sp);
+	    sp->_tried = TRUE;
+	}
+	ret = OK;
+    }
+
+    return ret;
+}
+
+static int
+drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int c, int flag)
+{
+    SCREEN *sp;
+    int code = ERR;
+    int count = 0;
+    char *s;
+
+    AssertTCB();
+    SetSP();
+
+    if (c >= 0) {
+	unsigned ch = (unsigned) c;
+	if (flag) {
+	    while ((s = _nc_expand_try(sp->_key_ok,
+				       ch, &count, (size_t) 0)) != 0
+		   && _nc_remove_key(&(sp->_key_ok), ch)) {
+		code = _nc_add_to_try(&(sp->_keytry), s, ch);
+		free(s);
+		count = 0;
+		if (code != OK)
+		    break;
+	    }
+	} else {
+	    while ((s = _nc_expand_try(sp->_keytry,
+				       ch, &count, (size_t) 0)) != 0
+		   && _nc_remove_key(&(sp->_keytry), ch)) {
+		code = _nc_add_to_try(&(sp->_key_ok), s, ch);
+		free(s);
+		count = 0;
+		if (code != OK)
+		    break;
+	    }
+	}
+    }
+    return (code);
+}
+
+static int
+drv_cursorSet(TERMINAL_CONTROL_BLOCK * TCB, int vis)
+{
+    SCREEN *sp;
+    int code = ERR;
+
+    AssertTCB();
+    SetSP();
+
+    T((T_CALLED("tinfo:drv_cursorSet(%p,%d)"), (void *) SP_PARM, vis));
+
+    if (SP_PARM != 0 && IsTermInfo(SP_PARM)) {
+	switch (vis) {
+	case 2:
+	    code = NCURSES_PUTP2_FLUSH("cursor_visible", cursor_visible);
+	    break;
+	case 1:
+	    code = NCURSES_PUTP2_FLUSH("cursor_normal", cursor_normal);
+	    break;
+	case 0:
+	    code = NCURSES_PUTP2_FLUSH("cursor_invisible", cursor_invisible);
+	    break;
+	}
+    } else {
+	code = ERR;
+    }
+    returnCode(code);
+}
+
+static bool
+drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int key)
+{
+    bool res = FALSE;
+
+    AssertTCB();
+    if (TCB->csp)
+	res = TINFO_HAS_KEY(TCB->csp, key) == 0 ? FALSE : TRUE;
+
+    return res;
+}
+
+NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_TINFO_DRIVER = {
+    TRUE,
+	drv_Name,		/* Name */
+	drv_CanHandle,		/* CanHandle */
+	drv_init,		/* init */
+	drv_release,		/* release */
+	drv_size,		/* size */
+	drv_sgmode,		/* sgmode */
+	drv_conattr,		/* conattr */
+	drv_mvcur,		/* hwcur */
+	drv_mode,		/* mode */
+	drv_rescol,		/* rescol */
+	drv_rescolors,		/* rescolors */
+	drv_setcolor,		/* color */
+	drv_dobeepflash,	/* doBeepOrFlash */
+	drv_initpair,		/* initpair */
+	drv_initcolor,		/* initcolor */
+	drv_do_color,		/* docolor */
+	drv_initmouse,		/* initmouse */
+	drv_testmouse,		/* testmouse */
+	drv_setfilter,		/* setfilter */
+	drv_hwlabel,		/* hwlabel */
+	drv_hwlabelOnOff,	/* hwlabelOnOff */
+	drv_doupdate,		/* update */
+	drv_defaultcolors,	/* defaultcolors */
+	drv_print,		/* print */
+	drv_getsize,		/* getsize */
+	drv_setsize,		/* setsize */
+	drv_initacs,		/* initacs */
+	drv_screen_init,	/* scinit */
+	drv_wrap,		/* scexit */
+	drv_twait,		/* twait  */
+	drv_read,		/* read */
+	drv_nap,		/* nap */
+	drv_kpad,		/* kpad */
+	drv_keyok,		/* kyOk */
+	drv_kyExist,		/* kyExist */
+	drv_cursorSet		/* cursorSet */
+};
diff --git a/ncurses/tinfo/trim_sgr0.c b/ncurses/tinfo/trim_sgr0.c
index 80c8f77..ec5e2b7 100644
--- a/ncurses/tinfo/trim_sgr0.c
+++ b/ncurses/tinfo/trim_sgr0.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2005-2006,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 2005-2010,2012 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            *
@@ -35,9 +35,8 @@
 #include <ctype.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: trim_sgr0.c,v 1.8 2007/04/07 17:14:11 tom Exp $")
+MODULE_ID("$Id: trim_sgr0.c,v 1.15 2012/12/15 20:57:17 tom Exp $")
 
 #undef CUR
 #define CUR tp->
@@ -49,21 +48,28 @@
 static char *
 set_attribute_9(TERMTYPE *tp, int flag)
 {
-    const char *result;
+    const char *value;
+    char *result;
 
-    if ((result = tparm(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, flag)) == 0)
-	result = "";
-    return strdup(result);
+    value = tparm(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, flag);
+    if (PRESENT(value))
+	result = strdup(value);
+    else
+	result = 0;
+    return result;
 }
 
 static int
 is_csi(const char *s)
 {
-    if (UChar(s[0]) == CSI)
-	return 1;
-    else if (s[0] == ESC && s[1] == L_BRACK)
-	return 2;
-    return 0;
+    int result = 0;
+    if (s != 0) {
+	if (UChar(s[0]) == CSI)
+	    result = 1;
+	else if (s[0] == ESC && s[1] == L_BRACK)
+	    result = 2;
+    }
+    return result;
 }
 
 static char *
@@ -98,10 +104,10 @@
 static bool
 rewrite_sgr(char *s, char *attr)
 {
-    if (PRESENT(s)) {
+    if (s != 0) {
 	if (PRESENT(attr)) {
-	    unsigned len_s = strlen(s);
-	    unsigned len_a = strlen(attr);
+	    size_t len_s = strlen(s);
+	    size_t len_a = strlen(attr);
 
 	    if (len_s > len_a && !strncmp(attr, s, len_a)) {
 		unsigned n;
@@ -109,7 +115,7 @@
 		for (n = 0; n < len_s - len_a; ++n) {
 		    s[n] = s[n + len_a];
 		}
-		strcpy(s + n, attr);
+		_nc_STRCPY(s + n, attr, strlen(s) + 1);
 		TR(TRACE_DATABASE, ("to:\n\t%s", s));
 	    }
 	}
@@ -122,33 +128,35 @@
 similar_sgr(char *a, char *b)
 {
     bool result = FALSE;
-    int csi_a = is_csi(a);
-    int csi_b = is_csi(b);
-    unsigned len_a;
-    unsigned len_b;
+    if (a != 0 && b != 0) {
+	int csi_a = is_csi(a);
+	int csi_b = is_csi(b);
+	size_t len_a;
+	size_t len_b;
 
-    TR(TRACE_DATABASE, ("similar_sgr:\n\t%s\n\t%s",
-			_nc_visbuf2(1, a),
-			_nc_visbuf2(2, b)));
-    if (csi_a != 0 && csi_b != 0 && csi_a == csi_b) {
-	a += csi_a;
-	b += csi_b;
-	if (*a != *b) {
-	    a = skip_zero(a);
-	    b = skip_zero(b);
+	TR(TRACE_DATABASE, ("similar_sgr:\n\t%s\n\t%s",
+			    _nc_visbuf2(1, a),
+			    _nc_visbuf2(2, b)));
+	if (csi_a != 0 && csi_b != 0 && csi_a == csi_b) {
+	    a += csi_a;
+	    b += csi_b;
+	    if (*a != *b) {
+		a = skip_zero(a);
+		b = skip_zero(b);
+	    }
 	}
+	len_a = strlen(a);
+	len_b = strlen(b);
+	if (len_a && len_b) {
+	    if (len_a > len_b)
+		result = (strncmp(a, b, len_b) == 0);
+	    else
+		result = (strncmp(a, b, len_a) == 0);
+	}
+	TR(TRACE_DATABASE, ("...similar_sgr: %d\n\t%s\n\t%s", result,
+			    _nc_visbuf2(1, a),
+			    _nc_visbuf2(2, b)));
     }
-    len_a = strlen(a);
-    len_b = strlen(b);
-    if (len_a && len_b) {
-	if (len_a > len_b)
-	    result = (strncmp(a, b, len_b) == 0);
-	else
-	    result = (strncmp(a, b, len_a) == 0);
-    }
-    TR(TRACE_DATABASE, ("...similar_sgr: %d\n\t%s\n\t%s", result,
-			_nc_visbuf2(1, a),
-			_nc_visbuf2(2, b)));
     return result;
 }
 
@@ -170,13 +178,13 @@
  * Returns the number of chars from 'full' that we matched.  If any mismatch
  * occurs, return zero.
  */
-static int
+static unsigned
 compare_part(const char *part, const char *full)
 {
     const char *next_part;
     const char *next_full;
-    int used_full = 0;
-    int used_delay = 0;
+    unsigned used_full = 0;
+    unsigned used_delay = 0;
 
     while (*part != 0) {
 	if (*part != *full) {
@@ -199,7 +207,7 @@
 	    next_part = skip_delay(part);
 	    next_full = skip_delay(full);
 	    if (next_part != part && next_full != full) {
-		used_delay += (next_full - full);
+		used_delay += (unsigned) (next_full - full);
 		full = next_full;
 		part = next_part;
 		continue;
@@ -261,10 +269,11 @@
 		k = strlen(exit_alt_charset_mode);
 		if (j > k) {
 		    for (i = 0; i <= (j - k); ++i) {
-			int k2 = compare_part(exit_alt_charset_mode, off + i);
+			unsigned k2 = compare_part(exit_alt_charset_mode,
+						   off + i);
 			if (k2 != 0) {
 			    found = TRUE;
-			    chop_out(off, i, i + k2);
+			    chop_out(off, (unsigned) i, (unsigned) (i + k2));
 			    break;
 			}
 		    }
@@ -274,18 +283,18 @@
 	     * SGR 10 would reset to normal font.
 	     */
 	    if (!found) {
-		if ((i = is_csi(off)) != 0
+		if ((i = (size_t) is_csi(off)) != 0
 		    && off[strlen(off) - 1] == 'm') {
 		    TR(TRACE_DATABASE, ("looking for SGR 10 in %s",
 					_nc_visbuf(off)));
 		    tmp = skip_zero(off + i);
 		    if (tmp[0] == '1'
 			&& skip_zero(tmp + 1) != tmp + 1) {
-			i = tmp - off;
+			i = (size_t) (tmp - off);
 			if (off[i - 1] == ';')
 			    i--;
-			j = skip_zero(tmp + 1) - off;
-			i = chop_out(off, i, j);
+			j = (size_t) (skip_zero(tmp + 1) - off);
+			(void) chop_out(off, (unsigned) i, (unsigned) j);
 			found = TRUE;
 		    }
 		}
@@ -293,10 +302,10 @@
 	    if (!found
 		&& (tmp = strstr(end, off)) != 0
 		&& strcmp(end, off) != 0) {
-		i = tmp - end;
+		i = (size_t) (tmp - end);
 		j = strlen(off);
 		tmp = strdup(end);
-		chop_out(tmp, i, j);
+		chop_out(tmp, (unsigned) i, (unsigned) j);
 		free(off);
 		result = tmp;
 	    }
diff --git a/ncurses/tinfo/use_screen.c b/ncurses/tinfo/use_screen.c
index 6c3b12f..6a0297c 100644
--- a/ncurses/tinfo/use_screen.c
+++ b/ncurses/tinfo/use_screen.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2007,2008 Free Software Foundation, Inc.                   *
+ * Copyright (c) 2007-2008,2009 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            *
@@ -32,7 +32,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: use_screen.c,v 1.6 2008/06/07 19:16:56 tom Exp $")
+MODULE_ID("$Id: use_screen.c,v 1.8 2009/10/24 22:40:20 tom Exp $")
 
 NCURSES_EXPORT(int)
 use_screen(SCREEN *screen, NCURSES_SCREEN_CB func, void *data)
@@ -40,14 +40,14 @@
     SCREEN *save_SP;
     int code = OK;
 
-    T((T_CALLED("use_screen(%p,%p,%p)"), screen, func, data));
+    T((T_CALLED("use_screen(%p,%p,%p)"), (void *) screen, func, (void *) data));
 
     /*
      * FIXME - add a flag so a given thread can check if _it_ has already
      * recurred through this point, return an error if so.
      */
     _nc_lock_global(curses);
-    save_SP = SP;
+    save_SP = CURRENT_SCREEN;
     set_term(screen);
 
     code = func(screen, data);
diff --git a/ncurses/tinfo/write_entry.c b/ncurses/tinfo/write_entry.c
index b53bb21..b2edd5d 100644
--- a/ncurses/tinfo/write_entry.c
+++ b/ncurses/tinfo/write_entry.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2013,2014 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            *
@@ -39,14 +39,7 @@
 #include <curses.priv.h>
 #include <hashed_db.h>
 
-#include <sys/stat.h>
-
 #include <tic.h>
-#include <term_entry.h>
-
-#ifndef S_ISDIR
-#define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR)
-#endif
 
 #if 1
 #define TRACE_OUT(p) DEBUG(2, p)
@@ -54,7 +47,7 @@
 #define TRACE_OUT(p)		/*nothing */
 #endif
 
-MODULE_ID("$Id: write_entry.c,v 1.72 2008/08/03 19:24:00 tom Exp $")
+MODULE_ID("$Id: write_entry.c,v 1.92 2014/11/01 14:47:00 tom Exp $")
 
 static int total_written;
 
@@ -77,7 +70,7 @@
     DEBUG(1, ("Created %s", filename));
 
     if (write_object(tp, buffer, &offset, limit) == ERR
-	|| fwrite(buffer, sizeof(char), offset, fp) != offset) {
+	|| fwrite(buffer, sizeof(char), (size_t) offset, fp) != offset) {
 	_nc_syserr_abort("error writing %s/%s", _nc_tic_dir(0), filename);
     }
 
@@ -100,13 +93,13 @@
     char dir[sizeof(LEAF_FMT)];
     char *s = 0;
 
-    if (code == 0 || (s = strchr(dirnames, code)) == 0)
+    if (code == 0 || (s = (strchr) (dirnames, code)) == 0)
 	_nc_err_abort("Illegal terminfo subdirectory \"" LEAF_FMT "\"", code);
 
     if (verified[s - dirnames])
 	return;
 
-    sprintf(dir, LEAF_FMT, code);
+    _nc_SPRINTF(dir, _nc_SLIMIT(sizeof(dir)) LEAF_FMT, code);
     if (make_db_root(dir) < 0) {
 	_nc_err_abort("%s/%s: permission denied", _nc_tic_dir(0), dir);
     }
@@ -116,34 +109,35 @@
 #endif /* !USE_HASHED_DB */
 
 static int
-make_db_path(char *dst, const char *src, unsigned limit)
+make_db_path(char *dst, const char *src, size_t limit)
 {
     int rc = -1;
     const char *top = _nc_tic_dir(0);
 
     if (src == top || _nc_is_abs_path(src)) {
 	if (strlen(src) + 1 <= limit) {
-	    (void) strcpy(dst, src);
+	    _nc_STRCPY(dst, src, limit);
 	    rc = 0;
 	}
     } else {
 	if (strlen(top) + strlen(src) + 2 <= limit) {
-	    (void) sprintf(dst, "%s/%s", top, src);
+	    _nc_SPRINTF(dst, _nc_SLIMIT(limit) "%s/%s", top, src);
 	    rc = 0;
 	}
     }
 #if USE_HASHED_DB
     if (rc == 0) {
-	if (_nc_is_dir_path(dst)) {
-	    rc = -1;
-	} else {
-	    unsigned have = strlen(dst);
-	    if (have > 3 && strcmp(dst + have - 3, DBM_SUFFIX)) {
-		if (have + 3 <= limit)
-		    strcat(dst, DBM_SUFFIX);
-		else
-		    rc = -1;
+	static const char suffix[] = DBM_SUFFIX;
+	size_t have = strlen(dst);
+	size_t need = strlen(suffix);
+	if (have > need && strcmp(dst + (int) (have - need), suffix)) {
+	    if (have + need <= limit) {
+		_nc_STRCAT(dst, suffix, limit);
+	    } else {
+		rc = -1;
 	    }
+	} else if (_nc_is_dir_path(dst)) {
+	    rc = -1;
 	}
     }
 #endif
@@ -163,15 +157,20 @@
 #if USE_HASHED_DB
 	DB *capdbp;
 
-	if ((capdbp = _nc_db_open(fullpath, TRUE)) == NULL)
+	if ((capdbp = _nc_db_open(fullpath, TRUE)) == NULL) {
 	    rc = -1;
-	else if (_nc_db_close(capdbp) < 0)
+	} else if (_nc_db_close(capdbp) < 0) {
 	    rc = -1;
+	}
 #else
 	struct stat statbuf;
 
 	if ((rc = stat(path, &statbuf)) < 0) {
-	    rc = mkdir(path, 0777);
+	    rc = mkdir(path
+#if !defined(__MINGW32__)
+		       ,0777
+#endif
+		);
 	} else if (_nc_access(path, R_OK | W_OK | X_OK) < 0) {
 	    rc = -1;		/* permission denied */
 	} else if (!(S_ISDIR(statbuf.st_mode))) {
@@ -186,13 +185,16 @@
  * Set the write directory for compiled entries.
  */
 NCURSES_EXPORT(void)
-_nc_set_writedir(char *dir)
+_nc_set_writedir(const char *dir)
 {
     const char *destination;
     char actual[PATH_MAX];
 
     if (dir == 0
-	&& use_terminfo_vars())
+#ifndef USE_ROOT_ENVIRON
+	&& use_terminfo_vars()
+#endif
+	)
 	dir = getenv("TERMINFO");
 
     if (dir != 0)
@@ -274,16 +276,21 @@
     char name_list[MAX_TERMINFO_LENGTH];
     char *first_name, *other_names;
     char *ptr;
+    char *term_names = tp->term_names;
+    size_t name_size = strlen(term_names);
 
-    assert(strlen(tp->term_names) != 0);
-    assert(strlen(tp->term_names) < sizeof(name_list));
+    if (name_size == 0) {
+	_nc_syserr_abort("no terminal name found.");
+    } else if (name_size >= sizeof(name_list) - 1) {
+	_nc_syserr_abort("terminal name too long: %s", term_names);
+    }
 
-    (void) strcpy(name_list, tp->term_names);
+    _nc_STRCPY(name_list, term_names, sizeof(name_list));
     DEBUG(7, ("Name list = '%s'", name_list));
 
     first_name = name_list;
 
-    ptr = &name_list[strlen(name_list) - 1];
+    ptr = &name_list[name_size - 1];
     other_names = ptr + 1;
 
     while (ptr > name_list && *ptr != '|')
@@ -317,8 +324,8 @@
 	    buffer[0] = 0;
 
 	    memset(&key, 0, sizeof(key));
-	    key.data = tp->term_names;
-	    key.size = strlen(tp->term_names);
+	    key.data = term_names;
+	    key.size = name_size;
 
 	    memset(&data, 0, sizeof(data));
 	    data.data = buffer;
@@ -331,13 +338,16 @@
 	    key.data = name_list;
 	    key.size = strlen(name_list);
 
-	    strcpy(buffer + 1, tp->term_names);
-	    data.size = strlen(tp->term_names) + 1;
+	    _nc_STRCPY(buffer + 1,
+		       term_names,
+		       sizeof(buffer) - 1);
+	    data.size = name_size + 1;
 
 	    _nc_db_put(capdb, &key, &data);
 
 	    while (*other_names != '\0') {
 		ptr = other_names++;
+		assert(ptr < buffer + sizeof(buffer) - 1);
 		while (*other_names != '|' && *other_names != '\0')
 		    other_names++;
 
@@ -349,7 +359,6 @@
 
 		_nc_db_put(capdb, &key, &data);
 	    }
-	    _nc_db_close(capdb);
 	}
     }
 #else /* !USE_HASHED_DB */
@@ -357,10 +366,11 @@
 	start_time = 0;
     }
 
-    if (strlen(first_name) >= sizeof(filename) - 3)
+    if (strlen(first_name) >= sizeof(filename) - (2 + LEAF_LEN))
 	_nc_warning("terminal name too long.");
 
-    sprintf(filename, LEAF_FMT "/%s", first_name[0], first_name);
+    _nc_SPRINTF(filename, _nc_SLIMIT(sizeof(filename))
+		LEAF_FMT "/%s", first_name[0], first_name);
 
     /*
      * Has this primary name been written since the first call to
@@ -370,7 +380,22 @@
     if (start_time > 0 &&
 	stat(filename, &statbuf) >= 0
 	&& statbuf.st_mtime >= start_time) {
+#if HAVE_LINK && !USE_SYMLINKS
+	/*
+	 * If the file has more than one link, the reason for the previous
+	 * write could be that the current primary name used to be an alias for
+	 * the previous entry.  In that case, unlink the file so that we will
+	 * not modify the previous entry as we write this one.
+	 */
+	if (statbuf.st_nlink > 1) {
+	    _nc_warning("name redefined.");
+	    unlink(filename);
+	} else {
+	    _nc_warning("name multiply defined.");
+	}
+#else
 	_nc_warning("name multiply defined.");
+#endif
     }
 
     check_writeable(first_name[0]);
@@ -385,14 +410,13 @@
     }
     while (*other_names != '\0') {
 	ptr = other_names++;
-	assert(ptr < buffer + sizeof(buffer) - 1);
 	while (*other_names != '|' && *other_names != '\0')
 	    other_names++;
 
 	if (*other_names != '\0')
 	    *(other_names++) = '\0';
 
-	if (strlen(ptr) > sizeof(linkname) - 3) {
+	if (strlen(ptr) > sizeof(linkname) - (2 + LEAF_LEN)) {
 	    _nc_warning("terminal alias %s too long.", ptr);
 	    continue;
 	}
@@ -402,7 +426,8 @@
 	}
 
 	check_writeable(ptr[0]);
-	sprintf(linkname, LEAF_FMT "/%s", ptr[0], ptr);
+	_nc_SPRINTF(linkname, _nc_SLIMIT(sizeof(linkname))
+		    LEAF_FMT "/%s", ptr[0], ptr);
 
 	if (strcmp(filename, linkname) == 0) {
 	    _nc_warning("self-synonym ignored");
@@ -414,8 +439,12 @@
 	{
 	    int code;
 #if USE_SYMLINKS
-	    strcpy(symlinkname, "../");
-	    strncat(symlinkname, filename, sizeof(symlinkname) - 4);
+	    if (first_name[0] == linkname[0])
+		strncpy(symlinkname, first_name, sizeof(symlinkname) - 1);
+	    else {
+		_nc_STRCPY(symlinkname, "../", sizeof(suymlinkname));
+		strncat(symlinkname, filename, sizeof(symlinkname) - 4);
+	    }
 	    symlinkname[sizeof(symlinkname) - 1] = '\0';
 #endif /* USE_SYMLINKS */
 #if HAVE_REMOVE
@@ -460,42 +489,43 @@
 #endif /* USE_HASHED_DB */
 }
 
-static unsigned
+static size_t
 fake_write(char *dst,
 	   unsigned *offset,
-	   unsigned limit,
+	   size_t limit,
 	   char *src,
-	   unsigned want,
-	   unsigned size)
+	   size_t want,
+	   size_t size)
 {
-    int have = (limit - *offset);
+    size_t have = (limit - *offset);
 
     want *= size;
     if (have > 0) {
-	if ((int) want > have)
+	if (want > have)
 	    want = have;
 	memcpy(dst + *offset, src, want);
-	*offset += want;
+	*offset += (unsigned) want;
     } else {
 	want = 0;
     }
-    return (int) (want / size);
+    return (want / size);
 }
 
-#define Write(buf, size, count) fake_write(buffer, offset, limit, (char *) buf, count, size)
+#define Write(buf, size, count) fake_write(buffer, offset, (size_t) limit, (char *) buf, (size_t) count, (size_t) size)
 
 #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)
+#define LITTLE_ENDIAN(p, x)	(p)[0] = (unsigned char)LO(x),  \
+                                (p)[1] = (unsigned char)HI(x)
 
 #define WRITE_STRING(str) (Write(str, sizeof(char), strlen(str) + 1) == strlen(str) + 1)
 
 static int
-compute_offsets(char **Strings, unsigned strmax, short *offsets)
+compute_offsets(char **Strings, size_t strmax, short *offsets)
 {
-    size_t nextfree = 0;
-    unsigned i;
+    int nextfree = 0;
+    size_t i;
 
     for (i = 0; i < strmax; i++) {
 	if (Strings[i] == ABSENT_STRING) {
@@ -503,8 +533,8 @@
 	} else if (Strings[i] == CANCELLED_STRING) {
 	    offsets[i] = -2;
 	} else {
-	    offsets[i] = nextfree;
-	    nextfree += strlen(Strings[i]) + 1;
+	    offsets[i] = (short) nextfree;
+	    nextfree += (int) strlen(Strings[i]) + 1;
 	    TRACE_OUT(("put Strings[%d]=%s(%d)", (int) i,
 		       _nc_visbuf(Strings[i]), (int) nextfree));
 	}
@@ -513,9 +543,9 @@
 }
 
 static void
-convert_shorts(unsigned char *buf, short *Numbers, unsigned count)
+convert_shorts(unsigned char *buf, short *Numbers, size_t count)
 {
-    unsigned i;
+    size_t i;
     for (i = 0; i < count; i++) {
 	if (Numbers[i] == ABSENT_NUMERIC) {	/* HI/LO won't work */
 	    buf[2 * i] = buf[2 * i + 1] = 0377;
@@ -524,7 +554,7 @@
 	    buf[2 * i + 1] = 0377;
 	} else {
 	    LITTLE_ENDIAN(buf + 2 * i, Numbers[i]);
-	    TRACE_OUT(("put Numbers[%d]=%d", i, Numbers[i]));
+	    TRACE_OUT(("put Numbers[%u]=%d", (unsigned) i, Numbers[i]));
 	}
     }
 }
@@ -536,8 +566,8 @@
 static unsigned
 extended_Booleans(TERMTYPE *tp)
 {
-    unsigned short result = 0;
-    unsigned short i;
+    unsigned result = 0;
+    unsigned i;
 
     for (i = 0; i < tp->ext_Booleans; ++i) {
 	if (tp->Booleans[BOOLCOUNT + i] == TRUE)
@@ -549,8 +579,8 @@
 static unsigned
 extended_Numbers(TERMTYPE *tp)
 {
-    unsigned short result = 0;
-    unsigned short i;
+    unsigned result = 0;
+    unsigned i;
 
     for (i = 0; i < tp->ext_Numbers; ++i) {
 	if (tp->Numbers[NUMCOUNT + i] != ABSENT_NUMERIC)
@@ -567,7 +597,7 @@
 
     for (i = 0; i < tp->ext_Strings; ++i) {
 	if (tp->Strings[STRCOUNT + i] != ABSENT_STRING)
-	    result = (i + 1);
+	    result = (unsigned short) (i + 1);
     }
     return result;
 }
@@ -597,7 +627,7 @@
     size_t namelen, boolmax, nummax, strmax;
     char zero = '\0';
     size_t i;
-    short nextfree;
+    int nextfree;
     short offsets[MAX_ENTRY_SIZE / 2];
     unsigned char buf[MAX_ENTRY_SIZE];
     unsigned last_bool = BOOLWRITE;
@@ -690,13 +720,13 @@
 
 #if NCURSES_XNAMES
     if (extended_object(tp)) {
-	unsigned extcnt = NUM_EXT_NAMES(tp);
+	unsigned extcnt = (unsigned) NUM_EXT_NAMES(tp);
 
 	if (even_boundary(nextfree))
 	    return (ERR);
 
 	nextfree = compute_offsets(tp->Strings + STRCOUNT,
-				   tp->ext_Strings,
+				   (size_t) tp->ext_Strings,
 				   offsets);
 	TRACE_OUT(("after extended string capabilities, nextfree=%d", nextfree));
 
@@ -704,7 +734,7 @@
 	    return (ERR);
 
 	nextfree += compute_offsets(tp->ext_Names,
-				    extcnt,
+				    (size_t) extcnt,
 				    offsets + tp->ext_Strings);
 	TRACE_OUT(("after extended capnames, nextfree=%d", nextfree));
 	strmax = tp->ext_Strings + extcnt;
@@ -732,7 +762,7 @@
 
 	TRACE_OUT(("WRITE %d numbers @%d", tp->ext_Numbers, *offset));
 	if (tp->ext_Numbers) {
-	    convert_shorts(buf, tp->Numbers + NUMCOUNT, tp->ext_Numbers);
+	    convert_shorts(buf, tp->Numbers + NUMCOUNT, (size_t) tp->ext_Numbers);
 	    if (Write(buf, 2, tp->ext_Numbers) != tp->ext_Numbers)
 		return (ERR);
 	}