summaryrefslogtreecommitdiff
path: root/lib/libcurses/tinfo
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libcurses/tinfo')
-rw-r--r--lib/libcurses/tinfo/MKcaptab.awk161
-rw-r--r--lib/libcurses/tinfo/MKcaptab.sh150
-rw-r--r--lib/libcurses/tinfo/MKcodes.awk165
-rw-r--r--lib/libcurses/tinfo/MKfallback.sh32
-rw-r--r--lib/libcurses/tinfo/MKkeys_list.sh63
-rw-r--r--lib/libcurses/tinfo/MKnames.awk256
-rw-r--r--lib/libcurses/tinfo/access.c114
-rw-r--r--lib/libcurses/tinfo/add_tries.c41
-rw-r--r--lib/libcurses/tinfo/alloc_entry.c182
-rw-r--r--lib/libcurses/tinfo/alloc_ttype.c61
-rw-r--r--lib/libcurses/tinfo/captoinfo.c85
-rw-r--r--lib/libcurses/tinfo/comp_error.c53
-rw-r--r--lib/libcurses/tinfo/comp_expand.c37
-rw-r--r--lib/libcurses/tinfo/comp_hash.c398
-rw-r--r--lib/libcurses/tinfo/comp_parse.c214
-rw-r--r--lib/libcurses/tinfo/comp_scan.c619
-rw-r--r--lib/libcurses/tinfo/db_iterator.c227
-rw-r--r--lib/libcurses/tinfo/doalloc.c8
-rw-r--r--lib/libcurses/tinfo/entries.c147
-rw-r--r--lib/libcurses/tinfo/free_ttype.c17
-rw-r--r--lib/libcurses/tinfo/getenv_num.c4
-rw-r--r--lib/libcurses/tinfo/hashed_db.c262
-rw-r--r--lib/libcurses/tinfo/home_terminfo.c34
-rw-r--r--lib/libcurses/tinfo/init_keytry.c65
-rw-r--r--lib/libcurses/tinfo/keys.list159
-rw-r--r--lib/libcurses/tinfo/lib_acs.c195
-rw-r--r--lib/libcurses/tinfo/lib_baudrate.c82
-rw-r--r--lib/libcurses/tinfo/lib_cur_term.c55
-rw-r--r--lib/libcurses/tinfo/lib_data.c265
-rw-r--r--lib/libcurses/tinfo/lib_has_cap.c7
-rw-r--r--lib/libcurses/tinfo/lib_kernel.c46
-rw-r--r--lib/libcurses/tinfo/lib_longname.c4
-rw-r--r--lib/libcurses/tinfo/lib_napms.c45
-rw-r--r--lib/libcurses/tinfo/lib_options.c210
-rw-r--r--lib/libcurses/tinfo/lib_print.c12
-rw-r--r--lib/libcurses/tinfo/lib_raw.c236
-rw-r--r--lib/libcurses/tinfo/lib_setup.c489
-rw-r--r--lib/libcurses/tinfo/lib_termcap.c154
-rw-r--r--lib/libcurses/tinfo/lib_termname.c21
-rw-r--r--lib/libcurses/tinfo/lib_tgoto.c25
-rw-r--r--lib/libcurses/tinfo/lib_ti.c12
-rw-r--r--lib/libcurses/tinfo/lib_tparm.c592
-rw-r--r--lib/libcurses/tinfo/lib_tputs.c131
-rw-r--r--lib/libcurses/tinfo/lib_ttyflags.c164
-rw-r--r--lib/libcurses/tinfo/make_keys.c28
-rw-r--r--lib/libcurses/tinfo/name_match.c40
-rw-r--r--lib/libcurses/tinfo/parse_entry.c120
-rw-r--r--lib/libcurses/tinfo/read_bsd_terminfo.c13
-rw-r--r--lib/libcurses/tinfo/read_entry.c463
-rw-r--r--lib/libcurses/tinfo/read_termcap.c235
-rw-r--r--lib/libcurses/tinfo/setbuf.c60
-rw-r--r--lib/libcurses/tinfo/strings.c27
-rw-r--r--lib/libcurses/tinfo/trim_sgr0.c328
-rw-r--r--lib/libcurses/tinfo/use_screen.c60
-rw-r--r--lib/libcurses/tinfo/write_entry.c417
55 files changed, 5547 insertions, 2543 deletions
diff --git a/lib/libcurses/tinfo/MKcaptab.awk b/lib/libcurses/tinfo/MKcaptab.awk
index 4f5df3afdb2..b105931c55d 100644
--- a/lib/libcurses/tinfo/MKcaptab.awk
+++ b/lib/libcurses/tinfo/MKcaptab.awk
@@ -1,72 +1,95 @@
-#!/bin/sh
-# $OpenBSD: MKcaptab.awk,v 1.3 2001/01/22 18:01:49 millert Exp $
-# $From: MKcaptab.awk,v 1.12 2000/12/10 00:14:12 tom Exp $
-AWK=${1-awk}
-DATA=${2-../include/Caps}
-
-cat <<'EOF'
-/*
- * comp_captab.c -- The names of the capabilities indexed via a hash
- * table for the compiler.
- *
- */
-
-#include <ncurses_cfg.h>
-#include <curses.priv.h>
-#include <tic.h>
-#include <term.h>
-
-EOF
-
-./make_hash 1 info <$DATA
-./make_hash 3 cap <$DATA
-
-cat <<'EOF'
-const struct alias _nc_capalias_table[] =
-{
-EOF
+# $OpenBSD: MKcaptab.awk,v 1.4 2010/01/12 23:22:06 nicm Exp $
+##############################################################################
+# Copyright (c) 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"), #
+# 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: MKcaptab.awk,v 1.4 2010/01/12 23:22:06 nicm Exp $
+function add_string(text) {
+ if (text != "IGNORE") {
+ offsets[num_strings] = offset;
+ offset = offset + length(text) + 1;
+ printf "%s\\0", text;
+ } else {
+ offsets[num_strings] = -1;
+ }
+ num_strings = num_strings + 1;
+ if ((num_strings % 3) == 0) {
+ printf "\\\n";
+ }
+ return offsets[num_strings - 1];
+}
+BEGIN {
+ first = 1;
+ num_aliases = 0;
+ num_strings = 0;
+ offset = 0;
+}
-$AWK <$DATA '
-$1 == "capalias" {
- if ($3 == "IGNORE")
- to = "(char *)NULL";
- else
- to = "\"" $3 "\"";
- printf "\t{\"%s\", %s, \"%s\"},\t /* %s */\n",
- $2, to, $4, $5
+/^[^#]/ {
+ if (first) {
+ printf "/* generated by MKcaptab.awk %s(%d) */\n", tablename, bigstrings;
+ print ""
+ if (bigstrings) {
+ printf "static struct alias *_nc_%s_table = 0;\n", tablename;
+ print "";
+ printf "static const char %s_text[] = \"\\\n", tablename;
+ } else {
+ printf "static const struct alias _nc_%s_table[] =\n", tablename;
+ printf "{\n";
}
-'
-
-cat <<'EOF'
- {(char *)NULL, (char *)NULL, (char *)NULL}
-};
-
-const struct alias _nc_infoalias_table[] =
-{
-EOF
-
-$AWK <$DATA '
-$1 == "infoalias" {
- if ($3 == "IGNORE")
- to = "(char *)NULL";
- else
- to = "\"" $3 "\"";
- printf "\t{\"%s\", %s, \"%s\"},\t /* %s */\n",
- $2, to, $4, $5
+ first = 0;
+ }
+ if ($1 == tablename) {
+ if ($3 == "IGNORE") {
+ to = "(char *)NULL";
+ } else {
+ to = "\"" $3 "\"";
}
-'
-
-cat <<'EOF'
- {(char *)NULL, (char *)NULL, (char *)NULL}
-};
-
-NCURSES_EXPORT(const struct name_table_entry *) _nc_get_table (bool termcap)
-{
- return termcap ? _nc_cap_table: _nc_info_table ;
-}
-
-NCURSES_EXPORT(const struct name_table_entry * const *) _nc_get_hash_table (bool termcap)
-{
- return termcap ? _nc_cap_hash_table: _nc_info_hash_table ;
-}
-EOF
+ if (bigstrings) {
+ c1 = add_string($2);
+ c2 = add_string($3);
+ c3 = add_string($4);
+ aliases[num_aliases] = sprintf("\t{%5d, %5d, %5d},\t /* %s */", c1, c2, c3, $5);
+ num_aliases = num_aliases + 1;
+ } else {
+ printf "\t{\"%s\", %s, \"%s\"},\t /* %s */\n", $2, to, $4, $5;
+ }
+ }
+ }
+END {
+ if (bigstrings) {
+ printf "\";\n\n";
+ printf "static const alias_table_data %s_data[] = {\n", tablename;
+ for (n = 0; n < num_aliases; ++n) {
+ printf "%s\n", aliases[n];
+ }
+ printf "};\n\n";
+ } else {
+ printf "\t{(char *)NULL, (char *)NULL, (char *)NULL}\n";
+ printf "};\n\n";
+ }
+ }
+# vile:sw=4:
diff --git a/lib/libcurses/tinfo/MKcaptab.sh b/lib/libcurses/tinfo/MKcaptab.sh
new file mode 100644
index 00000000000..d7305f2f88e
--- /dev/null
+++ b/lib/libcurses/tinfo/MKcaptab.sh
@@ -0,0 +1,150 @@
+#!/bin/sh
+# $OpenBSD: MKcaptab.sh,v 1.1 2010/01/12 23:22:06 nicm Exp $
+##############################################################################
+# Copyright (c) 2007 Free Software Foundation, Inc. #
+# #
+# Permission is hereby granted, free of charge, to any person obtaining a #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation #
+# the rights to use, copy, modify, merge, publish, distribute, distribute #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the #
+# following conditions: #
+# #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software. #
+# #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
+# DEALINGS IN THE SOFTWARE. #
+# #
+# Except as contained in this notice, the name(s) of the above copyright #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written #
+# authorization. #
+##############################################################################
+# $Id: MKcaptab.sh,v 1.1 2010/01/12 23:22:06 nicm Exp $
+AWK=${1-awk}
+OPT1=${2-0}
+OPT2=${3-tinfo/MKcaptab.awk}
+DATA=${4-../include/Caps}
+
+cat <<'EOF'
+/*
+ * comp_captab.c -- The names of the capabilities indexed via a hash
+ * table for the compiler.
+ *
+ */
+
+#include <curses.priv.h>
+#include <tic.h>
+#include <hashsize.h>
+
+EOF
+
+./make_hash 1 info $OPT1 <$DATA
+./make_hash 3 cap $OPT1 <$DATA
+
+$AWK -f $OPT2 bigstrings=$OPT1 tablename=capalias <$DATA
+
+$AWK -f $OPT2 bigstrings=$OPT1 tablename=infoalias <$DATA
+
+cat <<EOF
+
+#if $OPT1
+static void
+next_string(const char *strings, unsigned *offset)
+{
+ *offset += strlen(strings + *offset) + 1;
+}
+
+static const struct name_table_entry *
+_nc_build_names(struct name_table_entry **actual,
+ const name_table_data *source,
+ const char *strings)
+{
+ if (*actual == 0) {
+ *actual = typeCalloc(struct name_table_entry, CAPTABSIZE);
+ if (*actual != 0) {
+ unsigned n;
+ unsigned len = 0;
+ for (n = 0; n < CAPTABSIZE; ++n) {
+ (*actual)[n].nte_name = strings + len;
+ (*actual)[n].nte_type = source[n].nte_type;
+ (*actual)[n].nte_index = source[n].nte_index;
+ (*actual)[n].nte_link = source[n].nte_link;
+ next_string(strings, &len);
+ }
+ }
+ }
+ return *actual;
+}
+
+#define add_alias(field) \\
+ if (source[n].field >= 0) { \\
+ (*actual)[n].field = strings + source[n].field; \\
+ }
+
+static const struct alias *
+_nc_build_alias(struct alias **actual,
+ const alias_table_data *source,
+ const char *strings,
+ unsigned tablesize)
+{
+ if (*actual == 0) {
+ *actual = typeCalloc(struct alias, tablesize + 1);
+ if (*actual != 0) {
+ unsigned n;
+ for (n = 0; n < tablesize; ++n) {
+ add_alias(from);
+ add_alias(to);
+ add_alias(source);
+ }
+ }
+ }
+ return *actual;
+}
+
+#define build_names(root) _nc_build_names(&_nc_##root##_table, \\
+ root##_names_data, \\
+ root##_names_text)
+#define build_alias(root) _nc_build_alias(&_nc_##root##alias_table, \\
+ root##alias_data, \\
+ root##alias_text, \\
+ SIZEOF(root##alias_data))
+#else
+#define build_names(root) _nc_ ## root ## _table
+#define build_alias(root) _nc_ ## root ## alias_table
+#endif
+
+NCURSES_EXPORT(const struct name_table_entry *) _nc_get_table (bool termcap)
+{
+ return termcap ? build_names(cap) : build_names(info) ;
+}
+
+NCURSES_EXPORT(const short *) _nc_get_hash_table (bool termcap)
+{
+ return termcap ? _nc_cap_hash_table: _nc_info_hash_table ;
+}
+
+NCURSES_EXPORT(const struct alias *) _nc_get_alias_table (bool termcap)
+{
+ return termcap ? build_alias(cap) : build_alias(info) ;
+}
+
+#if NO_LEAKS
+NCURSES_EXPORT(void) _nc_comp_captab_leaks(void)
+{
+#if $OPT1
+ FreeIfNeeded(_nc_cap_table);
+ FreeIfNeeded(_nc_info_table);
+ FreeIfNeeded(_nc_capalias_table);
+ FreeIfNeeded(_nc_infoalias_table);
+#endif
+}
+#endif /* NO_LEAKS */
+EOF
diff --git a/lib/libcurses/tinfo/MKcodes.awk b/lib/libcurses/tinfo/MKcodes.awk
new file mode 100644
index 00000000000..669f673c91b
--- /dev/null
+++ b/lib/libcurses/tinfo/MKcodes.awk
@@ -0,0 +1,165 @@
+# $OpenBSD: MKcodes.awk,v 1.1 2010/01/12 23:22:06 nicm Exp $
+##############################################################################
+# Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. #
+# #
+# Permission is hereby granted, free of charge, to any person obtaining a #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation #
+# the rights to use, copy, modify, merge, publish, distribute, distribute #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the #
+# following conditions: #
+# #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software. #
+# #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
+# DEALINGS IN THE SOFTWARE. #
+# #
+# Except as contained in this notice, the name(s) of the above copyright #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written #
+# authorization. #
+##############################################################################
+# $Id: MKcodes.awk,v 1.1 2010/01/12 23:22:06 nicm Exp $
+function large_item(value) {
+ result = sprintf("%d,", offset);
+ offset = offset + length(value) + 1;
+ offcol = offcol + length(result) + 2;
+ if (offcol > 70) {
+ result = result "\n";
+ offcol = 0;
+ } else {
+ result = result " ";
+ }
+ bigstr = bigstr sprintf("\"%s\\0\" ", value);
+ bigcol = bigcol + length(value) + 5;
+ if (bigcol > 70) {
+ bigstr = bigstr "\\\n";
+ bigcol = 0;
+ }
+ return result;
+}
+
+function small_item(value) {
+ return sprintf("\t\t\"%s\",\n", value);
+}
+
+function print_strings(name,value) {
+ printf "DCL(%s) = {\n", name
+ print value
+ print "\t\t(NCURSES_CONST char *)0,"
+ print "};"
+ print ""
+}
+
+function print_offsets(name,value) {
+ printf "static const short _nc_offset_%s[] = {\n", name
+ printf "%s", value
+ print "};"
+ print ""
+ printf "static NCURSES_CONST char ** ptr_%s = 0;\n", name
+ print ""
+}
+
+BEGIN {
+ print "/* This file was generated by MKcodes.awk */"
+ print ""
+ print "#include <curses.priv.h>"
+ print ""
+ print "#define IT NCURSES_CONST char * const"
+ print ""
+ offset = 0;
+ offcol = 0;
+ bigcol = 0;
+ }
+
+$1 ~ /^#/ {next;}
+
+$1 == "SKIPWARN" {next;}
+
+$3 == "bool" {
+ small_boolcodes = small_boolcodes small_item($4);
+ large_boolcodes = large_boolcodes large_item($4);
+ }
+
+$3 == "num" {
+ small_numcodes = small_numcodes small_item($4);
+ large_numcodes = large_numcodes large_item($4);
+ }
+
+$3 == "str" {
+ small_strcodes = small_strcodes small_item($4);
+ large_strcodes = large_strcodes large_item($4);
+ }
+
+END {
+ print ""
+ print "#if BROKEN_LINKER || USE_REENTRANT"
+ print ""
+ print "#include <term.h>"
+ print ""
+ if (bigstrings) {
+ printf "static const char _nc_code_blob[] = \n"
+ printf "%s;\n", bigstr;
+ print_offsets("boolcodes", large_boolcodes);
+ print_offsets("numcodes", large_numcodes);
+ print_offsets("strcodes", large_strcodes);
+ print ""
+ print "static IT *"
+ print "alloc_array(NCURSES_CONST char ***value, const short *offsets, unsigned size)"
+ print "{"
+ print " if (*value == 0) {"
+ print " if ((*value = typeCalloc(NCURSES_CONST char *, size + 1)) != 0) {"
+ print " unsigned n;"
+ print " for (n = 0; n < size; ++n) {"
+ print " (*value)[n] = _nc_code_blob + offsets[n];"
+ print " }"
+ print " }"
+ print " }"
+ print " return *value;"
+ print "}"
+ print ""
+ print "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return alloc_array(&ptr_##it, _nc_offset_##it, SIZEOF(_nc_offset_##it)); }"
+ } else {
+ print "#define DCL(it) static IT data##it[]"
+ print ""
+ print_strings("boolcodes", small_boolcodes);
+ print_strings("numcodes", small_numcodes);
+ print_strings("strcodes", small_strcodes);
+ print "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return data##it; }"
+ }
+ print ""
+ print "FIX(boolcodes)"
+ print "FIX(numcodes)"
+ print "FIX(strcodes)"
+ print ""
+ print "#define FREE_FIX(it) if (ptr_##it) { FreeAndNull(ptr_##it); }"
+ print ""
+ print "#if NO_LEAKS"
+ print "NCURSES_EXPORT(void)"
+ print "_nc_codes_leaks(void)"
+ print "{"
+ if (bigstrings) {
+ print "FREE_FIX(boolcodes)"
+ print "FREE_FIX(numcodes)"
+ print "FREE_FIX(strcodes)"
+ }
+ print "}"
+ print "#endif"
+ print ""
+ print "#else"
+ print ""
+ print "#define DCL(it) NCURSES_EXPORT_VAR(IT) it[]"
+ print ""
+ print_strings("boolcodes", small_boolcodes);
+ print_strings("numcodes", small_numcodes);
+ print_strings("strcodes", small_strcodes);
+ print ""
+ print "#endif /* BROKEN_LINKER */"
+ }
diff --git a/lib/libcurses/tinfo/MKfallback.sh b/lib/libcurses/tinfo/MKfallback.sh
index ce7d14cb7a4..c33d8489e9f 100644
--- a/lib/libcurses/tinfo/MKfallback.sh
+++ b/lib/libcurses/tinfo/MKfallback.sh
@@ -1,6 +1,33 @@
#!/bin/sh
-# $OpenBSD: MKfallback.sh,v 1.3 2001/01/22 18:01:50 millert Exp $
-# $From: MKfallback.sh,v 1.10 2000/12/10 00:14:39 tom Exp $
+# $OpenBSD: MKfallback.sh,v 1.4 2010/01/12 23:22:06 nicm Exp $
+##############################################################################
+# Copyright (c) 1998-2001,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 "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: MKfallback.sh,v 1.4 2010/01/12 23:22:06 nicm Exp $
#
# MKfallback.sh -- create fallback table for entry reads
#
@@ -9,6 +36,7 @@
# from an on-disk terminfo tree) tries to match the type with one of a
# specified list of types generated in.
#
+
cat <<EOF
/*
* DO NOT EDIT THIS FILE BY HAND! It is generated by MKfallback.sh.
diff --git a/lib/libcurses/tinfo/MKkeys_list.sh b/lib/libcurses/tinfo/MKkeys_list.sh
new file mode 100644
index 00000000000..e28d899fedf
--- /dev/null
+++ b/lib/libcurses/tinfo/MKkeys_list.sh
@@ -0,0 +1,63 @@
+#! /bin/sh
+# $OpenBSD: MKkeys_list.sh,v 1.1 2010/01/12 23:22:06 nicm Exp $
+# $Id: MKkeys_list.sh,v 1.1 2010/01/12 23:22:06 nicm Exp $
+##############################################################################
+# Copyright (c) 2001,2003 Free Software Foundation, Inc. #
+# #
+# Permission is hereby granted, free of charge, to any person obtaining a #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation #
+# the rights to use, copy, modify, merge, publish, distribute, distribute #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the #
+# following conditions: #
+# #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software. #
+# #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
+# DEALINGS IN THE SOFTWARE. #
+# #
+# Except as contained in this notice, the name(s) of the above copyright #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written #
+# authorization. #
+##############################################################################
+#
+# MKkey_defs.sh -- generate list of function-keys for terminfo database
+#
+# Author: Thomas E. Dickey 2001
+#
+# Extract function-key names from the Caps file
+#
+: ${AWK-awk}
+DATA=${1-../../include/Caps}
+
+data=data$$
+trap 'rm -f $data' 0 1 2 5 15
+sed -e 's/[ ][ ]*/ /g' < $DATA >$data
+
+cat <<EOF
+# These definitions were generated by $0 $DATA
+KEY_BREAK
+KEY_SRESET
+KEY_RESET
+KEY_RESIZE
+EOF
+
+${AWK-awk} <$data '
+/^#/ {next;}
+/^capalias/ {next;}
+/^infoalias/ {next;}
+
+$5 != "-" {
+ if (substr($5, 1, 4) == "KEY_" ) {
+ printf "%s %s\n", $5, $1
+ }
+}
+'
diff --git a/lib/libcurses/tinfo/MKnames.awk b/lib/libcurses/tinfo/MKnames.awk
index 5fdb8c20690..64ce6431fb7 100644
--- a/lib/libcurses/tinfo/MKnames.awk
+++ b/lib/libcurses/tinfo/MKnames.awk
@@ -1,99 +1,187 @@
-# $OpenBSD: MKnames.awk,v 1.2 2001/01/22 18:01:50 millert Exp $
-# $From: MKnames.awk,v 1.11 2000/12/09 23:46:13 tom Exp $
-BEGIN {
- print "/* This file was generated by MKnames.awk */" > "namehdr"
- print "" > "namehdr"
- print "#include <curses.priv.h>" > "namehdr"
- print "" > "namehdr"
- print "#define IT NCURSES_CONST char * const" > "namehdr"
- print "" > "namehdr"
- print "#if BROKEN_LINKER" > "namehdr"
- print "#include <term.h>" > "namehdr"
- print "#define DCL(it) static IT data##it[]" > "namehdr"
- print "#else" > "namehdr"
- print "#define DCL(it) NCURSES_EXPORT_VAR(IT) it[]" > "namehdr"
- print "#endif" > "namehdr"
- print "" > "namehdr"
- print "/*" > "boolnames"
- print " * names.c - Arrays of capability names and codes" > "boolnames"
- print " *" > "boolnames"
- print " */" > "boolnames"
- print "" > "boolnames"
- print "DCL(boolnames) = {" > "boolnames"
- print "DCL(boolfnames) = {" > "boolfnames"
- print "DCL(boolcodes) = {" > "boolcodes"
- print "DCL(numnames) = {" > "numnames"
- print "DCL(numfnames) = {" > "numfnames"
- print "DCL(numcodes) = {" > "numcodes"
- print "DCL(strnames) = {" > "strnames"
- print "DCL(strfnames) = {" > "strfnames"
- print "DCL(strcodes) = {" > "strcodes"
- }
+# $OpenBSD: MKnames.awk,v 1.3 2010/01/12 23:22:06 nicm Exp $
+##############################################################################
+# Copyright (c) 2007,2008 Free Software Foundation, Inc. #
+# #
+# Permission is hereby granted, free of charge, to any person obtaining a #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation #
+# the rights to use, copy, modify, merge, publish, distribute, distribute #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the #
+# following conditions: #
+# #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software. #
+# #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
+# DEALINGS IN THE SOFTWARE. #
+# #
+# Except as contained in this notice, the name(s) of the above copyright #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written #
+# authorization. #
+##############################################################################
+# $Id: MKnames.awk,v 1.3 2010/01/12 23:22:06 nicm Exp $
+function large_item(value) {
+ result = sprintf("%d,", offset);
+ offset = offset + length(value) + 1;
+ offcol = offcol + length(result) + 2;
+ if (offcol > 70) {
+ result = result "\n";
+ offcol = 0;
+ } else {
+ result = result " ";
+ }
+ bigstr = bigstr sprintf("\"%s\\0\" ", value);
+ bigcol = bigcol + length(value) + 5;
+ if (bigcol > 70) {
+ bigstr = bigstr "\\\n";
+ bigcol = 0;
+ }
+ return result;
+}
+
+function small_item(value) {
+ return sprintf("\t\t\"%s\",\n", value);
+}
+
+function print_strings(name,value) {
+ printf "DCL(%s) = {\n", name
+ print value
+ print "\t\t(NCURSES_CONST char *)0,"
+ print "};"
+ print ""
+}
+
+function print_offsets(name,value) {
+ printf "static const short _nc_offset_%s[] = {\n", name
+ printf "%s", value
+ print "};"
+ print ""
+ printf "static NCURSES_CONST char ** ptr_%s = 0;\n", name
+ print ""
+}
+
+BEGIN {
+ print "/* This file was generated by MKnames.awk */"
+ print ""
+ print "#include <curses.priv.h>"
+ print ""
+ print "#define IT NCURSES_CONST char * const"
+ print ""
+ offset = 0;
+ offcol = 0;
+ bigcol = 0;
+ }
$1 ~ /^#/ {next;}
$1 == "SKIPWARN" {next;}
$3 == "bool" {
- printf "\t\t\"%s\",\n", $2 > "boolnames"
- printf "\t\t\"%s\",\n", $1 > "boolfnames"
- printf "\t\t\"%s\",\n", $4 > "boolcodes"
+ small_boolnames = small_boolnames small_item($2);
+ large_boolnames = large_boolnames large_item($2);
+ small_boolfnames = small_boolfnames small_item($1);
+ large_boolfnames = large_boolfnames large_item($1);
}
$3 == "num" {
- printf "\t\t\"%s\",\n", $2 > "numnames"
- printf "\t\t\"%s\",\n", $1 > "numfnames"
- printf "\t\t\"%s\",\n", $4 > "numcodes"
+ small_numnames = small_numnames small_item($2);
+ large_numnames = large_numnames large_item($2);
+ small_numfnames = small_numfnames small_item($1);
+ large_numfnames = large_numfnames large_item($1);
}
$3 == "str" {
- printf "\t\t\"%s\",\n", $2 > "strnames"
- printf "\t\t\"%s\",\n", $1 > "strfnames"
- printf "\t\t\"%s\",\n", $4 > "strcodes"
+ small_strnames = small_strnames small_item($2);
+ large_strnames = large_strnames large_item($2);
+ small_strfnames = small_strfnames small_item($1);
+ large_strfnames = large_strfnames large_item($1);
}
-END {
- print "\t\t(NCURSES_CONST char *)0," > "boolnames"
- print "};" > "boolnames"
- print "" > "boolnames"
- print "\t\t(NCURSES_CONST char *)0," > "boolfnames"
- print "};" > "boolfnames"
- print "" > "boolfnames"
- print "\t\t(NCURSES_CONST char *)0," > "boolcodes"
- print "};" > "boolcodes"
- print "" > "boolcodes"
- print "\t\t(NCURSES_CONST char *)0," > "numnames"
- print "};" > "numnames"
- print "" > "numnames"
- print "\t\t(NCURSES_CONST char *)0," > "numfnames"
- print "};" > "numfnames"
- print "" > "numfnames"
- print "\t\t(NCURSES_CONST char *)0," > "numcodes"
- print "};" > "numcodes"
- print "" > "numcodes"
- print "\t\t(NCURSES_CONST char *)0," > "strnames"
- print "};" > "strnames"
- print "" > "strnames"
- print "\t\t(NCURSES_CONST char *)0," > "strfnames"
- print "};" > "strfnames"
- print "" > "strfnames"
- print "\t\t(NCURSES_CONST char *)0," > "strcodes"
- print "};" > "strcodes"
- print "" > "strcodes"
- print "#if BROKEN_LINKER" > "nameftr"
- print "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return data##it; }" > "nameftr"
- print "FIX(boolnames)" > "nameftr"
- print "FIX(boolfnames)" > "nameftr"
- print "FIX(numnames)" > "nameftr"
- print "FIX(numfnames)" > "nameftr"
- print "FIX(strnames)" > "nameftr"
- print "FIX(strfnames)" > "nameftr"
- print "#endif /* BROKEN_LINKER */" > "nameftr"
- print "" > "codeftr"
- print "#if BROKEN_LINKER" > "codeftr"
- print "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return data##it; }" > "codeftr"
- print "FIX(boolcodes)" > "codeftr"
- print "FIX(numcodes)" > "codeftr"
- print "FIX(strcodes)" > "codeftr"
- print "#endif /* BROKEN_LINKER */" > "codeftr"
+END {
+ print ""
+ print "#if BROKEN_LINKER || USE_REENTRANT"
+ print ""
+ print "#include <term.h>"
+ print ""
+ if (bigstrings) {
+ printf "static const char _nc_name_blob[] = \n"
+ printf "%s;\n", bigstr;
+ print_offsets("boolfnames", large_boolfnames);
+ print_offsets("boolnames", large_boolnames);
+ print_offsets("numfnames", large_numfnames);
+ print_offsets("numnames", large_numnames);
+ print_offsets("strfnames", large_strfnames);
+ print_offsets("strnames", large_strnames);
+ print ""
+ print "static IT *"
+ print "alloc_array(NCURSES_CONST char ***value, const short *offsets, unsigned size)"
+ print "{"
+ print " if (*value == 0) {"
+ print " if ((*value = typeCalloc(NCURSES_CONST char *, size + 1)) != 0) {"
+ print " unsigned n;"
+ print " for (n = 0; n < size; ++n) {"
+ print " (*value)[n] = (NCURSES_CONST char *) _nc_name_blob + offsets[n];"
+ print " }"
+ print " }"
+ print " }"
+ print " return *value;"
+ print "}"
+ print ""
+ print "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return alloc_array(&ptr_##it, _nc_offset_##it, SIZEOF(_nc_offset_##it)); }"
+ } else {
+ print "#define DCL(it) static IT data##it[]"
+ print ""
+ print_strings("boolnames", small_boolnames);
+ print_strings("boolfnames", small_boolfnames);
+ print_strings("numnames", small_numnames);
+ print_strings("numfnames", small_numfnames);
+ print_strings("strnames", small_strnames);
+ print_strings("strfnames", small_strfnames);
+ print "#define FIX(it) NCURSES_IMPEXP IT * NCURSES_API _nc_##it(void) { return data##it; }"
+ }
+ print ""
+ print "FIX(boolnames)"
+ print "FIX(boolfnames)"
+ print "FIX(numnames)"
+ print "FIX(numfnames)"
+ print "FIX(strnames)"
+ print "FIX(strfnames)"
+ print ""
+ print ""
+ print "#define FREE_FIX(it) if (ptr_##it) { FreeAndNull(ptr_##it); }"
+ print ""
+ print "#if NO_LEAKS"
+ print "NCURSES_EXPORT(void)"
+ print "_nc_names_leaks(void)"
+ print "{"
+ if (bigstrings) {
+ print "FREE_FIX(boolnames)"
+ print "FREE_FIX(boolfnames)"
+ print "FREE_FIX(numnames)"
+ print "FREE_FIX(numfnames)"
+ print "FREE_FIX(strnames)"
+ print "FREE_FIX(strfnames)"
}
+ print "}"
+ print "#endif"
+ print ""
+ print "#else"
+ print ""
+ print "#define DCL(it) NCURSES_EXPORT_VAR(IT) it[]"
+ print ""
+ print_strings("boolnames", small_boolnames);
+ print_strings("boolfnames", small_boolfnames);
+ print_strings("numnames", small_numnames);
+ print_strings("numfnames", small_numfnames);
+ print_strings("strnames", small_strnames);
+ print_strings("strfnames", small_strfnames);
+ print ""
+ print "#endif /* BROKEN_LINKER */"
+ }
diff --git a/lib/libcurses/tinfo/access.c b/lib/libcurses/tinfo/access.c
index a4a184e699c..0ea39c1106c 100644
--- a/lib/libcurses/tinfo/access.c
+++ b/lib/libcurses/tinfo/access.c
@@ -1,5 +1,7 @@
+/* $OpenBSD: access.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
+
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 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 *
@@ -27,27 +29,83 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1998,2000 *
+ * Author: Thomas E. Dickey *
****************************************************************************/
#include <curses.priv.h>
+
+#include <ctype.h>
+#include <sys/stat.h>
+
#include <tic.h>
+#include <nc_alloc.h>
-MODULE_ID("$From: access.c,v 1.7 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: access.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
+
+#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
NCURSES_EXPORT(char *)
-_nc_basename(char *path)
+_nc_rootname(char *path)
{
- char *result = strrchr(path, '/');
+ char *result = _nc_basename(path);
+#if !MIXEDCASE_FILENAMES || defined(PROG_EXT)
+ static char *temp;
+ char *s;
+
+ temp = strdup(result);
+ result = temp;
+#if !MIXEDCASE_FILENAMES
+ for (s = result; *s != '\0'; ++s) {
+ *s = LOWERCASE(*s);
+ }
+#endif
+#if defined(PROG_EXT)
+ if ((s = strrchr(result, '.')) != 0) {
+ if (!strcmp(s, PROG_EXT))
+ *s = '\0';
+ }
+#endif
+#endif
+ return result;
+}
+
+/*
+ * Check if a string appears to be an absolute pathname.
+ */
+NCURSES_EXPORT(bool)
+_nc_is_abs_path(const char *path)
+{
+#if defined(__EMX__) || defined(__DJGPP__)
+#define is_pathname(s) ((((s) != 0) && ((s)[0] == '/')) \
+ || (((s)[0] != 0) && ((s)[1] == ':')))
+#else
+#define is_pathname(s) ((s) != 0 && (s)[0] == '/')
+#endif
+ return is_pathname(path);
+}
+
+/*
+ * Return index of the basename
+ */
+NCURSES_EXPORT(unsigned)
+_nc_pathlast(const char *path)
+{
+ const char *test = strrchr(path, '/');
#ifdef __EMX__
- if (result == 0)
- result = strrchr(path, '\\');
+ if (test == 0)
+ test = strrchr(path, '\\');
#endif
- if (result == 0)
- result = path;
+ if (test == 0)
+ test = path;
else
- result++;
- return result;
+ test++;
+ return (test - path);
+}
+
+NCURSES_EXPORT(char *)
+_nc_basename(char *path)
+{
+ return path + _nc_pathlast(path);
}
NCURSES_EXPORT(int)
@@ -59,10 +117,10 @@ _nc_access(const char *path, int mode)
&& strlen(path) < PATH_MAX) {
char *leaf, head[PATH_MAX];
- strlcpy(head, path, sizeof(head));
- if ((leaf = _nc_basename(head)) == 0)
- leaf = head;
- *leaf = '\0';
+ strlcpy(head, path, sizeof(head));
+ if ((leaf = _nc_basename(head)) == 0)
+ leaf = head;
+ *leaf = '\0';
if (head == leaf)
(void) strlcpy(head, ".", sizeof(head));
@@ -73,6 +131,32 @@ _nc_access(const char *path, int mode)
return 0;
}
+NCURSES_EXPORT(bool)
+_nc_is_dir_path(const char *path)
+{
+ bool result = FALSE;
+ struct stat sb;
+
+ if (stat(path, &sb) == 0
+ && (sb.st_mode & S_IFMT) == S_IFDIR) {
+ result = TRUE;
+ }
+ return result;
+}
+
+NCURSES_EXPORT(bool)
+_nc_is_file_path(const char *path)
+{
+ bool result = FALSE;
+ struct stat sb;
+
+ if (stat(path, &sb) == 0
+ && (sb.st_mode & S_IFMT) == S_IFREG) {
+ result = TRUE;
+ }
+ return result;
+}
+
#ifndef USE_ROOT_ENVIRON
/*
* Returns true if we allow application to use environment variables that are
diff --git a/lib/libcurses/tinfo/add_tries.c b/lib/libcurses/tinfo/add_tries.c
index 55ad69543d5..247087fd815 100644
--- a/lib/libcurses/tinfo/add_tries.c
+++ b/lib/libcurses/tinfo/add_tries.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: add_tries.c,v 1.3 2001/01/22 18:01:50 millert Exp $ */
+/* $OpenBSD: add_tries.c,v 1.4 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2005,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 *
@@ -29,7 +29,7 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1998 *
+ * Author: Thomas E. Dickey 1998-on *
****************************************************************************/
/*
@@ -41,20 +41,20 @@
#include <curses.priv.h>
-MODULE_ID("$From: add_tries.c,v 1.4 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: add_tries.c,v 1.4 2010/01/12 23:22:06 nicm Exp $")
#define SET_TRY(dst,src) if ((dst->ch = *src++) == 128) dst->ch = '\0'
#define CMP_TRY(a,b) ((a)? (a == b) : (b == 128))
-NCURSES_EXPORT(void)
-_nc_add_to_try(struct tries **tree, const char *str, unsigned short code)
+NCURSES_EXPORT(int)
+_nc_add_to_try(TRIES ** tree, const char *str, unsigned code)
{
- static bool out_of_memory = FALSE;
- struct tries *ptr, *savedptr;
+ TRIES *ptr, *savedptr;
unsigned const char *txt = (unsigned const char *) str;
- if (txt == 0 || *txt == '\0' || out_of_memory || code == 0)
- return;
+ T((T_CALLED("_nc_add_to_try(%p, %s, %u)"), *tree, _nc_visbuf(str), code));
+ if (txt == 0 || *txt == '\0' || code == 0)
+ returnCode(ERR);
if ((*tree) != 0) {
ptr = savedptr = (*tree);
@@ -69,16 +69,15 @@ _nc_add_to_try(struct tries **tree, const char *str, unsigned short code)
if (CMP_TRY(ptr->ch, cmp)) {
if (*(++txt) == '\0') {
ptr->value = code;
- return;
+ returnCode(OK);
}
if (ptr->child != 0)
ptr = ptr->child;
else
break;
} else {
- if ((ptr->sibling = typeCalloc(struct tries, 1)) == 0) {
- out_of_memory = TRUE;
- return;
+ if ((ptr->sibling = typeCalloc(TRIES, 1)) == 0) {
+ returnCode(ERR);
}
savedptr = ptr = ptr->sibling;
@@ -89,11 +88,10 @@ _nc_add_to_try(struct tries **tree, const char *str, unsigned short code)
}
} /* end for (;;) */
} else { /* (*tree) == 0 :: First sequence to be added */
- savedptr = ptr = (*tree) = typeCalloc(struct tries, 1);
+ savedptr = ptr = (*tree) = typeCalloc(TRIES, 1);
if (ptr == 0) {
- out_of_memory = TRUE;
- return;
+ returnCode(ERR);
}
SET_TRY(ptr, txt);
@@ -103,19 +101,16 @@ _nc_add_to_try(struct tries **tree, const char *str, unsigned short code)
/* at this point, we are adding to the try. ptr->child == 0 */
while (*txt) {
- ptr->child = typeCalloc(struct tries, 1);
+ ptr->child = typeCalloc(TRIES, 1);
ptr = ptr->child;
if (ptr == 0) {
- out_of_memory = TRUE;
-
while ((ptr = savedptr) != 0) {
savedptr = ptr->child;
free(ptr);
}
-
- return;
+ returnCode(ERR);
}
SET_TRY(ptr, txt);
@@ -123,5 +118,5 @@ _nc_add_to_try(struct tries **tree, const char *str, unsigned short code)
}
ptr->value = code;
- return;
+ returnCode(OK);
}
diff --git a/lib/libcurses/tinfo/alloc_entry.c b/lib/libcurses/tinfo/alloc_entry.c
index b0bab761de8..c0861482018 100644
--- a/lib/libcurses/tinfo/alloc_entry.c
+++ b/lib/libcurses/tinfo/alloc_entry.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: alloc_entry.c,v 1.5 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: alloc_entry.c,v 1.6 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -49,21 +50,31 @@
#include <tic.h>
#include <term_entry.h>
-MODULE_ID("$From: alloc_entry.c,v 1.35 2001/01/13 22:40:17 tom Exp $")
+MODULE_ID("$Id: alloc_entry.c,v 1.6 2010/01/12 23:22:06 nicm Exp $")
#define ABSENT_OFFSET -1
#define CANCELLED_OFFSET -2
#define MAX_STRTAB 4096 /* documented maximum entry size */
-static char stringbuf[MAX_STRTAB]; /* buffer for string capabilities */
+static 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(TERMTYPE *const tp)
/* initialize a terminal type data block */
{
- int i;
+ unsigned i;
+
+#if NO_LEAKS
+ if (tp == 0 && stringbuf != 0) {
+ FreeAndNull(stringbuf);
+ return;
+ }
+#endif
+
+ if (stringbuf == 0)
+ stringbuf = (char *) malloc(MAX_STRTAB);
#if NCURSES_XNAMES
tp->num_Booleans = BOOLCOUNT;
@@ -74,7 +85,7 @@ _nc_init_entry(TERMTYPE * const tp)
tp->ext_Strings = 0;
#endif
if (tp->Booleans == 0)
- tp->Booleans = typeMalloc(char, BOOLCOUNT);
+ tp->Booleans = typeMalloc(NCURSES_SBOOL, BOOLCOUNT);
if (tp->Numbers == 0)
tp->Numbers = typeMalloc(short, NUMCOUNT);
if (tp->Strings == 0)
@@ -104,28 +115,42 @@ _nc_copy_entry(ENTRY * oldp)
return newp;
}
+/* save a copy of string in the string buffer */
NCURSES_EXPORT(char *)
_nc_save_str(const char *const string)
-/* save a copy of string in the string buffer */
{
+ char *result = 0;
size_t old_next_free = next_free;
- size_t len;
-
- len = strlcpy(stringbuf + next_free, string, sizeof(stringbuf) - next_free);
- if (++len < sizeof(stringbuf) - next_free) {
+ size_t len = strlen(string) + 1;
+
+ if (len == 1 && next_free != 0) {
+ /*
+ * Cheat a little by making an empty string point to the end of the
+ * previous string.
+ */
+ if (next_free < MAX_STRTAB) {
+ result = (stringbuf + next_free - 1);
+ }
+ } else if (next_free + len < MAX_STRTAB) {
+ strlcpy(&stringbuf[next_free], string, MAX_STRTAB - next_free);
DEBUG(7, ("Saved string %s", _nc_visbuf(string)));
DEBUG(7, ("at location %d", (int) next_free));
next_free += len;
+ result = (stringbuf + old_next_free);
+ } else {
+ _nc_warning("Too much data, some is lost");
}
- return (stringbuf + old_next_free);
+ return result;
}
NCURSES_EXPORT(void)
_nc_wrap_entry(ENTRY * const ep, bool copy_strings)
/* copy the string parts to allocated storage, preserving pointers to it */
{
- int offsets[MAX_ENTRY_SIZE / 2], useoffsets[MAX_USES];
- int i, n;
+ int offsets[MAX_ENTRY_SIZE / sizeof(short)];
+ int useoffsets[MAX_USES];
+ unsigned i, n;
+ unsigned nuses = ep->nuses;
TERMTYPE *tp = &(ep->tterm);
if (copy_strings) {
@@ -140,7 +165,7 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
}
}
- for (i = 0; i < ep->nuses; i++) {
+ for (i = 0; i < nuses; i++) {
if (ep->uses[i].name == 0) {
ep->uses[i].name = _nc_save_str(ep->uses[i].name);
}
@@ -149,17 +174,21 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
free(tp->str_table);
}
- n = tp->term_names - stringbuf;
+ assert(tp->term_names >= stringbuf);
+ n = (unsigned) (tp->term_names - stringbuf);
for_each_string(i, &(ep->tterm)) {
- if (tp->Strings[i] == ABSENT_STRING)
- offsets[i] = ABSENT_OFFSET;
- else if (tp->Strings[i] == CANCELLED_STRING)
- offsets[i] = CANCELLED_OFFSET;
- else
- offsets[i] = tp->Strings[i] - stringbuf;
+ if (i < SIZEOF(offsets)) {
+ if (tp->Strings[i] == ABSENT_STRING) {
+ offsets[i] = ABSENT_OFFSET;
+ } else if (tp->Strings[i] == CANCELLED_STRING) {
+ offsets[i] = CANCELLED_OFFSET;
+ } else {
+ offsets[i] = tp->Strings[i] - stringbuf;
+ }
+ }
}
- for (i = 0; i < ep->nuses; i++) {
+ for (i = 0; i < nuses; i++) {
if (ep->uses[i].name == 0)
useoffsets[i] = ABSENT_OFFSET;
else
@@ -167,43 +196,48 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
}
if ((tp->str_table = typeMalloc(char, next_free)) == (char *) 0)
- _nc_err_abort("Out of memory");
+ _nc_err_abort(MSG_NO_MEMORY);
(void) memcpy(tp->str_table, stringbuf, next_free);
tp->term_names = tp->str_table + n;
for_each_string(i, &(ep->tterm)) {
- if (offsets[i] == ABSENT_OFFSET)
- tp->Strings[i] = ABSENT_STRING;
- else if (offsets[i] == CANCELLED_OFFSET)
- tp->Strings[i] = CANCELLED_STRING;
- else
- tp->Strings[i] = tp->str_table + offsets[i];
+ if (i < SIZEOF(offsets)) {
+ if (offsets[i] == ABSENT_OFFSET) {
+ tp->Strings[i] = ABSENT_STRING;
+ } else if (offsets[i] == CANCELLED_OFFSET) {
+ tp->Strings[i] = CANCELLED_STRING;
+ } else {
+ tp->Strings[i] = tp->str_table + offsets[i];
+ }
+ }
}
#if NCURSES_XNAMES
if (!copy_strings) {
- if ((n = NUM_EXT_NAMES(tp)) != 0) {
- size_t copied, length, strtabsize = 0;
- for (i = 0; i < n; i++) {
- strtabsize += strlen(tp->ext_Names[i]) + 1;
- offsets[i] = tp->ext_Names[i] - stringbuf;
- }
- if ((tp->ext_str_table = typeMalloc(char, strtabsize)) == 0)
- _nc_err_abort("Out of memory");
- for (i = 0, length = 0; i < n; i++) {
- tp->ext_Names[i] = tp->ext_str_table + length;
- copied = strlcpy(tp->ext_Names[i], stringbuf + offsets[i],
- strtabsize) + 1;
- if (copied > strtabsize)
- _nc_err_abort("Buffer overflow");
- length += copied;
- strtabsize -= copied;
+ if ((n = (unsigned) NUM_EXT_NAMES(tp)) != 0) {
+ if (n < SIZEOF(offsets)) {
+ size_t copied, length, strtabsize = 0;
+ for (i = 0; i < n; i++) {
+ strtabsize += strlen(tp->ext_Names[i]) + 1;
+ offsets[i] = tp->ext_Names[i] - stringbuf;
+ }
+ if ((tp->ext_str_table = typeMalloc(char, strtabsize)) == 0)
+ _nc_err_abort(MSG_NO_MEMORY);
+ for (i = 0, length = 0; i < n; i++) {
+ tp->ext_Names[i] = tp->ext_str_table + length;
+ copied = strlcpy(tp->ext_Names[i], stringbuf + offsets[i],
+ strtabsize) + 1;
+ if (copied > strtabsize)
+ _nc_err_abort("Buffer overflow");
+ length += copied;
+ strtabsize -= copied;
+ }
}
}
}
#endif
- for (i = 0; i < ep->nuses; i++) {
+ for (i = 0; i < nuses; i++) {
if (useoffsets[i] == ABSENT_OFFSET)
ep->uses[i].name = 0;
else
@@ -212,31 +246,34 @@ _nc_wrap_entry(ENTRY * const ep, bool copy_strings)
}
NCURSES_EXPORT(void)
-_nc_merge_entry
-(TERMTYPE * const to, TERMTYPE * const from)
+_nc_merge_entry(TERMTYPE *const to, TERMTYPE *const from)
/* merge capabilities from `from' entry into `to' entry */
{
- int i;
+ unsigned i;
#if NCURSES_XNAMES
_nc_align_termtype(to, from);
#endif
for_each_boolean(i, from) {
- int mergebool = from->Booleans[i];
+ if (to->Booleans[i] != (char) CANCELLED_BOOLEAN) {
+ int mergebool = from->Booleans[i];
- if (mergebool == CANCELLED_BOOLEAN)
- to->Booleans[i] = FALSE;
- else if (mergebool == TRUE)
- to->Booleans[i] = mergebool;
+ if (mergebool == CANCELLED_BOOLEAN)
+ to->Booleans[i] = FALSE;
+ else if (mergebool == TRUE)
+ to->Booleans[i] = (char) mergebool;
+ }
}
for_each_number(i, from) {
- int mergenum = from->Numbers[i];
+ if (to->Numbers[i] != CANCELLED_NUMERIC) {
+ short mergenum = from->Numbers[i];
- if (mergenum == CANCELLED_NUMERIC)
- to->Numbers[i] = ABSENT_NUMERIC;
- else if (mergenum != ABSENT_NUMERIC)
- to->Numbers[i] = mergenum;
+ if (mergenum == CANCELLED_NUMERIC)
+ to->Numbers[i] = ABSENT_NUMERIC;
+ else if (mergenum != ABSENT_NUMERIC)
+ to->Numbers[i] = mergenum;
+ }
}
/*
@@ -245,11 +282,24 @@ _nc_merge_entry
* we ever want to deallocate entries.
*/
for_each_string(i, from) {
- char *mergestring = from->Strings[i];
+ if (to->Strings[i] != CANCELLED_STRING) {
+ char *mergestring = from->Strings[i];
+
+ if (mergestring == CANCELLED_STRING)
+ to->Strings[i] = ABSENT_STRING;
+ else if (mergestring != ABSENT_STRING)
+ to->Strings[i] = mergestring;
+ }
+ }
+}
- if (mergestring == CANCELLED_STRING)
- to->Strings[i] = ABSENT_STRING;
- else if (mergestring != ABSENT_STRING)
- to->Strings[i] = mergestring;
+#if NO_LEAKS
+NCURSES_EXPORT(void)
+_nc_alloc_entry_leaks(void)
+{
+ if (stringbuf != 0) {
+ FreeAndNull(stringbuf);
}
+ next_free = 0;
}
+#endif
diff --git a/lib/libcurses/tinfo/alloc_ttype.c b/lib/libcurses/tinfo/alloc_ttype.c
index 43583824c0f..f474e502be4 100644
--- a/lib/libcurses/tinfo/alloc_ttype.c
+++ b/lib/libcurses/tinfo/alloc_ttype.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: alloc_ttype.c,v 1.5 2001/01/22 18:01:50 millert Exp $ */
+/* $OpenBSD: alloc_ttype.c,v 1.6 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1999-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -29,7 +29,7 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1999 *
+ * Author: Thomas E. Dickey <dickey@clark.net> 1999-on *
****************************************************************************/
/*
@@ -45,7 +45,7 @@
#include <tic.h>
#include <term_entry.h>
-MODULE_ID("$From: alloc_ttype.c,v 1.12 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: alloc_ttype.c,v 1.6 2010/01/12 23:22:06 nicm Exp $")
#if NCURSES_XNAMES
/*
@@ -94,15 +94,17 @@ find_name(char **table, int length, char *name)
}
static void
-realign_data(TERMTYPE * to, char **ext_Names, int ext_Booleans, int
- ext_Numbers, int ext_Strings)
+realign_data(TERMTYPE *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);
if (to->ext_Booleans != ext_Booleans) {
to->num_Booleans += (ext_Booleans - to->ext_Booleans);
- to->Booleans = typeRealloc(char, to->num_Booleans, to->Booleans);
+ to->Booleans = typeRealloc(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--) {
@@ -148,7 +150,7 @@ realign_data(TERMTYPE * to, char **ext_Names, int ext_Booleans, int
* Returns the first index in ext_Names[] for the given token-type
*/
static int
-_nc_first_ext_name(TERMTYPE * tp, int token_type)
+_nc_first_ext_name(TERMTYPE *tp, int token_type)
{
int first;
@@ -173,7 +175,7 @@ _nc_first_ext_name(TERMTYPE * tp, int token_type)
* Returns the last index in ext_Names[] for the given token-type
*/
static int
-_nc_last_ext_name(TERMTYPE * tp, int token_type)
+_nc_last_ext_name(TERMTYPE *tp, int token_type)
{
int last;
@@ -196,7 +198,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(TERMTYPE *tp, char *name, int token_type)
{
unsigned j;
unsigned first = _nc_first_ext_name(tp, token_type);
@@ -215,7 +217,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(TERMTYPE *tp, int n, int token_type)
{
switch (token_type) {
case BOOLEAN:
@@ -238,7 +240,7 @@ _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(TERMTYPE *tp, char *name, int token_type)
{
int j;
int first, last;
@@ -282,7 +284,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(TERMTYPE *tp, char *name, int token_type)
{
unsigned first = _nc_first_ext_name(tp, token_type);
unsigned last = _nc_last_ext_name(tp, token_type);
@@ -293,7 +295,7 @@ _nc_ins_ext_name(TERMTYPE * tp, char *name, int token_type)
int cmp = strcmp(name, tp->ext_Names[j]);
if (cmp == 0)
/* already present */
- return _nc_ext_data_index(tp, j, token_type);
+ return _nc_ext_data_index(tp, (int) j, token_type);
if (cmp < 0) {
break;
}
@@ -303,13 +305,13 @@ _nc_ins_ext_name(TERMTYPE * tp, char *name, int token_type)
for (k = total - 1; k > j; k--)
tp->ext_Names[k] = tp->ext_Names[k - 1];
tp->ext_Names[j] = name;
- j = _nc_ext_data_index(tp, j, token_type);
+ j = _nc_ext_data_index(tp, (int) j, token_type);
switch (token_type) {
case BOOLEAN:
tp->ext_Booleans += 1;
tp->num_Booleans += 1;
- tp->Booleans = typeRealloc(char, tp->num_Booleans, tp->Booleans);
+ tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
for (k = tp->num_Booleans - 1; k > j; k--)
tp->Booleans[k] = tp->Booleans[k - 1];
break;
@@ -337,7 +339,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(TERMTYPE *to, TERMTYPE *from)
{
int first = to->ext_Booleans + to->ext_Numbers;
int last = first + to->ext_Strings;
@@ -365,6 +367,17 @@ adjust_cancels(TERMTYPE * to, TERMTYPE * from)
} else {
j++;
}
+ } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],
+ STRING)) >= 0) {
+ if (_nc_del_ext_name(to, name, NUMBER)
+ || _nc_del_ext_name(to, name, BOOLEAN)) {
+ k = _nc_ins_ext_name(to, name, STRING);
+ to->Strings[k] = CANCELLED_STRING;
+ } else {
+ j++;
+ }
+ } else {
+ j++;
}
} else {
j++;
@@ -373,8 +386,7 @@ adjust_cancels(TERMTYPE * to, TERMTYPE * from)
}
NCURSES_EXPORT(void)
-_nc_align_termtype
-(TERMTYPE * to, TERMTYPE * from)
+_nc_align_termtype(TERMTYPE *to, TERMTYPE *from)
{
int na = NUM_EXT_NAMES(to);
int nb = NUM_EXT_NAMES(from);
@@ -382,6 +394,7 @@ _nc_align_termtype
bool same;
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));
@@ -445,6 +458,7 @@ _nc_align_termtype
to->ext_Names = ext_Names;
DEBUG(2, ("realigned %d extended names for '%s' (to)",
NUM_EXT_NAMES(to), to->term_names));
+ used_ext_Names = TRUE;
}
if (nb != (ext_Booleans + ext_Numbers + ext_Strings)) {
nb = (ext_Booleans + ext_Numbers + ext_Strings);
@@ -454,18 +468,19 @@ _nc_align_termtype
DEBUG(2, ("realigned %d extended names for '%s' (from)",
NUM_EXT_NAMES(from), from->term_names));
}
+ if (!used_ext_Names)
+ free(ext_Names);
}
}
#endif
NCURSES_EXPORT(void)
-_nc_copy_termtype
-(TERMTYPE * dst, TERMTYPE * src)
+_nc_copy_termtype(TERMTYPE *dst, TERMTYPE *src)
{
- int i;
+ unsigned i;
*dst = *src; /* ...to copy the sizes and string-tables */
- dst->Booleans = typeMalloc(char, NUM_BOOLEANS(dst));
+ dst->Booleans = typeMalloc(NCURSES_SBOOL, NUM_BOOLEANS(dst));
dst->Numbers = typeMalloc(short, NUM_NUMBERS(dst));
dst->Strings = typeMalloc(char *, NUM_STRINGS(dst));
diff --git a/lib/libcurses/tinfo/captoinfo.c b/lib/libcurses/tinfo/captoinfo.c
index 7c6a4587f58..6caf24560d1 100644
--- a/lib/libcurses/tinfo/captoinfo.c
+++ b/lib/libcurses/tinfo/captoinfo.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: captoinfo.c,v 1.15 2006/10/24 17:25:48 moritz Exp $ */
+/* $OpenBSD: captoinfo.c,v 1.16 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -41,7 +42,7 @@
*
* There is just one entry point:
*
- * char *_nc_captoinfo(n, s, parametrized)
+ * char *_nc_captoinfo(n, s, parameterized)
*
* Convert value s for termcap string capability named n into terminfo
* format.
@@ -94,7 +95,7 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$From: captoinfo.c,v 1.40 2000/11/05 00:22:36 tom Exp $")
+MODULE_ID("$Id: captoinfo.c,v 1.16 2010/01/12 23:22:06 nicm Exp $")
#define MAX_PUSHED 16 /* max # args we can push onto the stack */
@@ -117,7 +118,7 @@ init_string(void)
if (my_string == 0)
my_string = typeMalloc(char, my_length = 256);
if (my_string == 0)
- _nc_err_abort("Out of memory");
+ _nc_err_abort(MSG_NO_MEMORY);
*my_string = '\0';
return my_string;
@@ -132,19 +133,19 @@ save_string(char *d, const char *const s)
if (need > my_length) {
my_string = (char *) realloc(my_string, my_length = (need + need));
if (my_string == 0)
- _nc_err_abort("Out of memory");
+ _nc_err_abort(MSG_NO_MEMORY);
d = my_string + have;
}
if ((copied = strlcpy(d, s, my_length - have)) >= my_length - have)
- _nc_err_abort("Buffer overflow");
+ _nc_err_abort("Buffer overflow");
return d + copied;
}
-static inline char *
-save_char(char *s, char c)
+static NCURSES_INLINE char *
+save_char(char *s, int c)
{
static char temp[2];
- temp[0] = c;
+ temp[0] = (char) c;
return save_string(s, temp);
}
@@ -152,7 +153,7 @@ static void
push(void)
/* push onstack on to the stack */
{
- if (stackptr > MAX_PUSHED)
+ if (stackptr >= MAX_PUSHED)
_nc_warning("string too complex to convert");
else
stack[stackptr++] = onstack;
@@ -186,7 +187,7 @@ cvtchar(register const char *sp)
case '$':
case '\\':
case '%':
- c = *sp;
+ c = (unsigned char) (*sp);
len = 2;
break;
case '\0':
@@ -198,13 +199,13 @@ cvtchar(register const char *sp)
case '2':
case '3':
len = 1;
- while (isdigit(CharOf(*sp))) {
+ while (isdigit(UChar(*sp))) {
c = 8 * c + (*sp++ - '0');
len++;
}
break;
default:
- c = *sp;
+ c = (unsigned char) (*sp);
len = 2;
break;
}
@@ -214,7 +215,7 @@ cvtchar(register const char *sp)
len = 2;
break;
default:
- c = *sp;
+ c = (unsigned char) (*sp);
len = 1;
}
if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') {
@@ -276,12 +277,12 @@ getparm(int parm, int n)
* Convert a termcap string to terminfo format.
* 'cap' is the relevant terminfo capability index.
* 's' is the string value of the capability.
- * 'parametrized' tells what type of translations to do:
+ * 'parameterized' tells what type of translations to do:
* % translations if 1
* pad translations if >=0
*/
-char *
-_nc_captoinfo(const char *cap, const char *s, int const parametrized)
+NCURSES_EXPORT(char *)
+_nc_captoinfo(const char *cap, const char *s, int const parameterized)
{
const char *capstart;
@@ -298,16 +299,16 @@ _nc_captoinfo(const char *cap, const char *s, int const parametrized)
capstart = 0;
if (s == 0)
s = "";
- if (parametrized >= 0 && isdigit(CharOf(*s)))
+ if (parameterized >= 0 && isdigit(UChar(*s)))
for (capstart = s;; s++)
- if (!(isdigit(CharOf(*s)) || *s == '*' || *s == '.'))
+ if (!(isdigit(UChar(*s)) || *s == '*' || *s == '.'))
break;
while (*s != '\0') {
switch (*s) {
case '%':
s++;
- if (parametrized < 1) {
+ if (parameterized < 1) {
dp = save_char(dp, '%');
break;
}
@@ -468,7 +469,7 @@ _nc_captoinfo(const char *cap, const char *s, int const parametrized)
dp = save_char(dp, '%');
s--;
_nc_warning("unknown %% code %s (%#x) in %s",
- unctrl((chtype) * s), CharOf(*s), cap);
+ unctrl((chtype) *s), UChar(*s), cap);
break;
}
break;
@@ -549,7 +550,7 @@ _nc_captoinfo(const char *cap, const char *s, int const parametrized)
if (capstart) {
dp = save_string(dp, "$<");
for (s = capstart;; s++)
- if (isdigit(CharOf(*s)) || *s == '*' || *s == '.')
+ if (isdigit(UChar(*s)) || *s == '*' || *s == '.')
dp = save_char(dp, *s);
else
break;
@@ -573,8 +574,8 @@ bcd_expression(const char *str)
char ch1, ch2;
if (sscanf(str, fmt, &ch1, &ch2) == 2
- && isdigit(CharOf(ch1))
- && isdigit(CharOf(ch2))
+ && isdigit(UChar(ch1))
+ && isdigit(UChar(ch2))
&& (ch1 == ch2)) {
len = 28;
#ifndef NDEBUG
@@ -640,8 +641,8 @@ save_tc_inequality(char *bufptr, int c1, int c2)
* Convert a terminfo string to termcap format. Parameters are as in
* _nc_captoinfo().
*/
-char *
-_nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parametrized)
+NCURSES_EXPORT(char *)
+_nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameterized)
{
int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0;
const char *padding;
@@ -655,13 +656,13 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parametrize
padding = str + strlen(str) - 1;
if (padding > str && *padding == '>' && *--padding == '/') {
--padding;
- while (isdigit(CharOf(*padding)) || *padding == '.' || *padding == '*')
+ while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*')
padding--;
if (padding > str && *padding == '<' && *--padding == '$')
trimmed = padding;
padding += 2;
- while (isdigit(CharOf(*padding)) || *padding == '.' || *padding == '*')
+ while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*')
bufptr = save_char(bufptr, *padding++);
}
@@ -673,7 +674,7 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parametrize
bufptr = save_char(bufptr, *++str);
} else if (str[0] == '$' && str[1] == '<') { /* discard padding */
str += 2;
- while (isdigit(CharOf(*str))
+ while (isdigit(UChar(*str))
|| *str == '.'
|| *str == '*'
|| *str == '/'
@@ -682,7 +683,8 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parametrize
--str;
} else if (str[0] == '%' && str[1] == '%') { /* escaped '%' */
bufptr = save_string(bufptr, "%%");
- } else if (*str != '%' || (parametrized < 1)) {
+ ++str;
+ } else if (*str != '%' || (parameterized < 1)) {
bufptr = save_char(bufptr, *str);
} else if (sscanf(str, "%%?%%{%d}%%>%%t%%{%d}%%+%%;", &c1, &c2) == 2) {
str = strchr(str, ';');
@@ -741,7 +743,7 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parametrize
case '8':
case '9':
bufptr = save_char(bufptr, '%');
- while (isdigit(CharOf(*str)))
+ while (isdigit(UChar(*str)))
bufptr = save_char(bufptr, *str++);
if (strchr("doxX.", *str)) {
if (*str != 'd') /* termcap doesn't have octal, hex */
@@ -790,6 +792,11 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parametrize
} /* endswitch (*str) */
} /* endelse (*str == '%') */
+ /*
+ * 'str' always points to the end of what was scanned in this step,
+ * but that may not be the end of the string.
+ */
+ assert(str != 0);
if (*str == '\0')
break;
@@ -807,7 +814,7 @@ main(int argc, char *argv[])
{
int c, tc = FALSE;
- while ((c = getopt(argc, argv, "c")) != -1)
+ while ((c = getopt(argc, argv, "c")) != EOF)
switch (c) {
case 'c':
tc = TRUE;
@@ -817,7 +824,6 @@ main(int argc, char *argv[])
curr_line = 0;
for (;;) {
char buf[BUFSIZ];
- size_t buflen;
++curr_line;
if (fgets(buf, sizeof(buf), stdin) == NULL)
@@ -840,4 +846,13 @@ main(int argc, char *argv[])
}
#endif /* MAIN */
-/* captoinfo.c ends here */
+#if NO_LEAKS
+NCURSES_EXPORT(void)
+_nc_captoinfo_leaks(void)
+{
+ if (my_string != 0) {
+ FreeAndNull(my_string);
+ }
+ my_length = 0;
+}
+#endif
diff --git a/lib/libcurses/tinfo/comp_error.c b/lib/libcurses/tinfo/comp_error.c
index 13259e1efc4..319bd5fb35b 100644
--- a/lib/libcurses/tinfo/comp_error.c
+++ b/lib/libcurses/tinfo/comp_error.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: comp_error.c,v 1.5 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: comp_error.c,v 1.6 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2005,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 *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -42,48 +43,62 @@
#include <tic.h>
-MODULE_ID("$From: comp_error.c,v 1.21 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: comp_error.c,v 1.6 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT_VAR(bool) _nc_suppress_warnings = FALSE;
-NCURSES_EXPORT_VAR(int)
-_nc_curr_line = 0; /* current line # in input */
-NCURSES_EXPORT_VAR(int)
-_nc_curr_col = 0; /* current column # in input */
+NCURSES_EXPORT_VAR(int) _nc_curr_line = 0; /* current line # in input */
+NCURSES_EXPORT_VAR(int) _nc_curr_col = 0; /* current column # in input */
- static const char *sourcename;
- static char termtype[MAX_NAME_SIZE + 1];
+#define SourceName _nc_globals.comp_sourcename
+#define TermType _nc_globals.comp_termtype
+
+NCURSES_EXPORT(const char *)
+_nc_get_source(void)
+{
+ return SourceName;
+}
NCURSES_EXPORT(void)
_nc_set_source(const char *const name)
{
- sourcename = name;
+ SourceName = name;
}
NCURSES_EXPORT(void)
_nc_set_type(const char *const name)
{
- if (name)
- strlcpy(termtype, name, sizeof(termtype));
- else
- termtype[0] = '\0';
+ if (TermType == 0)
+ TermType = typeMalloc(char, MAX_NAME_SIZE + 1);
+ if (TermType != 0) {
+ TermType[0] = '\0';
+ if (name)
+ strncat(TermType, name, MAX_NAME_SIZE);
+ }
}
NCURSES_EXPORT(void)
_nc_get_type(char *name)
{
- strlcpy(name, termtype, MAX_NAME_SIZE + 1);
+#if NO_LEAKS
+ if (name == 0 && TermType != 0) {
+ FreeAndNull(TermType);
+ return;
+ }
+#endif
+ if (name != 0)
+ strlcpy(name, TermType != 0 ? TermType : "", MAX_NAME_SIZE + 1);
}
-static inline void
+static NCURSES_INLINE void
where_is_problem(void)
{
- fprintf(stderr, "\"%s\"", sourcename);
+ fprintf(stderr, "\"%s\"", SourceName ? SourceName : "?");
if (_nc_curr_line >= 0)
fprintf(stderr, ", line %d", _nc_curr_line);
if (_nc_curr_col >= 0)
fprintf(stderr, ", col %d", _nc_curr_col);
- if (termtype[0])
- fprintf(stderr, ", terminal '%s'", termtype);
+ if (TermType != 0 && TermType[0] != '\0')
+ fprintf(stderr, ", terminal '%s'", TermType);
fputc(':', stderr);
fputc(' ', stderr);
}
diff --git a/lib/libcurses/tinfo/comp_expand.c b/lib/libcurses/tinfo/comp_expand.c
index e78d365168c..598592856da 100644
--- a/lib/libcurses/tinfo/comp_expand.c
+++ b/lib/libcurses/tinfo/comp_expand.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: comp_expand.c,v 1.6 2007/06/02 01:29:11 pvalchev Exp $ */
+/* $OpenBSD: comp_expand.c,v 1.7 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -37,7 +37,7 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$From: comp_expand.c,v 1.15 2000/12/10 01:30:10 tom Exp $")
+MODULE_ID("$Id: comp_expand.c,v 1.7 2010/01/12 23:22:06 nicm Exp $")
static int
trailing_spaces(const char *src)
@@ -48,30 +48,37 @@ trailing_spaces(const char *src)
}
/* this deals with differences over whether 0x7f and 0x80..0x9f are controls */
-#define CHAR_OF(s) (*(unsigned const char *)(s))
-#define REALCTL(s) (CHAR_OF(s) < 127 && iscntrl(CHAR_OF(s)))
-#define REALPRINT(s) (CHAR_OF(s) < 127 && isprint(CHAR_OF(s)))
+#define REALCTL(s) (UChar(*(s)) < 127 && iscntrl(UChar(*(s))))
+#define REALPRINT(s) (UChar(*(s)) < 127 && isprint(UChar(*(s))))
NCURSES_EXPORT(char *)
-_nc_tic_expand
-(const char *srcp, bool tic_format, int numbers)
+_nc_tic_expand(const char *srcp, bool tic_format, int numbers)
{
static char *buffer;
static size_t length;
int bufp;
- const char *str = VALID_STRING(srcp) ? srcp : "";
+ const char *str = VALID_STRING(srcp) ? srcp : "\0\0";
bool islong = (strlen(str) > 3);
size_t need = (2 + strlen(str)) * 4;
int ch;
+#if NO_LEAKS
+ if (srcp == 0) {
+ if (buffer != 0) {
+ FreeAndNull(buffer);
+ length = 0;
+ }
+ return 0;
+ }
+#endif
if (buffer == 0 || need > length) {
if ((buffer = typeRealloc(char, length = need, buffer)) == 0)
return 0;
}
bufp = 0;
- while ((ch = CharOf(*str)) != 0) {
+ while ((ch = UChar(*str)) != 0) {
if (ch == '%' && REALPRINT(str + 1)) {
buffer[bufp++] = *str++;
/*
@@ -101,7 +108,7 @@ _nc_tic_expand
*/
case 1:
if (str[0] == L_BRACE
- && isdigit(CharOf(str[1]))) {
+ && isdigit(UChar(str[1]))) {
char *dst = 0;
long value = strtol(str + 1, &dst, 0);
if (dst != 0
@@ -114,7 +121,7 @@ _nc_tic_expand
if (ch == '\\'
|| ch == S_QUOTE)
buffer[bufp++] = '\\';
- buffer[bufp++] = ch;
+ buffer[bufp++] = (char) ch;
buffer[bufp++] = S_QUOTE;
str = dst;
} else {
@@ -143,13 +150,13 @@ _nc_tic_expand
buffer[bufp++] = 's';
} else if ((ch == ',' || ch == ':' || ch == '^') && tic_format) {
buffer[bufp++] = '\\';
- buffer[bufp++] = ch;
+ buffer[bufp++] = (char) ch;
} else if (REALPRINT(str)
&& (ch != ','
&& ch != ':'
&& !(ch == '!' && !tic_format)
&& ch != '^'))
- buffer[bufp++] = 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++] = '\\';
@@ -171,7 +178,7 @@ _nc_tic_expand
}
#define UnCtl(c) ((c) + '@')
else if (REALCTL(str) && ch != '\\'
- && (!islong || isdigit(CharOf(str[1])))) {
+ && (!islong || isdigit(UChar(str[1])))) {
(void) snprintf(buffer + bufp, length - bufp, "^%c", UnCtl(ch));
bufp += strlen(buffer + bufp);
} else {
diff --git a/lib/libcurses/tinfo/comp_hash.c b/lib/libcurses/tinfo/comp_hash.c
index a4b10f3c546..87856a7e040 100644
--- a/lib/libcurses/tinfo/comp_hash.c
+++ b/lib/libcurses/tinfo/comp_hash.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: comp_hash.c,v 1.7 2007/03/20 03:40:06 tedu Exp $ */
+/* $OpenBSD: comp_hash.c,v 1.8 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,15 +31,16 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
-
/*
* comp_hash.c --- Routines to deal with the hashtable of capability
* names.
*
*/
+#define USE_TERMLIB 1
#include <curses.priv.h>
#include <tic.h>
@@ -48,12 +49,12 @@
#ifdef MAIN_PROGRAM
#include <ctype.h>
#undef DEBUG
-#define DEBUG(level, params) /*nothing*/
+#define DEBUG(level, params) /*nothing */
#endif
-MODULE_ID("$From: comp_hash.c,v 1.21 1999/06/26 21:25:11 tom Exp $")
+MODULE_ID("$Id: comp_hash.c,v 1.8 2010/01/12 23:22:06 nicm Exp $")
-static int hash_function(const char *);
+static int hash_function(const char *);
/*
* _nc_make_hash_table()
@@ -67,59 +68,61 @@ static int hash_function(const char *);
#ifdef MAIN_PROGRAM
#undef MODULE_ID
-#define MODULE_ID(id) /*nothing*/
+#define MODULE_ID(id) /*nothing */
#include <tinfo/doalloc.c>
-static void _nc_make_hash_table(struct name_table_entry *table,
- struct name_table_entry **hash_table)
+static void
+_nc_make_hash_table(struct name_table_entry *table,
+ short *hash_table)
{
-int i;
-int hashvalue;
-int collisions = 0;
-
- for (i = 0; i < CAPTABSIZE; i++) {
- hashvalue = hash_function(table[i].nte_name);
-
- if (hash_table[hashvalue] != (struct name_table_entry *) 0)
- collisions++;
-
- if (hash_table[hashvalue] != 0)
- table[i].nte_link = (short)(hash_table[hashvalue] - table);
- hash_table[hashvalue] = &table[i];
- }
-
- DEBUG(4, ("Hash table complete: %d collisions out of %d entries", collisions, CAPTABSIZE));
+ short i;
+ int hashvalue;
+ int collisions = 0;
+
+ for (i = 0; i < HASHTABSIZE; i++) {
+ hash_table[i] = -1;
+ }
+ for (i = 0; i < CAPTABSIZE; i++) {
+ hashvalue = hash_function(table[i].nte_name);
+
+ if (hash_table[hashvalue] >= 0)
+ collisions++;
+
+ if (hash_table[hashvalue] != 0)
+ table[i].nte_link = hash_table[hashvalue];
+ hash_table[hashvalue] = i;
+ }
+
+ DEBUG(4, ("Hash table complete: %d collisions out of %d entries",
+ collisions, CAPTABSIZE));
}
#endif
-
/*
* int hash_function(string)
*
* Computes the hashing function on the given string.
*
* The current hash function is the sum of each consectutive pair
- * of characters, taken as two-byte integers, mod Hashtabsize.
+ * of characters, taken as two-byte integers, mod HASHTABSIZE.
*
*/
-static
-int
+static int
hash_function(const char *string)
{
-long sum = 0;
+ long sum = 0;
- DEBUG(9, ("hashing %s", string));
- while (*string) {
- sum += (long)(*string + (*(string + 1) << 8));
- string++;
- }
+ DEBUG(9, ("hashing %s", string));
+ while (*string) {
+ sum += (long) (*string + (*(string + 1) << 8));
+ string++;
+ }
- DEBUG(9, ("sum is %ld", sum));
- return (int)(sum % HASHTABSIZE);
+ DEBUG(9, ("sum is %ld", sum));
+ return (int) (sum % HASHTABSIZE);
}
-
/*
* struct name_table_entry *
* find_entry(string)
@@ -130,23 +133,27 @@ long sum = 0;
*/
#ifndef MAIN_PROGRAM
-struct name_table_entry const *
-_nc_find_entry(const char *string, const struct name_table_entry *const *hash_table)
+NCURSES_EXPORT(struct name_table_entry const *)
+_nc_find_entry(const char *string,
+ const short *hash_table)
{
-int hashvalue;
-struct name_table_entry const *ptr;
-
- hashvalue = hash_function(string);
-
- if ((ptr = hash_table[hashvalue]) != 0) {
- while (strcmp(ptr->nte_name, string) != 0) {
- if (ptr->nte_link < 0)
- return 0;
- ptr = ptr->nte_link + hash_table[HASHTABSIZE];
- }
+ int hashvalue;
+ struct name_table_entry const *ptr = 0;
+ struct name_table_entry const *real_table;
+
+ hashvalue = hash_function(string);
+
+ if (hash_table[hashvalue] >= 0) {
+ real_table = _nc_get_table(hash_table != _nc_get_hash_table(FALSE));
+ ptr = real_table + hash_table[hashvalue];
+ while (strcmp(ptr->nte_name, string) != 0) {
+ if (ptr->nte_link < 0)
+ return 0;
+ ptr = real_table + (ptr->nte_link + hash_table[HASHTABSIZE]);
}
+ }
- return (ptr);
+ return (ptr);
}
/*
@@ -160,19 +167,19 @@ struct name_table_entry const *ptr;
* in the table or 0 if not found.
*/
-struct name_table_entry const *
+NCURSES_EXPORT(struct name_table_entry const *)
_nc_find_type_entry(const char *string,
int type,
const struct name_table_entry *table)
{
-struct name_table_entry const *ptr;
+ struct name_table_entry const *ptr;
- for (ptr = table; ptr < table + CAPTABSIZE; ptr++) {
- if (ptr->nte_type == type && strcmp(string, ptr->nte_name) == 0)
- return(ptr);
- }
+ for (ptr = table; ptr < table + CAPTABSIZE; ptr++) {
+ if (ptr->nte_type == type && strcmp(string, ptr->nte_name) == 0)
+ return (ptr);
+ }
- return ((struct name_table_entry *)NULL);
+ return ((struct name_table_entry *) NULL);
}
#endif
@@ -189,140 +196,177 @@ struct name_table_entry const *ptr;
#define MAX_COLUMNS BUFSIZ /* this _has_ to be worst-case */
-static char **parse_columns(char *buffer)
+static char **
+parse_columns(char *buffer)
{
- static char **list;
-
- int col = 0;
-
- if (list == 0 && (list = typeCalloc(char *, MAX_COLUMNS)) == 0)
- return(0);
-
- if (*buffer != '#') {
- while (*buffer != '\0') {
- char *s;
- for (s = buffer; (*s != '\0') && !isspace(*s); s++)
- /*EMPTY*/;
- if (s != buffer) {
- char mark = *s;
- *s = '\0';
- if ((s - buffer) > 1
- && (*buffer == '"')
- && (s[-1] == '"')) { /* strip the quotes */
- buffer++;
- s[-1] = '\0';
- }
- list[col] = buffer;
- col++;
- if (mark == '\0')
- break;
- while (isspace(*++s))
- /*EMPTY*/;
- buffer = s;
- } else
- break;
+ static char **list;
+
+ int col = 0;
+
+ if (list == 0 && (list = typeCalloc(char *, MAX_COLUMNS)) == 0)
+ return (0);
+
+ if (*buffer != '#') {
+ while (*buffer != '\0') {
+ char *s;
+ for (s = buffer; (*s != '\0') && !isspace(UChar(*s)); s++)
+ /*EMPTY */ ;
+ if (s != buffer) {
+ char mark = *s;
+ *s = '\0';
+ if ((s - buffer) > 1
+ && (*buffer == '"')
+ && (s[-1] == '"')) { /* strip the quotes */
+ assert(s > buffer + 1);
+ s[-1] = '\0';
+ buffer++;
}
+ list[col] = buffer;
+ col++;
+ if (mark == '\0')
+ break;
+ while (*++s && isspace(UChar(*s)))
+ /*EMPTY */ ;
+ buffer = s;
+ } else
+ break;
}
- return col ? list : 0;
+ }
+ return col ? list : 0;
}
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
- struct name_table_entry *name_table = typeCalloc(struct name_table_entry, CAPTABSIZE);
- struct name_table_entry **hash_table = typeCalloc(struct name_table_entry *, HASHTABSIZE);
- const char *root_name = "";
- int column = 0;
- int n;
- char buffer[BUFSIZ];
-
- static const char * typenames[] = { "BOOLEAN", "NUMBER", "STRING" };
-
- short BoolCount = 0;
- short NumCount = 0;
- short StrCount = 0;
-
- /* The first argument is the column-number (starting with 0).
- * The second is the root name of the tables to generate.
- */
- if (argc <= 2
- || (column = atoi(argv[1])) <= 0
- || (column >= MAX_COLUMNS)
- || *(root_name = argv[2]) == 0) {
- fprintf(stderr, "usage: make_hash column root_name\n");
- exit(EXIT_FAILURE);
+ struct name_table_entry *name_table = typeCalloc(struct
+ name_table_entry, CAPTABSIZE);
+ short *hash_table = typeCalloc(short, HASHTABSIZE);
+ const char *root_name = "";
+ int column = 0;
+ int bigstring = 0;
+ int n;
+ char buffer[BUFSIZ];
+
+ static const char *typenames[] =
+ {"BOOLEAN", "NUMBER", "STRING"};
+
+ short BoolCount = 0;
+ short NumCount = 0;
+ short StrCount = 0;
+
+ /* The first argument is the column-number (starting with 0).
+ * The second is the root name of the tables to generate.
+ */
+ if (argc <= 3
+ || (column = atoi(argv[1])) <= 0
+ || (column >= MAX_COLUMNS)
+ || *(root_name = argv[2]) == 0
+ || (bigstring = atoi(argv[3])) < 0
+ || name_table == 0
+ || hash_table == 0) {
+ fprintf(stderr, "usage: make_hash column root_name bigstring\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Read the table into our arrays.
+ */
+ for (n = 0; (n < CAPTABSIZE) && fgets(buffer, BUFSIZ, stdin);) {
+ char **list, *nlp = strchr(buffer, '\n');
+ if (nlp)
+ *nlp = '\0';
+ list = parse_columns(buffer);
+ if (list == 0) /* blank or comment */
+ continue;
+ name_table[n].nte_link = -1; /* end-of-hash */
+ name_table[n].nte_name = strdup(list[column]);
+ if (!strcmp(list[2], "bool")) {
+ name_table[n].nte_type = BOOLEAN;
+ name_table[n].nte_index = BoolCount++;
+ } else if (!strcmp(list[2], "num")) {
+ name_table[n].nte_type = NUMBER;
+ name_table[n].nte_index = NumCount++;
+ } else if (!strcmp(list[2], "str")) {
+ name_table[n].nte_type = STRING;
+ name_table[n].nte_index = StrCount++;
+ } else {
+ fprintf(stderr, "Unknown type: %s\n", list[2]);
+ exit(EXIT_FAILURE);
}
-
- /*
- * Read the table into our arrays.
- */
- for (n = 0; (n < CAPTABSIZE) && fgets(buffer, BUFSIZ, stdin); ) {
- char **list, *nlp = strchr(buffer, '\n');
- if (nlp)
- *nlp = '\0';
- list = parse_columns(buffer);
- if (list == 0) /* blank or comment */
- continue;
- name_table[n].nte_link = -1; /* end-of-hash */
- name_table[n].nte_name = strdup(list[column]);
- if (!strcmp(list[2], "bool")) {
- name_table[n].nte_type = BOOLEAN;
- name_table[n].nte_index = BoolCount++;
- } else if (!strcmp(list[2], "num")) {
- name_table[n].nte_type = NUMBER;
- name_table[n].nte_index = NumCount++;
- } else if (!strcmp(list[2], "str")) {
- name_table[n].nte_type = STRING;
- name_table[n].nte_index = StrCount++;
- } else {
- fprintf(stderr, "Unknown type: %s\n", list[2]);
- exit(EXIT_FAILURE);
- }
- n++;
+ n++;
+ }
+ _nc_make_hash_table(name_table, hash_table);
+
+ /*
+ * Write the compiled tables to standard output
+ */
+ if (bigstring) {
+ int len = 0;
+ int nxt;
+
+ printf("static const char %s_names_text[] = \\\n", root_name);
+ for (n = 0; n < CAPTABSIZE; n++) {
+ nxt = (int) strlen(name_table[n].nte_name) + 5;
+ if (nxt + len > 72) {
+ printf("\\\n");
+ len = 0;
+ }
+ printf("\"%s\\0\" ", name_table[n].nte_name);
+ len += nxt;
}
- _nc_make_hash_table(name_table, hash_table);
+ printf(";\n\n");
- /*
- * Write the compiled tables to standard output
- */
- printf("static struct name_table_entry const _nc_%s_table[] =\n",
- root_name);
+ len = 0;
+ printf("static name_table_data const %s_names_data[] =\n",
+ root_name);
printf("{\n");
for (n = 0; n < CAPTABSIZE; n++) {
- snprintf(buffer, sizeof(buffer), "\"%s\"",
- name_table[n].nte_name);
- printf("\t{ %15s,\t%10s,\t%3d, %3d }%c\n",
- buffer,
- typenames[name_table[n].nte_type],
- name_table[n].nte_index,
- name_table[n].nte_link,
- n < CAPTABSIZE - 1 ? ',' : ' ');
+ printf("\t{ %15d,\t%10s,\t%3d, %3d }%c\n",
+ len,
+ typenames[name_table[n].nte_type],
+ name_table[n].nte_index,
+ name_table[n].nte_link,
+ n < CAPTABSIZE - 1 ? ',' : ' ');
+ len += (int) strlen(name_table[n].nte_name) + 1;
}
printf("};\n\n");
+ printf("static struct name_table_entry *_nc_%s_table = 0;\n\n", root_name);
+ } else {
- printf("const struct name_table_entry * const _nc_%s_hash_table[%d] =\n",
- root_name,
- HASHTABSIZE+1);
+ printf("static struct name_table_entry %s _nc_%s_table[] =\n",
+ bigstring ? "" : "const",
+ root_name);
printf("{\n");
- for (n = 0; n < HASHTABSIZE; n++) {
- if (hash_table[n] != 0) {
- snprintf(buffer, sizeof(buffer), "_nc_%s_table + %3ld",
- root_name,
- (long) (hash_table[n] - name_table));
- } else {
- buffer[0] = '0';
- buffer[1] = '\0';
- }
- printf("\t%s,\n", buffer);
+ for (n = 0; n < CAPTABSIZE; n++) {
+ snprintf(buffer, sizeof(buffer), "\"%s\"",
+ name_table[n].nte_name);
+ printf("\t{ %15s,\t%10s,\t%3d, %3d }%c\n",
+ buffer,
+ typenames[name_table[n].nte_type],
+ name_table[n].nte_index,
+ name_table[n].nte_link,
+ n < CAPTABSIZE - 1 ? ',' : ' ');
}
- printf("\t_nc_%s_table\t/* base-of-table */\n", root_name);
printf("};\n\n");
-
- printf("#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n",
- BoolCount, NumCount, StrCount);
- printf("#error\t--> term.h and comp_captab.c disagree about the <--\n");
- printf("#error\t--> numbers of booleans, numbers and/or strings <--\n");
- printf("#endif\n\n");
-
- return EXIT_SUCCESS;
+ }
+
+ printf("static const short _nc_%s_hash_table[%d] =\n",
+ root_name,
+ HASHTABSIZE + 1);
+ printf("{\n");
+ for (n = 0; n < HASHTABSIZE; n++) {
+ printf("\t%3d,\n", hash_table[n]);
+ }
+ printf("\t0\t/* base-of-table */\n");
+ printf("};\n\n");
+
+ printf("#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n",
+ BoolCount, NumCount, StrCount);
+ printf("#error\t--> term.h and comp_captab.c disagree about the <--\n");
+ printf("#error\t--> numbers of booleans, numbers and/or strings <--\n");
+ printf("#endif\n\n");
+
+ free(hash_table);
+ return EXIT_SUCCESS;
}
#endif
diff --git a/lib/libcurses/tinfo/comp_parse.c b/lib/libcurses/tinfo/comp_parse.c
index 4c9b83497d3..1cf53acb120 100644
--- a/lib/libcurses/tinfo/comp_parse.c
+++ b/lib/libcurses/tinfo/comp_parse.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: comp_parse.c,v 1.11 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: comp_parse.c,v 1.12 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,18 +31,19 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
* comp_parse.c -- parser driver loop and use handling.
*
* _nc_read_entry_source(FILE *, literal, bool, bool (*hook)())
- * _nc_resolve_uses(void)
+ * _nc_resolve_uses2(void)
* _nc_free_entries(void)
*
* Use this code by calling _nc_read_entry_source() on as many source
* files as you like (either terminfo or termcap syntax). If you
- * want use-resolution, call _nc_resolve_uses(). To free the list
+ * want use-resolution, call _nc_resolve_uses2(). To free the list
* storage, do _nc_free_entries().
*
*/
@@ -54,43 +55,23 @@
#include <tic.h>
#include <term_entry.h>
-MODULE_ID("$From: comp_parse.c,v 1.48 2001/01/15 00:44:51 tom Exp $")
+MODULE_ID("$Id: comp_parse.c,v 1.12 2010/01/12 23:22:06 nicm Exp $")
+static void sanity_check2(TERMTYPE *, bool);
+NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2;
+
+/* obsolete: 20040705 */
static void sanity_check(TERMTYPE *);
NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype) (TERMTYPE *) = sanity_check;
-/****************************************************************************
- *
- * Entry queue handling
- *
- ****************************************************************************/
-/*
- * The entry list is a doubly linked list with NULLs terminating the lists:
- *
- * --------- --------- ---------
- * | | | | | | offset
- * |-------| |-------| |-------|
- * | ----+-->| ----+-->| NULL | next
- * |-------| |-------| |-------|
- * | NULL |<--+---- |<--+---- | last
- * --------- --------- ---------
- * ^ ^
- * | |
- * | |
- * _nc_head _nc_tail
- */
-
-NCURSES_EXPORT_VAR(ENTRY *) _nc_head = 0;
-NCURSES_EXPORT_VAR(ENTRY *) _nc_tail = 0;
-
- static void
- enqueue(ENTRY * ep)
+static void
+enqueue(ENTRY * ep)
/* add an entry to the in-core list */
{
ENTRY *newp = _nc_copy_entry(ep);
if (newp == 0)
- _nc_err_abort("Out of memory");
+ _nc_err_abort(MSG_NO_MEMORY);
newp->last = _nc_tail;
_nc_tail = newp;
@@ -100,43 +81,18 @@ NCURSES_EXPORT_VAR(ENTRY *) _nc_tail = 0;
newp->last->next = newp;
}
-NCURSES_EXPORT(void)
-_nc_free_entries(ENTRY * headp)
-/* free the allocated storage consumed by list entries */
-{
- ENTRY *ep, *next;
-
- for (ep = headp; ep; ep = next) {
- /*
- * This conditional lets us disconnect storage from the list.
- * To do this, copy an entry out of the list, then null out
- * the string-table member in the original and any use entries
- * it references.
- */
- FreeIfNeeded(ep->tterm.str_table);
-
- next = ep->next;
-
- free(ep);
- if (ep == _nc_head)
- _nc_head = 0;
- if (ep == _nc_tail)
- _nc_tail = 0;
- }
-}
-
static char *
force_bar(char *dst, char *src, size_t siz)
{
if (strchr(src, '|') == 0) {
- size_t len;
-
- len = strlcpy(dst, src, siz);
- if (len > siz - 2)
- len = siz - 2;
- dst[len++] = '|';
- dst[len] = '\0';
- src = dst;
+ size_t len;
+
+ len = strlcpy(dst, src, siz);
+ if (len > siz - 2)
+ len = siz - 2;
+ dst[len++] = '|';
+ dst[len] = '\0';
+ src = dst;
}
return src;
}
@@ -167,7 +123,7 @@ _nc_entry_match(char *n1, char *n2)
****************************************************************************/
NCURSES_EXPORT(void)
-_nc_read_entry_source(FILE * fp, char *buf,
+_nc_read_entry_source(FILE *fp, char *buf,
int literal, bool silent,
bool(*hook) (ENTRY *))
/* slurp all entries in the given file into core */
@@ -184,18 +140,29 @@ _nc_read_entry_source(FILE * fp, char *buf,
memset(&thisentry, 0, sizeof(thisentry));
if (_nc_parse_entry(&thisentry, literal, silent) == ERR)
break;
- if (!isalnum(CharOf(thisentry.tterm.term_names[0])))
+ if (!isalnum(UChar(thisentry.tterm.term_names[0])))
_nc_err_abort("terminal names must start with letter or digit");
/*
- * This can be used for immediate compilation of entries with no
- * use references to disk, so as to avoid chewing up a lot of
- * core when the resolution code could fetch entries off disk.
+ * This can be used for immediate compilation of entries with no "use="
+ * references to disk. That avoids consuming a lot of memory when the
+ * resolution code could fetch entries off disk.
*/
- if (hook != NULLHOOK && (*hook) (&thisentry))
+ if (hook != NULLHOOK && (*hook) (&thisentry)) {
immediate++;
- else
+ } else {
enqueue(&thisentry);
+ /*
+ * The enqueued entry is copied with _nc_copy_termtype(), so we can
+ * free some of the data from thisentry, i.e., the arrays.
+ */
+ FreeIfNeeded(thisentry.tterm.Booleans);
+ FreeIfNeeded(thisentry.tterm.Numbers);
+ FreeIfNeeded(thisentry.tterm.Strings);
+#if NCURSES_XNAMES
+ FreeIfNeeded(thisentry.tterm.ext_Names);
+#endif
+ }
}
if (_nc_tail) {
@@ -215,12 +182,13 @@ _nc_read_entry_source(FILE * fp, char *buf,
}
NCURSES_EXPORT(int)
-_nc_resolve_uses(bool fullresolve)
+_nc_resolve_uses2(bool fullresolve, bool literal)
/* try to resolve all use capabilities */
{
ENTRY *qp, *rp, *lastread = 0;
bool keepgoing;
- int i, j, unresolved, total_unresolved, multiples;
+ unsigned i;
+ int unresolved, total_unresolved, multiples;
DEBUG(2, ("RESOLUTION BEGINNING"));
@@ -293,7 +261,7 @@ _nc_resolve_uses(bool fullresolve)
rp = typeMalloc(ENTRY, 1);
if (rp == 0)
- _nc_err_abort("Out of memory");
+ _nc_err_abort(MSG_NO_MEMORY);
rp->tterm = thisterm;
rp->nuses = 0;
rp->next = lastread;
@@ -324,8 +292,8 @@ _nc_resolve_uses(bool fullresolve)
DEBUG(2, ("NAME RESOLUTION COMPLETED OK"));
/*
- * OK, at this point all (char *) references in `name' mwmbers
- * have been successfully converred to (ENTRY *) pointers in
+ * OK, at this point all (char *) references in `name' members
+ * have been successfully converted to (ENTRY *) pointers in
* `link' members. Time to do the actual merges.
*/
if (fullresolve) {
@@ -351,10 +319,10 @@ _nc_resolve_uses(bool fullresolve)
}
/*
- * First, make sure there's no garbage in the
- * merge block. as a side effect, copy into
- * the merged entry the name field and string
- * table pointer.
+ * First, make sure there is no garbage in the
+ * merge block. As a side effect, copy into
+ * the merged entry the name field and string
+ * table pointer.
*/
_nc_copy_termtype(&merged, &(qp->tterm));
@@ -377,6 +345,9 @@ _nc_resolve_uses(bool fullresolve)
FreeIfNeeded(qp->tterm.Booleans);
FreeIfNeeded(qp->tterm.Numbers);
FreeIfNeeded(qp->tterm.Strings);
+#if NCURSES_XNAMES
+ FreeIfNeeded(qp->tterm.ext_Names);
+#endif
qp->tterm = merged;
_nc_wrap_entry(qp, TRUE);
@@ -393,26 +364,6 @@ _nc_resolve_uses(bool fullresolve)
(keepgoing);
DEBUG(2, ("MERGES COMPLETED OK"));
-
- /*
- * The exit condition of the loop above is such that all entries
- * must now be resolved. Now handle cancellations. In a resolved
- * entry there should be no cancellation markers.
- */
- for_entry_list(qp) {
- for_each_boolean(j, &(qp->tterm)) {
- if ((int) qp->tterm.Booleans[j] == CANCELLED_BOOLEAN)
- qp->tterm.Booleans[j] = ABSENT_BOOLEAN;
- }
- for_each_number(j, &(qp->tterm)) {
- if (qp->tterm.Numbers[j] == CANCELLED_NUMERIC)
- qp->tterm.Numbers[j] = ABSENT_NUMERIC;
- }
- for_each_string(j, &(qp->tterm)) {
- if (qp->tterm.Strings[j] == CANCELLED_STRING)
- qp->tterm.Strings[j] = ABSENT_STRING;
- }
- }
}
/*
@@ -430,7 +381,7 @@ _nc_resolve_uses(bool fullresolve)
for_entry_list(qp) {
_nc_curr_line = qp->startline;
_nc_set_type(_nc_first_name(qp->tterm.term_names));
- _nc_check_termtype(&qp->tterm);
+ _nc_check_termtype2(&qp->tterm, literal);
}
DEBUG(2, ("SANITY CHECK FINISHED"));
}
@@ -438,6 +389,13 @@ _nc_resolve_uses(bool fullresolve)
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 ---
@@ -448,7 +406,7 @@ _nc_resolve_uses(bool fullresolve)
#define CUR tp->
static void
-sanity_check(TERMTYPE * tp)
+sanity_check2(TERMTYPE *tp, bool literal)
{
if (!PRESENT(exit_attribute_mode)) {
#ifdef __UNUSED__ /* this casts too wide a net */
@@ -465,14 +423,24 @@ sanity_check(TERMTYPE * tp)
|| PRESENT(enter_reverse_mode)))
_nc_warning("no exit_attribute_mode");
#endif /* __UNUSED__ */
- PAIRED(enter_standout_mode, exit_standout_mode)
- PAIRED(enter_underline_mode, exit_underline_mode)
+ PAIRED(enter_standout_mode, exit_standout_mode);
+ PAIRED(enter_underline_mode, exit_underline_mode);
+ }
+
+ /* we do this check/fix in postprocess_termcap(), but some packagers
+ * prefer to bypass it...
+ */
+ if (!literal) {
+ if (acs_chars == 0
+ && enter_alt_charset_mode != 0
+ && exit_alt_charset_mode != 0)
+ acs_chars = strdup(VT_ACSC);
+ ANDMISSING(enter_alt_charset_mode, acs_chars);
+ ANDMISSING(exit_alt_charset_mode, acs_chars);
}
/* listed in structure-member order of first argument */
PAIRED(enter_alt_charset_mode, exit_alt_charset_mode);
- ANDMISSING(enter_alt_charset_mode, acs_chars);
- ANDMISSING(exit_alt_charset_mode, acs_chars);
ANDMISSING(enter_blink_mode, exit_attribute_mode);
ANDMISSING(enter_bold_mode, exit_attribute_mode);
PAIRED(exit_ca_mode, enter_ca_mode);
@@ -490,6 +458,38 @@ sanity_check(TERMTYPE * tp)
PAIRED(enter_xon_mode, exit_xon_mode);
PAIRED(enter_am_mode, exit_am_mode);
ANDMISSING(label_off, label_on);
+#ifdef 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)
+{
+ _nc_alloc_entry_leaks();
+ _nc_captoinfo_leaks();
+ _nc_comp_captab_leaks();
+ _nc_comp_scan_leaks();
+#if BROKEN_LINKER || USE_REENTRANT
+ _nc_names_leaks();
+ _nc_codes_leaks();
+#endif
+ _nc_tic_expand(0, FALSE, 0);
+}
+
+NCURSES_EXPORT(void)
+_nc_free_tic(int code)
+{
+ _nc_leaks_tic();
+ _nc_free_tinfo(code);
+}
+#endif
diff --git a/lib/libcurses/tinfo/comp_scan.c b/lib/libcurses/tinfo/comp_scan.c
index a241322f188..ff3b9ac7ff2 100644
--- a/lib/libcurses/tinfo/comp_scan.c
+++ b/lib/libcurses/tinfo/comp_scan.c
@@ -1,5 +1,7 @@
+/* $OpenBSD: comp_scan.c,v 1.15 2010/01/12 23:22:06 nicm Exp $ */
+
/****************************************************************************
- * Copyright (c) 1998,1999,2000,2001 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -29,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996 on *
****************************************************************************/
/*
@@ -50,7 +53,7 @@
#include <term_entry.h>
#include <tic.h>
-MODULE_ID("$From: comp_scan.c,v 1.54 2001/02/04 01:09:26 tom Exp $")
+MODULE_ID("$Id: comp_scan.c,v 1.15 2010/01/12 23:22:06 nicm Exp $")
/*
* Maximum length of string capability we'll accept before raising an error.
@@ -84,23 +87,207 @@ _nc_curr_token =
*****************************************************************************/
static bool first_column; /* See 'next_char()' below */
+static bool had_newline;
static char separator; /* capability separator */
static int pushtype; /* type of pushback token */
-static char pushname[MAX_NAME_SIZE + 1];
+static char *pushname;
#if NCURSES_EXT_FUNCS
NCURSES_EXPORT_VAR(bool)
_nc_disable_period = FALSE; /* used by tic -a option */
#endif
-static int last_char(void);
-static int next_char(void);
-static long stream_pos(void);
-static bool end_of_stream(void);
-static void push_back(char c);
+/*****************************************************************************
+ *
+ * Character-stream handling
+ *
+ *****************************************************************************/
+
+#define LEXBUFSIZ 1024
+
+static char *bufptr; /* otherwise, the input buffer pointer */
+static char *bufstart; /* start of buffer so we can compute offsets */
+static FILE *yyin; /* scanner's input file descriptor */
+
+/*
+ * _nc_reset_input()
+ *
+ * Resets the input-reading routines. Used on initialization,
+ * or after a seek has been done. Exactly one argument must be
+ * non-null.
+ */
+
+NCURSES_EXPORT(void)
+_nc_reset_input(FILE *fp, char *buf)
+{
+ pushtype = NO_PUSHBACK;
+ if (pushname != 0)
+ pushname[0] = '\0';
+ yyin = fp;
+ bufstart = bufptr = buf;
+ _nc_curr_file_pos = 0L;
+ if (fp != 0)
+ _nc_curr_line = 0;
+ _nc_curr_col = 0;
+}
+
+/*
+ * int last_char()
+ *
+ * Returns the final nonblank character on the current input buffer
+ */
+static int
+last_char(void)
+{
+ size_t len = strlen(bufptr);
+ while (len--) {
+ if (!isspace(UChar(bufptr[len])))
+ return bufptr[len];
+ }
+ return 0;
+}
+
+/*
+ * int next_char()
+ *
+ * Returns the next character in the input stream. Comments and leading
+ * white space are stripped.
+ *
+ * The global state variable 'firstcolumn' is set TRUE if the character
+ * returned is from the first column of the input line.
+ *
+ * The global variable _nc_curr_line is incremented for each new line.
+ * The global variable _nc_curr_file_pos is set to the file offset of the
+ * beginning of each line.
+ */
+
+static int
+next_char(void)
+{
+ static char *result;
+ static size_t allocated;
+ int the_char;
+
+ if (!yyin) {
+ if (result != 0) {
+ FreeAndNull(result);
+ FreeAndNull(pushname);
+ allocated = 0;
+ }
+ /*
+ * An string with an embedded null will truncate the input. This is
+ * intentional (we don't read binary files here).
+ */
+ if (bufptr == 0 || *bufptr == '\0')
+ return (EOF);
+ if (*bufptr == '\n') {
+ _nc_curr_line++;
+ _nc_curr_col = 0;
+ } else if (*bufptr == '\t') {
+ _nc_curr_col = (_nc_curr_col | 7);
+ }
+ } else if (!bufptr || !*bufptr) {
+ /*
+ * In theory this could be recoded to do its I/O one character at a
+ * time, saving the buffer space. In practice, this turns out to be
+ * quite hard to get completely right. Try it and see. If you
+ * succeed, don't forget to hack push_back() correspondingly.
+ */
+ size_t used;
+ size_t len;
+
+ do {
+ bufstart = 0;
+ used = 0;
+ do {
+ if (used + (LEXBUFSIZ / 4) >= allocated) {
+ allocated += (allocated + LEXBUFSIZ);
+ result = typeRealloc(char, allocated, result);
+ if (result == 0)
+ return (EOF);
+ bufstart = result;
+ }
+ if (used == 0)
+ _nc_curr_file_pos = ftell(yyin);
+
+ if (fgets(result + used, (int) (allocated - used), yyin) != 0) {
+ bufstart = result;
+ if (used == 0) {
+ _nc_curr_line++;
+ _nc_curr_col = 0;
+ }
+ } else {
+ if (used != 0)
+ strlcat(result, "\n", allocated);
+ }
+ if ((bufptr = bufstart) != 0) {
+ used = strlen(bufptr);
+ while (iswhite(*bufptr)) {
+ if (*bufptr == '\t') {
+ _nc_curr_col = (_nc_curr_col | 7) + 1;
+ } else {
+ _nc_curr_col++;
+ }
+ bufptr++;
+ }
+
+ /*
+ * Treat a trailing <cr><lf> the same as a <newline> so we
+ * can read files on OS/2, etc.
+ */
+ if ((len = strlen(bufptr)) > 1) {
+ if (bufptr[len - 1] == '\n'
+ && bufptr[len - 2] == '\r') {
+ len--;
+ bufptr[len - 1] = '\n';
+ bufptr[len] = '\0';
+ }
+ }
+ } else {
+ return (EOF);
+ }
+ } while (bufptr[len - 1] != '\n'); /* complete a line */
+ } while (result[0] == '#'); /* ignore comments */
+ } else if (*bufptr == '\t') {
+ _nc_curr_col = (_nc_curr_col | 7);
+ }
+
+ first_column = (bufptr == bufstart);
+ if (first_column)
+ had_newline = FALSE;
+
+ _nc_curr_col++;
+ the_char = *bufptr++;
+ return UChar(the_char);
+}
+
+static void
+push_back(char c)
+/* push a character back onto the input stream */
+{
+ if (bufptr == bufstart)
+ _nc_syserr_abort("Can't backspace off beginning of line");
+ *--bufptr = c;
+ _nc_curr_col--;
+}
+
+static long
+stream_pos(void)
+/* return our current character position in the input stream */
+{
+ return (yyin ? ftell(yyin) : (bufptr ? bufptr - bufstart : 0));
+}
+
+static bool
+end_of_stream(void)
+/* are we at end of input? */
+{
+ return ((yyin ? feof(yyin) : (bufptr && *bufptr == '\0'))
+ ? TRUE : FALSE);
+}
/* Assume we may be looking at a termcap-style continuation */
-static inline int
+static NCURSES_INLINE int
eat_escaped_newline(int ch)
{
if (ch == '\\')
@@ -109,6 +296,15 @@ eat_escaped_newline(int ch)
return ch;
}
+#define TOK_BUF_SIZE MAX_ENTRY_SIZE
+
+#define OkToAdd() \
+ ((tok_ptr - tok_buf) < (TOK_BUF_SIZE - 2))
+
+#define AddCh(ch) \
+ *tok_ptr++ = (char) ch; \
+ *tok_ptr = '\0'
+
/*
* int
* get_token()
@@ -146,41 +342,65 @@ NCURSES_EXPORT(int)
_nc_get_token(bool silent)
{
static const char terminfo_punct[] = "@%&*!#";
- long number;
- int type;
- int ch;
+ static char *tok_buf;
+
+ char *after_list;
+ char *after_name;
char *numchk;
+ char *tok_ptr;
+ char *s;
char numbuf[80];
- unsigned found;
- static char buffer[MAX_ENTRY_SIZE];
- char *ptr;
+ int ch;
int dot_flag = FALSE;
+ int type;
+ long number;
long token_start;
+ unsigned found;
+#ifdef TRACE
+ int old_line;
+ int old_col;
+#endif
if (pushtype != NO_PUSHBACK) {
int retval = pushtype;
- _nc_set_type(pushname);
+ _nc_set_type(pushname != 0 ? pushname : "");
DEBUG(3, ("pushed-back token: `%s', class %d",
_nc_curr_token.tk_name, pushtype));
pushtype = NO_PUSHBACK;
- pushname[0] = '\0';
+ if (pushname != 0)
+ pushname[0] = '\0';
/* currtok wasn't altered by _nc_push_token() */
return (retval);
}
- if (end_of_stream())
+ if (end_of_stream()) {
+ yyin = 0;
+ next_char(); /* frees its allocated memory */
+ if (tok_buf != 0) {
+ if (_nc_curr_token.tk_name == tok_buf)
+ _nc_curr_token.tk_name = 0;
+ FreeAndNull(tok_buf);
+ }
return (EOF);
+ }
start_token:
token_start = stream_pos();
- while ((ch = next_char()) == '\n' || iswhite(ch))
+ while ((ch = next_char()) == '\n' || iswhite(ch)) {
+ if (ch == '\n')
+ had_newline = TRUE;
continue;
+ }
ch = eat_escaped_newline(ch);
+#ifdef TRACE
+ old_line = _nc_curr_line;
+ old_col = _nc_curr_col;
+#endif
if (ch == EOF)
type = EOF;
else {
@@ -206,33 +426,44 @@ _nc_get_token(bool silent)
}
/* have to make some punctuation chars legal for terminfo */
- if (!isalnum(ch)
+ if (!isalnum(UChar(ch))
#if NCURSES_EXT_FUNCS
&& !(ch == '.' && _nc_disable_period)
#endif
&& !strchr(terminfo_punct, (char) ch)) {
if (!silent)
- _nc_warning("Illegal character (expected alphanumeric or %s) - %s",
+ _nc_warning("Illegal character (expected alphanumeric or %s) - '%s'",
terminfo_punct, unctrl((chtype) ch));
_nc_panic_mode(separator);
goto start_token;
}
- ptr = buffer;
- *(ptr++) = ch;
+ if (tok_buf == 0)
+ tok_buf = typeMalloc(char, TOK_BUF_SIZE);
- if (first_column) {
- char *desc;
+#ifdef TRACE
+ old_line = _nc_curr_line;
+ old_col = _nc_curr_col;
+#endif
+ tok_ptr = tok_buf;
+ AddCh(ch);
+ if (first_column) {
_nc_comment_start = token_start;
_nc_comment_end = _nc_curr_file_pos;
_nc_start_line = _nc_curr_line;
_nc_syntax = ERR;
+ after_name = 0;
+ after_list = 0;
while ((ch = next_char()) != '\n') {
- if (ch == EOF)
- _nc_err_abort("premature EOF");
- else if (ch == ':' && last_char() != ',') {
+ if (ch == EOF) {
+ _nc_err_abort(MSG_NO_INPUTS);
+ } else if (ch == '|') {
+ after_list = tok_ptr;
+ if (after_name == 0)
+ after_name = tok_ptr;
+ } else if (ch == ':' && last_char() != ',') {
_nc_syntax = SYN_TERMCAP;
separator = ':';
break;
@@ -240,20 +471,29 @@ _nc_get_token(bool silent)
_nc_syntax = SYN_TERMINFO;
separator = ',';
/*
- * Fall-through here is not an accident. The idea is that
- * if we see a comma, we figure this is terminfo unless we
- * subsequently run into a colon -- but we don't stop
- * looking for that colon until hitting a newline. This
+ * If we did not see a '|', then we found a name with no
+ * aliases or description.
+ */
+ if (after_name == 0)
+ break;
+ /*
+ * If we see a comma, we assume this is terminfo unless we
+ * subsequently run into a colon. But we don't stop
+ * looking for a colon until hitting a newline. This
* allows commas to be embedded in description fields of
* either syntax.
*/
- /* FALLTHRU */
} else
ch = eat_escaped_newline(ch);
- *ptr++ = ch;
+ if (OkToAdd()) {
+ AddCh(ch);
+ } else {
+ ch = EOF;
+ break;
+ }
}
- ptr[0] = '\0';
+ *tok_ptr = '\0';
if (_nc_syntax == ERR) {
/*
* Grrr...what we ought to do here is barf, complaining that
@@ -265,65 +505,71 @@ _nc_get_token(bool silent)
separator = ':';
} else if (_nc_syntax == SYN_TERMINFO) {
/* throw away trailing /, *$/ */
- for (--ptr; iswhite(*ptr) || *ptr == ','; ptr--)
+ for (--tok_ptr;
+ iswhite(*tok_ptr) || *tok_ptr == ',';
+ tok_ptr--)
continue;
- ptr[1] = '\0';
+ tok_ptr[1] = '\0';
}
/*
* This is the soonest we have the terminal name fetched. Set up
- * for following warning messages.
+ * for following warning messages. If there's no '|', then there
+ * is no description.
*/
- ptr = strchr(buffer, '|');
- if (ptr == (char *) NULL)
- ptr = buffer + strlen(buffer);
- ch = *ptr;
- *ptr = '\0';
- _nc_set_type(buffer);
- *ptr = ch;
+ if (after_name != 0) {
+ ch = *after_name;
+ *after_name = '\0';
+ _nc_set_type(tok_buf);
+ *after_name = (char) ch;
+ }
/*
* Compute the boundary between the aliases and the description
* field for syntax-checking purposes.
*/
- desc = strrchr(buffer, '|');
- if (!silent && desc) {
- if (*desc == '\0')
- _nc_warning("empty longname field");
- else if (strchr(desc, ' ') == (char *) NULL)
- _nc_warning("older tic versions may treat the description field as an alias");
+ if (after_list != 0) {
+ if (!silent) {
+ if (*after_list == '\0')
+ _nc_warning("empty longname field");
+ else if (strchr(after_list, ' ') == 0)
+ _nc_warning("older tic versions may treat the description field as an alias");
+ }
+ } else {
+ after_list = tok_buf + strlen(tok_buf);
+ DEBUG(1, ("missing description"));
}
- if (!desc)
- desc = buffer + strlen(buffer);
/*
* Whitespace in a name field other than the long name can confuse
* rdist and some termcap tools. Slashes are a no-no. Other
* special characters can be dangerous due to shell expansion.
*/
- for (ptr = buffer; ptr < desc; ptr++) {
- if (isspace(CharOf(*ptr))) {
+ for (s = tok_buf; s < after_list; ++s) {
+ if (isspace(UChar(*s))) {
if (!silent)
_nc_warning("whitespace in name or alias field");
break;
- } else if (*ptr == '/') {
+ } else if (*s == '/') {
if (!silent)
_nc_warning("slashes aren't allowed in names or aliases");
break;
- } else if (strchr("$[]!*?", *ptr)) {
+ } else if (strchr("$[]!*?", *s)) {
if (!silent)
- _nc_warning("dubious character `%c' in name or alias field", *ptr);
+ _nc_warning("dubious character `%c' in name or alias field", *s);
break;
}
}
- ptr = buffer;
-
- _nc_curr_token.tk_name = buffer;
+ _nc_curr_token.tk_name = tok_buf;
type = NAMES;
} else {
+ if (had_newline && _nc_syntax == SYN_TERMCAP) {
+ _nc_warning("Missing backslash before newline");
+ had_newline = FALSE;
+ }
while ((ch = next_char()) != EOF) {
- if (!isalnum(ch)) {
+ if (!isalnum(UChar(ch))) {
if (_nc_syntax == SYN_TERMINFO) {
if (ch != '_')
break;
@@ -332,30 +578,35 @@ _nc_get_token(bool silent)
break;
}
}
- *(ptr++) = ch;
+ if (OkToAdd()) {
+ AddCh(ch);
+ } else {
+ ch = EOF;
+ break;
+ }
}
- *ptr++ = '\0';
+ *tok_ptr++ = '\0'; /* separate name/value in buffer */
switch (ch) {
case ',':
case ':':
if (ch != separator)
_nc_err_abort("Separator inconsistent with syntax");
- _nc_curr_token.tk_name = buffer;
+ _nc_curr_token.tk_name = tok_buf;
type = BOOLEAN;
break;
case '@':
if ((ch = next_char()) != separator && !silent)
_nc_warning("Missing separator after `%s', have %s",
- buffer, unctrl((chtype) ch));
- _nc_curr_token.tk_name = buffer;
+ tok_buf, unctrl((chtype) ch));
+ _nc_curr_token.tk_name = tok_buf;
type = CANCEL;
break;
case '#':
found = 0;
while (isalnum(ch = next_char())) {
- numbuf[found++] = ch;
+ numbuf[found++] = (char) ch;
if (found >= sizeof(numbuf) - 1)
break;
}
@@ -363,21 +614,21 @@ _nc_get_token(bool silent)
number = strtol(numbuf, &numchk, 0);
if (!silent) {
if (numchk == numbuf)
- _nc_warning("no value given for `%s'", buffer);
+ _nc_warning("no value given for `%s'", tok_buf);
if ((*numchk != '\0') || (ch != separator))
_nc_warning("Missing separator");
}
- _nc_curr_token.tk_name = buffer;
+ _nc_curr_token.tk_name = tok_buf;
_nc_curr_token.tk_valnumber = number;
type = NUMBER;
break;
case '=':
- ch = _nc_trans_string(ptr, buffer + sizeof(buffer));
+ ch = _nc_trans_string(tok_ptr, tok_buf + TOK_BUF_SIZE);
if (!silent && ch != separator)
_nc_warning("Missing separator");
- _nc_curr_token.tk_name = buffer;
- _nc_curr_token.tk_valstring = ptr;
+ _nc_curr_token.tk_name = tok_buf;
+ _nc_curr_token.tk_valstring = tok_ptr;
type = STRING;
break;
@@ -388,7 +639,7 @@ _nc_get_token(bool silent)
/* just to get rid of the compiler warning */
type = UNDEF;
if (!silent)
- _nc_warning("Illegal character - %s", unctrl((chtype) ch));
+ _nc_warning("Illegal character - '%s'", unctrl((chtype) ch));
}
} /* end else (first_column == FALSE) */
} /* end else (ch != EOF) */
@@ -399,6 +650,11 @@ _nc_get_token(bool silent)
if (dot_flag == TRUE)
DEBUG(8, ("Commented out "));
+ if (_nc_tracing >= DEBUG_LEVEL(8)) {
+ _tracef("parsed %d.%d to %d.%d",
+ old_line, old_col,
+ _nc_curr_line, _nc_curr_col);
+ }
if (_nc_tracing >= DEBUG_LEVEL(7)) {
switch (type) {
case BOOLEAN:
@@ -443,8 +699,9 @@ _nc_get_token(bool silent)
type = _nc_get_token(silent);
DEBUG(3, ("token: `%s', class %d",
- _nc_curr_token.tk_name != 0 ? _nc_curr_token.tk_name :
- "<null>",
+ ((_nc_curr_token.tk_name != 0)
+ ? _nc_curr_token.tk_name
+ : "<null>"),
type));
return (type);
@@ -469,7 +726,7 @@ _nc_get_token(bool silent)
*
*/
-NCURSES_EXPORT(char)
+NCURSES_EXPORT(int)
_nc_trans_string(char *ptr, char *last)
{
int count = 0;
@@ -480,17 +737,24 @@ _nc_trans_string(char *ptr, char *last)
bool long_warning = FALSE;
while ((ch = c = next_char()) != (chtype) separator && c != EOF) {
- if (ptr == (last - 1))
+ if (ptr >= (last - 1)) {
+ if (c != EOF) {
+ while ((c = next_char()) != separator && c != EOF) {
+ ;
+ }
+ ch = c;
+ }
break;
+ }
if ((_nc_syntax == SYN_TERMCAP) && c == '\n')
break;
if (ch == '^' && last_ch != '%') {
ch = c = next_char();
if (c == EOF)
- _nc_err_abort("Premature EOF");
+ _nc_err_abort(MSG_NO_INPUTS);
if (!(is7bits(ch) && isprint(ch))) {
- _nc_warning("Illegal ^ character - %s", unctrl(ch));
+ _nc_warning("Illegal ^ character - '%s'", unctrl(ch));
}
if (ch == '?') {
*(ptr++) = '\177';
@@ -504,14 +768,14 @@ _nc_trans_string(char *ptr, char *last)
} else if (ch == '\\') {
ch = c = next_char();
if (c == EOF)
- _nc_err_abort("Premature EOF");
+ _nc_err_abort(MSG_NO_INPUTS);
if (ch >= '0' && ch <= '7') {
number = ch - '0';
for (i = 0; i < 2; i++) {
ch = c = next_char();
if (c == EOF)
- _nc_err_abort("Premature EOF");
+ _nc_err_abort(MSG_NO_INPUTS);
if (c < '0' || c > '7') {
if (isdigit(c)) {
@@ -585,21 +849,31 @@ _nc_trans_string(char *ptr, char *last)
continue;
default:
- _nc_warning("Illegal character %s in \\ sequence",
+ _nc_warning("Illegal character '%s' in \\ sequence",
unctrl(ch));
+ /* FALLTHRU */
+ case '|':
*(ptr++) = (char) ch;
} /* endswitch (ch) */
} /* endelse (ch < '0' || ch > '7') */
}
/* end else if (ch == '\\') */
else if (ch == '\n' && (_nc_syntax == SYN_TERMINFO)) {
- /* newlines embedded in a terminfo string are ignored */
+ /*
+ * Newlines embedded in a terminfo string are ignored, provided
+ * that the next line begins with whitespace.
+ */
ignored = TRUE;
} else {
*(ptr++) = (char) ch;
}
if (!ignored) {
+ if (_nc_curr_col <= 1) {
+ push_back((char) ch);
+ ch = '\n';
+ break;
+ }
last_ch = ch;
count++;
}
@@ -629,14 +903,19 @@ _nc_push_token(int tokclass)
/*
* This implementation is kind of bogus, it will fail if we ever do more
* than one pushback at a time between get_token() calls. It relies on the
- * fact that curr_tok is static storage that nothing but get_token()
- * touches.
+ * fact that _nc_curr_token is static storage that nothing but
+ * _nc_get_token() touches.
*/
pushtype = tokclass;
+ if (pushname == 0)
+ pushname = typeMalloc(char, MAX_NAME_SIZE + 1);
_nc_get_type(pushname);
DEBUG(3, ("pushing token: `%s', class %d",
- _nc_curr_token.tk_name, pushtype));
+ ((_nc_curr_token.tk_name != 0)
+ ? _nc_curr_token.tk_name
+ : "<null>"),
+ pushtype));
}
/*
@@ -656,168 +935,12 @@ _nc_panic_mode(char ch)
}
}
-/*****************************************************************************
- *
- * Character-stream handling
- *
- *****************************************************************************/
-
-#define LEXBUFSIZ 1024
-
-static char *bufptr; /* otherwise, the input buffer pointer */
-static char *bufstart; /* start of buffer so we can compute offsets */
-static FILE *yyin; /* scanner's input file descriptor */
-
-/*
- * _nc_reset_input()
- *
- * Resets the input-reading routines. Used on initialization,
- * or after a seek has been done. Exactly one argument must be
- * non-null.
- */
-
+#if NO_LEAKS
NCURSES_EXPORT(void)
-_nc_reset_input(FILE * fp, char *buf)
-{
- pushtype = NO_PUSHBACK;
- pushname[0] = '\0';
- yyin = fp;
- bufstart = bufptr = buf;
- _nc_curr_file_pos = 0L;
- if (fp != 0)
- _nc_curr_line = 0;
- _nc_curr_col = 0;
-}
-
-/*
- * int last_char()
- *
- * Returns the final nonblank character on the current input buffer
- */
-static int
-last_char(void)
-{
- size_t len = strlen(bufptr);
- while (len--) {
- if (!isspace(CharOf(bufptr[len])))
- return bufptr[len];
- }
- return 0;
-}
-
-/*
- * int next_char()
- *
- * Returns the next character in the input stream. Comments and leading
- * white space are stripped.
- *
- * The global state variable 'firstcolumn' is set TRUE if the character
- * returned is from the first column of the input line.
- *
- * The global variable _nc_curr_line is incremented for each new line.
- * The global variable _nc_curr_file_pos is set to the file offset of the
- * beginning of each line.
- */
-
-static int
-next_char(void)
+_nc_comp_scan_leaks(void)
{
- if (!yyin) {
- /*
- * An string with an embedded null will truncate the input. This is
- * intentional (we don't read binary files here).
- */
- if (*bufptr == '\0')
- return (EOF);
- if (*bufptr == '\n') {
- _nc_curr_line++;
- _nc_curr_col = 0;
- }
- } else if (!bufptr || !*bufptr) {
- /*
- * In theory this could be recoded to do its I/O one character at a
- * time, saving the buffer space. In practice, this turns out to be
- * quite hard to get completely right. Try it and see. If you
- * succeed, don't forget to hack push_back() correspondingly.
- */
- static char *result;
- static size_t allocated;
- size_t used;
- size_t len;
-
- do {
- bufstart = 0;
- used = 0;
- do {
- if (used + (LEXBUFSIZ / 4) >= allocated) {
- allocated += (allocated + LEXBUFSIZ);
- result = _nc_doalloc(result, allocated);
- if (result == 0)
- return (EOF);
- }
- if (used == 0)
- _nc_curr_file_pos = ftell(yyin);
-
- if (fgets(result + used, allocated - used, yyin) != NULL) {
- bufstart = result;
- if (used == 0) {
- _nc_curr_line++;
- _nc_curr_col = 0;
- }
- } else {
- if (used != 0)
- strlcat(result, "\n", allocated);
- }
- if ((bufptr = bufstart) != 0) {
- used = strlen(bufptr);
- while (iswhite(*bufptr))
- bufptr++;
-
- /*
- * Treat a trailing <cr><lf> the same as a <newline> so we
- * can read files on OS/2, etc.
- */
- if ((len = strlen(bufptr)) > 1) {
- if (bufptr[len - 1] == '\n'
- && bufptr[len - 2] == '\r') {
- len--;
- bufptr[len - 1] = '\n';
- bufptr[len] = '\0';
- }
- }
- } else {
- return (EOF);
- }
- } while (bufptr[len - 1] != '\n'); /* complete a line */
- } while (result[0] == '#'); /* ignore comments */
+ if (pushname != 0) {
+ FreeAndNull(pushname);
}
-
- first_column = (bufptr == bufstart);
-
- _nc_curr_col++;
- return (*bufptr++);
-}
-
-static void
-push_back(char c)
-/* push a character back onto the input stream */
-{
- if (bufptr == bufstart)
- _nc_syserr_abort("Can't backspace off beginning of line");
- *--bufptr = c;
-}
-
-static long
-stream_pos(void)
-/* return our current character position in the input stream */
-{
- return (yyin ? ftell(yyin) : (bufptr ? bufptr - bufstart : 0));
-}
-
-static bool
-end_of_stream(void)
-/* are we at end of input? */
-{
- return ((yyin ? feof(yyin) : (bufptr && *bufptr == '\0'))
- ? TRUE : FALSE);
}
+#endif
diff --git a/lib/libcurses/tinfo/db_iterator.c b/lib/libcurses/tinfo/db_iterator.c
new file mode 100644
index 00000000000..84418492672
--- /dev/null
+++ b/lib/libcurses/tinfo/db_iterator.c
@@ -0,0 +1,227 @@
+/* $OpenBSD: db_iterator.c,v 1.1 2010/01/12 23:22:06 nicm Exp $ */
+
+/****************************************************************************
+ * Copyright (c) 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"), to deal in the Software without restriction, including *
+ * without limitation the rights to use, copy, modify, merge, publish, *
+ * distribute, distribute with modifications, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included *
+ * in all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey *
+ ****************************************************************************/
+
+/*
+ * Iterators for terminal databases.
+ */
+
+#include <curses.priv.h>
+
+#include <tic.h>
+
+MODULE_ID("$Id: db_iterator.c,v 1.1 2010/01/12 23:22:06 nicm Exp $")
+
+#define HaveTicDirectory _nc_globals.have_tic_directory
+#define KeepTicDirectory _nc_globals.keep_tic_directory
+#define TicDirectory _nc_globals.tic_directory
+
+/*
+ * Record the "official" location of the terminfo directory, according to
+ * the place where we're writing to, or the normal default, if not.
+ */
+NCURSES_EXPORT(const char *)
+_nc_tic_dir(const char *path)
+{
+ if (!KeepTicDirectory) {
+ if (path != 0) {
+ TicDirectory = path;
+ HaveTicDirectory = TRUE;
+ } else if (!HaveTicDirectory && use_terminfo_vars()) {
+ char *envp;
+ if ((envp = getenv("TERMINFO")) != 0)
+ return _nc_tic_dir(envp);
+ }
+ }
+ return TicDirectory;
+}
+
+/*
+ * Special fix to prevent the terminfo directory from being moved after tic
+ * has chdir'd to it. If we let it be changed, then if $TERMINFO has a
+ * relative path, we'll lose track of the actual directory.
+ */
+NCURSES_EXPORT(void)
+_nc_keep_tic_dir(const char *path)
+{
+ _nc_tic_dir(path);
+ KeepTicDirectory = TRUE;
+}
+
+/*
+ * Process the list of :-separated directories, looking for the terminal type.
+ * We don't use strtok because it does not show us empty tokens.
+ */
+#define ThisDbList _nc_globals.dbi_list
+#define ThisDbSize _nc_globals.dbi_size
+
+/*
+ * Cleanup.
+ */
+NCURSES_EXPORT(void)
+_nc_last_db(void)
+{
+ if (ThisDbList != 0) {
+ FreeAndNull(ThisDbList);
+ }
+ ThisDbSize = 0;
+}
+
+/* The TERMINFO_DIRS value, if defined by the configure script, begins with a
+ * ":", which will be interpreted as TERMINFO.
+ */
+static const char *
+next_list_item(const char *source, int *offset)
+{
+ if (source != 0) {
+ FreeIfNeeded(ThisDbList);
+ ThisDbList = strdup(source);
+ ThisDbSize = strlen(source);
+ }
+
+ if (ThisDbList != 0 && ThisDbSize && *offset < ThisDbSize) {
+ static char system_db[] = TERMINFO;
+ char *result = ThisDbList + *offset;
+ char *marker = strchr(result, NCURSES_PATHSEP);
+
+ /*
+ * Put a null on the marker if a separator was found. Set the offset
+ * to the next position after the marker so we can call this function
+ * again, using the data at the offset.
+ */
+ if (marker == 0) {
+ *offset += strlen(result) + 1;
+ marker = result + *offset;
+ } else {
+ *marker++ = 0;
+ *offset = marker - ThisDbList;
+ }
+ if (*result == 0 && result != (ThisDbList + ThisDbSize))
+ result = system_db;
+ return result;
+ }
+ return 0;
+}
+
+#define NEXT_DBD(var, offset) next_list_item((*offset == 0) ? var : 0, offset)
+
+/*
+ * This is a simple iterator which allows the caller to step through the
+ * possible locations for a terminfo directory. ncurses uses this to find
+ * terminfo files to read.
+ */
+NCURSES_EXPORT(const char *)
+_nc_next_db(DBDIRS * state, int *offset)
+{
+ const char *result;
+ char *envp;
+
+ while (*state < dbdLAST) {
+ DBDIRS next = (DBDIRS) ((int) (*state) + 1);
+
+ result = 0;
+
+ switch (*state) {
+ case dbdTIC:
+ if (HaveTicDirectory)
+ result = _nc_tic_dir(0);
+ break;
+#if USE_DATABASE
+ case dbdEnvOnce:
+ if (use_terminfo_vars()) {
+ if ((envp = getenv("TERMINFO")) != 0)
+ result = _nc_tic_dir(envp);
+ }
+ break;
+ case dbdHome:
+ if (use_terminfo_vars()) {
+ result = _nc_home_terminfo();
+ }
+ break;
+ case dbdEnvList:
+ if (use_terminfo_vars()) {
+ if ((result = NEXT_DBD(getenv("TERMINFO_DIRS"), offset)) != 0)
+ next = *state;
+ }
+ break;
+ case dbdCfgList:
+#ifdef TERMINFO_DIRS
+ if ((result = NEXT_DBD(TERMINFO_DIRS, offset)) != 0)
+ next = *state;
+#endif
+ break;
+ case dbdCfgOnce:
+#ifndef TERMINFO_DIRS
+ result = TERMINFO;
+#endif
+ break;
+#endif /* USE_DATABASE */
+#if USE_TERMCAP
+ case dbdEnvOnce2:
+ if (use_terminfo_vars()) {
+ if ((envp = getenv("TERMCAP")) != 0)
+ result = _nc_tic_dir(envp);
+ }
+ break;
+ case dbdEnvList2:
+ if (use_terminfo_vars()) {
+ if ((result = NEXT_DBD(getenv("TERMPATH"), offset)) != 0)
+ next = *state;
+ }
+ break;
+ case dbdCfgList2:
+ if ((result = NEXT_DBD(TERMPATH, offset)) != 0)
+ next = *state;
+ break;
+#endif /* USE_TERMCAP */
+ case dbdLAST:
+ break;
+ }
+ if (*state != next) {
+ *state = next;
+ *offset = 0;
+ _nc_last_db();
+ }
+ if (result != 0) {
+ return result;
+ }
+ }
+ return 0;
+}
+
+NCURSES_EXPORT(void)
+_nc_first_db(DBDIRS * state, int *offset)
+{
+ *state = dbdTIC;
+ *offset = 0;
+}
diff --git a/lib/libcurses/tinfo/doalloc.c b/lib/libcurses/tinfo/doalloc.c
index 54659f55888..a28a5cbdffb 100644
--- a/lib/libcurses/tinfo/doalloc.c
+++ b/lib/libcurses/tinfo/doalloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: doalloc.c,v 1.6 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: doalloc.c,v 1.7 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
* Copyright (c) 1998,2000 Free Software Foundation, Inc. *
@@ -41,7 +41,7 @@
#include <curses.priv.h>
-MODULE_ID("$From: doalloc.c,v 1.7 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: doalloc.c,v 1.7 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(void *)
_nc_doalloc(void *oldp, size_t amount)
@@ -54,7 +54,7 @@ _nc_doalloc(void *oldp, size_t amount)
errno = ENOMEM; /* just in case 'free' reset */
}
} else {
- newp = typeMalloc(char, amount);
+ newp = malloc(amount);
}
return newp;
}
@@ -67,7 +67,7 @@ _nc_strdup(const char *src)
size_t dsize;
if (src != 0) {
dsize = strlen(src) + 1;
- dst = typeMalloc(char, dsize);
+ dst = typeMalloc(char, strlen(src) + 1);
if (dst != 0) {
(void) strlcpy(dst, src, dsize);
}
diff --git a/lib/libcurses/tinfo/entries.c b/lib/libcurses/tinfo/entries.c
new file mode 100644
index 00000000000..ad76fadfb83
--- /dev/null
+++ b/lib/libcurses/tinfo/entries.c
@@ -0,0 +1,147 @@
+/* $OpenBSD: entries.c,v 1.1 2010/01/12 23:22:06 nicm Exp $ */
+
+/****************************************************************************
+ * Copyright (c) 2006-2007,2008 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+ * copy of this software and associated documentation files (the *
+ * "Software"), to deal in the Software without restriction, including *
+ * without limitation the rights to use, copy, modify, merge, publish, *
+ * distribute, distribute with modifications, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included *
+ * in all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+
+#include <tic.h>
+#include <term_entry.h>
+
+MODULE_ID("$Id: entries.c,v 1.1 2010/01/12 23:22:06 nicm Exp $")
+
+/****************************************************************************
+ *
+ * Entry queue handling
+ *
+ ****************************************************************************/
+/*
+ * The entry list is a doubly linked list with NULLs terminating the lists:
+ *
+ * --------- --------- ---------
+ * | | | | | | offset
+ * |-------| |-------| |-------|
+ * | ----+-->| ----+-->| NULL | next
+ * |-------| |-------| |-------|
+ * | NULL |<--+---- |<--+---- | last
+ * --------- --------- ---------
+ * ^ ^
+ * | |
+ * | |
+ * _nc_head _nc_tail
+ */
+
+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)
+/* delink the allocated storage for the given list entry */
+{
+ ENTRY *ep, *last;
+
+ for (last = 0, ep = headp; ep != 0; last = ep, ep = ep->next) {
+ if (&(ep->tterm) == tterm) {
+ if (last != 0) {
+ last->next = ep->next;
+ }
+ if (ep == _nc_head) {
+ _nc_head = ep->next;
+ }
+ if (ep == _nc_tail) {
+ _nc_tail = last;
+ }
+ break;
+ }
+ }
+ return ep;
+}
+
+NCURSES_EXPORT(void)
+_nc_leaks_tinfo(void)
+{
+#if NO_LEAKS
+ char *s;
+#endif
+
+ T((T_CALLED("_nc_free_tinfo()")));
+#if NO_LEAKS
+ _nc_free_tparm();
+ _nc_tgetent_leaks();
+ _nc_free_entries(_nc_head);
+ _nc_get_type(0);
+ _nc_first_name(0);
+ _nc_keyname_leaks();
+#if BROKEN_LINKER || USE_REENTRANT
+ _nc_names_leaks();
+ _nc_codes_leaks();
+ FreeIfNeeded(_nc_prescreen.real_acs_map);
+#endif
+
+ if ((s = _nc_home_terminfo()) != 0)
+ free(s);
+#endif /* NO_LEAKS */
+ returnVoid;
+}
+
+#if NO_LEAKS
+NCURSES_EXPORT(void)
+_nc_free_tinfo(int code)
+{
+ _nc_leaks_tinfo();
+ exit(code);
+}
+#endif
diff --git a/lib/libcurses/tinfo/free_ttype.c b/lib/libcurses/tinfo/free_ttype.c
index 3fac7bc6122..a506df3eadf 100644
--- a/lib/libcurses/tinfo/free_ttype.c
+++ b/lib/libcurses/tinfo/free_ttype.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: free_ttype.c,v 1.6 2007/04/16 11:53:38 otto Exp $ */
+/* $OpenBSD: free_ttype.c,v 1.7 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1999-2005,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 *
@@ -29,7 +29,7 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1999 *
+ * Author: Thomas E. Dickey 1999-on *
****************************************************************************/
/*
@@ -45,11 +45,13 @@
#include <tic.h>
#include <term_entry.h>
-MODULE_ID("$From: free_ttype.c,v 1.7 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: free_ttype.c,v 1.7 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(void)
-_nc_free_termtype(TERMTYPE * ptr)
+_nc_free_termtype(TERMTYPE *ptr)
{
+ T(("_nc_free_termtype(%s)", ptr->term_names));
+
FreeIfNeeded(ptr->str_table);
FreeIfNeeded(ptr->Booleans);
FreeIfNeeded(ptr->Numbers);
@@ -59,6 +61,7 @@ _nc_free_termtype(TERMTYPE * ptr)
FreeIfNeeded(ptr->ext_Names);
#endif
memset(ptr, 0, sizeof(TERMTYPE));
+ _nc_free_entry(_nc_head, ptr);
}
#if NCURSES_XNAMES
@@ -68,7 +71,9 @@ NCURSES_EXPORT(int)
use_extended_names(bool flag)
{
int oldflag = _nc_user_definable;
+
+ T((T_CALLED("use_extended_names(%d)"), flag));
_nc_user_definable = flag;
- return oldflag;
+ returnBool(oldflag);
}
#endif
diff --git a/lib/libcurses/tinfo/getenv_num.c b/lib/libcurses/tinfo/getenv_num.c
index 80723dbedf8..b4c91796ca5 100644
--- a/lib/libcurses/tinfo/getenv_num.c
+++ b/lib/libcurses/tinfo/getenv_num.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getenv_num.c,v 1.2 2001/01/22 18:01:51 millert Exp $ */
+/* $OpenBSD: getenv_num.c,v 1.3 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
* Copyright (c) 1998,2000 Free Software Foundation, Inc. *
@@ -38,7 +38,7 @@
#include <curses.priv.h>
-MODULE_ID("$From: getenv_num.c,v 1.3 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: getenv_num.c,v 1.3 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(int)
_nc_getenv_num(const char *name)
diff --git a/lib/libcurses/tinfo/hashed_db.c b/lib/libcurses/tinfo/hashed_db.c
new file mode 100644
index 00000000000..2ce463a707f
--- /dev/null
+++ b/lib/libcurses/tinfo/hashed_db.c
@@ -0,0 +1,262 @@
+/* $OpenBSD: hashed_db.c,v 1.1 2010/01/12 23:22:06 nicm Exp $ */
+
+/****************************************************************************
+ * Copyright (c) 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 *
+ * "Software"), to deal in the Software without restriction, including *
+ * without limitation the rights to use, copy, modify, merge, publish, *
+ * distribute, distribute with modifications, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included *
+ * in all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey 2006 *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+#include <tic.h>
+#include <hashed_db.h>
+
+#if USE_HASHED_DB
+
+MODULE_ID("$Id: hashed_db.c,v 1.1 2010/01/12 23:22:06 nicm Exp $")
+
+#if HASHED_DB_API >= 2
+static DBC *cursor;
+#endif
+
+/*
+ * Open the database.
+ */
+NCURSES_EXPORT(DB *)
+_nc_db_open(const char *path, bool modify)
+{
+ DB *result = 0;
+
+#if HASHED_DB_API >= 4
+ db_create(&result, NULL, 0);
+ result->open(result,
+ NULL,
+ path,
+ NULL,
+ DB_HASH,
+ modify ? DB_CREATE : DB_RDONLY,
+ 0644);
+#elif HASHED_DB_API >= 3
+ db_create(&result, NULL, 0);
+ result->open(result,
+ path,
+ NULL,
+ DB_HASH,
+ modify ? DB_CREATE : DB_RDONLY,
+ 0644);
+#elif HASHED_DB_API >= 2
+ int code;
+
+ if ((code = db_open(path,
+ DB_HASH,
+ modify ? DB_CREATE : DB_RDONLY,
+ 0644,
+ (DB_ENV *) 0,
+ (DB_INFO *) 0,
+ &result)) != 0) {
+ T(("cannot open %s: %s", path, strerror(code)));
+ result = 0;
+ } else {
+ T(("opened %s", path));
+ }
+#else
+ result = dbopen(path,
+ modify ? (O_CREAT | O_RDWR) : O_RDONLY,
+ 0644,
+ DB_HASH,
+ NULL);
+ if (result != 0) {
+ T(("opened %s", path));
+ }
+#endif
+ return result;
+}
+
+/*
+ * Close the database. Do not attempt to use the 'db' handle after this call.
+ */
+NCURSES_EXPORT(int)
+_nc_db_close(DB * db)
+{
+ int result;
+
+#if HASHED_DB_API >= 2
+ result = db->close(db, 0);
+#else
+ result = db->close(db);
+#endif
+ return result;
+}
+
+/*
+ * Write a record to the database.
+ *
+ * Returns 0 on success.
+ *
+ * FIXME: the FreeBSD cap_mkdb program assumes the database could have
+ * duplicates. There appears to be no good reason for that (review/fix).
+ */
+NCURSES_EXPORT(int)
+_nc_db_put(DB * db, DBT * key, DBT * data)
+{
+ int result;
+#if HASHED_DB_API >= 2
+ /* remove any pre-existing value, since we do not want duplicates */
+ (void) db->del(db, NULL, key, 0);
+ result = db->put(db, NULL, key, data, DB_NOOVERWRITE);
+#else
+ result = db->put(db, key, data, R_NOOVERWRITE);
+#endif
+ return result;
+}
+
+/*
+ * Read a record from the database.
+ *
+ * Returns 0 on success.
+ */
+NCURSES_EXPORT(int)
+_nc_db_get(DB * db, DBT * key, DBT * data)
+{
+ int result;
+
+ memset(data, 0, sizeof(*data));
+#if HASHED_DB_API >= 2
+ result = db->get(db, NULL, key, data, 0);
+#else
+ result = db->get(db, key, data, 0);
+#endif
+ return result;
+}
+
+/*
+ * Read the first record from the database, ignoring order.
+ *
+ * Returns 0 on success.
+ */
+NCURSES_EXPORT(int)
+_nc_db_first(DB * db, DBT * key, DBT * data)
+{
+ int result;
+
+ memset(key, 0, sizeof(*key));
+ memset(data, 0, sizeof(*data));
+#if HASHED_DB_API >= 2
+ if ((result = db->cursor(db, NULL, &cursor, 0)) == 0) {
+ result = cursor->c_get(cursor, key, data, DB_FIRST);
+ }
+#else
+ result = db->seq(db, key, data, 0);
+#endif
+ return result;
+}
+
+/*
+ * Read the next record from the database, ignoring order.
+ *
+ * Returns 0 on success.
+ */
+NCURSES_EXPORT(int)
+_nc_db_next(DB * db, DBT * key, DBT * data)
+{
+ int result;
+
+#if HASHED_DB_API >= 2
+ (void) db;
+ if (cursor != 0) {
+ result = cursor->c_get(cursor, key, data, DB_NEXT);
+ } else {
+ result = -1;
+ }
+#else
+ result = db->seq(db, key, data, 0);
+#endif
+ return result;
+}
+
+/*
+ * Check if a record is a terminfo index record. Index records are those that
+ * contain only an alias pointing to a list of aliases.
+ */
+NCURSES_EXPORT(bool)
+_nc_db_have_index(DBT * key, DBT * data, char **buffer, int *size)
+{
+ bool result = FALSE;
+ int used = data->size - 1;
+ char *have = (char *) data->data;
+
+ (void) key;
+ if (*have++ == 2) {
+ result = TRUE;
+ }
+ /*
+ * Update params in any case for consistency with _nc_db_have_data().
+ */
+ *buffer = have;
+ *size = used;
+ return result;
+}
+
+/*
+ * Check if a record is the terminfo data record. Ignore index records, e.g.,
+ * those that contain only an alias pointing to a list of aliases.
+ */
+NCURSES_EXPORT(bool)
+_nc_db_have_data(DBT * key, DBT * data, char **buffer, int *size)
+{
+ bool result = FALSE;
+ int used = data->size - 1;
+ char *have = (char *) data->data;
+
+ if (*have++ == 0) {
+ if (data->size > key->size
+ && IS_TIC_MAGIC(have)) {
+ result = TRUE;
+ }
+ }
+ /*
+ * Update params in any case to make it simple to follow a index record
+ * to the data record.
+ */
+ *buffer = have;
+ *size = used;
+ return result;
+}
+
+#else
+
+extern
+NCURSES_EXPORT(void)
+_nc_hashed_db(void);
+
+NCURSES_EXPORT(void)
+_nc_hashed_db(void)
+{
+}
+
+#endif /* USE_HASHED_DB */
diff --git a/lib/libcurses/tinfo/home_terminfo.c b/lib/libcurses/tinfo/home_terminfo.c
index 955955484fc..a33924aa46a 100644
--- a/lib/libcurses/tinfo/home_terminfo.c
+++ b/lib/libcurses/tinfo/home_terminfo.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: home_terminfo.c,v 1.8 2003/03/17 19:16:59 millert Exp $ */
+/* $OpenBSD: home_terminfo.c,v 1.9 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -29,7 +29,7 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1998,2000 *
+ * Author: Thomas E. Dickey *
****************************************************************************/
/*
@@ -39,29 +39,31 @@
#include <curses.priv.h>
#include <tic.h>
-MODULE_ID("$From: home_terminfo.c,v 1.6 2000/12/10 02:55:07 tom Exp $")
-
-#define my_length (strlen(home) + sizeof(PRIVATE_INFO))
+MODULE_ID("$Id: home_terminfo.c,v 1.9 2010/01/12 23:22:06 nicm Exp $")
/* ncurses extension...fall back on user's private directory */
+#define MyBuffer _nc_globals.home_terminfo
+
NCURSES_EXPORT(char *)
_nc_home_terminfo(void)
{
+ char *result = 0;
+#if USE_HOME_TERMINFO
char *home;
- static char *temp = 0;
if (use_terminfo_vars()) {
- if (temp == 0) {
- if ((home = getenv("HOME")) != 0 && *home != '\0'
- && my_length <= PATH_MAX) {
- temp = typeMalloc(char, my_length);
- if (temp == 0)
- _nc_err_abort("Out of memory");
- (void) snprintf(temp, my_length, PRIVATE_INFO, home);
+ if (MyBuffer == 0) {
+ if ((home = getenv("HOME")) != 0 && *home != '\0') {
+ size_t want = (strlen(home) + sizeof(PRIVATE_INFO));
+ MyBuffer = typeMalloc(char, want);
+ if (MyBuffer == 0)
+ _nc_err_abort(MSG_NO_MEMORY);
+ (void) snprintf(MyBuffer, want, PRIVATE_INFO, home);
}
}
- return temp;
+ result = MyBuffer;
}
- return 0;
+#endif
+ return result;
}
diff --git a/lib/libcurses/tinfo/init_keytry.c b/lib/libcurses/tinfo/init_keytry.c
index 083861d2690..05bc1b62343 100644
--- a/lib/libcurses/tinfo/init_keytry.c
+++ b/lib/libcurses/tinfo/init_keytry.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: init_keytry.c,v 1.5 2001/01/22 18:01:51 millert Exp $ */
+/* $OpenBSD: init_keytry.c,v 1.6 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1999-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -30,11 +30,15 @@
#include <curses.priv.h>
-#include <term.h> /* keypad_xmit, keypad_local, meta_on, meta_off */
- /* cursor_visible,cursor_normal,cursor_invisible */
+#include <term.h>
+/* keypad_xmit, keypad_local, meta_on, meta_off */
+/* cursor_visible,cursor_normal,cursor_invisible */
+
#include <tic.h> /* struct tinfo_fkeys */
-MODULE_ID("$From: init_keytry.c,v 1.5 2000/12/10 02:55:07 tom Exp $")
+#include <term_entry.h>
+
+MODULE_ID("$Id: init_keytry.c,v 1.6 2010/01/12 23:22:06 nicm Exp $")
/*
** _nc_init_keytry()
@@ -43,6 +47,13 @@ MODULE_ID("$From: init_keytry.c,v 1.5 2000/12/10 02:55:07 tom Exp $")
**
*/
+/*
+ * Internal entrypoints use SCREEN* parameter to obtain capabilities rather
+ * than cur_term.
+ */
+#undef CUR
+#define CUR (sp->_term)->type.
+
#if BROKEN_LINKER
#undef _nc_tinfo_fkeys
#endif
@@ -54,7 +65,7 @@ MODULE_ID("$From: init_keytry.c,v 1.5 2000/12/10 02:55:07 tom Exp $")
#endif*/
#if BROKEN_LINKER
-struct tinfo_fkeys *
+const struct tinfo_fkeys *
_nc_tinfo_fkeysf(void)
{
return _nc_tinfo_fkeys;
@@ -62,21 +73,47 @@ _nc_tinfo_fkeysf(void)
#endif
NCURSES_EXPORT(void)
-_nc_init_keytry(void)
+_nc_init_keytry(SCREEN *sp)
{
size_t n;
- /* The SP->_keytry value is initialized in newterm(), where the SP
+ /* The sp->_keytry value is initialized in newterm(), where the sp
* structure is created, because we can not tell where keypad() or
* mouse_activate() (which will call keyok()) are first called.
*/
- for (n = 0; _nc_tinfo_fkeys[n].code; n++)
- if (_nc_tinfo_fkeys[n].offset < STRCOUNT)
- _nc_add_to_try(&(SP->_keytry),
- CUR Strings[_nc_tinfo_fkeys[n].offset],
- _nc_tinfo_fkeys[n].code);
+ if (sp != 0) {
+ for (n = 0; _nc_tinfo_fkeys[n].code; n++) {
+ if (_nc_tinfo_fkeys[n].offset < STRCOUNT) {
+ (void) _nc_add_to_try(&(sp->_keytry),
+ CUR Strings[_nc_tinfo_fkeys[n].offset],
+ _nc_tinfo_fkeys[n].code);
+ }
+ }
+#if NCURSES_XNAMES
+ /*
+ * Add any of the extended strings to the tries if their name begins
+ * with 'k', i.e., they follow the convention of other terminfo key
+ * names.
+ */
+ {
+ TERMTYPE *tp = &(sp->_term->type);
+ for (n = STRCOUNT; n < NUM_STRINGS(tp); ++n) {
+ const char *name = ExtStrname(tp, n, strnames);
+ char *value = tp->Strings[n];
+ if (name != 0
+ && *name == 'k'
+ && value != 0
+ && key_defined(value) == 0) {
+ (void) _nc_add_to_try(&(sp->_keytry),
+ value,
+ n - STRCOUNT + KEY_MAX);
+ }
+ }
+ }
+#endif
#ifdef TRACE
- _nc_trace_tries(SP->_keytry);
+ _nc_trace_tries(sp->_keytry);
#endif
+ }
}
diff --git a/lib/libcurses/tinfo/keys.list b/lib/libcurses/tinfo/keys.list
deleted file mode 100644
index 078c4747aa5..00000000000
--- a/lib/libcurses/tinfo/keys.list
+++ /dev/null
@@ -1,159 +0,0 @@
-# $OpenBSD: keys.list,v 1.1 1999/01/18 19:10:15 millert Exp $
-# $From: keys.list,v 1.5 1997/10/25 21:05:24 tom Exp $
-# The first column is the #define symbol that is in curses.h
-# The second column is the term.h symbol, for terminfo
-# Not all keycodes have corresponding terminfo capabilities.
-KEY_A1 key_a1
-KEY_A3 key_a3
-KEY_B2 key_b2
-KEY_BACKSPACE key_backspace
-KEY_BEG key_beg
-KEY_BREAK
-KEY_BTAB key_btab
-KEY_C1 key_c1
-KEY_C3 key_c3
-KEY_CANCEL key_cancel
-KEY_CATAB key_catab
-KEY_CLEAR key_clear
-KEY_CLOSE key_close
-KEY_COMMAND key_command
-KEY_COPY key_copy
-KEY_CREATE key_create
-KEY_CTAB key_ctab
-KEY_DC key_dc
-KEY_DL key_dl
-KEY_DOWN key_down
-KEY_EIC key_eic
-KEY_END key_end
-KEY_ENTER key_enter
-KEY_EOL key_eol
-KEY_EOS key_eos
-KEY_EXIT key_exit
-KEY_F(0) key_f0
-KEY_F(1) key_f1
-KEY_F(10) key_f10
-KEY_F(11) key_f11
-KEY_F(12) key_f12
-KEY_F(13) key_f13
-KEY_F(14) key_f14
-KEY_F(15) key_f15
-KEY_F(16) key_f16
-KEY_F(17) key_f17
-KEY_F(18) key_f18
-KEY_F(19) key_f19
-KEY_F(2) key_f2
-KEY_F(20) key_f20
-KEY_F(21) key_f21
-KEY_F(22) key_f22
-KEY_F(23) key_f23
-KEY_F(24) key_f24
-KEY_F(25) key_f25
-KEY_F(26) key_f26
-KEY_F(27) key_f27
-KEY_F(28) key_f28
-KEY_F(29) key_f29
-KEY_F(3) key_f3
-KEY_F(30) key_f30
-KEY_F(31) key_f31
-KEY_F(32) key_f32
-KEY_F(33) key_f33
-KEY_F(34) key_f34
-KEY_F(35) key_f35
-KEY_F(36) key_f36
-KEY_F(37) key_f37
-KEY_F(38) key_f38
-KEY_F(39) key_f39
-KEY_F(4) key_f4
-KEY_F(40) key_f40
-KEY_F(41) key_f41
-KEY_F(42) key_f42
-KEY_F(43) key_f43
-KEY_F(44) key_f44
-KEY_F(45) key_f45
-KEY_F(46) key_f46
-KEY_F(47) key_f47
-KEY_F(48) key_f48
-KEY_F(49) key_f49
-KEY_F(5) key_f5
-KEY_F(50) key_f50
-KEY_F(51) key_f51
-KEY_F(52) key_f52
-KEY_F(53) key_f53
-KEY_F(54) key_f54
-KEY_F(55) key_f55
-KEY_F(56) key_f56
-KEY_F(57) key_f57
-KEY_F(58) key_f58
-KEY_F(59) key_f59
-KEY_F(6) key_f6
-KEY_F(60) key_f60
-KEY_F(61) key_f61
-KEY_F(62) key_f62
-KEY_F(63) key_f63
-KEY_F(7) key_f7
-KEY_F(8) key_f8
-KEY_F(9) key_f9
-KEY_FIND key_find
-KEY_HELP key_help
-KEY_HOME key_home
-KEY_IC key_ic
-KEY_IL key_il
-KEY_LEFT key_left
-KEY_LL key_ll
-KEY_MARK key_mark
-KEY_MESSAGE key_message
-KEY_MOUSE key_mouse
-KEY_MOVE key_move
-KEY_NEXT key_next
-KEY_NPAGE key_npage
-KEY_OPEN key_open
-KEY_OPTIONS key_options
-KEY_PPAGE key_ppage
-KEY_PREVIOUS key_previous
-KEY_PRINT key_print
-KEY_REDO key_redo
-KEY_REFERENCE key_reference
-KEY_REFRESH key_refresh
-KEY_REPLACE key_replace
-KEY_RESET
-KEY_RESIZE
-KEY_RESTART key_restart
-KEY_RESUME key_resume
-KEY_RIGHT key_right
-KEY_SAVE key_save
-KEY_SBEG key_sbeg
-KEY_SCANCEL key_scancel
-KEY_SCOMMAND key_scommand
-KEY_SCOPY key_scopy
-KEY_SCREATE key_screate
-KEY_SDC key_sdc
-KEY_SDL key_sdl
-KEY_SELECT key_select
-KEY_SEND key_send
-KEY_SEOL key_seol
-KEY_SEXIT key_sexit
-KEY_SF key_sf
-KEY_SFIND key_sfind
-KEY_SHELP key_shelp
-KEY_SHOME key_shome
-KEY_SIC key_sic
-KEY_SLEFT key_sleft
-KEY_SMESSAGE key_smessage
-KEY_SMOVE key_smove
-KEY_SNEXT key_snext
-KEY_SOPTIONS key_soptions
-KEY_SPREVIOUS key_sprevious
-KEY_SPRINT key_sprint
-KEY_SR key_sr
-KEY_SREDO key_sredo
-KEY_SREPLACE key_sreplace
-KEY_SRESET
-KEY_SRIGHT key_sright
-KEY_SRSUME key_srsume
-KEY_SSAVE key_ssave
-KEY_SSUSPEND key_ssuspend
-KEY_STAB key_stab
-KEY_SUNDO key_sundo
-KEY_SUSPEND key_suspend
-KEY_UNDO key_undo
-KEY_UP key_up
diff --git a/lib/libcurses/tinfo/lib_acs.c b/lib/libcurses/tinfo/lib_acs.c
index 9e406cf4d18..b5a5c12a4be 100644
--- a/lib/libcurses/tinfo/lib_acs.c
+++ b/lib/libcurses/tinfo/lib_acs.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_acs.c,v 1.4 2001/01/22 18:01:52 millert Exp $ */
+/* $OpenBSD: lib_acs.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,128 +31,158 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
#include <curses.priv.h>
#include <term.h> /* ena_acs, acs_chars */
-MODULE_ID("$From: lib_acs.c,v 1.18 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_acs.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
+#if BROKEN_LINKER || USE_REENTRANT
+#define MyBuffer _nc_prescreen.real_acs_map
+NCURSES_EXPORT_VAR(chtype *)
+_nc_acs_map(void)
+{
+ if (MyBuffer == 0)
+ MyBuffer = typeCalloc(chtype, ACS_LEN);
+ return MyBuffer;
+}
+#undef MyBuffer
+#else
NCURSES_EXPORT_VAR(chtype) acs_map[ACS_LEN] =
{
0
};
+#endif
NCURSES_EXPORT(void)
_nc_init_acs(void)
{
+ chtype *fake_map = acs_map;
+ chtype *real_map = SP != 0 ? SP->_acs_map : fake_map;
+ int j;
+
T(("initializing ACS map"));
/*
+ * If we're using this from curses (rather than terminfo), we are storing
+ * the mapping information in the SCREEN struct so we can decide how to
+ * render it.
+ */
+ if (real_map != fake_map) {
+ for (j = 1; j < ACS_LEN; ++j) {
+ real_map[j] = 0;
+ fake_map[j] = A_ALTCHARSET | j;
+ if (SP)
+ SP->_screen_acs_map[j] = FALSE;
+ }
+ } else {
+ for (j = 1; j < ACS_LEN; ++j) {
+ real_map[j] = 0;
+ }
+ }
+
+ /*
* Initializations for a UNIX-like multi-terminal environment. Use
* ASCII chars and count on the terminfo description to do better.
*/
- ACS_ULCORNER = '+'; /* should be upper left corner */
- ACS_LLCORNER = '+'; /* should be lower left corner */
- ACS_URCORNER = '+'; /* should be upper right corner */
- ACS_LRCORNER = '+'; /* should be lower right corner */
- ACS_RTEE = '+'; /* should be tee pointing left */
- ACS_LTEE = '+'; /* should be tee pointing right */
- ACS_BTEE = '+'; /* should be tee pointing up */
- ACS_TTEE = '+'; /* should be tee pointing down */
- ACS_HLINE = '-'; /* should be horizontal line */
- ACS_VLINE = '|'; /* should be vertical line */
- ACS_PLUS = '+'; /* should be large plus or crossover */
- ACS_S1 = '~'; /* should be scan line 1 */
- ACS_S9 = '_'; /* should be scan line 9 */
- ACS_DIAMOND = '+'; /* should be diamond */
- ACS_CKBOARD = ':'; /* should be checker board (stipple) */
- ACS_DEGREE = '\''; /* should be degree symbol */
- ACS_PLMINUS = '#'; /* should be plus/minus */
- ACS_BULLET = 'o'; /* should be bullet */
- ACS_LARROW = '<'; /* should be arrow pointing left */
- ACS_RARROW = '>'; /* should be arrow pointing right */
- ACS_DARROW = 'v'; /* should be arrow pointing down */
- ACS_UARROW = '^'; /* should be arrow pointing up */
- ACS_BOARD = '#'; /* should be board of squares */
- ACS_LANTERN = '#'; /* should be lantern symbol */
- ACS_BLOCK = '#'; /* should be solid square block */
+ real_map['l'] = '+'; /* should be upper left corner */
+ real_map['m'] = '+'; /* should be lower left corner */
+ real_map['k'] = '+'; /* should be upper right corner */
+ real_map['j'] = '+'; /* should be lower right corner */
+ real_map['u'] = '+'; /* should be tee pointing left */
+ real_map['t'] = '+'; /* should be tee pointing right */
+ real_map['v'] = '+'; /* should be tee pointing up */
+ real_map['w'] = '+'; /* should be tee pointing down */
+ real_map['q'] = '-'; /* should be horizontal line */
+ real_map['x'] = '|'; /* should be vertical line */
+ real_map['n'] = '+'; /* should be large plus or crossover */
+ real_map['o'] = '~'; /* should be scan line 1 */
+ real_map['s'] = '_'; /* should be scan line 9 */
+ real_map['`'] = '+'; /* should be diamond */
+ real_map['a'] = ':'; /* should be checker board (stipple) */
+ real_map['f'] = '\''; /* should be degree symbol */
+ real_map['g'] = '#'; /* should be plus/minus */
+ real_map['~'] = 'o'; /* should be bullet */
+ real_map[','] = '<'; /* should be arrow pointing left */
+ real_map['+'] = '>'; /* should be arrow pointing right */
+ real_map['.'] = 'v'; /* should be arrow pointing down */
+ real_map['-'] = '^'; /* should be arrow pointing up */
+ real_map['h'] = '#'; /* should be board of squares */
+ real_map['i'] = '#'; /* should be lantern symbol */
+ real_map['0'] = '#'; /* should be solid square block */
/* these defaults were invented for ncurses */
- ACS_S3 = '-'; /* should be scan line 3 */
- ACS_S7 = '-'; /* should be scan line 7 */
- ACS_LEQUAL = '<'; /* should be less-than-or-equal-to */
- ACS_GEQUAL = '>'; /* should be greater-than-or-equal-to */
- ACS_PI = '*'; /* should be greek pi */
- ACS_NEQUAL = '!'; /* should be not-equal */
- ACS_STERLING = 'f'; /* should be pound-sterling symbol */
+ real_map['p'] = '-'; /* should be scan line 3 */
+ real_map['r'] = '-'; /* should be scan line 7 */
+ real_map['y'] = '<'; /* should be less-than-or-equal-to */
+ real_map['z'] = '>'; /* should be greater-than-or-equal-to */
+ real_map['{'] = '*'; /* should be greek pi */
+ real_map['|'] = '!'; /* should be not-equal */
+ real_map['}'] = 'f'; /* should be pound-sterling symbol */
if (ena_acs != NULL) {
TPUTS_TRACE("ena_acs");
putp(ena_acs);
}
-#define ALTCHAR(c) ((chtype)(((unsigned char)(c)) | A_ALTCHARSET))
+#if NCURSES_EXT_FUNCS
+ /*
+ * Linux console "supports" the "PC ROM" character set by the coincidence
+ * that smpch/rmpch and smacs/rmacs have the same values. ncurses has
+ * no codepage support (see SCO Merge for an example). Outside of the
+ * values defined in acsc, there are no definitions for the "PC ROM"
+ * character set (assumed by some applications to be codepage 437), but we
+ * allow those applications to use those codepoints.
+ *
+ * test/blue.c uses this feature.
+ */
+#define PCH_KLUDGE(a,b) (a != 0 && b != 0 && !strcmp(a,b))
+ if (PCH_KLUDGE(enter_pc_charset_mode, enter_alt_charset_mode) &&
+ PCH_KLUDGE(exit_pc_charset_mode, exit_alt_charset_mode)) {
+ size_t i;
+ for (i = 1; i < ACS_LEN; ++i) {
+ if (real_map[i] == 0) {
+ real_map[i] = i;
+ if (real_map != fake_map) {
+ if (SP != 0)
+ SP->_screen_acs_map[i] = TRUE;
+ }
+ }
+ }
+ }
+#endif
if (acs_chars != NULL) {
size_t i = 0;
size_t length = strlen(acs_chars);
- while (i < length)
- switch (acs_chars[i]) {
- case 'l':
- case 'm':
- case 'k':
- case 'j':
- case 'u':
- case 't':
- case 'v':
- case 'w':
- case 'q':
- case 'x':
- case 'n':
- case 'o':
- case 's':
- case '`':
- case 'a':
- case 'f':
- case 'g':
- case '~':
- case ',':
- case '+':
- case '.':
- case '-':
- case 'h':
- case 'i':
- case '0':
- case 'p':
- case 'r':
- case 'y':
- case 'z':
- case '{':
- case '|':
- case '}':
- acs_map[(unsigned int) acs_chars[i]] =
- ALTCHAR(acs_chars[i + 1]);
- i++;
- /* FALLTHRU */
- default:
- i++;
- break;
+ while (i + 1 < length) {
+ if (acs_chars[i] != 0 && UChar(acs_chars[i]) < ACS_LEN) {
+ real_map[UChar(acs_chars[i])] = UChar(acs_chars[i + 1]) | A_ALTCHARSET;
+ if (SP != 0)
+ SP->_screen_acs_map[UChar(acs_chars[i])] = TRUE;
}
+ i += 2;
+ }
}
#ifdef TRACE
/* Show the equivalent mapping, noting if it does not match the
* given attribute, whether by re-ordering or duplication.
*/
- if (_nc_tracing & TRACE_CALLS) {
+ if (USE_TRACEF(TRACE_CALLS)) {
size_t n, m;
- char show[SIZEOF(acs_map) + 1];
- for (n = 1, m = 0; n < SIZEOF(acs_map); n++) {
- if (acs_map[n] != 0) {
+ char show[ACS_LEN * 2 + 1];
+ for (n = 1, m = 0; n < ACS_LEN; n++) {
+ if (real_map[n] != 0) {
show[m++] = (char) n;
- show[m++] = TextOf(acs_map[n]);
+ show[m++] = (char) ChCharOf(real_map[n]);
}
}
show[m] = 0;
+ if (acs_chars == NULL || strcmp(acs_chars, show))
+ _tracef("%s acs_chars %s",
+ (acs_chars == NULL) ? "NULL" : "READ",
+ _nc_visbuf(acs_chars));
_tracef("%s acs_chars %s",
(acs_chars == NULL)
? "NULL"
@@ -160,6 +190,7 @@ _nc_init_acs(void)
? "DIFF"
: "SAME"),
_nc_visbuf(show));
+ _nc_unlock_global(tracef);
}
#endif /* TRACE */
}
diff --git a/lib/libcurses/tinfo/lib_baudrate.c b/lib/libcurses/tinfo/lib_baudrate.c
index 39342dcb9ab..a171993945a 100644
--- a/lib/libcurses/tinfo/lib_baudrate.c
+++ b/lib/libcurses/tinfo/lib_baudrate.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_baudrate.c,v 1.4 2001/01/22 18:01:52 millert Exp $ */
+/* $OpenBSD: lib_baudrate.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -41,8 +42,47 @@
#include <curses.priv.h>
#include <term.h> /* cur_term, pad_char */
#include <termcap.h> /* ospeed */
+#if defined(__FreeBSD__)
+#include <sys/param.h>
+#endif
+
+/*
+ * These systems use similar header files, which define B1200 as 1200, etc.,
+ * but can be overridden by defining USE_OLD_TTY so B1200 is 9, which makes all
+ * of the indices up to B115200 fit nicely in a 'short', allowing us to retain
+ * ospeed's type for compatibility.
+ */
+#if (defined(__FreeBSD__) && (__FreeBSD_version < 700000)) || defined(__NetBSD__) || defined(__OpenBSD__)
+#undef B0
+#undef B50
+#undef B75
+#undef B110
+#undef B134
+#undef B150
+#undef B200
+#undef B300
+#undef B600
+#undef B1200
+#undef B1800
+#undef B2400
+#undef B4800
+#undef B9600
+#undef B19200
+#undef EXTA
+#undef B38400
+#undef EXTB
+#undef B57600
+#undef B115200
+#undef B230400
+#undef B460800
+#undef B921600
+#define USE_OLD_TTY
+#include <sys/ttydev.h>
+#else
+#undef USE_OLD_TTY
+#endif /* USE_OLD_TTY */
-MODULE_ID("$From: lib_baudrate.c,v 1.19 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_baudrate.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
/*
* int
@@ -99,21 +139,28 @@ static struct speed const speeds[] =
#ifdef B460800
{B460800, 460800},
#endif
+#ifdef B921600
+ {B921600, 921600},
+#endif
};
NCURSES_EXPORT(int)
_nc_baudrate(int OSpeed)
{
+#if !USE_REENTRANT
static int last_OSpeed;
static int last_baudrate;
+#endif
- int result;
+ int result = ERR;
unsigned i;
+#if !USE_REENTRANT
if (OSpeed == last_OSpeed) {
result = last_baudrate;
- } else {
- result = ERR;
+ }
+#endif
+ if (result == ERR) {
if (OSpeed >= 0) {
for (i = 0; i < SIZEOF(speeds); i++) {
if (speeds[i].s == OSpeed) {
@@ -122,7 +169,12 @@ _nc_baudrate(int OSpeed)
}
}
}
- last_baudrate = result;
+#if !USE_REENTRANT
+ if (OSpeed == last_OSpeed) {
+ last_OSpeed = OSpeed;
+ last_baudrate = result;
+ }
+#endif
}
return (result);
}
@@ -157,24 +209,32 @@ baudrate(void)
* that take into account costs that depend on baudrate.
*/
#ifdef TRACE
- if (SP && !isatty(fileno(SP->_ofp))
+ if (!isatty(fileno(SP ? SP->_ofp : stdout))
&& getenv("BAUDRATE") != 0) {
int ret;
if ((ret = _nc_getenv_num("BAUDRATE")) <= 0)
ret = 9600;
ospeed = _nc_ospeed(ret);
returnCode(ret);
- } else
+ }
#endif
+ if (cur_term != 0) {
+#ifdef USE_OLD_TTY
+ result = cfgetospeed(&cur_term->Nttyb);
+ ospeed = _nc_ospeed(result);
+#else /* !USE_OLD_TTY */
#ifdef TERMIOS
ospeed = cfgetospeed(&cur_term->Nttyb);
#else
ospeed = cur_term->Nttyb.sg_ospeed;
#endif
- result = _nc_baudrate(ospeed);
- if (cur_term != 0)
+ result = _nc_baudrate(ospeed);
+#endif
cur_term->_baudrate = result;
+ } else {
+ result = ERR;
+ }
returnCode(result);
}
diff --git a/lib/libcurses/tinfo/lib_cur_term.c b/lib/libcurses/tinfo/lib_cur_term.c
index 3fcf4abe47c..68bb567f793 100644
--- a/lib/libcurses/tinfo/lib_cur_term.c
+++ b/lib/libcurses/tinfo/lib_cur_term.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_cur_term.c,v 1.5 2001/01/22 18:01:52 millert Exp $ */
+/* $OpenBSD: lib_cur_term.c,v 1.6 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2003,2008 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,33 +42,66 @@
#include <term_entry.h> /* TTY, cur_term */
#include <termcap.h> /* ospeed */
-MODULE_ID("$From: lib_cur_term.c,v 1.11 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_cur_term.c,v 1.6 2010/01/12 23:22:06 nicm Exp $")
+#undef CUR
+#define CUR termp->type.
+
+#if BROKEN_LINKER || USE_REENTRANT
+NCURSES_EXPORT(TERMINAL *)
+NCURSES_PUBLIC_VAR(cur_term) (void)
+{
+ return (SP != 0 && SP->_term != 0) ? SP->_term : _nc_prescreen._cur_term;
+}
+#else
NCURSES_EXPORT_VAR(TERMINAL *) cur_term = 0;
+#endif
NCURSES_EXPORT(TERMINAL *)
set_curterm(TERMINAL * termp)
{
- TERMINAL *oldterm = cur_term;
+ TERMINAL *oldterm;
+
+ T((T_CALLED("set_curterm(%p)"), termp));
- if ((cur_term = termp) != 0) {
- ospeed = _nc_ospeed(cur_term->_baudrate);
- PC = (pad_char != NULL) ? pad_char[0] : 0;
+ _nc_lock_global(curses);
+ oldterm = cur_term;
+ if (SP)
+ SP->_term = termp;
+#if BROKEN_LINKER || USE_REENTRANT
+ _nc_prescreen._cur_term = termp;
+#else
+ cur_term = termp;
+#endif
+ if (termp != 0) {
+ ospeed = _nc_ospeed(termp->_baudrate);
+ if (termp->type.Strings) {
+ PC = (char) ((pad_char != NULL) ? pad_char[0] : 0);
+ }
}
- return oldterm;
+ _nc_unlock_global(curses);
+
+ T((T_RETURN("%p"), oldterm));
+ return (oldterm);
}
NCURSES_EXPORT(int)
del_curterm(TERMINAL * termp)
{
+ int rc = ERR;
+
T((T_CALLED("del_curterm(%p)"), termp));
+ _nc_lock_global(curses);
if (termp != 0) {
_nc_free_termtype(&(termp->type));
+ FreeIfNeeded(termp->_termname);
free(termp);
if (termp == cur_term)
- cur_term = 0;
- returnCode(OK);
+ set_curterm(0);
+ rc = OK;
}
- returnCode(ERR);
+ _nc_unlock_global(curses);
+
+ returnCode(rc);
}
diff --git a/lib/libcurses/tinfo/lib_data.c b/lib/libcurses/tinfo/lib_data.c
index cdc8044ab18..57e8d7e9a06 100644
--- a/lib/libcurses/tinfo/lib_data.c
+++ b/lib/libcurses/tinfo/lib_data.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_data.c,v 1.3 2001/01/22 18:01:52 millert Exp $ */
+/* $OpenBSD: lib_data.c,v 1.4 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -42,18 +43,33 @@
#include <curses.priv.h>
-MODULE_ID("$From: lib_data.c,v 1.16 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_data.c,v 1.4 2010/01/12 23:22:06 nicm Exp $")
/*
* OS/2's native linker complains if we don't initialize public data when
* constructing a dll (reported by J.J.G.Ripoll).
*/
-NCURSES_EXPORT_VAR(WINDOW *)
-stdscr = 0;
-NCURSES_EXPORT_VAR(WINDOW *)
-curscr = 0;
-NCURSES_EXPORT_VAR(WINDOW *)
-newscr = 0;
+#if USE_REENTRANT
+NCURSES_EXPORT(WINDOW *)
+NCURSES_PUBLIC_VAR(stdscr) (void)
+{
+ return SP ? SP->_stdscr : 0;
+}
+NCURSES_EXPORT(WINDOW *)
+NCURSES_PUBLIC_VAR(curscr) (void)
+{
+ return SP ? SP->_curscr : 0;
+}
+NCURSES_EXPORT(WINDOW *)
+NCURSES_PUBLIC_VAR(newscr) (void)
+{
+ return SP ? SP->_newscr : 0;
+}
+#else
+NCURSES_EXPORT_VAR(WINDOW *) stdscr = 0;
+NCURSES_EXPORT_VAR(WINDOW *) curscr = 0;
+NCURSES_EXPORT_VAR(WINDOW *) newscr = 0;
+#endif
NCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain = 0;
@@ -68,7 +84,7 @@ NCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain = 0;
* module coupling that increases the size of the executable.
*/
#if BROKEN_LINKER
- static SCREEN *my_screen;
+static SCREEN *my_screen;
NCURSES_EXPORT(SCREEN *)
_nc_screen(void)
@@ -83,11 +99,236 @@ _nc_alloc_screen(void)
}
NCURSES_EXPORT(void)
-_nc_set_screen(SCREEN * sp)
+_nc_set_screen(SCREEN *sp)
{
my_screen = sp;
}
#else
-NCURSES_EXPORT_VAR(SCREEN *) SP = NULL; /* Some linkers require initialized data... */
+NCURSES_EXPORT_VAR(SCREEN *) SP = NULL; /* Some linkers require initialized data... */
+#endif
+/* *INDENT-OFF* */
+#define CHARS_0s { '\0' }
+
+#define TGETENT_0 { 0L, FALSE, NULL, NULL, NULL }
+#define TGETENT_0s { TGETENT_0, TGETENT_0, TGETENT_0, TGETENT_0 }
+
+NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
+ 0, /* have_sigwinch */
+ 0, /* cleanup_nested */
+
+ FALSE, /* init_signals */
+ FALSE, /* init_screen */
+
+ NULL, /* comp_sourcename */
+ NULL, /* comp_termtype */
+
+ FALSE, /* have_tic_directory */
+ FALSE, /* keep_tic_directory */
+ TERMINFO, /* tic_directory */
+
+ NULL, /* dbi_list */
+ 0, /* dbi_size */
+
+ NULL, /* first_name */
+ NULL, /* keyname_table */
+
+ 0, /* slk_format */
+
+ NULL, /* safeprint_buf */
+ 0, /* safeprint_used */
+
+ TGETENT_0s, /* tgetent_cache */
+ 0, /* tgetent_index */
+ 0, /* tgetent_sequence */
+
+ 0, /* _nc_windowlist */
+
+#if USE_HOME_TERMINFO
+ NULL, /* home_terminfo */
+#endif
+
+#if !USE_SAFE_SPRINTF
+ 0, /* safeprint_cols */
+ 0, /* safeprint_rows */
+#endif
+
+#ifdef TRACE
+ FALSE, /* init_trace */
+ CHARS_0s, /* trace_fname */
+ 0, /* trace_level */
+ NULL, /* trace_fp */
+
+ NULL, /* tracearg_buf */
+ 0, /* tracearg_used */
+
+ NULL, /* tracebuf_ptr */
+ 0, /* tracebuf_used */
+
+ CHARS_0s, /* tracechr_buf */
+
+ NULL, /* tracedmp_buf */
+ 0, /* tracedmp_used */
+
+ NULL, /* tracetry_buf */
+ 0, /* tracetry_used */
+
+ { CHARS_0s, CHARS_0s }, /* traceatr_color_buf */
+ 0, /* traceatr_color_sel */
+ -1, /* traceatr_color_last */
+
+#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
+};
+
+#define STACK_FRAME_0 { { 0 }, 0 }
+#define STACK_FRAME_0s { STACK_FRAME_0 }
+#define NUM_VARS_0s { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+
+#define RIPOFF_0 { 0,0,0 }
+#define RIPOFF_0s { RIPOFF_0 }
+
+NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = {
+ TRUE, /* use_env */
+ FALSE, /* filter_mode */
+ A_NORMAL, /* previous_attr */
+ RIPOFF_0s, /* ripoff */
+ NULL, /* rsp */
+ { /* tparm_state */
+#ifdef TRACE
+ NULL, /* tname */
+#endif
+ NULL, /* tparam_base */
+
+ STACK_FRAME_0s, /* stack */
+ 0, /* stack_ptr */
+
+ NULL, /* out_buff */
+ 0, /* out_size */
+ 0, /* out_used */
+
+ NULL, /* fmt_buff */
+ 0, /* fmt_size */
+
+ NUM_VARS_0s, /* dynamic_var */
+ NUM_VARS_0s, /* static_vars */
+ },
+ NULL, /* saved_tty */
+#if NCURSES_NO_PADDING
+ FALSE, /* flag to set if padding disabled */
+#endif
+#if BROKEN_LINKER || USE_REENTRANT
+ NULL, /* real_acs_map */
+ 0, /* LINES */
+ 0, /* COLS */
+ 0, /* cur_term */
+#ifdef TRACE
+ 0L, /* _outchars */
+ NULL, /* _tputs_trace */
+#endif
+#endif
+};
+/* *INDENT-ON* */
+
+/******************************************************************************/
+#ifdef USE_PTHREADS
+static void
+init_global_mutexes(void)
+{
+ static bool initialized = FALSE;
+
+ if (!initialized) {
+ initialized = TRUE;
+ _nc_mutex_init(&_nc_globals.mutex_curses);
+ _nc_mutex_init(&_nc_globals.mutex_tst_tracef);
+ _nc_mutex_init(&_nc_globals.mutex_tracef);
+ }
+}
+
+NCURSES_EXPORT(void)
+_nc_init_pthreads(void)
+{
+ if (_nc_use_pthreads)
+ return;
+# if USE_WEAK_SYMBOLS
+ if ((pthread_mutex_init) == 0)
+ return;
+ if ((pthread_mutex_lock) == 0)
+ return;
+ if ((pthread_mutex_unlock) == 0)
+ return;
+ if ((pthread_mutex_trylock) == 0)
+ return;
+ if ((pthread_mutexattr_settype) == 0)
+ return;
+# endif
+ _nc_use_pthreads = 1;
+ init_global_mutexes();
+}
+
+/*
+ * Use recursive mutexes if we have them - they're part of Unix98.
+ * For the cases where we do not, _nc_mutex_trylock() is used to avoid a
+ * deadlock, at the expense of memory leaks and unexpected failures that
+ * may not be handled by typical clients.
+ *
+ * FIXME - need configure check for PTHREAD_MUTEX_RECURSIVE, define it to
+ * PTHREAD_MUTEX_NORMAL if not supported.
+ */
+NCURSES_EXPORT(void)
+_nc_mutex_init(pthread_mutex_t * obj)
+{
+ pthread_mutexattr_t recattr;
+
+ if (_nc_use_pthreads) {
+ pthread_mutexattr_init(&recattr);
+ pthread_mutexattr_settype(&recattr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(obj, &recattr);
+ }
+}
+
+NCURSES_EXPORT(int)
+_nc_mutex_lock(pthread_mutex_t * obj)
+{
+ if (_nc_use_pthreads == 0)
+ return 0;
+ return pthread_mutex_lock(obj);
+}
+
+NCURSES_EXPORT(int)
+_nc_mutex_trylock(pthread_mutex_t * obj)
+{
+ if (_nc_use_pthreads == 0)
+ return 0;
+ return pthread_mutex_trylock(obj);
+}
+
+NCURSES_EXPORT(int)
+_nc_mutex_unlock(pthread_mutex_t * obj)
+{
+ if (_nc_use_pthreads == 0)
+ return 0;
+ return pthread_mutex_unlock(obj);
+}
+
+#if USE_WEAK_SYMBOLS
+/*
+ * NB: sigprocmask(2) is global but pthread_sigmask(3p)
+ * only for the calling thread.
+ */
+NCURSES_EXPORT(int)
+_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);
+}
#endif
+#endif /* USE_PTHREADS */
diff --git a/lib/libcurses/tinfo/lib_has_cap.c b/lib/libcurses/tinfo/lib_has_cap.c
index d95e3f908c7..6be944be979 100644
--- a/lib/libcurses/tinfo/lib_has_cap.c
+++ b/lib/libcurses/tinfo/lib_has_cap.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_has_cap.c,v 1.2 2001/01/22 18:01:52 millert Exp $ */
+/* $OpenBSD: lib_has_cap.c,v 1.3 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2000,2003 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-2003 *
****************************************************************************/
/*
@@ -44,7 +45,7 @@
#include <term.h>
-MODULE_ID("$From: lib_has_cap.c,v 1.3 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_has_cap.c,v 1.3 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(bool)
has_ic(void)
diff --git a/lib/libcurses/tinfo/lib_kernel.c b/lib/libcurses/tinfo/lib_kernel.c
index 730ba1551fd..024227fdc03 100644
--- a/lib/libcurses/tinfo/lib_kernel.c
+++ b/lib/libcurses/tinfo/lib_kernel.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_kernel.c,v 1.2 2001/01/22 18:01:52 millert Exp $ */
+/* $OpenBSD: lib_kernel.c,v 1.3 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2003,2004 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 2002 *
****************************************************************************/
/*
@@ -49,7 +50,28 @@
#include <curses.priv.h>
#include <term.h> /* cur_term */
-MODULE_ID("$From: lib_kernel.c,v 1.21 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_kernel.c,v 1.3 2010/01/12 23:22:06 nicm Exp $")
+
+static int
+_nc_vdisable(void)
+{
+ int value = -1;
+#if defined(_POSIX_VDISABLE) && HAVE_UNISTD_H
+ value = _POSIX_VDISABLE;
+#endif
+#if defined(_PC_VDISABLE)
+ if (value == -1) {
+ value = fpathconf(0, _PC_VDISABLE);
+ if (value == -1) {
+ value = 0377;
+ }
+ }
+#elif defined(VDISABLE)
+ if (value == -1)
+ value = VDISABLE;
+#endif
+ return value;
+}
/*
* erasechar()
@@ -61,16 +83,19 @@ MODULE_ID("$From: lib_kernel.c,v 1.21 2000/12/10 02:55:07 tom Exp $")
NCURSES_EXPORT(char)
erasechar(void)
{
+ int result = ERR;
T((T_CALLED("erasechar()")));
if (cur_term != 0) {
#ifdef TERMIOS
- returnCode(cur_term->Ottyb.c_cc[VERASE]);
+ result = cur_term->Ottyb.c_cc[VERASE];
+ if (result == _nc_vdisable())
+ result = ERR;
#else
- returnCode(cur_term->Ottyb.sg_erase);
+ result = cur_term->Ottyb.sg_erase;
#endif
}
- returnCode(ERR);
+ returnCode(result);
}
/*
@@ -83,16 +108,19 @@ erasechar(void)
NCURSES_EXPORT(char)
killchar(void)
{
+ int result = ERR;
T((T_CALLED("killchar()")));
if (cur_term != 0) {
#ifdef TERMIOS
- returnCode(cur_term->Ottyb.c_cc[VKILL]);
+ result = cur_term->Ottyb.c_cc[VKILL];
+ if (result == _nc_vdisable())
+ result = ERR;
#else
- returnCode(cur_term->Ottyb.sg_kill);
+ result = cur_term->Ottyb.sg_kill;
#endif
}
- returnCode(ERR);
+ returnCode(result);
}
/*
diff --git a/lib/libcurses/tinfo/lib_longname.c b/lib/libcurses/tinfo/lib_longname.c
index 9cbbf5fcbf5..74616fa7bc7 100644
--- a/lib/libcurses/tinfo/lib_longname.c
+++ b/lib/libcurses/tinfo/lib_longname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lib_longname.c,v 1.2 2001/01/22 18:01:52 millert Exp $ */
+/* $OpenBSD: lib_longname.c,v 1.3 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
* Copyright (c) 1998,2000 Free Software Foundation, Inc. *
@@ -42,7 +42,7 @@
#include <curses.priv.h>
-MODULE_ID("$From: lib_longname.c,v 1.9 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_longname.c,v 1.3 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(char *)
longname(void)
diff --git a/lib/libcurses/tinfo/lib_napms.c b/lib/libcurses/tinfo/lib_napms.c
index bf29ef488f5..b92431d9701 100644
--- a/lib/libcurses/tinfo/lib_napms.c
+++ b/lib/libcurses/tinfo/lib_napms.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_napms.c,v 1.7 2001/01/22 18:01:53 millert Exp $ */
+/* $OpenBSD: lib_napms.c,v 1.8 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -38,6 +38,8 @@
*
* The routine napms.
*
+ * (This file was originally written by Eric Raymond; however except for
+ * comments, none of the original code remains - T.Dickey).
*/
#include <curses.priv.h>
@@ -47,20 +49,9 @@
#if HAVE_SYS_TIME_H
#include <sys/time.h> /* needed for MacOS X DP3 */
#endif
-#elif USE_FUNC_POLL
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#elif HAVE_SELECT
-#if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT
-#include <sys/time.h>
-#endif
-#if HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
#endif
-MODULE_ID("$From: lib_napms.c,v 1.11 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_napms.c,v 1.8 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(int)
napms(int ms)
@@ -69,23 +60,17 @@ napms(int ms)
#if HAVE_NANOSLEEP
{
- struct timespec ts;
- ts.tv_sec = ms / 1000;
- ts.tv_nsec = (ms % 1000) * 1000000;
- nanosleep(&ts, NULL);
- }
-#elif USE_FUNC_POLL
- {
- struct pollfd fds[1];
- poll(fds, 0, ms);
- }
-#elif HAVE_SELECT
- {
- struct timeval tval;
- tval.tv_sec = ms / 1000;
- tval.tv_usec = (ms % 1000) * 1000;
- select(0, NULL, NULL, NULL, &tval);
+ struct timespec request, remaining;
+ request.tv_sec = ms / 1000;
+ request.tv_nsec = (ms % 1000) * 1000000;
+ while (nanosleep(&request, &remaining) == -1
+ && errno == EINTR) {
+ request = remaining;
+ }
}
+#else
+ _nc_timed_wait(0, 0, ms, (int *) 0 EVENTLIST_2nd(0));
#endif
+
returnCode(OK);
}
diff --git a/lib/libcurses/tinfo/lib_options.c b/lib/libcurses/tinfo/lib_options.c
index ca96bc3d7db..00e079fce5b 100644
--- a/lib/libcurses/tinfo/lib_options.c
+++ b/lib/libcurses/tinfo/lib_options.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_options.c,v 1.9 2001/01/22 18:01:53 millert Exp $ */
+/* $OpenBSD: lib_options.c,v 1.10 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -44,7 +45,10 @@
#include <term.h>
-MODULE_ID("$From: lib_options.c,v 1.42 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_options.c,v 1.10 2010/01/12 23:22:06 nicm Exp $")
+
+static int _nc_curs_set(SCREEN *, int);
+static int _nc_meta(SCREEN *, bool);
NCURSES_EXPORT(int)
idlok(WINDOW *win, bool flag)
@@ -74,7 +78,7 @@ halfdelay(int t)
{
T((T_CALLED("halfdelay(%d)"), t));
- if (t < 1 || t > 255)
+ if (t < 1 || t > 255 || SP == 0)
returnCode(ERR);
cbreak();
@@ -100,7 +104,7 @@ nodelay(WINDOW *win, bool flag)
NCURSES_EXPORT(int)
notimeout(WINDOW *win, bool f)
{
- T((T_CALLED("notimout(%p,%d)"), win, f));
+ T((T_CALLED("notimeout(%p,%d)"), win, f));
if (win) {
win->_notimeout = f;
@@ -117,6 +121,7 @@ wtimeout(WINDOW *win, int delay)
if (win) {
win->_delay = delay;
}
+ returnVoid;
}
NCURSES_EXPORT(int)
@@ -126,7 +131,7 @@ keypad(WINDOW *win, bool flag)
if (win) {
win->_use_keypad = flag;
- returnCode(_nc_keypad(flag));
+ returnCode(_nc_keypad(SP, flag));
} else
returnCode(ERR);
}
@@ -134,19 +139,12 @@ keypad(WINDOW *win, bool flag)
NCURSES_EXPORT(int)
meta(WINDOW *win GCC_UNUSED, bool flag)
{
+ int result;
+
/* Ok, we stay relaxed and don't signal an error if win is NULL */
T((T_CALLED("meta(%p,%d)"), win, flag));
-
- SP->_use_meta = flag;
-
- if (flag && meta_on) {
- TPUTS_TRACE("meta_on");
- putp(meta_on);
- } else if (!flag && meta_off) {
- TPUTS_TRACE("meta_off");
- putp(meta_off);
- }
- returnCode(OK);
+ result = _nc_meta(SP, flag);
+ returnCode(result);
}
/* curs_set() moved here to narrow the kernel interface */
@@ -154,51 +152,23 @@ meta(WINDOW *win GCC_UNUSED, bool flag)
NCURSES_EXPORT(int)
curs_set(int vis)
{
- int cursor = SP->_cursor;
+ int result;
T((T_CALLED("curs_set(%d)"), vis));
-
- if (vis < 0 || vis > 2)
- returnCode(ERR);
-
- if (vis == cursor)
- returnCode(cursor);
-
- switch (vis) {
- case 2:
- if (cursor_visible) {
- TPUTS_TRACE("cursor_visible");
- putp(cursor_visible);
- } else
- returnCode(ERR);
- break;
- case 1:
- if (cursor_normal) {
- TPUTS_TRACE("cursor_normal");
- putp(cursor_normal);
- } else
- returnCode(ERR);
- break;
- case 0:
- if (cursor_invisible) {
- TPUTS_TRACE("cursor_invisible");
- putp(cursor_invisible);
- } else
- returnCode(ERR);
- break;
- }
- SP->_cursor = vis;
- _nc_flush();
-
- returnCode(cursor == -1 ? 1 : cursor);
+ result = _nc_curs_set(SP, vis);
+ returnCode(result);
}
NCURSES_EXPORT(int)
typeahead(int fd)
{
T((T_CALLED("typeahead(%d)"), fd));
- SP->_checkfd = fd;
- returnCode(OK);
+ if (SP != 0) {
+ SP->_checkfd = fd;
+ returnCode(OK);
+ } else {
+ returnCode(ERR);
+ }
}
/*
@@ -210,7 +180,7 @@ typeahead(int fd)
#if NCURSES_EXT_FUNCS
static int
-has_key_internal(int keycode, struct tries *tp)
+has_key_internal(int keycode, TRIES * tp)
{
if (tp == 0)
return (FALSE);
@@ -225,10 +195,39 @@ NCURSES_EXPORT(int)
has_key(int keycode)
{
T((T_CALLED("has_key(%d)"), keycode));
- returnCode(has_key_internal(keycode, SP->_keytry));
+ returnCode(SP != 0 ? has_key_internal(keycode, SP->_keytry) : FALSE);
}
#endif /* NCURSES_EXT_FUNCS */
+/*
+ * Internal entrypoints use SCREEN* parameter to obtain capabilities rather
+ * than cur_term.
+ */
+#undef CUR
+#define CUR (sp->_term)->type.
+
+static int
+_nc_putp(const char *name GCC_UNUSED, const char *value)
+{
+ int rc = ERR;
+
+ if (value) {
+ TPUTS_TRACE(name);
+ rc = putp(value);
+ }
+ return rc;
+}
+
+static int
+_nc_putp_flush(const char *name, const char *value)
+{
+ int rc = _nc_putp(name, value);
+ if (rc != ERR) {
+ _nc_flush();
+ }
+ return rc;
+}
+
/* Turn the keypad on/off
*
* Note: we flush the output because changing this mode causes some terminals
@@ -237,21 +236,94 @@ has_key(int keycode)
* the terminal state _before_ switching modes.
*/
NCURSES_EXPORT(int)
-_nc_keypad(bool flag)
+_nc_keypad(SCREEN *sp, bool flag)
{
- if (flag && keypad_xmit) {
- TPUTS_TRACE("keypad_xmit");
- putp(keypad_xmit);
- _nc_flush();
- } else if (!flag && keypad_local) {
- TPUTS_TRACE("keypad_local");
- putp(keypad_local);
- _nc_flush();
+ int rc = ERR;
+
+ if (sp != 0) {
+#ifdef USE_PTHREADS
+ /*
+ * We might have this situation in a multithreaded application that
+ * has wgetch() reading in more than one thread. putp() and below
+ * may use SP explicitly.
+ */
+ if (_nc_use_pthreads && sp != SP) {
+ SCREEN *save_sp;
+
+ /* cannot use use_screen(), since that is not in tinfo library */
+ _nc_lock_global(curses);
+ save_sp = SP;
+ _nc_set_screen(sp);
+ rc = _nc_keypad(sp, flag);
+ _nc_set_screen(save_sp);
+ _nc_unlock_global(curses);
+ } else
+#endif
+ {
+ if (flag) {
+ (void) _nc_putp_flush("keypad_xmit", keypad_xmit);
+ } else if (!flag && keypad_local) {
+ (void) _nc_putp_flush("keypad_local", keypad_local);
+ }
+
+ if (flag && !sp->_tried) {
+ _nc_init_keytry(sp);
+ sp->_tried = TRUE;
+ }
+ sp->_keypad_on = flag;
+ rc = OK;
+ }
+ }
+ return (rc);
+}
+
+static int
+_nc_curs_set(SCREEN *sp, int vis)
+{
+ int result = ERR;
+
+ T((T_CALLED("curs_set(%d)"), vis));
+ if (sp != 0 && vis >= 0 && vis <= 2) {
+ int cursor = sp->_cursor;
+
+ if (vis == cursor) {
+ result = cursor;
+ } else {
+ switch (vis) {
+ case 2:
+ result = _nc_putp_flush("cursor_visible", cursor_visible);
+ break;
+ case 1:
+ result = _nc_putp_flush("cursor_normal", cursor_normal);
+ break;
+ case 0:
+ result = _nc_putp_flush("cursor_invisible", cursor_invisible);
+ break;
+ }
+ if (result != ERR)
+ result = (cursor == -1 ? 1 : cursor);
+ sp->_cursor = vis;
+ }
}
+ returnCode(result);
+}
+
+static int
+_nc_meta(SCREEN *sp, bool flag)
+{
+ int result = ERR;
+
+ /* Ok, we stay relaxed and don't signal an error if win is NULL */
+
+ if (SP != 0) {
+ SP->_use_meta = flag;
- if (flag && !SP->_tried) {
- _nc_init_keytry();
- SP->_tried = TRUE;
+ if (flag) {
+ _nc_putp("meta_on", meta_on);
+ } else {
+ _nc_putp("meta_off", meta_off);
+ }
+ result = OK;
}
- return (OK);
+ return result;
}
diff --git a/lib/libcurses/tinfo/lib_print.c b/lib/libcurses/tinfo/lib_print.c
index 9a5b3157e07..5043c551004 100644
--- a/lib/libcurses/tinfo/lib_print.c
+++ b/lib/libcurses/tinfo/lib_print.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_print.c,v 1.4 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: lib_print.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2002,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 *
@@ -37,7 +37,7 @@
#include <term.h>
-MODULE_ID("$From: lib_print.c,v 1.13 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_print.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(int)
mcprint(char *data, int len)
@@ -53,7 +53,7 @@ mcprint(char *data, int len)
}
if (prtr_non) {
- switchon = tparm(prtr_non, len);
+ switchon = TPARM_1(prtr_non, len);
onsize = strlen(switchon);
offsize = 0;
} else {
@@ -63,13 +63,13 @@ mcprint(char *data, int len)
}
res = onsize + len + offsize + 1;
- if ((mybuf = typeMalloc(char, res)) == (char *) 0) {
+ if (switchon == 0 || (mybuf = typeMalloc(char, res)) == 0) {
errno = ENOMEM;
return (ERR);
}
(void) strlcpy(mybuf, switchon, res);
- memcpy(mybuf + onsize, data, len);
+ memcpy(mybuf + onsize, data, (unsigned) len);
if (offsize)
(void) strlcpy(mybuf + onsize + len, prtr_off, res - onsize - len);
diff --git a/lib/libcurses/tinfo/lib_raw.c b/lib/libcurses/tinfo/lib_raw.c
index eb10b64e30b..724ba92a4a2 100644
--- a/lib/libcurses/tinfo/lib_raw.c
+++ b/lib/libcurses/tinfo/lib_raw.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_raw.c,v 1.7 2001/01/22 18:01:53 millert Exp $ */
+/* $OpenBSD: lib_raw.c,v 1.8 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2002,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 *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1998 on *
****************************************************************************/
/*
@@ -50,7 +51,7 @@
#include <curses.priv.h>
#include <term.h> /* cur_term */
-MODULE_ID("$From: lib_raw.c,v 1.10 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_raw.c,v 1.8 2010/01/12 23:22:06 nicm Exp $")
#if SVR4_TERMIO && !defined(_POSIX_SOURCE)
#define _POSIX_SOURCE
@@ -62,13 +63,16 @@ MODULE_ID("$From: lib_raw.c,v 1.10 2000/12/10 02:55:07 tom Exp $")
#ifdef __EMX__
#include <io.h>
+#define _nc_setmode(mode) setmode(SP->_ifd, mode)
+#else
+#define _nc_setmode(mode) /* nothing */
#endif
#define COOKED_INPUT (IXON|BRKINT|PARMRK)
#ifdef TRACE
-#define BEFORE(N) if (_nc_tracing&TRACE_BITS) _tracef("%s before bits: %s", N, _nc_tracebits())
-#define AFTER(N) if (_nc_tracing&TRACE_BITS) _tracef("%s after bits: %s", N, _nc_tracebits())
+#define BEFORE(N) if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s before bits: %s", N, _nc_tracebits())
+#define AFTER(N) if (USE_TRACEF(TRACE_BITS)) _nc_locked_tracef("%s after bits: %s", N, _nc_tracebits())
#else
#define BEFORE(s)
#define AFTER(s)
@@ -77,162 +81,218 @@ MODULE_ID("$From: lib_raw.c,v 1.10 2000/12/10 02:55:07 tom Exp $")
NCURSES_EXPORT(int)
raw(void)
{
+ int result = ERR;
+
T((T_CALLED("raw()")));
- if (SP != 0 && cur_term != 0) {
- SP->_raw = TRUE;
- SP->_cbreak = 1;
+ if (SP != 0 && cur_term != 0) {
+ TTY buf;
-#ifdef __EMX__
- setmode(SP->_ifd, O_BINARY);
-#endif
+ BEFORE("raw");
+ _nc_setmode(O_BINARY);
+ buf = cur_term->Nttyb;
#ifdef TERMIOS
- BEFORE("raw");
- cur_term->Nttyb.c_lflag &= ~(ICANON | ISIG | IEXTEN);
- cur_term->Nttyb.c_iflag &= ~(COOKED_INPUT);
- cur_term->Nttyb.c_cc[VMIN] = 1;
- cur_term->Nttyb.c_cc[VTIME] = 0;
- AFTER("raw");
+ buf.c_lflag &= ~(ICANON | ISIG | IEXTEN);
+ buf.c_iflag &= ~(COOKED_INPUT);
+ buf.c_cc[VMIN] = 1;
+ buf.c_cc[VTIME] = 0;
#else
- cur_term->Nttyb.sg_flags |= RAW;
+ buf.sg_flags |= RAW;
#endif
- returnCode(_nc_set_tty_mode(&cur_term->Nttyb));
+ if ((result = _nc_set_tty_mode(&buf)) == OK) {
+ SP->_raw = TRUE;
+ SP->_cbreak = 1;
+ cur_term->Nttyb = buf;
+ }
+ AFTER("raw");
}
- returnCode(ERR);
+ returnCode(result);
}
NCURSES_EXPORT(int)
cbreak(void)
{
+ int result = ERR;
+
T((T_CALLED("cbreak()")));
- SP->_cbreak = 1;
+ if (SP != 0 && cur_term != 0) {
+ TTY buf;
-#ifdef __EMX__
- setmode(SP->_ifd, O_BINARY);
-#endif
+ BEFORE("cbreak");
+ _nc_setmode(O_BINARY);
+ buf = cur_term->Nttyb;
#ifdef TERMIOS
- BEFORE("cbreak");
- cur_term->Nttyb.c_lflag &= ~ICANON;
- cur_term->Nttyb.c_iflag &= ~ICRNL;
- cur_term->Nttyb.c_lflag |= ISIG;
- cur_term->Nttyb.c_cc[VMIN] = 1;
- cur_term->Nttyb.c_cc[VTIME] = 0;
- AFTER("cbreak");
+ buf.c_lflag &= ~ICANON;
+ buf.c_iflag &= ~ICRNL;
+ buf.c_lflag |= ISIG;
+ buf.c_cc[VMIN] = 1;
+ buf.c_cc[VTIME] = 0;
#else
- cur_term->Nttyb.sg_flags |= CBREAK;
+ buf.sg_flags |= CBREAK;
#endif
- returnCode(_nc_set_tty_mode(&cur_term->Nttyb));
+ if ((result = _nc_set_tty_mode(&buf)) == OK) {
+ SP->_cbreak = 1;
+ cur_term->Nttyb = buf;
+ }
+ AFTER("cbreak");
+ }
+ returnCode(result);
}
+/*
+ * Note:
+ * this implementation may be wrong. See the comment under intrflush().
+ */
NCURSES_EXPORT(void)
qiflush(void)
{
+ int result = ERR;
+
T((T_CALLED("qiflush()")));
- /*
- * Note: this implementation may be wrong. See the comment under
- * intrflush().
- */
+ if (cur_term != 0) {
+ TTY buf;
+ BEFORE("qiflush");
+ buf = cur_term->Nttyb;
#ifdef TERMIOS
- BEFORE("qiflush");
- cur_term->Nttyb.c_lflag &= ~(NOFLSH);
- AFTER("qiflush");
- (void) _nc_set_tty_mode(&cur_term->Nttyb);
- returnVoid;
+ buf.c_lflag &= ~(NOFLSH);
+ result = _nc_set_tty_mode(&buf);
+#else
+ /* FIXME */
#endif
+ if (result == OK)
+ cur_term->Nttyb = buf;
+ AFTER("qiflush");
+ }
+ returnVoid;
}
NCURSES_EXPORT(int)
noraw(void)
{
+ int result = ERR;
+
T((T_CALLED("noraw()")));
- SP->_raw = FALSE;
- SP->_cbreak = 0;
+ if (SP != 0 && cur_term != 0) {
+ TTY buf;
-#ifdef __EMX__
- setmode(SP->_ifd, O_TEXT);
-#endif
+ BEFORE("noraw");
+ _nc_setmode(O_TEXT);
+ buf = cur_term->Nttyb;
#ifdef TERMIOS
- BEFORE("noraw");
- cur_term->Nttyb.c_lflag |= ISIG | ICANON |
- (cur_term->Ottyb.c_lflag & IEXTEN);
- cur_term->Nttyb.c_iflag |= COOKED_INPUT;
- AFTER("noraw");
+ buf.c_lflag |= ISIG | ICANON |
+ (cur_term->Ottyb.c_lflag & IEXTEN);
+ buf.c_iflag |= COOKED_INPUT;
#else
- cur_term->Nttyb.sg_flags &= ~(RAW | CBREAK);
+ buf.sg_flags &= ~(RAW | CBREAK);
#endif
- returnCode(_nc_set_tty_mode(&cur_term->Nttyb));
+ if ((result = _nc_set_tty_mode(&buf)) == OK) {
+ SP->_raw = FALSE;
+ SP->_cbreak = 0;
+ cur_term->Nttyb = buf;
+ }
+ AFTER("noraw");
+ }
+ returnCode(result);
}
NCURSES_EXPORT(int)
nocbreak(void)
{
+ int result = ERR;
+
T((T_CALLED("nocbreak()")));
- SP->_cbreak = 0;
+ if (SP != 0 && cur_term != 0) {
+ TTY buf;
-#ifdef __EMX__
- setmode(SP->_ifd, O_TEXT);
-#endif
+ BEFORE("nocbreak");
+ _nc_setmode(O_TEXT);
+ buf = cur_term->Nttyb;
#ifdef TERMIOS
- BEFORE("nocbreak");
- cur_term->Nttyb.c_lflag |= ICANON;
- cur_term->Nttyb.c_iflag |= ICRNL;
- AFTER("nocbreak");
+ buf.c_lflag |= ICANON;
+ buf.c_iflag |= ICRNL;
#else
- cur_term->Nttyb.sg_flags &= ~CBREAK;
+ buf.sg_flags &= ~CBREAK;
#endif
- returnCode(_nc_set_tty_mode(&cur_term->Nttyb));
+ if ((result = _nc_set_tty_mode(&buf)) == OK) {
+ SP->_cbreak = 0;
+ cur_term->Nttyb = buf;
+ }
+ AFTER("nocbreak");
+ }
+ returnCode(result);
}
+/*
+ * Note:
+ * this implementation may be wrong. See the comment under intrflush().
+ */
NCURSES_EXPORT(void)
noqiflush(void)
{
+ int result = ERR;
+
T((T_CALLED("noqiflush()")));
- /*
- * Note: this implementation may be wrong. See the comment under
- * intrflush().
- */
+ if (cur_term != 0) {
+ TTY buf;
+ BEFORE("noqiflush");
+ buf = cur_term->Nttyb;
#ifdef TERMIOS
- BEFORE("noqiflush");
- cur_term->Nttyb.c_lflag |= NOFLSH;
- AFTER("noqiflush");
- (void) _nc_set_tty_mode(&cur_term->Nttyb);
- returnVoid;
+ buf.c_lflag |= NOFLSH;
+ result = _nc_set_tty_mode(&buf);
+#else
+ /* FIXME */
#endif
+ if (result == OK) {
+ cur_term->Nttyb = buf;
+ }
+ AFTER("noqiflush");
+ }
+ returnVoid;
}
+/*
+ * This call does the same thing as the qiflush()/noqiflush() pair. We know
+ * for certain that SVr3 intrflush() tweaks the NOFLSH bit; on the other hand,
+ * the match (in the SVr4 man pages) between the language describing NOFLSH in
+ * termio(7) and the language describing qiflush()/noqiflush() in
+ * curs_inopts(3x) is too exact to be coincidence.
+ */
NCURSES_EXPORT(int)
intrflush(WINDOW *win GCC_UNUSED, bool flag)
{
+ int result = ERR;
+
T((T_CALLED("intrflush(%d)"), flag));
- /*
- * This call does the same thing as the qiflush()/noqiflush() pair. We
- * know for certain that SVr3 intrflush() tweaks the NOFLSH bit; on the
- * other hand, the match (in the SVr4 man pages) between the language
- * describing NOFLSH in termio(7) and the language describing
- * qiflush()/noqiflush() in curs_inopts(3x) is too exact to be coincidence.
- */
+ if (cur_term != 0) {
+ TTY buf;
+ BEFORE("intrflush");
+ buf = cur_term->Nttyb;
#ifdef TERMIOS
- BEFORE("intrflush");
- if (flag)
- cur_term->Nttyb.c_lflag &= ~(NOFLSH);
- else
- cur_term->Nttyb.c_lflag |= (NOFLSH);
- AFTER("intrflush");
- returnCode(_nc_set_tty_mode(&cur_term->Nttyb));
+ if (flag)
+ buf.c_lflag &= ~(NOFLSH);
+ else
+ buf.c_lflag |= (NOFLSH);
+ result = _nc_set_tty_mode(&buf);
#else
- returnCode(ERR);
+ /* FIXME */
#endif
+ if (result == OK) {
+ cur_term->Nttyb = buf;
+ }
+ AFTER("intrflush");
+ }
+ returnCode(result);
}
diff --git a/lib/libcurses/tinfo/lib_setup.c b/lib/libcurses/tinfo/lib_setup.c
index 1db8a06bc1b..63643848a29 100644
--- a/lib/libcurses/tinfo/lib_setup.c
+++ b/lib/libcurses/tinfo/lib_setup.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_setup.c,v 1.11 2001/01/22 18:01:53 millert Exp $ */
+/* $OpenBSD: lib_setup.c,v 1.12 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -48,9 +49,13 @@
#define _POSIX_SOURCE
#endif
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
#include <term.h> /* lines, columns, cur_term */
-MODULE_ID("$From: lib_setup.c,v 1.64 2000/12/10 02:55:07 tom Exp $")
+MODULE_ID("$Id: lib_setup.c,v 1.12 2010/01/12 23:22:06 nicm Exp $")
/****************************************************************************
*
@@ -74,6 +79,10 @@ MODULE_ID("$From: lib_setup.c,v 1.64 2000/12/10 02:55:07 tom Exp $")
# include <sys/ptem.h>
#endif
+#if HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
/*
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
* Solaris, IRIX) define TIOCGWINSZ and struct winsize.
@@ -92,31 +101,113 @@ MODULE_ID("$From: lib_setup.c,v 1.64 2000/12/10 02:55:07 tom Exp $")
# endif
#endif
-static int _use_env = TRUE;
+/*
+ * Reduce explicit use of "cur_term" global variable.
+ */
+#undef CUR
+#define CUR termp->type.
+
+/*
+ * Wrap global variables in this module.
+ */
+#if USE_REENTRANT
+NCURSES_EXPORT(char *)
+NCURSES_PUBLIC_VAR(ttytype) (void)
+{
+ static char empty[] = "";
+ return cur_term ? cur_term->type.term_names : empty;
+}
+NCURSES_EXPORT(int *)
+_nc_ptr_Lines(void)
+{
+ return ptrLines();
+}
+NCURSES_EXPORT(int)
+NCURSES_PUBLIC_VAR(LINES) (void)
+{
+ return *_nc_ptr_Lines();
+}
+NCURSES_EXPORT(int *)
+_nc_ptr_Cols(void)
+{
+ return ptrCols();
+}
+NCURSES_EXPORT(int)
+NCURSES_PUBLIC_VAR(COLS) (void)
+{
+ return *_nc_ptr_Cols();
+}
+NCURSES_EXPORT(int)
+NCURSES_PUBLIC_VAR(TABSIZE) (void)
+{
+ return SP ? SP->_TABSIZE : 8;
+}
+#else
+NCURSES_EXPORT_VAR(char) ttytype[NAMESIZE] = "";
+NCURSES_EXPORT_VAR(int) LINES = 0;
+NCURSES_EXPORT_VAR(int) COLS = 0;
+NCURSES_EXPORT_VAR(int) TABSIZE = 0;
+#endif
+
+#if NCURSES_EXT_FUNCS
+NCURSES_EXPORT(int)
+set_tabsize(int value)
+{
+ int code = OK;
+#if USE_REENTRANT
+ if (SP) {
+ SP->_TABSIZE = value;
+ } else {
+ code = ERR;
+ }
+#else
+ TABSIZE = value;
+#endif
+ return code;
+}
+#endif
+
+#if USE_SIGWINCH
+/*
+ * If we have a pending SIGWINCH, set the flag in each screen.
+ */
+NCURSES_EXPORT(int)
+_nc_handle_sigwinch(SCREEN *sp)
+{
+ SCREEN *scan;
-static void do_prototype(void);
+ if (_nc_globals.have_sigwinch) {
+ _nc_globals.have_sigwinch = 0;
+
+ for (each_screen(scan)) {
+ scan->_sig_winch = TRUE;
+ }
+ }
+
+ return (sp ? sp->_sig_winch : 0);
+}
+
+#endif
NCURSES_EXPORT(void)
use_env(bool f)
{
- _use_env = f;
+ T((T_CALLED("use_env()")));
+ _nc_prescreen.use_env = f;
+ returnVoid;
}
-NCURSES_EXPORT_VAR(int)
-LINES = 0;
-NCURSES_EXPORT_VAR(int)
-COLS = 0;
-NCURSES_EXPORT_VAR(int)
-TABSIZE = 0;
-
- static void
- _nc_get_screensize(int *linep, int *colp)
+NCURSES_EXPORT(void)
+_nc_get_screensize(SCREEN *sp, int *linep, int *colp)
/* Obtain lines/columns values from the environment and/or terminfo entry */
{
+ TERMINAL *termp = cur_term;
+ int my_tabsize;
+
/* figure out the size of the screen */
T(("screen size: terminfo lines = %d columns = %d", lines, columns));
- if (!_use_env) {
+ if (!_nc_prescreen.use_env) {
*linep = (int) lines;
*colp = (int) columns;
} else { /* usually want to query LINES and COLUMNS from environment */
@@ -162,7 +253,7 @@ TABSIZE = 0;
* environment variable.
*/
if (*linep <= 0)
- *linep = WINSIZE_ROWS(size);
+ *linep = (sp != 0 && sp->_filtered) ? 1 : WINSIZE_ROWS(size);
if (*colp <= 0)
*colp = WINSIZE_COLS(size);
}
@@ -180,8 +271,10 @@ TABSIZE = 0;
}
/* the ultimate fallback, assume fixed 24x80 size */
- if (*linep <= 0 || *colp <= 0) {
+ if (*linep <= 0) {
*linep = 24;
+ }
+ if (*colp <= 0) {
*colp = 80;
}
@@ -196,22 +289,42 @@ TABSIZE = 0;
T(("screen size is %dx%d", *linep, *colp));
if (VALID_NUMERIC(init_tabs))
- TABSIZE = (int) init_tabs;
+ my_tabsize = (int) init_tabs;
else
- TABSIZE = 8;
- T(("TABSIZE = %d", TABSIZE));
+ my_tabsize = 8;
+#if USE_REENTRANT
+ if (sp != 0)
+ sp->_TABSIZE = my_tabsize;
+#else
+ TABSIZE = my_tabsize;
+#endif
+ T(("TABSIZE = %d", TABSIZE));
}
#if USE_SIZECHANGE
NCURSES_EXPORT(void)
-_nc_update_screensize(void)
+_nc_update_screensize(SCREEN *sp)
{
- int my_lines, my_cols;
+ TERMINAL *termp = cur_term;
+ int old_lines = lines;
+ int new_lines;
+ int old_cols = columns;
+ int new_cols;
- _nc_get_screensize(&my_lines, &my_cols);
- if (SP != 0 && SP->_resize != 0)
- SP->_resize(my_lines, my_cols);
+ _nc_get_screensize(sp, &new_lines, &new_cols);
+
+ /*
+ * See is_term_resized() and resizeterm().
+ * We're doing it this way because those functions belong to the upper
+ * ncurses library, while this resides in the lower terminfo library.
+ */
+ if (sp != 0
+ && sp->_resize != 0) {
+ if ((new_lines != old_lines) || (new_cols != old_cols))
+ sp->_resize(new_lines, new_cols);
+ sp->_sig_winch = FALSE;
+ }
}
#endif
@@ -237,33 +350,16 @@ _nc_update_screensize(void)
exit(EXIT_FAILURE);\
}
-#if USE_DATABASE
+#if USE_DATABASE || USE_TERMCAP
+/*
+ * Return 1 if entry found, 0 if not found, -1 if database not accessible,
+ * just like tgetent().
+ */
static int
-grab_entry(const char *const tn, TERMTYPE * const tp)
-/* return 1 if entry found, 0 if not found, -1 if database not accessible */
+grab_entry(const char *const tn, TERMTYPE *const tp)
{
char filename[PATH_MAX];
- int status;
-
- /*
- * $TERM shouldn't contain pathname delimiters.
- */
- if (strchr(tn, '/'))
- return 0;
-
- if ((status = _nc_read_entry(tn, filename, tp)) != 1) {
-
-#if !PURE_TERMINFO
- /*
- * Try falling back on the termcap file.
- * Note: allowing this call links the entire terminfo/termcap
- * compiler into the startup code. It's preferable to build a
- * real terminfo database and use that.
- */
- status = _nc_read_termcap_entry(tn, tp);
-#endif /* PURE_TERMINFO */
-
- }
+ int status = _nc_read_entry(tn, filename, tp);
/*
* If we have an entry, force all of the cancelled strings to null
@@ -271,8 +367,8 @@ grab_entry(const char *const tn, TERMTYPE * const tp)
* (The terminfo compiler bypasses this logic, since it must know if
* a string is cancelled, for merging entries).
*/
- if (status == 1) {
- int n;
+ if (status == TGETENT_YES) {
+ unsigned n;
for_each_boolean(n, tp) {
if (!VALID_BOOLEAN(tp->Booleans[n]))
tp->Booleans[n] = FALSE;
@@ -286,139 +382,252 @@ grab_entry(const char *const tn, TERMTYPE * const tp)
}
#endif
-NCURSES_EXPORT_VAR(char) ttytype[NAMESIZE] = "";
+/*
+** do_prototype()
+**
+** Take the real command character out of the CC environment variable
+** and substitute it in for the prototype given in 'command_character'.
+*/
+static void
+do_prototype(TERMINAL * termp)
+{
+ unsigned i;
+ char CC;
+ char proto;
+ char *tmp;
+
+ if ((tmp = getenv("CC")) != 0) {
+ if ((CC = *tmp) != 0) {
+ proto = *command_character;
+
+ for_each_string(i, &(termp->type)) {
+ for (tmp = termp->type.Strings[i]; *tmp; tmp++) {
+ if (*tmp == proto)
+ *tmp = CC;
+ }
+ }
+ }
+ }
+}
/*
- * setupterm(termname, Filedes, errret)
- *
- * Find and read the appropriate object file for the terminal
- * Make cur_term point to the structure.
- *
+ * Find the locale which is in effect.
+ */
+NCURSES_EXPORT(char *)
+_nc_get_locale(void)
+{
+ char *env;
+#if HAVE_LOCALE_H
+ /*
+ * This is preferable to using getenv() since it ensures that we are using
+ * the locale which was actually initialized by the application.
+ */
+ env = setlocale(LC_CTYPE, 0);
+#else
+ if (((env = getenv("LC_ALL")) != 0 && *env != '\0')
+ || ((env = getenv("LC_CTYPE")) != 0 && *env != '\0')
+ || ((env = getenv("LANG")) != 0 && *env != '\0')) {
+ ;
+ }
+#endif
+ T(("_nc_get_locale %s", _nc_visbuf(env)));
+ return env;
+}
+
+/*
+ * Check if we are running in a UTF-8 locale.
+ */
+NCURSES_EXPORT(int)
+_nc_unicode_locale(void)
+{
+ int result = 0;
+#if HAVE_LANGINFO_CODESET
+ char *env = nl_langinfo(CODESET);
+ result = !strcmp(env, "UTF-8");
+ T(("_nc_unicode_locale(%s) ->%d", env, result));
+#else
+ char *env = _nc_get_locale();
+ if (env != 0) {
+ if (strstr(env, ".UTF-8") != 0) {
+ result = 1;
+ T(("_nc_unicode_locale(%s) ->%d", env, result));
+ }
+ }
+#endif
+ return result;
+}
+
+#define CONTROL_N(s) ((s) != 0 && strstr(s, "\016") != 0)
+#define CONTROL_O(s) ((s) != 0 && strstr(s, "\017") != 0)
+
+/*
+ * Check for known broken cases where a UTF-8 locale breaks the alternate
+ * character set.
*/
+NCURSES_EXPORT(int)
+_nc_locale_breaks_acs(TERMINAL * termp)
+{
+ char *env;
+
+ if ((env = getenv("NCURSES_NO_UTF8_ACS")) != 0) {
+ return atoi(env);
+ } else if ((env = getenv("TERM")) != 0) {
+ if (strstr(env, "linux"))
+ return 1; /* always broken */
+ if (strstr(env, "screen") != 0
+ && ((env = getenv("TERMCAP")) != 0
+ && strstr(env, "screen") != 0)
+ && strstr(env, "hhII00") != 0) {
+ if (CONTROL_N(enter_alt_charset_mode) ||
+ CONTROL_O(enter_alt_charset_mode) ||
+ CONTROL_N(set_attributes) ||
+ CONTROL_O(set_attributes))
+ return 1;
+ }
+ }
+ return 0;
+}
+/*
+ * This entrypoint is called from tgetent() to allow a special case of reusing
+ * the same TERMINAL data (see comment).
+ */
NCURSES_EXPORT(int)
-setupterm
-(NCURSES_CONST char *tname, int Filedes, int *errret)
+_nc_setupterm(NCURSES_CONST char *tname, int Filedes, int *errret, bool reuse)
{
- struct term *term_ptr;
+ TERMINAL *termp;
int status;
+ START_TRACE();
T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret));
if (tname == 0) {
tname = getenv("TERM");
if (tname == 0 || *tname == '\0') {
- ret_error0(-1, "TERM environment variable not set.\n");
+ ret_error0(TGETENT_ERR, "TERM environment variable not set.\n");
}
}
+
if (strlen(tname) > MAX_NAME_SIZE) {
- ret_error(-1, "TERM environment must be <= %d characters.\n",
+ ret_error(TGETENT_ERR,
+ "TERM environment must be <= %d characters.\n",
MAX_NAME_SIZE);
}
T(("your terminal name is %s", tname));
- term_ptr = typeCalloc(TERMINAL, 1);
+ /*
+ * Allow output redirection. This is what SVr3 does. If stdout is
+ * directed to a file, screen updates go to standard error.
+ */
+ if (Filedes == STDOUT_FILENO && !isatty(Filedes))
+ Filedes = STDERR_FILENO;
- if (term_ptr == 0) {
- ret_error0(-1, "Not enough memory to create terminal structure.\n");
- }
-#if USE_DATABASE
- status = grab_entry(tname, &term_ptr->type);
+ /*
+ * Check if we have already initialized to use this terminal. If so, we
+ * do not need to re-read the terminfo entry, or obtain TTY settings.
+ *
+ * This is an improvement on SVr4 curses. If an application mixes curses
+ * and termcap calls, it may call both initscr and tgetent. This is not
+ * really a good thing to do, but can happen if someone tries using ncurses
+ * with the readline library. The problem we are fixing is that when
+ * tgetent calls setupterm, the resulting Ottyb struct in cur_term is
+ * zeroed. A subsequent call to endwin uses the zeroed terminal settings
+ * rather than the ones saved in initscr. So we check if cur_term appears
+ * to contain terminal settings for the same output file as our current
+ * call - and copy those terminal settings. (SVr4 curses does not do this,
+ * however applications that are working around the problem will still work
+ * properly with this feature).
+ */
+ if (reuse
+ && (termp = cur_term) != 0
+ && termp->Filedes == Filedes
+ && termp->_termname != 0
+ && !strcmp(termp->_termname, tname)
+ && _nc_name_match(termp->type.term_names, tname, "|")) {
+ T(("reusing existing terminal information and mode-settings"));
+ } else {
+
+ termp = typeCalloc(TERMINAL, 1);
+
+ if (termp == 0) {
+ ret_error0(TGETENT_ERR,
+ "Not enough memory to create terminal structure.\n");
+ }
+#if USE_DATABASE || USE_TERMCAP
+ status = grab_entry(tname, &termp->type);
#else
- status = 0;
+ status = TGETENT_NO;
#endif
- /* try fallback list if entry on disk */
- if (status != 1) {
- const TERMTYPE *fallback = _nc_fallback(tname);
+ /* try fallback list if entry on disk */
+ if (status != TGETENT_YES) {
+ const TERMTYPE *fallback = _nc_fallback(tname);
- if (fallback) {
- term_ptr->type = *fallback;
- status = 1;
+ if (fallback) {
+ termp->type = *fallback;
+ status = TGETENT_YES;
+ }
}
- }
- if (status == -1) {
- ret_error0(-1, "terminals database is inaccessible\n");
- } else if (status == 0) {
- ret_error(0, "'%s': unknown terminal type.\n", tname);
- }
+ if (status != TGETENT_YES) {
+ del_curterm(termp);
+ if (status == TGETENT_ERR) {
+ ret_error0(status, "terminals database is inaccessible\n");
+ } else if (status == TGETENT_NO) {
+ ret_error(status, "'%s': unknown terminal type.\n", tname);
+ }
+ }
+#if !USE_REENTRANT
+ strncpy(ttytype, termp->type.term_names, NAMESIZE - 1);
+ ttytype[NAMESIZE - 1] = '\0';
+#endif
- /*
- * Improve on SVr4 curses. If an application mixes curses and termcap
- * calls, it may call both initscr and tgetent. This is not really a
- * good thing to do, but can happen if someone tries using ncurses with
- * the readline library. The problem we are fixing is that when
- * tgetent calls setupterm, the resulting Ottyb struct in cur_term is
- * zeroed. A subsequent call to endwin uses the zeroed terminal
- * settings rather than the ones saved in initscr. So we check if
- * cur_term appears to contain terminal settings for the same output
- * file as our current call - and copy those terminal settings. (SVr4
- * curses does not do this, however applications that are working
- * around the problem will still work properly with this feature).
- */
- if (cur_term != 0) {
- if (cur_term->Filedes == Filedes)
- term_ptr->Ottyb = cur_term->Ottyb;
- }
+ termp->Filedes = Filedes;
+ termp->_termname = strdup(tname);
- set_curterm(term_ptr);
+ set_curterm(termp);
- if (command_character && getenv("CC"))
- do_prototype();
+ if (command_character && getenv("CC"))
+ do_prototype(termp);
- strlcpy(ttytype, cur_term->type.term_names, NAMESIZE);
+ /*
+ * 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 (isatty(Filedes)) {
+ def_prog_mode();
+ baudrate();
+ }
+ }
/*
- * Allow output redirection. This is what SVr3 does.
- * If stdout is directed to a file, screen updates go
- * to standard error.
+ * We should always check the screensize, just in case.
*/
- if (Filedes == STDOUT_FILENO && !isatty(Filedes))
- Filedes = STDERR_FILENO;
- cur_term->Filedes = Filedes;
-
- _nc_get_screensize(&LINES, &COLS);
+ _nc_get_screensize(SP, ptrLines(), ptrCols());
if (errret)
- *errret = 1;
-
- T((T_CREATE("screen %s %dx%d"), tname, LINES, COLS));
+ *errret = TGETENT_YES;
if (generic_type) {
- ret_error(0, "'%s': I need something more specific.\n", tname);
+ ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname);
}
if (hard_copy) {
- ret_error(1, "'%s': I can't handle hardcopy terminals.\n", tname);
+ ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname);
}
returnCode(OK);
}
/*
-** do_prototype()
-**
-** Take the real command character out of the CC environment variable
-** and substitute it in for the prototype given in 'command_character'.
-**
-*/
-
-static void
-do_prototype(void)
+ * setupterm(termname, Filedes, errret)
+ *
+ * Find and read the appropriate object file for the terminal
+ * Make cur_term point to the structure.
+ */
+NCURSES_EXPORT(int)
+setupterm(NCURSES_CONST char *tname, int Filedes, int *errret)
{
- int i;
- char CC;
- char proto;
- char *tmp;
-
- tmp = getenv("CC");
- CC = *tmp;
- proto = *command_character;
-
- for_each_string(i, &(cur_term->type)) {
- for (tmp = cur_term->type.Strings[i]; *tmp; tmp++) {
- if (*tmp == proto)
- *tmp = CC;
- }
- }
+ return _nc_setupterm(tname, Filedes, errret, FALSE);
}
diff --git a/lib/libcurses/tinfo/lib_termcap.c b/lib/libcurses/tinfo/lib_termcap.c
index b307aac5754..66ccb8cf63d 100644
--- a/lib/libcurses/tinfo/lib_termcap.c
+++ b/lib/libcurses/tinfo/lib_termcap.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_termcap.c,v 1.9 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: lib_termcap.c,v 1.10 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,27 +31,36 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
+ * *
+ * some of the code in here was contributed by: *
+ * Magnus Bengtsson, d6mbeng@dtek.chalmers.se (Nov'93) *
+ * (but it has changed a lot) *
****************************************************************************/
+#define __INTERNAL_CAPS_VISIBLE
#include <curses.priv.h>
#include <termcap.h>
#include <tic.h>
+#include <ctype.h>
-#define __INTERNAL_CAPS_VISIBLE
#include <term_entry.h>
-MODULE_ID("$From: lib_termcap.c,v 1.39 2000/12/10 02:56:30 tom Exp $")
+MODULE_ID("$Id: lib_termcap.c,v 1.10 2010/01/12 23:22:06 nicm Exp $")
-/*
- some of the code in here was contributed by:
- Magnus Bengtsson, d6mbeng@dtek.chalmers.se
-*/
+NCURSES_EXPORT_VAR(char *) UP = 0;
+NCURSES_EXPORT_VAR(char *) BC = 0;
-NCURSES_EXPORT_VAR(char *)
-UP = 0;
-NCURSES_EXPORT_VAR(char *)
-BC = 0;
+#define MyCache _nc_globals.tgetent_cache
+#define CacheInx _nc_globals.tgetent_index
+#define CacheSeq _nc_globals.tgetent_sequence
+
+#define FIX_SGR0 MyCache[CacheInx].fix_sgr0
+#define LAST_TRM MyCache[CacheInx].last_term
+#define LAST_BUF MyCache[CacheInx].last_bufp
+#define LAST_USE MyCache[CacheInx].last_used
+#define LAST_SEQ MyCache[CacheInx].sequence
/***************************************************************************
*
@@ -69,19 +78,73 @@ BC = 0;
***************************************************************************/
NCURSES_EXPORT(int)
-tgetent
-(char *bufp GCC_UNUSED, const char *name)
+tgetent(char *bufp, const char *name)
{
int errcode;
+ int n;
+ bool found_cache = FALSE;
+ START_TRACE();
T((T_CALLED("tgetent()")));
- setupterm((NCURSES_CONST char *) name, STDOUT_FILENO, &errcode);
+ _nc_setupterm((NCURSES_CONST char *) name, STDOUT_FILENO, &errcode, TRUE);
+
+ /*
+ * In general we cannot tell if the fixed sgr0 is still used by the
+ * caller, but if tgetent() is called with the same buffer, that is
+ * good enough, since the previous data would be invalidated by the
+ * current call.
+ *
+ * bufp may be a null pointer, e.g., GNU termcap. That allocates data,
+ * which is good until the next tgetent() call. The conventional termcap
+ * is inconvenient because of the fixed buffer size, but because it uses
+ * caller-supplied buffers, can have multiple terminal descriptions in
+ * use at a given time.
+ */
+ for (n = 0; n < TGETENT_MAX; ++n) {
+ bool same_result = (MyCache[n].last_used && MyCache[n].last_bufp == bufp);
+ if (same_result) {
+ CacheInx = n;
+ if (FIX_SGR0 != 0) {
+ FreeAndNull(FIX_SGR0);
+ }
+ /*
+ * Also free the terminfo data that we loaded (much bigger leak).
+ */
+ if (LAST_TRM != 0 && LAST_TRM != cur_term) {
+ TERMINAL *trm = LAST_TRM;
+ del_curterm(LAST_TRM);
+ for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx)
+ if (LAST_TRM == trm)
+ LAST_TRM = 0;
+ CacheInx = n;
+ }
+ found_cache = TRUE;
+ break;
+ }
+ }
+ if (!found_cache) {
+ int best = 0;
+
+ for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
+ if (LAST_SEQ < MyCache[best].sequence) {
+ best = CacheInx;
+ }
+ }
+ CacheInx = best;
+ }
+ LAST_TRM = cur_term;
+ LAST_SEQ = ++CacheSeq;
+
+ PC = 0;
+ UP = 0;
+ BC = 0;
+ FIX_SGR0 = 0; /* don't free it - application may still use */
if (errcode == 1) {
if (cursor_left)
- if ((backspaces_with_bs = !strcmp(cursor_left, "\b")) == 0)
+ if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
backspace_if_not_bs = cursor_left;
/* we're required to export these */
@@ -92,6 +155,18 @@ tgetent
if (backspace_if_not_bs != NULL)
BC = backspace_if_not_bs;
+ if ((FIX_SGR0 = _nc_trim_sgr0(&(cur_term->type))) != 0) {
+ if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
+ if (FIX_SGR0 != exit_attribute_mode) {
+ free(FIX_SGR0);
+ }
+ FIX_SGR0 = 0;
+ }
+ }
+ LAST_BUF = bufp;
+ LAST_USE = TRUE;
+
+ SetNoPadding(SP);
(void) baudrate(); /* sets ospeed as a side-effect */
/* LINT_PREPRO
@@ -116,7 +191,7 @@ tgetent
NCURSES_EXPORT(int)
tgetflag(NCURSES_CONST char *id)
{
- int i;
+ unsigned i;
T((T_CALLED("tgetflag(%s)"), id));
if (cur_term != 0) {
@@ -144,7 +219,7 @@ tgetflag(NCURSES_CONST char *id)
NCURSES_EXPORT(int)
tgetnum(NCURSES_CONST char *id)
{
- int i;
+ unsigned i;
T((T_CALLED("tgetnum(%s)"), id));
if (cur_term != 0) {
@@ -171,28 +246,49 @@ tgetnum(NCURSES_CONST char *id)
***************************************************************************/
NCURSES_EXPORT(char *)
-tgetstr
-(NCURSES_CONST char *id, char **area)
+tgetstr(NCURSES_CONST char *id, char **area)
{
- int i;
+ unsigned i;
+ char *result = NULL, *base;
+ if (area != 0 && *area != 0)
+ base = *area;
T((T_CALLED("tgetstr(%s,%p)"), id, area));
if (cur_term != 0) {
TERMTYPE *tp = &(cur_term->type);
for_each_string(i, tp) {
const char *capname = ExtStrname(tp, i, strcodes);
if (!strncmp(id, capname, 2)) {
- TR(TRACE_DATABASE, ("found match : %s", _nc_visbuf(tp->Strings[i])));
+ result = tp->Strings[i];
+ TR(TRACE_DATABASE, ("found match : %s", _nc_visbuf(result)));
/* setupterm forces canceled strings to null */
- if (area != 0
- && *area != 0
- && VALID_STRING(tp->Strings[i])) {
- (void) strlcpy(*area, tp->Strings[i], 1024);
- *area += strlen(*area) + 1;
+ if (VALID_STRING(result)) {
+ if (result == exit_attribute_mode
+ && FIX_SGR0 != 0) {
+ result = FIX_SGR0;
+ TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result)));
+ }
+ if (area != 0 && *area != 0) {
+ (void) strlcpy(*area, result, 1024 - (*area - base));
+ result = *area;
+ *area += strlen(*area) + 1;
+ }
}
- returnPtr(tp->Strings[i]);
+ break;
}
}
}
- returnPtr(NULL);
+ returnPtr(result);
+}
+
+#if NO_LEAKS
+NCURSES_EXPORT(void)
+_nc_tgetent_leaks(void)
+{
+ for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
+ FreeIfNeeded(FIX_SGR0);
+ if (LAST_TRM != 0)
+ del_curterm(LAST_TRM);
+ }
}
+#endif
diff --git a/lib/libcurses/tinfo/lib_termname.c b/lib/libcurses/tinfo/lib_termname.c
index 8e744f1ed31..f4ddf8b334b 100644
--- a/lib/libcurses/tinfo/lib_termname.c
+++ b/lib/libcurses/tinfo/lib_termname.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_termname.c,v 1.4 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: lib_termname.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2001,2003 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,21 +29,18 @@
****************************************************************************/
#include <curses.priv.h>
-#include <tic.h> /* for MAX_ALIAS */
-MODULE_ID("$From: lib_termname.c,v 1.6 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: lib_termname.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(char *)
termname(void)
{
- char *name = getenv("TERM");
- static char ret[MAX_ALIAS + 1];
+ char *name = 0;
- T(("termname() called"));
+ T((T_CALLED("termname()")));
- if (name != 0) {
- (void) strlcpy(ret, name, sizeof(ret));
- name = ret;
- }
- return name;
+ if (cur_term != 0)
+ name = cur_term->_termname;
+
+ returnPtr(name);
}
diff --git a/lib/libcurses/tinfo/lib_tgoto.c b/lib/libcurses/tinfo/lib_tgoto.c
index bb7fb9c2670..536771fd17e 100644
--- a/lib/libcurses/tinfo/lib_tgoto.c
+++ b/lib/libcurses/tinfo/lib_tgoto.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_tgoto.c,v 1.4 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: lib_tgoto.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 2000 Free Software Foundation, Inc. *
+ * Copyright (c) 2000-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -37,7 +37,7 @@
#include <ctype.h>
#include <termcap.h>
-MODULE_ID("$From: lib_tgoto.c,v 1.5 2000/12/10 01:33:16 tom Exp $")
+MODULE_ID("$Id: lib_tgoto.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
#if !PURE_TERMINFO
static bool
@@ -91,13 +91,13 @@ tgoto_internal(const char *string, int x, int y)
while (*string != 0) {
if ((used + need) > length) {
length += (used + need);
- if ((result = _nc_doalloc(result, length)) == 0) {
+ if ((result = typeRealloc(char, length, result)) == 0) {
length = 0;
break;
}
}
if (*string == '%') {
- char *fmt = 0;
+ const char *fmt = 0;
switch (*++string) {
case '\0':
@@ -115,7 +115,7 @@ tgoto_internal(const char *string, int x, int y)
*value %= 1000;
break;
case '+':
- *value += CharOf(*++string);
+ *value += UChar(*++string);
/* FALLTHRU */
case '.':
/*
@@ -131,7 +131,7 @@ tgoto_internal(const char *string, int x, int y)
*value = 0200; /* tputs will treat this as \0 */
}
}
- result[used++] = *value++;
+ result[used++] = (char) *value++;
break;
case '%':
result[used++] = *string;
@@ -158,7 +158,7 @@ tgoto_internal(const char *string, int x, int y)
*value = 16 * (*value / 10) + (*value % 10);
break;
case 'D': /* Reverse coding (Delta Data) */
- *value -= 2 * (*value / 16);
+ *value -= 2 * (*value % 16);
break;
}
if (fmt != 0) {
@@ -175,14 +175,14 @@ tgoto_internal(const char *string, int x, int y)
}
string++;
}
- if (need_BC) {
+ if (result != 0) {
copied = strlcpy(result + used, BC, length - used);
if (copied < length - used)
used += copied;
else
used += length - used - 1;
+ result[used] = '\0';
}
- result[used] = '\0';
return result;
}
#endif
@@ -192,8 +192,7 @@ tgoto_internal(const char *string, int x, int y)
* the last two arguments when invoking tparm().
*/
NCURSES_EXPORT(char *)
-tgoto
-(const char *string, int x, int y)
+tgoto(const char *string, int x, int y)
{
char *result;
@@ -203,6 +202,6 @@ tgoto
result = tgoto_internal(string, x, y);
else
#endif
- result = tparm((NCURSES_CONST char *) string, y, x);
+ result = TPARM_2((NCURSES_CONST char *) string, y, x);
returnPtr(result);
}
diff --git a/lib/libcurses/tinfo/lib_ti.c b/lib/libcurses/tinfo/lib_ti.c
index 3c1595aef0c..9416c56cca9 100644
--- a/lib/libcurses/tinfo/lib_ti.c
+++ b/lib/libcurses/tinfo/lib_ti.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_ti.c,v 1.6 2001/01/22 18:01:54 millert Exp $ */
+/* $OpenBSD: lib_ti.c,v 1.7 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2000,2003 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -38,12 +38,12 @@
#include <term_entry.h>
#include <tic.h>
-MODULE_ID("$From: lib_ti.c,v 1.22 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: lib_ti.c,v 1.7 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(int)
tigetflag(NCURSES_CONST char *str)
{
- int i;
+ unsigned i;
T((T_CALLED("tigetflag(%s)"), str));
@@ -64,7 +64,7 @@ tigetflag(NCURSES_CONST char *str)
NCURSES_EXPORT(int)
tigetnum(NCURSES_CONST char *str)
{
- int i;
+ unsigned i;
T((T_CALLED("tigetnum(%s)"), str));
@@ -86,7 +86,7 @@ tigetnum(NCURSES_CONST char *str)
NCURSES_EXPORT(char *)
tigetstr(NCURSES_CONST char *str)
{
- int i;
+ unsigned i;
T((T_CALLED("tigetstr(%s)"), str));
diff --git a/lib/libcurses/tinfo/lib_tparm.c b/lib/libcurses/tinfo/lib_tparm.c
index 3cdd7b915fc..45c07f01e06 100644
--- a/lib/libcurses/tinfo/lib_tparm.c
+++ b/lib/libcurses/tinfo/lib_tparm.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_tparm.c,v 1.8 2003/03/17 19:16:59 millert Exp $ */
+/* $OpenBSD: lib_tparm.c,v 1.9 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey, 1996 on *
****************************************************************************/
/*
@@ -44,7 +45,7 @@
#include <term.h>
#include <tic.h>
-MODULE_ID("$From: lib_tparm.c,v 1.51 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: lib_tparm.c,v 1.9 2010/01/12 23:22:06 nicm Exp $")
/*
* char *
@@ -106,57 +107,37 @@ MODULE_ID("$From: lib_tparm.c,v 1.51 2000/12/10 02:55:08 tom Exp $")
* resulting in x mod y, not the reverse.
*/
-#define STACKSIZE 20
+NCURSES_EXPORT_VAR(int) _nc_tparm_err = 0;
-typedef struct {
- union {
- unsigned int num;
- char *str;
- } data;
- bool num_type;
-} stack_frame;
-
-static stack_frame stack[STACKSIZE];
-static int stack_ptr;
-
-#ifdef TRACE
-static const char *tname;
-#endif /* TRACE */
-
-static char *out_buff;
-static size_t out_size;
-static size_t out_used;
+#define TPS(var) _nc_prescreen.tparm_state.var
#if NO_LEAKS
NCURSES_EXPORT(void)
_nc_free_tparm(void)
{
- if (out_buff != 0) {
- FreeAndNull(out_buff);
- out_size = 0;
- out_used = 0;
+ if (TPS(out_buff) != 0) {
+ FreeAndNull(TPS(out_buff));
+ TPS(out_size) = 0;
+ TPS(out_used) = 0;
+ FreeAndNull(TPS(fmt_buff));
+ TPS(fmt_size) = 0;
}
}
#endif
-static void
-really_get_space(size_t need)
-{
- out_size = need * 2;
- out_buff = typeRealloc(char, out_size, out_buff);
- if (out_buff == 0)
- _nc_err_abort("Out of memory");
-}
-
-static inline void
+static NCURSES_INLINE void
get_space(size_t need)
{
- need += out_used;
- if (need > out_size)
- really_get_space(need);
+ need += TPS(out_used);
+ if (need > TPS(out_size)) {
+ TPS(out_size) = need * 2;
+ TPS(out_buff) = typeRealloc(char, TPS(out_size), TPS(out_buff));
+ if (TPS(out_buff) == 0)
+ _nc_err_abort(MSG_NO_MEMORY);
+ }
}
-static inline void
+static NCURSES_INLINE void
save_text(const char *fmt, const char *s, int len)
{
size_t s_len = strlen(s);
@@ -165,222 +146,223 @@ save_text(const char *fmt, const char *s, int len)
get_space(s_len + 1);
- (void) snprintf(out_buff + out_used, out_size - out_used, fmt, s);
- out_used += strlen(out_buff + out_used);
+ (void) snprintf(TPS(out_buff) + TPS(out_used), TPS(out_size) - TPS(out_used), fmt, s);
+ TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used));
}
-static inline void
+static NCURSES_INLINE void
save_number(const char *fmt, int number, int len)
{
if (len < 30)
len = 30; /* actually log10(MAX_INT)+1 */
- get_space(len + 1);
+ get_space((unsigned) len + 1);
- (void) snprintf(out_buff + out_used, out_size - out_used, fmt, number);
- out_used += strlen(out_buff + out_used);
+ (void) snprintf(TPS(out_buff) + TPS(out_used), TPS(out_size) - TPS(out_used), fmt, number);
+ TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used));
}
-static inline void
+static NCURSES_INLINE void
save_char(int c)
{
if (c == 0)
c = 0200;
get_space(1);
- out_buff[out_used++] = c;
+ TPS(out_buff)[TPS(out_used)++] = (char) c;
}
-static inline void
+static NCURSES_INLINE void
npush(int x)
{
- if (stack_ptr < STACKSIZE) {
- stack[stack_ptr].num_type = TRUE;
- stack[stack_ptr].data.num = x;
- stack_ptr++;
+ if (TPS(stack_ptr) < STACKSIZE) {
+ TPS(stack)[TPS(stack_ptr)].num_type = TRUE;
+ TPS(stack)[TPS(stack_ptr)].data.num = x;
+ TPS(stack_ptr)++;
+ } else {
+ DEBUG(2, ("npush: stack overflow: %s", _nc_visbuf(TPS(tparam_base))));
+ _nc_tparm_err++;
}
}
-static inline int
+static NCURSES_INLINE int
npop(void)
{
int result = 0;
- if (stack_ptr > 0) {
- stack_ptr--;
- if (stack[stack_ptr].num_type)
- result = stack[stack_ptr].data.num;
+ if (TPS(stack_ptr) > 0) {
+ TPS(stack_ptr)--;
+ if (TPS(stack)[TPS(stack_ptr)].num_type)
+ result = TPS(stack)[TPS(stack_ptr)].data.num;
+ } else {
+ DEBUG(2, ("npop: stack underflow: %s", _nc_visbuf(TPS(tparam_base))));
+ _nc_tparm_err++;
}
return result;
}
-static inline void
+static NCURSES_INLINE void
spush(char *x)
{
- if (stack_ptr < STACKSIZE) {
- stack[stack_ptr].num_type = FALSE;
- stack[stack_ptr].data.str = x;
- stack_ptr++;
+ if (TPS(stack_ptr) < STACKSIZE) {
+ TPS(stack)[TPS(stack_ptr)].num_type = FALSE;
+ TPS(stack)[TPS(stack_ptr)].data.str = x;
+ TPS(stack_ptr)++;
+ } else {
+ DEBUG(2, ("spush: stack overflow: %s", _nc_visbuf(TPS(tparam_base))));
+ _nc_tparm_err++;
}
}
-static inline char *
+static NCURSES_INLINE char *
spop(void)
{
static char dummy[] = ""; /* avoid const-cast */
char *result = dummy;
- if (stack_ptr > 0) {
- stack_ptr--;
- if (!stack[stack_ptr].num_type && stack[stack_ptr].data.str != 0)
- result = stack[stack_ptr].data.str;
+ if (TPS(stack_ptr) > 0) {
+ TPS(stack_ptr)--;
+ if (!TPS(stack)[TPS(stack_ptr)].num_type
+ && TPS(stack)[TPS(stack_ptr)].data.str != 0)
+ result = TPS(stack)[TPS(stack_ptr)].data.str;
+ } else {
+ DEBUG(2, ("spop: stack underflow: %s", _nc_visbuf(TPS(tparam_base))));
+ _nc_tparm_err++;
}
return result;
}
-static inline const char *
+static NCURSES_INLINE const char *
parse_format(const char *s, char *format, int *len)
{
- bool done = FALSE;
- bool allowminus = FALSE;
- bool dot = FALSE;
- bool err = FALSE;
- char *fmt = format;
- int prec = 0;
- int width = 0;
- int value = 0;
-
*len = 0;
- *format++ = '%';
- while (*s != '\0' && !done) {
- switch (*s) {
- case 'c': /* FALLTHRU */
- case 'd': /* FALLTHRU */
- case 'o': /* FALLTHRU */
- case 'x': /* FALLTHRU */
- case 'X': /* FALLTHRU */
- case 's':
- *format++ = *s;
- done = TRUE;
- break;
- case '.':
- *format++ = *s++;
- if (dot) {
- err = TRUE;
- } else {
- dot = TRUE;
- prec = value;
- }
- value = 0;
- break;
- case '#':
- *format++ = *s++;
- break;
- case ' ':
- *format++ = *s++;
- break;
- case ':':
- s++;
- allowminus = TRUE;
- break;
- case '-':
- if (allowminus) {
- *format++ = *s++;
- } else {
+ if (format != 0) {
+ bool done = FALSE;
+ bool allowminus = FALSE;
+ bool dot = FALSE;
+ bool err = FALSE;
+ char *fmt = format;
+ int my_width = 0;
+ int my_prec = 0;
+ int value = 0;
+
+ *len = 0;
+ *format++ = '%';
+ while (*s != '\0' && !done) {
+ switch (*s) {
+ case 'c': /* FALLTHRU */
+ case 'd': /* FALLTHRU */
+ case 'o': /* FALLTHRU */
+ case 'x': /* FALLTHRU */
+ case 'X': /* FALLTHRU */
+ case 's':
+ *format++ = *s;
done = TRUE;
- }
- break;
- default:
- if (isdigit(CharOf(*s))) {
- value = (value * 10) + (*s - '0');
- if (value > 10000)
+ break;
+ case '.':
+ *format++ = *s++;
+ if (dot) {
err = TRUE;
+ } else { /* value before '.' is the width */
+ dot = TRUE;
+ my_width = value;
+ }
+ value = 0;
+ break;
+ case '#':
*format++ = *s++;
- } else {
- done = TRUE;
+ break;
+ case ' ':
+ *format++ = *s++;
+ break;
+ case ':':
+ s++;
+ allowminus = TRUE;
+ break;
+ case '-':
+ if (allowminus) {
+ *format++ = *s++;
+ } else {
+ done = TRUE;
+ }
+ break;
+ default:
+ if (isdigit(UChar(*s))) {
+ value = (value * 10) + (*s - '0');
+ if (value > 10000)
+ err = TRUE;
+ *format++ = *s++;
+ } else {
+ done = TRUE;
+ }
}
}
- }
-
- /*
- * If we found an error, ignore (and remove) the flags.
- */
- if (err) {
- prec = width = value = 0;
- format = fmt;
- *format++ = '%';
- *format++ = *s;
- }
- if (dot)
- width = value;
- else
- prec = value;
+ /*
+ * If we found an error, ignore (and remove) the flags.
+ */
+ if (err) {
+ my_width = my_prec = value = 0;
+ format = fmt;
+ *format++ = '%';
+ *format++ = *s;
+ }
- *format = '\0';
- /* return maximum string length in print */
- *len = (prec > width) ? prec : width;
+ /*
+ * Any value after '.' is the precision. If we did not see '.', then
+ * the value is the width.
+ */
+ if (dot)
+ my_prec = value;
+ else
+ my_width = value;
+
+ *format = '\0';
+ /* return maximum string length in print */
+ *len = (my_width > my_prec) ? my_width : my_prec;
+ }
return s;
}
#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
-static inline char *
-tparam_internal(const char *string, va_list ap)
+/*
+ * Analyze the string to see how many parameters we need from the varargs list,
+ * and what their types are. We will only accept string parameters if they
+ * appear as a %l or %s format following an explicit parameter reference (e.g.,
+ * %p2%s). All other parameters are numbers.
+ *
+ * 'number' counts coarsely the number of pop's we see in the string, and
+ * 'popcount' shows the highest parameter number in the string. We would like
+ * to simply use the latter count, but if we are reading termcap strings, there
+ * may be cases that we cannot see the explicit parameter numbers.
+ */
+NCURSES_EXPORT(int)
+_nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
{
-#define NUM_VARS 26
- char *p_is_s[9];
- int param[9];
- int lastpop;
- int popcount;
- int number;
- int len;
- int level;
- int x, y;
- int i;
size_t len2;
- register const char *cp;
- static size_t len_fmt;
+ int i;
+ int lastpop = -1;
+ int len;
+ int number = 0;
+ const char *cp = string;
static char dummy[] = "";
- static char *format;
- static int dynamic_var[NUM_VARS];
- static int static_vars[NUM_VARS];
- out_used = 0;
- if (string == NULL)
- return NULL;
+ if (cp == 0)
+ return 0;
- if ((len2 = strlen(string)) > len_fmt) {
- len_fmt = len2 + len_fmt + 2;
- if ((format = typeRealloc(char, len_fmt, format)) == 0)
- return 0;
+ if ((len2 = strlen(cp)) > TPS(fmt_size)) {
+ TPS(fmt_size) = len2 + TPS(fmt_size) + 2;
+ TPS(fmt_buff) = typeRealloc(char, TPS(fmt_size), TPS(fmt_buff));
+ if (TPS(fmt_buff) == 0)
+ return 0;
}
- /*
- * Find the highest parameter-number referred to in the format string.
- * Use this value to limit the number of arguments copied from the
- * variable-length argument list.
- */
-
- number = 0;
- lastpop = -1;
- popcount = 0;
- memset(p_is_s, 0, sizeof(p_is_s));
+ memset(p_is_s, 0, sizeof(p_is_s[0]) * NUM_PARM);
+ *popcount = 0;
- /*
- * Analyze the string to see how many parameters we need from the varargs
- * list, and what their types are. We will only accept string parameters
- * if they appear as a %l or %s format following an explicit parameter
- * reference (e.g., %p2%s). All other parameters are numbers.
- *
- * 'number' counts coarsely the number of pop's we see in the string, and
- * 'popcount' shows the highest parameter number in the string. We would
- * like to simply use the latter count, but if we are reading termcap
- * strings, there may be cases that we cannot see the explicit parameter
- * numbers.
- */
- for (cp = string; (cp - string) < (int) len2;) {
+ while ((cp - string) < (int) len2) {
if (*cp == '%') {
cp++;
- cp = parse_format(cp, format, &len);
+ cp = parse_format(cp, TPS(fmt_buff), &len);
switch (*cp) {
default:
break;
@@ -390,7 +372,8 @@ tparam_internal(const char *string, va_list ap)
case 'x': /* FALLTHRU */
case 'X': /* FALLTHRU */
case 'c': /* FALLTHRU */
- number++;
+ if (lastpop <= 0)
+ number++;
lastpop = -1;
break;
@@ -403,15 +386,19 @@ tparam_internal(const char *string, va_list ap)
case 'p':
cp++;
- i = (*cp - '0');
- if (i >= 0 && i <= 9) {
+ i = (UChar(*cp) - '0');
+ if (i >= 0 && i <= NUM_PARM) {
lastpop = i;
- if (lastpop > popcount)
- popcount = lastpop;
+ if (lastpop > *popcount)
+ *popcount = lastpop;
}
break;
case 'P':
+ ++number;
+ ++cp;
+ break;
+
case 'g':
cp++;
break;
@@ -423,7 +410,7 @@ tparam_internal(const char *string, va_list ap)
case L_BRACE:
cp++;
- while (*cp >= '0' && *cp <= '9') {
+ while (isdigit(UChar(*cp))) {
cp++;
}
break;
@@ -441,16 +428,18 @@ tparam_internal(const char *string, va_list ap)
case '=':
case '<':
case '>':
+ lastpop = -1;
+ number += 2;
+ break;
+
case '!':
case '~':
lastpop = -1;
- number += 2;
+ ++number;
break;
case 'i':
- lastpop = -1;
- if (popcount < 2)
- popcount = 2;
+ /* will add 1 to first (usually two) parameters */
break;
}
}
@@ -458,18 +447,52 @@ tparam_internal(const char *string, va_list ap)
cp++;
}
- if (number > 9)
- number = 9;
+ if (number > NUM_PARM)
+ number = NUM_PARM;
+ return number;
+}
+
+static NCURSES_INLINE char *
+tparam_internal(const char *string, va_list ap)
+{
+ char *p_is_s[NUM_PARM];
+ TPARM_ARG param[NUM_PARM];
+ int popcount;
+ int number;
+ int len;
+ int level;
+ int x, y;
+ int i;
+ const char *cp = string;
+ size_t len2;
+
+ if (cp == NULL)
+ return NULL;
+
+ TPS(out_used) = 0;
+ len2 = strlen(cp);
+
+ /*
+ * Find the highest parameter-number referred to in the format string.
+ * Use this value to limit the number of arguments copied from the
+ * variable-length argument list.
+ */
+ number = _nc_tparm_analyze(cp, p_is_s, &popcount);
+ if (TPS(fmt_buff) == 0)
+ return NULL;
+
for (i = 0; i < max(popcount, number); i++) {
/*
* A few caps (such as plab_norm) have string-valued parms.
* We'll have to assume that the caller knows the difference, since
- * a char* and an int may not be the same size on the stack.
+ * a char* and an int may not be the same size on the stack. The
+ * normal prototype for this uses 9 long's, which is consistent with
+ * our va_arg() usage.
*/
if (p_is_s[i] != 0) {
p_is_s[i] = va_arg(ap, char *);
} else {
- param[i] = va_arg(ap, int);
+ param[i] = va_arg(ap, TPARM_ARG);
}
}
@@ -480,32 +503,37 @@ tparam_internal(const char *string, va_list ap)
* the expansion of (for example) \E[%d;%dH work correctly in termcap
* style, which means tparam() will expand termcap strings OK.
*/
- stack_ptr = 0;
+ TPS(stack_ptr) = 0;
if (popcount == 0) {
popcount = number;
- for (i = number - 1; i >= 0; i--)
- npush(param[i]);
+ for (i = number - 1; i >= 0; i--) {
+ if (p_is_s[i])
+ spush(p_is_s[i]);
+ else
+ npush(param[i]);
+ }
}
#ifdef TRACE
- if (_nc_tracing & TRACE_CALLS) {
+ if (USE_TRACEF(TRACE_CALLS)) {
for (i = 0; i < popcount; i++) {
if (p_is_s[i] != 0)
save_text(", %s", _nc_visbuf(p_is_s[i]), 0);
else
save_number(", %d", param[i], 0);
}
- _tracef(T_CALLED("%s(%s%s)"), tname, _nc_visbuf(string), out_buff);
- out_used = 0;
+ _tracef(T_CALLED("%s(%s%s)"), TPS(tname), _nc_visbuf(cp), TPS(out_buff));
+ TPS(out_used) = 0;
+ _nc_unlock_global(tracef);
}
#endif /* TRACE */
- while (*string) {
- if (*string != '%') {
- save_char(*string);
+ while ((cp - string) < (int) len2) {
+ if (*cp != '%') {
+ save_char(UChar(*cp));
} else {
- string++;
- string = parse_format(string, format, &len);
- switch (*string) {
+ TPS(tparam_base) = cp++;
+ cp = parse_format(cp, TPS(fmt_buff), &len);
+ switch (*cp) {
default:
break;
case '%':
@@ -516,22 +544,25 @@ tparam_internal(const char *string, va_list ap)
case 'o': /* FALLTHRU */
case 'x': /* FALLTHRU */
case 'X': /* FALLTHRU */
+ save_number(TPS(fmt_buff), npop(), len);
+ break;
+
case 'c': /* FALLTHRU */
- save_number(format, npop(), len);
+ save_char(npop());
break;
case 'l':
- save_number("%d", strlen(spop()), 0);
+ save_number("%d", (int) strlen(spop()), 0);
break;
case 's':
- save_text(format, spop(), len);
+ save_text(TPS(fmt_buff), spop(), len);
break;
case 'p':
- string++;
- i = (*string - '1');
- if (i >= 0 && i < 9) {
+ cp++;
+ i = (UChar(*cp) - '1');
+ if (i >= 0 && i < NUM_PARM) {
if (p_is_s[i])
spush(p_is_s[i]);
else
@@ -540,39 +571,39 @@ tparam_internal(const char *string, va_list ap)
break;
case 'P':
- string++;
- if (isUPPER(*string)) {
- i = (*string - 'A');
- static_vars[i] = npop();
- } else if (isLOWER(*string)) {
- i = (*string - 'a');
- dynamic_var[i] = npop();
+ cp++;
+ if (isUPPER(*cp)) {
+ i = (UChar(*cp) - 'A');
+ TPS(static_vars)[i] = npop();
+ } else if (isLOWER(*cp)) {
+ i = (UChar(*cp) - 'a');
+ TPS(dynamic_var)[i] = npop();
}
break;
case 'g':
- string++;
- if (isUPPER(*string)) {
- i = (*string - 'A');
- npush(static_vars[i]);
- } else if (isLOWER(*string)) {
- i = (*string - 'a');
- npush(dynamic_var[i]);
+ cp++;
+ if (isUPPER(*cp)) {
+ i = (UChar(*cp) - 'A');
+ npush(TPS(static_vars)[i]);
+ } else if (isLOWER(*cp)) {
+ i = (UChar(*cp) - 'a');
+ npush(TPS(dynamic_var)[i]);
}
break;
case S_QUOTE:
- string++;
- npush(*string);
- string++;
+ cp++;
+ npush(UChar(*cp));
+ cp++;
break;
case L_BRACE:
number = 0;
- string++;
- while (*string >= '0' && *string <= '9') {
- number = number * 10 + *string - '0';
- string++;
+ cp++;
+ while (isdigit(UChar(*cp))) {
+ number = (number * 10) + (UChar(*cp) - '0');
+ cp++;
}
npush(number);
break;
@@ -663,38 +694,38 @@ tparam_internal(const char *string, va_list ap)
x = npop();
if (!x) {
/* scan forward for %e or %; at level zero */
- string++;
+ cp++;
level = 0;
- while (*string) {
- if (*string == '%') {
- string++;
- if (*string == '?')
+ while (*cp) {
+ if (*cp == '%') {
+ cp++;
+ if (*cp == '?')
level++;
- else if (*string == ';') {
+ else if (*cp == ';') {
if (level > 0)
level--;
else
break;
- } else if (*string == 'e' && level == 0)
+ } else if (*cp == 'e' && level == 0)
break;
}
- if (*string)
- string++;
+ if (*cp)
+ cp++;
}
}
break;
case 'e':
/* scan forward for a %; at level zero */
- string++;
+ cp++;
level = 0;
- while (*string) {
- if (*string == '%') {
- string++;
- if (*string == '?')
+ while (*cp) {
+ if (*cp == '%') {
+ cp++;
+ if (*cp == '?')
level++;
- else if (*string == ';') {
+ else if (*cp == ';') {
if (level > 0)
level--;
else
@@ -702,42 +733,65 @@ tparam_internal(const char *string, va_list ap)
}
}
- if (*string)
- string++;
+ if (*cp)
+ cp++;
}
break;
case ';':
break;
- } /* endswitch (*string) */
- } /* endelse (*string == '%') */
+ } /* endswitch (*cp) */
+ } /* endelse (*cp == '%') */
- if (*string == '\0')
+ if (*cp == '\0')
break;
- string++;
- } /* endwhile (*string) */
+ cp++;
+ } /* endwhile (*cp) */
get_space(1);
- out_buff[out_used] = '\0';
+ TPS(out_buff)[TPS(out_used)] = '\0';
- T((T_RETURN("%s"), _nc_visbuf(out_buff)));
- return (out_buff);
+ T((T_RETURN("%s"), _nc_visbuf(TPS(out_buff))));
+ return (TPS(out_buff));
}
+#if NCURSES_TPARM_VARARGS
+#define tparm_varargs tparm
+#else
+#define tparm_proto tparm
+#endif
+
NCURSES_EXPORT(char *)
-tparm
-(NCURSES_CONST char *string,...)
+tparm_varargs(NCURSES_CONST char *string,...)
{
va_list ap;
char *result;
+ _nc_tparm_err = 0;
va_start(ap, string);
#ifdef TRACE
- tname = "tparm";
+ TPS(tname) = "tparm";
#endif /* TRACE */
result = tparam_internal(string, ap);
va_end(ap);
return result;
}
+
+#if !NCURSES_TPARM_VARARGS
+NCURSES_EXPORT(char *)
+tparm_proto(NCURSES_CONST char *string,
+ TPARM_ARG a1,
+ TPARM_ARG a2,
+ TPARM_ARG a3,
+ TPARM_ARG a4,
+ TPARM_ARG a5,
+ TPARM_ARG a6,
+ TPARM_ARG a7,
+ TPARM_ARG a8,
+ TPARM_ARG a9)
+{
+ return tparm_varargs(string, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+}
+#endif /* NCURSES_TPARM_VARARGS */
diff --git a/lib/libcurses/tinfo/lib_tputs.c b/lib/libcurses/tinfo/lib_tputs.c
index 634d0317114..c085ecfb77f 100644
--- a/lib/libcurses/tinfo/lib_tputs.c
+++ b/lib/libcurses/tinfo/lib_tputs.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_tputs.c,v 1.11 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: lib_tputs.c,v 1.12 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -47,16 +48,30 @@
#include <termcap.h> /* ospeed */
#include <tic.h>
-MODULE_ID("$From: lib_tputs.c,v 1.55 2000/12/10 02:55:08 tom Exp $");
+MODULE_ID("$Id: lib_tputs.c,v 1.12 2010/01/12 23:22:06 nicm Exp $")
-NCURSES_EXPORT_VAR(char)
-PC = 0; /* used by termcap library */
-NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed = 0; /* used by termcap library */
+NCURSES_EXPORT_VAR(char) PC = 0; /* used by termcap library */
+NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed = 0; /* used by termcap library */
-NCURSES_EXPORT_VAR(int)
-_nc_nulls_sent = 0; /* used by 'tack' program */
+NCURSES_EXPORT_VAR(int) _nc_nulls_sent = 0; /* used by 'tack' program */
- static int (*my_outch) (int c) = _nc_outch;
+#if NCURSES_NO_PADDING
+NCURSES_EXPORT(void)
+_nc_set_no_padding(SCREEN *sp)
+{
+ bool no_padding = (getenv("NCURSES_NO_PADDING") != 0);
+
+ if (sp)
+ sp->_no_padding = no_padding;
+ else
+ _nc_prescreen._no_padding = no_padding;
+
+ TR(TRACE_CHARPUT | TRACE_MOVE, ("padding will%s be used",
+ GetNoPadding(sp) ? " not" : ""));
+}
+#endif
+
+static int (*my_outch) (int c) = _nc_outch;
NCURSES_EXPORT(int)
delay_output(int ms)
@@ -69,7 +84,7 @@ delay_output(int ms)
} else {
register int nullcount;
- nullcount = (ms * _nc_baudrate(ospeed)) / 10000;
+ nullcount = (ms * _nc_baudrate(ospeed)) / (BAUDBYTE * 1000);
for (_nc_nulls_sent += nullcount; nullcount > 0; nullcount--)
my_outch(PC);
if (my_outch == _nc_outch)
@@ -88,9 +103,7 @@ _nc_flush(void)
NCURSES_EXPORT(int)
_nc_outch(int ch)
{
-#ifdef TRACE
- _nc_outchars++;
-#endif /* TRACE */
+ COUNT_OUTCHARS(1);
if (SP != 0
&& SP->_cleanup) {
@@ -106,72 +119,6 @@ _nc_outch(int ch)
return OK;
}
-#if USE_WIDEC_SUPPORT
-/*
- * Reference: The Unicode Standard 2.0
- *
- * No surrogates supported (we're storing only one 16-bit Unicode value per
- * cell).
- */
-NCURSES_EXPORT(int)
-_nc_utf8_outch(int ch)
-{
- static const unsigned byteMask = 0xBF;
- static const unsigned otherMark = 0x80;
- static const unsigned firstMark[] =
- {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
-
- int result[7], *ptr;
- int count = 0;
-
- if ((unsigned int) ch < 0x80)
- count = 1;
- else if ((unsigned int) ch < 0x800)
- count = 2;
- else if ((unsigned int) ch < 0x10000)
- count = 3;
- else if ((unsigned int) ch < 0x200000)
- count = 4;
- else if ((unsigned int) ch < 0x4000000)
- count = 5;
- else if ((unsigned int) ch <= 0x7FFFFFFF)
- count = 6;
- else {
- count = 3;
- ch = 0xFFFD;
- }
- ptr = result + count;
- switch (count) {
- case 6:
- *--ptr = (ch | otherMark) & byteMask;
- ch >>= 6;
- /* FALLTHRU */
- case 5:
- *--ptr = (ch | otherMark) & byteMask;
- ch >>= 6;
- /* FALLTHRU */
- case 4:
- *--ptr = (ch | otherMark) & byteMask;
- ch >>= 6;
- /* FALLTHRU */
- case 3:
- *--ptr = (ch | otherMark) & byteMask;
- ch >>= 6;
- /* FALLTHRU */
- case 2:
- *--ptr = (ch | otherMark) & byteMask;
- ch >>= 6;
- /* FALLTHRU */
- case 1:
- *--ptr = (ch | firstMark[count]);
- break;
- }
- while (count--)
- _nc_outch(*ptr++);
- return OK;
-}
-#endif
-
NCURSES_EXPORT(int)
putp(const char *string)
{
@@ -179,8 +126,7 @@ putp(const char *string)
}
NCURSES_EXPORT(int)
-tputs
-(const char *string, int affcnt, int (*outc) (int))
+tputs(const char *string, int affcnt, int (*outc) (int))
{
bool always_delay;
bool normal_delay;
@@ -192,7 +138,7 @@ tputs
#ifdef TRACE
char addrbuf[32];
- if (_nc_tracing & TRACE_TPUTS) {
+ if (USE_TRACEF(TRACE_TPUTS)) {
if (outc == _nc_outch)
(void) strlcpy(addrbuf, "_nc_outch", sizeof(addrbuf));
else
@@ -203,7 +149,8 @@ tputs
} else {
_tracef("tputs(%s, %d, %s) called", _nc_visbuf(string), affcnt, addrbuf);
}
- _nc_tputs_trace = (char *) NULL;
+ TPUTS_TRACE(NULL);
+ _nc_unlock_global(tracef);
}
#endif /* TRACE */
@@ -219,7 +166,7 @@ tputs
!xon_xoff
&& padding_baud_rate
#if NCURSES_NO_PADDING
- && (SP == 0 || !(SP->_no_padding))
+ && !GetNoPadding(SP)
#endif
&& (_nc_baudrate(ospeed) >= padding_baud_rate);
}
@@ -230,19 +177,19 @@ tputs
* (like nethack) actually do the likes of tputs("50") to get delays.
*/
trailpad = 0;
- if (isdigit(*string)) {
- while (isdigit(*string)) {
+ if (isdigit(UChar(*string))) {
+ while (isdigit(UChar(*string))) {
trailpad = trailpad * 10 + (*string - '0');
string++;
}
trailpad *= 10;
if (*string == '.') {
string++;
- if (isdigit(*string)) {
+ if (isdigit(UChar(*string))) {
trailpad += (*string - '0');
string++;
}
- while (isdigit(*string))
+ while (isdigit(UChar(*string)))
string++;
}
@@ -267,7 +214,7 @@ tputs
bool mandatory;
string++;
- if ((!isdigit(CharOf(*string)) && *string != '.')
+ if ((!isdigit(UChar(*string)) && *string != '.')
|| !strchr(string, '>')) {
(*outc) ('$');
(*outc) ('<');
@@ -275,18 +222,18 @@ tputs
}
number = 0;
- while (isdigit(CharOf(*string))) {
+ while (isdigit(UChar(*string))) {
number = number * 10 + (*string - '0');
string++;
}
number *= 10;
if (*string == '.') {
string++;
- if (isdigit(CharOf(*string))) {
+ if (isdigit(UChar(*string))) {
number += (*string - '0');
string++;
}
- while (isdigit(CharOf(*string)))
+ while (isdigit(UChar(*string)))
string++;
}
diff --git a/lib/libcurses/tinfo/lib_ttyflags.c b/lib/libcurses/tinfo/lib_ttyflags.c
index 615e0092564..ec604dcaa53 100644
--- a/lib/libcurses/tinfo/lib_ttyflags.c
+++ b/lib/libcurses/tinfo/lib_ttyflags.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: lib_ttyflags.c,v 1.4 2001/01/22 18:01:54 millert Exp $ */
+/* $OpenBSD: lib_ttyflags.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -40,79 +40,114 @@
#include <curses.priv.h>
#include <term.h> /* cur_term */
-MODULE_ID("$From: lib_ttyflags.c,v 1.5 2000/12/10 02:55:08 tom Exp $")
-
-#undef tabs
-
-#ifdef TAB3
-# define tabs TAB3
-#else
-# ifdef XTABS
-# define tabs XTABS
-# else
-# ifdef OXTABS
-# define tabs OXTABS
-# else
-# define tabs 0
-# endif
-# endif
-#endif
+MODULE_ID("$Id: lib_ttyflags.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
NCURSES_EXPORT(int)
_nc_get_tty_mode(TTY * buf)
{
- if (cur_term == 0
- || GET_TTY(cur_term->Filedes, buf) != 0)
- return (ERR);
- TR(TRACE_BITS, ("_nc_get_tty_mode: %s", _nc_tracebits()));
- return (OK);
+ int result = OK;
+
+ if (buf == 0) {
+ result = ERR;
+ } else {
+ if (cur_term == 0) {
+ result = ERR;
+ } else {
+ for (;;) {
+ if (GET_TTY(cur_term->Filedes, buf) != 0) {
+ if (errno == EINTR)
+ continue;
+ result = ERR;
+ }
+ break;
+ }
+ }
+
+ if (result == ERR)
+ memset(buf, 0, sizeof(*buf));
+
+ TR(TRACE_BITS, ("_nc_get_tty_mode(%d): %s",
+ cur_term ? cur_term->Filedes : -1,
+ _nc_trace_ttymode(buf)));
+ }
+ return (result);
}
NCURSES_EXPORT(int)
_nc_set_tty_mode(TTY * buf)
{
- if (cur_term == 0
- || SET_TTY(cur_term->Filedes, buf) != 0)
- return (ERR);
- TR(TRACE_BITS, ("_nc_set_tty_mode: %s", _nc_tracebits()));
- return (OK);
+ int result = OK;
+
+ if (buf == 0) {
+ result = ERR;
+ } else {
+ if (cur_term == 0) {
+ result = ERR;
+ } else {
+ for (;;) {
+ if (SET_TTY(cur_term->Filedes, buf) != 0) {
+ if (errno == EINTR)
+ continue;
+ if ((errno == ENOTTY) && (SP != 0))
+ SP->_notty = TRUE;
+ result = ERR;
+ }
+ break;
+ }
+ }
+ TR(TRACE_BITS, ("_nc_set_tty_mode(%d): %s",
+ cur_term ? cur_term->Filedes : -1,
+ _nc_trace_ttymode(buf)));
+ }
+ return (result);
}
NCURSES_EXPORT(int)
def_shell_mode(void)
{
- T((T_CALLED("def_shell_mode()")));
+ int rc = ERR;
- /*
- * Turn off the XTABS bit in the tty structure if it was on. If XTABS
- * was on, remove the tab and backtab capabilities.
- */
+ T((T_CALLED("def_shell_mode()")));
- if (_nc_get_tty_mode(&cur_term->Ottyb) != OK)
- returnCode(ERR);
+ if (cur_term != 0) {
+ /*
+ * If XTABS was on, remove the tab and backtab capabilities.
+ */
+ if (_nc_get_tty_mode(&cur_term->Ottyb) == OK) {
#ifdef TERMIOS
- if (cur_term->Ottyb.c_oflag & tabs)
- tab = back_tab = NULL;
+ if (cur_term->Ottyb.c_oflag & OFLAGS_TABS)
+ tab = back_tab = NULL;
#else
- if (cur_term->Ottyb.sg_flags & XTABS)
- tab = back_tab = NULL;
+ if (cur_term->Ottyb.sg_flags & XTABS)
+ tab = back_tab = NULL;
#endif
- returnCode(OK);
+ rc = OK;
+ }
+ }
+ returnCode(rc);
}
NCURSES_EXPORT(int)
def_prog_mode(void)
{
+ int rc = ERR;
+
T((T_CALLED("def_prog_mode()")));
- if (_nc_get_tty_mode(&cur_term->Nttyb) != OK)
- returnCode(ERR);
+ if (cur_term != 0) {
+ /*
+ * Turn off the XTABS bit in the tty structure if it was on.
+ */
+ if (_nc_get_tty_mode(&cur_term->Nttyb) == OK) {
#ifdef TERMIOS
- cur_term->Nttyb.c_oflag &= ~tabs;
+ cur_term->Nttyb.c_oflag &= ~OFLAGS_TABS;
#else
- cur_term->Nttyb.sg_flags &= ~XTABS;
+ cur_term->Nttyb.sg_flags &= ~XTABS;
#endif
- returnCode(OK);
+ rc = OK;
+ }
+ }
+ returnCode(rc);
}
NCURSES_EXPORT(int)
@@ -121,13 +156,14 @@ reset_prog_mode(void)
T((T_CALLED("reset_prog_mode()")));
if (cur_term != 0) {
- _nc_set_tty_mode(&cur_term->Nttyb);
- if (SP) {
- if (stdscr && stdscr->_use_keypad)
- _nc_keypad(TRUE);
- NC_BUFFERED(TRUE);
+ if (_nc_set_tty_mode(&cur_term->Nttyb) == OK) {
+ if (SP) {
+ if (SP->_keypad_on)
+ _nc_keypad(SP, TRUE);
+ NC_BUFFERED(TRUE);
+ }
+ returnCode(OK);
}
- returnCode(OK);
}
returnCode(ERR);
}
@@ -139,7 +175,7 @@ reset_shell_mode(void)
if (cur_term != 0) {
if (SP) {
- _nc_keypad(FALSE);
+ _nc_keypad(SP, FALSE);
_nc_flush();
NC_BUFFERED(FALSE);
}
@@ -148,19 +184,33 @@ reset_shell_mode(void)
returnCode(ERR);
}
+static TTY *
+saved_tty(void)
+{
+ TTY *result = 0;
+
+ if (SP != 0) {
+ result = &(SP->_saved_tty);
+ } else {
+ if (_nc_prescreen.saved_tty == 0) {
+ _nc_prescreen.saved_tty = typeCalloc(TTY, 1);
+ }
+ result = _nc_prescreen.saved_tty;
+ }
+ return result;
+}
+
/*
** savetty() and resetty()
**
*/
-static TTY buf;
-
NCURSES_EXPORT(int)
savetty(void)
{
T((T_CALLED("savetty()")));
- returnCode(_nc_get_tty_mode(&buf));
+ returnCode(_nc_get_tty_mode(saved_tty()));
}
NCURSES_EXPORT(int)
@@ -168,5 +218,5 @@ resetty(void)
{
T((T_CALLED("resetty()")));
- returnCode(_nc_set_tty_mode(&buf));
+ returnCode(_nc_set_tty_mode(saved_tty()));
}
diff --git a/lib/libcurses/tinfo/make_keys.c b/lib/libcurses/tinfo/make_keys.c
index 0b6697d0319..caec31c9ffc 100644
--- a/lib/libcurses/tinfo/make_keys.c
+++ b/lib/libcurses/tinfo/make_keys.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: make_keys.c,v 1.8 2006/10/10 21:38:16 cloder Exp $ */
+/* $OpenBSD: make_keys.c,v 1.9 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -29,7 +29,7 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1997 *
+ * Author: Thomas E. Dickey 1997-on *
****************************************************************************/
/*
@@ -37,9 +37,11 @@
* making the output show the indices into the TERMTYPE Strings array. Doing
* it that way lets us cut down on the size of the init_keytry() function.
*/
+
+#define USE_TERMLIB 1
#include <curses.priv.h>
-MODULE_ID("$From: make_keys.c,v 1.10 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: make_keys.c,v 1.9 2010/01/12 23:22:06 nicm Exp $")
#include <names.c>
@@ -68,17 +70,23 @@ lookup(const char *name)
}
static void
-make_keys(FILE * ifp, FILE * ofp)
+make_keys(FILE *ifp, FILE *ofp)
{
char buffer[BUFSIZ];
- char from[BUFSIZ];
- char to[BUFSIZ];
+ char from[256];
+ char to[256];
int maxlen = 16;
+ int scanned;
while (fgets(buffer, sizeof(buffer), ifp) != NULL) {
if (*buffer == '#')
continue;
- if (sscanf(buffer, "%s %s", to, from) == 2) {
+
+ to[sizeof(to) - 1] = '\0';
+ from[sizeof(from) - 1] = '\0';
+
+ scanned = sscanf(buffer, "%255s %255s", to, from);
+ if (scanned == 2) {
int code = lookup(from);
if (code == UNKNOWN)
continue;
@@ -94,7 +102,7 @@ make_keys(FILE * ifp, FILE * ofp)
}
static void
-write_list(FILE * ofp, const char **list)
+write_list(FILE *ofp, const char **list)
{
while (*list != 0)
fprintf(ofp, "%s\n", *list++);
@@ -113,7 +121,7 @@ main(int argc, char *argv[])
"#if BROKEN_LINKER",
"static",
"#endif",
- "struct tinfo_fkeys _nc_tinfo_fkeys[] = {",
+ "const struct tinfo_fkeys _nc_tinfo_fkeys[] = {",
0
};
static const char *suffix[] =
diff --git a/lib/libcurses/tinfo/name_match.c b/lib/libcurses/tinfo/name_match.c
index 6db7ac7057f..1162430ee2f 100644
--- a/lib/libcurses/tinfo/name_match.c
+++ b/lib/libcurses/tinfo/name_match.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: name_match.c,v 1.3 2001/01/22 18:01:55 millert Exp $ */
+/* $OpenBSD: name_match.c,v 1.4 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1999-2007,2008 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,35 +29,48 @@
****************************************************************************/
/****************************************************************************
- * Author: Thomas E. Dickey <dickey@clark.net> 1999 *
+ * Author: Thomas E. Dickey 1999-on *
****************************************************************************/
#include <curses.priv.h>
#include <term.h>
#include <tic.h>
-MODULE_ID("$From: name_match.c,v 1.10 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: name_match.c,v 1.4 2010/01/12 23:22:06 nicm Exp $")
/*
* _nc_first_name(char *names)
*
* Extract the primary name from a compiled entry.
*/
+#define FirstName _nc_globals.first_name
NCURSES_EXPORT(char *)
_nc_first_name(const char *const sp)
/* get the first name from the given name list */
{
- static char buf[MAX_NAME_SIZE + 1];
- register unsigned n;
+ unsigned n;
- for (n = 0; n < sizeof(buf) - 1; n++) {
- if ((buf[n] = sp[n]) == '\0'
- || (buf[n] == '|'))
- break;
+#if NO_LEAKS
+ if (sp == 0) {
+ if (FirstName != 0)
+ FreeAndNull(FirstName);
+ } else
+#endif
+ {
+ if (FirstName == 0)
+ FirstName = typeMalloc(char, MAX_NAME_SIZE + 1);
+
+ if (FirstName != 0) {
+ for (n = 0; n < MAX_NAME_SIZE; n++) {
+ if ((FirstName[n] = sp[n]) == '\0'
+ || (FirstName[n] == '|'))
+ break;
+ }
+ FirstName[n] = '\0';
+ }
}
- buf[n] = '\0';
- return (buf);
+ return (FirstName);
}
/*
@@ -67,8 +80,7 @@ _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)
+_nc_name_match(const char *const namelst, const char *const name, const char *const delim)
{
const char *s, *d, *t;
int code, found;
diff --git a/lib/libcurses/tinfo/parse_entry.c b/lib/libcurses/tinfo/parse_entry.c
index 4a42654d670..2270ad90c07 100644
--- a/lib/libcurses/tinfo/parse_entry.c
+++ b/lib/libcurses/tinfo/parse_entry.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: parse_entry.c,v 1.12 2003/03/17 19:16:59 millert Exp $ */
+/* $OpenBSD: parse_entry.c,v 1.13 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -42,14 +43,14 @@
* from the input stream.
*/
+#define __INTERNAL_CAPS_VISIBLE
#include <curses.priv.h>
#include <ctype.h>
#include <tic.h>
-#define __INTERNAL_CAPS_VISIBLE
#include <term_entry.h>
-MODULE_ID("$From: parse_entry.c,v 1.52 2001/01/13 22:44:29 tom Exp $")
+MODULE_ID("$Id: parse_entry.c,v 1.13 2010/01/12 23:22:06 nicm Exp $")
#ifdef LINT
static short const parametrized[] =
@@ -143,7 +144,7 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
case BOOLEAN:
tp->ext_Booleans += 1;
tp->num_Booleans += 1;
- tp->Booleans = typeRealloc(char, tp->num_Booleans, tp->Booleans);
+ tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
for (last = tp->num_Booleans - 1; last > tindex; last--)
tp->Booleans[last] = tp->Booleans[last - 1];
break;
@@ -197,13 +198,17 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
* push back token
*/
+#define BAD_TC_USAGE if (!bad_tc_usage) \
+ { bad_tc_usage = TRUE; \
+ _nc_warning("Legacy termcap allows only a trailing tc= clause"); }
+
NCURSES_EXPORT(int)
-_nc_parse_entry
-(struct entry *entryp, int literal, bool silent)
+_nc_parse_entry(struct entry *entryp, int literal, bool silent)
{
int token_type;
struct name_table_entry const *entry_ptr;
char *ptr, *base;
+ bool bad_tc_usage = FALSE;
token_type = _nc_get_token(silent);
@@ -219,15 +224,32 @@ _nc_parse_entry
entryp->startline = _nc_start_line;
DEBUG(2, ("Comment range is %ld to %ld", entryp->cstart, entryp->cend));
- /* junk the 2-character termcap name, if present */
+ /*
+ * Strip off the 2-character termcap name, if present. Originally termcap
+ * used that as an indexing aid. We can retain 2-character terminfo names,
+ * but note that they would be lost if we translate to/from termcap. This
+ * feature is supposedly obsolete since "newer" BSD implementations do not
+ * use it; however our reference for this feature is SunOS 4.x, which
+ * implemented it. Note that the resulting terminal type was never the
+ * 2-character name, but was instead the first alias after that.
+ */
ptr = _nc_curr_token.tk_name;
- if (ptr[2] == '|') {
- ptr = _nc_curr_token.tk_name + 3;
- _nc_curr_token.tk_name[2] = '\0';
+ if (_nc_syntax == SYN_TERMCAP
+#if NCURSES_XNAMES
+ && !_nc_user_definable
+#endif
+ ) {
+ if (ptr[2] == '|') {
+ ptr += 3;
+ _nc_curr_token.tk_name[2] = '\0';
+ }
}
entryp->tterm.str_table = entryp->tterm.term_names = _nc_save_str(ptr);
+ if (entryp->tterm.str_table == 0)
+ return (ERR);
+
DEBUG(1, ("Starting '%s'", ptr));
/*
@@ -245,7 +267,7 @@ _nc_parse_entry
(base == entryp->tterm.term_names)
? "primary name"
: "alias",
- ptr - base, base);
+ (int) (ptr - base), base);
}
}
@@ -254,15 +276,19 @@ _nc_parse_entry
for (token_type = _nc_get_token(silent);
token_type != EOF && token_type != NAMES;
token_type = _nc_get_token(silent)) {
- if (strcmp(_nc_curr_token.tk_name, "use") == 0
- || strcmp(_nc_curr_token.tk_name, "tc") == 0) {
+ 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) {
entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring);
entryp->uses[entryp->nuses].line = _nc_curr_line;
entryp->nuses++;
+ if (entryp->nuses > 1 && is_tc) {
+ BAD_TC_USAGE
+ }
} else {
/* normal token lookup */
entry_ptr = _nc_find_entry(_nc_curr_token.tk_name,
- _nc_syntax ? _nc_cap_hash_table : _nc_info_hash_table);
+ _nc_get_hash_table(_nc_syntax));
/*
* Our kluge to handle aliasing. The reason it's done
@@ -276,7 +302,10 @@ _nc_parse_entry
const struct alias *ap;
if (_nc_syntax == SYN_TERMCAP) {
- for (ap = _nc_capalias_table; ap->from; ap++)
+ if (entryp->nuses != 0) {
+ BAD_TC_USAGE
+ }
+ for (ap = _nc_get_alias_table(TRUE); ap->from; ap++)
if (strcmp(ap->from, _nc_curr_token.tk_name) == 0) {
if (ap->to == (char *) 0) {
_nc_warning("%s (%s termcap extension) ignored",
@@ -284,14 +313,15 @@ _nc_parse_entry
goto nexttok;
}
- entry_ptr = _nc_find_entry(ap->to, _nc_cap_hash_table);
+ entry_ptr = _nc_find_entry(ap->to,
+ _nc_get_hash_table(TRUE));
if (entry_ptr && !silent)
_nc_warning("%s (%s termcap extension) aliased to %s",
ap->from, ap->source, ap->to);
break;
}
} else { /* if (_nc_syntax == SYN_TERMINFO) */
- for (ap = _nc_infoalias_table; ap->from; ap++)
+ for (ap = _nc_get_alias_table(FALSE); ap->from; ap++)
if (strcmp(ap->from, _nc_curr_token.tk_name) == 0) {
if (ap->to == (char *) 0) {
_nc_warning("%s (%s terminfo extension) ignored",
@@ -299,7 +329,8 @@ _nc_parse_entry
goto nexttok;
}
- entry_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);
+ entry_ptr = _nc_find_entry(ap->to,
+ _nc_get_hash_table(FALSE));
if (entry_ptr && !silent)
_nc_warning("%s (%s terminfo extension) aliased to %s",
ap->from, ap->source, ap->to);
@@ -346,23 +377,28 @@ _nc_parse_entry
* type, this will do the job.
*/
- /* tell max_attributes from arrow_key_map */
- if (token_type == NUMBER && !strcmp("ma", _nc_curr_token.tk_name))
+ if (token_type == NUMBER
+ && !strcmp("ma", _nc_curr_token.tk_name)) {
+ /* tell max_attributes from arrow_key_map */
entry_ptr = _nc_find_type_entry("ma", NUMBER,
_nc_get_table(_nc_syntax
!= 0));
+ assert(entry_ptr != 0);
- /* map terminfo's string MT to MT */
- else if (token_type == STRING && !strcmp("MT", _nc_curr_token.tk_name))
+ } else if (token_type == STRING
+ && !strcmp("MT", _nc_curr_token.tk_name)) {
+ /* map terminfo's string MT to MT */
entry_ptr = _nc_find_type_entry("MT", STRING,
_nc_get_table(_nc_syntax
!= 0));
+ assert(entry_ptr != 0);
- /* treat strings without following "=" as empty strings */
- else if (token_type == BOOLEAN && entry_ptr->nte_type == STRING)
+ } else if (token_type == BOOLEAN
+ && entry_ptr->nte_type == STRING) {
+ /* treat strings without following "=" as empty strings */
token_type = STRING;
- /* we couldn't recover; skip this token */
- else {
+ } else {
+ /* we couldn't recover; skip this token */
if (!silent) {
const char *type_name;
switch (entry_ptr->nte_type) {
@@ -425,7 +461,7 @@ _nc_parse_entry
default:
if (!silent)
_nc_warning("unknown token type");
- _nc_panic_mode((_nc_syntax == SYN_TERMCAP) ? ':' : ',');
+ _nc_panic_mode((char) ((_nc_syntax == SYN_TERMCAP) ? ':' : ','));
continue;
}
} /* end else cur_token.name != "use" */
@@ -445,7 +481,7 @@ _nc_parse_entry
if (!literal) {
if (_nc_syntax == SYN_TERMCAP) {
bool has_base_entry = FALSE;
- int i;
+ unsigned i;
/*
* Don't insert defaults if this is a `+' entry meant only
@@ -484,7 +520,7 @@ _nc_capcmp(const char *s, const char *t)
for (;;) {
if (s[0] == '$' && s[1] == '<') {
for (s += 2;; s++)
- if (!(isdigit(CharOf(*s))
+ if (!(isdigit(UChar(*s))
|| *s == '.'
|| *s == '*'
|| *s == '/'
@@ -494,7 +530,7 @@ _nc_capcmp(const char *s, const char *t)
if (t[0] == '$' && t[1] == '<') {
for (t += 2;; t++)
- if (!(isdigit(CharOf(*t))
+ if (!(isdigit(UChar(*t))
|| *t == '.'
|| *t == '*'
|| *t == '/'
@@ -520,8 +556,8 @@ append_acs0(string_desc * dst, int code, int src)
{
if (src != 0) {
char temp[3];
- temp[0] = code;
- temp[1] = src;
+ temp[0] = (char) code;
+ temp[1] = (char) src;
temp[2] = 0;
_nc_safe_strcat(dst, temp);
}
@@ -596,7 +632,7 @@ static const char C_HT[] = "\t";
#define CUR tp->
static void
-postprocess_termcap(TERMTYPE * tp, bool has_base)
+postprocess_termcap(TERMTYPE *tp, bool has_base)
{
char buf[MAX_LINE * 2 + 2];
string_desc result;
@@ -619,7 +655,7 @@ postprocess_termcap(TERMTYPE * tp, bool has_base)
if (WANTED(carriage_return)) {
if (carriage_return_delay > 0) {
- snprintf(buf, sizeof(buf), "%s$<%d>", C_CR, carriage_return_delay);
+ snprintf(buf, sizeof(buf), "%s$<%d>", C_CR, carriage_return_delay);
carriage_return = _nc_save_str(buf);
} else
carriage_return = _nc_save_str(C_CR);
@@ -756,11 +792,12 @@ postprocess_termcap(TERMTYPE * tp, bool has_base)
base = cp + 1) {
size_t len = cp - base;
- for (ap = ko_xlate; ap->from; ap++)
+ for (ap = ko_xlate; ap->from; ap++) {
if (len == strlen(ap->from)
&& strncmp(ap->from, base, len) == 0)
break;
- if (!ap->to) {
+ }
+ if (!(ap->from && ap->to)) {
_nc_warning("unknown capability `%.*s' in ko string",
(int) len, base);
continue;
@@ -769,8 +806,8 @@ postprocess_termcap(TERMTYPE * tp, bool has_base)
/* now we know we found a match in ko_table, so... */
- from_ptr = _nc_find_entry(ap->from, _nc_cap_hash_table);
- to_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);
+ from_ptr = _nc_find_entry(ap->from, _nc_get_hash_table(TRUE));
+ to_ptr = _nc_find_entry(ap->to, _nc_get_hash_table(FALSE));
if (!from_ptr || !to_ptr) /* should never happen! */
_nc_err_abort("ko translation table is invalid, I give up");
@@ -871,13 +908,12 @@ postprocess_termcap(TERMTYPE * tp, bool has_base)
} else if (acs_chars == 0
&& enter_alt_charset_mode != 0
&& exit_alt_charset_mode != 0) {
- acs_chars =
- _nc_save_str("``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~");
+ acs_chars = _nc_save_str(VT_ACSC);
}
}
static void
-postprocess_terminfo(TERMTYPE * tp)
+postprocess_terminfo(TERMTYPE *tp)
{
/*
* TERMINFO-TO-TERMINFO MAPPINGS FOR SOURCE TRANSLATION
diff --git a/lib/libcurses/tinfo/read_bsd_terminfo.c b/lib/libcurses/tinfo/read_bsd_terminfo.c
index dae8298ec69..9c34da830f1 100644
--- a/lib/libcurses/tinfo/read_bsd_terminfo.c
+++ b/lib/libcurses/tinfo/read_bsd_terminfo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: read_bsd_terminfo.c,v 1.17 2009/10/28 23:22:45 schwarze Exp $ */
+/* $OpenBSD: read_bsd_terminfo.c,v 1.18 2010/01/12 23:22:06 nicm Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -245,13 +245,10 @@ _nc_lookup_bsd_terminfo_entry(tn, filename, tp)
goto done;
}
- /*
- * Save term entry and prevent _nc_free_entries() from freeing
- * up the string table (since we use it in tp).
- */
- *tp = _nc_head->tterm;
- _nc_head->tterm.str_table = NULL;
- _nc_free_entries(_nc_head);
+ /* Save term entry and free from _nc_head list. */
+ *tp = _nc_head->tterm;
+ _nc_free_entry(_nc_head, tp);
+ _nc_head = _nc_tail = NULL;
}
done:
diff --git a/lib/libcurses/tinfo/read_entry.c b/lib/libcurses/tinfo/read_entry.c
index 7bbf35a3a3a..f1b3179705d 100644
--- a/lib/libcurses/tinfo/read_entry.c
+++ b/lib/libcurses/tinfo/read_entry.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: read_entry.c,v 1.15 2008/01/29 13:02:31 krw Exp $ */
+/* $OpenBSD: read_entry.c,v 1.16 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,77 +31,24 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
* read_entry.c -- Routine for reading in a compiled terminfo file
- *
*/
#include <curses.priv.h>
+#include <hashed_db.h>
#include <tic.h>
#include <term_entry.h>
-MODULE_ID("$From: read_entry.c,v 1.72 2000/12/10 02:55:08 tom Exp $")
-
-#if !HAVE_TELL
-#define tell(fd) 0 /* lseek() is POSIX, but not tell() - odd... */
-#endif
-
-/*
- * int
- * _nc_read_file_entry(filename, ptr)
- *
- * Read the compiled terminfo entry in the given file into the
- * structure pointed to by ptr, allocating space for the string
- * table.
- */
-
-#undef BYTE
-#define BYTE(p,n) (unsigned char)((p)[n])
+MODULE_ID("$Id: read_entry.c,v 1.16 2010/01/12 23:22:06 nicm Exp $")
-#define IS_NEG1(p) ((BYTE(p,0) == 0377) && (BYTE(p,1) == 0377))
-#define IS_NEG2(p) ((BYTE(p,0) == 0376) && (BYTE(p,1) == 0377))
-#define LOW_MSB(p) (BYTE(p,0) + 256*BYTE(p,1))
-
-static bool have_tic_directory = FALSE;
-static bool keep_tic_directory = FALSE;
-
-/*
- * Record the "official" location of the terminfo directory, according to
- * the place where we're writing to, or the normal default, if not.
- */
-NCURSES_EXPORT(const char *)
-_nc_tic_dir(const char *path)
-{
- static const char *result = TERMINFO;
-
- if (!keep_tic_directory) {
- if (path != 0) {
- result = path;
- have_tic_directory = TRUE;
- } else if (!have_tic_directory && use_terminfo_vars()) {
- char *envp;
- if ((envp = getenv("TERMINFO")) != 0)
- return _nc_tic_dir(envp);
- }
- }
- return result;
-}
-
-/*
- * Special fix to prevent the terminfo directory from being moved after tic
- * has chdir'd to it. If we let it be changed, then if $TERMINFO has a
- * relative path, we'll lose track of the actual directory.
- */
-NCURSES_EXPORT(void)
-_nc_keep_tic_dir(const char *path)
-{
- _nc_tic_dir(path);
- keep_tic_directory = TRUE;
-}
+#define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts))
+#if USE_DATABASE
static void
convert_shorts(char *buf, short *Numbers, int count)
{
@@ -128,7 +75,7 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table)
Strings[i] = ABSENT_STRING;
} else if (IS_NEG2(buf + 2 * i)) {
Strings[i] = CANCELLED_STRING;
- } else if (LOW_MSB(buf + 2 * i) > size) {
+ } else if ((int) LOW_MSB(buf + 2 * i) > size) {
Strings[i] = ABSENT_STRING;
} else {
Strings[i] = (LOW_MSB(buf + 2 * i) + table);
@@ -147,31 +94,51 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table)
}
}
-#define read_shorts(fd, buf, count) (read(fd, buf, (count)*2) == (count)*2)
+static int
+fake_read(char *src, int *offset, int limit, char *dst, unsigned want)
+{
+ int have = (limit - *offset);
+
+ if (have > 0) {
+ if ((int) want > have)
+ want = have;
+ memcpy(dst, src + *offset, want);
+ *offset += want;
+ } else {
+ want = 0;
+ }
+ return (int) want;
+}
+
+#define Read(buf, count) fake_read(buffer, &offset, limit, buf, count)
+
+#define read_shorts(buf, count) \
+ (Read(buf, (unsigned) (count)*2) == (int) (count)*2)
#define even_boundary(value) \
- if ((value) % 2 != 0) read(fd, buf, 1)
+ if ((value) % 2 != 0) Read(buf, 1)
-static int
-read_termtype(int fd, TERMTYPE * ptr)
+NCURSES_EXPORT(int)
+_nc_read_termtype(TERMTYPE *ptr, char *buffer, int limit)
/* return 1 if read, 0 if not found or garbled */
{
+ int offset = 0;
int name_size, bool_count, num_count, str_count, str_size;
int i;
- size_t bsize;
- char buf[MAX_ENTRY_SIZE];
+ char buf[MAX_ENTRY_SIZE + 1];
+ char *string_table;
+ unsigned want, have;
- TR(TRACE_DATABASE, ("READ termtype header @%d", tell(fd)));
+ TR(TRACE_DATABASE, ("READ termtype header @%d", offset));
memset(ptr, 0, sizeof(*ptr));
/* grab the header */
- if (!read_shorts(fd, buf, 6)
- || LOW_MSB(buf) != MAGIC) {
- return (0);
+ if (!read_shorts(buf, 6)
+ || !IS_TIC_MAGIC(buf)) {
+ return (TGETENT_NO);
}
- _nc_free_termtype(ptr);
name_size = LOW_MSB(buf + 2);
bool_count = LOW_MSB(buf + 4);
num_count = LOW_MSB(buf + 6);
@@ -187,35 +154,41 @@ read_termtype(int fd, TERMTYPE * ptr)
|| num_count < 0
|| str_count < 0
|| str_size < 0) {
- return (0);
+ return (TGETENT_NO);
}
+ want = str_size + name_size + 1;
if (str_size) {
/* try to allocate space for the string table */
if (str_count * 2 >= (int) sizeof(buf)
- || (ptr->str_table = typeMalloc(char, (unsigned) str_size)) == 0) {
- return (0);
+ || (string_table = typeMalloc(char, want)) == 0) {
+ return (TGETENT_NO);
}
} else {
str_count = 0;
+ if ((string_table = typeMalloc(char, want)) == 0) {
+ return (TGETENT_NO);
+ }
}
- /* grab the name (a null-terminate string) */
- read(fd, buf, min(MAX_NAME_SIZE, (unsigned) name_size));
- buf[MAX_NAME_SIZE] = '\0';
- bsize = strlen(buf) + 1;
- ptr->term_names = typeCalloc(char, bsize);
- if (ptr->term_names == NULL) {
- return (0);
+ /* grab the name (a null-terminated string) */
+ want = min(MAX_NAME_SIZE, (unsigned) name_size);
+ ptr->str_table = string_table;
+ ptr->term_names = string_table;
+ if ((have = Read(ptr->term_names, want)) != want) {
+ memset(ptr->term_names + have, 0, want - have);
}
- (void) strlcpy(ptr->term_names, buf, bsize);
- if (name_size > MAX_NAME_SIZE)
- lseek(fd, (off_t) (name_size - MAX_NAME_SIZE), 1);
+ ptr->term_names[want] = '\0';
+ string_table += (want + 1);
+
+ if (have > MAX_NAME_SIZE)
+ offset = (have - MAX_NAME_SIZE);
/* grab the booleans */
- if ((ptr->Booleans = typeCalloc(char, max(BOOLCOUNT, bool_count))) == 0
- || read(fd, ptr->Booleans, (unsigned) bool_count) != bool_count) {
- return (0);
+ if ((ptr->Booleans = TYPE_CALLOC(NCURSES_SBOOL,
+ max(BOOLCOUNT, bool_count))) == 0
+ || Read(ptr->Booleans, (unsigned) bool_count) < bool_count) {
+ return (TGETENT_NO);
}
/*
@@ -227,24 +200,24 @@ read_termtype(int fd, TERMTYPE * ptr)
even_boundary(name_size + bool_count);
/* grab the numbers */
- if ((ptr->Numbers = typeCalloc(short, max(NUMCOUNT, num_count))) == 0
- || !read_shorts(fd, buf, num_count)) {
- return (0);
+ if ((ptr->Numbers = TYPE_CALLOC(short, max(NUMCOUNT, num_count))) == 0
+ || !read_shorts(buf, num_count)) {
+ return (TGETENT_NO);
}
convert_shorts(buf, ptr->Numbers, num_count);
- if ((ptr->Strings = typeCalloc(char *, max(STRCOUNT, str_count))) == 0)
- return (0);
+ if ((ptr->Strings = TYPE_CALLOC(char *, max(STRCOUNT, str_count))) == 0)
+ return (TGETENT_NO);
if (str_count) {
/* grab the string offsets */
- if (!read_shorts(fd, buf, str_count)) {
- return (0);
+ if (!read_shorts(buf, str_count)) {
+ return (TGETENT_NO);
}
/* finally, grab the string table itself */
- if (read(fd, ptr->str_table, (unsigned) str_size) != str_size)
- return (0);
- convert_strings(buf, ptr->Strings, str_count, str_size, ptr->str_table);
+ if (Read(string_table, (unsigned) str_size) != str_size)
+ return (TGETENT_NO);
+ convert_strings(buf, ptr->Strings, str_count, str_size, string_table);
}
#if NCURSES_XNAMES
@@ -256,17 +229,17 @@ read_termtype(int fd, TERMTYPE * ptr)
* Read extended entries, if any, after the normal end of terminfo data.
*/
even_boundary(str_size);
- TR(TRACE_DATABASE, ("READ extended_header @%d", tell(fd)));
- if (_nc_user_definable && read_shorts(fd, buf, 5)) {
+ TR(TRACE_DATABASE, ("READ extended_header @%d", offset));
+ if (_nc_user_definable && read_shorts(buf, 5)) {
int ext_bool_count = LOW_MSB(buf + 0);
int ext_num_count = LOW_MSB(buf + 2);
int ext_str_count = LOW_MSB(buf + 4);
int ext_str_size = LOW_MSB(buf + 6);
int ext_str_limit = LOW_MSB(buf + 8);
- int need = (ext_bool_count + ext_num_count + ext_str_count);
+ unsigned need = (ext_bool_count + ext_num_count + ext_str_count);
int base = 0;
- if (need >= (int) sizeof(buf)
+ if (need >= sizeof(buf)
|| ext_str_size >= (int) sizeof(buf)
|| ext_str_limit >= (int) sizeof(buf)
|| ext_bool_count < 0
@@ -274,13 +247,13 @@ read_termtype(int fd, TERMTYPE * ptr)
|| ext_str_count < 0
|| ext_str_size < 0
|| ext_str_limit < 0)
- return (0);
+ return (TGETENT_NO);
ptr->num_Booleans = BOOLCOUNT + ext_bool_count;
ptr->num_Numbers = NUMCOUNT + ext_num_count;
ptr->num_Strings = STRCOUNT + ext_str_count;
- ptr->Booleans = typeRealloc(char, ptr->num_Booleans, ptr->Booleans);
+ ptr->Booleans = typeRealloc(NCURSES_SBOOL, ptr->num_Booleans, ptr->Booleans);
ptr->Numbers = typeRealloc(short, ptr->num_Numbers, ptr->Numbers);
ptr->Strings = typeRealloc(char *, ptr->num_Strings, ptr->Strings);
@@ -289,36 +262,36 @@ read_termtype(int fd, TERMTYPE * ptr)
ext_str_size, ext_str_limit));
TR(TRACE_DATABASE, ("READ %d extended-booleans @%d",
- ext_bool_count, tell(fd)));
+ ext_bool_count, offset));
if ((ptr->ext_Booleans = ext_bool_count) != 0) {
- if (read(fd, ptr->Booleans + BOOLCOUNT, (unsigned)
+ if (Read(ptr->Booleans + BOOLCOUNT, (unsigned)
ext_bool_count) != ext_bool_count)
- return (0);
+ return (TGETENT_NO);
}
even_boundary(ext_bool_count);
TR(TRACE_DATABASE, ("READ %d extended-numbers @%d",
- ext_num_count, tell(fd)));
+ ext_num_count, offset));
if ((ptr->ext_Numbers = ext_num_count) != 0) {
- if (!read_shorts(fd, buf, ext_num_count))
- return (0);
+ if (!read_shorts(buf, ext_num_count))
+ return (TGETENT_NO);
TR(TRACE_DATABASE, ("Before converting extended-numbers"));
convert_shorts(buf, ptr->Numbers + NUMCOUNT, ext_num_count);
}
- TR(TRACE_DATABASE, ("READ extended-offsets @%d", tell(fd)));
+ TR(TRACE_DATABASE, ("READ extended-offsets @%d", offset));
if ((ext_str_count || need)
- && !read_shorts(fd, buf, ext_str_count + need))
- return (0);
+ && !read_shorts(buf, ext_str_count + need))
+ return (TGETENT_NO);
TR(TRACE_DATABASE, ("READ %d bytes of extended-strings @%d",
- ext_str_limit, tell(fd)));
+ ext_str_limit, offset));
if (ext_str_limit) {
if ((ptr->ext_str_table = typeMalloc(char, ext_str_limit)) == 0)
- return (0);
- if (read(fd, ptr->ext_str_table, ext_str_limit) != ext_str_limit)
- return (0);
+ return (TGETENT_NO);
+ if (Read(ptr->ext_str_table, (unsigned) ext_str_limit) != ext_str_limit)
+ return (TGETENT_NO);
TR(TRACE_DATABASE, ("first extended-string is %s", _nc_visbuf(ptr->ext_str_table)));
}
@@ -342,12 +315,16 @@ read_termtype(int fd, TERMTYPE * ptr)
}
if (need) {
- if ((ptr->ext_Names = typeCalloc(char *, need)) == 0)
- return (0);
+ if (ext_str_count >= (MAX_ENTRY_SIZE * 2))
+ return (TGETENT_NO);
+ if ((ptr->ext_Names = TYPE_CALLOC(char *, need)) == 0)
+ return (TGETENT_NO);
TR(TRACE_DATABASE,
("ext_NAMES starting @%d in extended_strings, first = %s",
base, _nc_visbuf(ptr->ext_str_table + base)));
- convert_strings(buf + (2 * ext_str_count), ptr->ext_Names, need,
+ convert_strings(buf + (2 * ext_str_count),
+ ptr->ext_Names,
+ (int) need,
ext_str_limit, ptr->ext_str_table + base);
}
@@ -374,15 +351,24 @@ read_termtype(int fd, TERMTYPE * ptr)
for (i = str_count; i < STRCOUNT; i++)
ptr->Strings[i] = ABSENT_STRING;
- return (1);
+ return (TGETENT_YES);
}
+/*
+ * int
+ * _nc_read_file_entry(filename, ptr)
+ *
+ * Read the compiled terminfo entry in the given file into the
+ * structure pointed to by ptr, allocating space for the string
+ * table.
+ */
NCURSES_EXPORT(int)
-_nc_read_file_entry
-(const char *const filename, TERMTYPE * ptr)
+_nc_read_file_entry(const char *const filename, TERMTYPE *ptr)
/* return 1 if read, 0 if not found or garbled */
{
int code, fd = -1;
+ int limit;
+ char buffer[MAX_ENTRY_SIZE + 1];
#ifdef __OpenBSD__
if (_nc_read_bsd_terminfo_file(filename, ptr) == 1)
@@ -392,73 +378,137 @@ _nc_read_file_entry
if (_nc_access(filename, R_OK) < 0
|| (fd = open(filename, O_RDONLY | O_BINARY)) < 0) {
T(("cannot open terminfo %s (errno=%d)", filename, errno));
- return (0);
- }
+ code = TGETENT_NO;
+ } else {
+ if ((limit = read(fd, buffer, sizeof(buffer))) > 0) {
- T(("read terminfo %s", filename));
- if ((code = read_termtype(fd, ptr)) == 0)
- _nc_free_termtype(ptr);
- close(fd);
+ T(("read terminfo %s", filename));
+ if ((code = _nc_read_termtype(ptr, buffer, limit)) == TGETENT_NO) {
+ _nc_free_termtype(ptr);
+ }
+ } else {
+ code = TGETENT_NO;
+ }
+ close(fd);
+ }
return (code);
}
/*
- * Build a terminfo pathname and try to read the data. Returns 1 on success,
- * 0 on failure.
+ * Build a terminfo pathname and try to read the data. Returns TGETENT_YES on
+ * success, TGETENT_NO on failure.
*/
static int
-_nc_read_tic_entry(char *const filename,
- const char *const dir, const char *ttn, TERMTYPE * const tp)
+_nc_read_tic_entry(char *filename,
+ unsigned limit,
+ const char *const path,
+ const char *name,
+ TERMTYPE *const tp)
{
-/* maximum safe length of terminfo root directory name */
-#define MAX_TPATH (PATH_MAX - MAX_ALIAS - 6)
+ int result = TGETENT_NO;
- if (strlen(dir) > MAX_TPATH)
- return 0;
- (void) snprintf(filename, MAX_TPATH + 1, "%s/%s", dir, ttn);
- return _nc_read_file_entry(filename, tp);
-}
+ /*
+ * If we are looking in a directory, assume the entry is a file under that,
+ * according to the normal rules.
+ *
+ * FIXME - add caseless-filename fixup.
+ */
+ unsigned need = 4 + strlen(path) + strlen(name);
+ if (need <= limit) {
+ (void) snprintf(filename, limit, "%s/" LEAF_FMT "/%s", path, *name, name);
+ if (_nc_is_dir_path(path))
+ result = _nc_read_file_entry(filename, tp);
+ }
-/*
- * Process the list of :-separated directories, looking for the terminal type.
- * We don't use strtok because it does not show us empty tokens.
- */
-static int
-_nc_read_terminfo_dirs(const char *dirs, char *const filename, const char *const
- ttn, TERMTYPE * const tp)
-{
- char *list, *a;
- const char *b;
- int code = 0;
-
- /* we'll modify the argument, so we must copy */
- if ((b = a = list = strdup(dirs)) == NULL)
- return (0);
-
- for (;;) {
- int c = *a;
- if (c == 0 || c == NCURSES_PATHSEP) {
- *a = 0;
- if ((b + 1) >= a)
- b = TERMINFO;
- if (_nc_read_tic_entry(filename, b, ttn, tp) == 1) {
- code = 1;
- break;
+#if USE_HASHED_DB
+ else {
+ static const char suffix[] = DBM_SUFFIX;
+ DB *capdbp;
+ unsigned lens = sizeof(suffix) - 1;
+ unsigned size = strlen(path);
+ unsigned need = lens + size;
+
+ if (need <= limit) {
+ if (size >= lens
+ && !strcmp(path + size - lens, suffix))
+ (void) strlcpy(filename, path, limit);
+ else
+ (void) snprintf(filename, limit, "%s%s", path, suffix);
+
+ /*
+ * It would be nice to optimize the dbopen/close activity, as
+ * done in the cgetent implementation for tc= clauses. However,
+ * since we support multiple database locations, we cannot do
+ * that.
+ */
+ if ((capdbp = _nc_db_open(filename, FALSE)) != 0) {
+ DBT key, data;
+ int reccnt = 0;
+ char *save = strdup(name);
+
+ memset(&key, 0, sizeof(key));
+ key.data = save;
+ key.size = strlen(save);
+
+ /*
+ * This lookup could return termcap data, which we do not want.
+ * We are looking for compiled (binary) terminfo data.
+ *
+ * cgetent uses a two-level lookup. On the first it uses the
+ * given name to return a record containing only the aliases
+ * for an entry. On the second (using that list of aliases as
+ * a key), it returns the content of the terminal description.
+ * We expect second lookup to return data beginning with the
+ * same set of aliases.
+ *
+ * For compiled terminfo, the list of aliases in the second
+ * case will be null-terminated. A termcap entry will not be,
+ * and will run on into the description. So we can easily
+ * distinguish between the two (source/binary) by checking the
+ * lengths.
+ */
+ while (_nc_db_get(capdbp, &key, &data) == 0) {
+ int used = data.size - 1;
+ char *have = (char *) data.data;
+
+ if (*have++ == 0) {
+ if (data.size > key.size
+ && IS_TIC_MAGIC(have)) {
+ result = _nc_read_termtype(tp, have, used);
+ if (result == TGETENT_NO) {
+ _nc_free_termtype(tp);
+ }
+ }
+ break;
+ }
+
+ /*
+ * Just in case we have a corrupt database, do not waste
+ * time with it.
+ */
+ if (++reccnt >= 3)
+ break;
+
+ /*
+ * Prepare for the second level.
+ */
+ key.data = have;
+ key.size = used;
+ }
+
+ _nc_db_close(capdbp);
+ free(save);
}
- b = a + 1;
- if (c == 0)
- break;
}
- a++;
}
-
- free(list);
- return (code);
+#endif
+ return result;
}
+#endif /* USE_DATABASE */
/*
- * _nc_read_entry(char *tn, char *filename, TERMTYPE *tp)
+ * _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
@@ -467,52 +517,43 @@ _nc_read_terminfo_dirs(const char *dirs, char *const filename, const char *const
*/
NCURSES_EXPORT(int)
-_nc_read_entry
-(const char *const tn, char *const filename, TERMTYPE * const tp)
+_nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp)
{
- char *envp;
- char ttn[MAX_ALIAS + 3];
+ int code = TGETENT_NO;
#ifdef __OpenBSD__
/* First check the BSD terminfo.db file */
- if (_nc_read_bsd_terminfo_entry(tn, filename, tp) == 1)
+ if (_nc_read_bsd_terminfo_entry(name, filename, tp) == 1)
return (1);
#endif /* __OpenBSD__ */
- /* truncate the terminal name to prevent dangerous buffer airline */
- (void) snprintf(ttn, sizeof(ttn), "%c/%.*s", *tn, MAX_ALIAS, tn);
-
- /* This is System V behavior, in conjunction with our requirements for
- * writing terminfo entries.
- */
- if (have_tic_directory
- && _nc_read_tic_entry(filename, _nc_tic_dir(0), ttn, tp) == 1)
- return 1;
-
- if (use_terminfo_vars()) {
- if ((envp = getenv("TERMINFO")) != 0
- && _nc_read_tic_entry(filename, _nc_tic_dir(envp), ttn, tp) == 1)
- return 1;
-
- /* this is an ncurses extension */
- if ((envp = _nc_home_terminfo()) != 0) {
- if (_nc_read_tic_entry(filename, envp, ttn, tp) == 1) {
- return (1);
+ snprintf(filename, PATH_MAX, "%s", name);
+ if (strlen(name) == 0
+ || strcmp(name, ".") == 0
+ || strcmp(name, "..") == 0
+ || _nc_pathlast(name) != 0
+ || strchr(name, NCURSES_PATHSEP) != 0) {
+ T(("illegal or missing entry name '%s'", name));
+ } else {
+#if USE_DATABASE
+ DBDIRS state = dbdTIC;
+ int offset = 0;
+ const char *path;
+
+ while ((path = _nc_next_db(&state, &offset)) != 0) {
+ code = _nc_read_tic_entry(filename, PATH_MAX, path, name, tp);
+ if (code == TGETENT_YES) {
+ _nc_last_db();
+ break;
}
}
-
- /* this is an ncurses extension */
- if ((envp = getenv("TERMINFO_DIRS")) != 0)
- return _nc_read_terminfo_dirs(envp, filename, ttn, tp);
- }
-
- /* Try the system directory. Note that the TERMINFO_DIRS value, if
- * defined by the configure script, begins with a ":", which will be
- * interpreted as TERMINFO.
- */
-#ifdef TERMINFO_DIRS
- return _nc_read_terminfo_dirs(TERMINFO_DIRS, filename, ttn, tp);
-#else
- return _nc_read_tic_entry(filename, TERMINFO, ttn, tp);
#endif
+#if USE_TERMCAP
+ if (code != TGETENT_YES) {
+ code = _nc_read_termcap_entry(name, tp);
+ snprintf(filename, PATH_MAX, "%s", _nc_get_source());
+ }
+#endif
+ }
+ return code;
}
diff --git a/lib/libcurses/tinfo/read_termcap.c b/lib/libcurses/tinfo/read_termcap.c
index 65dc97fd04a..9968879f235 100644
--- a/lib/libcurses/tinfo/read_termcap.c
+++ b/lib/libcurses/tinfo/read_termcap.c
@@ -1,5 +1,7 @@
+/* $OpenBSD: read_termcap.c,v 1.22 2010/01/12 23:22:06 nicm Exp $ */
+
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2005,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 *
@@ -29,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -52,25 +55,31 @@
#include <curses.priv.h>
#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <tic.h>
#include <term_entry.h>
-MODULE_ID("$From: read_termcap.c,v 1.55 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: read_termcap.c,v 1.22 2010/01/12 23:22:06 nicm Exp $")
#if !PURE_TERMINFO
-#ifdef __EMX__
-#define is_pathname(s) ((((s) != 0) && ((s)[0] == '/')) \
- || (((s)[0] != 0) && ((s)[1] == ':')))
-#else
-#define is_pathname(s) ((s) != 0 && (s)[0] == '/')
-#endif
-
#define TC_SUCCESS 0
-#define TC_UNRESOLVED -1
-#define TC_NOT_FOUND -2
-#define TC_SYS_ERR -3
-#define TC_REF_LOOP -4
+#define TC_NOT_FOUND -1
+#define TC_SYS_ERR -2
+#define TC_REF_LOOP -3
+#define TC_UNRESOLVED -4 /* this is not returned by BSD cgetent */
+
+static NCURSES_CONST char *
+get_termpath(void)
+{
+ NCURSES_CONST char *result;
+
+ if (!use_terminfo_vars() || (result = getenv("TERMPATH")) == 0)
+ result = TERMPATH;
+ T(("TERMPATH is %s", result));
+ return result;
+}
#if USE_GETCAP
@@ -119,13 +128,7 @@ static int _nc_nfcmp(const char *, char *);
#define BFRAG 1024
#define BSIZE 1024
-#define ESC ('[' & 037) /* ASCII ESC */
#define MAX_RECURSION 32 /* maximum getent recursion */
-#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */
-
-#define RECOK (char)0
-#define TCERR (char)1
-#define SHADOW (char)2
static size_t topreclen; /* toprec length */
static char *toprec; /* Additional record specified by cgetset() */
@@ -218,10 +221,10 @@ _nc_cgetcap(char *buf, const char *cap, int type)
* Returns:
*
* positive # on success (i.e., the index in db_array)
- * TC_UNRESOLVED if we had too many recurrences to resolve
* TC_NOT_FOUND if the requested record couldn't be found
* TC_SYS_ERR if a system error was encountered (e.g.,couldn't open a file)
* TC_REF_LOOP if a potential reference loop is detected
+ * TC_UNRESOLVED if we had too many recurrences to resolve
*/
static int
_nc_cgetent(char **buf, int *oline, char **db_array, const char *name)
@@ -284,7 +287,7 @@ _nc_getent(
errno = ENOMEM;
return (TC_SYS_ERR);
}
- (void) strlcpy(record, toprec, topreclen + BFRAG);
+ (void) strlcpy(record, toprec, topreclen + BFRAG);
rp = record + topreclen + 1;
r_end = rp + BFRAG;
current = in_array;
@@ -659,7 +662,11 @@ _nc_nfcmp(const char *nf, char *rec)
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgment:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -701,7 +708,7 @@ get_tc_token(char **srcp, int *endp)
if (*s == '\0') {
break;
} else if (*s++ == '\n') {
- while (isspace(*s))
+ while (isspace(UChar(*s)))
s++;
} else {
found = TRUE;
@@ -715,7 +722,7 @@ get_tc_token(char **srcp, int *endp)
break;
}
base = s;
- } else if (isgraph(ch)) {
+ } else if (isgraph(UChar(ch))) {
found = TRUE;
}
}
@@ -735,7 +742,7 @@ copy_tc_token(char *dst, const char *src, size_t len)
while ((ch = *src++) != '\0') {
if (ch == '\\' && *src == '\n') {
- while (isspace(*src))
+ while (isspace(UChar(*src)))
src++;
continue;
}
@@ -755,7 +762,6 @@ static int
_nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
{
static char *the_source;
-
register char *p;
register char *cp;
char *dummy = NULL;
@@ -765,7 +771,7 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
char pathbuf[PBUFSIZ]; /* holds raw path of filenames */
char *pathvec[PVECSIZ]; /* to point to names in pathbuf */
char **pvec; /* holds usable tail of path vector */
- char *termpath;
+ NCURSES_CONST char *termpath;
string_desc desc;
fname = pathvec;
@@ -785,23 +791,23 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
*/
_nc_str_init(&desc, pathbuf, sizeof(pathbuf));
if (cp == NULL) {
- _nc_safe_strcpy(&desc, "/usr/share/misc/termcap /etc/termcap");
- } else if (!is_pathname(cp)) { /* TERMCAP holds an entry */
- if ((termpath = getenv("TERMPATH")) != 0) {
+ _nc_safe_strcpy(&desc, get_termpath());
+ } else if (!_nc_is_abs_path(cp)) { /* TERMCAP holds an entry */
+ if ((termpath = get_termpath()) != 0) {
_nc_safe_strcat(&desc, termpath);
} else {
char temp[PBUFSIZ];
- size_t len;
temp[0] = 0;
if ((home = getenv("HOME")) != 0 && *home != '\0'
- && strchr(home, ' ') == 0) { /* setup path */
- len = snprintf(temp, sizeof(temp), "%s/.termcap", home);
- if (len < sizeof(temp)) {
- _nc_safe_strcat(&desc, temp);
- }
+ && strchr(home, ' ') == 0
+ && strlen(home) < sizeof(temp) - 10) { /* setup path */
+ snprintf(temp, sizeof(temp), "%s/", home); /* $HOME first */
}
- _nc_safe_strcat(&desc, " /usr/share/misc/termcap");
- _nc_safe_strcat(&desc, " /etc/termcap");
+ /* if no $HOME look in current directory */
+ strlcat(temp, ".termcap", sizeof temp);
+ _nc_safe_strcat(&desc, temp);
+ _nc_safe_strcat(&desc, " ");
+ _nc_safe_strcat(&desc, get_termpath());
}
} else { /* user-defined name in TERMCAP */
_nc_safe_strcat(&desc, cp); /* still can be tokenized */
@@ -824,7 +830,7 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
}
}
*fname = 0; /* mark end of vector */
- if (is_pathname(cp)) {
+ if (_nc_is_abs_path(cp)) {
if (_nc_cgetset(cp) < 0) {
return (TC_SYS_ERR);
}
@@ -877,8 +883,21 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
* cgetent, then it is the actual filename).
*/
if (i >= 0) {
+#if HAVE_BSD_CGETENT
+ char temp[PATH_MAX];
+
+ _nc_str_init(&desc, temp, sizeof(temp));
+ _nc_safe_strcpy(&desc, pathvec[i]);
+ _nc_safe_strcat(&desc, ".db");
+ if (_nc_access(temp, R_OK) == 0) {
+ _nc_safe_strcpy(&desc, pathvec[i]);
+ }
+ if ((the_source = strdup(temp)) != 0)
+ *sourcename = the_source;
+#else
if ((the_source = strdup(pathvec[i])) != 0)
*sourcename = the_source;
+#endif
}
return (i);
@@ -896,20 +915,26 @@ _nc_tgetent(char *bp, char **sourcename, int *lineno, const char *name)
static int
add_tc(char *termpaths[], char *path, int count)
{
+ char *save = strchr(path, NCURSES_PATHSEP);
+ if (save != 0)
+ *save = '\0';
if (count < MAXPATHS
- && _nc_access(path, R_OK) == 0)
+ && _nc_access(path, R_OK) == 0) {
termpaths[count++] = path;
+ T(("Adding termpath %s", path));
+ }
termpaths[count] = 0;
+ if (save != 0)
+ *save = NCURSES_PATHSEP;
return count;
}
#define ADD_TC(path, count) filecount = add_tc(termpaths, path, 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, TERMTYPE *const tp)
{
- int found = FALSE;
+ int found = TGETENT_NO;
ENTRY *ep;
#if USE_GETCAP_CACHE
char cwd_buf[PATH_MAX];
@@ -920,20 +945,31 @@ _nc_read_termcap_entry
static char *source;
static int lineno;
+ T(("read termcap entry for %s", tn));
+
+ if (strlen(tn) == 0
+ || strcmp(tn, ".") == 0
+ || strcmp(tn, "..") == 0
+ || _nc_pathlast(tn) != 0) {
+ T(("illegal or missing entry name '%s'", tn));
+ return TGETENT_NO;
+ }
+
if (use_terminfo_vars() && (p = getenv("TERMCAP")) != 0
- && !is_pathname(p) && _nc_name_match(p, tn, "|:")) {
+ && !_nc_is_abs_path(p) && _nc_name_match(p, tn, "|:")) {
/* TERMCAP holds a termcap entry */
- strlcpy(tc, p, sizeof(tc));
+ strncpy(tc, p, sizeof(tc) - 1);
+ tc[sizeof(tc) - 1] = '\0';
_nc_set_source("TERMCAP");
} else {
/* we're using getcap(3) */
if ((status = _nc_tgetent(tc, &source, &lineno, tn)) < 0)
- return (status == -1 ? 0 : -1);
+ return (status == TC_NOT_FOUND ? TGETENT_NO : TGETENT_ERR);
_nc_curr_line = lineno;
_nc_set_source(source);
}
- _nc_read_entry_source((FILE *) 0, tc, FALSE, TRUE, NULLHOOK);
+ _nc_read_entry_source((FILE *) 0, tc, FALSE, FALSE, NULLHOOK);
#else
/*
* Here is what the 4.4BSD termcap(3) page prescribes:
@@ -964,65 +1000,98 @@ _nc_read_termcap_entry
FILE *fp;
char *tc, *termpaths[MAXPATHS];
int filecount = 0;
+ int j, k;
bool use_buffer = FALSE;
+ bool normal = TRUE;
char tc_buf[1024];
char pathbuf[PATH_MAX];
+ char *copied = 0;
+ char *cp;
+ struct stat test_stat[MAXPATHS];
termpaths[filecount] = 0;
if (use_terminfo_vars() && (tc = getenv("TERMCAP")) != 0) {
- if (is_pathname(tc)) { /* interpret as a filename */
+ if (_nc_is_abs_path(tc)) { /* interpret as a filename */
ADD_TC(tc, 0);
+ normal = FALSE;
} else if (_nc_name_match(tc, tn, "|:")) { /* treat as a capability file */
use_buffer = TRUE;
- (void) snprintf(tc_buf, sizeof(tc_buf), "%.*s\n",
- (int) sizeof(tc_buf) - 2, tc);
- } else if ((tc = getenv("TERMPATH")) != 0) {
- char *cp;
-
- for (cp = tc; *cp; cp++) {
- if (*cp == NCURSES_PATHSEP)
- *cp = '\0';
- else if (cp == tc || cp[-1] == '\0') {
- ADD_TC(cp, filecount);
- }
- }
+ (void) snprintf(tc_buf, sizeof(tc_buf), "%.*s\n", (int) sizeof(tc_buf) - 2, tc);
+ normal = FALSE;
}
- } else { /* normal case */
- char envhome[PATH_MAX], *h;
+ }
- filecount = 0;
+ if (normal) { /* normal case */
+ char envhome[PATH_MAX], *h;
- /*
- * Probably /etc/termcap is a symlink to /usr/share/misc/termcap.
- * Avoid reading the same file twice.
- */
- if (_nc_access("/etc/termcap", F_OK) == 0)
- ADD_TC("/etc/termcap", filecount);
- else
- ADD_TC("/usr/share/misc/termcap", filecount);
+ copied = strdup(get_termpath());
+ for (cp = copied; *cp; cp++) {
+ if (*cp == NCURSES_PATHSEP)
+ *cp = '\0';
+ else if (cp == copied || cp[-1] == '\0') {
+ ADD_TC(cp, filecount);
+ }
+ }
#define PRIVATE_CAP "%s/.termcap"
if (use_terminfo_vars() && (h = getenv("HOME")) != NULL && *h != '\0'
&& (strlen(h) + sizeof(PRIVATE_CAP)) < PATH_MAX) {
/* user's .termcap, if any, should override it */
- (void) strlcpy(envhome, h, sizeof(envhome));
+ (void) strlcpy(envhome, h, sizeof(envhome);
(void) snprintf(pathbuf, sizeof(pathbuf), PRIVATE_CAP, envhome);
ADD_TC(pathbuf, filecount);
}
}
+ /*
+ * Probably /etc/termcap is a symlink to /usr/share/misc/termcap.
+ * Avoid reading the same file twice.
+ */
+#if HAVE_LINK
+ for (j = 0; j < filecount; j++) {
+ bool omit = FALSE;
+ if (stat(termpaths[j], &test_stat[j]) != 0
+ || (test_stat[j].st_mode & S_IFMT) != S_IFREG) {
+ omit = TRUE;
+ } else {
+ for (k = 0; k < j; k++) {
+ if (test_stat[k].st_dev == test_stat[j].st_dev
+ && test_stat[k].st_ino == test_stat[j].st_ino) {
+ omit = TRUE;
+ break;
+ }
+ }
+ }
+ if (omit) {
+ T(("Path %s is a duplicate", termpaths[j]));
+ for (k = j + 1; k < filecount; k++) {
+ termpaths[k - 1] = termpaths[k];
+ test_stat[k - 1] = test_stat[k];
+ }
+ --filecount;
+ --j;
+ }
+ }
+#endif
+
/* parse the sources */
if (use_buffer) {
_nc_set_source("TERMCAP");
- _nc_read_entry_source((FILE *) 0, tc_buf, FALSE, TRUE, NULLHOOK);
+
+ /*
+ * We don't suppress warning messages here. The presumption is
+ * that since it's just a single entry, they won't be a pain.
+ */
+ _nc_read_entry_source((FILE *) 0, tc_buf, FALSE, FALSE, NULLHOOK);
} else {
int i;
for (i = 0; i < filecount; i++) {
T(("Looking for %s in %s", tn, termpaths[i]));
- if ((fp = fopen(termpaths[i], "r")) != (FILE *) 0) {
+ if (_nc_access(termpaths[i], R_OK) == 0
+ && (fp = fopen(termpaths[i], "r")) != (FILE *) 0) {
_nc_set_source(termpaths[i]);
/*
@@ -1036,13 +1105,15 @@ _nc_read_termcap_entry
}
}
}
+ if (copied != 0)
+ free(copied);
#endif /* USE_GETCAP */
if (_nc_head == 0)
- return (ERR);
+ return (TGETENT_ERR);
/* resolve all use references */
- _nc_resolve_uses(TRUE);
+ _nc_resolve_uses2(TRUE, FALSE);
/* find a terminal matching tn, if we can */
#if USE_GETCAP_CACHE
@@ -1052,13 +1123,12 @@ _nc_read_termcap_entry
for_entry_list(ep) {
if (_nc_name_match(ep->tterm.term_names, tn, "|:")) {
/*
- * Make a local copy of the terminal capabilities. Free all
- * entry storage except the string table for the loaded type
- * (which we disconnected from the list by NULLing out
- * ep->tterm.str_table above).
+ * Make a local copy of the terminal capabilities, delinked
+ * from the list.
*/
*tp = ep->tterm;
- ep->tterm.str_table = (char *) 0;
+ _nc_delink_entry(_nc_head, &(ep->tterm));
+ free(ep);
/*
* OK, now try to write the type to user's terminfo directory.
@@ -1075,7 +1145,7 @@ _nc_read_termcap_entry
#if USE_GETCAP_CACHE
(void) _nc_write_entry(tp);
#endif
- found = TRUE;
+ found = TGETENT_YES;
break;
}
}
@@ -1084,7 +1154,6 @@ _nc_read_termcap_entry
}
#endif
- _nc_free_entries(_nc_head);
return (found);
}
#else
diff --git a/lib/libcurses/tinfo/setbuf.c b/lib/libcurses/tinfo/setbuf.c
index cfe3771b036..a569f45cc52 100644
--- a/lib/libcurses/tinfo/setbuf.c
+++ b/lib/libcurses/tinfo/setbuf.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: setbuf.c,v 1.4 2001/01/22 18:01:57 millert Exp $ */
+/* $OpenBSD: setbuf.c,v 1.5 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2003,2007 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -42,7 +42,7 @@
#include <curses.priv.h>
-MODULE_ID("$From: setbuf.c,v 1.7 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: setbuf.c,v 1.5 2010/01/12 23:22:06 nicm Exp $")
/*
* If the output file descriptor is connected to a tty (the typical case) it
@@ -100,47 +100,53 @@ MODULE_ID("$From: setbuf.c,v 1.7 2000/12/10 02:55:08 tom Exp $")
* buffer. So we disable this by default (there may yet be a workaround).
*/
NCURSES_EXPORT(void)
-_nc_set_buffer(FILE * ofp, bool buffered)
+_nc_set_buffer(FILE *ofp, bool buffered)
{
/* optional optimization hack -- do before any output to ofp */
#if HAVE_SETVBUF || HAVE_SETBUFFER
- unsigned buf_len;
- char *buf_ptr;
+ if (SP->_buffered != buffered) {
+ unsigned buf_len;
+ char *buf_ptr;
- if (getenv("NCURSES_NO_SETBUF") != 0)
- return;
+ if (getenv("NCURSES_NO_SETBUF") != 0)
+ return;
- fflush(ofp);
- if ((SP->_buffered = buffered) != 0) {
- buf_len = min(LINES * (COLS + 6), 2800);
- if ((buf_ptr = SP->_setbuf) == 0) {
- if ((buf_ptr = typeMalloc(char, buf_len)) == NULL)
- return;
- SP->_setbuf = buf_ptr;
- /* Don't try to free this! */
- }
+ fflush(ofp);
+#ifdef __DJGPP__
+ setmode(ofp, O_BINARY);
+#endif
+ if (buffered != 0) {
+ buf_len = min(LINES * (COLS + 6), 2800);
+ if ((buf_ptr = SP->_setbuf) == 0) {
+ if ((buf_ptr = typeMalloc(char, buf_len)) == NULL)
+ return;
+ SP->_setbuf = buf_ptr;
+ /* Don't try to free this! */
+ }
#if !USE_SETBUF_0
- else
- return;
+ else
+ return;
#endif
- } else {
+ } else {
#if !USE_SETBUF_0
- return;
+ return;
#else
- buf_len = 0;
- buf_ptr = 0;
+ buf_len = 0;
+ buf_ptr = 0;
#endif
- }
+ }
#if HAVE_SETVBUF
#ifdef SETVBUF_REVERSED /* pre-svr3? */
- (void) setvbuf(ofp, buf_ptr, buf_len, buf_len ? _IOFBF : _IOLBF);
+ (void) setvbuf(ofp, buf_ptr, buf_len, buf_len ? _IOFBF : _IOLBF);
#else
- (void) setvbuf(ofp, buf_ptr, buf_len ? _IOFBF : _IOLBF, buf_len);
+ (void) setvbuf(ofp, buf_ptr, buf_len ? _IOFBF : _IOLBF, buf_len);
#endif
#elif HAVE_SETBUFFER
- (void) setbuffer(ofp, buf_ptr, (int) buf_len);
+ (void) setbuffer(ofp, buf_ptr, (int) buf_len);
#endif
+ SP->_buffered = buffered;
+ }
#endif /* HAVE_SETVBUF || HAVE_SETBUFFER */
}
diff --git a/lib/libcurses/tinfo/strings.c b/lib/libcurses/tinfo/strings.c
index fd5d7f314b8..b0f06598466 100644
--- a/lib/libcurses/tinfo/strings.c
+++ b/lib/libcurses/tinfo/strings.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: strings.c,v 1.3 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: strings.c,v 1.4 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 2000 Free Software Foundation, Inc. *
+ * Copyright (c) 2000-2003,2007 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -38,7 +38,7 @@
#include <curses.priv.h>
-MODULE_ID("$From: strings.c,v 1.3 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: strings.c,v 1.4 2010/01/12 23:22:06 nicm Exp $")
/****************************************************************************
* Useful string functions (especially for mvcur)
@@ -46,8 +46,7 @@ MODULE_ID("$From: strings.c,v 1.3 2000/12/10 02:55:08 tom Exp $")
#if !HAVE_STRSTR
NCURSES_EXPORT(char *)
-_nc_strstr
-(const char *haystack, const char *needle)
+_nc_strstr(const char *haystack, const char *needle)
{
size_t len1 = strlen(haystack);
size_t len2 = strlen(needle);
@@ -55,7 +54,7 @@ _nc_strstr
while ((len1 != 0) && (len1-- >= len2)) {
if (!strncmp(haystack, needle, len2)) {
- result = haystack;
+ result = (char *) haystack;
break;
}
haystack++;
@@ -65,16 +64,18 @@ _nc_strstr
#endif
/*
- * Initialize the descriptor so we can append to it.
+ * Initialize the descriptor so we can append to it. Note that 'src' may
+ * be a null pointer (see _nc_str_null), so the corresponding strcat and
+ * strcpy calls have to allow for this.
*/
NCURSES_EXPORT(string_desc *)
-_nc_str_init
-(string_desc * dst, char *src, size_t len)
+_nc_str_init(string_desc * dst, char *src, size_t len)
{
if (dst != 0) {
dst->s_head = src;
dst->s_tail = src;
dst->s_size = len - 1;
+ dst->s_init = dst->s_size;
if (src != 0)
*src = 0;
}
@@ -85,8 +86,7 @@ _nc_str_init
* Initialize the descriptor for only tracking the amount of memory used.
*/
NCURSES_EXPORT(string_desc *)
-_nc_str_null
-(string_desc * dst, size_t len)
+_nc_str_null(string_desc * dst, size_t len)
{
return _nc_str_init(dst, 0, len);
}
@@ -95,8 +95,7 @@ _nc_str_null
* Copy a descriptor
*/
NCURSES_EXPORT(string_desc *)
-_nc_str_copy
-(string_desc * dst, string_desc * src)
+_nc_str_copy(string_desc * dst, string_desc * src)
{
*dst = *src;
return dst;
@@ -137,7 +136,7 @@ _nc_safe_strcpy(string_desc * dst, const char *src)
strlcpy(dst->s_head, src, dst->s_size);
dst->s_tail = dst->s_head + len;
}
- dst->s_size -= len;
+ dst->s_size = dst->s_init - len;
return TRUE;
}
}
diff --git a/lib/libcurses/tinfo/trim_sgr0.c b/lib/libcurses/tinfo/trim_sgr0.c
new file mode 100644
index 00000000000..017d715bd01
--- /dev/null
+++ b/lib/libcurses/tinfo/trim_sgr0.c
@@ -0,0 +1,328 @@
+/* $OpenBSD: trim_sgr0.c,v 1.1 2010/01/12 23:22:06 nicm Exp $ */
+
+/****************************************************************************
+ * Copyright (c) 2005-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"), to deal in the Software without restriction, including *
+ * without limitation the rights to use, copy, modify, merge, publish, *
+ * distribute, distribute with modifications, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included *
+ * in all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas Dickey *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+
+#include <ctype.h>
+
+#include <tic.h>
+#include <term_entry.h>
+
+MODULE_ID("$Id: trim_sgr0.c,v 1.1 2010/01/12 23:22:06 nicm Exp $")
+
+#undef CUR
+#define CUR tp->
+
+#define CSI 233
+#define ESC 033 /* ^[ */
+#define L_BRACK '['
+
+static char *
+set_attribute_9(TERMTYPE *tp, int flag)
+{
+ const char *result;
+
+ if ((result = tparm(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, flag)) == 0)
+ result = "";
+ return strdup(result);
+}
+
+static int
+is_csi(const char *s)
+{
+ if (UChar(s[0]) == CSI)
+ return 1;
+ else if (s[0] == ESC && s[1] == L_BRACK)
+ return 2;
+ return 0;
+}
+
+static char *
+skip_zero(char *s)
+{
+ if (s[0] == '0') {
+ if (s[1] == ';')
+ s += 2;
+ else if (isalpha(UChar(s[1])))
+ s += 1;
+ }
+ return s;
+}
+
+static const char *
+skip_delay(const char *s)
+{
+ if (s[0] == '$' && s[1] == '<') {
+ s += 2;
+ while (isdigit(UChar(*s)) || *s == '/')
+ ++s;
+ if (*s == '>')
+ ++s;
+ }
+ return s;
+}
+
+/*
+ * Improve similar_sgr a little by moving the attr-string from the beginning
+ * to the end of the s-string.
+ */
+static bool
+rewrite_sgr(char *s, char *attr)
+{
+ if (PRESENT(s)) {
+ if (PRESENT(attr)) {
+ unsigned len_s = strlen(s);
+ unsigned len_a = strlen(attr);
+
+ if (len_s > len_a && !strncmp(attr, s, len_a)) {
+ unsigned n;
+ TR(TRACE_DATABASE, ("rewrite:\n\t%s", s));
+ for (n = 0; n < len_s - len_a; ++n) {
+ s[n] = s[n + len_a];
+ }
+ strlcpy(s + n, attr, len_s - n);
+ TR(TRACE_DATABASE, ("to:\n\t%s", s));
+ }
+ }
+ return TRUE;
+ }
+ return FALSE; /* oops */
+}
+
+static bool
+similar_sgr(char *a, char *b)
+{
+ bool result = FALSE;
+ int csi_a = is_csi(a);
+ int csi_b = is_csi(b);
+ unsigned len_a;
+ unsigned len_b;
+
+ TR(TRACE_DATABASE, ("similar_sgr:\n\t%s\n\t%s",
+ _nc_visbuf2(1, a),
+ _nc_visbuf2(2, b)));
+ if (csi_a != 0 && csi_b != 0 && csi_a == csi_b) {
+ a += csi_a;
+ b += csi_b;
+ if (*a != *b) {
+ a = skip_zero(a);
+ b = skip_zero(b);
+ }
+ }
+ len_a = strlen(a);
+ len_b = strlen(b);
+ if (len_a && len_b) {
+ if (len_a > len_b)
+ result = (strncmp(a, b, len_b) == 0);
+ else
+ result = (strncmp(a, b, len_a) == 0);
+ }
+ TR(TRACE_DATABASE, ("...similar_sgr: %d\n\t%s\n\t%s", result,
+ _nc_visbuf2(1, a),
+ _nc_visbuf2(2, b)));
+ return result;
+}
+
+static unsigned
+chop_out(char *string, unsigned i, unsigned j)
+{
+ TR(TRACE_DATABASE, ("chop_out %d..%d from %s", i, j, _nc_visbuf(string)));
+ while (string[j] != '\0') {
+ string[i++] = string[j++];
+ }
+ string[i] = '\0';
+ return i;
+}
+
+/*
+ * Compare, ignoring delays. Some of the delay values are inconsistent, and
+ * we do not want to be stopped by that.
+ *
+ * Returns the number of chars from 'full' that we matched. If any mismatch
+ * occurs, return zero.
+ */
+static int
+compare_part(const char *part, const char *full)
+{
+ const char *next_part;
+ const char *next_full;
+ int used_full = 0;
+ int used_delay = 0;
+
+ while (*part != 0) {
+ if (*part != *full) {
+ used_full = 0;
+ break;
+ }
+
+ /*
+ * Adjust the return-value to allow the rare case of
+ * string<delay>string
+ * to remove the whole piece. The most common case is a delay at the
+ * end of the string. The adjusted string will retain the delay, which
+ * is conservative.
+ */
+ if (used_delay != 0) {
+ used_full += used_delay;
+ used_delay = 0;
+ }
+ if (*part == '$' && *full == '$') {
+ next_part = skip_delay(part);
+ next_full = skip_delay(full);
+ if (next_part != part && next_full != full) {
+ used_delay += (next_full - full);
+ full = next_full;
+ part = next_part;
+ continue;
+ }
+ }
+ ++used_full;
+ ++part;
+ ++full;
+ }
+ return used_full;
+}
+
+/*
+ * While 'sgr0' is the "same" as termcap 'me', there is a compatibility issue.
+ * The sgr/sgr0 capabilities include setting/clearing alternate character set
+ * mode. A termcap application cannot use sgr, so sgr0 strings that reset
+ * alternate character set mode will be misinterpreted. Here, we remove those
+ * from the more common ISO/ANSI/VT100 entries, which have sgr0 agreeing with
+ * sgr.
+ *
+ * This function returns the modified sgr0 if it can be modified, a null if
+ * an error occurs, or the original sgr0 if no change is needed.
+ */
+NCURSES_EXPORT(char *)
+_nc_trim_sgr0(TERMTYPE *tp)
+{
+ char *result = exit_attribute_mode;
+
+ T((T_CALLED("_nc_trim_sgr0()")));
+
+ if (PRESENT(exit_attribute_mode)
+ && PRESENT(set_attributes)) {
+ bool found = FALSE;
+ char *on = set_attribute_9(tp, 1);
+ char *off = set_attribute_9(tp, 0);
+ char *end = strdup(exit_attribute_mode);
+ char *tmp;
+ size_t i, j, k;
+
+ TR(TRACE_DATABASE, ("checking if we can trim sgr0 based on sgr"));
+ TR(TRACE_DATABASE, ("sgr0 %s", _nc_visbuf(end)));
+ TR(TRACE_DATABASE, ("sgr(9:off) %s", _nc_visbuf(off)));
+ TR(TRACE_DATABASE, ("sgr(9:on) %s", _nc_visbuf(on)));
+
+ if (!rewrite_sgr(on, enter_alt_charset_mode)
+ || !rewrite_sgr(off, exit_alt_charset_mode)
+ || !rewrite_sgr(end, exit_alt_charset_mode)) {
+ FreeIfNeeded(off);
+ } else if (similar_sgr(off, end)
+ && !similar_sgr(off, on)) {
+ TR(TRACE_DATABASE, ("adjusting sgr(9:off) : %s", _nc_visbuf(off)));
+ result = off;
+ /*
+ * If rmacs is a substring of sgr(0), remove that chunk.
+ */
+ if (exit_alt_charset_mode != 0) {
+ TR(TRACE_DATABASE, ("scan for rmacs %s", _nc_visbuf(exit_alt_charset_mode)));
+ j = strlen(off);
+ k = strlen(exit_alt_charset_mode);
+ if (j > k) {
+ for (i = 0; i <= (j - k); ++i) {
+ int k2 = compare_part(exit_alt_charset_mode, off + i);
+ if (k2 != 0) {
+ found = TRUE;
+ chop_out(off, i, i + k2);
+ break;
+ }
+ }
+ }
+ }
+ /*
+ * SGR 10 would reset to normal font.
+ */
+ if (!found) {
+ if ((i = is_csi(off)) != 0
+ && off[strlen(off) - 1] == 'm') {
+ TR(TRACE_DATABASE, ("looking for SGR 10 in %s",
+ _nc_visbuf(off)));
+ tmp = skip_zero(off + i);
+ if (tmp[0] == '1'
+ && skip_zero(tmp + 1) != tmp + 1) {
+ i = tmp - off;
+ if (off[i - 1] == ';')
+ i--;
+ j = skip_zero(tmp + 1) - off;
+ i = chop_out(off, i, j);
+ found = TRUE;
+ }
+ }
+ }
+ if (!found
+ && (tmp = strstr(end, off)) != 0
+ && strcmp(end, off) != 0) {
+ i = tmp - end;
+ j = strlen(off);
+ tmp = strdup(end);
+ chop_out(tmp, i, j);
+ free(off);
+ result = tmp;
+ }
+ TR(TRACE_DATABASE, ("...adjusted sgr0 : %s", _nc_visbuf(result)));
+ if (!strcmp(result, exit_attribute_mode)) {
+ TR(TRACE_DATABASE, ("...same result, discard"));
+ free(result);
+ result = exit_attribute_mode;
+ }
+ } else {
+ /*
+ * Either the sgr does not reference alternate character set,
+ * or it is incorrect. That's too hard to decide right now.
+ */
+ free(off);
+ }
+ FreeIfNeeded(end);
+ FreeIfNeeded(on);
+ } else {
+ /*
+ * Possibly some applications are confused if sgr0 contains rmacs,
+ * but that would be a different bug report -TD
+ */
+ }
+
+ returnPtr(result);
+}
diff --git a/lib/libcurses/tinfo/use_screen.c b/lib/libcurses/tinfo/use_screen.c
new file mode 100644
index 00000000000..2d79e734601
--- /dev/null
+++ b/lib/libcurses/tinfo/use_screen.c
@@ -0,0 +1,60 @@
+/* $OpenBSD: use_screen.c,v 1.1 2010/01/12 23:22:06 nicm Exp $ */
+
+/****************************************************************************
+ * Copyright (c) 2007,2008 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+ * copy of this software and associated documentation files (the *
+ * "Software"), to deal in the Software without restriction, including *
+ * without limitation the rights to use, copy, modify, merge, publish, *
+ * distribute, distribute with modifications, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included *
+ * in all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey 2007 *
+ ****************************************************************************/
+
+#include <curses.priv.h>
+
+MODULE_ID("$Id: use_screen.c,v 1.1 2010/01/12 23:22:06 nicm Exp $")
+
+NCURSES_EXPORT(int)
+use_screen(SCREEN *screen, NCURSES_SCREEN_CB func, void *data)
+{
+ SCREEN *save_SP;
+ int code = OK;
+
+ T((T_CALLED("use_screen(%p,%p,%p)"), screen, func, data));
+
+ /*
+ * FIXME - add a flag so a given thread can check if _it_ has already
+ * recurred through this point, return an error if so.
+ */
+ _nc_lock_global(curses);
+ save_SP = SP;
+ set_term(screen);
+
+ code = func(screen, data);
+
+ set_term(save_SP);
+ _nc_unlock_global(curses);
+ returnCode(code);
+}
diff --git a/lib/libcurses/tinfo/write_entry.c b/lib/libcurses/tinfo/write_entry.c
index 9aff48b5ef0..4f28313b905 100644
--- a/lib/libcurses/tinfo/write_entry.c
+++ b/lib/libcurses/tinfo/write_entry.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: write_entry.c,v 1.12 2003/03/18 16:55:54 millert Exp $ */
+/* $OpenBSD: write_entry.c,v 1.13 2010/01/12 23:22:06 nicm Exp $ */
/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@@ -31,6 +31,7 @@
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
@@ -38,6 +39,7 @@
*/
#include <curses.priv.h>
+#include <hashed_db.h>
#include <sys/stat.h>
@@ -48,21 +50,27 @@
#define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR)
#endif
-#if 0
+#if 1
#define TRACE_OUT(p) DEBUG(2, p)
#else
#define TRACE_OUT(p) /*nothing */
#endif
-MODULE_ID("$From: write_entry.c,v 1.56 2000/12/10 02:55:08 tom Exp $")
+MODULE_ID("$Id: write_entry.c,v 1.13 2010/01/12 23:22:06 nicm Exp $")
static int total_written;
-static int write_object(FILE *, TERMTYPE *);
+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, TERMTYPE *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);
@@ -70,49 +78,117 @@ write_file(char *filename, TERMTYPE * tp)
}
DEBUG(1, ("Created %s", filename));
- if (write_object(fp, tp) == ERR) {
+ if (write_object(tp, buffer, &offset, limit) == ERR
+ || fwrite(buffer, sizeof(char), offset, fp) != offset) {
_nc_syserr_abort("error writing %s/%s", _nc_tic_dir(0), filename);
}
+
fclose(fp);
}
/*
- * make_directory(char *path)
+ * Check for access rights to destination directories
+ * Create any directories which don't exist.
*
- * Make a directory if it doesn't exist.
+ * Note: there's no reason to return the result of make_db_root(), since
+ * this function is called only in instances where that has to succeed.
*/
+static void
+check_writeable(int code)
+{
+ static const char dirnames[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ static bool verified[sizeof(dirnames)];
+
+ char dir[sizeof(LEAF_FMT)];
+ char *s = 0;
+
+ if (code == 0 || (s = strchr(dirnames, code)) == 0)
+ _nc_err_abort("Illegal terminfo subdirectory \"" LEAF_FMT "\"", code);
+
+ if (verified[s - dirnames])
+ return;
+
+ snprintf(dir, sizeof(dir), LEAF_FMT, code);
+ if (make_db_root(dir) < 0) {
+ _nc_err_abort("%s/%s: permission denied", _nc_tic_dir(0), dir);
+ }
+
+ verified[s - dirnames] = TRUE;
+}
+#endif /* !USE_HASHED_DB */
+
static int
-make_directory(const char *path)
+make_db_path(char *dst, const char *src, unsigned limit)
{
- int rc;
- struct stat statbuf;
- char fullpath[PATH_MAX];
- const char *destination = _nc_tic_dir(0);
+ int rc = -1;
+ const char *top = _nc_tic_dir(0);
- if (path == destination || *path == '/') {
- if (strlcpy(fullpath, path, sizeof(fullpath)) >= sizeof(fullpath))
- return (-1);
+ if (src == top || _nc_is_abs_path(src)) {
+ if (strlen(src) + 1 <= limit) {
+ (void) strlcpy(dst, src, limit);
+ rc = 0;
+ }
} else {
- if (strlen(destination) + strlen(path) + 2 > sizeof(fullpath))
- return (-1);
- (void) snprintf(fullpath, sizeof(fullpath), "%s/%s", destination, path);
+ if (strlen(top) + strlen(src) + 2 <= limit) {
+ (void) snprintf(dst, limit, "%s/%s", top, src);
+ rc = 0;
+ }
+ }
+#if USE_HASHED_DB
+ if (rc == 0) {
+ if (_nc_is_dir_path(dst)) {
+ rc = -1;
+ } else {
+ unsigned have = strlen(dst);
+ if (have > 3 && strcmp(dst + have - 3, DBM_SUFFIX)) {
+ if (have + 3 <= limit)
+ strlcat(dst, DBM_SUFFIX, limit);
+ else
+ rc = -1;
+ }
+ }
}
+#endif
+ return rc;
+}
- if ((rc = stat(path, &statbuf)) < 0) {
- rc = mkdir(path, 0777);
- } else {
- if (_nc_access(path, R_OK | W_OK | X_OK) < 0) {
+/*
+ * Make a database-root if it doesn't exist.
+ */
+static int
+make_db_root(const char *path)
+{
+ int rc;
+ char fullpath[PATH_MAX];
+
+ if ((rc = make_db_path(fullpath, path, sizeof(fullpath))) == 0) {
+#if USE_HASHED_DB
+ DB *capdbp;
+
+ if ((capdbp = _nc_db_open(fullpath, TRUE)) == NULL)
+ rc = -1;
+ else if (_nc_db_close(capdbp) < 0)
+ rc = -1;
+#else
+ struct stat statbuf;
+
+ if ((rc = stat(path, &statbuf)) < 0) {
+ rc = mkdir(path, 0777);
+ } else if (_nc_access(path, R_OK | W_OK | X_OK) < 0) {
rc = -1; /* permission denied */
} else if (!(S_ISDIR(statbuf.st_mode))) {
rc = -1; /* not a directory */
}
+#endif
}
return rc;
}
+/*
+ * Set the write directory for compiled entries.
+ */
NCURSES_EXPORT(void)
_nc_set_writedir(char *dir)
-/* set the write directory for compiled entries */
{
const char *destination;
char actual[PATH_MAX];
@@ -125,12 +201,12 @@ _nc_set_writedir(char *dir)
(void) _nc_tic_dir(dir);
destination = _nc_tic_dir(0);
- if (make_directory(destination) < 0) {
+ if (make_db_root(destination) < 0) {
char *home = _nc_home_terminfo();
if (home != 0) {
destination = home;
- if (make_directory(destination) < 0)
+ if (make_db_root(destination) < 0)
_nc_err_abort("%s: permission denied (errno %d)",
destination, errno);
}
@@ -140,51 +216,17 @@ _nc_set_writedir(char *dir)
* Note: because of this code, this logic should be exercised
* *once only* per run.
*/
+#if USE_HASHED_DB
+ make_db_path(actual, destination, sizeof(actual));
+#else
if (chdir(_nc_tic_dir(destination)) < 0
|| getcwd(actual, sizeof(actual)) == 0)
_nc_err_abort("%s: not a directory", destination);
+#endif
_nc_keep_tic_dir(strdup(actual));
}
/*
- * check_writeable(char code)
- *
- * Miscellaneous initialisations
- *
- * Check for access rights to destination directories
- * Create any directories which don't exist.
- * Note: there's no reason to return the result of make_directory(), since
- * this function is called only in instances where that has to succeed.
- *
- */
-
-static void
-check_writeable(int code)
-{
- static const char dirnames[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- static bool verified[sizeof(dirnames)];
-
- char dir[2];
- char *s = 0;
-
- if (code == 0 || (s = strchr(dirnames, code)) == 0)
- _nc_err_abort("Illegal terminfo subdirectory \"%c\"", code);
-
- if (verified[s - dirnames])
- return;
-
- dir[0] = code;
- dir[1] = '\0';
- if (make_directory(dir) < 0) {
- _nc_err_abort("%s/%s: permission denied", _nc_tic_dir(0), dir);
- }
-
- verified[s - dirnames] = TRUE;
-}
-
-/*
- * _nc_write_entry()
- *
* Save the compiled version of a description in the filesystem.
*
* make a copy of the name-list
@@ -204,24 +246,39 @@ check_writeable(int code)
* _nc_curr_line is properly set before the write_entry() call.
*/
-void
-_nc_write_entry(TERMTYPE * const tp)
+NCURSES_EXPORT(void)
+_nc_write_entry(TERMTYPE *const tp)
{
+#if USE_HASHED_DB
+
+ char buffer[MAX_ENTRY_SIZE + 1];
+ unsigned limit = sizeof(buffer);
+ unsigned offset = 0;
+
+#else /* !USE_HASHED_DB */
+
struct stat statbuf;
- char name_list[MAX_TERMINFO_LENGTH];
- char *first_name, *other_names;
- char *ptr;
char filename[PATH_MAX];
char linkname[PATH_MAX];
#if USE_SYMLINKS
char symlinkname[PATH_MAX];
+#if !HAVE_LINK
+#undef HAVE_LINK
+#define HAVE_LINK 1
+#endif
#endif /* USE_SYMLINKS */
+
static int call_count;
static time_t start_time; /* time at start of writes */
- if (call_count++ == 0) {
- start_time = 0;
- }
+#endif /* USE_HASHED_DB */
+
+ char name_list[MAX_TERMINFO_LENGTH];
+ char *first_name, *other_names;
+ char *ptr;
+
+ assert(strlen(tp->term_names) != 0);
+ assert(strlen(tp->term_names) < sizeof(name_list));
(void) strlcpy(name_list, tp->term_names, sizeof(name_list));
DEBUG(7, ("Name list = '%s'", name_list));
@@ -253,10 +310,59 @@ _nc_write_entry(TERMTYPE * const tp)
_nc_set_type(first_name);
- if (strlen(first_name) > sizeof(filename) - 3)
+#if USE_HASHED_DB
+ if (write_object(tp, buffer + 1, &offset, limit - 1) != ERR) {
+ DB *capdb = _nc_db_open(_nc_tic_dir(0), TRUE);
+ DBT key, data;
+
+ if (capdb != 0) {
+ buffer[0] = 0;
+
+ memset(&key, 0, sizeof(key));
+ key.data = tp->term_names;
+ key.size = strlen(tp->term_names);
+
+ memset(&data, 0, sizeof(data));
+ data.data = buffer;
+ data.size = offset + 1;
+
+ _nc_db_put(capdb, &key, &data);
+
+ buffer[0] = 2;
+
+ key.data = name_list;
+ key.size = strlen(name_list);
+
+ strlcpy(buffer + 1, tp->term_names, sizeof(buffer) - 1);
+ data.size = strlen(tp->term_names) + 1;
+
+ _nc_db_put(capdb, &key, &data);
+
+ while (*other_names != '\0') {
+ ptr = other_names++;
+ while (*other_names != '|' && *other_names != '\0')
+ other_names++;
+
+ if (*other_names != '\0')
+ *(other_names++) = '\0';
+
+ key.data = ptr;
+ key.size = strlen(ptr);
+
+ _nc_db_put(capdb, &key, &data);
+ }
+ _nc_db_close(capdb);
+ }
+ }
+#else /* !USE_HASHED_DB */
+ if (call_count++ == 0) {
+ start_time = 0;
+ }
+
+ if (strlen(first_name) >= sizeof(filename) - 3)
_nc_warning("terminal name too long.");
- snprintf(filename, sizeof(filename), "%c/%s", first_name[0], first_name);
+ snprintf(filename, sizeof(filename), LEAF_FMT "/%s", first_name[0], first_name);
/*
* Has this primary name been written since the first call to
@@ -281,6 +387,7 @@ _nc_write_entry(TERMTYPE * const tp)
}
while (*other_names != '\0') {
ptr = other_names++;
+ assert(ptr < buffer + sizeof(buffer) - 1);
while (*other_names != '|' && *other_names != '\0')
other_names++;
@@ -297,7 +404,7 @@ _nc_write_entry(TERMTYPE * const tp)
}
check_writeable(ptr[0]);
- snprintf(linkname, sizeof(linkname), "%c/%s", ptr[0], ptr);
+ snprintf(linkname, sizeof(linkname), LEAF_FMT "/%s", ptr[0], ptr);
if (strcmp(filename, linkname) == 0) {
_nc_warning("self-synonym ignored");
@@ -309,8 +416,8 @@ _nc_write_entry(TERMTYPE * const tp)
{
int code;
#if USE_SYMLINKS
- strlcpy(symlinkname, "../", sizeof(symlinkname));
- strlcat(symlinkname, filename, sizeof(symlinkname));
+ strlcpy(symlinkname, "../", sizeof(symlinkname));
+ strlcat(symlinkname, filename, sizeof(symlinkname));
#endif /* USE_SYMLINKS */
#if HAVE_REMOVE
code = remove(linkname);
@@ -351,20 +458,45 @@ _nc_write_entry(TERMTYPE * const tp)
write_file(linkname, tp);
#endif /* HAVE_LINK */
}
+#endif /* USE_HASHED_DB */
}
+static unsigned
+fake_write(char *dst,
+ unsigned *offset,
+ unsigned limit,
+ char *src,
+ unsigned want,
+ unsigned size)
+{
+ int have = (limit - *offset);
+
+ want *= size;
+ if (have > 0) {
+ if ((int) want > have)
+ want = have;
+ memcpy(dst + *offset, src, want);
+ *offset += want;
+ } else {
+ want = 0;
+ }
+ return (int) (want / size);
+}
+
+#define Write(buf, size, count) fake_write(buffer, offset, limit, (char *) buf, count, size)
+
#undef LITTLE_ENDIAN /* BSD/OS defines this as a feature macro */
#define HI(x) ((x) / 256)
#define LO(x) ((x) % 256)
#define LITTLE_ENDIAN(p, x) (p)[0] = LO(x), (p)[1] = HI(x)
-#define WRITE_STRING(str) (fwrite(str, sizeof(char), strlen(str) + 1, fp) == strlen(str) + 1)
+#define WRITE_STRING(str) (Write(str, sizeof(char), strlen(str) + 1) == strlen(str) + 1)
static int
-compute_offsets(char **Strings, int strmax, short *offsets)
+compute_offsets(char **Strings, unsigned strmax, short *offsets)
{
size_t nextfree = 0;
- int i;
+ unsigned i;
for (i = 0; i < strmax; i++) {
if (Strings[i] == ABSENT_STRING) {
@@ -374,16 +506,17 @@ compute_offsets(char **Strings, int strmax, short *offsets)
} else {
offsets[i] = nextfree;
nextfree += strlen(Strings[i]) + 1;
- TRACE_OUT(("put Strings[%d]=%s(%d)", i, _nc_visbuf(Strings[i]), nextfree));
+ TRACE_OUT(("put Strings[%d]=%s(%d)", (int) i,
+ _nc_visbuf(Strings[i]), (int) nextfree));
}
}
return nextfree;
}
static void
-convert_shorts(unsigned char *buf, short *Numbers, int count)
+convert_shorts(unsigned char *buf, short *Numbers, unsigned count)
{
- int i;
+ unsigned i;
for (i = 0; i < count; i++) {
if (Numbers[i] == ABSENT_NUMERIC) { /* HI/LO won't work */
buf[2 * i] = buf[2 * i + 1] = 0377;
@@ -398,10 +531,68 @@ convert_shorts(unsigned char *buf, short *Numbers, int count)
}
#define even_boundary(value) \
- ((value) % 2 != 0 && fwrite(&zero, sizeof(char), 1, fp) != 1)
+ ((value) % 2 != 0 && Write(&zero, sizeof(char), 1) != 1)
+
+#if NCURSES_XNAMES
+static unsigned
+extended_Booleans(TERMTYPE *tp)
+{
+ unsigned short result = 0;
+ unsigned short i;
+
+ for (i = 0; i < tp->ext_Booleans; ++i) {
+ if (tp->Booleans[BOOLCOUNT + i] == TRUE)
+ result = (i + 1);
+ }
+ return result;
+}
+
+static unsigned
+extended_Numbers(TERMTYPE *tp)
+{
+ unsigned short result = 0;
+ unsigned short i;
+
+ for (i = 0; i < tp->ext_Numbers; ++i) {
+ if (tp->Numbers[NUMCOUNT + i] != ABSENT_NUMERIC)
+ result = (i + 1);
+ }
+ return result;
+}
+
+static unsigned
+extended_Strings(TERMTYPE *tp)
+{
+ unsigned short result = 0;
+ unsigned short i;
+
+ for (i = 0; i < tp->ext_Strings; ++i) {
+ if (tp->Strings[STRCOUNT + i] != ABSENT_STRING)
+ result = (i + 1);
+ }
+ return result;
+}
+
+/*
+ * _nc_align_termtype() will extend entries that are referenced in a use=
+ * clause - discard the unneeded data.
+ */
+static bool
+extended_object(TERMTYPE *tp)
+{
+ bool result = FALSE;
+
+ if (_nc_user_definable) {
+ result = ((extended_Booleans(tp)
+ + extended_Numbers(tp)
+ + extended_Strings(tp)) != 0);
+ }
+ return result;
+}
+#endif
static int
-write_object(FILE * fp, TERMTYPE * tp)
+write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit)
{
char *namelist;
size_t namelen, boolmax, nummax, strmax;
@@ -460,9 +651,9 @@ write_object(FILE * fp, TERMTYPE * tp)
LITTLE_ENDIAN(buf + 10, nextfree);
/* write out the header */
- TRACE_OUT(("Header of %s @%ld", namelist, ftell(fp)));
- if (fwrite(buf, 12, 1, fp) != 1
- || fwrite(namelist, sizeof(char), namelen, fp) != namelen)
+ TRACE_OUT(("Header of %s @%d", namelist, *offset));
+ if (Write(buf, 12, 1) != 1
+ || Write(namelist, sizeof(char), namelen) != namelen)
return (ERR);
for (i = 0; i < boolmax; i++)
@@ -470,27 +661,27 @@ write_object(FILE * fp, TERMTYPE * tp)
buf[i] = TRUE;
else
buf[i] = FALSE;
- if (fwrite(buf, sizeof(char), boolmax, fp) != boolmax)
+ if (Write(buf, sizeof(char), boolmax) != boolmax)
return (ERR);
if (even_boundary(namelen + boolmax))
return (ERR);
- TRACE_OUT(("Numerics begin at %04lx", ftell(fp)));
+ TRACE_OUT(("Numerics begin at %04x", *offset));
/* the numerics */
convert_shorts(buf, tp->Numbers, nummax);
- if (fwrite(buf, 2, nummax, fp) != nummax)
+ if (Write(buf, 2, nummax) != nummax)
return (ERR);
- TRACE_OUT(("String offsets begin at %04lx", ftell(fp)));
+ TRACE_OUT(("String offsets begin at %04x", *offset));
/* the string offsets */
convert_shorts(buf, offsets, strmax);
- if (fwrite(buf, 2, strmax, fp) != strmax)
+ if (Write(buf, 2, strmax) != strmax)
return (ERR);
- TRACE_OUT(("String table begins at %04lx", ftell(fp)));
+ TRACE_OUT(("String table begins at %04x", *offset));
/* the strings */
for (i = 0; i < strmax; i++)
@@ -499,15 +690,23 @@ write_object(FILE * fp, TERMTYPE * tp)
return (ERR);
#if NCURSES_XNAMES
- if (NUM_EXT_NAMES(tp)) {
+ if (extended_object(tp)) {
unsigned extcnt = NUM_EXT_NAMES(tp);
if (even_boundary(nextfree))
return (ERR);
- nextfree = compute_offsets(tp->Strings + STRCOUNT, tp->ext_Strings, offsets);
+ nextfree = compute_offsets(tp->Strings + STRCOUNT,
+ tp->ext_Strings,
+ offsets);
TRACE_OUT(("after extended string capabilities, nextfree=%d", nextfree));
- nextfree += compute_offsets(tp->ext_Names, extcnt, offsets + tp->ext_Strings);
+
+ if (tp->ext_Strings >= SIZEOF(offsets))
+ return (ERR);
+
+ nextfree += compute_offsets(tp->ext_Names,
+ extcnt,
+ offsets + tp->ext_Strings);
TRACE_OUT(("after extended capnames, nextfree=%d", nextfree));
strmax = tp->ext_Strings + extcnt;
@@ -519,23 +718,23 @@ write_object(FILE * fp, TERMTYPE * tp)
LITTLE_ENDIAN(buf + 4, tp->ext_Strings);
LITTLE_ENDIAN(buf + 6, strmax);
LITTLE_ENDIAN(buf + 8, nextfree);
- TRACE_OUT(("WRITE extended-header @%ld", ftell(fp)));
- if (fwrite(buf, 10, 1, fp) != 1)
+ TRACE_OUT(("WRITE extended-header @%d", *offset));
+ if (Write(buf, 10, 1) != 1)
return (ERR);
- TRACE_OUT(("WRITE %d booleans @%ld", tp->ext_Booleans, ftell(fp)));
+ TRACE_OUT(("WRITE %d booleans @%d", tp->ext_Booleans, *offset));
if (tp->ext_Booleans
- && fwrite(tp->Booleans + BOOLCOUNT, sizeof(char),
- tp->ext_Booleans, fp) != tp->ext_Booleans)
+ && Write(tp->Booleans + BOOLCOUNT, sizeof(char),
+ tp->ext_Booleans) != tp->ext_Booleans)
return (ERR);
if (even_boundary(tp->ext_Booleans))
return (ERR);
- TRACE_OUT(("WRITE %d numbers @%ld", tp->ext_Numbers, ftell(fp)));
+ TRACE_OUT(("WRITE %d numbers @%d", tp->ext_Numbers, *offset));
if (tp->ext_Numbers) {
convert_shorts(buf, tp->Numbers + NUMCOUNT, tp->ext_Numbers);
- if (fwrite(buf, 2, tp->ext_Numbers, fp) != tp->ext_Numbers)
+ if (Write(buf, 2, tp->ext_Numbers) != tp->ext_Numbers)
return (ERR);
}
@@ -544,8 +743,8 @@ write_object(FILE * fp, TERMTYPE * tp)
* in that order.
*/
convert_shorts(buf, offsets, strmax);
- TRACE_OUT(("WRITE offsets @%ld", ftell(fp)));
- if (fwrite(buf, 2, strmax, fp) != strmax)
+ TRACE_OUT(("WRITE offsets @%d", *offset));
+ if (Write(buf, 2, strmax) != strmax)
return (ERR);
/*
@@ -554,7 +753,7 @@ write_object(FILE * fp, TERMTYPE * tp)
*/
for (i = 0; i < tp->ext_Strings; i++) {
if (VALID_STRING(tp->Strings[i + STRCOUNT])) {
- TRACE_OUT(("WRITE ext_Strings[%d]=%s", i,
+ TRACE_OUT(("WRITE ext_Strings[%d]=%s", (int) i,
_nc_visbuf(tp->Strings[i + STRCOUNT])));
if (!WRITE_STRING(tp->Strings[i + STRCOUNT]))
return (ERR);
@@ -565,7 +764,7 @@ write_object(FILE * fp, TERMTYPE * tp)
* Write the extended names
*/
for (i = 0; i < extcnt; i++) {
- TRACE_OUT(("WRITE ext_Names[%d]=%s", i, tp->ext_Names[i]));
+ TRACE_OUT(("WRITE ext_Names[%d]=%s", (int) i, tp->ext_Names[i]));
if (!WRITE_STRING(tp->ext_Names[i]))
return (ERR);
}