summaryrefslogtreecommitdiff
path: root/ncurses/tinfo
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2020-02-12 02:21:21 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2020-02-12 02:21:21 +0000
commitff448436b2b70771d09b8d5ff34a509dcf02f81b (patch)
tree2f7abbba7198a4e1c4a23955bc3a539db5a7d999 /ncurses/tinfo
parentf6d73a10a980bc78969c3af93665cbe7d06c3646 (diff)
downloadncurses-ff448436b2b70771d09b8d5ff34a509dcf02f81b.tar.gz
ncurses-6.2ncurses-6.2
Diffstat (limited to 'ncurses/tinfo')
-rw-r--r--ncurses/tinfo/MKcaptab.awk5
-rwxr-xr-xncurses/tinfo/MKcaptab.sh76
-rw-r--r--ncurses/tinfo/MKcodes.awk7
-rwxr-xr-xncurses/tinfo/MKfallback.sh53
-rwxr-xr-xncurses/tinfo/MKkeys_list.sh17
-rw-r--r--ncurses/tinfo/MKnames.awk7
-rwxr-xr-xncurses/tinfo/MKuserdefs.sh146
-rw-r--r--ncurses/tinfo/README5
-rw-r--r--ncurses/tinfo/access.c13
-rw-r--r--ncurses/tinfo/add_tries.c6
-rw-r--r--ncurses/tinfo/alloc_entry.c47
-rw-r--r--ncurses/tinfo/alloc_ttype.c204
-rw-r--r--ncurses/tinfo/captoinfo.c241
-rw-r--r--ncurses/tinfo/comp_error.c29
-rw-r--r--ncurses/tinfo/comp_expand.c72
-rw-r--r--ncurses/tinfo/comp_hash.c46
-rw-r--r--ncurses/tinfo/comp_parse.c270
-rw-r--r--ncurses/tinfo/comp_scan.c30
-rw-r--r--ncurses/tinfo/db_iterator.c77
-rw-r--r--ncurses/tinfo/doalloc.c5
-rw-r--r--ncurses/tinfo/entries.c68
-rw-r--r--ncurses/tinfo/free_ttype.c34
-rw-r--r--ncurses/tinfo/getenv_num.c7
-rw-r--r--ncurses/tinfo/hashed_db.c7
-rw-r--r--ncurses/tinfo/home_terminfo.c10
-rw-r--r--ncurses/tinfo/init_keytry.c9
-rw-r--r--ncurses/tinfo/lib_acs.c83
-rw-r--r--ncurses/tinfo/lib_baudrate.c82
-rw-r--r--ncurses/tinfo/lib_cur_term.c35
-rw-r--r--ncurses/tinfo/lib_data.c73
-rw-r--r--ncurses/tinfo/lib_has_cap.c5
-rw-r--r--ncurses/tinfo/lib_kernel.c5
-rw-r--r--ncurses/tinfo/lib_longname.c16
-rw-r--r--ncurses/tinfo/lib_napms.c9
-rw-r--r--ncurses/tinfo/lib_options.c11
-rw-r--r--ncurses/tinfo/lib_print.c7
-rw-r--r--ncurses/tinfo/lib_raw.c31
-rw-r--r--ncurses/tinfo/lib_setup.c308
-rw-r--r--ncurses/tinfo/lib_termcap.c68
-rw-r--r--ncurses/tinfo/lib_termname.c5
-rw-r--r--ncurses/tinfo/lib_tgoto.c16
-rw-r--r--ncurses/tinfo/lib_ti.c29
-rw-r--r--ncurses/tinfo/lib_tparm.c66
-rw-r--r--ncurses/tinfo/lib_tputs.c26
-rw-r--r--ncurses/tinfo/lib_ttyflags.c47
-rw-r--r--ncurses/tinfo/make_hash.c257
-rw-r--r--ncurses/tinfo/make_keys.c27
-rw-r--r--ncurses/tinfo/name_match.c14
-rw-r--r--ncurses/tinfo/obsolete.c9
-rw-r--r--ncurses/tinfo/parse_entry.c362
-rw-r--r--ncurses/tinfo/read_entry.c411
-rw-r--r--ncurses/tinfo/read_termcap.c61
-rw-r--r--ncurses/tinfo/strings.c10
-rw-r--r--ncurses/tinfo/tinfo_driver.c194
-rw-r--r--ncurses/tinfo/trim_sgr0.c11
-rw-r--r--ncurses/tinfo/use_screen.c11
-rw-r--r--ncurses/tinfo/write_entry.c264
57 files changed, 2949 insertions, 1095 deletions
diff --git a/ncurses/tinfo/MKcaptab.awk b/ncurses/tinfo/MKcaptab.awk
index 56d3d17..ee4e2e9 100644
--- a/ncurses/tinfo/MKcaptab.awk
+++ b/ncurses/tinfo/MKcaptab.awk
@@ -1,5 +1,6 @@
##############################################################################
-# Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. #
+# Copyright 2020 Thomas E. Dickey #
+# Copyright 1998-2006,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"), #
@@ -25,7 +26,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
-# $Id: MKcaptab.awk,v 1.20 2007/08/12 00:26:15 tom Exp $
+# $Id: MKcaptab.awk,v 1.21 2020/02/02 23:34:34 tom Exp $
function add_string(text) {
if (text != "IGNORE") {
offsets[num_strings] = offset;
diff --git a/ncurses/tinfo/MKcaptab.sh b/ncurses/tinfo/MKcaptab.sh
index 20c94a6..c800023 100755
--- a/ncurses/tinfo/MKcaptab.sh
+++ b/ncurses/tinfo/MKcaptab.sh
@@ -1,6 +1,7 @@
#!/bin/sh
##############################################################################
-# Copyright (c) 2007-2010,2011 Free Software Foundation, Inc. #
+# Copyright 2019,2020 Thomas E. Dickey #
+# Copyright 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,11 +27,28 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
-# $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}
+# $Id: MKcaptab.sh,v 1.19 2020/02/02 23:34:34 tom Exp $
+
+if test $# != 0
+then
+ AWK="$1"; shift 1
+else
+ AWK=awk
+fi
+
+if test $# != 0
+then
+ OPT1="$1"; shift 1
+else
+ OPT1="-0"
+fi
+
+if test $# != 0
+then
+ OPT2="$1"; shift 1
+else
+ OPT2="tinfo/MKcaptab.awk"
+fi
cat <<EOF
/*
@@ -50,16 +68,18 @@ cat <<'EOF'
#include <tic.h>
#include <hashsize.h>
+/* *INDENT-OFF* */
EOF
-./make_hash 1 info $OPT1 <$DATA
-./make_hash 3 cap $OPT1 <$DATA
+cat "$@" |./make_hash 1 info $OPT1
+cat "$@" |./make_hash 3 cap $OPT1
-$AWK -f $OPT2 bigstrings=$OPT1 tablename=capalias <$DATA
+cat "$@" |$AWK -f $OPT2 bigstrings=$OPT1 tablename=capalias
-$AWK -f $OPT2 bigstrings=$OPT1 tablename=infoalias <$DATA
+cat "$@" |$AWK -f $OPT2 bigstrings=$OPT1 tablename=infoalias
cat <<EOF
+/* *INDENT-ON* */
#if $OPT1
static void
@@ -70,7 +90,7 @@ next_string(const char *strings, unsigned *offset)
static const struct name_table_entry *
_nc_build_names(struct name_table_entry **actual,
- const name_table_data *source,
+ const name_table_data * source,
const char *strings)
{
if (*actual == 0) {
@@ -97,7 +117,7 @@ _nc_build_names(struct name_table_entry **actual,
static const struct alias *
_nc_build_alias(struct alias **actual,
- const alias_table_data *source,
+ const alias_table_data * source,
const char *strings,
size_t tablesize)
{
@@ -127,20 +147,23 @@ _nc_build_alias(struct alias **actual,
#define build_alias(root) _nc_ ## root ## alias_table
#endif
-NCURSES_EXPORT(const struct name_table_entry *) _nc_get_table (bool termcap)
+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);
}
-/* entrypoint used by tack (do not alter) */
-NCURSES_EXPORT(const HashValue *) _nc_get_hash_table (bool termcap)
+/* entrypoint used by tack 1.07 */
+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)
+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
@@ -150,7 +173,7 @@ info_hash(const char *string)
DEBUG(9, ("hashing %s", string));
while (*string) {
- sum += (long) (*string + (*(string + 1) << 8));
+ sum += (long) (UChar(*string) + (UChar(*(string + 1)) << 8));
string++;
}
@@ -187,18 +210,21 @@ 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 }
+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)
+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)
+NCURSES_EXPORT(void)
+_nc_comp_captab_leaks(void)
{
#if $OPT1
FreeIfNeeded(_nc_cap_table);
diff --git a/ncurses/tinfo/MKcodes.awk b/ncurses/tinfo/MKcodes.awk
index 97e5131..48f4800 100644
--- a/ncurses/tinfo/MKcodes.awk
+++ b/ncurses/tinfo/MKcodes.awk
@@ -1,5 +1,6 @@
##############################################################################
-# Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. #
+# Copyright 2019,2020 Thomas E. Dickey #
+# Copyright 2007-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 +26,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
-# $Id: MKcodes.awk,v 1.9 2010/01/23 17:57:43 tom Exp $
+# $Id: MKcodes.awk,v 1.11 2020/02/02 23:34:34 tom Exp $
function large_item(value) {
result = sprintf("%d,", offset);
offset = offset + length(value) + 1;
@@ -79,7 +80,9 @@ BEGIN {
}
$1 ~ /^#/ {next;}
+$1 ~ /^(cap|info)alias/ {next;}
+$1 == "userdef" {next;}
$1 == "SKIPWARN" {next;}
$3 == "bool" {
diff --git a/ncurses/tinfo/MKfallback.sh b/ncurses/tinfo/MKfallback.sh
index 11f1d2e..319ab06 100755
--- a/ncurses/tinfo/MKfallback.sh
+++ b/ncurses/tinfo/MKfallback.sh
@@ -1,6 +1,7 @@
#!/bin/sh
##############################################################################
-# Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. #
+# Copyright 2020 Thomas E. Dickey #
+# Copyright 1998-2019,2020 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 +27,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
-# $Id: MKfallback.sh,v 1.15 2010/08/07 20:32:34 tom Exp $
+# $Id: MKfallback.sh,v 1.24 2020/02/08 21:52:37 tom Exp $
#
# MKfallback.sh -- create fallback table for entry reads
#
@@ -45,6 +46,9 @@ shift
tic_path=$1
shift
+infocmp_path=$1
+shift
+
case $tic_path in #(vi
/*)
tic_head=`echo "$tic_path" | sed -e 's,/[^/]*$,,'`
@@ -69,8 +73,10 @@ else
fi
cat <<EOF
+/* This file was generated by $0 */
+
/*
- * DO NOT EDIT THIS FILE BY HAND! It is generated by MKfallback.sh.
+ * DO NOT EDIT THIS FILE BY HAND!
*/
#include <curses.priv.h>
@@ -87,18 +93,18 @@ EOF
for x in $*
do
echo "/* $x */"
- infocmp -E $x
+ $infocmp_path -E $x | sed -e 's/\<short\>/NCURSES_INT2/g'
done
cat <<EOF
-static const TERMTYPE fallbacks[$#] =
+static const TERMTYPE2 fallbacks[$#] =
{
EOF
comma=""
for x in $*
do
echo "$comma /* $x */"
- infocmp -e $x
+ $infocmp_path -e $x
comma=","
done
@@ -109,28 +115,51 @@ EOF
fi
cat <<EOF
-NCURSES_EXPORT(const TERMTYPE *) _nc_fallback (const char *name GCC_UNUSED)
+NCURSES_EXPORT(const TERMTYPE2 *)
+_nc_fallback2 (const char *name GCC_UNUSED)
{
EOF
if [ "$*" ]
then
cat <<EOF
- const TERMTYPE *tp;
+ const TERMTYPE2 *tp;
for (tp = fallbacks;
- tp < fallbacks + sizeof(fallbacks)/sizeof(TERMTYPE);
- tp++)
- if (_nc_name_match(tp->term_names, name, "|"))
+ tp < fallbacks + sizeof(fallbacks)/sizeof(TERMTYPE2);
+ tp++) {
+ if (_nc_name_match(tp->term_names, name, "|")) {
return(tp);
+ }
+ }
EOF
else
echo " /* the fallback list is empty */";
fi
cat <<EOF
- return((TERMTYPE *)0);
+ return((const TERMTYPE2 *)0);
+}
+
+#if NCURSES_EXT_NUMBERS
+#undef _nc_fallback
+
+/*
+ * This entrypoint is used by tack 1.07
+ */
+NCURSES_EXPORT(const TERMTYPE *)
+_nc_fallback (const char *name)
+{
+ const TERMTYPE2 *tp = _nc_fallback2(name);
+ const TERMTYPE *result = 0;
+ if (tp != 0) {
+ static TERMTYPE temp;
+ _nc_export_termtype2(&temp, tp);
+ result = &temp;
+ }
+ return result;
}
+#endif
EOF
if test -n "$tmp_info" ; then
diff --git a/ncurses/tinfo/MKkeys_list.sh b/ncurses/tinfo/MKkeys_list.sh
index 14017b0..3b8beae 100755
--- a/ncurses/tinfo/MKkeys_list.sh
+++ b/ncurses/tinfo/MKkeys_list.sh
@@ -1,7 +1,8 @@
#! /bin/sh
-# $Id: MKkeys_list.sh,v 1.4 2003/10/25 16:19:54 tom Exp $
+# $Id: MKkeys_list.sh,v 1.7 2020/02/02 23:34:34 tom Exp $
##############################################################################
-# Copyright (c) 2001,2003 Free Software Foundation, Inc. #
+# Copyright 2019,2020 Thomas E. Dickey #
+# Copyright 2001-2003,2017 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"), #
@@ -35,11 +36,16 @@
# Extract function-key names from the Caps file
#
: ${AWK-awk}
-DATA=${1-../../include/Caps}
+if test $# != 0
+then
+ DATA="$*"
+else
+ DATA=../../include/Caps
+fi
data=data$$
-trap 'rm -f $data' 0 1 2 5 15
-sed -e 's/[ ][ ]*/ /g' < $DATA >$data
+trap 'rm -f $data' EXIT INT QUIT TERM HUP
+cat $DATA | sed -e 's/[ ][ ]*/ /g' >$data
cat <<EOF
# These definitions were generated by $0 $DATA
@@ -53,6 +59,7 @@ ${AWK-awk} <$data '
/^#/ {next;}
/^capalias/ {next;}
/^infoalias/ {next;}
+/^userdef/ {next;}
$5 != "-" {
if (substr($5, 1, 4) == "KEY_" ) {
diff --git a/ncurses/tinfo/MKnames.awk b/ncurses/tinfo/MKnames.awk
index 7685d18..4594c72 100644
--- a/ncurses/tinfo/MKnames.awk
+++ b/ncurses/tinfo/MKnames.awk
@@ -1,5 +1,6 @@
##############################################################################
-# Copyright (c) 2007-2008,2009 Free Software Foundation, Inc. #
+# Copyright 2019,2020 Thomas E. Dickey #
+# Copyright 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 "Software"), #
@@ -25,7 +26,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
-# $Id: MKnames.awk,v 1.22 2009/03/21 21:03:39 tom Exp $
+# $Id: MKnames.awk,v 1.24 2020/02/02 23:34:34 tom Exp $
function large_item(value) {
result = sprintf("%d,", offset);
offset = offset + length(value) + 1;
@@ -79,7 +80,9 @@ BEGIN {
}
$1 ~ /^#/ {next;}
+$1 ~ /^(cap|info)alias/ {next;}
+$1 == "userdef" {next;}
$1 == "SKIPWARN" {next;}
$3 == "bool" {
diff --git a/ncurses/tinfo/MKuserdefs.sh b/ncurses/tinfo/MKuserdefs.sh
new file mode 100755
index 0000000..109dd64
--- /dev/null
+++ b/ncurses/tinfo/MKuserdefs.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+##############################################################################
+# Copyright 2019,2020 Thomas E. Dickey #
+# #
+# 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. #
+##############################################################################
+# $Id: MKuserdefs.sh,v 1.10 2020/02/02 23:34:34 tom Exp $
+AWK=${1-awk}; shift 1
+OPT1=${1-0}; shift 1
+
+cat <<EOF
+/*
+ * generated by $0
+ */
+
+EOF
+
+cat <<'EOF'
+/*
+ * comp_userdefs.c -- The names of widely used user-defined capabilities
+ * indexed via a hash table for the compiler.
+ *
+ */
+
+#include <curses.priv.h>
+#include <tic.h>
+#include <hashsize.h>
+
+#if NCURSES_XNAMES
+EOF
+
+cat "$@" | ./make_hash 1 user $OPT1
+
+cat <<EOF
+
+#define USERTABSIZE SIZEOF(user_names_data)
+
+#if $OPT1
+static void
+next_string(const char *strings, unsigned *offset)
+{
+ *offset += (unsigned) strlen(strings + *offset) + 1;
+}
+
+static const struct user_table_entry *
+_nc_build_names(struct user_table_entry **actual,
+ const user_table_data *source,
+ const char *strings)
+{
+ if (*actual == 0) {
+ *actual = typeCalloc(struct user_table_entry, USERTABSIZE);
+ if (*actual != 0) {
+ unsigned n;
+ unsigned len = 0;
+ for (n = 0; n < USERTABSIZE; ++n) {
+ (*actual)[n].ute_name = strings + len;
+ (*actual)[n].ute_type = (int) source[n].ute_type;
+ (*actual)[n].ute_argc = source[n].ute_argc;
+ (*actual)[n].ute_args = source[n].ute_args;
+ (*actual)[n].ute_index = source[n].ute_index;
+ (*actual)[n].ute_link = source[n].ute_link;
+ next_string(strings, &len);
+ }
+ }
+ }
+ return *actual;
+}
+
+#define build_names(root) _nc_build_names(&_nc_##root##_table, \\
+ root##_names_data, \\
+ root##_names_text)
+#else
+#define build_names(root) _nc_ ## root ## _table
+#endif
+
+NCURSES_EXPORT(const struct user_table_entry *) _nc_get_userdefs_table (void)
+{
+ return build_names(user) ;
+}
+
+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);
+}
+
+static int
+compare_info_names(const char *a, const char *b)
+{
+ return !strcmp(a, b);
+}
+
+static const HashData hash_data[] = {
+ { HASHTABSIZE, _nc_user_hash_table, info_hash, compare_info_names }
+};
+
+NCURSES_EXPORT(const HashData *) _nc_get_hash_user (void)
+{
+ return hash_data;
+}
+
+#if NO_LEAKS
+NCURSES_EXPORT(void) _nc_comp_userdefs_leaks(void)
+{
+#if $OPT1
+ FreeIfNeeded(_nc_user_table);
+#endif
+}
+#endif /* NO_LEAKS */
+
+#else /*! NCURSES_XNAMES */
+NCURSES_EXPORT(void) _nc_comp_userdefs(void);
+NCURSES_EXPORT(void) _nc_comp_userdefs(void) { }
+#endif /* NCURSES_XNAMES */
+EOF
diff --git a/ncurses/tinfo/README b/ncurses/tinfo/README
index 14c4220..6157ba1 100644
--- a/ncurses/tinfo/README
+++ b/ncurses/tinfo/README
@@ -1,5 +1,6 @@
-------------------------------------------------------------------------------
--- Copyright (c) 1998,2006 Free Software Foundation, Inc. --
+-- Copyright 2020 Thomas E. Dickey --
+-- Copyright 1998,2006 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 --
@@ -25,7 +26,7 @@
-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
--- $Id: README,v 1.2 2006/04/22 22:19:37 tom Exp $
+-- $Id: README,v 1.3 2020/02/02 23:34:34 tom Exp $
-------------------------------------------------------------------------------
The files in this directory (tinfo) are those that support the terminfo
diff --git a/ncurses/tinfo/access.c b/ncurses/tinfo/access.c
index d987687..c69707f 100644
--- a/ncurses/tinfo/access.c
+++ b/ncurses/tinfo/access.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 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 *
@@ -36,15 +37,7 @@
#include <tic.h>
-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
+MODULE_ID("$Id: access.c,v 1.25 2020/02/02 23:34:34 tom Exp $")
#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
diff --git a/ncurses/tinfo/add_tries.c b/ncurses/tinfo/add_tries.c
index 29a1a60..d41f488 100644
--- a/ncurses/tinfo/add_tries.c
+++ b/ncurses/tinfo/add_tries.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 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 +40,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: add_tries.c,v 1.10 2010/12/19 01:31:14 tom Exp $")
+MODULE_ID("$Id: add_tries.c,v 1.12 2020/02/02 23:34:34 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))
@@ -109,6 +110,7 @@ _nc_add_to_try(TRIES ** tree, const char *str, unsigned code)
savedptr = ptr->child;
free(ptr);
}
+ *tree = NULL;
returnCode(ERR);
}
diff --git a/ncurses/tinfo/alloc_entry.c b/ncurses/tinfo/alloc_entry.c
index 14ea391..4bf7d6c 100644
--- a/ncurses/tinfo/alloc_entry.c
+++ b/ncurses/tinfo/alloc_entry.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2013,2017 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 *
@@ -47,7 +48,7 @@
#include <tic.h>
-MODULE_ID("$Id: alloc_entry.c,v 1.58 2013/08/17 19:20:38 tom Exp $")
+MODULE_ID("$Id: alloc_entry.c,v 1.64 2020/02/02 23:34:34 tom Exp $")
#define ABSENT_OFFSET -1
#define CANCELLED_OFFSET -2
@@ -58,7 +59,7 @@ static char *stringbuf; /* buffer for string capabilities */
static size_t next_free; /* next free character in stringbuf */
NCURSES_EXPORT(void)
-_nc_init_entry(TERMTYPE *const tp)
+_nc_init_entry(ENTRY * const tp)
/* initialize a terminal type data block */
{
#if NO_LEAKS
@@ -75,7 +76,7 @@ _nc_init_entry(TERMTYPE *const tp)
next_free = 0;
- _nc_init_termtype(tp);
+ _nc_init_termtype(&(tp->tterm));
}
NCURSES_EXPORT(ENTRY *)
@@ -85,7 +86,7 @@ _nc_copy_entry(ENTRY * oldp)
if (newp != 0) {
*newp = *oldp;
- _nc_copy_termtype(&(newp->tterm), &(oldp->tterm));
+ _nc_copy_termtype2(&(newp->tterm), &(oldp->tterm));
}
return newp;
}
@@ -96,7 +97,11 @@ _nc_save_str(const char *const string)
{
char *result = 0;
size_t old_next_free = next_free;
- size_t len = strlen(string) + 1;
+ size_t len;
+
+ if (!VALID_STRING(string))
+ return _nc_save_str("");
+ len = strlen(string) + 1;
if (len == 1 && next_free != 0) {
/*
@@ -126,7 +131,7 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
int useoffsets[MAX_USES];
unsigned i, n;
unsigned nuses = ep->nuses;
- TERMTYPE *tp = &(ep->tterm);
+ TERMTYPE2 *tp = &(ep->tterm);
if (copy_strings) {
next_free = 0; /* clear static storage */
@@ -218,12 +223,22 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
}
NCURSES_EXPORT(void)
-_nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
+_nc_merge_entry(ENTRY * const target, ENTRY * const source)
/* merge capabilities from `from' entry into `to' entry */
{
+ TERMTYPE2 *to = &(target->tterm);
+ TERMTYPE2 *from = &(source->tterm);
+#if NCURSES_XNAMES
+ TERMTYPE2 copy;
+#endif
unsigned i;
+ if (source == 0 || from == 0 || target == 0 || to == 0)
+ return;
+
#if NCURSES_XNAMES
+ _nc_copy_termtype2(&copy, from);
+ from = &copy;
_nc_align_termtype(to, from);
#endif
for_each_boolean(i, from) {
@@ -233,18 +248,18 @@ _nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
if (mergebool == CANCELLED_BOOLEAN)
to->Booleans[i] = FALSE;
else if (mergebool == TRUE)
- to->Booleans[i] = (char) mergebool;
+ to->Booleans[i] = (NCURSES_SBOOL) mergebool;
}
}
for_each_number(i, from) {
if (to->Numbers[i] != CANCELLED_NUMERIC) {
- short mergenum = from->Numbers[i];
+ int mergenum = from->Numbers[i];
if (mergenum == CANCELLED_NUMERIC)
to->Numbers[i] = ABSENT_NUMERIC;
else if (mergenum != ABSENT_NUMERIC)
- to->Numbers[i] = mergenum;
+ to->Numbers[i] = (NCURSES_INT2) mergenum;
}
}
@@ -263,6 +278,16 @@ _nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
to->Strings[i] = mergestring;
}
}
+#if NCURSES_XNAMES
+ /* Discard the data allocated in _nc_copy_termtype2, but do not use
+ * _nc_free_termtype2 because that frees the string-table (which is
+ * not allocated by _nc_copy_termtype2).
+ */
+ free(copy.Booleans);
+ free(copy.Numbers);
+ free(copy.Strings);
+ free(copy.ext_Names);
+#endif
}
#if NO_LEAKS
diff --git a/ncurses/tinfo/alloc_ttype.c b/ncurses/tinfo/alloc_ttype.c
index 35c92dd..222868e 100644
--- a/ncurses/tinfo/alloc_ttype.c
+++ b/ncurses/tinfo/alloc_ttype.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1999-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1999-2016,2017 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 *
@@ -42,7 +43,7 @@
#include <tic.h>
-MODULE_ID("$Id: alloc_ttype.c,v 1.27 2013/06/08 16:54:50 tom Exp $")
+MODULE_ID("$Id: alloc_ttype.c,v 1.33 2020/02/02 23:34:34 tom Exp $")
#if NCURSES_XNAMES
/*
@@ -61,7 +62,7 @@ merge_names(char **dst, char **a, int na, char **b, int nb)
} else if (cmp > 0) {
dst[n++] = *b++;
nb--;
- } else if (cmp == 0) {
+ } else {
dst[n++] = *a;
a++, b++;
na--, nb--;
@@ -78,37 +79,59 @@ merge_names(char **dst, char **a, int na, char **b, int nb)
}
static bool
-find_name(char **table, int length, char *name)
+find_name(char **table, int item, int length, const char *name)
{
- while (length-- > 0) {
- if (!strcmp(*table++, name)) {
- DEBUG(4, ("found name '%s'", name));
- return TRUE;
+ int n;
+ int result = -1;
+
+ for (n = item; n < length; ++n) {
+ if (!strcmp(table[n], name)) {
+ DEBUG(4, ("found name '%s' @%d", name, n));
+ result = n;
+ break;
}
}
- DEBUG(4, ("did not find name '%s'", name));
- return FALSE;
+ if (result < 0) {
+ DEBUG(4, ("did not find name '%s'", name));
+ }
+ return (result >= 0);
}
#define EXTEND_NUM(num, ext) \
+ DEBUG(4, ("extending " #num " from %d to %d", \
+ to->num, (unsigned short) (to->num + (ext - to->ext)))); \
to->num = (unsigned short) (to->num + (ext - to->ext))
static void
-realign_data(TERMTYPE *to, char **ext_Names,
+realign_data(TERMTYPE2 *to, char **ext_Names,
int ext_Booleans,
int ext_Numbers,
int ext_Strings)
{
int n, m, base;
- int limit = (to->ext_Booleans + to->ext_Numbers + to->ext_Strings);
+ int to_Booleans = to->ext_Booleans;
+ int to_Numbers = to->ext_Numbers;
+ int to_Strings = to->ext_Strings;
+ int to1, to2, from;
+
+ DEBUG(4, ("realign_data %d/%d/%d vs %d/%d/%d",
+ ext_Booleans,
+ ext_Numbers,
+ ext_Strings,
+ to->ext_Booleans,
+ to->ext_Numbers,
+ to->ext_Strings));
if (to->ext_Booleans != ext_Booleans) {
+ to1 = 0;
+ to2 = to_Booleans + to1;
+ from = 0;
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--) {
- if (find_name(to->ext_Names, limit, ext_Names[m])) {
+ if (find_name(to->ext_Names, to1, to2, ext_Names[m + from])) {
to->Booleans[base + m] = to->Booleans[base + n--];
} else {
to->Booleans[base + m] = FALSE;
@@ -118,12 +141,15 @@ realign_data(TERMTYPE *to, char **ext_Names,
}
if (to->ext_Numbers != ext_Numbers) {
+ to1 = to_Booleans;
+ to2 = to_Numbers + to1;
+ from = ext_Booleans;
EXTEND_NUM(num_Numbers, ext_Numbers);
- TYPE_REALLOC(short, to->num_Numbers, to->Numbers);
+ TYPE_REALLOC(NCURSES_INT2, to->num_Numbers, to->Numbers);
for (n = to->ext_Numbers - 1,
m = ext_Numbers - 1,
base = to->num_Numbers - (m + 1); m >= 0; m--) {
- if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans])) {
+ if (find_name(to->ext_Names, to1, to2, ext_Names[m + from])) {
to->Numbers[base + m] = to->Numbers[base + n--];
} else {
to->Numbers[base + m] = ABSENT_NUMERIC;
@@ -131,13 +157,17 @@ realign_data(TERMTYPE *to, char **ext_Names,
}
to->ext_Numbers = UShort(ext_Numbers);
}
+
if (to->ext_Strings != ext_Strings) {
+ to1 = to_Booleans + to_Numbers;
+ to2 = to_Strings + to1;
+ from = ext_Booleans + ext_Numbers;
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--) {
- if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans + ext_Numbers])) {
+ if (find_name(to->ext_Names, to1, to2, ext_Names[m + from])) {
to->Strings[base + m] = to->Strings[base + n--];
} else {
to->Strings[base + m] = ABSENT_STRING;
@@ -151,7 +181,7 @@ realign_data(TERMTYPE *to, char **ext_Names,
* Returns the first index in ext_Names[] for the given token-type
*/
static unsigned
-_nc_first_ext_name(TERMTYPE *tp, int token_type)
+_nc_first_ext_name(TERMTYPE2 *tp, int token_type)
{
unsigned first;
@@ -176,7 +206,7 @@ _nc_first_ext_name(TERMTYPE *tp, int token_type)
* Returns the last index in ext_Names[] for the given token-type
*/
static unsigned
-_nc_last_ext_name(TERMTYPE *tp, int token_type)
+_nc_last_ext_name(TERMTYPE2 *tp, int token_type)
{
unsigned last;
@@ -199,7 +229,7 @@ _nc_last_ext_name(TERMTYPE *tp, int token_type)
* Lookup an entry from extended-names, returning -1 if not found
*/
static int
-_nc_find_ext_name(TERMTYPE *tp, char *name, int token_type)
+_nc_find_ext_name(TERMTYPE2 *tp, char *name, int token_type)
{
unsigned j;
unsigned first = _nc_first_ext_name(tp, token_type);
@@ -218,7 +248,7 @@ _nc_find_ext_name(TERMTYPE *tp, char *name, int token_type)
* (e.g., Booleans[]).
*/
static int
-_nc_ext_data_index(TERMTYPE *tp, int n, int token_type)
+_nc_ext_data_index(TERMTYPE2 *tp, int n, int token_type)
{
switch (token_type) {
case BOOLEAN:
@@ -241,13 +271,14 @@ _nc_ext_data_index(TERMTYPE *tp, int n, int token_type)
* data.
*/
static bool
-_nc_del_ext_name(TERMTYPE *tp, char *name, int token_type)
+_nc_del_ext_name(TERMTYPE2 *tp, char *name, int token_type)
{
- int j;
- int first, last;
+ int first;
if ((first = _nc_find_ext_name(tp, name, token_type)) >= 0) {
- last = (int) NUM_EXT_NAMES(tp) - 1;
+ int j;
+ int last = (int) NUM_EXT_NAMES(tp) - 1;
+
for (j = first; j < last; j++) {
tp->ext_Names[j] = tp->ext_Names[j + 1];
}
@@ -285,7 +316,7 @@ _nc_del_ext_name(TERMTYPE *tp, char *name, int token_type)
* index into the corresponding data array is returned.
*/
static int
-_nc_ins_ext_name(TERMTYPE *tp, char *name, int token_type)
+_nc_ins_ext_name(TERMTYPE2 *tp, char *name, int token_type)
{
unsigned first = _nc_first_ext_name(tp, token_type);
unsigned last = _nc_last_ext_name(tp, token_type);
@@ -319,7 +350,7 @@ _nc_ins_ext_name(TERMTYPE *tp, char *name, int token_type)
case NUMBER:
tp->ext_Numbers++;
tp->num_Numbers++;
- TYPE_REALLOC(short, tp->num_Numbers, tp->Numbers);
+ TYPE_REALLOC(NCURSES_INT2, tp->num_Numbers, tp->Numbers);
for (k = (unsigned) (tp->num_Numbers - 1); k > j; k--)
tp->Numbers[k] = tp->Numbers[k - 1];
break;
@@ -340,7 +371,7 @@ _nc_ins_ext_name(TERMTYPE *tp, char *name, int token_type)
* cancellation of a name that is inherited from another entry.
*/
static void
-adjust_cancels(TERMTYPE *to, TERMTYPE *from)
+adjust_cancels(TERMTYPE2 *to, TERMTYPE2 *from)
{
int first = to->ext_Booleans + to->ext_Numbers;
int last = first + to->ext_Strings;
@@ -385,24 +416,30 @@ adjust_cancels(TERMTYPE *to, TERMTYPE *from)
}
NCURSES_EXPORT(void)
-_nc_align_termtype(TERMTYPE *to, TERMTYPE *from)
+_nc_align_termtype(TERMTYPE2 *to, TERMTYPE2 *from)
{
- int na = (int) NUM_EXT_NAMES(to);
- int nb = (int) NUM_EXT_NAMES(from);
- int n;
- bool same;
+ int na;
+ int nb;
char **ext_Names;
- int ext_Booleans, ext_Numbers, ext_Strings;
- bool used_ext_Names = FALSE;
- DEBUG(2, ("align_termtype to(%d:%s), from(%d:%s)", na, to->term_names,
- nb, from->term_names));
+ na = to ? ((int) NUM_EXT_NAMES(to)) : 0;
+ nb = from ? ((int) NUM_EXT_NAMES(from)) : 0;
+
+ DEBUG(2, ("align_termtype to(%d:%s), from(%d:%s)",
+ na, to ? NonNull(to->term_names) : "?",
+ nb, from ? NonNull(from->term_names) : "?"));
if (na != 0 || nb != 0) {
+ int ext_Booleans, ext_Numbers, ext_Strings;
+ bool used_ext_Names = FALSE;
+
if ((na == nb) /* check if the arrays are equivalent */
&&(to->ext_Booleans == from->ext_Booleans)
&& (to->ext_Numbers == from->ext_Numbers)
&& (to->ext_Strings == from->ext_Strings)) {
+ int n;
+ bool same;
+
for (n = 0, same = TRUE; n < na; n++) {
if (strcmp(to->ext_Names[n], from->ext_Names[n])) {
same = FALSE;
@@ -473,29 +510,80 @@ _nc_align_termtype(TERMTYPE *to, TERMTYPE *from)
}
#endif
-NCURSES_EXPORT(void)
-_nc_copy_termtype(TERMTYPE *dst, const TERMTYPE *src)
+#define srcINT 1
+#define dstINT 2
+
+/*
+ * TERMTYPE and TERMTYPE2 differ only with regard to the values in Numbers.
+ * Use 'mode' to decide which to use.
+ */
+static void
+copy_termtype(TERMTYPE2 *dst, const TERMTYPE2 *src, int mode)
{
-#if NCURSES_XNAMES
+#if NCURSES_XNAMES || NCURSES_EXT_NUMBERS
unsigned i;
#endif
+#if NCURSES_EXT_NUMBERS
+ short *oldptr = 0;
+ int *newptr = 0;
+#endif
+ DEBUG(2, ("copy_termtype"));
*dst = *src; /* ...to copy the sizes and string-tables */
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]));
+#if NCURSES_EXT_NUMBERS
+ if ((mode & dstINT) == 0) {
+ DEBUG(2, ("...convert int ->short"));
+ TYPE_MALLOC(short, NUM_NUMBERS(dst), oldptr);
+ ((TERMTYPE *) dst)->Numbers = oldptr;
+ } else {
+ DEBUG(2, ("...copy without changing size"));
+ TYPE_MALLOC(int, NUM_NUMBERS(dst), newptr);
+ dst->Numbers = newptr;
+ }
+ if ((mode == srcINT) && (oldptr != 0)) {
+ DEBUG(2, ("...copy int ->short"));
+ for (i = 0; i < NUM_NUMBERS(dst); ++i) {
+ if (src->Numbers[i] > MAX_OF_TYPE(short)) {
+ oldptr[i] = MAX_OF_TYPE(short);
+ } else {
+ oldptr[i] = (short) src->Numbers[i];
+ }
+ }
+ } else if ((mode == dstINT) && (newptr != 0)) {
+ DEBUG(2, ("...copy short ->int"));
+ for (i = 0; i < NUM_NUMBERS(dst); ++i) {
+ newptr[i] = ((const short *) (src->Numbers))[i];
+ }
+ } else {
+ DEBUG(2, ("...copy %s without change",
+ (mode & dstINT)
+ ? "int"
+ : "short"));
+ memcpy(dst->Numbers,
+ src->Numbers,
+ NUM_NUMBERS(dst) * ((mode & dstINT)
+ ? sizeof(int)
+ : sizeof(short)));
+ }
+#else
+ (void) mode;
+ TYPE_MALLOC(short, NUM_NUMBERS(dst), dst->Numbers);
+ memcpy(dst->Numbers,
+ src->Numbers,
+ NUM_NUMBERS(dst) * sizeof(dst->Numbers[0]));
+#endif
+
/* FIXME: we probably should also copy str_table and ext_str_table,
* but tic and infocmp are not written to exploit that (yet).
*/
@@ -509,3 +597,33 @@ _nc_copy_termtype(TERMTYPE *dst, const TERMTYPE *src)
}
#endif
}
+
+/*
+ * This entrypoint is used by tack 1.07
+ */
+NCURSES_EXPORT(void)
+_nc_copy_termtype(TERMTYPE *dst, const TERMTYPE *src)
+{
+ DEBUG(2, ("_nc_copy_termtype..."));
+ copy_termtype((TERMTYPE2 *) dst, (const TERMTYPE2 *) src, 0);
+}
+
+#if NCURSES_EXT_NUMBERS
+NCURSES_EXPORT(void)
+_nc_copy_termtype2(TERMTYPE2 *dst, const TERMTYPE2 *src)
+{
+ DEBUG(2, ("_nc_copy_termtype2..."));
+ copy_termtype(dst, src, srcINT | dstINT);
+}
+
+/*
+ * Use this for exporting the internal TERMTYPE2 to the legacy format used via
+ * the CUR macro by applications.
+ */
+NCURSES_EXPORT(void)
+_nc_export_termtype2(TERMTYPE *dst, const TERMTYPE2 *src)
+{
+ DEBUG(2, ("_nc_export_termtype2..."));
+ copy_termtype((TERMTYPE2 *) dst, src, srcINT);
+}
+#endif /* NCURSES_EXT_NUMBERS */
diff --git a/ncurses/tinfo/captoinfo.c b/ncurses/tinfo/captoinfo.c
index e02e622..8b3b83d 100644
--- a/ncurses/tinfo/captoinfo.c
+++ b/ncurses/tinfo/captoinfo.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 +34,16 @@
****************************************************************************/
/*
- * captoinfo.c --- conversion between termcap and terminfo formats
+ * captoinfo.c
+ *
+ * Provide conversion in both directions between termcap and terminfo.
+ *
+ * cap-to-info --- conversion between termcap and terminfo formats
*
* The captoinfo() code was swiped from Ross Ridge's mytinfo package,
* adapted to fit ncurses by Eric S. Raymond <esr@snark.thyrsus.com>.
*
- * There is just one entry point:
+ * It has just one entry point:
*
* char *_nc_captoinfo(n, s, parameterized)
*
@@ -93,7 +98,13 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$Id: captoinfo.c,v 1.77 2012/12/30 00:50:40 tom Exp $")
+MODULE_ID("$Id: captoinfo.c,v 1.98 2020/02/02 23:34:34 tom Exp $")
+
+#if 0
+#define DEBUG_THIS(p) DEBUG(9, p)
+#else
+#define DEBUG_THIS(p) /* nothing */
+#endif
#define MAX_PUSHED 16 /* max # args we can push onto the stack */
@@ -181,7 +192,7 @@ cvtchar(register const char *sp)
case '$':
case '\\':
case '%':
- c = (unsigned char) (*sp);
+ c = UChar(*sp);
len = 2;
break;
case '\0':
@@ -194,29 +205,33 @@ cvtchar(register const char *sp)
case '3':
len = 1;
while (isdigit(UChar(*sp))) {
- c = (unsigned char) (8 * c + (*sp++ - '0'));
+ c = UChar(8 * c + (*sp++ - '0'));
len++;
}
break;
default:
- c = (unsigned char) (*sp);
- len = 2;
+ c = UChar(*sp);
+ len = (c != '\0') ? 2 : 1;
break;
}
break;
case '^':
- c = (unsigned char) (*++sp & 0x1f);
+ c = UChar(*++sp);
+ if (c == '?')
+ c = 127;
+ else
+ c &= 0x1f;
len = 2;
break;
default:
- c = (unsigned char) (*sp);
- len = 1;
+ c = UChar(*sp);
+ len = (c != '\0') ? 1 : 0;
}
if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') {
dp = save_string(dp, "%\'");
dp = save_char(dp, c);
dp = save_char(dp, '\'');
- } else {
+ } else if (c != '\0') {
dp = save_string(dp, "%{");
if (c > 99)
dp = save_char(dp, c / 100 + '0');
@@ -232,6 +247,8 @@ static void
getparm(int parm, int n)
/* push n copies of param on the terminfo stack if not already there */
{
+ int nn;
+
if (seenr) {
if (parm == 1)
parm = 2;
@@ -239,7 +256,7 @@ getparm(int parm, int n)
parm = 1;
}
- while (n--) {
+ for (nn = 0; nn < n; ++nn) {
dp = save_string(dp, "%p");
dp = save_char(dp, '0' + parm);
}
@@ -248,7 +265,7 @@ getparm(int parm, int n)
if (n > 1) {
_nc_warning("string may not be optimal");
dp = save_string(dp, "%Pa");
- while (n--) {
+ while (n-- > 0) {
dp = save_string(dp, "%ga");
}
}
@@ -288,6 +305,8 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
seenr = 0;
param = 1;
+ DEBUG_THIS(("_nc_captoinfo params %d, %s", parameterized, s));
+
dp = init_string();
/* skip the initial padding (if we haven't been told not to) */
@@ -295,7 +314,7 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
if (s == 0)
s = "";
if (parameterized >= 0 && isdigit(UChar(*s)))
- for (capstart = s;; s++)
+ for (capstart = s; *s != '\0'; s++)
if (!(isdigit(UChar(*s)) || *s == '*' || *s == '.'))
break;
@@ -309,7 +328,7 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
}
switch (*s++) {
case '%':
- dp = save_char(dp, '%');
+ dp = save_string(dp, "%%");
break;
case 'r':
if (seenr++ == 1) {
@@ -342,13 +361,18 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
dp = save_string(dp, "%{2}%*%-");
break;
case '>':
- getparm(param, 2);
/* %?%{x}%>%t%{y}%+%; */
- dp = save_string(dp, "%?");
- s += cvtchar(s);
- dp = save_string(dp, "%>%t");
- s += cvtchar(s);
- dp = save_string(dp, "%+%;");
+ if (s[0] && s[1]) {
+ getparm(param, 2);
+ dp = save_string(dp, "%?");
+ s += cvtchar(s);
+ dp = save_string(dp, "%>%t");
+ s += cvtchar(s);
+ dp = save_string(dp, "%+%;");
+ } else {
+ _nc_warning("expected two characters after %%>");
+ dp = save_string(dp, "%>");
+ }
break;
case 'a':
if ((*s == '=' || *s == '+' || *s == '-'
@@ -429,12 +453,17 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
pop();
break;
case '0': /* not clear any of the historical termcaps did this */
- if (*s == '3')
+ if (*s == '3') {
+ ++s;
goto see03;
- else if (*s != '2')
- goto invalid;
- /* FALLTHRU */
+ }
+ if (*s == '2') {
+ ++s;
+ goto see02;
+ }
+ goto invalid;
case '2':
+ see02:
getparm(param, 1);
dp = save_string(dp, "%2d");
pop();
@@ -469,7 +498,8 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
}
break;
default:
- dp = save_char(dp, *s++);
+ if (*s != '\0')
+ dp = save_char(dp, *s++);
break;
}
}
@@ -480,7 +510,7 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
*/
if (capstart) {
dp = save_string(dp, "$<");
- for (s = capstart;; s++)
+ for (s = capstart; *s != '\0'; s++)
if (isdigit(UChar(*s)) || *s == '*' || *s == '.')
dp = save_char(dp, *s);
else
@@ -489,6 +519,9 @@ _nc_captoinfo(const char *cap, const char *s, int const parameterized)
}
(void) save_char(dp, '\0');
+
+ DEBUG_THIS(("... _nc_captoinfo %s", NonNull(my_string)));
+
return (my_string);
}
@@ -525,13 +558,13 @@ bcd_expression(const char *str)
static char *
save_tc_char(char *bufptr, int c1)
{
- char temp[80];
-
if (is7bits(c1) && isprint(c1)) {
if (c1 == ':' || c1 == '\\')
bufptr = save_char(bufptr, '\\');
bufptr = save_char(bufptr, c1);
} else {
+ char temp[80];
+
if (c1 == (c1 & 0x1f)) { /* iscntrl() returns T on 255 */
_nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp))
"%.20s", unctrl((chtype) c1));
@@ -554,6 +587,8 @@ save_tc_inequality(char *bufptr, int c1, int c2)
}
/*
+ * info-to-cap --- conversion between terminfo and termcap formats
+ *
* Here are the capabilities infotocap assumes it can translate to:
*
* %% output `%'
@@ -571,6 +606,8 @@ save_tc_inequality(char *bufptr, int c1, int c2)
* %m exclusive-or all parameters with 0177 (not in 4.4BSD)
*/
+#define octal_fixup(n, c) fixups[n].ch = ((fixups[n].ch << 3) | ((c) - '0'))
+
/*
* Convert a terminfo string to termcap format. Parameters are as in
* _nc_captoinfo().
@@ -586,7 +623,15 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
char *bufptr = init_string();
char octal[4];
int len;
+ int digits;
bool syntax_error = FALSE;
+ int myfix = 0;
+ struct {
+ int ch;
+ int offset;
+ } fixups[MAX_TC_FIXUPS];
+
+ DEBUG_THIS(("_nc_infotocap params %d, %s", parameterized, str));
/* we may have to move some trailing mandatory padding up front */
padding = str + strlen(str) - 1;
@@ -603,7 +648,9 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
bufptr = save_char(bufptr, *padding++);
}
- for (; *str && ((trimmed == 0) || (str < trimmed)); str++) {
+ for (; !syntax_error &&
+ *str &&
+ ((trimmed == 0) || (str < trimmed)); str++) {
int c1, c2;
char *cp = 0;
@@ -611,6 +658,14 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
if (str[1] == '\0' || (str + 1) == trimmed) {
bufptr = save_string(bufptr, "\\136");
++str;
+ } else if (str[1] == '?') {
+ /*
+ * Although the 4.3BSD termcap file has an instance of "kb=^?",
+ * that appears to be just cut/paste since neither 4.3BSD nor
+ * 4.4BSD termcap interprets "^?" as DEL.
+ */
+ bufptr = save_string(bufptr, "\\177");
+ ++str;
} else {
bufptr = save_char(bufptr, *str++);
bufptr = save_char(bufptr, *str);
@@ -625,17 +680,20 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
} else if (str[1] == ',') {
bufptr = save_char(bufptr, *++str);
} else {
- int xx1, xx2;
+ int xx1;
bufptr = save_char(bufptr, *str++);
xx1 = *str;
if (_nc_strict_bsd) {
- if (isdigit(UChar(xx1))) {
+
+ if (isoctal(UChar(xx1))) {
int pad = 0;
+ int xx2;
+ int fix = 0;
- if (!isdigit(UChar(str[1])))
+ if (!isoctal(UChar(str[1])))
pad = 2;
- else if (str[1] && !isdigit(UChar(str[2])))
+ else if (str[1] && !isoctal(UChar(str[2])))
pad = 1;
/*
@@ -650,10 +708,31 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
xx2 = '0';
pad = 0; /* FIXME - optionally pad to 3 digits */
}
+ if (myfix < MAX_TC_FIXUPS) {
+ fix = 3 - pad;
+ fixups[myfix].ch = 0;
+ fixups[myfix].offset = (int) (bufptr
+ - my_string
+ - 1);
+ }
while (pad-- > 0) {
bufptr = save_char(bufptr, xx2);
+ if (myfix < MAX_TC_FIXUPS) {
+ fixups[myfix].ch <<= 3;
+ fixups[myfix].ch |= (xx2 - '0');
+ }
xx2 = '0';
}
+ if (myfix < MAX_TC_FIXUPS) {
+ int n;
+ for (n = 0; n < fix; ++n) {
+ fixups[myfix].ch <<= 3;
+ fixups[myfix].ch |= (str[n] - '0');
+ }
+ if (fixups[myfix].ch < 32) {
+ ++myfix;
+ }
+ }
} else if (strchr("E\\nrtbf", xx1) == 0) {
switch (xx1) {
case 'e':
@@ -689,6 +768,24 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
break;
}
}
+ } else {
+ if (myfix < MAX_TC_FIXUPS && isoctal(UChar(xx1))) {
+ bool will_fix = TRUE;
+ int n;
+
+ fixups[myfix].ch = 0;
+ fixups[myfix].offset = (int) (bufptr - my_string - 1);
+ for (n = 0; n < 3; ++n) {
+ if (isoctal(str[n])) {
+ octal_fixup(myfix, str[n]);
+ } else {
+ will_fix = FALSE;
+ break;
+ }
+ }
+ if (will_fix && (fixups[myfix].ch < 32))
+ ++myfix;
+ }
}
bufptr = save_char(bufptr, xx1);
}
@@ -735,8 +832,9 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
} else if ((len = bcd_expression(str)) != 0) {
str += len;
bufptr = save_string(bufptr, "%B");
- } else if ((sscanf(str, "%%{%d}%%+%%c", &c1) == 1
- || sscanf(str, "%%'%c'%%+%%c", &ch1) == 1)
+ } else if ((sscanf(str, "%%{%d}%%+%%%c", &c1, &ch2) == 2
+ || sscanf(str, "%%'%c'%%+%%%c", &ch1, &ch2) == 2)
+ && ch2 == 'c'
&& (cp = strchr(str, '+'))) {
str = cp + 2;
bufptr = save_string(bufptr, "%+");
@@ -779,26 +877,46 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
bufptr = save_char(bufptr, '%');
ch1 = 0;
ch2 = 0;
+ digits = 0;
while (isdigit(UChar(*str))) {
+ if (++digits > 2) {
+ syntax_error = TRUE;
+ break;
+ }
ch2 = ch1;
ch1 = *str++;
- if (_nc_strict_bsd) {
- if (ch1 > '3')
- return 0;
+ if (digits == 2 && ch2 != '0') {
+ syntax_error = TRUE;
+ break;
+ } else if (_nc_strict_bsd) {
+ if (ch1 > '3') {
+ syntax_error = TRUE;
+ break;
+ }
} else {
bufptr = save_char(bufptr, ch1);
}
}
+ if (syntax_error)
+ break;
+ /*
+ * Convert %02 to %2 and %03 to %3
+ */
+ if (ch2 == '0' && !_nc_strict_bsd) {
+ ch2 = 0;
+ bufptr[-2] = bufptr[-1];
+ *--bufptr = 0;
+ }
if (_nc_strict_bsd) {
- if (ch2 != 0 && ch2 != '0')
- return 0;
- if (ch1 < '2')
+ if (ch2 != 0 && ch2 != '0') {
+ syntax_error = TRUE;
+ } else 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;
+ if (strchr("oxX.", *str)) {
+ syntax_error = TRUE; /* termcap doesn't have octal, hex */
}
break;
@@ -816,9 +934,11 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
* termcap notation.
*/
case 's':
- if (_nc_strict_bsd)
- return 0;
- bufptr = save_string(bufptr, "%s");
+ if (_nc_strict_bsd) {
+ syntax_error = TRUE;
+ } else {
+ bufptr = save_string(bufptr, "%s");
+ }
break;
case 'p':
@@ -830,8 +950,9 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
bufptr = save_string(bufptr, "%r");
seentwo++;
}
- } else if (*str >= '3')
- return (0);
+ } else if (*str >= '3') {
+ syntax_error = TRUE;
+ }
break;
case 'i':
@@ -855,6 +976,24 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz
} /* endwhile (*str) */
+ if (!syntax_error &&
+ myfix > 0 &&
+ ((int) strlen(my_string) - (4 * myfix)) < MIN_TC_FIXUPS) {
+ while (--myfix >= 0) {
+ char *p = fixups[myfix].offset + my_string;
+ *p++ = '^';
+ *p++ = (char) (fixups[myfix].ch | '@');
+ while ((p[0] = p[2]) != '\0') {
+ ++p;
+ }
+ }
+ }
+
+ DEBUG_THIS(("... _nc_infotocap %s",
+ syntax_error
+ ? "<ERR>"
+ : _nc_visbuf(my_string)));
+
return (syntax_error ? NULL : my_string);
}
diff --git a/ncurses/tinfo/comp_error.c b/ncurses/tinfo/comp_error.c
index ff0acc7..48f4878 100644
--- a/ncurses/tinfo/comp_error.c
+++ b/ncurses/tinfo/comp_error.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2012,2016 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 +42,7 @@
#include <tic.h>
-MODULE_ID("$Id: comp_error.c,v 1.36 2012/02/22 22:34:31 tom Exp $")
+MODULE_ID("$Id: comp_error.c,v 1.40 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT_VAR(bool) _nc_suppress_warnings = FALSE;
NCURSES_EXPORT_VAR(int) _nc_curr_line = 0; /* current line # in input */
@@ -66,12 +67,14 @@ _nc_set_source(const char *const name)
NCURSES_EXPORT(void)
_nc_set_type(const char *const name)
{
+#define MY_SIZE (size_t) MAX_NAME_SIZE
if (TermType == 0)
- TermType = typeMalloc(char, MAX_NAME_SIZE + 1);
+ TermType = typeMalloc(char, MY_SIZE + 1);
if (TermType != 0) {
TermType[0] = '\0';
- if (name)
- strncat(TermType, name, (size_t) MAX_NAME_SIZE);
+ if (name) {
+ _nc_STRNCAT(TermType, name, MY_SIZE, MY_SIZE);
+ }
}
}
@@ -103,7 +106,7 @@ where_is_problem(void)
}
NCURSES_EXPORT(void)
-_nc_warning(const char *const fmt,...)
+_nc_warning(const char *const fmt, ...)
{
va_list argp;
@@ -118,7 +121,7 @@ _nc_warning(const char *const fmt,...)
}
NCURSES_EXPORT(void)
-_nc_err_abort(const char *const fmt,...)
+_nc_err_abort(const char *const fmt, ...)
{
va_list argp;
@@ -131,7 +134,7 @@ _nc_err_abort(const char *const fmt,...)
}
NCURSES_EXPORT(void)
-_nc_syserr_abort(const char *const fmt,...)
+_nc_syserr_abort(const char *const fmt, ...)
{
va_list argp;
@@ -141,16 +144,18 @@ _nc_syserr_abort(const char *const fmt,...)
fprintf(stderr, "\n");
va_end(argp);
+#if defined(TRACE) || !defined(NDEBUG)
/* If we're debugging, try to show where the problem occurred - this
* will dump core.
*/
-#if defined(TRACE) || !defined(NDEBUG)
- abort();
-#else
+#ifndef USE_ROOT_ENVIRON
+ if (getuid() != ROOT_UID)
+#endif
+ abort();
+#endif
/* Dumping core in production code is not a good idea.
*/
exit(EXIT_FAILURE);
-#endif
}
#if NO_LEAKS
diff --git a/ncurses/tinfo/comp_expand.c b/ncurses/tinfo/comp_expand.c
index 2ab06eb..02e38e6 100644
--- a/ncurses/tinfo/comp_expand.c
+++ b/ncurses/tinfo/comp_expand.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 +28,7 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1998 *
+ * Author: Thomas E. Dickey 1998 *
****************************************************************************/
#include <curses.priv.h>
@@ -35,7 +36,13 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$Id: comp_expand.c,v 1.25 2012/03/24 18:37:17 tom Exp $")
+MODULE_ID("$Id: comp_expand.c,v 1.32 2020/02/02 23:34:34 tom Exp $")
+
+#if 0
+#define DEBUG_THIS(p) DEBUG(9, p)
+#else
+#define DEBUG_THIS(p) /* nothing */
+#endif
static int
trailing_spaces(const char *src)
@@ -46,10 +53,9 @@ trailing_spaces(const char *src)
}
/* this deals with differences over whether 0x7f and 0x80..0x9f are controls */
-#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))
+#define P_LIMIT(p) (length - (size_t)(p))
NCURSES_EXPORT(char *)
_nc_tic_expand(const char *srcp, bool tic_format, int numbers)
@@ -59,9 +65,13 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers)
int bufp;
const char *str = VALID_STRING(srcp) ? srcp : "\0\0";
- bool islong = (strlen(str) > 3);
size_t need = (2 + strlen(str)) * 4;
int ch;
+ int octals = 0;
+ struct {
+ int ch;
+ int offset;
+ } fixups[MAX_TC_FIXUPS];
if (srcp == 0) {
#if NO_LEAKS
@@ -77,6 +87,7 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers)
return 0;
}
+ DEBUG_THIS(("_nc_tic_expand %s", _nc_visbuf(srcp)));
bufp = 0;
while ((ch = UChar(*str)) != 0) {
if (ch == '%' && REALPRINT(str + 1)) {
@@ -133,6 +144,8 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers)
}
break;
default:
+ if (*str == ',') /* minitel1 uses this */
+ buffer[bufp++] = '\\';
buffer[bufp++] = *str;
break;
}
@@ -158,34 +171,28 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers)
&& !(ch == '!' && !tic_format)
&& ch != '^'))
buffer[bufp++] = (char) ch;
-#if 0 /* FIXME: this would be more readable (in fact the whole 'islong' logic should be removed) */
- else if (ch == '\b') {
- buffer[bufp++] = '\\';
- buffer[bufp++] = 'b';
- } else if (ch == '\f') {
- buffer[bufp++] = '\\';
- buffer[bufp++] = 'f';
- } else if (ch == '\t' && islong) {
- buffer[bufp++] = '\\';
- buffer[bufp++] = 't';
- }
-#endif
- else if (ch == '\r' && (islong || (strlen(srcp) > 2 && str[1] == '\0'))) {
+ else if (ch == '\r') {
buffer[bufp++] = '\\';
buffer[bufp++] = 'r';
- } else if (ch == '\n' && islong) {
+ } else if (ch == '\n') {
buffer[bufp++] = '\\';
buffer[bufp++] = 'n';
}
#define UnCtl(c) ((c) + '@')
- else if (REALCTL(str) && ch != '\\'
- && (!islong || isdigit(UChar(str[1])))) {
+ else if (UChar(ch) < 32
+ && isdigit(UChar(str[1]))) {
_nc_SPRINTF(&buffer[bufp], _nc_SLIMIT(P_LIMIT(bufp))
"^%c", UnCtl(ch));
bufp += 2;
} else {
_nc_SPRINTF(&buffer[bufp], _nc_SLIMIT(P_LIMIT(bufp))
"\\%03o", ch);
+ if ((octals < MAX_TC_FIXUPS) &&
+ ((tic_format && (ch == 127)) || ch < 32)) {
+ fixups[octals].ch = UChar(ch);
+ fixups[octals].offset = bufp;
+ ++octals;
+ }
bufp += 4;
}
@@ -193,5 +200,26 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers)
}
buffer[bufp] = '\0';
+
+ /*
+ * If most of a short string is ASCII control characters, reformat the
+ * string to show those in up-arrow format. For longer strings, it's
+ * more likely that the characters are just binary coding.
+ *
+ * If we're formatting termcap, just use the shorter format (up-arrows).
+ */
+ if (octals != 0 && (!tic_format || (bufp - (4 * octals)) < MIN_TC_FIXUPS)) {
+ while (--octals >= 0) {
+ char *p = buffer + fixups[octals].offset;
+ *p++ = '^';
+ *p++ = (char) ((fixups[octals].ch == 127)
+ ? '?'
+ : (fixups[octals].ch + (int) '@'));
+ while ((p[0] = p[2]) != 0) {
+ ++p;
+ }
+ }
+ }
+ DEBUG_THIS(("... %s", _nc_visbuf(buffer)));
return (buffer);
}
diff --git a/ncurses/tinfo/comp_hash.c b/ncurses/tinfo/comp_hash.c
index 959c6e1..80755f2 100644
--- a/ncurses/tinfo/comp_hash.c
+++ b/ncurses/tinfo/comp_hash.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. *
+ * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 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,13 +45,13 @@
#include <tic.h>
#include <hashsize.h>
-MODULE_ID("$Id: comp_hash.c,v 1.48 2009/08/08 17:36:21 tom Exp $")
+MODULE_ID("$Id: comp_hash.c,v 1.53 2020/02/02 23:34:34 tom Exp $")
/*
* 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.
*/
-/* entrypoint used by tack (do not alter) */
+/* entrypoint used by tack 1.07 */
NCURSES_EXPORT(struct name_table_entry const *)
_nc_find_entry(const char *string,
const HashValue * hash_table)
@@ -63,7 +64,9 @@ _nc_find_entry(const char *string,
hashvalue = data->hash_of(string);
- if (data->table_data[hashvalue] >= 0) {
+ if (hashvalue >= 0
+ && (unsigned) hashvalue < data->table_size
+ && data->table_data[hashvalue] >= 0) {
real_table = _nc_get_table(termcap);
ptr = real_table + data->table_data[hashvalue];
@@ -96,7 +99,9 @@ _nc_find_type_entry(const char *string,
const HashData *data = _nc_get_hash_info(termcap);
int hashvalue = data->hash_of(string);
- if (data->table_data[hashvalue] >= 0) {
+ if (hashvalue >= 0
+ && (unsigned) hashvalue < data->table_size
+ && data->table_data[hashvalue] >= 0) {
const struct name_table_entry *const table = _nc_get_table(termcap);
ptr = table + data->table_data[hashvalue];
@@ -112,3 +117,34 @@ _nc_find_type_entry(const char *string,
return ptr;
}
+
+#if NCURSES_XNAMES
+NCURSES_EXPORT(struct user_table_entry const *)
+_nc_find_user_entry(const char *string)
+{
+ const HashData *data = _nc_get_hash_user();
+ int hashvalue;
+ struct user_table_entry const *ptr = 0;
+ struct user_table_entry const *real_table;
+
+ hashvalue = data->hash_of(string);
+
+ if (hashvalue >= 0
+ && (unsigned) hashvalue < data->table_size
+ && data->table_data[hashvalue] >= 0) {
+
+ real_table = _nc_get_userdefs_table();
+ ptr = real_table + data->table_data[hashvalue];
+ while (!data->compare_names(ptr->ute_name, string)) {
+ if (ptr->ute_link < 0) {
+ ptr = 0;
+ break;
+ }
+ ptr = real_table + (ptr->ute_link
+ + data->table_data[data->table_size]);
+ }
+ }
+
+ return (ptr);
+}
+#endif /* NCURSES_XNAMES */
diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c
index 82a61a5..ab25d5b 100644
--- a/ncurses/tinfo/comp_parse.c
+++ b/ncurses/tinfo/comp_parse.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -47,16 +48,12 @@
#include <tic.h>
-MODULE_ID("$Id: comp_parse.c,v 1.90 2013/08/31 15:22:31 tom Exp $")
+MODULE_ID("$Id: comp_parse.c,v 1.109 2020/02/02 23:34:34 tom Exp $")
-static void sanity_check2(TERMTYPE *, bool);
-NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2;
+static void sanity_check2(TERMTYPE2 *, bool);
+NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE2 *, bool) = sanity_check2;
-/* obsolete: 20040705 */
-static void sanity_check(TERMTYPE *);
-NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype) (TERMTYPE *) = sanity_check;
-
-static void fixup_acsc(TERMTYPE *, int);
+static void fixup_acsc(TERMTYPE2 *, int);
static void
enqueue(ENTRY * ep)
@@ -75,6 +72,8 @@ enqueue(ENTRY * ep)
newp->last->next = newp;
}
+#define NAMEBUFFER_SIZE (MAX_NAME_SIZE + 2)
+
static char *
force_bar(char *dst, char *src)
{
@@ -82,8 +81,8 @@ force_bar(char *dst, char *src)
size_t len = strlen(src);
if (len > MAX_NAME_SIZE)
len = MAX_NAME_SIZE;
- (void) strncpy(dst, src, len);
- _nc_STRCPY(dst + len, "|", MAX_NAME_SIZE);
+ _nc_STRNCPY(dst, src, MAX_NAME_SIZE);
+ _nc_STRCPY(dst + len, "|", NAMEBUFFER_SIZE - len);
src = dst;
}
return src;
@@ -107,8 +106,8 @@ static bool
check_collisions(char *n1, char *n2, int counter)
{
char *pstart, *qstart, *pend, *qend;
- char nc1[MAX_NAME_SIZE + 2];
- char nc2[MAX_NAME_SIZE + 2];
+ char nc1[NAMEBUFFER_SIZE];
+ char nc2[NAMEBUFFER_SIZE];
n1 = ForceBar(nc1, n1);
n2 = ForceBar(nc2, n2);
@@ -182,11 +181,11 @@ remove_collision(char *n1, char *n2)
++qend;
while ((*qstart++ = *qend++) != '\0') ;
fprintf(stderr, "...now\t%s\n", p2);
+ removed = TRUE;
} else {
fprintf(stderr, "Cannot remove alias '%.*s'\n",
(int) (qend - qstart), qstart);
}
- removed = TRUE;
break;
}
}
@@ -267,6 +266,126 @@ _nc_read_entry_source(FILE *fp, char *buf,
_nc_suppress_warnings = oldsuppress;
}
+#if NCURSES_XNAMES
+static unsigned
+find_capname(TERMTYPE2 *p, const char *name)
+{
+ unsigned num_names = NUM_EXT_NAMES(p);
+ unsigned n;
+ if (name != 0) {
+ for (n = 0; n < num_names; ++n) {
+ if (!strcmp(p->ext_Names[n], name))
+ break;
+ }
+ } else {
+ n = num_names + 1;
+ }
+ return n;
+}
+
+static int
+extended_captype(TERMTYPE2 *p, unsigned which)
+{
+ int result = UNDEF;
+ unsigned limit = 0;
+ limit += p->ext_Booleans;
+ if (limit != 0 && which < limit) {
+ result = BOOLEAN;
+ } else {
+ limit += p->ext_Numbers;
+ if (limit != 0 && which < limit) {
+ result = NUMBER;
+ } else {
+ limit += p->ext_Strings;
+ if (limit != 0 && which < limit) {
+ result = STRING;
+ } else if (which >= limit) {
+ result = CANCEL;
+ }
+ }
+ }
+ return result;
+}
+
+static const char *
+name_of_captype(int which)
+{
+ const char *result = "?";
+ switch (which) {
+ case BOOLEAN:
+ result = "boolean";
+ break;
+ case NUMBER:
+ result = "number";
+ break;
+ case STRING:
+ result = "string";
+ break;
+ }
+ return result;
+}
+
+#define valid_TERMTYPE2(p) \
+ ((p) != 0 && \
+ (p)->term_names != 0 && \
+ (p)->ext_Names != 0)
+
+/*
+ * Disallow changing the type of an extended capability when doing a "use"
+ * if one or the other is a string.
+ */
+static int
+invalid_merge(TERMTYPE2 *to, TERMTYPE2 *from)
+{
+ int rc = FALSE;
+ if (valid_TERMTYPE2(to)
+ && valid_TERMTYPE2(from)) {
+ char *to_name = _nc_first_name(to->term_names);
+ char *from_name = strdup(_nc_first_name(from->term_names));
+ unsigned num_names = NUM_EXT_NAMES(from);
+ unsigned n;
+
+ for (n = 0; n < num_names; ++n) {
+ const char *capname = from->ext_Names[n];
+ int tt = extended_captype(to, find_capname(to, capname));
+ int tf = extended_captype(from, n);
+
+ if (tt <= STRING
+ && tf <= STRING
+ && (tt == STRING) != (tf == STRING)) {
+ if (from_name != 0 && strcmp(to_name, from_name)) {
+ DEBUG(2,
+ ("merge of %s to %s changes type of %s from %s to %s",
+ from_name,
+ to_name,
+ from->ext_Names[n],
+ name_of_captype(tf),
+ name_of_captype(tt)));
+ } else {
+ DEBUG(2, ("merge of %s changes type of %s from %s to %s",
+ to_name,
+ from->ext_Names[n],
+ name_of_captype(tf),
+ name_of_captype(tt)));
+ }
+ _nc_warning("merge changes type of %s from %s to %s",
+ from->ext_Names[n],
+ name_of_captype(tf),
+ name_of_captype(tt));
+ rc = TRUE;
+ }
+ }
+ free(from_name);
+ }
+ return rc;
+}
+#define validate_merge(p, q) \
+ if (invalid_merge(&((p)->tterm), &((q)->tterm))) \
+ return FALSE
+#else
+#define validate_merge(p, q) /* nothing */
+#endif
+
NCURSES_EXPORT(int)
_nc_resolve_uses2(bool fullresolve, bool literal)
/* try to resolve all use capabilities */
@@ -319,6 +438,9 @@ _nc_resolve_uses2(bool fullresolve, bool literal)
char *lookfor = qp->uses[i].name;
long lookline = qp->uses[i].line;
+ if (lookfor == 0)
+ continue;
+
foundit = FALSE;
_nc_set_type(child);
@@ -337,11 +459,11 @@ _nc_resolve_uses2(bool fullresolve, bool literal)
/* if that didn't work, try to merge in a compiled entry */
if (!foundit) {
- TERMTYPE thisterm;
+ TERMTYPE2 thisterm;
char filename[PATH_MAX];
memset(&thisterm, 0, sizeof(thisterm));
- if (_nc_read_entry(lookfor, filename, &thisterm) == 1) {
+ if (_nc_read_entry2(lookfor, filename, &thisterm) == 1) {
DEBUG(2, ("%s: resolving use=%s (compiled)",
child, lookfor));
@@ -382,7 +504,7 @@ _nc_resolve_uses2(bool fullresolve, bool literal)
*/
if (fullresolve) {
do {
- TERMTYPE merged;
+ ENTRY merged;
keepgoing = FALSE;
@@ -396,7 +518,8 @@ _nc_resolve_uses2(bool fullresolve, bool literal)
* subsequent pass.
*/
for (i = 0; i < qp->nuses; i++)
- if (qp->uses[i].link->nuses) {
+ if (qp->uses[i].link
+ && qp->uses[i].link->nuses) {
DEBUG(2, ("%s: use entry %d unresolved",
_nc_first_name(qp->tterm.term_names), i));
goto incomplete;
@@ -408,20 +531,24 @@ _nc_resolve_uses2(bool fullresolve, bool literal)
* the merged entry the name field and string
* table pointer.
*/
- _nc_copy_termtype(&merged, &(qp->tterm));
+ _nc_copy_termtype2(&(merged.tterm), &(qp->tterm));
/*
* Now merge in each use entry in the proper
* (reverse) order.
*/
- for (; qp->nuses; qp->nuses--)
+ for (; qp->nuses; qp->nuses--) {
+ validate_merge(&merged,
+ qp->uses[qp->nuses - 1].link);
_nc_merge_entry(&merged,
- &qp->uses[qp->nuses - 1].link->tterm);
+ qp->uses[qp->nuses - 1].link);
+ }
/*
* Now merge in the original entry.
*/
- _nc_merge_entry(&merged, &qp->tterm);
+ validate_merge(&merged, qp);
+ _nc_merge_entry(&merged, qp);
/*
* Replace the original entry with the merged one.
@@ -432,7 +559,7 @@ _nc_resolve_uses2(bool fullresolve, bool literal)
#if NCURSES_XNAMES
FreeIfNeeded(qp->tterm.ext_Names);
#endif
- qp->tterm = merged;
+ qp->tterm = merged.tterm;
_nc_wrap_entry(qp, TRUE);
/*
@@ -459,54 +586,46 @@ _nc_resolve_uses2(bool fullresolve, bool literal)
DEBUG(2, ("RESOLUTION FINISHED"));
- if (fullresolve)
- if (_nc_check_termtype != 0) {
- _nc_curr_col = -1;
- for_entry_list(qp) {
- _nc_curr_line = (int) qp->startline;
- _nc_set_type(_nc_first_name(qp->tterm.term_names));
+ if (fullresolve) {
+ _nc_curr_col = -1;
+ for_entry_list(qp) {
+ _nc_curr_line = (int) qp->startline;
+ _nc_set_type(_nc_first_name(qp->tterm.term_names));
+ /*
+ * 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;
+
/*
- * tic overrides this function pointer to provide more verbose
- * checking.
+ * Setup so that tic can use ordinary terminfo interface to
+ * obtain capability information.
*/
- 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);
- }
+ memset(&fake_sp, 0, sizeof(fake_sp));
+ memset(&fake_tm, 0, sizeof(fake_tm));
+ fake_sp._term = &fake_tm;
+ TerminalType(&fake_tm) = 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"));
}
+ DEBUG(2, ("SANITY CHECK FINISHED"));
+ }
return (TRUE);
}
-/* obsolete: 20040705 */
-NCURSES_EXPORT(int)
-_nc_resolve_uses(bool fullresolve)
-{
- return _nc_resolve_uses2(fullresolve, FALSE);
-}
-
/*
* This bit of legerdemain turns all the terminfo variable names into
* references to locations in the arrays Booleans, Numbers, and Strings ---
@@ -517,18 +636,18 @@ _nc_resolve_uses(bool fullresolve)
#define CUR tp->
static void
-fixup_acsc(TERMTYPE *tp, int literal)
+fixup_acsc(TERMTYPE2 *tp, int literal)
{
if (!literal) {
- if (acs_chars == 0
- && enter_alt_charset_mode != 0
- && exit_alt_charset_mode != 0)
+ if (acs_chars == ABSENT_STRING
+ && PRESENT(enter_alt_charset_mode)
+ && PRESENT(exit_alt_charset_mode))
acs_chars = strdup(VT_ACSC);
}
}
static void
-sanity_check2(TERMTYPE *tp, bool literal)
+sanity_check2(TERMTYPE2 *tp, bool literal)
{
if (!PRESENT(exit_attribute_mode)) {
#ifdef __UNUSED__ /* this casts too wide a net */
@@ -547,7 +666,9 @@ sanity_check2(TERMTYPE *tp, bool literal)
#endif /* __UNUSED__ */
PAIRED(enter_standout_mode, exit_standout_mode);
PAIRED(enter_underline_mode, exit_underline_mode);
+#if defined(enter_italics_mode) && defined(exit_italics_mode)
PAIRED(enter_italics_mode, exit_italics_mode);
+#endif
}
/* we do this check/fix in postprocess_termcap(), but some packagers
@@ -578,23 +699,18 @@ sanity_check2(TERMTYPE *tp, bool literal)
PAIRED(enter_xon_mode, exit_xon_mode);
PAIRED(enter_am_mode, exit_am_mode);
ANDMISSING(label_off, label_on);
-#ifdef remove_clock
+#if defined(display_clock) && defined(remove_clock)
PAIRED(display_clock, remove_clock);
#endif
ANDMISSING(set_color_pair, initialize_pair);
}
-/* obsolete: 20040705 */
-static void
-sanity_check(TERMTYPE *tp)
-{
- sanity_check2(tp, FALSE);
-}
-
#if NO_LEAKS
NCURSES_EXPORT(void)
_nc_leaks_tic(void)
{
+ T((T_CALLED("_nc_free_tic()")));
+ _nc_globals.leak_checking = TRUE;
_nc_alloc_entry_leaks();
_nc_captoinfo_leaks();
_nc_comp_scan_leaks();
@@ -609,6 +725,6 @@ NCURSES_EXPORT(void)
_nc_free_tic(int code)
{
_nc_leaks_tic();
- _nc_free_tinfo(code);
+ exit_terminfo(code);
}
#endif
diff --git a/ncurses/tinfo/comp_scan.c b/ncurses/tinfo/comp_scan.c
index fe6e8e7..87929d2 100644
--- a/ncurses/tinfo/comp_scan.c
+++ b/ncurses/tinfo/comp_scan.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -50,7 +51,7 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$Id: comp_scan.c,v 1.102 2013/11/16 19:57:50 tom Exp $")
+MODULE_ID("$Id: comp_scan.c,v 1.109 2020/02/02 23:34:34 tom Exp $")
/*
* Maximum length of string capability we'll accept before raising an error.
@@ -168,6 +169,8 @@ next_char(void)
if (result != 0) {
FreeAndNull(result);
FreeAndNull(pushname);
+ bufptr = 0;
+ bufstart = 0;
allocated = 0;
}
/*
@@ -189,12 +192,11 @@ next_char(void)
* quite hard to get completely right. Try it and see. If you
* succeed, don't forget to hack push_back() correspondingly.
*/
- size_t used;
size_t len;
do {
+ size_t used = 0;
bufstart = 0;
- used = 0;
do {
if (used + (LEXBUFSIZ / 4) >= allocated) {
allocated += (allocated + LEXBUFSIZ);
@@ -223,6 +225,8 @@ next_char(void)
}
if ((bufptr = bufstart) != 0) {
used = strlen(bufptr);
+ if (used == 0)
+ return (EOF);
while (iswhite(*bufptr)) {
if (*bufptr == '\t') {
_nc_curr_col = (_nc_curr_col | 7) + 1;
@@ -669,7 +673,15 @@ _nc_get_token(bool silent)
if (numchk == numbuf)
_nc_warning("no value given for `%s'", tok_buf);
if ((*numchk != '\0') || (ch != separator))
- _nc_warning("Missing separator");
+ _nc_warning("Missing separator for `%s'", tok_buf);
+ if (number < 0)
+ _nc_warning("value of `%s' cannot be negative", tok_buf);
+ if (number > MAX_OF_TYPE(NCURSES_INT2)) {
+ _nc_warning("limiting value of `%s' from %#lx to %#x",
+ tok_buf,
+ number, MAX_OF_TYPE(NCURSES_INT2));
+ number = MAX_OF_TYPE(NCURSES_INT2);
+ }
}
_nc_curr_token.tk_name = tok_buf;
_nc_curr_token.tk_valnumber = (int) number;
@@ -810,8 +822,6 @@ _nc_trans_string(char *ptr, char *last)
}
if (c == '?' && (_nc_syntax != SYN_TERMCAP)) {
*(ptr++) = '\177';
- if (_nc_tracing)
- _nc_warning("Allow ^? as synonym for \\177");
} else {
if ((c &= 037) == 0)
c = 128;
@@ -824,8 +834,6 @@ _nc_trans_string(char *ptr, char *last)
if (c == EOF)
_nc_err_abort(MSG_NO_INPUTS);
-#define isoctal(c) ((c) >= '0' && (c) <= '7')
-
if (isoctal(c) || (strict_bsd && isdigit(c))) {
number = c - '0';
for (i = 0; i < 2; i++) {
@@ -990,10 +998,8 @@ _nc_push_token(int tokclass)
NCURSES_EXPORT(void)
_nc_panic_mode(char ch)
{
- int c;
-
for (;;) {
- c = next_char();
+ int c = next_char();
if (c == ch)
return;
if (c == EOF)
diff --git a/ncurses/tinfo/db_iterator.c b/ncurses/tinfo/db_iterator.c
index 94a4082..f072668 100644
--- a/ncurses/tinfo/db_iterator.c
+++ b/ncurses/tinfo/db_iterator.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2006-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 2006-2016,2017 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 *
@@ -43,7 +44,7 @@
#include <hashed_db.h>
#endif
-MODULE_ID("$Id: db_iterator.c,v 1.39 2014/11/01 14:47:00 tom Exp $")
+MODULE_ID("$Id: db_iterator.c,v 1.48 2020/02/02 23:34:34 tom Exp $")
#define HaveTicDirectory _nc_globals.have_tic_directory
#define KeepTicDirectory _nc_globals.keep_tic_directory
@@ -72,15 +73,18 @@ 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))) {
+ if (quick_prefix(name)) {
+ result = TRUE;
+ } else if (stat(name, sb) == 0
+ && (S_ISDIR(sb->st_mode)
+ || (S_ISREG(sb->st_mode) && sb->st_size))) {
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)) {
+ if (stat(temp, sb) == 0 && S_ISREG(sb->st_mode) && sb->st_size) {
result = TRUE;
}
}
@@ -89,6 +93,27 @@ check_existence(const char *name, struct stat *sb)
}
/*
+ * Trim newlines (and backslashes preceding those) and tab characters to
+ * help simplify scripting of the quick-dump feature. Leave spaces and
+ * other backslashes alone.
+ */
+static void
+trim_formatting(char *source)
+{
+ char *target = source;
+ char ch;
+
+ while ((ch = *source++) != '\0') {
+ if (ch == '\\' && *source == '\n')
+ continue;
+ if (ch == '\n' || ch == '\t')
+ continue;
+ *target++ = ch;
+ }
+ *target = '\0';
+}
+
+/*
* Store the latest value of an environment variable in my_vars[] so we can
* detect if one changes, invalidating the cached search-list.
*/
@@ -99,19 +124,21 @@ update_getenv(const char *name, DBDIRS which)
if (which < dbdLAST) {
char *value;
+ char *cached_value = my_vars[which].value;
+ bool same_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)) {
+ if ((value = getenv(name)) != 0) {
+ value = strdup(value);
+ }
+ same_value = ((value == 0 && cached_value == 0) ||
+ (value != 0 &&
+ cached_value != 0 &&
+ strcmp(value, cached_value) == 0));
+
+ /* Set variable name to enable checks in cache_expired(). */
+ my_vars[which].name = name;
+
+ if (!same_value) {
FreeIfNeeded(my_vars[which].value);
my_vars[which].value = value;
result = TRUE;
@@ -122,6 +149,7 @@ update_getenv(const char *name, DBDIRS which)
return result;
}
+#if NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP
static char *
cache_getenv(const char *name, DBDIRS which)
{
@@ -133,6 +161,7 @@ cache_getenv(const char *name, DBDIRS which)
}
return result;
}
+#endif
/*
* The cache expires if at least a second has passed since the initial lookup,
@@ -251,7 +280,7 @@ _nc_first_db(DBDIRS * state, int *offset)
*state = dbdTIC;
*offset = 0;
- T(("_nc_first_db"));
+ T((T_CALLED("_nc_first_db")));
/* build a blob containing all of the strings we will use for a lookup
* table.
@@ -260,7 +289,7 @@ _nc_first_db(DBDIRS * state, int *offset)
size_t blobsize = 0;
const char *values[dbdLAST];
struct stat *my_stat;
- int j, k;
+ int j;
if (cache_has_expired)
free_cache();
@@ -330,10 +359,12 @@ _nc_first_db(DBDIRS * state, int *offset)
my_list = typeCalloc(char *, blobsize);
my_stat = typeCalloc(struct stat, blobsize);
if (my_list != 0 && my_stat != 0) {
- k = 0;
+ int k = 0;
my_list[k++] = my_blob;
for (j = 0; my_blob[j] != '\0'; ++j) {
- if (my_blob[j] == NCURSES_PATHSEP) {
+ if (my_blob[j] == NCURSES_PATHSEP
+ && ((&my_blob[j] - my_list[k - 1]) != 3
+ || !quick_prefix(my_list[k - 1]))) {
my_blob[j] = '\0';
my_list[k++] = &my_blob[j + 1];
}
@@ -347,8 +378,10 @@ _nc_first_db(DBDIRS * state, int *offset)
if (*my_list[j] == '\0')
my_list[j] = strdup(TERMINFO);
#endif
+ trim_formatting(my_list[j]);
for (k = 0; k < j; ++k) {
if (!strcmp(my_list[j], my_list[k])) {
+ T(("duplicate %s", my_list[j]));
k = j - 1;
while ((my_list[j] = my_list[j + 1]) != 0) {
++j;
@@ -377,6 +410,7 @@ _nc_first_db(DBDIRS * state, int *offset)
}
#endif
if (!found) {
+ T(("not found %s", my_list[j]));
k = j;
while ((my_list[k] = my_list[k + 1]) != 0) {
++k;
@@ -392,6 +426,7 @@ _nc_first_db(DBDIRS * state, int *offset)
free(my_stat);
}
}
+ returnVoid;
}
#if NO_LEAKS
diff --git a/ncurses/tinfo/doalloc.c b/ncurses/tinfo/doalloc.c
index 7c502b0..f0c8141 100644
--- a/ncurses/tinfo/doalloc.c
+++ b/ncurses/tinfo/doalloc.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2000,2012 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2002,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 +40,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: doalloc.c,v 1.11 2012/11/03 19:27:41 tom Exp $")
+MODULE_ID("$Id: doalloc.c,v 1.12 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(void *)
_nc_doalloc(void *oldp, size_t amount)
diff --git a/ncurses/tinfo/entries.c b/ncurses/tinfo/entries.c
index e84033d..1c55bfe 100644
--- a/ncurses/tinfo/entries.c
+++ b/ncurses/tinfo/entries.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2006-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 2006-2012,2017 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 +38,7 @@
#include <tic.h>
-MODULE_ID("$Id: entries.c,v 1.21 2012/05/05 20:33:44 tom Exp $")
+MODULE_ID("$Id: entries.c,v 1.30 2020/02/02 23:34:34 tom Exp $")
/****************************************************************************
*
@@ -63,30 +64,8 @@ MODULE_ID("$Id: entries.c,v 1.21 2012/05/05 20:33:44 tom Exp $")
NCURSES_EXPORT_VAR(ENTRY *) _nc_head = 0;
NCURSES_EXPORT_VAR(ENTRY *) _nc_tail = 0;
-NCURSES_EXPORT(void)
-_nc_free_entry(ENTRY * headp, TERMTYPE *tterm)
-/* free the allocated storage consumed by the given list entry */
-{
- ENTRY *ep;
-
- if ((ep = _nc_delink_entry(headp, tterm)) != 0) {
- free(ep);
- }
-}
-
-NCURSES_EXPORT(void)
-_nc_free_entries(ENTRY * headp)
-/* free the allocated storage consumed by list entries */
-{
- (void) headp; /* unused - _nc_head is altered here! */
-
- while (_nc_head != 0) {
- _nc_free_termtype(&(_nc_head->tterm));
- }
-}
-
-NCURSES_EXPORT(ENTRY *)
-_nc_delink_entry(ENTRY * headp, TERMTYPE *tterm)
+static ENTRY *
+_nc_delink_entry(ENTRY * headp, TERMTYPE2 *tterm)
/* delink the allocated storage for the given list entry */
{
ENTRY *ep, *last;
@@ -112,6 +91,28 @@ _nc_delink_entry(ENTRY * headp, TERMTYPE *tterm)
}
NCURSES_EXPORT(void)
+_nc_free_entry(ENTRY * headp, TERMTYPE2 *tterm)
+/* free the allocated storage consumed by the given list entry */
+{
+ ENTRY *ep;
+
+ if ((ep = _nc_delink_entry(headp, tterm)) != 0) {
+ free(ep);
+ }
+}
+
+NCURSES_EXPORT(void)
+_nc_free_entries(ENTRY * headp)
+/* free the allocated storage consumed by list entries */
+{
+ (void) headp; /* unused - _nc_head is altered here! */
+
+ while (_nc_head != 0) {
+ _nc_free_termtype2(&(_nc_head->tterm));
+ }
+}
+
+NCURSES_EXPORT(void)
_nc_leaks_tinfo(void)
{
#if NO_LEAKS
@@ -120,14 +121,17 @@ _nc_leaks_tinfo(void)
T((T_CALLED("_nc_free_tinfo()")));
#if NO_LEAKS
+ _nc_globals.leak_checking = TRUE;
_nc_free_tparm();
_nc_tgetent_leaks();
if (TerminalOf(CURRENT_SCREEN) != 0) {
del_curterm(TerminalOf(CURRENT_SCREEN));
}
+ _nc_forget_prescr();
_nc_comp_captab_leaks();
+ _nc_comp_userdefs_leaks();
_nc_free_entries(_nc_head);
_nc_get_type(0);
_nc_first_name(0);
@@ -144,7 +148,8 @@ _nc_leaks_tinfo(void)
free(s);
#ifdef TRACE
- trace(0);
+ T((T_RETURN("")));
+ curses_trace(0);
_nc_trace_buf(-1, (size_t) 0);
#endif
@@ -160,3 +165,12 @@ _nc_free_tinfo(int code)
exit(code);
}
#endif
+
+NCURSES_EXPORT(void)
+exit_terminfo(int code)
+{
+#if NO_LEAKS
+ _nc_leaks_tinfo();
+#endif
+ exit(code);
+}
diff --git a/ncurses/tinfo/free_ttype.c b/ncurses/tinfo/free_ttype.c
index ad056ba..7f0fbcc 100644
--- a/ncurses/tinfo/free_ttype.c
+++ b/ncurses/tinfo/free_ttype.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1999-2010,2011 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1999-2011,2017 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 *
@@ -42,25 +43,46 @@
#include <tic.h>
-MODULE_ID("$Id: free_ttype.c,v 1.15 2011/02/06 01:08:31 tom Exp $")
+MODULE_ID("$Id: free_ttype.c,v 1.19 2020/02/02 23:34:34 tom Exp $")
-NCURSES_EXPORT(void)
-_nc_free_termtype(TERMTYPE *ptr)
+static void
+really_free_termtype(TERMTYPE2 *ptr, bool freeStrings)
{
T(("_nc_free_termtype(%s)", ptr->term_names));
- FreeIfNeeded(ptr->str_table);
+ if (freeStrings) {
+ FreeIfNeeded(ptr->str_table);
+ }
FreeIfNeeded(ptr->Booleans);
FreeIfNeeded(ptr->Numbers);
FreeIfNeeded(ptr->Strings);
#if NCURSES_XNAMES
- FreeIfNeeded(ptr->ext_str_table);
+ if (freeStrings) {
+ FreeIfNeeded(ptr->ext_str_table);
+ }
FreeIfNeeded(ptr->ext_Names);
#endif
memset(ptr, 0, sizeof(TERMTYPE));
_nc_free_entry(_nc_head, ptr);
}
+/*
+ * This entrypoint is used by tack 1.07
+ */
+NCURSES_EXPORT(void)
+_nc_free_termtype(TERMTYPE *ptr)
+{
+ really_free_termtype((TERMTYPE2 *) ptr, !NCURSES_EXT_NUMBERS);
+}
+
+#if NCURSES_EXT_NUMBERS
+NCURSES_EXPORT(void)
+_nc_free_termtype2(TERMTYPE2 *ptr)
+{
+ really_free_termtype(ptr, TRUE);
+}
+#endif
+
#if NCURSES_XNAMES
NCURSES_EXPORT_VAR(bool) _nc_user_definable = TRUE;
diff --git a/ncurses/tinfo/getenv_num.c b/ncurses/tinfo/getenv_num.c
index d5e35cb..ca179d3 100644
--- a/ncurses/tinfo/getenv_num.c
+++ b/ncurses/tinfo/getenv_num.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 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 +37,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: getenv_num.c,v 1.6 2013/09/28 20:25:08 tom Exp $")
+MODULE_ID("$Id: getenv_num.c,v 1.8 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(int)
_nc_getenv_num(const char *name)
@@ -68,6 +69,8 @@ _nc_setenv_num(const char *name, int value)
_nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) "%s=%d", name, value);
if ((s = strdup(buffer)) != 0)
putenv(s);
+#else
+#error expected setenv/putenv functions
#endif
}
}
diff --git a/ncurses/tinfo/hashed_db.c b/ncurses/tinfo/hashed_db.c
index b594205..b78d98f 100644
--- a/ncurses/tinfo/hashed_db.c
+++ b/ncurses/tinfo/hashed_db.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2006-2011,2013 Free Software Foundation, Inc. *
+ * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 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 *
@@ -36,7 +37,7 @@
#if USE_HASHED_DB
-MODULE_ID("$Id: hashed_db.c,v 1.17 2013/12/15 00:33:01 tom Exp $")
+MODULE_ID("$Id: hashed_db.c,v 1.19 2020/02/02 23:34:34 tom Exp $")
#if HASHED_DB_API >= 2
static DBC *cursor;
@@ -273,7 +274,7 @@ _nc_db_next(DB * db, DBT * key, DBT * data)
result = -1;
}
#else
- result = db->seq(db, key, data, 0);
+ result = db->seq(db, key, data, R_NEXT);
#endif
return result;
}
diff --git a/ncurses/tinfo/home_terminfo.c b/ncurses/tinfo/home_terminfo.c
index e77f71c..7e626df 100644
--- a/ncurses/tinfo/home_terminfo.c
+++ b/ncurses/tinfo/home_terminfo.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2010,2012 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2012,2016 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 +38,7 @@
#include <curses.priv.h>
#include <tic.h>
-MODULE_ID("$Id: home_terminfo.c,v 1.15 2012/10/27 21:49:14 tom Exp $")
+MODULE_ID("$Id: home_terminfo.c,v 1.17 2020/02/02 23:34:34 tom Exp $")
/* ncurses extension...fall back on user's private directory */
@@ -48,10 +49,11 @@ _nc_home_terminfo(void)
{
char *result = 0;
#if USE_HOME_TERMINFO
- char *home;
-
if (use_terminfo_vars()) {
+
if (MyBuffer == 0) {
+ char *home;
+
if ((home = getenv("HOME")) != 0) {
size_t want = (strlen(home) + sizeof(PRIVATE_INFO));
TYPE_MALLOC(char, want, MyBuffer);
diff --git a/ncurses/tinfo/init_keytry.c b/ncurses/tinfo/init_keytry.c
index ea47b38..1669c64 100644
--- a/ncurses/tinfo/init_keytry.c
+++ b/ncurses/tinfo/init_keytry.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1999-2009,2010 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1999-2010,2016 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 +30,7 @@
#include <curses.priv.h>
#include <tic.h> /* struct tinfo_fkeys */
-MODULE_ID("$Id: init_keytry.c,v 1.17 2010/04/24 22:29:56 tom Exp $")
+MODULE_ID("$Id: init_keytry.c,v 1.19 2020/02/02 23:34:34 tom Exp $")
/*
** _nc_init_keytry()
@@ -66,14 +67,14 @@ _nc_tinfo_fkeysf(void)
NCURSES_EXPORT(void)
_nc_init_keytry(SCREEN *sp)
{
- unsigned n;
-
/* The sp->_keytry value is initialized in newterm(), where the sp
* structure is created, because we can not tell where keypad() or
* mouse_activate() (which will call keyok()) are first called.
*/
if (sp != 0) {
+ unsigned n;
+
for (n = 0; _nc_tinfo_fkeys[n].code; n++) {
if (_nc_tinfo_fkeys[n].offset < STRCOUNT) {
(void) _nc_add_to_try(&(sp->_keytry),
diff --git a/ncurses/tinfo/lib_acs.c b/ncurses/tinfo/lib_acs.c
index 69a1851..4ede53f 100644
--- a/ncurses/tinfo/lib_acs.c
+++ b/ncurses/tinfo/lib_acs.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2014,2017 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 +40,7 @@
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_acs.c,v 1.45 2014/03/08 20:32:59 tom Exp $")
+MODULE_ID("$Id: lib_acs.c,v 1.50 2020/02/02 23:34:34 tom Exp $")
#if BROKEN_LINKER || USE_REENTRANT
#define MyBuffer _nc_prescreen.real_acs_map
@@ -171,7 +172,7 @@ NCURSES_SP_NAME(_nc_init_acs) (NCURSES_SP_DCL0)
if (ena_acs != NULL) {
NCURSES_PUTP2("ena_acs", ena_acs);
}
-#if NCURSES_EXT_FUNCS
+#if NCURSES_EXT_FUNCS && defined(enter_pc_charset_mode) && defined(exit_pc_charset_mode)
/*
* Linux console "supports" the "PC ROM" character set by the coincidence
* that smpch/rmpch and smacs/rmacs have the same values. ncurses has
@@ -205,8 +206,13 @@ NCURSES_SP_NAME(_nc_init_acs) (NCURSES_SP_DCL0)
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)
+ T(("#%d real_map[%s] = %s",
+ (int) i,
+ _tracechar(UChar(acs_chars[i])),
+ _tracechtype(real_map[UChar(acs_chars[i])])));
+ if (SP != 0) {
SP->_screen_acs_map[UChar(acs_chars[i])] = TRUE;
+ }
}
i += 2;
}
@@ -249,3 +255,72 @@ _nc_init_acs(void)
NCURSES_SP_NAME(_nc_init_acs) (CURRENT_SCREEN);
}
#endif
+
+#if !NCURSES_WCWIDTH_GRAPHICS
+NCURSES_EXPORT(int)
+_nc_wacs_width(unsigned ch)
+{
+ int result;
+ switch (ch) {
+ case 0x00a3: /* FALLTHRU - ncurses pound-sterling symbol */
+ case 0x00b0: /* FALLTHRU - VT100 degree symbol */
+ case 0x00b1: /* FALLTHRU - VT100 plus/minus */
+ case 0x00b7: /* FALLTHRU - VT100 bullet */
+ case 0x03c0: /* FALLTHRU - ncurses greek pi */
+ case 0x2190: /* FALLTHRU - Teletype arrow pointing left */
+ case 0x2191: /* FALLTHRU - Teletype arrow pointing up */
+ case 0x2192: /* FALLTHRU - Teletype arrow pointing right */
+ case 0x2193: /* FALLTHRU - Teletype arrow pointing down */
+ case 0x2260: /* FALLTHRU - ncurses not-equal */
+ case 0x2264: /* FALLTHRU - ncurses less-than-or-equal-to */
+ case 0x2265: /* FALLTHRU - ncurses greater-than-or-equal-to */
+ case 0x23ba: /* FALLTHRU - VT100 scan line 1 */
+ case 0x23bb: /* FALLTHRU - ncurses scan line 3 */
+ case 0x23bc: /* FALLTHRU - ncurses scan line 7 */
+ case 0x23bd: /* FALLTHRU - VT100 scan line 9 */
+ case 0x2500: /* FALLTHRU - VT100 horizontal line */
+ case 0x2501: /* FALLTHRU - thick horizontal line */
+ case 0x2502: /* FALLTHRU - VT100 vertical line */
+ case 0x2503: /* FALLTHRU - thick vertical line */
+ case 0x250c: /* FALLTHRU - VT100 upper left corner */
+ case 0x250f: /* FALLTHRU - thick upper left corner */
+ case 0x2510: /* FALLTHRU - VT100 upper right corner */
+ case 0x2513: /* FALLTHRU - thick upper right corner */
+ case 0x2514: /* FALLTHRU - VT100 lower left corner */
+ case 0x2517: /* FALLTHRU - thick lower left corner */
+ case 0x2518: /* FALLTHRU - VT100 lower right corner */
+ case 0x251b: /* FALLTHRU - thick lower right corner */
+ case 0x251c: /* FALLTHRU - VT100 tee pointing left */
+ case 0x2523: /* FALLTHRU - thick tee pointing left */
+ case 0x2524: /* FALLTHRU - VT100 tee pointing right */
+ case 0x252b: /* FALLTHRU - thick tee pointing right */
+ case 0x252c: /* FALLTHRU - VT100 tee pointing down */
+ case 0x2533: /* FALLTHRU - thick tee pointing down */
+ case 0x2534: /* FALLTHRU - VT100 tee pointing up */
+ case 0x253b: /* FALLTHRU - thick tee pointing up */
+ case 0x253c: /* FALLTHRU - VT100 large plus or crossover */
+ case 0x254b: /* FALLTHRU - thick large plus or crossover */
+ case 0x2550: /* FALLTHRU - double horizontal line */
+ case 0x2551: /* FALLTHRU - double vertical line */
+ case 0x2554: /* FALLTHRU - double upper left corner */
+ case 0x2557: /* FALLTHRU - double upper right corner */
+ case 0x255a: /* FALLTHRU - double lower left corner */
+ case 0x255d: /* FALLTHRU - double lower right corner */
+ case 0x2560: /* FALLTHRU - double tee pointing right */
+ case 0x2563: /* FALLTHRU - double tee pointing left */
+ case 0x2566: /* FALLTHRU - double tee pointing down */
+ case 0x2569: /* FALLTHRU - double tee pointing up */
+ case 0x256c: /* FALLTHRU - double large plus or crossover */
+ case 0x2592: /* FALLTHRU - VT100 checker board (stipple) */
+ case 0x25ae: /* FALLTHRU - Teletype solid square block */
+ case 0x25c6: /* FALLTHRU - VT100 diamond */
+ case 0x2603: /* FALLTHRU - Teletype lantern symbol */
+ result = 1;
+ break;
+ default:
+ result = wcwidth(ch);
+ break;
+ }
+ return result;
+}
+#endif /* !NCURSES_WCWIDTH_GRAPHICS */
diff --git a/ncurses/tinfo/lib_baudrate.c b/ncurses/tinfo/lib_baudrate.c
index 1dee46c..4f72de5 100644
--- a/ncurses/tinfo/lib_baudrate.c
+++ b/ncurses/tinfo/lib_baudrate.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 +40,7 @@
#include <curses.priv.h>
#include <termcap.h> /* ospeed */
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
#include <sys/param.h>
#endif
@@ -49,7 +50,11 @@
* of the indices up to B115200 fit nicely in a 'short', allowing us to retain
* ospeed's type for compatibility.
*/
-#if NCURSES_OSPEED_COMPAT && ((defined(__FreeBSD__) && (__FreeBSD_version < 700000)) || defined(__NetBSD__) || defined(__OpenBSD__))
+#if NCURSES_OSPEED_COMPAT && \
+ ((defined(__FreeBSD__) && (__FreeBSD_version < 700000)) || \
+ defined(__NetBSD__) || \
+ ((defined(__OpenBSD__) && OpenBSD < 201510)) || \
+ defined(__APPLE__))
#undef B0
#undef B50
#undef B75
@@ -79,7 +84,7 @@
#undef USE_OLD_TTY
#endif /* USE_OLD_TTY */
-MODULE_ID("$Id: lib_baudrate.c,v 1.35 2014/04/26 18:48:19 juergen Exp $")
+MODULE_ID("$Id: lib_baudrate.c,v 1.44 2020/02/02 23:34:34 tom Exp $")
/*
* int
@@ -90,8 +95,8 @@ MODULE_ID("$Id: lib_baudrate.c,v 1.35 2014/04/26 18:48:19 juergen Exp $")
*/
struct speed {
- NCURSES_OSPEED s; /* values for 'ospeed' */
- int sp; /* the actual speed */
+ int given_speed; /* values for 'ospeed' */
+ int actual_speed; /* the actual speed */
};
#define DATA(number) { B##number, number }
@@ -117,6 +122,9 @@ static struct speed const speeds[] =
#elif defined(EXTA)
{EXTA, 19200},
#endif
+#ifdef B28800
+ DATA(28800),
+#endif
#ifdef B38400
DATA(38400),
#elif defined(EXTB)
@@ -127,18 +135,57 @@ static struct speed const speeds[] =
#endif
/* ifdef to prevent overflow when OLD_TTY is not available */
#if !(NCURSES_OSPEED_COMPAT && defined(__FreeBSD__) && (__FreeBSD_version > 700000))
+#ifdef B76800
+ DATA(76800),
+#endif
#ifdef B115200
DATA(115200),
#endif
+#ifdef B153600
+ DATA(153600),
+#endif
#ifdef B230400
DATA(230400),
#endif
+#ifdef B307200
+ DATA(307200),
+#endif
#ifdef B460800
DATA(460800),
#endif
+#ifdef B500000
+ DATA(500000),
+#endif
+#ifdef B576000
+ DATA(576000),
+#endif
#ifdef B921600
DATA(921600),
#endif
+#ifdef B1000000
+ DATA(1000000),
+#endif
+#ifdef B1152000
+ DATA(1152000),
+#endif
+#ifdef B1500000
+ DATA(1500000),
+#endif
+#ifdef B2000000
+ DATA(2000000),
+#endif
+#ifdef B2500000
+ DATA(2500000),
+#endif
+#ifdef B3000000
+ DATA(3000000),
+#endif
+#ifdef B3500000
+ DATA(3500000),
+#endif
+#ifdef B4000000
+ DATA(4000000),
+#endif
#endif
};
@@ -151,8 +198,11 @@ _nc_baudrate(int OSpeed)
#endif
int result = ERR;
- unsigned i;
+ if (OSpeed < 0)
+ OSpeed = (NCURSES_OSPEED) OSpeed;
+ if (OSpeed < 0)
+ OSpeed = (unsigned short) OSpeed;
#if !USE_REENTRANT
if (OSpeed == last_OSpeed) {
result = last_baudrate;
@@ -160,9 +210,14 @@ _nc_baudrate(int OSpeed)
#endif
if (result == ERR) {
if (OSpeed >= 0) {
+ unsigned i;
+
for (i = 0; i < SIZEOF(speeds); i++) {
- if (speeds[i].s == OSpeed) {
- result = speeds[i].sp;
+ if (speeds[i].given_speed > OSpeed) {
+ break;
+ }
+ if (speeds[i].given_speed == OSpeed) {
+ result = speeds[i].actual_speed;
break;
}
}
@@ -181,12 +236,13 @@ NCURSES_EXPORT(int)
_nc_ospeed(int BaudRate)
{
int result = 1;
- unsigned i;
if (BaudRate >= 0) {
+ unsigned i;
+
for (i = 0; i < SIZEOF(speeds); i++) {
- if (speeds[i].sp == BaudRate) {
- result = speeds[i].s;
+ if (speeds[i].actual_speed == BaudRate) {
+ result = speeds[i].given_speed;
break;
}
}
@@ -208,7 +264,7 @@ NCURSES_SP_NAME(baudrate) (NCURSES_SP_DCL0)
*/
#ifdef TRACE
if (IsValidTIScreen(SP_PARM)
- && !NC_ISATTY(fileno(SP_PARM ? SP_PARM->_ofp : stdout))
+ && !NC_ISATTY(fileno((SP_PARM && SP_PARM->_ofp) ? SP_PARM->_ofp : stdout))
&& getenv("BAUDRATE") != 0) {
int ret;
if ((ret = _nc_getenv_num("BAUDRATE")) <= 0)
diff --git a/ncurses/tinfo/lib_cur_term.c b/ncurses/tinfo/lib_cur_term.c
index 9941d13..4a90335 100644
--- a/ncurses/tinfo/lib_cur_term.c
+++ b/ncurses/tinfo/lib_cur_term.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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,10 +40,10 @@
#include <curses.priv.h>
#include <termcap.h> /* ospeed */
-MODULE_ID("$Id: lib_cur_term.c,v 1.33 2014/03/08 20:32:59 tom Exp $")
+MODULE_ID("$Id: lib_cur_term.c,v 1.42 2020/02/02 23:34:34 tom Exp $")
#undef CUR
-#define CUR termp->type.
+#define CUR TerminalType(termp).
#if USE_REENTRANT
@@ -76,7 +77,7 @@ NCURSES_EXPORT_VAR(TERMINAL *) cur_term = 0;
#endif
NCURSES_EXPORT(TERMINAL *)
-NCURSES_SP_NAME(set_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
+NCURSES_SP_NAME(set_curterm) (NCURSES_SP_DCLx TERMINAL *termp)
{
TERMINAL *oldterm;
@@ -95,16 +96,21 @@ NCURSES_SP_NAME(set_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
#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) {
+ if (TCB->drv &&
+ TCB->drv->isTerminfo &&
+ TerminalType(termp).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) {
+ if (TerminalType(termp).Strings) {
PC = (char) ((pad_char != NULL) ? pad_char[0] : 0);
}
#endif
+#if !USE_REENTRANT
+ save_ttytype(termp);
+#endif
}
_nc_unlock_global(curses);
@@ -114,14 +120,14 @@ NCURSES_SP_NAME(set_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(TERMINAL *)
-set_curterm(TERMINAL * termp)
+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)
+NCURSES_SP_NAME(del_curterm) (NCURSES_SP_DCLx TERMINAL *termp)
{
int rc = ERR;
@@ -139,7 +145,10 @@ NCURSES_SP_NAME(del_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
#endif
);
- _nc_free_termtype(&(termp->type));
+#if NCURSES_EXT_NUMBERS
+ _nc_free_termtype(&termp->type);
+#endif
+ _nc_free_termtype2(&TerminalType(termp));
if (termp == cur)
NCURSES_SP_NAME(set_curterm) (NCURSES_SP_ARGx 0);
@@ -153,6 +162,10 @@ NCURSES_SP_NAME(del_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
if (TCB->drv)
TCB->drv->td_release(TCB);
#endif
+#if NO_LEAKS
+ /* discard memory used in tgetent's cache for this terminal */
+ _nc_tgetent_leak(termp);
+#endif
free(termp);
rc = OK;
@@ -162,9 +175,9 @@ NCURSES_SP_NAME(del_curterm) (NCURSES_SP_DCLx TERMINAL * termp)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(int)
-del_curterm(TERMINAL * termp)
+del_curterm(TERMINAL *termp)
{
- int rc = ERR;
+ int rc;
_nc_lock_global(curses);
rc = NCURSES_SP_NAME(del_curterm) (CURRENT_SCREEN, termp);
diff --git a/ncurses/tinfo/lib_data.c b/ncurses/tinfo/lib_data.c
index 06b6f88..bf3e554 100644
--- a/ncurses/tinfo/lib_data.c
+++ b/ncurses/tinfo/lib_data.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -42,7 +43,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: lib_data.c,v 1.66 2013/08/24 17:28:24 tom Exp $")
+MODULE_ID("$Id: lib_data.c,v 1.80 2020/02/02 23:34:34 tom Exp $")
/*
* OS/2's native linker complains if we don't initialize public data when
@@ -94,7 +95,9 @@ _nc_screen(void)
NCURSES_EXPORT(int)
_nc_alloc_screen(void)
{
- return ((my_screen = _nc_alloc_screen_sp()) != 0);
+ my_screen = _nc_alloc_screen_sp();
+ T(("_nc_alloc_screen_sp %p", my_screen));
+ return (my_screen != 0);
}
NCURSES_EXPORT(void)
@@ -137,6 +140,8 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
0, /* slk_format */
+ 2048, /* getstr_limit */
+
NULL, /* safeprint_buf */
0, /* safeprint_used */
@@ -150,6 +155,10 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
0, /* dbd_time */
{ { 0, 0 } }, /* dbd_vars */
+#ifdef USE_TERM_DRIVER
+ 0, /* term_driver */
+#endif
+
#ifndef USE_SP_WINDOWLIST
0, /* _nc_windowlist */
#endif
@@ -163,15 +172,28 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
0, /* safeprint_rows */
#endif
-#ifdef USE_TERM_DRIVER
- 0, /* term_driver */
+#ifdef USE_PTHREADS
+ PTHREAD_MUTEX_INITIALIZER, /* mutex_curses */
+ PTHREAD_MUTEX_INITIALIZER, /* mutex_prescreen */
+ PTHREAD_MUTEX_INITIALIZER, /* mutex_screen */
+ PTHREAD_MUTEX_INITIALIZER, /* mutex_update */
+ PTHREAD_MUTEX_INITIALIZER, /* mutex_tst_tracef */
+ PTHREAD_MUTEX_INITIALIZER, /* mutex_tracef */
+ 0, /* nested_tracef */
+ 0, /* use_pthreads */
+#if USE_PTHREADS_EINTR
+ 0, /* read_thread */
+#endif
+#endif
+#if USE_WIDEC_SUPPORT
+ CHARS_0s, /* key_name */
#endif
-
#ifdef TRACE
- FALSE, /* init_trace */
+ FALSE, /* trace_opened */
CHARS_0s, /* trace_fname */
0, /* trace_level */
NULL, /* trace_fp */
+ -1, /* trace_fd */
NULL, /* tracearg_buf */
0, /* tracearg_used */
@@ -194,15 +216,8 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
0, /* nested_tracef */
#endif
#endif /* TRACE */
-#ifdef USE_PTHREADS
- PTHREAD_MUTEX_INITIALIZER, /* mutex_curses */
- PTHREAD_MUTEX_INITIALIZER, /* mutex_tst_tracef */
- PTHREAD_MUTEX_INITIALIZER, /* mutex_tracef */
- 0, /* nested_tracef */
- 0, /* use_pthreads */
-#endif
-#if USE_PTHREADS_EINTR
- 0, /* read_thread */
+#if NO_LEAKS
+ FALSE, /* leak_checking */
#endif
};
@@ -214,17 +229,11 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
#define RIPOFF_0s { RIPOFF_0 }
NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = {
+ NULL, /* allocated */
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 */
-#endif
NULL, /* tparam_base */
STACK_FRAME_0s, /* stack */
@@ -239,12 +248,20 @@ NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = {
NUM_VARS_0s, /* dynamic_var */
NUM_VARS_0s, /* static_vars */
+#ifdef TRACE
+ NULL, /* tname */
+#endif
},
NULL, /* saved_tty */
+ FALSE, /* use_tioctl */
+ 0, /* _outch */
+#ifndef USE_SP_RIPOFF
+ RIPOFF_0s, /* ripoff */
+ NULL, /* rsp */
+#endif
#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 */
@@ -252,12 +269,13 @@ NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = {
8, /* TABSIZE */
1000, /* ESCDELAY */
0, /* cur_term */
+#endif
#ifdef TRACE
+#if BROKEN_LINKER || USE_REENTRANT
0L, /* _outchars */
NULL, /* _tputs_trace */
#endif
#endif
- FALSE, /* use_tioctl */
};
/* *INDENT-ON* */
@@ -287,6 +305,9 @@ init_global_mutexes(void)
if (!initialized) {
initialized = TRUE;
_nc_mutex_init(&_nc_globals.mutex_curses);
+ _nc_mutex_init(&_nc_globals.mutex_prescreen);
+ _nc_mutex_init(&_nc_globals.mutex_screen);
+ _nc_mutex_init(&_nc_globals.mutex_update);
_nc_mutex_init(&_nc_globals.mutex_tst_tracef);
_nc_mutex_init(&_nc_globals.mutex_tracef);
}
@@ -371,7 +392,7 @@ _nc_sigprocmask(int how, const sigset_t * newmask, sigset_t * oldmask)
if ((pthread_sigmask))
return pthread_sigmask(how, newmask, oldmask);
else
- return sigprocmask(how, newmask, oldmask);
+ return (sigprocmask) (how, newmask, oldmask);
}
#endif
#endif /* USE_PTHREADS */
diff --git a/ncurses/tinfo/lib_has_cap.c b/ncurses/tinfo/lib_has_cap.c
index 17e59d5..cbf68b3 100644
--- a/ncurses/tinfo/lib_has_cap.c
+++ b/ncurses/tinfo/lib_has_cap.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2009,2013 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 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 *
@@ -46,7 +47,7 @@
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_has_cap.c,v 1.10 2013/11/16 19:57:22 tom Exp $")
+MODULE_ID("$Id: lib_has_cap.c,v 1.11 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(bool)
NCURSES_SP_NAME(has_ic) (NCURSES_SP_DCL0)
diff --git a/ncurses/tinfo/lib_kernel.c b/ncurses/tinfo/lib_kernel.c
index 37f7084..482657a 100644
--- a/ncurses/tinfo/lib_kernel.c
+++ b/ncurses/tinfo/lib_kernel.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 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 *
@@ -48,7 +49,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: lib_kernel.c,v 1.31 2010/12/19 01:21:19 tom Exp $")
+MODULE_ID("$Id: lib_kernel.c,v 1.32 2020/02/02 23:34:34 tom Exp $")
static int
_nc_vdisable(void)
diff --git a/ncurses/tinfo/lib_longname.c b/ncurses/tinfo/lib_longname.c
index 1490317..835d15c 100644
--- a/ncurses/tinfo/lib_longname.c
+++ b/ncurses/tinfo/lib_longname.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 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 *
@@ -42,7 +43,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: lib_longname.c,v 1.12 2010/12/20 00:31:26 tom Exp $")
+MODULE_ID("$Id: lib_longname.c,v 1.14 2020/02/02 23:34:34 tom Exp $")
#if USE_REENTRANT
NCURSES_EXPORT(char *)
@@ -74,6 +75,17 @@ longname(void)
#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)
{
diff --git a/ncurses/tinfo/lib_napms.c b/ncurses/tinfo/lib_napms.c
index df17363..99dacd7 100644
--- a/ncurses/tinfo/lib_napms.c
+++ b/ncurses/tinfo/lib_napms.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2014 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2014,2017 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 *
@@ -51,7 +52,7 @@
#endif
#endif
-MODULE_ID("$Id: lib_napms.c,v 1.24 2014/03/08 20:32:59 tom Exp $")
+MODULE_ID("$Id: lib_napms.c,v 1.26 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(int)
NCURSES_SP_NAME(napms) (NCURSES_SP_DCLx int ms)
@@ -59,9 +60,7 @@ 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);
- }
+ CallDriver_1(SP_PARM, td_nap, ms);
#else /* !USE_TERM_DRIVER */
#if NCURSES_SP_FUNCS
(void) sp;
diff --git a/ncurses/tinfo/lib_options.c b/ncurses/tinfo/lib_options.c
index b736d5f..784e06c 100644
--- a/ncurses/tinfo/lib_options.c
+++ b/ncurses/tinfo/lib_options.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2014,2017 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,7 +47,7 @@
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_options.c,v 1.78 2014/09/27 21:55:24 tom Exp $")
+MODULE_ID("$Id: lib_options.c,v 1.81 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(int)
idlok(WINDOW *win, bool flag)
@@ -87,7 +88,7 @@ NCURSES_SP_NAME(halfdelay) (NCURSES_SP_DCLx int t)
{
T((T_CALLED("halfdelay(%p,%d)"), (void *) SP_PARM, t));
- if (t < 1 || t > 255 || !IsValidTIScreen(SP_PARM))
+ if (t < 1 || t > 255 || !SP_PARM || !IsValidTIScreen(SP_PARM))
returnCode(ERR);
NCURSES_SP_NAME(cbreak) (NCURSES_SP_ARG);
@@ -202,7 +203,7 @@ NCURSES_SP_NAME(curs_set) (NCURSES_SP_DCLx int vis)
#ifdef USE_TERM_DRIVER
code = CallDriver_1(SP_PARM, td_cursorSet, vis);
#else
- if (IsTermInfo(SP_PARM)) {
+ if (IsValidTIScreen(SP_PARM)) {
switch (vis) {
case 2:
code = NCURSES_PUTP2_FLUSH("cursor_visible",
@@ -241,7 +242,7 @@ 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)) {
+ if (SP_PARM && IsValidTIScreen(SP_PARM)) {
SP_PARM->_checkfd = fd;
returnCode(OK);
} else {
diff --git a/ncurses/tinfo/lib_print.c b/ncurses/tinfo/lib_print.c
index 0dab4d4..eb92149 100644
--- a/ncurses/tinfo/lib_print.c
+++ b/ncurses/tinfo/lib_print.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 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 *
@@ -39,7 +40,7 @@
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_print.c,v 1.23 2012/02/22 22:34:31 tom Exp $")
+MODULE_ID("$Id: lib_print.c,v 1.25 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(int)
NCURSES_SP_NAME(mcprint) (NCURSES_SP_DCLx char *data, int len)
@@ -95,7 +96,7 @@ NCURSES_SP_NAME(mcprint) (NCURSES_SP_DCLx char *data, int len)
* kernel will ship the contiguous clist items from the last write
* immediately.
*/
-#ifndef __MINGW32__
+#ifndef _WIN32
(void) sleep(0);
#endif
free(mybuf);
diff --git a/ncurses/tinfo/lib_raw.c b/ncurses/tinfo/lib_raw.c
index 928692b..a691a26 100644
--- a/ncurses/tinfo/lib_raw.c
+++ b/ncurses/tinfo/lib_raw.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -49,7 +50,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: lib_raw.c,v 1.21 2012/01/21 19:21:29 KO.Myung-Hun Exp $")
+MODULE_ID("$Id: lib_raw.c,v 1.24 2020/02/02 23:34:34 tom Exp $")
#if HAVE_SYS_TERMIO_H
#include <sys/termio.h> /* needed for ISC */
@@ -112,8 +113,10 @@ NCURSES_SP_NAME(raw) (NCURSES_SP_DCL0)
kbdinfo.fsMask |= KEYBOARD_BINARY_MODE;
KbdSetStatus(&kbdinfo, 0);
#endif
- SP_PARM->_raw = TRUE;
- SP_PARM->_cbreak = 1;
+ if (SP_PARM) {
+ SP_PARM->_raw = TRUE;
+ SP_PARM->_cbreak = 1;
+ }
termp->Nttyb = buf;
}
AFTER("raw");
@@ -154,7 +157,9 @@ NCURSES_SP_NAME(cbreak) (NCURSES_SP_DCL0)
#endif
result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
if (result == OK) {
- SP_PARM->_cbreak = 1;
+ if (SP_PARM) {
+ SP_PARM->_cbreak = 1;
+ }
termp->Nttyb = buf;
}
AFTER("cbreak");
@@ -177,12 +182,12 @@ cbreak(void)
NCURSES_EXPORT(void)
NCURSES_SP_NAME(qiflush) (NCURSES_SP_DCL0)
{
- int result = ERR;
TERMINAL *termp;
T((T_CALLED("qiflush(%p)"), (void *) SP_PARM));
if ((termp = TerminalOf(SP_PARM)) != 0) {
TTY buf;
+ int result;
BEFORE("qiflush");
buf = termp->Nttyb;
@@ -190,6 +195,7 @@ NCURSES_SP_NAME(qiflush) (NCURSES_SP_DCL0)
buf.c_lflag &= (unsigned) ~(NOFLSH);
result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
#else
+ result = ERR;
/* FIXME */
#endif
if (result == OK)
@@ -241,8 +247,10 @@ NCURSES_SP_NAME(noraw) (NCURSES_SP_DCL0)
kbdinfo.fsMask |= KEYBOARD_ASCII_MODE;
KbdSetStatus(&kbdinfo, 0);
#endif
- SP_PARM->_raw = FALSE;
- SP_PARM->_cbreak = 0;
+ if (SP_PARM) {
+ SP_PARM->_raw = FALSE;
+ SP_PARM->_cbreak = 0;
+ }
termp->Nttyb = buf;
}
AFTER("noraw");
@@ -280,7 +288,9 @@ NCURSES_SP_NAME(nocbreak) (NCURSES_SP_DCL0)
#endif
result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
if (result == OK) {
- SP_PARM->_cbreak = 0;
+ if (SP_PARM) {
+ SP_PARM->_cbreak = 0;
+ }
termp->Nttyb = buf;
}
AFTER("nocbreak");
@@ -299,12 +309,12 @@ nocbreak(void)
NCURSES_EXPORT(void)
NCURSES_SP_NAME(noqiflush) (NCURSES_SP_DCL0)
{
- int result = ERR;
TERMINAL *termp;
T((T_CALLED("noqiflush(%p)"), (void *) SP_PARM));
if ((termp = TerminalOf(SP_PARM)) != 0) {
TTY buf;
+ int result;
BEFORE("noqiflush");
buf = termp->Nttyb;
@@ -313,6 +323,7 @@ NCURSES_SP_NAME(noqiflush) (NCURSES_SP_DCL0)
result = NCURSES_SP_NAME(_nc_set_tty_mode) (NCURSES_SP_ARGx &buf);
#else
/* FIXME */
+ result = ERR;
#endif
if (result == OK)
termp->Nttyb = buf;
diff --git a/ncurses/tinfo/lib_setup.c b/ncurses/tinfo/lib_setup.c
index 0b81a5e..a6527bf 100644
--- a/ncurses/tinfo/lib_setup.c
+++ b/ncurses/tinfo/lib_setup.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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,7 +49,7 @@
#include <locale.h>
#endif
-MODULE_ID("$Id: lib_setup.c,v 1.161 2014/11/01 12:33:16 tom Exp $")
+MODULE_ID("$Id: lib_setup.c,v 1.207 2020/02/02 23:34:34 tom Exp $")
/****************************************************************************
*
@@ -98,7 +99,7 @@ MODULE_ID("$Id: lib_setup.c,v 1.161 2014/11/01 12:33:16 tom Exp $")
* Reduce explicit use of "cur_term" global variable.
*/
#undef CUR
-#define CUR termp->type.
+#define CUR TerminalType(termp).
/*
* Wrap global variables in this module.
@@ -115,12 +116,12 @@ NCURSES_PUBLIC_VAR(ttytype) (void)
if (CURRENT_SCREEN) {
TERMINAL *termp = TerminalOf(CURRENT_SCREEN);
if (termp != 0) {
- result = termp->type.term_names;
+ result = TerminalType(termp).term_names;
}
}
#else
if (cur_term != 0) {
- result = cur_term->type.term_names;
+ result = TerminalType(cur_term).term_names;
}
#endif
return result;
@@ -173,16 +174,20 @@ NCURSES_EXPORT(int)
NCURSES_SP_NAME(set_tabsize) (NCURSES_SP_DCLx int value)
{
int code = OK;
-#if USE_REENTRANT
- if (SP_PARM) {
- SP_PARM->_TABSIZE = value;
- } else {
+ if (value <= 0) {
code = ERR;
- }
+ } else {
+#if USE_REENTRANT
+ if (SP_PARM) {
+ SP_PARM->_TABSIZE = value;
+ } else {
+ code = ERR;
+ }
#else
- (void) SP_PARM;
- TABSIZE = value;
+ (void) SP_PARM;
+ TABSIZE = value;
#endif
+ }
return code;
}
@@ -220,9 +225,9 @@ _nc_handle_sigwinch(SCREEN *sp)
NCURSES_EXPORT(void)
NCURSES_SP_NAME(use_env) (NCURSES_SP_DCLx bool f)
{
+ START_TRACE();
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;
}
@@ -235,11 +240,11 @@ NCURSES_SP_NAME(use_env) (NCURSES_SP_DCLx bool f)
NCURSES_EXPORT(void)
NCURSES_SP_NAME(use_tioctl) (NCURSES_SP_DCLx bool f)
{
+ START_TRACE();
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;
+ SP_PARM->use_tioctl = f;
}
#else
_nc_prescreen.use_tioctl = f;
@@ -251,8 +256,8 @@ NCURSES_SP_NAME(use_tioctl) (NCURSES_SP_DCLx bool f)
NCURSES_EXPORT(void)
use_env(bool f)
{
- T((T_CALLED("use_env(%d)"), (int) f));
START_TRACE();
+ T((T_CALLED("use_env(%d)"), (int) f));
_nc_prescreen.use_env = f;
returnVoid;
}
@@ -260,8 +265,8 @@ use_env(bool f)
NCURSES_EXPORT(void)
use_tioctl(bool f)
{
- T((T_CALLED("use_tioctl(%d)"), (int) f));
START_TRACE();
+ T((T_CALLED("use_tioctl(%d)"), (int) f));
_nc_prescreen.use_tioctl = f;
returnVoid;
}
@@ -270,7 +275,7 @@ use_tioctl(bool f)
NCURSES_EXPORT(void)
_nc_get_screensize(SCREEN *sp,
#ifdef USE_TERM_DRIVER
- TERMINAL * termp,
+ TERMINAL *termp,
#endif
int *linep, int *colp)
/* Obtain lines/columns values from the environment and/or terminfo entry */
@@ -297,6 +302,8 @@ _nc_get_screensize(SCREEN *sp,
#else /* !USE_TERM_DRIVER */
TERMINAL *termp = cur_term;
int my_tabsize;
+ bool useEnv = _nc_prescreen.use_env;
+ bool useTioctl = _nc_prescreen.use_tioctl;
/* figure out the size of the screen */
T(("screen size: terminfo lines = %d columns = %d", lines, columns));
@@ -304,9 +311,14 @@ _nc_get_screensize(SCREEN *sp,
*linep = (int) lines;
*colp = (int) columns;
- if (_nc_prescreen.use_env || _nc_prescreen.use_tioctl) {
- int value;
+#if NCURSES_SP_FUNCS
+ if (sp) {
+ useEnv = sp->_use_env;
+ useTioctl = sp->use_tioctl;
+ }
+#endif
+ if (useEnv || useTioctl) {
#ifdef __EMX__
{
int screendata[2];
@@ -340,8 +352,10 @@ _nc_get_screensize(SCREEN *sp,
}
#endif /* HAVE_SIZECHANGE */
- if (_nc_prescreen.use_env) {
- if (_nc_prescreen.use_tioctl) {
+ if (useEnv) {
+ int value;
+
+ if (useTioctl) {
/*
* If environment variables are used, update them.
*/
@@ -389,8 +403,14 @@ _nc_get_screensize(SCREEN *sp,
* 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);
+ lines = (NCURSES_INT2) (*linep);
+ columns = (NCURSES_INT2) (*colp);
+#if NCURSES_EXT_NUMBERS
+#define OldNumber(termp,name) \
+ (termp)->type.Numbers[(&name - (termp)->type2.Numbers)]
+ OldNumber(termp, lines) = (short) (*linep);
+ OldNumber(termp, columns) = (short) (*colp);
+#endif
}
T(("screen size is %dx%d", *linep, *colp));
@@ -431,23 +451,24 @@ _nc_update_screensize(SCREEN *sp)
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(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 */
+ if (sp != 0) {
+ 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->_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;
}
- sp->_sig_winch = FALSE;
}
}
-#endif
+#endif /* USE_SIZECHANGE */
/****************************************************************************
*
@@ -461,10 +482,10 @@ _nc_update_screensize(SCREEN *sp)
* just like tgetent().
*/
int
-_nc_setup_tinfo(const char *const tn, TERMTYPE *const tp)
+_nc_setup_tinfo(const char *const tn, TERMTYPE2 *const tp)
{
char filename[PATH_MAX];
- int status = _nc_read_entry(tn, filename, tp);
+ int status = _nc_read_entry2(tn, filename, tp);
/*
* If we have an entry, force all of the cancelled strings to null
@@ -492,10 +513,8 @@ _nc_setup_tinfo(const char *const tn, TERMTYPE *const tp)
** and substitute it in for the prototype given in 'command_character'.
*/
void
-_nc_tinfo_cmdch(TERMINAL * termp, int proto)
+_nc_tinfo_cmdch(TERMINAL *termp, int proto)
{
- unsigned i;
- char CC;
char *tmp;
/*
@@ -504,7 +523,9 @@ _nc_tinfo_cmdch(TERMINAL * termp, int proto)
* name as an environment variable - using the same symbol.
*/
if ((tmp = getenv("CC")) != 0 && strlen(tmp) == 1) {
- CC = *tmp;
+ unsigned i;
+ char CC = *tmp;
+
for_each_string(i, &(termp->type)) {
for (tmp = termp->type.Strings[i]; tmp && *tmp; tmp++) {
if (UChar(*tmp) == proto)
@@ -528,9 +549,9 @@ _nc_get_locale(void)
*/
env = setlocale(LC_CTYPE, 0);
#else
- if (((env = getenv("LC_ALL")) != 0 && *env != '\0')
+ if (((env = getenv("LANG")) != 0 && *env != '\0')
|| ((env = getenv("LC_CTYPE")) != 0 && *env != '\0')
- || ((env = getenv("LANG")) != 0 && *env != '\0')) {
+ || ((env = getenv("LC_ALL")) != 0 && *env != '\0')) {
;
}
#endif
@@ -545,7 +566,7 @@ NCURSES_EXPORT(int)
_nc_unicode_locale(void)
{
int result = 0;
-#if defined(__MINGW32__) && USE_WIDEC_SUPPORT
+#if defined(_WIN32) && USE_WIDEC_SUPPORT
result = 1;
#elif HAVE_LANGINFO_CODESET
char *env = nl_langinfo(CODESET);
@@ -571,13 +592,14 @@ _nc_unicode_locale(void)
* character set.
*/
NCURSES_EXPORT(int)
-_nc_locale_breaks_acs(TERMINAL * termp)
+_nc_locale_breaks_acs(TERMINAL *termp)
{
const char *env_name = "NCURSES_NO_UTF8_ACS";
const char *env;
int value;
int result = 0;
+ 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) {
@@ -597,23 +619,22 @@ _nc_locale_breaks_acs(TERMINAL * termp)
}
}
}
- return result;
+ returnCode(result);
}
NCURSES_EXPORT(int)
-TINFO_SETUP_TERM(TERMINAL ** tp,
- NCURSES_CONST char *tname,
+TINFO_SETUP_TERM(TERMINAL **tp,
+ const char *tname,
int Filedes,
int *errret,
int reuse)
{
#ifdef USE_TERM_DRIVER
TERMINAL_CONTROL_BLOCK *TCB = 0;
-#else
- int status;
#endif
TERMINAL *termp;
SCREEN *sp = 0;
+ char *myname;
int code = ERR;
START_TRACE();
@@ -642,14 +663,16 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
#endif
}
}
+ myname = strdup(tname);
- if (strlen(tname) > MAX_NAME_SIZE) {
+ if (strlen(myname) > MAX_NAME_SIZE) {
ret_error(TGETENT_ERR,
"TERM environment must be <= %d characters.\n",
- MAX_NAME_SIZE);
+ MAX_NAME_SIZE,
+ free(myname));
}
- T(("your terminal name is %s", tname));
+ T(("your terminal name is %s", myname));
/*
* Allow output redirection. This is what SVr3 does. If stdout is
@@ -678,8 +701,8 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
&& (termp != 0)
&& termp->Filedes == Filedes
&& termp->_termname != 0
- && !strcmp(termp->_termname, tname)
- && _nc_name_match(termp->type.term_names, tname, "|")) {
+ && !strcmp(termp->_termname, myname)
+ && _nc_name_match(TerminalType(termp).term_names, myname, "|")) {
T(("reusing existing terminal information and mode-settings"));
code = OK;
#ifdef USE_TERM_DRIVER
@@ -688,39 +711,65 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
} else {
#ifdef USE_TERM_DRIVER
TERMINAL_CONTROL_BLOCK *my_tcb;
- my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1);
- termp = &(my_tcb->term);
+ termp = 0;
+ if ((my_tcb = typeCalloc(TERMINAL_CONTROL_BLOCK, 1)) != 0)
+ termp = &(my_tcb->term);
#else
+ int status;
+
termp = typeCalloc(TERMINAL, 1);
#endif
if (termp == 0) {
- ret_error0(TGETENT_ERR,
- "Not enough memory to create terminal structure.\n");
+ ret_error1(TGETENT_ERR,
+ "Not enough memory to create terminal structure.\n",
+ myname, free(myname));
}
+#if HAVE_SYSCONF
+ {
+ long limit;
+#ifdef LINE_MAX
+ limit = LINE_MAX;
+#else
+ limit = _nc_globals.getstr_limit;
+#endif
+#ifdef _SC_LINE_MAX
+ if (limit < sysconf(_SC_LINE_MAX))
+ limit = sysconf(_SC_LINE_MAX);
+#endif
+ if (_nc_globals.getstr_limit < (int) limit)
+ _nc_globals.getstr_limit = (int) limit;
+ }
+#endif /* HAVE_SYSCONF */
+ T(("using %d for getstr limit", _nc_globals.getstr_limit));
+
#ifdef USE_TERM_DRIVER
INIT_TERM_DRIVER();
TCB = (TERMINAL_CONTROL_BLOCK *) termp;
- code = _nc_globals.term_driver(TCB, tname, errret);
+ code = _nc_globals.term_driver(TCB, myname, errret);
if (code == OK) {
termp->Filedes = (short) Filedes;
- termp->_termname = strdup(tname);
+ termp->_termname = strdup(myname);
} else {
- ret_error0(TGETENT_ERR,
- "Could not find any driver to handle this terminal.\n");
+ ret_error1(errret ? *errret : TGETENT_ERR,
+ "Could not find any driver to handle terminal.\n",
+ myname, free(myname));
}
#else
#if NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP
- status = _nc_setup_tinfo(tname, &termp->type);
+ status = _nc_setup_tinfo(myname, &TerminalType(termp));
+ T(("_nc_setup_tinfo returns %d", status));
#else
+ T(("no database available"));
status = TGETENT_NO;
#endif
/* try fallback list if entry on disk */
if (status != TGETENT_YES) {
- const TERMTYPE *fallback = _nc_fallback(tname);
+ const TERMTYPE2 *fallback = _nc_fallback2(myname);
if (fallback) {
- _nc_copy_termtype(&(termp->type), fallback);
+ T(("found fallback entry"));
+ _nc_copy_termtype2(&(TerminalType(termp)), fallback);
status = TGETENT_YES;
}
}
@@ -728,18 +777,24 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
if (status != TGETENT_YES) {
del_curterm(termp);
if (status == TGETENT_ERR) {
+ free(myname);
ret_error0(status, "terminals database is inaccessible\n");
} else if (status == TGETENT_NO) {
- ret_error1(status, "unknown terminal type.\n", tname);
+ ret_error1(status, "unknown terminal type.\n",
+ myname, free(myname));
+ } else {
+ ret_error0(status, "unexpected return-code\n");
}
}
+#if NCURSES_EXT_NUMBERS
+ _nc_export_termtype2(&termp->type, &TerminalType(termp));
+#endif
#if !USE_REENTRANT
- strncpy(ttytype, termp->type.term_names, (size_t) (NAMESIZE - 1));
- ttytype[NAMESIZE - 1] = '\0';
+ save_ttytype(termp);
#endif
termp->Filedes = (short) Filedes;
- termp->_termname = strdup(tname);
+ termp->_termname = strdup(myname);
set_curterm(termp);
@@ -750,10 +805,11 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
* 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.
+ * baudrate. Also get the shell-mode so that erasechar() works.
*/
if (NC_ISATTY(Filedes)) {
- def_prog_mode();
+ NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_ARG);
+ NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_ARG);
baudrate();
}
code = OK;
@@ -785,36 +841,97 @@ TINFO_SETUP_TERM(TERMINAL ** tp,
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);
+ ret_error1(TGETENT_YES, "terminal is not really generic.\n",
+ myname, free(myname));
} else {
del_curterm(termp);
- ret_error1(TGETENT_NO, "I need something more specific.\n", tname);
+ ret_error1(TGETENT_NO, "I need something more specific.\n",
+ myname, free(myname));
}
} else if (hard_copy) {
- ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname);
+ ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n",
+ myname, free(myname));
}
#endif
+ free(myname);
returnCode(code);
}
+#ifdef USE_PTHREADS
+/*
+ * Returns a non-null pointer unless a new screen should be allocated because
+ * no match was found in the pre-screen cache.
+ */
+NCURSES_EXPORT(SCREEN *)
+_nc_find_prescr(void)
+{
+ SCREEN *result = 0;
+ PRESCREEN_LIST *p;
+ pthread_t id = GetThreadID();
+ for (p = _nc_prescreen.allocated; p != 0; p = p->next) {
+ if (p->id == id) {
+ result = p->sp;
+ break;
+ }
+ }
+ return result;
+}
+
+/*
+ * Tells ncurses to forget that this thread was associated with the pre-screen
+ * cache. It does not modify the pre-screen cache itself, since that is used
+ * for creating new screens.
+ */
+NCURSES_EXPORT(void)
+_nc_forget_prescr(void)
+{
+ PRESCREEN_LIST *p, *q;
+ pthread_t id = GetThreadID();
+ for (p = _nc_prescreen.allocated, q = 0; p != 0; q = p, p = p->next) {
+ if (p->id == id) {
+ if (q) {
+ q->next = p->next;
+ } else {
+ _nc_prescreen.allocated = p->next;
+ }
+ free(p);
+ break;
+ }
+ }
+}
+#endif /* USE_PTHREADS */
+
#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.
+ * initialization in _nc_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;
+ SCREEN *sp;
START_TRACE();
T((T_CALLED("new_prescr()")));
- if (sp == 0) {
+ _nc_lock_global(screen);
+ if ((sp = _nc_find_prescr()) == 0) {
sp = _nc_alloc_screen_sp();
+ T(("_nc_alloc_screen_sp %p", (void *) sp));
if (sp != 0) {
+#ifdef USE_PTHREADS
+ PRESCREEN_LIST *p = typeCalloc(PRESCREEN_LIST, 1);
+ if (p != 0) {
+ p->id = GetThreadID();
+ p->sp = sp;
+ p->next = _nc_prescreen.allocated;
+ _nc_prescreen.allocated = p;
+ }
+#else
+ _nc_prescreen.allocated = sp;
+#endif
sp->rsp = sp->rippedoff;
sp->_filtered = _nc_prescreen.filter_mode;
sp->_use_env = _nc_prescreen.use_env;
@@ -830,7 +947,10 @@ new_prescr(void)
sp->_ESCDELAY = _nc_prescreen._ESCDELAY;
#endif
}
+ } else {
+ T(("_nc_alloc_screen_sp %p (reuse)", (void *) sp));
}
+ _nc_unlock_global(screen);
returnSP(sp);
}
#endif
@@ -841,17 +961,24 @@ new_prescr(void)
* the same TERMINAL data (see comment).
*/
NCURSES_EXPORT(int)
-_nc_setupterm(NCURSES_CONST char *tname,
+_nc_setupterm(const char *tname,
int Filedes,
int *errret,
int reuse)
{
- int res;
+ int rc = ERR;
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;
+
+ _nc_lock_global(prescreen);
+ START_TRACE();
+ if (TINFO_SETUP_TERM(&termp, tname, Filedes, errret, reuse) == OK) {
+ _nc_forget_prescr();
+ if (NCURSES_SP_NAME(set_curterm) (CURRENT_SCREEN_PRE, termp) != 0) {
+ rc = OK;
+ }
+ }
+ _nc_unlock_global(prescreen);
+ return rc;
}
#endif
@@ -862,7 +989,8 @@ _nc_setupterm(NCURSES_CONST char *tname,
* Make cur_term point to the structure.
*/
NCURSES_EXPORT(int)
-setupterm(NCURSES_CONST char *tname, int Filedes, int *errret)
+setupterm(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 fdfc494..5ce43a3 100644
--- a/ncurses/tinfo/lib_termcap.c
+++ b/ncurses/tinfo/lib_termcap.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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,7 +49,7 @@
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_termcap.c,v 1.80 2013/06/08 16:48:47 tom Exp $")
+MODULE_ID("$Id: lib_termcap.c,v 1.88 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT_VAR(char *) UP = 0;
NCURSES_EXPORT_VAR(char *) BC = 0;
@@ -100,8 +101,7 @@ NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
START_TRACE();
T((T_CALLED("tgetent()")));
- TINFO_SETUP_TERM(&termp, (NCURSES_CONST char *) name,
- STDOUT_FILENO, &rc, TRUE);
+ TINFO_SETUP_TERM(&termp, name, STDOUT_FILENO, &rc, TRUE);
#ifdef USE_TERM_DRIVER
if (termp == 0 ||
@@ -153,8 +153,12 @@ NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
}
CacheInx = best;
}
- LAST_TRM = TerminalOf(SP_PARM);
- LAST_SEQ = ++CacheSeq;
+ if (rc == 1) {
+ LAST_TRM = TerminalOf(SP_PARM);
+ LAST_SEQ = ++CacheSeq;
+ } else {
+ LAST_TRM = 0;
+ }
PC = 0;
UP = 0;
@@ -175,7 +179,8 @@ NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
if (backspace_if_not_bs != NULL)
BC = backspace_if_not_bs;
- if ((FIX_SGR0 = _nc_trim_sgr0(&(TerminalOf(SP_PARM)->type))) != 0) {
+ if ((FIX_SGR0 = _nc_trim_sgr0(&TerminalType(TerminalOf(SP_PARM))))
+ != 0) {
if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
if (FIX_SGR0 != exit_attribute_mode) {
free(FIX_SGR0);
@@ -230,15 +235,15 @@ same_tcname(const char *a, const char *b)
***************************************************************************/
NCURSES_EXPORT(int)
-NCURSES_SP_NAME(tgetflag) (NCURSES_SP_DCLx NCURSES_CONST char *id)
+NCURSES_SP_NAME(tgetflag) (NCURSES_SP_DCLx const char *id)
{
int result = 0; /* Solaris returns zero for missing flag */
- int j = -1;
T((T_CALLED("tgetflag(%p, %s)"), (void *) SP_PARM, id));
if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
- TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+ TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
struct name_table_entry const *entry_ptr;
+ int j = -1;
entry_ptr = _nc_find_type_entry(id, BOOLEAN, TRUE);
if (entry_ptr != 0) {
@@ -266,7 +271,7 @@ NCURSES_SP_NAME(tgetflag) (NCURSES_SP_DCLx NCURSES_CONST char *id)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(int)
-tgetflag(NCURSES_CONST char *id)
+tgetflag(const char *id)
{
return NCURSES_SP_NAME(tgetflag) (CURRENT_SCREEN, id);
}
@@ -282,15 +287,15 @@ tgetflag(NCURSES_CONST char *id)
***************************************************************************/
NCURSES_EXPORT(int)
-NCURSES_SP_NAME(tgetnum) (NCURSES_SP_DCLx NCURSES_CONST char *id)
+NCURSES_SP_NAME(tgetnum) (NCURSES_SP_DCLx const char *id)
{
int result = ABSENT_NUMERIC;
- int j = -1;
T((T_CALLED("tgetnum(%p, %s)"), (void *) SP_PARM, id));
if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
- TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+ TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
struct name_table_entry const *entry_ptr;
+ int j = -1;
entry_ptr = _nc_find_type_entry(id, NUMBER, TRUE);
if (entry_ptr != 0) {
@@ -318,7 +323,7 @@ NCURSES_SP_NAME(tgetnum) (NCURSES_SP_DCLx NCURSES_CONST char *id)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(int)
-tgetnum(NCURSES_CONST char *id)
+tgetnum(const char *id)
{
return NCURSES_SP_NAME(tgetnum) (CURRENT_SCREEN, id);
}
@@ -334,15 +339,15 @@ tgetnum(NCURSES_CONST char *id)
***************************************************************************/
NCURSES_EXPORT(char *)
-NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx NCURSES_CONST char *id, char **area)
+NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx const char *id, char **area)
{
char *result = NULL;
- int j = -1;
T((T_CALLED("tgetstr(%s,%p)"), id, (void *) area));
if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
- TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+ TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
struct name_table_entry const *entry_ptr;
+ int j = -1;
entry_ptr = _nc_find_type_entry(id, STRING, TRUE);
if (entry_ptr != 0) {
@@ -384,20 +389,41 @@ NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx NCURSES_CONST char *id, char **area)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(char *)
-tgetstr(NCURSES_CONST char *id, char **area)
+tgetstr(const char *id, char **area)
{
return NCURSES_SP_NAME(tgetstr) (CURRENT_SCREEN, id, area);
}
#endif
#if NO_LEAKS
+#undef CacheInx
+#define CacheInx num
+NCURSES_EXPORT(void)
+_nc_tgetent_leak(TERMINAL *termp)
+{
+ if (termp != 0) {
+ int num;
+ for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
+ if (LAST_TRM == termp) {
+ FreeAndNull(FIX_SGR0);
+ if (LAST_TRM != 0) {
+ LAST_TRM = 0;
+ }
+ break;
+ }
+ }
+ }
+}
+
NCURSES_EXPORT(void)
_nc_tgetent_leaks(void)
{
+ int num;
for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
- FreeIfNeeded(FIX_SGR0);
- if (LAST_TRM != 0)
+ if (LAST_TRM != 0) {
del_curterm(LAST_TRM);
+ _nc_tgetent_leak(LAST_TRM);
+ }
}
}
#endif
diff --git a/ncurses/tinfo/lib_termname.c b/ncurses/tinfo/lib_termname.c
index e3f6827..2d80bb3 100644
--- a/ncurses/tinfo/lib_termname.c
+++ b/ncurses/tinfo/lib_termname.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2003,2009 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 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,7 +29,7 @@
#include <curses.priv.h>
-MODULE_ID("$Id: lib_termname.c,v 1.12 2009/10/24 21:56:58 tom Exp $")
+MODULE_ID("$Id: lib_termname.c,v 1.13 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(char *)
NCURSES_SP_NAME(termname) (NCURSES_SP_DCL0)
diff --git a/ncurses/tinfo/lib_tgoto.c b/ncurses/tinfo/lib_tgoto.c
index 31daf44..8e24085 100644
--- a/ncurses/tinfo/lib_tgoto.c
+++ b/ncurses/tinfo/lib_tgoto.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2000-2008,2012 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 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 +36,7 @@
#include <ctype.h>
#include <termcap.h>
-MODULE_ID("$Id: lib_tgoto.c,v 1.16 2012/02/24 02:08:08 tom Exp $")
+MODULE_ID("$Id: lib_tgoto.c,v 1.19 2020/02/02 23:34:34 tom Exp $")
#if !PURE_TERMINFO
static bool
@@ -125,7 +126,14 @@ tgoto_internal(const char *string, int x, int y)
*value += 1;
need_BC = TRUE;
} else {
- *value = 0200; /* tputs will treat this as \0 */
+ /* tputs will pretend this is \0, which will almost
+ * always work since ANSI-compatible terminals ignore
+ * the character. ECMA-48 does not document a C1
+ * control for this value. A few (obsolete) terminals
+ * can use this value in special cases, such as cursor
+ * addressing using single-byte coordinates.
+ */
+ *value = 0200;
}
}
result[used++] = (char) *value++;
@@ -199,6 +207,6 @@ tgoto(const char *string, int x, int y)
result = tgoto_internal(string, x, y);
else
#endif
- result = TPARM_2((NCURSES_CONST char *) string, y, x);
+ result = TPARM_2(string, y, x);
returnPtr(result);
}
diff --git a/ncurses/tinfo/lib_ti.c b/ncurses/tinfo/lib_ti.c
index e9ae746..5cb77b8 100644
--- a/ncurses/tinfo/lib_ti.c
+++ b/ncurses/tinfo/lib_ti.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2010,2013 Free Software Foundation, Inc. *
+ * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 +37,7 @@
#include <tic.h>
-MODULE_ID("$Id: lib_ti.c,v 1.30 2013/06/08 16:55:05 tom Exp $")
+MODULE_ID("$Id: lib_ti.c,v 1.34 2020/02/02 23:34:34 tom Exp $")
#if 0
static bool
@@ -50,16 +51,16 @@ same_name(const char *a, const char *b)
#endif
NCURSES_EXPORT(int)
-NCURSES_SP_NAME(tigetflag) (NCURSES_SP_DCLx NCURSES_CONST char *str)
+NCURSES_SP_NAME(tigetflag) (NCURSES_SP_DCLx 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);
+ TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
struct name_table_entry const *entry_ptr;
+ int j = -1;
entry_ptr = _nc_find_type_entry(str, BOOLEAN, FALSE);
if (entry_ptr != 0) {
@@ -88,23 +89,23 @@ NCURSES_SP_NAME(tigetflag) (NCURSES_SP_DCLx NCURSES_CONST char *str)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(int)
-tigetflag(NCURSES_CONST char *str)
+tigetflag(const char *str)
{
return NCURSES_SP_NAME(tigetflag) (CURRENT_SCREEN, str);
}
#endif
NCURSES_EXPORT(int)
-NCURSES_SP_NAME(tigetnum) (NCURSES_SP_DCLx NCURSES_CONST char *str)
+NCURSES_SP_NAME(tigetnum) (NCURSES_SP_DCLx const char *str)
{
- int j = -1;
int result = CANCELLED_NUMERIC; /* Solaris returns a -1 on error */
T((T_CALLED("tigetnum(%p, %s)"), (void *) SP_PARM, str));
if (HasTInfoTerminal(SP_PARM)) {
- TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+ TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
struct name_table_entry const *entry_ptr;
+ int j = -1;
entry_ptr = _nc_find_type_entry(str, NUMBER, FALSE);
if (entry_ptr != 0) {
@@ -135,23 +136,23 @@ NCURSES_SP_NAME(tigetnum) (NCURSES_SP_DCLx NCURSES_CONST char *str)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(int)
-tigetnum(NCURSES_CONST char *str)
+tigetnum(const char *str)
{
return NCURSES_SP_NAME(tigetnum) (CURRENT_SCREEN, str);
}
#endif
NCURSES_EXPORT(char *)
-NCURSES_SP_NAME(tigetstr) (NCURSES_SP_DCLx NCURSES_CONST char *str)
+NCURSES_SP_NAME(tigetstr) (NCURSES_SP_DCLx const char *str)
{
char *result = CANCELLED_STRING;
- int j = -1;
T((T_CALLED("tigetstr(%p, %s)"), (void *) SP_PARM, str));
if (HasTInfoTerminal(SP_PARM)) {
- TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
+ TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
struct name_table_entry const *entry_ptr;
+ int j = -1;
entry_ptr = _nc_find_type_entry(str, STRING, FALSE);
if (entry_ptr != 0) {
@@ -180,7 +181,7 @@ NCURSES_SP_NAME(tigetstr) (NCURSES_SP_DCLx NCURSES_CONST char *str)
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(char *)
-tigetstr(NCURSES_CONST char *str)
+tigetstr(const char *str)
{
return NCURSES_SP_NAME(tigetstr) (CURRENT_SCREEN, str);
}
diff --git a/ncurses/tinfo/lib_tparm.c b/ncurses/tinfo/lib_tparm.c
index 44a2061..400cd31 100644
--- a/ncurses/tinfo/lib_tparm.c
+++ b/ncurses/tinfo/lib_tparm.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -42,7 +43,7 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$Id: lib_tparm.c,v 1.93 2014/10/11 03:04:31 tom Exp $")
+MODULE_ID("$Id: lib_tparm.c,v 1.108 2020/02/02 23:34:34 tom Exp $")
/*
* char *
@@ -326,6 +327,7 @@ parse_format(const char *s, char *format, int *len)
#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
+#define tc_BUMP() if (level < 0 && number < 2) number++
/*
* Analyze the string to see how many parameters we need from the varargs list,
@@ -346,14 +348,15 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
int lastpop = -1;
int len;
int number = 0;
+ int level = -1;
const char *cp = string;
static char dummy[] = "";
if (cp == 0)
return 0;
- if ((len2 = strlen(cp)) > TPS(fmt_size)) {
- TPS(fmt_size) = len2 + TPS(fmt_size) + 2;
+ if ((len2 = strlen(cp)) + 2 > TPS(fmt_size)) {
+ TPS(fmt_size) += len2 + 2;
TPS(fmt_buff) = typeRealloc(char, TPS(fmt_size), TPS(fmt_buff));
if (TPS(fmt_buff) == 0)
return 0;
@@ -378,22 +381,27 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
#ifdef EXP_XTERM_1005
case 'u':
#endif
- if (lastpop <= 0)
- number++;
+ if (lastpop <= 0) {
+ tc_BUMP();
+ }
+ level -= 1;
lastpop = -1;
break;
case 'l':
case 's':
- if (lastpop > 0)
+ if (lastpop > 0) {
+ level -= 1;
p_is_s[lastpop - 1] = dummy;
- ++number;
+ }
+ tc_BUMP();
break;
case 'p':
cp++;
i = (UChar(*cp) - '0');
if (i >= 0 && i <= NUM_PARM) {
+ ++level;
lastpop = i;
if (lastpop > *popcount)
*popcount = lastpop;
@@ -401,20 +409,22 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
break;
case 'P':
- ++number;
++cp;
break;
case 'g':
+ ++level;
cp++;
break;
case S_QUOTE:
+ ++level;
cp += 2;
lastpop = -1;
break;
case L_BRACE:
+ ++level;
cp++;
while (isdigit(UChar(*cp))) {
cp++;
@@ -434,14 +444,15 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
case '=':
case '<':
case '>':
+ tc_BUMP();
+ level -= 1; /* pop 2, operate, push 1 */
lastpop = -1;
- number += 2;
break;
case '!':
case '~':
+ tc_BUMP();
lastpop = -1;
- ++number;
break;
case 'i':
@@ -475,8 +486,10 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
bool termcap_hack;
bool incremented_two;
- if (cp == NULL)
+ if (cp == NULL) {
+ TR(TRACE_CALLS, ("%s: format is null", TPS(tname)));
return NULL;
+ }
TPS(out_used) = 0;
len2 = strlen(cp);
@@ -487,8 +500,10 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
* variable-length argument list.
*/
number = _nc_tparm_analyze(cp, p_is_s, &popcount);
- if (TPS(fmt_buff) == 0)
+ if (TPS(fmt_buff) == 0) {
+ TR(TRACE_CALLS, ("%s: error in analysis", TPS(tname)));
return NULL;
+ }
incremented_two = FALSE;
@@ -527,7 +542,6 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
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]);
@@ -538,10 +552,16 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
#ifdef TRACE
if (USE_TRACEF(TRACE_CALLS)) {
for (i = 0; i < num_args; i++) {
- if (p_is_s[i] != 0)
+ if (p_is_s[i] != 0) {
save_text(", %s", _nc_visbuf(p_is_s[i]), 0);
- else
+ } else if ((long) param[i] > MAX_OF_TYPE(NCURSES_INT2) ||
+ (long) param[i] < 0) {
+ _tracef("BUG: problem with tparm parameter #%d of %d",
+ i + 1, num_args);
+ break;
+ } else {
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;
@@ -672,11 +692,15 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
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 '&':
@@ -817,7 +841,7 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
#endif
NCURSES_EXPORT(char *)
-tparm_varargs(NCURSES_CONST char *string,...)
+tparm_varargs(const char *string, ...)
{
va_list ap;
char *result;
@@ -834,7 +858,7 @@ tparm_varargs(NCURSES_CONST char *string,...)
#if !NCURSES_TPARM_VARARGS
NCURSES_EXPORT(char *)
-tparm_proto(NCURSES_CONST char *string,
+tparm_proto(const char *string,
TPARM_ARG a1,
TPARM_ARG a2,
TPARM_ARG a3,
@@ -850,7 +874,7 @@ tparm_proto(NCURSES_CONST char *string,
#endif /* NCURSES_TPARM_VARARGS */
NCURSES_EXPORT(char *)
-tiparm(const char *string,...)
+tiparm(const char *string, ...)
{
va_list ap;
char *result;
diff --git a/ncurses/tinfo/lib_tputs.c b/ncurses/tinfo/lib_tputs.c
index 09cbbc2..bfde26e 100644
--- a/ncurses/tinfo/lib_tputs.c
+++ b/ncurses/tinfo/lib_tputs.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2015 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -51,7 +52,7 @@
#include <termcap.h> /* ospeed */
#include <tic.h>
-MODULE_ID("$Id: lib_tputs.c,v 1.96 2015/01/03 23:51:23 tom Exp $")
+MODULE_ID("$Id: lib_tputs.c,v 1.103 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT_VAR(char) PC = 0; /* used by termcap library */
NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed = 0; /* used by termcap library */
@@ -123,11 +124,11 @@ NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_DCL0)
if (SP_PARM->out_inuse) {
char *buf = SP_PARM->out_buffer;
size_t amount = SP->out_inuse;
- ssize_t res;
SP->out_inuse = 0;
+ TR(TRACE_CHARPUT, ("flushing %ld bytes", (unsigned long) amount));
while (amount) {
- res = write(SP_PARM->_ofd, buf, amount);
+ ssize_t res = write(SP_PARM->_ofd, buf, amount);
if (res > 0) {
/* if the write was incomplete, try again */
@@ -142,6 +143,8 @@ NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_DCL0)
}
}
}
+ } else {
+ fflush(stdout);
}
}
@@ -271,13 +274,16 @@ NCURSES_SP_NAME(tputs) (NCURSES_SP_DCLx
#endif /* BSD_TPUTS */
#ifdef TRACE
- char addrbuf[32];
-
if (USE_TRACEF(TRACE_TPUTS)) {
- if (outc == NCURSES_SP_NAME(_nc_outch))
+ char addrbuf[32];
+ TR_FUNC_BFR(1);
+
+ if (outc == NCURSES_SP_NAME(_nc_outch)) {
_nc_STRCPY(addrbuf, "_nc_outch", sizeof(addrbuf));
- else
- _nc_SPRINTF(addrbuf, _nc_SLIMIT(sizeof(addrbuf)) "%p", outc);
+ } else {
+ _nc_SPRINTF(addrbuf, _nc_SLIMIT(sizeof(addrbuf)) "%s",
+ TR_FUNC_ARG(0, outc));
+ }
if (_nc_tputs_trace) {
_tracef("tputs(%s = %s, %d, %s) called", _nc_tputs_trace,
_nc_visbuf(string), affcnt, addrbuf);
@@ -425,7 +431,7 @@ NCURSES_EXPORT(int)
_nc_outc_wrapper(SCREEN *sp, int c)
{
if (0 == sp) {
- return (ERR);
+ return fputc(c, stdout);
} else {
return sp->jump(c);
}
diff --git a/ncurses/tinfo/lib_ttyflags.c b/ncurses/tinfo/lib_ttyflags.c
index 43bed35..bfcd64a 100644
--- a/ncurses/tinfo/lib_ttyflags.c
+++ b/ncurses/tinfo/lib_ttyflags.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2014 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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,42 +42,42 @@
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_ttyflags.c,v 1.30 2014/04/26 18:47:20 juergen Exp $")
+MODULE_ID("$Id: lib_ttyflags.c,v 1.34 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(int)
NCURSES_SP_NAME(_nc_get_tty_mode) (NCURSES_SP_DCLx TTY * buf)
{
+ TERMINAL *termp = TerminalOf(SP_PARM);
int result = OK;
- if (buf == 0 || SP_PARM == 0) {
+ if (buf == 0 || termp == 0) {
result = ERR;
} else {
- TERMINAL *termp = TerminalOf(SP_PARM);
- if (0 == termp) {
- result = ERR;
- } else {
#ifdef USE_TERM_DRIVER
+ if (SP_PARM != 0) {
result = CallDriver_2(SP_PARM, td_sgmode, FALSE, buf);
+ } else {
+ result = ERR;
+ }
#else
- for (;;) {
- if (GET_TTY(termp->Filedes, buf) != 0) {
- if (errno == EINTR)
- continue;
- result = ERR;
- }
- break;
+ for (;;) {
+ if (GET_TTY(termp->Filedes, buf) != 0) {
+ if (errno == EINTR)
+ continue;
+ result = ERR;
}
-#endif
+ break;
}
-
- if (result == ERR)
- memset(buf, 0, sizeof(*buf));
+#endif
TR(TRACE_BITS, ("_nc_get_tty_mode(%d): %s",
termp ? termp->Filedes : -1,
_nc_trace_ttymode(buf)));
}
+ if (result == ERR && buf != 0)
+ memset(buf, 0, sizeof(*buf));
+
return (result);
}
@@ -141,7 +142,8 @@ NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_DCL0)
int rc = ERR;
TERMINAL *termp = TerminalOf(SP_PARM);
- T((T_CALLED("def_shell_mode(%p)"), (void *) SP_PARM));
+ T((T_CALLED("def_shell_mode(%p) ->term %p"),
+ (void *) SP_PARM, (void *) termp));
if (termp != 0) {
#ifdef USE_TERM_DRIVER
@@ -179,7 +181,7 @@ NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_DCL0)
int rc = ERR;
TERMINAL *termp = TerminalOf(SP_PARM);
- T((T_CALLED("def_prog_mode(%p)"), (void *) SP_PARM));
+ T((T_CALLED("def_prog_mode(%p) ->term %p"), (void *) SP_PARM, (void *) termp));
if (termp != 0) {
#ifdef USE_TERM_DRIVER
@@ -215,7 +217,7 @@ 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));
+ T((T_CALLED("reset_prog_mode(%p) ->term %p"), (void *) SP_PARM, (void *) termp));
if (termp != 0) {
#ifdef USE_TERM_DRIVER
@@ -247,7 +249,8 @@ 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));
+ T((T_CALLED("reset_shell_mode(%p) ->term %p"),
+ (void *) SP_PARM, (void *) termp));
if (termp != 0) {
#ifdef USE_TERM_DRIVER
diff --git a/ncurses/tinfo/make_hash.c b/ncurses/tinfo/make_hash.c
index 37ac765..9980279 100644
--- a/ncurses/tinfo/make_hash.c
+++ b/ncurses/tinfo/make_hash.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 2009-2013,2017 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 *
@@ -34,7 +35,6 @@
/*
* make_hash.c --- build-time program for constructing comp_captab.c
- *
*/
#include <build.priv.h>
@@ -44,14 +44,14 @@
#include <ctype.h>
-MODULE_ID("$Id: make_hash.c,v 1.13 2013/09/28 20:55:47 tom Exp $")
+MODULE_ID("$Id: make_hash.c,v 1.33 2020/02/02 23:34:34 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[].
+ * by name. There are CAPTABSIZE entries in the predefined table[]
+ * and HASHTABSIZE slots in hash_table[].
*
*/
@@ -59,6 +59,14 @@ MODULE_ID("$Id: make_hash.c,v 1.13 2013/09/28 20:55:47 tom Exp $")
#define MODULE_ID(id) /*nothing */
#include <tinfo/doalloc.c>
+#define L_PAREN "("
+#define R_PAREN ")"
+#define L_BRACE "{"
+#define R_BRACE "}"
+
+static const char *typenames[] =
+{"BOOLEAN", "NUMBER", "STRING"};
+
static void
failed(const char *s)
{
@@ -82,7 +90,7 @@ strmalloc(char *s)
*
* Computes the hashing function on the given string.
*
- * The current hash function is the sum of each consectutive pair
+ * The current hash function is the sum of each consecutive pair
* of characters, taken as two-byte integers, mod HASHTABSIZE.
*
*/
@@ -93,36 +101,40 @@ hash_function(const char *string)
long sum = 0;
while (*string) {
- sum += (long) (*string + (*(string + 1) << 8));
+ sum += (long) (UChar(*string) + (UChar(*(string + 1)) << 8));
string++;
}
return (int) (sum % HASHTABSIZE);
}
+#define UNUSED -1
+
static void
-_nc_make_hash_table(struct name_table_entry *table,
- HashValue * hash_table)
+_nc_make_hash_table(struct user_table_entry *table,
+ HashValue * hash_table,
+ unsigned tablesize)
{
- short i;
+ unsigned i;
int hashvalue;
int collisions = 0;
for (i = 0; i < HASHTABSIZE; i++) {
- hash_table[i] = -1;
+ hash_table[i] = UNUSED;
}
- for (i = 0; i < CAPTABSIZE; i++) {
- hashvalue = hash_function(table[i].nte_name);
+ for (i = 0; i < tablesize; i++) {
+ hashvalue = hash_function(table[i].ute_name);
if (hash_table[hashvalue] >= 0)
collisions++;
- if (hash_table[hashvalue] != 0)
- table[i].nte_link = hash_table[hashvalue];
- hash_table[hashvalue] = i;
+ if (hash_table[hashvalue] != UNUSED) {
+ table[i].ute_link = hash_table[hashvalue];
+ }
+ hash_table[hashvalue] = (HashValue) i;
}
- printf("/* %d collisions out of %d entries */\n", collisions, CAPTABSIZE);
+ printf("/* %d collisions out of %d entries */\n", collisions, tablesize);
}
/*
@@ -156,10 +168,18 @@ parse_columns(char *buffer)
int col = 0;
- if (list == 0 && (list = typeCalloc(char *, (MAX_COLUMNS + 1))) == 0)
- return (0);
+ if (buffer == 0) {
+ free(list);
+ list = 0;
+ return 0;
+ }
if (*buffer != '#') {
+ if (list == 0) {
+ list = typeCalloc(char *, (MAX_COLUMNS + 1));
+ if (list == 0)
+ return (0);
+ }
while (*buffer != '\0') {
char *s;
for (s = buffer; (*s != '\0') && !isspace(UChar(*s)); s++)
@@ -188,21 +208,58 @@ parse_columns(char *buffer)
return col ? list : 0;
}
+#define SetType(n,t) \
+ if (is_user) \
+ name_table[n].ute_type |= (int)(1 << (t)); \
+ else \
+ name_table[n].ute_type = (t)
+
+#define GetType(n) \
+ (is_user \
+ ? get_type(name_table[n].ute_type) \
+ : typenames[name_table[n].ute_type])
+
+static char *
+get_type(int type_mask)
+{
+ static char result[80];
+ unsigned n;
+ _nc_STRCPY(result, L_PAREN, sizeof(result));
+ for (n = 0; n < 3; ++n) {
+ if ((1 << n) & type_mask) {
+ size_t want = 5 + strlen(typenames[n]);
+ if (want > sizeof(result)) {
+ fprintf(stderr, "Buffer is not large enough for %s + %s\n",
+ result, typenames[n]);
+ exit(EXIT_FAILURE);
+ }
+ if (result[1])
+ _nc_STRCAT(result, "|", sizeof(result));
+ _nc_STRCAT(result, "1<<", sizeof(result));
+ _nc_STRCAT(result, typenames[n], sizeof(result));
+ }
+ }
+ _nc_STRCAT(result, R_PAREN, sizeof(result));
+ return result;
+}
+
int
main(int argc, char **argv)
{
- struct name_table_entry *name_table = typeCalloc(struct
- name_table_entry, CAPTABSIZE);
+ unsigned tablesize = CAPTABSIZE;
+ struct user_table_entry *name_table = typeCalloc(struct
+ user_table_entry, tablesize);
HashValue *hash_table = typeCalloc(HashValue, HASHTABSIZE);
const char *root_name = "";
int column = 0;
int bigstring = 0;
- int n;
+ unsigned n;
+ unsigned nn;
+ unsigned tableused = 0;
+ bool is_user;
+ const char *table_name;
char buffer[BUFSIZ];
- static const char *typenames[] =
- {"BOOLEAN", "NUMBER", "STRING"};
-
short BoolCount = 0;
short NumCount = 0;
short StrCount = 0;
@@ -220,42 +277,80 @@ main(int argc, char **argv)
fprintf(stderr, "usage: make_hash column root_name bigstring\n");
exit(EXIT_FAILURE);
}
+ is_user = (*root_name == 'u');
+ table_name = (is_user ? "user" : "name");
/*
* Read the table into our arrays.
*/
- for (n = 0; (n < CAPTABSIZE) && fgets(buffer, BUFSIZ, stdin);) {
- char **list, *nlp = strchr(buffer, '\n');
+ for (n = 0; (n < tablesize) && fgets(buffer, BUFSIZ, stdin);) {
+ char **list;
+ char *nlp = strchr(buffer, '\n');
if (nlp)
*nlp = '\0';
+ else
+ buffer[sizeof(buffer) - 2] = '\0';
list = parse_columns(buffer);
if (list == 0) /* blank or comment */
continue;
- if (column > count_columns(list)) {
+ if (is_user) {
+ if (strcmp(list[0], "userdef"))
+ continue;
+ } else if (!strcmp(list[0], "userdef")) {
+ continue;
+ }
+ if (column < 0 || 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]);
+ nn = tableused;
+ if (is_user) {
+ unsigned j;
+ for (j = 0; j < tableused; ++j) {
+ if (!strcmp(list[column], name_table[j].ute_name)) {
+ nn = j;
+ break;
+ }
+ }
+ }
+ if (nn == tableused) {
+ name_table[nn].ute_link = -1; /* end-of-hash */
+ name_table[nn].ute_name = strmalloc(list[column]);
+ ++tableused;
+ }
+
if (!strcmp(list[2], "bool")) {
- name_table[n].nte_type = BOOLEAN;
- name_table[n].nte_index = BoolCount++;
+ SetType(nn, BOOLEAN);
+ name_table[nn].ute_index = BoolCount++;
} else if (!strcmp(list[2], "num")) {
- name_table[n].nte_type = NUMBER;
- name_table[n].nte_index = NumCount++;
+ SetType(nn, NUMBER);
+ name_table[nn].ute_index = NumCount++;
} else if (!strcmp(list[2], "str")) {
- name_table[n].nte_type = STRING;
- name_table[n].nte_index = StrCount++;
+ SetType(nn, STRING);
+ name_table[nn].ute_index = StrCount++;
+ if (is_user) {
+ if (*list[3] != '-') {
+ unsigned j;
+ name_table[nn].ute_argc = (unsigned) strlen(list[3]);
+ for (j = 0; j < name_table[nn].ute_argc; ++j) {
+ if (list[3][j] == 's') {
+ name_table[nn].ute_args |= (1U << j);
+ }
+ }
+ }
+ }
} else {
fprintf(stderr, "Unknown type: %s\n", list[2]);
exit(EXIT_FAILURE);
}
n++;
}
- _nc_make_hash_table(name_table, hash_table);
+ if (tablesize > tableused)
+ tablesize = tableused;
+ _nc_make_hash_table(name_table, hash_table, tablesize);
/*
* Write the compiled tables to standard output
@@ -265,66 +360,86 @@ main(int argc, char **argv)
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;
+ for (n = 0; n < tablesize; n++) {
+ nxt = (int) strlen(name_table[n].ute_name) + 5;
if (nxt + len > 72) {
printf("\\\n");
len = 0;
}
- printf("\"%s\\0\" ", name_table[n].nte_name);
+ printf("\"%s\\0\" ", name_table[n].ute_name);
len += nxt;
}
printf(";\n\n");
len = 0;
- printf("static name_table_data const %s_names_data[] =\n",
+ printf("static %s_table_data const %s_names_data[] =\n",
+ table_name,
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("%s\n", L_BRACE);
+ for (n = 0; n < tablesize; n++) {
+ printf("\t%s %15d,\t%10s,", L_BRACE, len, GetType(n));
+ if (is_user)
+ printf("\t%d,%d,",
+ name_table[n].ute_argc,
+ name_table[n].ute_args);
+ printf("\t%3d, %3d %s%c\n",
+ name_table[n].ute_index,
+ name_table[n].ute_link,
+ R_BRACE,
+ n < tablesize - 1 ? ',' : ' ');
+ len += (int) strlen(name_table[n].ute_name) + 1;
}
- printf("};\n\n");
- printf("static struct name_table_entry *_nc_%s_table = 0;\n\n", root_name);
+ printf("%s;\n\n", R_BRACE);
+ printf("static struct %s_table_entry *_nc_%s_table = 0;\n\n",
+ table_name,
+ root_name);
} else {
- printf("static struct name_table_entry const _nc_%s_table[] =\n",
+ printf("static struct %s_table_entry const _nc_%s_table[] =\n",
+ table_name,
root_name);
- printf("{\n");
- for (n = 0; n < CAPTABSIZE; n++) {
+ printf("%s\n", L_BRACE);
+ for (n = 0; n < tablesize; 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 ? ',' : ' ');
+ name_table[n].ute_name);
+ printf("\t%s %15s,\t%10s,", L_BRACE, buffer, GetType(n));
+ if (is_user)
+ printf("\t%d,%d,",
+ name_table[n].ute_argc,
+ name_table[n].ute_args);
+ printf("\t%3d, %3d %s%c\n",
+ name_table[n].ute_index,
+ name_table[n].ute_link,
+ R_BRACE,
+ n < tablesize - 1 ? ',' : ' ');
}
- printf("};\n\n");
+ printf("%s;\n\n", R_BRACE);
}
printf("static const HashValue _nc_%s_hash_table[%d] =\n",
root_name,
HASHTABSIZE + 1);
- printf("{\n");
+ printf("%s\n", L_BRACE);
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");
+ printf("%s;\n\n", R_BRACE);
+
+ if (!is_user) {
+ 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);
+ for (n = 0; (n < tablesize); ++n) {
+ free((void *) name_table[n].ute_name);
+ }
+ free(name_table);
+ parse_columns(0);
+
return EXIT_SUCCESS;
}
diff --git a/ncurses/tinfo/make_keys.c b/ncurses/tinfo/make_keys.c
index f44f7c7..80bbf63 100644
--- a/ncurses/tinfo/make_keys.c
+++ b/ncurses/tinfo/make_keys.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 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 *
@@ -39,11 +40,26 @@
#define USE_TERMLIB 1
#include <build.priv.h>
-MODULE_ID("$Id: make_keys.c,v 1.20 2011/10/22 16:34:50 tom Exp $")
+MODULE_ID("$Id: make_keys.c,v 1.22 2020/02/02 23:34:34 tom Exp $")
#include <names.c>
-#define UNKNOWN (unsigned) (SIZEOF(strnames) + SIZEOF(strfnames))
+static unsigned
+unknown(void)
+{
+ static unsigned result = 0;
+
+ 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)
@@ -64,7 +80,7 @@ lookup(const char *name)
}
}
}
- return found ? n : UNKNOWN;
+ return found ? n : unknown();
}
static void
@@ -73,6 +89,7 @@ make_keys(FILE *ifp, FILE *ofp)
char buffer[BUFSIZ];
char from[256];
char to[256];
+ unsigned ignore = unknown();
unsigned maxlen = 16;
int scanned;
@@ -86,7 +103,7 @@ make_keys(FILE *ifp, FILE *ofp)
scanned = sscanf(buffer, "%255s %255s", to, from);
if (scanned == 2) {
unsigned code = lookup(from);
- if (code == UNKNOWN)
+ if (code == ignore)
continue;
if (strlen(from) > maxlen)
maxlen = (unsigned) strlen(from);
diff --git a/ncurses/tinfo/name_match.c b/ncurses/tinfo/name_match.c
index c648535..71e584d 100644
--- a/ncurses/tinfo/name_match.c
+++ b/ncurses/tinfo/name_match.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1999-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 1998-2013,2016 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,7 +34,7 @@
#include <curses.priv.h>
#include <tic.h>
-MODULE_ID("$Id: name_match.c,v 1.23 2013/05/25 20:20:08 tom Exp $")
+MODULE_ID("$Id: name_match.c,v 1.25 2020/02/02 23:34:34 tom Exp $")
#define FirstName _nc_globals.first_name
@@ -58,8 +59,6 @@ skip_index(const char *name)
NCURSES_EXPORT(char *)
_nc_first_name(const char *const sp)
{
- unsigned n;
-
#if NO_LEAKS
if (sp == 0) {
if (FirstName != 0) {
@@ -72,6 +71,7 @@ _nc_first_name(const char *const sp)
FirstName = typeMalloc(char, MAX_NAME_SIZE + 1);
if (FirstName != 0) {
+ unsigned n;
const char *src = sp;
#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
src = skip_index(sp);
@@ -93,11 +93,13 @@ _nc_first_name(const char *const sp)
NCURSES_EXPORT(int)
_nc_name_match(const char *const namelst, const char *const name, const char *const delim)
{
- const char *s, *d, *t;
- int code, found;
+ const char *s;
if ((s = namelst) != 0) {
while (*s != '\0') {
+ const char *d, *t;
+ int code, found;
+
for (d = name; *d != '\0'; d++) {
if (*s != *d)
break;
diff --git a/ncurses/tinfo/obsolete.c b/ncurses/tinfo/obsolete.c
index 63476dc..972a9a1 100644
--- a/ncurses/tinfo/obsolete.c
+++ b/ncurses/tinfo/obsolete.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2013-2014,2016 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,10 +37,10 @@
#include <curses.priv.h>
-MODULE_ID("$Id: obsolete.c,v 1.3 2014/10/11 02:39:35 tom Exp $")
+MODULE_ID("$Id: obsolete.c,v 1.6 2020/02/02 23:34:34 tom Exp $")
/*
- * Obsolete entrypoint retained for binary compatbility.
+ * Obsolete entrypoint retained for binary compatibility.
*/
NCURSES_EXPORT(void)
NCURSES_SP_NAME(_nc_set_buffer) (NCURSES_SP_DCLx FILE *ofp, int buffered)
@@ -68,7 +69,7 @@ _nc_strdup(const char *s)
size_t need = strlen(s);
result = malloc(need + 1);
if (result != 0) {
- strcpy(result, s);
+ _nc_STRCPY(result, s, need);
}
}
return result;
diff --git a/ncurses/tinfo/parse_entry.c b/ncurses/tinfo/parse_entry.c
index 2936a64..23574b6 100644
--- a/ncurses/tinfo/parse_entry.c
+++ b/ncurses/tinfo/parse_entry.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -47,7 +48,7 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$Id: parse_entry.c,v 1.79 2012/10/27 21:43:45 tom Exp $")
+MODULE_ID("$Id: parse_entry.c,v 1.99 2020/02/02 23:34:34 tom Exp $")
#ifdef LINT
static short const parametrized[] =
@@ -56,17 +57,17 @@ static short const parametrized[] =
#include <parametrized.h>
#endif
-static void postprocess_termcap(TERMTYPE *, bool);
-static void postprocess_terminfo(TERMTYPE *);
+static void postprocess_termcap(TERMTYPE2 *, bool);
+static void postprocess_terminfo(TERMTYPE2 *);
static struct name_table_entry const *lookup_fullname(const char *name);
#if NCURSES_XNAMES
static struct name_table_entry const *
-_nc_extend_names(ENTRY * entryp, char *name, int token_type)
+_nc_extend_names(ENTRY * entryp, const char *name, int token_type)
{
static struct name_table_entry temp;
- TERMTYPE *tp = &(entryp->tterm);
+ TERMTYPE2 *tp = &(entryp->tterm);
unsigned offset = 0;
unsigned actual;
unsigned tindex;
@@ -152,7 +153,7 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
case NUMBER:
tp->ext_Numbers++;
tp->num_Numbers++;
- TYPE_REALLOC(short, tp->num_Numbers, tp->Numbers);
+ TYPE_REALLOC(NCURSES_INT2, tp->num_Numbers, tp->Numbers);
for_each_value(tp->num_Numbers)
tp->Numbers[last] = tp->Numbers[last - 1];
break;
@@ -178,8 +179,55 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
return &temp;
}
+
+static const char *
+usertype2s(int mask)
+{
+ const char *result = "unknown";
+ if (mask & (1 << BOOLEAN)) {
+ result = "boolean";
+ } else if (mask & (1 << NUMBER)) {
+ result = "number";
+ } else if (mask & (1 << STRING)) {
+ result = "string";
+ }
+ return result;
+}
+
+static bool
+expected_type(const char *name, int token_type, bool silent)
+{
+ struct user_table_entry const *entry = _nc_find_user_entry(name);
+ bool result = TRUE;
+ if ((entry != 0) && (token_type != CANCEL)) {
+ int have_type = (1 << token_type);
+ if (!(entry->ute_type & have_type)) {
+ if (!silent)
+ _nc_warning("expected %s-type for %s, have %s",
+ usertype2s(entry->ute_type),
+ name,
+ usertype2s(have_type));
+ result = FALSE;
+ }
+ }
+ return result;
+}
#endif /* NCURSES_XNAMES */
+static bool
+valid_entryname(const char *name)
+{
+ bool result = TRUE;
+ int ch;
+ while ((ch = UChar(*name++)) != '\0') {
+ if (ch <= ' ' || ch > '~' || ch == '/') {
+ result = FALSE;
+ break;
+ }
+ }
+ return result;
+}
+
/*
* int
* _nc_parse_entry(entry, literal, silent)
@@ -203,14 +251,15 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
{ bad_tc_usage = TRUE; \
_nc_warning("Legacy termcap allows only a trailing tc= clause"); }
-#define MAX_NUMBER 0x7fff /* positive shorts only */
+#define MAX_NUMBER MAX_OF_TYPE(NCURSES_INT2)
NCURSES_EXPORT(int)
-_nc_parse_entry(struct entry *entryp, int literal, bool silent)
+_nc_parse_entry(ENTRY * entryp, int literal, bool silent)
{
int token_type;
struct name_table_entry const *entry_ptr;
char *ptr, *base;
+ const char *name;
bool bad_tc_usage = FALSE;
token_type = _nc_get_token(silent);
@@ -220,7 +269,7 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
if (token_type != NAMES)
_nc_err_abort("Entry does not start with terminal names in column one");
- _nc_init_entry(&entryp->tterm);
+ _nc_init_entry(entryp);
entryp->cstart = _nc_comment_start;
entryp->cend = _nc_comment_end;
@@ -236,13 +285,14 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
* implemented it. Note that the resulting terminal type was never the
* 2-character name, but was instead the first alias after that.
*/
+#define ok_TC2(s) (isgraph(UChar(s)) && (s) != '|')
ptr = _nc_curr_token.tk_name;
if (_nc_syntax == SYN_TERMCAP
#if NCURSES_XNAMES
&& !_nc_user_definable
#endif
) {
- if (ptr[2] == '|') {
+ if (ok_TC2(ptr[0]) && ok_TC2(ptr[1]) && (ptr[2] == '|')) {
ptr += 3;
_nc_curr_token.tk_name[2] = '\0';
}
@@ -260,7 +310,12 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
* results in the terminal type getting prematurely set to correspond
* to that of the next entry.
*/
- _nc_set_type(_nc_first_name(entryp->tterm.term_names));
+ name = _nc_first_name(entryp->tterm.term_names);
+ if (!valid_entryname(name)) {
+ _nc_warning("invalid entry name \"%s\"", name);
+ name = "invalid";
+ }
+ _nc_set_type(name);
/* check for overly-long names and aliases */
for (base = entryp->tterm.term_names; (ptr = strchr(base, '|')) != 0;
@@ -282,6 +337,19 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
bool is_use = (strcmp(_nc_curr_token.tk_name, "use") == 0);
bool is_tc = !is_use && (strcmp(_nc_curr_token.tk_name, "tc") == 0);
if (is_use || is_tc) {
+ if (!VALID_STRING(_nc_curr_token.tk_valstring)
+ || _nc_curr_token.tk_valstring[0] == '\0') {
+ _nc_warning("missing name for use-clause");
+ continue;
+ } else if (!valid_entryname(_nc_curr_token.tk_valstring)) {
+ _nc_warning("invalid name for use-clause \"%s\"",
+ _nc_curr_token.tk_valstring);
+ continue;
+ } else if (entryp->nuses >= MAX_USES) {
+ _nc_warning("too many use-clauses, ignored \"%s\"",
+ _nc_curr_token.tk_valstring);
+ continue;
+ }
entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring);
entryp->uses[entryp->nuses].line = _nc_curr_line;
entryp->nuses++;
@@ -351,12 +419,20 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
* define a name based on its context.
*/
if (entry_ptr == NOTFOUND
- && _nc_user_definable
- && (entry_ptr = _nc_extend_names(entryp,
- _nc_curr_token.tk_name,
- token_type)) != 0) {
- if (_nc_tracing >= DEBUG_LEVEL(1))
- _nc_warning("extended capability '%s'", _nc_curr_token.tk_name);
+ && _nc_user_definable) {
+ if (expected_type(_nc_curr_token.tk_name, token_type, silent)) {
+ if ((entry_ptr = _nc_extend_names(entryp,
+ _nc_curr_token.tk_name,
+ token_type)) != 0) {
+ if (_nc_tracing >= DEBUG_LEVEL(1)) {
+ _nc_warning("extended capability '%s'",
+ _nc_curr_token.tk_name);
+ }
+ }
+ } else {
+ /* ignore it: we have already printed error message */
+ continue;
+ }
}
#endif /* NCURSES_XNAMES */
@@ -369,7 +445,16 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
}
/* deal with bad type/value combinations. */
- if (token_type != CANCEL && entry_ptr->nte_type != token_type) {
+ if (token_type == CANCEL) {
+ /*
+ * Prefer terminfo in this (long-obsolete) ambiguity:
+ */
+ if (!strcmp("ma", _nc_curr_token.tk_name)) {
+ entry_ptr = _nc_find_type_entry("ma", NUMBER,
+ _nc_syntax != 0);
+ assert(entry_ptr != 0);
+ }
+ } else if (entry_ptr->nte_type != token_type) {
/*
* Nasty special cases here handle situations in which type
* information can resolve name clashes. Normal lookup
@@ -446,11 +531,14 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
break;
case NUMBER:
+#if !NCURSES_EXT_NUMBERS
if (_nc_curr_token.tk_valnumber > MAX_NUMBER) {
entryp->tterm.Numbers[entry_ptr->nte_index] = MAX_NUMBER;
- } else {
+ } else
+#endif
+ {
entryp->tterm.Numbers[entry_ptr->nte_index] =
- (short) _nc_curr_token.tk_valnumber;
+ (NCURSES_INT2) _nc_curr_token.tk_valnumber;
}
break;
@@ -486,23 +574,26 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
if (!literal) {
if (_nc_syntax == SYN_TERMCAP) {
bool has_base_entry = FALSE;
- unsigned i;
/*
* Don't insert defaults if this is a `+' entry meant only
* for inclusion in other entries (not sure termcap ever
* had these, actually).
*/
- if (strchr(entryp->tterm.term_names, '+'))
+ if (strchr(entryp->tterm.term_names, '+')) {
has_base_entry = TRUE;
- else
+ } else {
+ unsigned i;
/*
* Otherwise, look for a base entry that will already
* have picked up defaults via translation.
*/
- for (i = 0; i < entryp->nuses; i++)
- if (!strchr((char *) entryp->uses[i].name, '+'))
+ for (i = 0; i < entryp->nuses; i++) {
+ if (entryp->uses[i].name != 0
+ && !strchr(entryp->uses[i].name, '+'))
has_base_entry = TRUE;
+ }
+ }
postprocess_termcap(&entryp->tterm, has_base_entry);
} else
@@ -517,52 +608,59 @@ NCURSES_EXPORT(int)
_nc_capcmp(const char *s, const char *t)
/* compare two string capabilities, stripping out padding */
{
- if (!VALID_STRING(s) && !VALID_STRING(t))
- return (0);
- else if (!VALID_STRING(s) || !VALID_STRING(t))
- return (1);
-
- for (;;) {
- if (s[0] == '$' && s[1] == '<') {
- for (s += 2;; s++)
- if (!(isdigit(UChar(*s))
- || *s == '.'
- || *s == '*'
- || *s == '/'
- || *s == '>'))
- break;
- }
+ bool ok_s = VALID_STRING(s);
+ bool ok_t = VALID_STRING(t);
+
+ if (ok_s && ok_t) {
+ for (;;) {
+ if (s[0] == '$' && s[1] == '<') {
+ for (s += 2;; s++) {
+ if (!(isdigit(UChar(*s))
+ || *s == '.'
+ || *s == '*'
+ || *s == '/'
+ || *s == '>')) {
+ break;
+ }
+ }
+ }
- if (t[0] == '$' && t[1] == '<') {
- for (t += 2;; t++)
- if (!(isdigit(UChar(*t))
- || *t == '.'
- || *t == '*'
- || *t == '/'
- || *t == '>'))
- break;
- }
+ if (t[0] == '$' && t[1] == '<') {
+ for (t += 2;; t++) {
+ if (!(isdigit(UChar(*t))
+ || *t == '.'
+ || *t == '*'
+ || *t == '/'
+ || *t == '>')) {
+ break;
+ }
+ }
+ }
- /* we've now pushed s and t past any padding they were pointing at */
+ /* we've now pushed s and t past any padding they pointed at */
- if (*s == '\0' && *t == '\0')
- return (0);
+ if (*s == '\0' && *t == '\0')
+ return (0);
- if (*s != *t)
- return (*t - *s);
+ if (*s != *t)
+ return (*t - *s);
- /* else *s == *t but one is not NUL, so continue */
- s++, t++;
+ /* else *s == *t but one is not NUL, so continue */
+ s++, t++;
+ }
+ } else if (ok_s || ok_t) {
+ return 1;
}
+ return 0;
}
static void
-append_acs0(string_desc * dst, int code, int src)
+append_acs0(string_desc * dst, int code, char *src, size_t off)
{
- if (src != 0) {
+ if (src != 0 && off < strlen(src)) {
char temp[3];
temp[0] = (char) code;
- temp[1] = (char) src;
+ temp[1] = src[off];
temp[2] = 0;
_nc_safe_strcat(dst, temp);
}
@@ -571,8 +669,8 @@ append_acs0(string_desc * dst, int code, int src)
static void
append_acs(string_desc * dst, int code, char *src)
{
- if (src != 0 && strlen(src) == 1) {
- append_acs0(dst, code, *src);
+ if (VALID_STRING(src) && strlen(src) == 1) {
+ append_acs0(dst, code, src, 0);
}
}
@@ -581,32 +679,32 @@ append_acs(string_desc * dst, int code, char *src)
* 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 */
};
/*
@@ -621,13 +719,6 @@ static const char C_BS[] = "\b";
static const char C_HT[] = "\t";
/*
- * Note that WANTED and PRESENT are not simple inverses! If a capability
- * has been explicitly cancelled, it's not considered WANTED.
- */
-#define WANTED(s) ((s) == ABSENT_STRING)
-#define PRESENT(s) (((s) != ABSENT_STRING) && ((s) != CANCELLED_STRING))
-
-/*
* This bit of legerdemain turns all the terminfo variable names into
* references to locations in the arrays Booleans, Numbers, and Strings ---
* precisely what's needed.
@@ -637,7 +728,7 @@ static const char C_HT[] = "\t";
#define CUR tp->
static void
-postprocess_termcap(TERMTYPE *tp, bool has_base)
+postprocess_termcap(TERMTYPE2 *tp, bool has_base)
{
char buf[MAX_LINE * 2 + 2];
string_desc result;
@@ -652,10 +743,10 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
/* if there was a tc entry, assume we picked up defaults via that */
if (!has_base) {
- if (WANTED(init_3string) && termcap_init2)
+ if (WANTED(init_3string) && PRESENT(termcap_init2))
init_3string = _nc_save_str(termcap_init2);
- if (WANTED(reset_2string) && termcap_reset)
+ if (WANTED(reset_2string) && PRESENT(termcap_reset))
reset_2string = _nc_save_str(termcap_reset);
if (WANTED(carriage_return)) {
@@ -770,7 +861,7 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
if (init_tabs != 8 && init_tabs != ABSENT_NUMERIC)
_nc_warning("hardware tabs with a width other than 8: %d", init_tabs);
else {
- if (tab && _nc_capcmp(tab, C_HT))
+ if (PRESENT(tab) && _nc_capcmp(tab, C_HT))
_nc_warning("hardware tabs with a non-^I tab string %s",
_nc_visbuf(tab));
else {
@@ -789,7 +880,6 @@ postprocess_termcap(TERMTYPE *tp, bool has_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;
@@ -802,17 +892,21 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
(cp = strchr(base, ',')) != 0;
base = cp + 1) {
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... */
@@ -829,15 +923,14 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
}
if (tp->Strings[to_ptr->nte_index]) {
+ const char *s = tp->Strings[from_ptr->nte_index];
+ const char *t = tp->Strings[to_ptr->nte_index];
/* There's no point in warning about it if it's the same
* string; that's just an inefficiency.
*/
- if (strcmp(
- tp->Strings[from_ptr->nte_index],
- tp->Strings[to_ptr->nte_index]) != 0)
+ if (VALID_STRING(s) && VALID_STRING(t) && strcmp(s, t) != 0)
_nc_warning("%s (%s) already has an explicit value %s, ignoring ko",
- ap->to, ap->from,
- _nc_visbuf(tp->Strings[to_ptr->nte_index]));
+ ap->to, ap->from, t);
continue;
}
@@ -845,17 +938,22 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
* The magic moment -- copy the mapped key string over,
* stripping out padding.
*/
- for (dp = buf2, bp = tp->Strings[from_ptr->nte_index]; *bp; bp++) {
- if (bp[0] == '$' && bp[1] == '<') {
- while (*bp && *bp != '>') {
- ++bp;
- }
- } else
- *dp++ = *bp;
- }
- *dp = '\0';
+ bp = tp->Strings[from_ptr->nte_index];
+ if (VALID_STRING(bp)) {
+ for (dp = buf2; *bp; bp++) {
+ if (bp[0] == '$' && bp[1] == '<') {
+ while (*bp && *bp != '>') {
+ ++bp;
+ }
+ } else
+ *dp++ = *bp;
+ }
+ *dp = '\0';
- tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
+ tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
+ } else {
+ tp->Strings[to_ptr->nte_index] = bp;
+ }
}
/*
@@ -864,7 +962,7 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
* got mapped to kich1 and im to kIC to avoid a collision.
* If the description has im but not ic, hack kIC back to kich1.
*/
- if (foundim && WANTED(key_ic) && key_sic) {
+ if (foundim && WANTED(key_ic) && PRESENT(key_sic)) {
key_ic = key_sic;
key_sic = ABSENT_STRING;
}
@@ -916,15 +1014,15 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
acs_chars = _nc_save_str(buf2);
_nc_warning("acsc string synthesized from XENIX capabilities");
}
- } else if (acs_chars == 0
- && enter_alt_charset_mode != 0
- && exit_alt_charset_mode != 0) {
+ } else if (acs_chars == ABSENT_STRING
+ && PRESENT(enter_alt_charset_mode)
+ && PRESENT(exit_alt_charset_mode)) {
acs_chars = _nc_save_str(VT_ACSC);
}
}
static void
-postprocess_terminfo(TERMTYPE *tp)
+postprocess_terminfo(TERMTYPE2 *tp)
{
/*
* TERMINFO-TO-TERMINFO MAPPINGS FOR SOURCE TRANSLATION
@@ -941,17 +1039,17 @@ postprocess_terminfo(TERMTYPE *tp)
_nc_str_init(&result, buf2, sizeof(buf2));
_nc_safe_strcat(&result, acs_chars);
- append_acs0(&result, 'l', box_chars_1[0]); /* ACS_ULCORNER */
- append_acs0(&result, 'q', box_chars_1[1]); /* ACS_HLINE */
- append_acs0(&result, 'k', box_chars_1[2]); /* ACS_URCORNER */
- append_acs0(&result, 'x', box_chars_1[3]); /* ACS_VLINE */
- append_acs0(&result, 'j', box_chars_1[4]); /* ACS_LRCORNER */
- append_acs0(&result, 'm', box_chars_1[5]); /* ACS_LLCORNER */
- append_acs0(&result, 'w', box_chars_1[6]); /* ACS_TTEE */
- append_acs0(&result, 'u', box_chars_1[7]); /* ACS_RTEE */
- append_acs0(&result, 'v', box_chars_1[8]); /* ACS_BTEE */
- append_acs0(&result, 't', box_chars_1[9]); /* ACS_LTEE */
- append_acs0(&result, 'n', box_chars_1[10]); /* ACS_PLUS */
+ append_acs0(&result, 'l', box_chars_1, 0); /* ACS_ULCORNER */
+ append_acs0(&result, 'q', box_chars_1, 1); /* ACS_HLINE */
+ append_acs0(&result, 'k', box_chars_1, 2); /* ACS_URCORNER */
+ append_acs0(&result, 'x', box_chars_1, 3); /* ACS_VLINE */
+ append_acs0(&result, 'j', box_chars_1, 4); /* ACS_LRCORNER */
+ append_acs0(&result, 'm', box_chars_1, 5); /* ACS_LLCORNER */
+ append_acs0(&result, 'w', box_chars_1, 6); /* ACS_TTEE */
+ append_acs0(&result, 'u', box_chars_1, 7); /* ACS_RTEE */
+ append_acs0(&result, 'v', box_chars_1, 8); /* ACS_BTEE */
+ append_acs0(&result, 't', box_chars_1, 9); /* ACS_LTEE */
+ append_acs0(&result, 'n', box_chars_1, 10); /* ACS_PLUS */
if (buf2[0]) {
acs_chars = _nc_save_str(buf2);
diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c
index e5c26b5..5b570b0 100644
--- a/ncurses/tinfo/read_entry.c
+++ b/ncurses/tinfo/read_entry.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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,15 +42,89 @@
#include <tic.h>
-MODULE_ID("$Id: read_entry.c,v 1.128 2014/06/14 22:30:41 tom Exp $")
+MODULE_ID("$Id: read_entry.c,v 1.157 2020/02/02 23:34:34 tom Exp $")
#define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts))
#define MyNumber(n) (short) LOW_MSB(n)
+#define SIZEOF_32BITS 4
+
#if NCURSES_USE_DATABASE
-static void
-convert_shorts(char *buf, short *Numbers, int count)
+#if NCURSES_EXT_NUMBERS
+static size_t
+convert_16bits(char *buf, NCURSES_INT2 *Numbers, int count)
+{
+ int i;
+ size_t j;
+ size_t size = SIZEOF_SHORT;
+ for (i = 0; i < count; i++) {
+ unsigned mask = 0xff;
+ unsigned char ch = 0;
+ Numbers[i] = 0;
+ for (j = 0; j < size; ++j) {
+ ch = UChar(*buf++);
+ Numbers[i] |= (ch << (8 * j));
+ mask <<= 8;
+ }
+ if (ch & 0x80) {
+ while (mask != 0) {
+ Numbers[i] |= (int) mask;
+ mask <<= 8;
+ }
+ }
+ TR(TRACE_DATABASE, ("get Numbers[%d]=%d", i, Numbers[i]));
+ }
+ return size;
+}
+
+static size_t
+convert_32bits(char *buf, NCURSES_INT2 *Numbers, int count)
+{
+ int i;
+ size_t j;
+ size_t size = SIZEOF_INT2;
+ unsigned char ch;
+
+ assert(sizeof(NCURSES_INT2) == size);
+ for (i = 0; i < count; i++) {
+ Numbers[i] = 0;
+ for (j = 0; j < size; ++j) {
+ ch = UChar(*buf++);
+ Numbers[i] |= (ch << (8 * j));
+ }
+ /* "unsigned" and NCURSES_INT2 are the same size - no sign-extension */
+ TR(TRACE_DATABASE, ("get Numbers[%d]=%d", i, Numbers[i]));
+ }
+ return size;
+}
+#else
+static size_t
+convert_32bits(char *buf, NCURSES_INT2 *Numbers, int count)
+{
+ int i, j;
+ unsigned char ch;
+ for (i = 0; i < count; i++) {
+ int value = 0;
+ for (j = 0; j < SIZEOF_32BITS; ++j) {
+ ch = UChar(*buf++);
+ value |= (ch << (8 * j));
+ }
+ if (value == -1)
+ Numbers[i] = ABSENT_NUMERIC;
+ else if (value == -2)
+ Numbers[i] = CANCELLED_NUMERIC;
+ else if (value > MAX_OF_TYPE(NCURSES_INT2))
+ Numbers[i] = MAX_OF_TYPE(NCURSES_INT2);
+ else
+ Numbers[i] = (short) value;
+ TR(TRACE_DATABASE, ("get Numbers[%d]=%d", i, Numbers[i]));
+ }
+ return SIZEOF_SHORT;
+}
+
+static size_t
+convert_16bits(char *buf, NCURSES_INT2 *Numbers, int count)
{
int i;
for (i = 0; i < count; i++) {
@@ -61,7 +136,9 @@ convert_shorts(char *buf, short *Numbers, int count)
Numbers[i] = MyNumber(buf + 2 * i);
TR(TRACE_DATABASE, ("get Numbers[%d]=%d", i, Numbers[i]));
}
+ return SIZEOF_SHORT;
}
+#endif
static void
convert_strings(char *buf, char **Strings, int count, int size, char *table)
@@ -112,14 +189,17 @@ fake_read(char *src, int *offset, int limit, char *dst, unsigned want)
#define Read(buf, count) fake_read(buffer, &offset, limit, (char *) buf, (unsigned) count)
#define read_shorts(buf, count) \
- (Read(buf, (count)*2) == (int) (count)*2)
+ (Read(buf, (count)*SIZEOF_SHORT) == (int) (count)*SIZEOF_SHORT)
+
+#define read_numbers(buf, count) \
+ (Read(buf, (count)*(unsigned)size_of_numbers) == (int) (count)*size_of_numbers)
#define even_boundary(value) \
if ((value) % 2 != 0) Read(buf, 1)
#endif
NCURSES_EXPORT(void)
-_nc_init_termtype(TERMTYPE *const tp)
+_nc_init_termtype(TERMTYPE2 *const tp)
{
unsigned i;
@@ -134,7 +214,7 @@ _nc_init_termtype(TERMTYPE *const tp)
if (tp->Booleans == 0)
TYPE_MALLOC(NCURSES_SBOOL, BOOLCOUNT, tp->Booleans);
if (tp->Numbers == 0)
- TYPE_MALLOC(short, NUMCOUNT, tp->Numbers);
+ TYPE_MALLOC(NCURSES_INT2, NUMCOUNT, tp->Numbers);
if (tp->Strings == 0)
TYPE_MALLOC(char *, STRCOUNT, tp->Strings);
@@ -169,7 +249,7 @@ valid_shorts(char *buffer, int limit)
* Return TGETENT_YES if read, TGETENT_NO if not found or garbled.
*/
NCURSES_EXPORT(int)
-_nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
+_nc_read_termtype(TERMTYPE2 *ptr, char *buffer, int limit)
{
int offset = 0;
int name_size, bool_count, num_count, str_count, str_size;
@@ -177,6 +257,14 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
char buf[MAX_ENTRY_SIZE + 2];
char *string_table;
unsigned want, have;
+ bool need_ints;
+ size_t (*convert_numbers) (char *, NCURSES_INT2 *, int);
+ int size_of_numbers;
+ int max_entry_size = MAX_ENTRY_SIZE;
+
+ TR(TRACE_DATABASE,
+ (T_CALLED("_nc_read_termtype(ptr=%p, buffer=%p, limit=%d)"),
+ (void *) ptr, buffer, limit));
TR(TRACE_DATABASE, ("READ termtype header @%d", offset));
@@ -185,14 +273,33 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
/* grab the header */
if (!read_shorts(buf, 6)
|| !IS_TIC_MAGIC(buf)) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
+ }
+#if NCURSES_EXT_NUMBERS
+ if ((need_ints = (LOW_MSB(buf) == MAGIC2))) {
+ convert_numbers = convert_32bits;
+ size_of_numbers = SIZEOF_INT2;
+ } else {
+ max_entry_size = MAX_ENTRY_SIZE1;
+ convert_numbers = convert_16bits;
+ size_of_numbers = SIZEOF_SHORT;
}
+#else
+ if ((need_ints = (LOW_MSB(buf) == MAGIC2))) {
+ convert_numbers = convert_32bits;
+ size_of_numbers = SIZEOF_32BITS;
+ } else {
+ convert_numbers = convert_16bits;
+ size_of_numbers = SIZEOF_INT2;
+ }
+#endif
- name_size = MyNumber(buf + 2);
+ /* *INDENT-EQLS* */
+ 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);
+ 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)",
@@ -203,21 +310,14 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
|| num_count < 0
|| str_count < 0
|| str_size < 0) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
want = (unsigned) (str_size + name_size + 1);
- if (str_size) {
- /* try to allocate space for the string table */
- if (str_count * 2 >= MAX_ENTRY_SIZE
- || (string_table = typeMalloc(char, want)) == 0) {
- return (TGETENT_NO);
- }
- } else {
- str_count = 0;
- if ((string_table = typeMalloc(char, want)) == 0) {
- return (TGETENT_NO);
- }
+ /* try to allocate space for the string table */
+ if (str_count * SIZEOF_SHORT >= max_entry_size
+ || (string_table = typeMalloc(char, want)) == 0) {
+ returnDB(TGETENT_NO);
}
/* grab the name (a null-terminated string) */
@@ -237,7 +337,7 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
if ((ptr->Booleans = TYPE_CALLOC(NCURSES_SBOOL,
max(BOOLCOUNT, bool_count))) == 0
|| Read(ptr->Booleans, (unsigned) bool_count) < bool_count) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
/*
@@ -249,24 +349,24 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
even_boundary(name_size + bool_count);
/* grab the numbers */
- if ((ptr->Numbers = TYPE_CALLOC(short, max(NUMCOUNT, num_count))) == 0
- || !read_shorts(buf, num_count)) {
- return (TGETENT_NO);
+ if (!(ptr->Numbers = TYPE_CALLOC(NCURSES_INT2, max(NUMCOUNT, num_count)))
+ || !read_numbers(buf, num_count)) {
+ returnDB(TGETENT_NO);
}
- convert_shorts(buf, ptr->Numbers, num_count);
+ convert_numbers(buf, ptr->Numbers, num_count);
if ((ptr->Strings = TYPE_CALLOC(char *, max(STRCOUNT, str_count))) == 0) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
if (str_count) {
/* grab the string offsets */
if (!read_shorts(buf, str_count)) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
/* finally, grab the string table itself */
if (Read(string_table, (unsigned) str_size) != str_size) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
convert_strings(buf, ptr->Strings, str_count, str_size, string_table);
}
@@ -285,20 +385,20 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
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_usage = 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 >= (MAX_ENTRY_SIZE / 2)
- || ext_str_size >= MAX_ENTRY_SIZE
- || ext_str_limit >= MAX_ENTRY_SIZE
+ if ((int) need >= (max_entry_size / 2)
+ || ext_str_usage >= 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_usage < 0
|| ext_str_limit < 0) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
ptr->num_Booleans = UShort(BOOLCOUNT + ext_bool_count);
@@ -306,19 +406,25 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
ptr->num_Strings = UShort(STRCOUNT + ext_str_count);
TYPE_REALLOC(NCURSES_SBOOL, ptr->num_Booleans, ptr->Booleans);
- TYPE_REALLOC(short, ptr->num_Numbers, ptr->Numbers);
+ TYPE_REALLOC(NCURSES_INT2, 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,
- ext_str_size, ext_str_limit));
+ TR(TRACE_DATABASE, ("extended header: "
+ "bool %d, "
+ "number %d, "
+ "string %d(%d:%d)",
+ ext_bool_count,
+ ext_num_count,
+ ext_str_count,
+ ext_str_usage,
+ ext_str_limit));
TR(TRACE_DATABASE, ("READ %d extended-booleans @%d",
ext_bool_count, offset));
if ((ptr->ext_Booleans = UShort(ext_bool_count)) != 0) {
if (Read(ptr->Booleans + BOOLCOUNT, (unsigned)
ext_bool_count) != ext_bool_count) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
}
even_boundary(ext_bool_count);
@@ -326,20 +432,20 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
TR(TRACE_DATABASE, ("READ %d extended-numbers @%d",
ext_num_count, offset));
if ((ptr->ext_Numbers = UShort(ext_num_count)) != 0) {
- if (!read_shorts(buf, ext_num_count)) {
- return (TGETENT_NO);
+ if (!read_numbers(buf, ext_num_count)) {
+ returnDB(TGETENT_NO);
}
TR(TRACE_DATABASE, ("Before converting extended-numbers"));
- convert_shorts(buf, ptr->Numbers + NUMCOUNT, ext_num_count);
+ convert_numbers(buf, ptr->Numbers + NUMCOUNT, ext_num_count);
}
TR(TRACE_DATABASE, ("READ extended-offsets @%d", offset));
- if ((unsigned) (ext_str_count + (int) need) >= (MAX_ENTRY_SIZE / 2)) {
- return (TGETENT_NO);
+ if ((ext_str_count + (int) need) >= (max_entry_size / 2)) {
+ returnDB(TGETENT_NO);
}
if ((ext_str_count || need)
&& !read_shorts(buf, ext_str_count + (int) need)) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
TR(TRACE_DATABASE, ("READ %d bytes of extended-strings @%d",
@@ -348,17 +454,20 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
if (ext_str_limit) {
ptr->ext_str_table = typeMalloc(char, (size_t) ext_str_limit);
if (ptr->ext_str_table == 0) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
if (Read(ptr->ext_str_table, (unsigned) ext_str_limit) != ext_str_limit) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
TR(TRACE_DATABASE, ("first extended-string is %s", _nc_visbuf(ptr->ext_str_table)));
}
if ((ptr->ext_Strings = UShort(ext_str_count)) != 0) {
+ int check = (ext_bool_count + ext_num_count + ext_str_count);
+
TR(TRACE_DATABASE,
- ("Before computing extended-string capabilities str_count=%d, ext_str_count=%d",
+ ("Before computing extended-string capabilities "
+ "str_count=%d, ext_str_count=%d",
str_count, ext_str_count));
convert_strings(buf, ptr->Strings + str_count, ext_str_count,
ext_str_limit, ptr->ext_str_table);
@@ -367,20 +476,30 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
i, i + str_count,
_nc_visbuf(ptr->Strings[i + str_count])));
ptr->Strings[i + STRCOUNT] = ptr->Strings[i + str_count];
- if (VALID_STRING(ptr->Strings[i + STRCOUNT]))
+ if (VALID_STRING(ptr->Strings[i + STRCOUNT])) {
base += (int) (strlen(ptr->Strings[i + STRCOUNT]) + 1);
+ ++check;
+ }
TR(TRACE_DATABASE, ("... to [%d] %s",
i + STRCOUNT,
_nc_visbuf(ptr->Strings[i + STRCOUNT])));
}
+ TR(TRACE_DATABASE, ("Check table-size: %d/%d", check, ext_str_usage));
+#if 0
+ /*
+ * Phasing in a proper check will be done "later".
+ */
+ if (check != ext_str_usage)
+ returnDB(TGETENT_NO);
+#endif
}
if (need) {
- if (ext_str_count >= (MAX_ENTRY_SIZE / 2)) {
- return (TGETENT_NO);
+ if (ext_str_count >= (max_entry_size / 2)) {
+ returnDB(TGETENT_NO);
}
if ((ptr->ext_Names = TYPE_CALLOC(char *, need)) == 0) {
- return (TGETENT_NO);
+ returnDB(TGETENT_NO);
}
TR(TRACE_DATABASE,
("ext_NAMES starting @%d in extended_strings, first = %s",
@@ -415,7 +534,7 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
for (i = str_count; i < STRCOUNT; i++)
ptr->Strings[i] = ABSENT_STRING;
- return (TGETENT_YES);
+ returnDB(TGETENT_YES);
}
/*
@@ -427,25 +546,26 @@ _nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
* table.
*/
NCURSES_EXPORT(int)
-_nc_read_file_entry(const char *const filename, TERMTYPE *ptr)
+_nc_read_file_entry(const char *const filename, TERMTYPE2 *ptr)
/* return 1 if read, 0 if not found or garbled */
{
FILE *fp = 0;
int code;
- int limit;
- char buffer[MAX_ENTRY_SIZE + 1];
if (_nc_access(filename, R_OK) < 0
- || (fp = fopen(filename, "rb")) == 0) {
+ || (fp = fopen(filename, BIN_R)) == 0) {
TR(TRACE_DATABASE, ("cannot open terminfo %s (errno=%d)", filename, errno));
code = TGETENT_NO;
} else {
+ int limit;
+ char buffer[MAX_ENTRY_SIZE + 1];
+
if ((limit = (int) fread(buffer, sizeof(char), sizeof(buffer), fp))
> 0) {
TR(TRACE_DATABASE, ("read terminfo %s", filename));
if ((code = _nc_read_termtype(ptr, buffer, limit)) == TGETENT_NO) {
- _nc_free_termtype(ptr);
+ _nc_free_termtype2(ptr);
}
} else {
code = TGETENT_NO;
@@ -508,6 +628,106 @@ make_dir_filename(char *filename,
return result;
}
+static int
+lookup_b64(int *target, const char **source)
+{
+ int result = 3;
+ int j;
+ /*
+ * ncurses' quickdump writes only RFC 4648 "url/filename-safe" encoding,
+ * but accepts RFC-3548
+ */
+ for (j = 0; j < 4; ++j) {
+ int ch = UChar(**source);
+ *source += 1;
+ if (ch >= 'A' && ch <= 'Z') {
+ target[j] = (ch - 'A');
+ } else if (ch >= 'a' && ch <= 'z') {
+ target[j] = 26 + (ch - 'a');
+ } else if (ch >= '0' && ch <= '9') {
+ target[j] = 52 + (ch - '0');
+ } else if (ch == '-' || ch == '+') {
+ target[j] = 62;
+ } else if (ch == '_' || ch == '/') {
+ target[j] = 63;
+ } else if (ch == '=') {
+ target[j] = 64;
+ result--;
+ } else {
+ result = -1;
+ break;
+ }
+ }
+ return result;
+}
+
+static int
+decode_hex(const char **source)
+{
+ int result = 0;
+ int nibble;
+ int ch;
+
+ for (nibble = 0; nibble < 2; ++nibble) {
+ result <<= 4;
+ ch = UChar(**source);
+ *source += 1;
+ if (ch >= '0' && ch <= '9') {
+ ch -= '0';
+ } else if (ch >= 'A' && ch <= 'F') {
+ ch -= 'A';
+ ch += 10;
+ } else if (ch >= 'a' && ch <= 'f') {
+ ch -= 'a';
+ ch += 10;
+ } else {
+ result = -1;
+ break;
+ }
+ result |= ch;
+ }
+ return result;
+}
+
+static int
+decode_quickdump(char *target, const char *source)
+{
+ char *base = target;
+ int result = 0;
+
+ if (!strncmp(source, "b64:", (size_t) 4)) {
+ source += 4;
+ while (*source != '\0') {
+ int bits[4];
+ int ch = lookup_b64(bits, &source);
+ if (ch < 0 || (ch + target - base) >= MAX_ENTRY_SIZE) {
+ result = 0;
+ break;
+ }
+ result += ch;
+ *target++ = (char) ((bits[0] << 2) | (bits[1] >> 4));
+ if (bits[2] < 64) {
+ *target++ = (char) ((bits[1] << 4) | (bits[2] >> 2));
+ if (bits[3] < 64) {
+ *target++ = (char) ((bits[2] << 6) | bits[3]);
+ }
+ }
+ }
+ } else if (!strncmp(source, "hex:", (size_t) 4)) {
+ source += 4;
+ while (*source != '\0') {
+ int ch = decode_hex(&source);
+ if (ch < 0 || (target - base) >= MAX_ENTRY_SIZE) {
+ result = 0;
+ break;
+ }
+ *target++ = (char) ch;
+ ++result;
+ }
+ }
+ return result;
+}
+
/*
* Build a terminfo pathname and try to read the data. Returns TGETENT_YES on
* success, TGETENT_NO on failure.
@@ -517,15 +737,31 @@ _nc_read_tic_entry(char *filename,
unsigned limit,
const char *const path,
const char *name,
- TERMTYPE *const tp)
+ TERMTYPE2 *const tp)
{
int code = TGETENT_NO;
-
#if USE_HASHED_DB
DB *capdbp;
+#endif
+ char buffer[MAX_ENTRY_SIZE + 1];
+ int used;
+
+ TR(TRACE_DATABASE,
+ (T_CALLED("_nc_read_tic_entry(file=%p, path=%s, name=%s)"),
+ filename, path, name));
- if (make_db_filename(filename, limit, path)
- && (capdbp = _nc_db_open(filename, FALSE)) != 0) {
+ assert(TGETENT_YES == TRUE); /* simplify call for _nc_name_match */
+
+ if ((used = decode_quickdump(buffer, path)) != 0
+ && (code = _nc_read_termtype(tp, buffer, used)) == TGETENT_YES
+ && (code = _nc_name_match(tp->term_names, name, "|")) == TGETENT_YES) {
+ TR(TRACE_DATABASE, ("loaded quick-dump for %s", name));
+ /* shorten name shown by infocmp */
+ _nc_STRCPY(filename, "$TERMINFO", limit);
+ } else
+#if USE_HASHED_DB
+ if (make_db_filename(filename, limit, path)
+ && (capdbp = _nc_db_open(filename, FALSE)) != 0) {
DBT key, data;
int reccnt = 0;
@@ -551,15 +787,15 @@ _nc_read_tic_entry(char *filename,
* (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;
+ used = (int) data.size - 1;
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);
+ _nc_free_termtype2(tp);
}
}
break;
@@ -586,30 +822,29 @@ _nc_read_tic_entry(char *filename,
code = _nc_read_file_entry(filename, tp);
}
#if NCURSES_USE_TERMCAP
- else if (code != TGETENT_YES) {
+ 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 code;
+ returnDB(code);
}
#endif /* NCURSES_USE_DATABASE */
/*
- * _nc_read_entry(char *name, char *filename, TERMTYPE *tp)
- *
- * Find and read the compiled entry for a given terminal type,
- * if it exists. We take pains here to make sure no combination
- * of environment variables and terminal type name can be used to
- * overrun the file buffer.
+ * Find and read the compiled entry for a given terminal type, if it exists.
+ * We take pains here to make sure no combination of environment variables and
+ * terminal type name can be used to overrun the file buffer.
*/
-
NCURSES_EXPORT(int)
-_nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp)
+_nc_read_entry2(const char *const name, char *const filename, TERMTYPE2 *const tp)
{
int code = TGETENT_NO;
+ if (name == 0)
+ return _nc_read_entry2("", filename, tp);
+
_nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
"%.*s", PATH_MAX - 1, name);
@@ -626,8 +861,8 @@ _nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp)
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();
@@ -644,3 +879,19 @@ _nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp)
}
return code;
}
+
+#if NCURSES_EXT_NUMBERS
+/*
+ * This entrypoint is used by tack 1.07
+ */
+NCURSES_EXPORT(int)
+_nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp)
+{
+ TERMTYPE2 dummy;
+ int rc;
+ rc = _nc_read_entry2(name, filename, &dummy);
+ if (rc == TGETENT_YES)
+ _nc_export_termtype2(tp, &dummy);
+ return rc;
+}
+#endif
diff --git a/ncurses/tinfo/read_termcap.c b/ncurses/tinfo/read_termcap.c
index 6bfb23c..fcb43a4 100644
--- a/ncurses/tinfo/read_termcap.c
+++ b/ncurses/tinfo/read_termcap.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -56,7 +57,7 @@
#include <sys/types.h>
#include <tic.h>
-MODULE_ID("$Id: read_termcap.c,v 1.89 2013/12/15 00:32:43 tom Exp $")
+MODULE_ID("$Id: read_termcap.c,v 1.98 2020/02/02 23:34:34 tom Exp $")
#if !PURE_TERMINFO
@@ -66,10 +67,10 @@ MODULE_ID("$Id: read_termcap.c,v 1.89 2013/12/15 00:32:43 tom Exp $")
#define TC_REF_LOOP -3
#define TC_UNRESOLVED -4 /* this is not returned by BSD cgetent */
-static NCURSES_CONST char *
+static const char *
get_termpath(void)
{
- NCURSES_CONST char *result;
+ const char *result;
if (!use_terminfo_vars() || (result = getenv("TERMPATH")) == 0)
result = TERMPATH;
@@ -364,7 +365,7 @@ _nc_getent(
if (bp >= b_end) {
int n;
- n = read(fd, buf, sizeof(buf));
+ n = (int) read(fd, buf, sizeof(buf));
if (n <= 0) {
if (myfd)
(void) close(fd);
@@ -393,7 +394,7 @@ _nc_getent(
|| *(rp - 1) != '\\')
break;
}
- *rp++ = c;
+ *rp++ = (char) c;
/*
* Enforce loop invariant: if no room
@@ -404,8 +405,8 @@ _nc_getent(
unsigned pos;
size_t newsize;
- pos = rp - record;
- newsize = r_end - record + BFRAG;
+ pos = (unsigned) (rp - record);
+ newsize = (size_t) (r_end - record + BFRAG);
record = DOALLOC(newsize);
if (record == 0) {
if (myfd)
@@ -492,14 +493,14 @@ _nc_getent(
}
}
tcstart = tc - 3;
- tclen = s - tcstart;
+ tclen = (int) (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. */
- newilen = ilen;
+ newilen = (int) ilen;
if (iret != TC_SUCCESS) {
/* an error */
if (iret < TC_NOT_FOUND) {
@@ -523,7 +524,7 @@ _nc_getent(
/* not interested in name field of tc'ed record */
s = newicap;
while (*s != '\0' && *s++ != ':') ;
- newilen -= s - newicap;
+ newilen -= (int) (s - newicap);
newicap = s;
/* make sure interpolated record is `:'-terminated */
@@ -542,10 +543,10 @@ _nc_getent(
unsigned pos, tcpos, tcposend;
size_t newsize;
- pos = rp - record;
- newsize = r_end - record + diff + BFRAG;
- tcpos = tcstart - record;
- tcposend = tcend - record;
+ pos = (unsigned) (rp - record);
+ newsize = (size_t) (r_end - record + diff + BFRAG);
+ tcpos = (unsigned) (tcstart - record);
+ tcposend = (unsigned) (tcend - record);
record = DOALLOC(newsize);
if (record == 0) {
if (myfd)
@@ -583,7 +584,7 @@ _nc_getent(
*/
if (myfd)
(void) close(fd);
- *len = rp - record - 1; /* don't count NUL */
+ *len = (unsigned) (rp - record - 1); /* don't count NUL */
if (r_end > rp) {
if ((record = DOALLOC((size_t) (rp - record))) == 0) {
errno = ENOMEM;
@@ -791,7 +792,7 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
int i;
char pathbuf[PBUFSIZ]; /* holds raw path of filenames */
CGETENT_CONST char *pathvec[PVECSIZ]; /* point to names in pathbuf */
- NCURSES_CONST char *termpath;
+ const char *termpath;
string_desc desc;
*lineno = 1;
@@ -956,7 +957,7 @@ add_tc(char *termpaths[], char *path, int count)
#endif /* !USE_GETCAP */
NCURSES_EXPORT(int)
-_nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
+_nc_read_termcap_entry(const char *const tn, TERMTYPE2 *const tp)
{
int found = TGETENT_NO;
ENTRY *ep;
@@ -965,6 +966,8 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
#endif
#if USE_GETCAP
char *p, tc[TBUFSIZ];
+ char *tc_buf = 0;
+#define MY_SIZE sizeof(tc) - 1
int status;
static char *source;
static int lineno;
@@ -982,8 +985,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
if (use_terminfo_vars() && (p = getenv("TERMCAP")) != 0
&& !_nc_is_abs_path(p) && _nc_name_match(p, tn, "|:")) {
/* TERMCAP holds a termcap entry */
- strncpy(tc, p, sizeof(tc) - 1);
- tc[sizeof(tc) - 1] = '\0';
+ tc_buf = strdup(p);
_nc_set_source("TERMCAP");
} else {
/* we're using getcap(3) */
@@ -992,8 +994,13 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
_nc_curr_line = lineno;
_nc_set_source(source);
+ tc_buf = tc;
}
- _nc_read_entry_source((FILE *) 0, tc, FALSE, TRUE, NULLHOOK);
+ if (tc_buf == 0)
+ return (TGETENT_ERR);
+ _nc_read_entry_source((FILE *) 0, tc_buf, FALSE, TRUE, NULLHOOK);
+ if (tc_buf != tc)
+ free(tc_buf);
#else
/*
* Here is what the 4.4BSD termcap(3) page prescribes:
@@ -1027,7 +1034,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
int j, k;
bool use_buffer = FALSE;
bool normal = TRUE;
- char tc_buf[1024];
+ char *tc_buf = 0;
char pathbuf[PATH_MAX];
char *copied = 0;
char *cp;
@@ -1039,10 +1046,8 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
ADD_TC(tc, 0);
normal = FALSE;
} else if (_nc_name_match(tc, tn, "|:")) { /* treat as a capability file */
- use_buffer = TRUE;
- _nc_SPRINTF(tc_buf,
- _nc_SLIMIT(sizeof(tc_buf))
- "%.*s\n", (int) sizeof(tc_buf) - 2, tc);
+ tc_buf = strdup(tc);
+ use_buffer = (tc_buf != 0);
normal = FALSE;
}
}
@@ -1111,6 +1116,7 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
* that since it's just a single entry, they won't be a pain.
*/
_nc_read_entry_source((FILE *) 0, tc_buf, FALSE, FALSE, NULLHOOK);
+ free(tc_buf);
} else {
int i;
@@ -1140,7 +1146,8 @@ _nc_read_termcap_entry(const char *const tn, TERMTYPE *const tp)
return (TGETENT_ERR);
/* resolve all use references */
- _nc_resolve_uses2(TRUE, FALSE);
+ if (_nc_resolve_uses2(TRUE, FALSE) != TRUE)
+ return (TGETENT_ERR);
/* find a terminal matching tn, if we can */
#if USE_GETCAP_CACHE
diff --git a/ncurses/tinfo/strings.c b/ncurses/tinfo/strings.c
index 393d8e7..a1d8beb 100644
--- a/ncurses/tinfo/strings.c
+++ b/ncurses/tinfo/strings.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2000-2007,2012 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2000-2012,2017 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,8 +36,9 @@
**/
#include <curses.priv.h>
+#include <tic.h>
-MODULE_ID("$Id: strings.c,v 1.8 2012/02/22 22:34:31 tom Exp $")
+MODULE_ID("$Id: strings.c,v 1.10 2020/02/02 23:34:34 tom Exp $")
/****************************************************************************
* Useful string functions (especially for mvcur)
@@ -105,7 +107,7 @@ _nc_str_copy(string_desc * dst, string_desc * src)
NCURSES_EXPORT(bool)
_nc_safe_strcat(string_desc * dst, const char *src)
{
- if (src != 0) {
+ if (PRESENT(src)) {
size_t len = strlen(src);
if (len < dst->s_size) {
@@ -126,7 +128,7 @@ _nc_safe_strcat(string_desc * dst, const char *src)
NCURSES_EXPORT(bool)
_nc_safe_strcpy(string_desc * dst, const char *src)
{
- if (src != 0) {
+ if (PRESENT(src)) {
size_t len = strlen(src);
if (len < dst->s_size) {
diff --git a/ncurses/tinfo/tinfo_driver.c b/ncurses/tinfo/tinfo_driver.c
index a17accd..7919a9b 100644
--- a/ncurses/tinfo/tinfo_driver.c
+++ b/ncurses/tinfo/tinfo_driver.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2008-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 2008-2016,2017 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,12 +29,13 @@
/****************************************************************************
* Author: Juergen Pfeifer *
- * *
+ * and: Thomas E. Dickey *
****************************************************************************/
#include <curses.priv.h>
-#define CUR ((TERMINAL*)TCB)->type.
+#define CUR TerminalType((TERMINAL*)TCB).
#include <tic.h>
+#include <termcap.h> /* ospeed */
#if HAVE_NANOSLEEP
#include <time.h>
@@ -50,7 +52,7 @@
# endif
#endif
-MODULE_ID("$Id: tinfo_driver.c,v 1.39 2014/09/27 21:58:57 tom Exp $")
+MODULE_ID("$Id: tinfo_driver.c,v 1.67 2020/02/02 23:34:34 tom Exp $")
/*
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
@@ -113,6 +115,38 @@ drv_Name(TERMINAL_CONTROL_BLOCK * TCB)
return "tinfo";
}
+static void
+get_baudrate(TERMINAL *termp)
+{
+ int my_ospeed;
+ int result;
+ if (GET_TTY(termp->Filedes, &termp->Nttyb) == OK) {
+#ifdef TERMIOS
+ termp->Nttyb.c_oflag &= (unsigned) (~OFLAGS_TABS);
+#else
+ termp->Nttyb.sg_flags &= (unsigned) (~XTABS);
+#endif
+ }
+#ifdef USE_OLD_TTY
+ result = (int) cfgetospeed(&(termp->Nttyb));
+ my_ospeed = (NCURSES_OSPEED) _nc_ospeed(result);
+#else /* !USE_OLD_TTY */
+#ifdef TERMIOS
+ my_ospeed = (NCURSES_OSPEED) cfgetospeed(&(termp->Nttyb));
+#else
+ my_ospeed = (NCURSES_OSPEED) termp->Nttyb.sg_ospeed;
+#endif
+ result = _nc_baudrate(my_ospeed);
+#endif
+ termp->_baudrate = result;
+ ospeed = (NCURSES_OSPEED) my_ospeed;
+}
+
+#undef SETUP_FAIL
+#define SETUP_FAIL FALSE
+
+#define NO_COPY {}
+
static bool
drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
{
@@ -121,7 +155,8 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
TERMINAL *termp;
SCREEN *sp;
- T((T_CALLED("tinfo::drv_CanHandle(%p)"), TCB));
+ START_TRACE();
+ T((T_CALLED("tinfo::drv_CanHandle(%p)"), (void *) TCB));
assert(TCB != 0 && tname != 0);
termp = (TERMINAL *) TCB;
@@ -129,17 +164,20 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
TCB->magic = TCBMAGIC;
#if (NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP)
- status = _nc_setup_tinfo(tname, &termp->type);
+ status = _nc_setup_tinfo(tname, &TerminalType(termp));
+ T(("_nc_setup_tinfo returns %d", status));
#else
+ T(("no database available"));
status = TGETENT_NO;
#endif
/* try fallback list if entry on disk */
if (status != TGETENT_YES) {
- const TERMTYPE *fallback = _nc_fallback(tname);
+ const TERMTYPE2 *fallback = _nc_fallback2(tname);
if (fallback) {
- termp->type = *fallback;
+ T(("found fallback entry"));
+ TerminalType(termp) = *fallback;
status = TGETENT_YES;
}
}
@@ -149,18 +187,41 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
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);
+ ret_error1(status, "unknown terminal type.\n",
+ tname, NO_COPY);
+ } else {
+ ret_error0(status, "unexpected return-code\n");
}
}
result = TRUE;
+#if NCURSES_EXT_NUMBERS
+ _nc_export_termtype2(&termp->type, &TerminalType(termp));
+#endif
#if !USE_REENTRANT
- strncpy(ttytype, termp->type.term_names, (size_t) NAMESIZE - 1);
- ttytype[NAMESIZE - 1] = '\0';
+ save_ttytype(termp);
#endif
if (command_character)
_nc_tinfo_cmdch(termp, *command_character);
+ /*
+ * 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 (sp == 0 && NC_ISATTY(termp->Filedes)) {
+ get_baudrate(termp);
+ }
+#if NCURSES_EXT_NUMBERS
+#define cleanup_termtype() \
+ _nc_free_termtype2(&TerminalType(termp)); \
+ _nc_free_termtype(&termp->type)
+#else
+#define cleanup_termtype() \
+ _nc_free_termtype2(&TerminalType(termp))
+#endif
+
if (generic_type) {
/*
* BSD 4.3's termcap contains mis-typed "gn" for wy99. Do a sanity
@@ -169,13 +230,19 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
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);
+ cleanup_termtype();
+ ret_error1(TGETENT_YES, "terminal is not really generic.\n",
+ tname, NO_COPY);
} else {
- ret_error1(TGETENT_NO, "I need something more specific.\n", tname);
+ cleanup_termtype();
+ ret_error1(TGETENT_NO, "I need something more specific.\n",
+ tname, NO_COPY);
}
}
if (hard_copy) {
- ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname);
+ cleanup_termtype();
+ ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n",
+ tname, NO_COPY);
}
returnBool(result);
@@ -257,8 +324,8 @@ drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB, int fg, int 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);
+ sp->_default_fg = isDefaultColor(fg) ? COLOR_DEFAULT : fg;
+ sp->_default_bg = isDefaultColor(bg) ? COLOR_DEFAULT : bg;
if (sp->_color_pairs != 0) {
bool save = sp->_default_color;
sp->_default_color = TRUE;
@@ -354,7 +421,7 @@ drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *linep, int *colp)
if (sp) {
useEnv = sp->_use_env;
- useTioctl = sp->_use_tioctl;
+ useTioctl = sp->use_tioctl;
} else {
useEnv = _nc_prescreen.use_env;
useTioctl = _nc_prescreen.use_tioctl;
@@ -745,9 +812,9 @@ drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
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;
+ int fg = COLOR_DEFAULT;
+ int bg = COLOR_DEFAULT;
+ int old_fg, old_bg;
AssertTCB();
if (sp == 0)
@@ -762,19 +829,13 @@ drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
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);
+ _nc_pair_content(SP_PARM, 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) {
+ && _nc_pair_content(SP_PARM, old_pair, &old_fg, &old_bg) != ERR) {
if ((isDefaultColor(fg) && !isDefaultColor(old_fg))
|| (isDefaultColor(bg) && !isDefaultColor(old_bg))) {
#if NCURSES_EXT_FUNCS
@@ -803,13 +864,13 @@ drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
#if NCURSES_EXT_FUNCS
if (isDefaultColor(fg))
- fg = (NCURSES_COLOR_T) default_fg(sp);
+ fg = default_fg(sp);
if (isDefaultColor(bg))
- bg = (NCURSES_COLOR_T) default_bg(sp);
+ bg = default_bg(sp);
#endif
if (reverse) {
- NCURSES_COLOR_T xx = fg;
+ int xx = fg;
fg = bg;
bg = xx;
}
@@ -845,12 +906,9 @@ drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB)
/* 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 (NonEmpty(key_mouse)) {
+ init_xterm_mouse(sp);
+ } else if (strstr(SP_TERMTYPE term_names, "xterm") != 0) {
if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK)
init_xterm_mouse(sp);
}
@@ -975,12 +1033,18 @@ 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;
+ /* *INDENT-EQLS* */
+ clear_screen = ABSENT_STRING;
+ cursor_address = ABSENT_STRING;
+ cursor_down = ABSENT_STRING;
+ cursor_up = ABSENT_STRING;
+ parm_down_cursor = ABSENT_STRING;
+ parm_up_cursor = ABSENT_STRING;
+ row_address = ABSENT_STRING;
+ cursor_home = carriage_return;
+
+ if (back_color_erase)
+ clr_eos = ABSENT_STRING;
}
static void
@@ -1027,8 +1091,13 @@ drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *real_map, chtype *fake_map)
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)
+ T(("#%d real_map[%s] = %s",
+ (int) i,
+ _tracechar(UChar(acs_chars[i])),
+ _tracechtype(real_map[UChar(acs_chars[i])])));
+ if (sp != 0) {
sp->_screen_acs_map[UChar(acs_chars[i])] = TRUE;
+ }
}
i += 2;
}
@@ -1058,7 +1127,6 @@ drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *real_map, chtype *fake_map)
? "DIFF"
: "SAME"),
_nc_visbuf(show));
-
_nc_unlock_global(tracef);
}
#endif /* TRACE */
@@ -1186,7 +1254,7 @@ drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
if ((pthread_self) && (pthread_kill) && (pthread_equal))
_nc_globals.read_thread = pthread_self();
# endif
- n = read(sp->_ifd, &c2, (size_t) 1);
+ n = (int) read(sp->_ifd, &c2, (size_t) 1);
#if USE_PTHREADS_EINTR
_nc_globals.read_thread = 0;
#endif
@@ -1275,23 +1343,29 @@ drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int c, int flag)
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;
+ ch, &count, (size_t) 0)) != 0) {
+ if (_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 {
+ free(s);
+ }
}
} 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;
+ ch, &count, (size_t) 0)) != 0) {
+ if (_nc_remove_key(&(sp->_keytry), ch)) {
+ code = _nc_add_to_try(&(sp->_key_ok), s, ch);
+ free(s);
+ count = 0;
+ if (code != OK)
+ break;
+ } else {
+ free(s);
+ }
}
}
}
diff --git a/ncurses/tinfo/trim_sgr0.c b/ncurses/tinfo/trim_sgr0.c
index ec5e2b7..4d10529 100644
--- a/ncurses/tinfo/trim_sgr0.c
+++ b/ncurses/tinfo/trim_sgr0.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2005-2010,2012 Free Software Foundation, Inc. *
+ * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2005-2012,2017 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 +37,7 @@
#include <tic.h>
-MODULE_ID("$Id: trim_sgr0.c,v 1.15 2012/12/15 20:57:17 tom Exp $")
+MODULE_ID("$Id: trim_sgr0.c,v 1.18 2020/02/02 23:34:34 tom Exp $")
#undef CUR
#define CUR tp->
@@ -46,7 +47,7 @@ MODULE_ID("$Id: trim_sgr0.c,v 1.15 2012/12/15 20:57:17 tom Exp $")
#define L_BRACK '['
static char *
-set_attribute_9(TERMTYPE *tp, int flag)
+set_attribute_9(TERMTYPE2 *tp, int flag)
{
const char *value;
char *result;
@@ -232,7 +233,7 @@ compare_part(const char *part, const char *full)
* an error occurs, or the original sgr0 if no change is needed.
*/
NCURSES_EXPORT(char *)
-_nc_trim_sgr0(TERMTYPE *tp)
+_nc_trim_sgr0(TERMTYPE2 *tp)
{
char *result = exit_attribute_mode;
@@ -263,7 +264,7 @@ _nc_trim_sgr0(TERMTYPE *tp)
/*
* If rmacs is a substring of sgr(0), remove that chunk.
*/
- if (exit_alt_charset_mode != 0) {
+ if (PRESENT(exit_alt_charset_mode)) {
TR(TRACE_DATABASE, ("scan for rmacs %s", _nc_visbuf(exit_alt_charset_mode)));
j = strlen(off);
k = strlen(exit_alt_charset_mode);
diff --git a/ncurses/tinfo/use_screen.c b/ncurses/tinfo/use_screen.c
index 6a0297c..a4bf932 100644
--- a/ncurses/tinfo/use_screen.c
+++ b/ncurses/tinfo/use_screen.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 2007-2008,2009 Free Software Foundation, Inc. *
+ * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 2007-2009,2016 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,15 +33,19 @@
#include <curses.priv.h>
-MODULE_ID("$Id: use_screen.c,v 1.8 2009/10/24 22:40:20 tom Exp $")
+MODULE_ID("$Id: use_screen.c,v 1.12 2020/02/02 23:34:34 tom Exp $")
NCURSES_EXPORT(int)
use_screen(SCREEN *screen, NCURSES_SCREEN_CB func, void *data)
{
SCREEN *save_SP;
int code = OK;
+ TR_FUNC_BFR(1);
- T((T_CALLED("use_screen(%p,%p,%p)"), (void *) screen, func, (void *) data));
+ T((T_CALLED("use_screen(%p,%s,%p)"),
+ (void *) screen,
+ TR_FUNC_ARG(0, func),
+ (void *) data));
/*
* FIXME - add a flag so a given thread can check if _it_ has already
diff --git a/ncurses/tinfo/write_entry.c b/ncurses/tinfo/write_entry.c
index b2edd5d..1385176 100644
--- a/ncurses/tinfo/write_entry.c
+++ b/ncurses/tinfo/write_entry.c
@@ -1,5 +1,6 @@
/****************************************************************************
- * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. *
+ * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 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 *
@@ -43,38 +44,62 @@
#if 1
#define TRACE_OUT(p) DEBUG(2, p)
+#define TRACE_NUM(n) if (VALID_NUMERIC(Numbers[n])) { \
+ TRACE_OUT(("put Numbers[%u]=%d", (unsigned) (n), Numbers[n])); }
#else
#define TRACE_OUT(p) /*nothing */
+#define TRACE_NUM(n) /* nothing */
#endif
-MODULE_ID("$Id: write_entry.c,v 1.92 2014/11/01 14:47:00 tom Exp $")
+MODULE_ID("$Id: write_entry.c,v 1.115 2020/02/02 23:34:34 tom Exp $")
static int total_written;
+static int total_parts;
+static int total_size;
static int make_db_root(const char *);
-static int write_object(TERMTYPE *, char *, unsigned *, unsigned);
#if !USE_HASHED_DB
static void
-write_file(char *filename, TERMTYPE *tp)
+write_file(char *filename, TERMTYPE2 *tp)
{
char buffer[MAX_ENTRY_SIZE];
unsigned limit = sizeof(buffer);
unsigned offset = 0;
- FILE *fp = (_nc_access(filename, W_OK) == 0) ? fopen(filename, "wb") : 0;
- if (fp == 0) {
- perror(filename);
- _nc_syserr_abort("can't open %s/%s", _nc_tic_dir(0), filename);
- }
- DEBUG(1, ("Created %s", filename));
+ if (_nc_write_object(tp, buffer, &offset, limit) == ERR) {
+ _nc_warning("entry is larger than %u bytes", limit);
+ } else {
+ FILE *fp = ((_nc_access(filename, W_OK) == 0)
+ ? fopen(filename, BIN_W)
+ : 0);
+ size_t actual;
+
+ if (fp == 0) {
+ perror(filename);
+ _nc_syserr_abort("can't open %s/%s", _nc_tic_dir(0), filename);
+ }
- if (write_object(tp, buffer, &offset, limit) == ERR
- || fwrite(buffer, sizeof(char), (size_t) offset, fp) != offset) {
- _nc_syserr_abort("error writing %s/%s", _nc_tic_dir(0), filename);
+ actual = fwrite(buffer, sizeof(char), (size_t) offset, fp);
+ if (actual != offset) {
+ int myerr = ferror(fp) ? errno : 0;
+ if (myerr) {
+ _nc_syserr_abort("error writing %s/%s: %s",
+ _nc_tic_dir(0),
+ filename,
+ strerror(myerr));
+ } else {
+ _nc_syserr_abort("error writing %s/%s: %u bytes vs actual %lu",
+ _nc_tic_dir(0),
+ filename,
+ offset,
+ (unsigned long) actual);
+ }
+ } else {
+ fclose(fp);
+ DEBUG(1, ("Created %s", filename));
+ }
}
-
- fclose(fp);
}
/*
@@ -167,7 +192,7 @@ make_db_root(const char *path)
if ((rc = stat(path, &statbuf)) < 0) {
rc = mkdir(path
-#if !defined(__MINGW32__)
+#if !defined(_WIN32)
,0777
#endif
);
@@ -247,7 +272,7 @@ _nc_set_writedir(const char *dir)
*/
NCURSES_EXPORT(void)
-_nc_write_entry(TERMTYPE *const tp)
+_nc_write_entry(TERMTYPE2 *const tp)
{
#if USE_HASHED_DB
@@ -268,6 +293,9 @@ _nc_write_entry(TERMTYPE *const tp)
#endif
#endif /* USE_SYMLINKS */
+ unsigned limit2 = sizeof(filename) - (2 + LEAF_LEN);
+ char saved = '\0';
+
static int call_count;
static time_t start_time; /* time at start of writes */
@@ -316,7 +344,7 @@ _nc_write_entry(TERMTYPE *const tp)
_nc_set_type(first_name);
#if USE_HASHED_DB
- if (write_object(tp, buffer + 1, &offset, limit - 1) != ERR) {
+ if (_nc_write_object(tp, buffer + 1, &offset, limit - 1) != ERR) {
DB *capdb = _nc_db_open(_nc_tic_dir(0), TRUE);
DBT key, data;
@@ -343,6 +371,8 @@ _nc_write_entry(TERMTYPE *const tp)
sizeof(buffer) - 1);
data.size = name_size + 1;
+ total_size += data.size;
+ total_parts++;
_nc_db_put(capdb, &key, &data);
while (*other_names != '\0') {
@@ -357,6 +387,8 @@ _nc_write_entry(TERMTYPE *const tp)
key.data = ptr;
key.size = strlen(ptr);
+ total_size += data.size;
+ total_parts++;
_nc_db_put(capdb, &key, &data);
}
}
@@ -366,11 +398,19 @@ _nc_write_entry(TERMTYPE *const tp)
start_time = 0;
}
- if (strlen(first_name) >= sizeof(filename) - (2 + LEAF_LEN))
+ if (strlen(first_name) >= limit2) {
_nc_warning("terminal name too long.");
+ saved = first_name[limit2];
+ first_name[limit2] = '\0';
+ }
_nc_SPRINTF(filename, _nc_SLIMIT(sizeof(filename))
- LEAF_FMT "/%s", first_name[0], first_name);
+ LEAF_FMT "/%.*s", UChar(first_name[0]),
+ (int) (sizeof(filename) - (LEAF_LEN + 2)),
+ first_name);
+
+ if (saved)
+ first_name[limit2] = saved;
/*
* Has this primary name been written since the first call to
@@ -427,7 +467,8 @@ _nc_write_entry(TERMTYPE *const tp)
check_writeable(ptr[0]);
_nc_SPRINTF(linkname, _nc_SLIMIT(sizeof(linkname))
- LEAF_FMT "/%s", ptr[0], ptr);
+ LEAF_FMT "/%.*s", ptr[0],
+ (int) sizeof(linkname) - (2 + LEAF_LEN), ptr);
if (strcmp(filename, linkname) == 0) {
_nc_warning("self-synonym ignored");
@@ -439,13 +480,14 @@ _nc_write_entry(TERMTYPE *const tp)
{
int code;
#if USE_SYMLINKS
- 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);
+#define MY_SIZE sizeof(symlinkname) - 1
+ if (first_name[0] == linkname[0]) {
+ _nc_STRNCPY(symlinkname, first_name, MY_SIZE);
+ } else {
+ _nc_STRCPY(symlinkname, "../", sizeof(symlinkname));
+ _nc_STRNCPY(symlinkname + 3, filename, MY_SIZE - 3);
}
- symlinkname[sizeof(symlinkname) - 1] = '\0';
+ symlinkname[MY_SIZE] = '\0';
#endif /* USE_SYMLINKS */
#if HAVE_REMOVE
code = remove(linkname);
@@ -542,7 +584,7 @@ compute_offsets(char **Strings, size_t strmax, short *offsets)
return nextfree;
}
-static void
+static size_t
convert_shorts(unsigned char *buf, short *Numbers, size_t count)
{
size_t i;
@@ -557,14 +599,49 @@ convert_shorts(unsigned char *buf, short *Numbers, size_t count)
TRACE_OUT(("put Numbers[%u]=%d", (unsigned) i, Numbers[i]));
}
}
+ return SIZEOF_SHORT;
+}
+
+#if NCURSES_EXT_NUMBERS
+static size_t
+convert_16bit(unsigned char *buf, NCURSES_INT2 *Numbers, size_t count)
+{
+ size_t i, j;
+ size_t size = SIZEOF_SHORT;
+ for (i = 0; i < count; i++) {
+ unsigned value = (unsigned) Numbers[i];
+ TRACE_NUM(i);
+ for (j = 0; j < size; ++j) {
+ *buf++ = value & 0xff;
+ value >>= 8;
+ }
+ }
+ return size;
}
+static size_t
+convert_32bit(unsigned char *buf, NCURSES_INT2 *Numbers, size_t count)
+{
+ size_t i, j;
+ size_t size = SIZEOF_INT2;
+ for (i = 0; i < count; i++) {
+ unsigned value = (unsigned) Numbers[i];
+ TRACE_NUM(i);
+ for (j = 0; j < size; ++j) {
+ *buf++ = value & 0xff;
+ value >>= 8;
+ }
+ }
+ return size;
+}
+#endif
+
#define even_boundary(value) \
((value) % 2 != 0 && Write(&zero, sizeof(char), 1) != 1)
#if NCURSES_XNAMES
static unsigned
-extended_Booleans(TERMTYPE *tp)
+extended_Booleans(TERMTYPE2 *tp)
{
unsigned result = 0;
unsigned i;
@@ -577,7 +654,7 @@ extended_Booleans(TERMTYPE *tp)
}
static unsigned
-extended_Numbers(TERMTYPE *tp)
+extended_Numbers(TERMTYPE2 *tp)
{
unsigned result = 0;
unsigned i;
@@ -590,7 +667,7 @@ extended_Numbers(TERMTYPE *tp)
}
static unsigned
-extended_Strings(TERMTYPE *tp)
+extended_Strings(TERMTYPE2 *tp)
{
unsigned short result = 0;
unsigned short i;
@@ -607,7 +684,7 @@ extended_Strings(TERMTYPE *tp)
* clause - discard the unneeded data.
*/
static bool
-extended_object(TERMTYPE *tp)
+extended_object(TERMTYPE2 *tp)
{
bool result = FALSE;
@@ -620,11 +697,11 @@ extended_object(TERMTYPE *tp)
}
#endif
-static int
-write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
+NCURSES_EXPORT(int)
+_nc_write_object(TERMTYPE2 *tp, char *buffer, unsigned *offset, unsigned limit)
{
char *namelist;
- size_t namelen, boolmax, nummax, strmax;
+ size_t namelen, boolmax, nummax, strmax, numlen;
char zero = '\0';
size_t i;
int nextfree;
@@ -633,6 +710,12 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
unsigned last_bool = BOOLWRITE;
unsigned last_num = NUMWRITE;
unsigned last_str = STRWRITE;
+#if NCURSES_EXT_NUMBERS
+ bool need_ints = FALSE;
+ size_t (*convert_numbers) (unsigned char *, NCURSES_INT2 *, size_t) = convert_32bit;
+#else
+#define convert_numbers convert_shorts
+#endif
#if NCURSES_XNAMES
/*
@@ -653,14 +736,21 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
boolmax = 0;
for (i = 0; i < last_bool; i++) {
- if (tp->Booleans[i] == TRUE)
+ if (tp->Booleans[i] == TRUE) {
boolmax = i + 1;
+ }
}
nummax = 0;
for (i = 0; i < last_num; i++) {
- if (tp->Numbers[i] != ABSENT_NUMERIC)
+ if (tp->Numbers[i] != ABSENT_NUMERIC) {
nummax = i + 1;
+#if NCURSES_EXT_NUMBERS
+ if (tp->Numbers[i] > MAX_OF_TYPE(NCURSES_COLOR_T)) {
+ need_ints = TRUE;
+ }
+#endif
+ }
}
strmax = 0;
@@ -672,7 +762,17 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
nextfree = compute_offsets(tp->Strings, strmax, offsets);
/* fill in the header */
+#if NCURSES_EXT_NUMBERS
+ if (need_ints) {
+ convert_numbers = convert_32bit;
+ LITTLE_ENDIAN(buf, MAGIC2);
+ } else {
+ convert_numbers = convert_16bit;
+ LITTLE_ENDIAN(buf, MAGIC);
+ }
+#else
LITTLE_ENDIAN(buf, MAGIC);
+#endif
LITTLE_ENDIAN(buf + 2, min(namelen, MAX_NAME_SIZE + 1));
LITTLE_ENDIAN(buf + 4, boolmax);
LITTLE_ENDIAN(buf + 6, nummax);
@@ -682,62 +782,81 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
/* write out the header */
TRACE_OUT(("Header of %s @%d", namelist, *offset));
if (Write(buf, 12, 1) != 1
- || Write(namelist, sizeof(char), namelen) != namelen)
- return (ERR);
+ || Write(namelist, sizeof(char), namelen) != namelen) {
+ return (ERR);
+ }
- for (i = 0; i < boolmax; i++)
- if (tp->Booleans[i] == TRUE)
+ for (i = 0; i < boolmax; i++) {
+ if (tp->Booleans[i] == TRUE) {
buf[i] = TRUE;
- else
+ } else {
buf[i] = FALSE;
- if (Write(buf, sizeof(char), boolmax) != boolmax)
- return (ERR);
+ }
+ }
+ if (Write(buf, sizeof(char), boolmax) != boolmax) {
+ return (ERR);
+ }
- if (even_boundary(namelen + boolmax))
+ if (even_boundary(namelen + boolmax)) {
return (ERR);
+ }
TRACE_OUT(("Numerics begin at %04x", *offset));
/* the numerics */
- convert_shorts(buf, tp->Numbers, nummax);
- if (Write(buf, 2, nummax) != nummax)
+ numlen = convert_numbers(buf, tp->Numbers, nummax);
+ if (Write(buf, numlen, nummax) != nummax) {
return (ERR);
+ }
TRACE_OUT(("String offsets begin at %04x", *offset));
/* the string offsets */
convert_shorts(buf, offsets, strmax);
- if (Write(buf, 2, strmax) != strmax)
+ if (Write(buf, SIZEOF_SHORT, strmax) != strmax) {
return (ERR);
+ }
TRACE_OUT(("String table begins at %04x", *offset));
/* the strings */
- for (i = 0; i < strmax; i++)
- if (VALID_STRING(tp->Strings[i]))
- if (!WRITE_STRING(tp->Strings[i]))
+ for (i = 0; i < strmax; i++) {
+ if (VALID_STRING(tp->Strings[i])) {
+ if (!WRITE_STRING(tp->Strings[i])) {
return (ERR);
+ }
+ }
+ }
#if NCURSES_XNAMES
if (extended_object(tp)) {
- unsigned extcnt = (unsigned) NUM_EXT_NAMES(tp);
+ unsigned ext_total = (unsigned) NUM_EXT_NAMES(tp);
+ unsigned ext_usage = ext_total;
- if (even_boundary(nextfree))
+ if (even_boundary(nextfree)) {
return (ERR);
+ }
nextfree = compute_offsets(tp->Strings + STRCOUNT,
(size_t) tp->ext_Strings,
offsets);
TRACE_OUT(("after extended string capabilities, nextfree=%d", nextfree));
- if (tp->ext_Strings >= SIZEOF(offsets))
+ if (tp->ext_Strings >= SIZEOF(offsets)) {
return (ERR);
+ }
nextfree += compute_offsets(tp->ext_Names,
- (size_t) extcnt,
+ (size_t) ext_total,
offsets + tp->ext_Strings);
TRACE_OUT(("after extended capnames, nextfree=%d", nextfree));
- strmax = tp->ext_Strings + extcnt;
+ strmax = tp->ext_Strings + ext_total;
+ for (i = 0; i < tp->ext_Strings; ++i) {
+ if (VALID_STRING(tp->Strings[i + STRCOUNT])) {
+ ext_usage++;
+ }
+ }
+ TRACE_OUT(("will write %u/%lu strings", ext_usage, (unsigned long) strmax));
/*
* Write the extended header
@@ -745,26 +864,30 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
LITTLE_ENDIAN(buf + 0, tp->ext_Booleans);
LITTLE_ENDIAN(buf + 2, tp->ext_Numbers);
LITTLE_ENDIAN(buf + 4, tp->ext_Strings);
- LITTLE_ENDIAN(buf + 6, strmax);
+ LITTLE_ENDIAN(buf + 6, ext_usage);
LITTLE_ENDIAN(buf + 8, nextfree);
TRACE_OUT(("WRITE extended-header @%d", *offset));
- if (Write(buf, 10, 1) != 1)
+ if (Write(buf, 10, 1) != 1) {
return (ERR);
+ }
TRACE_OUT(("WRITE %d booleans @%d", tp->ext_Booleans, *offset));
if (tp->ext_Booleans
&& Write(tp->Booleans + BOOLCOUNT, sizeof(char),
- tp->ext_Booleans) != tp->ext_Booleans)
- return (ERR);
+ tp->ext_Booleans) != tp->ext_Booleans) {
+ return (ERR);
+ }
- if (even_boundary(tp->ext_Booleans))
+ if (even_boundary(tp->ext_Booleans)) {
return (ERR);
+ }
TRACE_OUT(("WRITE %d numbers @%d", tp->ext_Numbers, *offset));
if (tp->ext_Numbers) {
- convert_shorts(buf, tp->Numbers + NUMCOUNT, (size_t) tp->ext_Numbers);
- if (Write(buf, 2, tp->ext_Numbers) != tp->ext_Numbers)
+ numlen = convert_numbers(buf, tp->Numbers + NUMCOUNT, (size_t) tp->ext_Numbers);
+ if (Write(buf, numlen, tp->ext_Numbers) != tp->ext_Numbers) {
return (ERR);
+ }
}
/*
@@ -773,8 +896,9 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
*/
convert_shorts(buf, offsets, strmax);
TRACE_OUT(("WRITE offsets @%d", *offset));
- if (Write(buf, 2, strmax) != strmax)
+ if (Write(buf, SIZEOF_SHORT, strmax) != strmax) {
return (ERR);
+ }
/*
* Write the string table after the offset tables so we do not
@@ -784,24 +908,28 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
if (VALID_STRING(tp->Strings[i + STRCOUNT])) {
TRACE_OUT(("WRITE ext_Strings[%d]=%s", (int) i,
_nc_visbuf(tp->Strings[i + STRCOUNT])));
- if (!WRITE_STRING(tp->Strings[i + STRCOUNT]))
+ if (!WRITE_STRING(tp->Strings[i + STRCOUNT])) {
return (ERR);
+ }
}
}
/*
* Write the extended names
*/
- for (i = 0; i < extcnt; i++) {
+ for (i = 0; i < ext_total; i++) {
TRACE_OUT(("WRITE ext_Names[%d]=%s", (int) i, tp->ext_Names[i]));
- if (!WRITE_STRING(tp->ext_Names[i]))
+ if (!WRITE_STRING(tp->ext_Names[i])) {
return (ERR);
+ }
}
}
#endif /* NCURSES_XNAMES */
total_written++;
+ total_parts++;
+ total_size = total_size + (int) (*offset + 1);
return (OK);
}
@@ -811,5 +939,7 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
NCURSES_EXPORT(int)
_nc_tic_written(void)
{
+ TR(TRACE_DATABASE, ("_nc_tic_written %d entries, %d parts, %d size",
+ total_written, total_parts, total_size));
return total_written;
}