summaryrefslogtreecommitdiff
path: root/progs
diff options
context:
space:
mode:
Diffstat (limited to 'progs')
-rw-r--r--[-rwxr-xr-x]progs/MKtermsort.sh35
-rw-r--r--progs/Makefile.in60
-rwxr-xr-xprogs/capconvert8
-rw-r--r--progs/clear.c6
-rw-r--r--[-rwxr-xr-x]progs/clear.sh0
-rw-r--r--progs/dump_entry.c82
-rw-r--r--progs/dump_entry.h9
-rw-r--r--progs/infocmp.c36
-rw-r--r--progs/modules10
-rw-r--r--progs/progs.priv.h23
-rw-r--r--progs/reset_cmd.c57
-rw-r--r--progs/reset_cmd.h6
-rw-r--r--progs/tabs.c213
-rw-r--r--progs/tic.c408
-rw-r--r--progs/toe.c81
-rw-r--r--progs/tparm_type.c30
-rw-r--r--progs/tparm_type.h6
-rw-r--r--progs/tput.c150
-rw-r--r--progs/tset.c34
-rw-r--r--progs/tty_settings.c12
20 files changed, 879 insertions, 387 deletions
diff --git a/progs/MKtermsort.sh b/progs/MKtermsort.sh
index 7206bc1..ca3232d 100755..100644
--- a/progs/MKtermsort.sh
+++ b/progs/MKtermsort.sh
@@ -1,10 +1,10 @@
#!/bin/sh
-# $Id: MKtermsort.sh,v 1.13 2020/02/02 23:34:34 tom Exp $
+# $Id: MKtermsort.sh,v 1.16 2021/04/18 20:12:50 tom Exp $
#
# MKtermsort.sh -- generate indirection vectors for the various sort methods
#
##############################################################################
-# Copyright 2020 Thomas E. Dickey #
+# Copyright 2020,2021 Thomas E. Dickey #
# Copyright 1998-2015,2017 Free Software Foundation, Inc. #
# #
# Permission is hereby granted, free of charge, to any person obtaining a #
@@ -48,14 +48,25 @@ DATA=${2-../include/Caps}
data=data$$
trap 'rm -f $data' 1 2 3 15
-sed -e 's/[ ][ ]*/ /g' < $DATA >$data
+sed -e 's/[ ][ ]*/ /g' < "$DATA" >$data
DATA=$data
-echo "/*";
-echo " * termsort.c --- sort order arrays for use by infocmp.";
-echo " *";
-echo " * Note: this file is generated using MKtermsort.sh, do not edit by hand.";
-echo " */";
+cat <<EOF
+/*
+ * termsort.h --- sort order arrays for use by infocmp.
+ *
+ * Note: this file is generated using MKtermsort.sh, do not edit by hand.
+ */
+#ifndef _TERMSORT_H
+#define _TERMSORT_H 1
+#include <curses.h>
+
+#ifndef DUMP_ENTRY_H
+typedef unsigned PredType;
+typedef unsigned PredIdx;
+#endif
+
+EOF
echo "static const PredIdx bool_terminfo_sort[] = {";
$AWK <$DATA '
@@ -165,7 +176,11 @@ $3 == "str" && substr($7, 1, 1) == "-" {print "\tFALSE,\t/* ", $2, " */";
$3 == "str" && substr($7, 1, 1) == "Y" {print "\tTRUE,\t/* ", $2, " */"; valid = count++; }
END { printf "#define OK_str_from_termcap %d\n", valid; }
'
-echo "};";
-echo "";
+
+cat <<EOF
+};
+
+#endif /* _TERMSORT_H */
+EOF
rm -f $data
diff --git a/progs/Makefile.in b/progs/Makefile.in
index 79cbc99..d818af4 100644
--- a/progs/Makefile.in
+++ b/progs/Makefile.in
@@ -1,6 +1,6 @@
-# $Id: Makefile.in,v 1.103 2020/02/02 23:34:34 tom Exp $
+# $Id: Makefile.in,v 1.111 2021/07/03 15:45:33 tom Exp $
##############################################################################
-# Copyright 2020 Thomas E. Dickey #
+# Copyright 2020,2021 Thomas E. Dickey #
# Copyright 1998-2016,2018 Free Software Foundation, Inc. #
# #
# Permission is hereby granted, free of charge, to any person obtaining a #
@@ -47,7 +47,7 @@ SHELL = @SHELL@
VPATH = @srcdir@
THIS = Makefile
-CF_MFLAGS = @cf_cv_makeflags@
+TOP_MFLAGS = @cf_cv_makeflags@ DESTDIR="$(DESTDIR)" RPATH_LIST="$(RPATH_LIST)"
@SET_MAKE@
x = @EXEEXT@
@@ -90,7 +90,7 @@ ETAGS = @ETAGS@
CC = @CC@
CPP = @CPP@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ @EXTRA_CFLAGS@
INCDIR = $(top_srcdir)/include
CPPFLAGS = -DHAVE_CONFIG_H -I../progs @CPPFLAGS@
@@ -98,9 +98,9 @@ CPPFLAGS = -DHAVE_CONFIG_H -I../progs @CPPFLAGS@
CCFLAGS = $(CPPFLAGS) $(CFLAGS)
CFLAGS_LIBTOOL = $(CCFLAGS)
-CFLAGS_NORMAL = $(CCFLAGS)
-CFLAGS_DEBUG = $(CCFLAGS) @CC_G_OPT@ -DTRACE
-CFLAGS_PROFILE = $(CCFLAGS) -pg
+CFLAGS_NORMAL = $(CCFLAGS) -DNCURSES_STATIC
+CFLAGS_DEBUG = $(CCFLAGS) -DNCURSES_STATIC @CC_G_OPT@ -DTRACE
+CFLAGS_PROFILE = $(CCFLAGS) -DNCURSES_STATIC -pg
CFLAGS_SHARED = $(CCFLAGS) @CC_SHARED_OPTS@
CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@)
@@ -133,7 +133,7 @@ LINT_OPTS = @LINT_OPTS@
LINT_LIBS = -lncurses @LIBS@
AUTO_SRC = \
- termsort.c \
+ termsort.h \
transform.h
# tic relies on direct access to the terminfo database
@@ -151,6 +151,23 @@ HEADER_DEPS = \
$(INCDIR)/nc_alloc.h
################################################################################
+
+@MAKE_PHONY@.PHONY : all
+@MAKE_PHONY@.PHONY : check
+@MAKE_PHONY@.PHONY : clean
+@MAKE_PHONY@.PHONY : distclean
+@MAKE_PHONY@.PHONY : install
+@MAKE_PHONY@.PHONY : install.libs
+@MAKE_PHONY@.PHONY : install.progs
+@MAKE_PHONY@.PHONY : libs
+@MAKE_PHONY@.PHONY : lint
+@MAKE_PHONY@.PHONY : mostlyclean
+@MAKE_PHONY@.PHONY : realclean
+@MAKE_PHONY@.PHONY : sources
+@MAKE_PHONY@.PHONY : uninstall
+@MAKE_PHONY@.PHONY : uninstall.libs
+@MAKE_PHONY@.PHONY : uninstall.progs
+
all: $(AUTO_SRC) $(PROGS)
sources: $(AUTO_SRC)
@@ -203,10 +220,10 @@ install.progs: $(AUTO_SRC) $(PROGS) $(DESTDIR)$(bindir)
@MAKE_TERMINFO@ $(LIBTOOL_INSTALL) $(INSTALL_PROG) toe$x $(DESTDIR)$(bindir)/$(actual_toe)
@MAKE_TERMINFO@ @echo "linking $(actual_infotocap) to $(actual_tic)"
@MAKE_TERMINFO@ -@rm -f $(DESTDIR)$(bindir)/$(actual_infotocap)
-@MAKE_TERMINFO@ (cd $(DESTDIR)$(bindir) && $(LN_S) $(actual_tic) $(actual_infotocap))
+@MAKE_TERMINFO@ ( cd $(DESTDIR)$(bindir) && $(LN_S) $(actual_tic) $(actual_infotocap) )
@MAKE_TERMINFO@ @echo "linking $(actual_captoinfo) to $(actual_tic)"
@MAKE_TERMINFO@ -@rm -f $(DESTDIR)$(bindir)/$(actual_captoinfo)
-@MAKE_TERMINFO@ (cd $(DESTDIR)$(bindir) && $(LN_S) $(actual_tic) $(actual_captoinfo))
+@MAKE_TERMINFO@ ( cd $(DESTDIR)$(bindir) && $(LN_S) $(actual_tic) $(actual_captoinfo) )
$(LIBTOOL_INSTALL) $(INSTALL_PROG) infocmp$x $(DESTDIR)$(bindir)/$(actual_infocmp)
$(LIBTOOL_INSTALL) $(INSTALL_PROG) clear$x $(DESTDIR)$(bindir)/$(actual_clear)
$(LIBTOOL_INSTALL) $(INSTALL_PROG) tabs$x $(DESTDIR)$(bindir)/$(actual_tabs)
@@ -214,7 +231,7 @@ install.progs: $(AUTO_SRC) $(PROGS) $(DESTDIR)$(bindir)
$(LIBTOOL_INSTALL) $(INSTALL_PROG) tset$x $(DESTDIR)$(bindir)/$(actual_tset)
@echo "linking $(actual_reset) to $(actual_tset)"
-@rm -f $(DESTDIR)$(bindir)/$(actual_reset)
- (cd $(DESTDIR)$(bindir) && $(LN_S) $(actual_tset) $(actual_reset))
+ ( cd $(DESTDIR)$(bindir) && $(LN_S) $(actual_tset) $(actual_reset) )
uninstall.progs:
@MAKE_TERMINFO@ -@$(LIBTOOL_CLEAN) rm -f $(DESTDIR)$(bindir)/$(actual_tic)
@@ -292,7 +309,7 @@ DEPS_TSET = \
tset$x: $(DEPS_TSET) $(DEPS_CURSES) transform.h
@ECHO_LD@ $(LINK) $(DEPS_TSET) $(LDFLAGS_TINFO) -o $@
-termsort.c: $(srcdir)/MKtermsort.sh
+termsort.h: $(srcdir)/MKtermsort.sh
$(SHELL) $(srcdir)/MKtermsort.sh $(AWK) $(srcdir)/../include/@TERMINFO_CAPS@ >$@
#
@@ -323,18 +340,29 @@ realclean :: distclean
../include/hashsize.h \
../include/parametrized.h \
../include/term.h :
- cd ../include; $(MAKE) $(CF_MFLAGS)
+ ( cd ../include && $(MAKE) $(TOP_MFLAGS) )
$(DEPS_CURSES) :
- cd ../ncurses; $(MAKE) $(CF_MFLAGS)
+ ( cd ../ncurses && $(MAKE) $(TOP_MFLAGS) )
lint:
@MAKE_TERMINFO@ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tic.c $(srcdir)/dump_entry.c $(LINT_LIBS)
-@MAKE_TERMINFO@ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/toe.c $(srcdir)/dump_entry.c $(LINT_LIBS)
+@MAKE_TERMINFO@ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/toe.c $(LINT_LIBS)
$(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/clear.c $(LINT_LIBS)
$(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/infocmp.c $(srcdir)/dump_entry.c $(LINT_LIBS)
$(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tabs.c $(LINT_LIBS)
$(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tput.c $(LINT_LIBS)
- $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tset.c $(srcdir)/dump_entry.c $(LINT_LIBS)
+ $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/tset.c $(LINT_LIBS)
+
+# Verify that each header-file can be compiled without including another.
+check:
+ @$(SHELL) -c "for header in *.h;\
+ do \
+ echo \"** testing \$${header}\" ; \
+ echo \"#include <\$${header}>\" >headers.c; \
+ echo \"int main(void) { return 0; }\" >>headers.c; \
+ $(CC) -c $(CFLAGS) $(CPPFLAGS) headers.c; \
+ done"
+ -@rm -f headers.*
###############################################################################
# The remainder of this file is automatically generated during configuration
diff --git a/progs/capconvert b/progs/capconvert
index bcd56d3..c73c368 100755
--- a/progs/capconvert
+++ b/progs/capconvert
@@ -1,6 +1,6 @@
#!/bin/sh
##############################################################################
-# Copyright 2019,2020 Thomas E. Dickey #
+# Copyright 2019-2020,2021 Thomas E. Dickey #
# Copyright 1998-2011,2017 Free Software Foundation, Inc. #
# #
# Permission is hereby granted, free of charge, to any person obtaining a #
@@ -27,7 +27,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
-# $Id: capconvert,v 1.9 2020/02/02 23:34:34 tom Exp $
+# $Id: capconvert,v 1.10 2021/09/04 10:55:04 tom Exp $
#
# capconvert -- automated conversion from termcap to terminfo
#
@@ -95,7 +95,7 @@ else
fi
echo "";
-# Check if test -x works (it's not portable, but useful)
+# Check if test -x works (it is not portable, but useful)
OPT="-x"
TMP=test$$; touch $TMP && chmod 755 $TMP
if test $OPT $TMP ; then
@@ -227,7 +227,7 @@ fi
# OK, here comes the nasty case...user has a TERMCAP. Instead of
# trying to follow all the convolutions of the relationship between
-# TERM and TERMCAP (partly because it's too painful, and partly because
+# TERM and TERMCAP (partly because it is too painful, and partly because
# we don't actually know what TERM will be nor even if it always has
# the same value for this user) we do the following three steps...
diff --git a/progs/clear.c b/progs/clear.c
index 85a5ea5..97cb0f3 100644
--- a/progs/clear.c
+++ b/progs/clear.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2020,2021 Thomas E. Dickey *
* Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -41,11 +41,11 @@
#include <clear_cmd.h>
#include <tty_settings.h>
-MODULE_ID("$Id: clear.c,v 1.23 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: clear.c,v 1.24 2021/03/20 18:23:14 tom Exp $")
const char *_nc_progname = "clear";
-static void
+static GCC_NORETURN void
usage(void)
{
#define KEEP(s) s "\n"
diff --git a/progs/clear.sh b/progs/clear.sh
index 1d899f1..1d899f1 100755..100644
--- a/progs/clear.sh
+++ b/progs/clear.sh
diff --git a/progs/dump_entry.c b/progs/dump_entry.c
index 85d56eb..860eccc 100644
--- a/progs/dump_entry.c
+++ b/progs/dump_entry.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 2018-2020,2021 Thomas E. Dickey *
* Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -36,11 +36,11 @@
#define __INTERNAL_CAPS_VISIBLE
#include <progs.priv.h>
-#include "dump_entry.h"
-#include "termsort.c" /* this C file is generated */
+#include <dump_entry.h>
+#include <termsort.h> /* this C file is generated */
#include <parametrized.h> /* so is this */
-MODULE_ID("$Id: dump_entry.c,v 1.176 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: dump_entry.c,v 1.189 2021/09/04 10:29:59 tom Exp $")
#define DISCARD(string) string = ABSENT_STRING
#define PRINTF (void) printf
@@ -85,7 +85,7 @@ static int indent = 8;
/* cover various ports and variants of terminfo */
#define V_ALLCAPS 0 /* all capabilities (SVr4, XSI, ncurses) */
#define V_SVR1 1 /* SVR1, Ultrix */
-#define V_HPUX 2 /* HP/UX */
+#define V_HPUX 2 /* HP-UX */
#define V_AIX 3 /* AIX */
#define V_BSD 4 /* BSD */
@@ -107,9 +107,7 @@ static int indent = 8;
#define StrIndirect(j) ((sortmode == S_NOSORT) ? (j) : str_indirect[j])
#endif
-static void failed(const char *) GCC_NORETURN;
-
-static void
+static GCC_NORETURN void
failed(const char *s)
{
perror(s);
@@ -433,10 +431,12 @@ static int
op_length(const char *src, int offset)
{
int result = 0;
- int ch;
+
if (offset > 0 && src[offset - 1] == '\\') {
result = 0;
} else {
+ int ch;
+
result++; /* for '%' mark */
ch = src[offset + result];
if (TcOutput()) {
@@ -477,10 +477,12 @@ static int
find_split(const char *src, int step, int size)
{
int result = size;
- int n;
+
if (size > 0) {
/* check if that would split a backslash-sequence */
int mark = size;
+ int n;
+
for (n = size - 1; n > 0; --n) {
int ch = UChar(src[step + n]);
if (ch == '\\') {
@@ -526,13 +528,13 @@ fill_spaces(const char *src)
size_t size = strlen(fill);
char *result = 0;
int pass;
- int s, d;
+ size_t s, d;
for (pass = 0; pass < 2; ++pass) {
for (s = d = 0; src[s] != '\0'; ++s) {
if (src[s] == ' ') {
if (pass) {
_nc_STRCPY(&result[d], fill, need + 1 - d);
- d += (int) size;
+ d += size;
} else {
need += size;
}
@@ -547,7 +549,7 @@ fill_spaces(const char *src)
if (pass) {
result[d] = '\0';
} else {
- result = malloc(need + 1);
+ result = calloc(need + 1, sizeof(char));
if (result == 0)
failed("fill_spaces");
}
@@ -585,7 +587,6 @@ wrap_concat(const char *src, int need, unsigned mode)
(column + want) > width) {
int step = 0;
int used = width > WRAPPED ? width : WRAPPED;
- int size;
int base = 0;
char *p, align[9];
const char *my_t = trailer;
@@ -619,7 +620,7 @@ wrap_concat(const char *src, int need, unsigned mode)
}
while ((column + (need + gaps)) > used) {
- size = used - tag;
+ int size = used - tag;
if (step) {
strcpy_DYN(&outbuf, align);
size -= base;
@@ -747,7 +748,7 @@ leading_DYN(DYNBUF * buffer, const char *leading)
}
bool
-has_params(const char *src)
+has_params(const char *src, bool formatting)
{
bool result = FALSE;
int len = (int) strlen(src);
@@ -765,7 +766,11 @@ has_params(const char *src)
}
}
if (!ifthen) {
- result = ((len > 50) && params);
+ if (formatting) {
+ result = ((len > 50) && params);
+ } else {
+ result = params;
+ }
}
return result;
}
@@ -774,7 +779,7 @@ static char *
fmt_complex(TERMTYPE2 *tterm, const char *capability, char *src, int level)
{
bool percent = FALSE;
- bool params = has_params(src);
+ bool params = has_params(src, TRUE);
while (*src != '\0') {
switch (*src) {
@@ -801,7 +806,7 @@ fmt_complex(TERMTYPE2 *tterm, const char *capability, char *src, int level)
strncpy_DYN(&tmpbuf, "%", (size_t) 1);
strncpy_DYN(&tmpbuf, src, (size_t) 1);
src++;
- params = has_params(src);
+ params = has_params(src, TRUE);
if (!params && *src != '\0' && *src != '%') {
strncpy_DYN(&tmpbuf, "\n", (size_t) 1);
indent_DYN(&tmpbuf, level + 1);
@@ -878,12 +883,15 @@ static const char *
number_format(int value)
{
const char *result = "%d";
+
if ((outform != F_TERMCAP) && (value > 255)) {
unsigned long lv = (unsigned long) value;
- unsigned long mm;
int bits = sizeof(unsigned long) * 8;
int nn;
+
for (nn = 8; nn < bits; ++nn) {
+ unsigned long mm;
+
mm = 1UL << nn;
if ((mm - 16) <= lv && (mm + 16) > lv) {
result = "%#x";
@@ -907,7 +915,6 @@ fmt_entry(TERMTYPE2 *tterm,
{
PredIdx i, j;
char buffer[MAX_TERMINFO_LENGTH + EXTRA_CAP];
- char *capability;
NCURSES_CONST char *name;
int predval, len;
PredIdx num_bools = 0;
@@ -1027,6 +1034,7 @@ fmt_entry(TERMTYPE2 *tterm,
}
for_each_string(j, tterm) {
+ char *capability;
i = StrIndirect(j);
name = ExtStrname(tterm, (int) i, str_names);
assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);
@@ -1110,7 +1118,7 @@ fmt_entry(TERMTYPE2 *tterm,
? parametrized[i]
: ((*srccap == 'k')
? 0
- : has_params(srccap)));
+ : has_params(srccap, FALSE)));
char *cv = _nc_infotocap(name, srccap, params);
if (cv == 0) {
@@ -1125,7 +1133,7 @@ fmt_entry(TERMTYPE2 *tterm,
char *s = srccap, *d = buffer;
int need = 3 + (int) strlen(name);
while ((*d = *s++) != 0) {
- if ((d - buffer + 1) >= (int) sizeof(buffer)) {
+ if ((d - buffer + 2) >= (int) sizeof(buffer)) {
fprintf(stderr,
"%s: value for %s is too long\n",
_nc_progname,
@@ -1342,10 +1350,11 @@ kill_labels(TERMTYPE2 *tterm, int target)
{
int n;
int result = 0;
- char *cap;
- char name[10];
+ char name[20];
for (n = 0; n <= 10; ++n) {
+ char *cap;
+
_nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "lf%d", n);
cap = find_string(tterm, name);
if (VALID_STRING(cap)
@@ -1368,10 +1377,11 @@ kill_fkeys(TERMTYPE2 *tterm, int target)
{
int n;
int result = 0;
- char *cap;
- char name[10];
+ char name[20];
for (n = 60; n >= 0; --n) {
+ char *cap;
+
_nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "kf%d", n);
cap = find_string(tterm, name);
if (VALID_STRING(cap)
@@ -1473,19 +1483,22 @@ dump_entry(TERMTYPE2 *tterm,
PredFunc pred)
{
TERMTYPE2 save_tterm;
- int len, critlen;
+ int critlen;
const char *legend;
bool infodump;
if (quickdump) {
char bigbuf[65536];
- unsigned n;
unsigned offset = 0;
+
separator = "";
trailer = "\n";
indent = 0;
+
if (_nc_write_object(tterm, bigbuf, &offset, sizeof(bigbuf)) == OK) {
char numbuf[80];
+ unsigned n;
+
if (quickdump & 1) {
if (outbuf.used)
wrap_concat1("\n");
@@ -1500,6 +1513,7 @@ dump_entry(TERMTYPE2 *tterm,
static char padding[] =
{0, 0};
int value = 0;
+
if (outbuf.used)
wrap_concat1("\n");
wrap_concat1("b64:");
@@ -1550,7 +1564,7 @@ dump_entry(TERMTYPE2 *tterm,
}
if (FMT_ENTRY() > critlen) {
/*
- * We pick on sgr because it's a nice long string capability that
+ * We pick on sgr because it is a nice long string capability that
* is really just an optimization hack. Another good candidate is
* acsc since it is both long and unused by BSD termcap.
*/
@@ -1595,6 +1609,7 @@ dump_entry(TERMTYPE2 *tterm,
}
if (!changed || (FMT_ENTRY() > critlen)) {
int oldversion = tversion;
+ int len;
tversion = V_BSD;
SHOW_WHY("# (terminfo-only capabilities suppressed to fit entry within %d bytes)\n",
@@ -1757,9 +1772,8 @@ void
repair_acsc(TERMTYPE2 *tp)
{
if (VALID_STRING(acs_chars)) {
- size_t n, m;
+ size_t n;
char mapped[256];
- char extra = 0;
unsigned source;
unsigned target;
bool fix_needed = FALSE;
@@ -1774,7 +1788,11 @@ repair_acsc(TERMTYPE2 *tp)
if (acs_chars[n + 1])
n++;
}
+
if (fix_needed) {
+ size_t m;
+ char extra = 0;
+
memset(mapped, 0, sizeof(mapped));
for (n = 0; acs_chars[n] != 0; n++) {
source = UChar(acs_chars[n]);
diff --git a/progs/dump_entry.h b/progs/dump_entry.h
index 984fee7..39e856f 100644
--- a/progs/dump_entry.h
+++ b/progs/dump_entry.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 2018-2020,2021 Thomas E. Dickey *
* Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -34,7 +34,7 @@
****************************************************************************/
/*
- * $Id: dump_entry.h,v 1.42 2020/02/02 23:34:34 tom Exp $
+ * $Id: dump_entry.h,v 1.44 2021/04/18 19:56:09 tom Exp $
*
* Dump control definitions and variables
*/
@@ -67,13 +67,16 @@
#define CMP_STRING 2 /* comparison on strings */
#define CMP_USE 3 /* comparison on use capabilities */
+#ifndef _TERMSORT_H
typedef unsigned PredType;
typedef unsigned PredIdx;
+#endif
+
typedef int (*PredFunc) (PredType, PredIdx);
typedef void (*PredHook) (PredType, PredIdx, const char *);
extern NCURSES_CONST char *nametrans(const char *);
-extern bool has_params(const char *src);
+extern bool has_params(const char *, bool);
extern int fmt_entry(TERMTYPE2 *, PredFunc, int, int, int, int);
extern int show_entry(void);
extern void compare_entry(PredHook, TERMTYPE2 *, bool);
diff --git a/progs/infocmp.c b/progs/infocmp.c
index f42ff34..d98c676 100644
--- a/progs/infocmp.c
+++ b/progs/infocmp.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2020,2021 Thomas E. Dickey *
* Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -43,7 +43,7 @@
#include <dump_entry.h>
-MODULE_ID("$Id: infocmp.c,v 1.144 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: infocmp.c,v 1.151 2021/06/17 21:11:08 tom Exp $")
#define MAX_STRING 1024 /* maximum formatted string */
@@ -94,7 +94,7 @@ typedef struct {
static ENTERED *entered;
#undef ExitProgram
-static void ExitProgram(int code) GCC_NORETURN;
+static GCC_NORETURN void ExitProgram(int code);
/* prototype is to get gcc to accept the noreturn attribute */
static void
ExitProgram(int code)
@@ -322,16 +322,17 @@ static void
print_uses(ENTRY * ep, FILE *fp)
/* print an entry's use references */
{
- unsigned i;
-
- if (!ep->nuses)
+ if (!ep->nuses) {
fputs("NULL", fp);
- else
+ } else {
+ unsigned i;
+
for (i = 0; i < ep->nuses; i++) {
fputs(ep->uses[i].name, fp);
if (i < ep->nuses - 1)
fputs(" ", fp);
}
+ }
}
static const char *
@@ -418,7 +419,7 @@ show_comparing(char **names)
/*
* ncurses stores two types of non-standard capabilities:
- * a) capabilities listed past the "STOP-HERE" comment in the Caps file.
+ * a) capabilities listed past the "STOP-HERE" comment in the Caps file.
* These are used in the terminfo source file to provide data for termcaps,
* e.g., when there is no equivalent capability in terminfo, as well as for
* widely-used non-standard capabilities.
@@ -835,6 +836,8 @@ analyze_string(const char *name, const char *cap, TERMTYPE2 *tp)
char *cp = tp->Strings[i];
/* don't use function-key capabilities */
+ if (strnames[i] == NULL)
+ continue;
if (strnames[i][0] == 'k' && strnames[i][1] == 'f')
continue;
@@ -1194,8 +1197,9 @@ usage(void)
DATA("Options:")
};
#undef DATA
+ /* length is given here so the compiler can make everything readonly */
#define DATA(s) s
- static const char options[][45] =
+ static const char options[][46] =
{
" -0 print single-row"
," -1 print single-column"
@@ -1304,9 +1308,9 @@ dump_initializers(TERMTYPE2 *term)
name_initializer("alias"), entries->tterm.term_names);
for_each_string(n, term) {
- char buf[MAX_STRING], *sp, *tp;
-
if (VALID_STRING(term->Strings[n])) {
+ char buf[MAX_STRING], *sp, *tp;
+
tp = buf;
#define TP_LIMIT ((MAX_STRING - 5) - (size_t)(tp - buf))
*tp++ = '"';
@@ -1509,6 +1513,8 @@ show_databases(void)
#if NO_LEAKS
#define MAIN_LEAKS() \
+ _nc_free_termtype2(&entries[0].tterm); \
+ _nc_free_termtype2(&entries[1].tterm); \
free(myargv); \
free(tfile); \
free(tname)
@@ -1528,7 +1534,7 @@ main(int argc, char *argv[])
char **myargv;
char *firstdir, *restdir;
- int c, i, len;
+ int c;
bool formatted = FALSE;
bool filecompare = FALSE;
int initdump = 0;
@@ -1835,8 +1841,8 @@ main(int argc, char *argv[])
tname[termcount]);
status = _nc_read_entry2(tname[termcount],
- tfile[termcount],
- &entries[termcount].tterm);
+ tfile[termcount],
+ &entries[termcount].tterm);
}
if (status <= 0) {
@@ -1880,6 +1886,8 @@ main(int argc, char *argv[])
analyze_string("rmkx", keypad_local, &entries[0].tterm);
#undef CUR
} else {
+ int i;
+ int len;
/*
* Here's where the real work gets done
diff --git a/progs/modules b/progs/modules
index f2bba15..349061f 100644
--- a/progs/modules
+++ b/progs/modules
@@ -1,7 +1,7 @@
-# $Id: modules,v 1.22 2020/02/02 23:34:34 tom Exp $
+# $Id: modules,v 1.25 2021/04/18 17:21:03 tom Exp $
# Program modules (some are in ncurses lib!)
##############################################################################
-# Copyright 2020 Thomas E. Dickey #
+# Copyright 2020,2021 Thomas E. Dickey #
# Copyright 1998-2014,2016 Free Software Foundation, Inc. #
# #
# Permission is hereby granted, free of charge, to any person obtaining a #
@@ -37,13 +37,13 @@ clear progs $(srcdir) $(HEADER_DEPS) tty_settings.h
tic progs $(srcdir) $(HEADER_DEPS) transform.h $(srcdir)/dump_entry.h $(srcdir)/tparm_type.h
toe progs $(srcdir) $(HEADER_DEPS) $(INCDIR)/hashed_db.h
clear_cmd progs $(srcdir) $(HEADER_DEPS) clear_cmd.h
-dump_entry progs $(srcdir) $(HEADER_DEPS) $(srcdir)/dump_entry.h ../include/parametrized.h $(INCDIR)/capdefaults.c termsort.c
+dump_entry progs $(srcdir) $(HEADER_DEPS) $(srcdir)/dump_entry.h ../include/parametrized.h $(INCDIR)/capdefaults.c termsort.h
infocmp progs $(srcdir) $(HEADER_DEPS) $(srcdir)/dump_entry.h
reset_cmd progs $(srcdir) $(HEADER_DEPS) reset_cmd.h tty_settings.h
tabs progs $(srcdir) $(HEADER_DEPS)
tparm_type progs $(srcdir) $(HEADER_DEPS) $(srcdir)/tparm_type.h
-tput progs $(srcdir) $(HEADER_DEPS) transform.h $(srcdir)/dump_entry.h $(srcdir)/tparm_type.h termsort.c reset_cmd.h tty_settings.h
-tset progs $(srcdir) $(HEADER_DEPS) transform.h $(srcdir)/dump_entry.h ../include/termcap.h reset_cmd.h tty_settings.h
+tput progs $(srcdir) $(HEADER_DEPS) transform.h $(srcdir)/tparm_type.h reset_cmd.h tty_settings.h
+tset progs $(srcdir) $(HEADER_DEPS) transform.h ../include/termcap.h reset_cmd.h tty_settings.h
transform progs $(srcdir) $(HEADER_DEPS) transform.h
tty_settings progs $(srcdir) $(HEADER_DEPS) tty_settings.h
diff --git a/progs/progs.priv.h b/progs/progs.priv.h
index da7a515..32f4e4e 100644
--- a/progs/progs.priv.h
+++ b/progs/progs.priv.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 2019-2020,2021 Thomas E. Dickey *
* Copyright 1998-2015,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -31,7 +31,7 @@
* Author: Thomas E. Dickey 1997-on *
****************************************************************************/
/*
- * $Id: progs.priv.h,v 1.48 2020/02/02 23:34:34 tom Exp $
+ * $Id: progs.priv.h,v 1.53 2021/06/26 20:43:19 tom Exp $
*
* progs.priv.h
*
@@ -58,10 +58,6 @@
#include <unistd.h>
#endif
-#if HAVE_SYS_BSDTYPES_H
-#include <sys/bsdtypes.h> /* needed for ISC */
-#endif
-
#if HAVE_LIMITS_H
# include <limits.h>
#elif HAVE_SYS_PARAM_H
@@ -119,10 +115,20 @@ extern char *optarg;
extern int optind;
#endif /* HAVE_GETOPT_H */
+#undef _NC_WINDOWS
+#if (defined(_WIN32) || defined(_WIN64))
+#define _NC_WINDOWS 1
+#endif
+
#define NCURSES_INTERNALS 1
#define NCURSES_OPAQUE 0
#include <curses.h>
+
+#if !(defined(NCURSES_WGETCH_EVENTS) && defined(NEED_KEY_EVENT))
+#undef KEY_EVENT /* reduce compiler-warnings with Visual C++ */
+#endif
+
#include <term_entry.h>
#include <nc_termios.h>
#include <tic.h>
@@ -130,6 +136,7 @@ extern int optind;
#include <nc_string.h>
#include <nc_alloc.h>
+#include <nc_access.h>
#if HAVE_NC_FREEALL
#undef ExitProgram
@@ -155,6 +162,10 @@ extern int optind;
#endif /* gcc workarounds */
/* usually in <unistd.h> */
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
diff --git a/progs/reset_cmd.c b/progs/reset_cmd.c
index 9d23cd0..eff3af7 100644
--- a/progs/reset_cmd.c
+++ b/progs/reset_cmd.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 2019-2020,2021 Thomas E. Dickey *
* Copyright 2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -47,13 +47,13 @@
#endif
#if NEED_PTEM_H
-/* they neglected to define struct winsize in termios.h -- it's only
+/* they neglected to define struct winsize in termios.h -- it is only
in termio.h */
#include <sys/stream.h>
#include <sys/ptem.h>
#endif
-MODULE_ID("$Id: reset_cmd.c,v 1.19 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: reset_cmd.c,v 1.28 2021/10/02 18:08:44 tom Exp $")
/*
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
@@ -80,7 +80,7 @@ static FILE *my_file;
static bool use_reset = FALSE; /* invoked as reset */
static bool use_init = FALSE; /* invoked as init */
-static void
+static GCC_NORETURN void
failed(const char *msg)
{
int code = errno;
@@ -102,7 +102,7 @@ cat_file(char *file)
bool sent = FALSE;
if (file != 0) {
- if ((fp = fopen(file, "r")) == 0)
+ if ((fp = safe_fopen(file, "r")) == 0)
failed(file);
while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) {
@@ -193,7 +193,7 @@ out_char(int c)
* a child program dies in raw mode.
*/
void
-reset_tty_settings(int fd, TTY * tty_settings)
+reset_tty_settings(int fd, TTY * tty_settings, int noset)
{
GET_TTY(fd, tty_settings);
@@ -329,7 +329,9 @@ reset_tty_settings(int fd, TTY * tty_settings)
);
#endif
- SET_TTY(fd, tty_settings);
+ if (!noset) {
+ SET_TTY(fd, tty_settings);
+ }
}
/*
@@ -363,6 +365,13 @@ default_erase(void)
void
set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill)
{
+#if defined(EXP_WIN32_DRIVER)
+ /* noop */
+ (void) tty_settings;
+ (void) my_erase;
+ (void) my_intr;
+ (void) my_kill;
+#else
if (DISABLED(tty_settings->c_cc[VERASE]) || my_erase >= 0) {
tty_settings->c_cc[VERASE] = UChar((my_erase >= 0)
? my_erase
@@ -380,6 +389,7 @@ set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill)
? my_kill
: CKILL);
}
+#endif
}
/*
@@ -389,6 +399,9 @@ set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill)
void
set_conversions(TTY * tty_settings)
{
+#if defined(EXP_WIN32_DRIVER)
+ /* FIXME */
+#else
#ifdef ONLCR
tty_settings->c_oflag |= ONLCR;
#endif
@@ -412,6 +425,7 @@ set_conversions(TTY * tty_settings)
tty_settings->c_oflag &= ~OXTABS;
#endif /* OXTABS */
tty_settings->c_lflag |= (ECHOE | ECHOK);
+#endif
}
static bool
@@ -501,16 +515,15 @@ send_init_strings(int fd GCC_UNUSED, TTY * old_settings)
} else
#if defined(set_lr_margin)
if (VALID_STRING(set_lr_margin)) {
- need_flush |= sent_string(TPARM_2(set_lr_margin, 0,
- columns - 1));
+ need_flush |= sent_string(TIPARM_2(set_lr_margin, 0, columns - 1));
} else
#endif
#if defined(set_left_margin_parm) && defined(set_right_margin_parm)
if (VALID_STRING(set_left_margin_parm)
&& VALID_STRING(set_right_margin_parm)) {
- need_flush |= sent_string(TPARM_1(set_left_margin_parm, 0));
- need_flush |= sent_string(TPARM_1(set_right_margin_parm,
- columns - 1));
+ need_flush |= sent_string(TIPARM_1(set_left_margin_parm, 0));
+ need_flush |= sent_string(TIPARM_1(set_right_margin_parm,
+ columns - 1));
} else
#endif
if (VALID_STRING(set_left_margin)
@@ -518,8 +531,8 @@ send_init_strings(int fd GCC_UNUSED, TTY * old_settings)
need_flush |= to_left_margin();
need_flush |= sent_string(set_left_margin);
if (VALID_STRING(parm_right_cursor)) {
- need_flush |= sent_string(TPARM_1(parm_right_cursor,
- columns - 1));
+ need_flush |= sent_string(TIPARM_1(parm_right_cursor,
+ columns - 1));
} else {
for (i = 0; i < columns - 1; i++) {
out_char(' ');
@@ -552,15 +565,23 @@ show_tty_change(TTY * old_settings,
int which,
unsigned def)
{
- unsigned older, newer;
+ unsigned older = 0, newer = 0;
char *p;
+#if defined(EXP_WIN32_DRIVER)
+ /* noop */
+ (void) old_settings;
+ (void) new_settings;
+ (void) name;
+ (void) which;
+ (void) def;
+#else
newer = new_settings->c_cc[which];
older = old_settings->c_cc[which];
if (older == newer && older == def)
return;
-
+#endif
(void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
if (DISABLED(newer)) {
@@ -604,9 +625,13 @@ reset_flush(void)
void
print_tty_chars(TTY * old_settings, TTY * new_settings)
{
+#if defined(EXP_WIN32_DRIVER)
+ /* noop */
+#else
show_tty_change(old_settings, new_settings, "Erase", VERASE, CERASE);
show_tty_change(old_settings, new_settings, "Kill", VKILL, CKILL);
show_tty_change(old_settings, new_settings, "Interrupt", VINTR, CINTR);
+#endif
}
#if HAVE_SIZECHANGE
diff --git a/progs/reset_cmd.h b/progs/reset_cmd.h
index 7d45715..91a637c 100644
--- a/progs/reset_cmd.h
+++ b/progs/reset_cmd.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2020,2021 Thomas E. Dickey *
* Copyright 2016 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -32,7 +32,7 @@
****************************************************************************/
/*
- * $Id: reset_cmd.h,v 1.8 2020/02/02 23:34:34 tom Exp $
+ * $Id: reset_cmd.h,v 1.9 2021/10/02 20:58:58 tom Exp $
*
* Utility functions for resetting terminal.
*/
@@ -51,7 +51,7 @@ extern bool send_init_strings(int /* fd */, TTY * /* old_settings */);
extern void print_tty_chars(TTY * /* old_settings */, TTY * /* new_settings */);
extern void reset_flush(void);
extern void reset_start(FILE * /* fp */, bool /* is_reset */, bool /* is_init */ );
-extern void reset_tty_settings(int /* fd */, TTY * /* tty_settings */);
+extern void reset_tty_settings(int /* fd */, TTY * /* tty_settings */, int /* noset */);
extern void set_control_chars(TTY * /* tty_settings */, int /* erase */, int /* intr */, int /* kill */);
extern void set_conversions(TTY * /* tty_settings */);
diff --git a/progs/tabs.c b/progs/tabs.c
index 8a3bc10..02de31c 100644
--- a/progs/tabs.c
+++ b/progs/tabs.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2020,2021 Thomas E. Dickey *
* Copyright 2008-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -39,9 +39,9 @@
#include <progs.priv.h>
#include <tty_settings.h>
-MODULE_ID("$Id: tabs.c,v 1.42 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: tabs.c,v 1.50 2021/10/10 00:54:41 tom Exp $")
-static void usage(void) GCC_NORETURN;
+static GCC_NORETURN void usage(void);
const char *_nc_progname;
static int max_cols;
@@ -59,14 +59,44 @@ putch(int c)
return putchar(c);
}
+static char *
+skip_csi(char *value)
+{
+ if (UChar(*value) == 0x9b)
+ ++value;
+ else if (!strncmp(value, "\033[", 2))
+ value += 2;
+ return value;
+}
+
+/*
+ * If the terminal uses ANSI clear_all_tabs, then it is not necessary to first
+ * move to the left margin before clearing tabs.
+ */
+static bool
+ansi_clear_tabs(void)
+{
+ bool result = FALSE;
+ if (VALID_STRING(clear_all_tabs)) {
+ char *param = skip_csi(clear_all_tabs);
+ if (!strcmp(param, "3g"))
+ result = TRUE;
+ }
+ return result;
+}
+
static void
do_tabs(int *tab_list)
{
int last = 1;
int stop;
+ bool first = TRUE;
- putchar('\r');
while ((stop = *tab_list++) > 0) {
+ if (first) {
+ first = FALSE;
+ putchar('\r');
+ }
if (last < stop) {
while (last++ < stop) {
if (last > max_cols)
@@ -75,7 +105,7 @@ do_tabs(int *tab_list)
}
}
if (stop <= max_cols) {
- tputs(tparm(set_tab, stop), 1, putch);
+ tputs(set_tab, 1, putch);
last = stop;
} else {
break;
@@ -84,8 +114,13 @@ do_tabs(int *tab_list)
putchar('\r');
}
+/*
+ * Decode a list of tab-stops from a string, returning an array of integers.
+ * If the margin is positive (because the terminal does not support margins),
+ * work around this by adding the margin to the decoded values.
+ */
static int *
-decode_tabs(const char *tab_list)
+decode_tabs(const char *tab_list, int margin)
{
int *result = typeCalloc(int, strlen(tab_list) + (unsigned) max_cols);
int n = 0;
@@ -96,12 +131,15 @@ decode_tabs(const char *tab_list)
if (result == 0)
failed("decode_tabs");
+ if (margin < 0)
+ margin = 0;
+
while ((ch = *tab_list++) != '\0') {
if (isdigit(UChar(ch))) {
value *= 10;
value += (ch - '0');
} else if (ch == ',') {
- result[n] = value + prior;
+ result[n] = value + prior + margin;
if (n > 0 && result[n] <= result[n - 1]) {
fprintf(stderr,
"%s: tab-stops are not in increasing order: %d %d\n",
@@ -127,7 +165,7 @@ decode_tabs(const char *tab_list)
int step = value;
value = 1;
while (n < max_cols - 1) {
- result[n++] = value;
+ result[n++] = value + margin;
value += step;
}
}
@@ -135,7 +173,7 @@ decode_tabs(const char *tab_list)
/*
* Add the last value, if any.
*/
- result[n++] = value + prior;
+ result[n++] = value + prior + margin;
result[n] = 0;
}
@@ -143,10 +181,9 @@ decode_tabs(const char *tab_list)
}
static void
-print_ruler(int *tab_list)
+print_ruler(int *tab_list, const char *new_line)
{
int last = 0;
- int stop;
int n;
/* first print a readable ruler */
@@ -160,11 +197,12 @@ print_ruler(int *tab_list)
: (ch + 'A' - 10)));
printf("%.*s", ((max_cols - n) > 10) ? 10 : (max_cols - n), buffer);
}
- putchar('\n');
+ printf("%s", new_line);
/* now, print '*' for each stop */
for (n = 0, last = 0; (tab_list[n] > 0) && (last < max_cols); ++n) {
- stop = tab_list[n];
+ int stop = tab_list[n];
+
while (++last < stop) {
if (last <= max_cols) {
putchar('-');
@@ -181,7 +219,7 @@ print_ruler(int *tab_list)
}
while (++last <= max_cols)
putchar('-');
- putchar('\n');
+ printf("%s", new_line);
}
/*
@@ -189,7 +227,7 @@ print_ruler(int *tab_list)
* ruler.
*/
static void
-write_tabs(int *tab_list)
+write_tabs(int *tab_list, const char *new_line)
{
int stop;
@@ -199,7 +237,7 @@ write_tabs(int *tab_list)
/* also show a tab _past_ the stops */
if (stop < max_cols)
fputs("\t+", stdout);
- putchar('\n');
+ fputs(new_line, stdout);
}
/*
@@ -210,11 +248,11 @@ static char *
trimmed_tab_list(const char *source)
{
char *result = strdup(source);
- int ch, j, k, last;
-
if (result != 0) {
+ int j, k, last;
+
for (j = k = last = 0; result[j] != 0; ++j) {
- ch = UChar(result[j]);
+ int ch = UChar(result[j]);
if (isspace(ch)) {
if (last == '\0') {
continue;
@@ -295,6 +333,60 @@ add_to_tab_list(char **append, const char *value)
}
/*
+ * If the terminal supports it, (re)set the left margin and return true.
+ * Otherwise, return false.
+ */
+static bool
+do_set_margin(int margin, bool no_op)
+{
+ bool result = FALSE;
+
+ if (margin == 0) { /* 0 is special case for resetting */
+ if (VALID_STRING(clear_margins)) {
+ result = TRUE;
+ if (!no_op)
+ tputs(clear_margins, 1, putch);
+ }
+ } else if (margin-- < 0) { /* margin will be 0-based from here on */
+ result = TRUE;
+ } else if (VALID_STRING(set_left_margin)) {
+ result = TRUE;
+ if (!no_op) {
+ /*
+ * assuming we're on the first column of the line, move the cursor
+ * to the column at which we will set a margin.
+ */
+ if (VALID_STRING(column_address)) {
+ tputs(TIPARM_1(column_address, margin), 1, putch);
+ } else if (margin >= 1) {
+ if (VALID_STRING(parm_right_cursor)) {
+ tputs(TIPARM_1(parm_right_cursor, margin), 1, putch);
+ } else {
+ while (margin-- > 0)
+ putch(' ');
+ }
+ }
+ tputs(set_left_margin, 1, putch);
+ }
+ } else if (VALID_STRING(set_left_margin_parm)) {
+ result = TRUE;
+ if (!no_op) {
+ if (VALID_STRING(set_right_margin_parm)) {
+ tputs(TIPARM_1(set_left_margin_parm, margin), 1, putch);
+ } else {
+ tputs(TIPARM_2(set_left_margin_parm, margin, max_cols), 1, putch);
+ }
+ }
+ } else if (VALID_STRING(set_lr_margin)) {
+ result = TRUE;
+ if (!no_op) {
+ tputs(TIPARM_2(set_lr_margin, margin, max_cols), 1, putch);
+ }
+ }
+ return result;
+}
+
+/*
* Check for illegal characters in the tab-list.
*/
static bool
@@ -304,9 +396,11 @@ legal_tab_list(const char *tab_list)
if (tab_list != 0 && *tab_list != '\0') {
if (comma_is_needed(tab_list)) {
- int n, ch;
+ int n;
+
for (n = 0; tab_list[n] != '\0'; ++n) {
- ch = UChar(tab_list[n]);
+ int ch = UChar(tab_list[n]);
+
if (!(isdigit(ch) || ch == ',' || ch == '+')) {
fprintf(stderr,
"%s: unexpected character found '%c'\n",
@@ -320,8 +414,7 @@ legal_tab_list(const char *tab_list)
result = FALSE;
}
} else {
- fprintf(stderr, "%s: no tab-list given\n", _nc_progname);
- result = FALSE;
+ /* if no list given, default to "tabs -8" */
}
return result;
}
@@ -379,17 +472,18 @@ main(int argc, char *argv[])
int rc = EXIT_FAILURE;
bool debug = FALSE;
bool no_op = FALSE;
+ bool change_tty = FALSE;
int n, ch;
NCURSES_CONST char *term_name = 0;
char *append = 0;
const char *tab_list = 0;
+ const char *new_line = "\n";
+ int margin = -1;
TTY tty_settings;
int fd;
_nc_progname = _nc_rootname(argv[0]);
- fd = save_tty_settings(&tty_settings, FALSE);
-
if ((term_name = getenv("TERM")) == 0)
term_name = "ansi+tabs";
@@ -481,7 +575,10 @@ main(int argc, char *argv[])
}
break;
case '+':
- while ((ch = *++option) != '\0') {
+ if ((ch = *++option) != '\0') {
+ int digits = 0;
+ int number = 0;
+
switch (ch) {
case 'm':
/*
@@ -489,6 +586,17 @@ main(int argc, char *argv[])
* att510d implements smgl, which is needed to support
* this option.
*/
+ while ((ch = *++option) != '\0') {
+ if (isdigit(UChar(ch))) {
+ ++digits;
+ number = number * 10 + (ch - '0');
+ } else {
+ usage();
+ }
+ }
+ if (digits == 0)
+ number = 10;
+ margin = number;
break;
default:
/* special case of relative stops separated by spaces? */
@@ -512,9 +620,13 @@ main(int argc, char *argv[])
}
}
+ fd = save_tty_settings(&tty_settings, FALSE);
+
setupterm(term_name, fd, (int *) 0);
max_cols = (columns > 0) ? columns : 80;
+ if (margin > 0)
+ max_cols -= margin;
if (!VALID_STRING(clear_all_tabs)) {
fprintf(stderr,
@@ -525,24 +637,61 @@ main(int argc, char *argv[])
"%s: terminal type '%s' cannot set tabs\n",
_nc_progname, term_name);
} else if (legal_tab_list(tab_list)) {
- int *list = decode_tabs(tab_list);
+ int *list;
+
+ if (tab_list == NULL)
+ tab_list = add_to_tab_list(&append, "8");
+
+ if (!no_op) {
+#if defined(TERMIOS) && defined(OCRNL)
+ /* set tty modes to -ocrnl to allow \r */
+ if (isatty(STDOUT_FILENO)) {
+ TTY new_settings = tty_settings;
+ new_settings.c_oflag &= (unsigned)~OCRNL;
+ update_tty_settings(&tty_settings, &new_settings);
+ change_tty = TRUE;
+ new_line = "\r\n";
+ }
+#endif
- if (!no_op)
+ if (!ansi_clear_tabs())
+ putch('\r');
tputs(clear_all_tabs, 1, putch);
+ }
+
+ if (margin >= 0) {
+ putch('\r');
+ if (margin > 0) {
+ /* reset existing margin before setting margin, to reduce
+ * problems moving left of the current margin.
+ */
+ if (do_set_margin(0, no_op))
+ putch('\r');
+ }
+ if (do_set_margin(margin, no_op))
+ margin = -1;
+ }
+
+ list = decode_tabs(tab_list, margin);
if (list != 0) {
if (!no_op)
do_tabs(list);
if (debug) {
fflush(stderr);
- printf("tabs %s\n", tab_list);
- print_ruler(list);
- write_tabs(list);
+ printf("tabs %s%s", tab_list, new_line);
+ print_ruler(list, new_line);
+ write_tabs(list, new_line);
}
free(list);
} else if (debug) {
fflush(stderr);
- printf("tabs %s\n", tab_list);
+ printf("tabs %s%s", tab_list, new_line);
+ }
+ if (!no_op) {
+ if (change_tty) {
+ restore_tty_settings();
+ }
}
rc = EXIT_SUCCESS;
}
diff --git a/progs/tic.c b/progs/tic.c
index 328bcd6..dba2890 100644
--- a/progs/tic.c
+++ b/progs/tic.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 2018-2020,2021 Thomas E. Dickey *
* Copyright 1998-2017,2018 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -49,7 +49,7 @@
#include <parametrized.h>
#include <transform.h>
-MODULE_ID("$Id: tic.c,v 1.282 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: tic.c,v 1.307 2021/10/05 08:07:05 tom Exp $")
#define STDIN_NAME "<stdin>"
@@ -116,8 +116,6 @@ free_namelist(char **src)
static void
cleanup(void)
{
- int rc;
-
#if NO_LEAKS
free_namelist(namelst);
_nc_leaks_dump_entry();
@@ -125,6 +123,8 @@ cleanup(void)
if (tmp_fp != 0)
fclose(tmp_fp);
if (to_remove != 0) {
+ int rc;
+
#if HAVE_REMOVE
rc = remove(to_remove);
#else
@@ -304,15 +304,17 @@ put_translate(int c)
/* emit a comment char, translating terminfo names to termcap names */
{
static bool in_name = FALSE;
- static size_t have, used;
- static char *namebuf, *suffix;
+ static size_t used;
if (in_name) {
+ static size_t have;
+ static char *namebuf, *suffix;
+
if (used + 1 >= have) {
have += 132;
- if ((namebuf = typeRealloc(char, have, namebuf)) == 0)
+ if ((namebuf = typeRealloc(char, have, namebuf)) == NULL)
failed("put_translate namebuf");
- if ((suffix = typeRealloc(char, have, suffix)) == 0)
+ if ((suffix = typeRealloc(char, have, suffix)) == NULL)
failed("put_translate suffix");
}
if (c == '\n' || c == '@') {
@@ -371,12 +373,10 @@ stripped(char *src)
src++;
if (*src != '\0') {
- size_t len;
-
if ((dst = strdup(src)) == NULL) {
failed("strdup");
} else {
- len = strlen(dst);
+ size_t len = strlen(dst);
while (--len != 0 && isspace(UChar(dst[len])))
dst[len] = '\0';
}
@@ -400,7 +400,7 @@ open_tempfile(char *filename)
}
#else
if (tmpnam(filename) != 0)
- result = fopen(filename, "w");
+ result = safe_fopen(filename, "w");
#endif
return result;
}
@@ -410,15 +410,15 @@ copy_input(FILE *source, const char *filename, char *alt_file)
{
char my_altfile[PATH_MAX];
FILE *result = 0;
- FILE *target = 0;
+ FILE *target;
int ch;
- if (alt_file == 0)
+ if (alt_file == NULL)
alt_file = my_altfile;
- if (source == 0) {
+ if (source == NULL) {
failed("copy_input (source)");
- } else if ((target = open_tempfile(alt_file)) == 0) {
+ } else if ((target = open_tempfile(alt_file)) == NULL) {
failed("copy_input (target)");
} else {
clearerr(source);
@@ -442,7 +442,7 @@ copy_input(FILE *source, const char *filename, char *alt_file)
* the one that we were writing on before starting to read from the
* second stream.
*/
- result = fopen(alt_file, "r+");
+ result = safe_fopen(alt_file, "r+");
fclose(target);
to_remove = strdup(alt_file);
}
@@ -458,7 +458,7 @@ open_input(const char *filename, char *alt_file)
if (!strcmp(filename, "-")) {
fp = copy_input(stdin, STDIN_NAME, alt_file);
- } else if (stat(filename, &sb) < 0) {
+ } else if (stat(filename, &sb) == -1) {
fprintf(stderr, "%s: %s %s\n", _nc_progname, filename, strerror(errno));
ExitProgram(EXIT_FAILURE);
} else if ((mode = (sb.st_mode & S_IFMT)) == S_IFDIR
@@ -466,9 +466,9 @@ open_input(const char *filename, char *alt_file)
fprintf(stderr, "%s: %s is not a file\n", _nc_progname, filename);
ExitProgram(EXIT_FAILURE);
} else {
- fp = fopen(filename, "r");
+ fp = safe_fopen(filename, "r");
- if (fp == 0) {
+ if (fp == NULL) {
fprintf(stderr, "%s: Can't open %s\n", _nc_progname, filename);
ExitProgram(EXIT_FAILURE);
}
@@ -495,7 +495,7 @@ make_namelist(char *src)
unsigned pass, n, nn;
char buffer[BUFSIZ];
- if (src == 0) {
+ if (src == NULL) {
/* EMPTY */ ;
} else if (strchr(src, '/') != 0) { /* a filename */
FILE *fp = open_input(src, (char *) 0);
@@ -512,7 +512,7 @@ make_namelist(char *src)
}
}
if (pass == 1) {
- if ((dst = typeCalloc(char *, nn + 1)) == 0)
+ if ((dst = typeCalloc(char *, nn + 1)) == NULL)
failed("make_namelist");
rewind(fp);
}
@@ -536,7 +536,7 @@ make_namelist(char *src)
break;
}
if (pass == 1) {
- if ((dst = typeCalloc(char *, nn + 1)) == 0)
+ if ((dst = typeCalloc(char *, nn + 1)) == NULL)
failed("make_namelist");
}
}
@@ -554,9 +554,10 @@ matches(char **needle, const char *haystack)
/* does entry in needle list match |-separated field in haystack? */
{
bool code = FALSE;
- size_t n;
if (needle != 0) {
+ size_t n;
+
for (n = 0; needle[n] != 0; n++) {
if (_nc_name_match(haystack, needle[n], "|")) {
code = TRUE;
@@ -577,7 +578,7 @@ valid_db_path(const char *nominal)
size_t need = strlen(nominal) + sizeof(suffix);
char *result = malloc(need);
- if (result == 0)
+ if (result == NULL)
failed("valid_db_path");
_nc_STRCPY(result, nominal, need);
if (strcmp(result + need - sizeof(suffix), suffix)) {
@@ -642,7 +643,7 @@ show_databases(const char *outdir)
char *result;
const char *tried = 0;
- if (outdir == 0) {
+ if (outdir == NULL) {
outdir = _nc_tic_dir(0);
}
if ((result = valid_db_path(outdir)) != 0) {
@@ -877,7 +878,7 @@ main(int argc, char *argv[])
* One problem with immedhook is it means we can't do -e. Problem
* is that we can't guarantee that for each terminal listed, all the
* terminals it depends on will have been kept in core for reference
- * resolution -- in fact it's certain the primitive types at the end
+ * resolution -- in fact it is certain the primitive types at the end
* of reference chains *won't* be in core unless they were explicitly
* in the select list themselves.
*/
@@ -931,7 +932,7 @@ main(int argc, char *argv[])
}
}
- if (tmp_fp == 0) {
+ if (tmp_fp == NULL) {
tmp_fp = open_input(source_file, my_altfile);
if (!strcmp(source_file, "-")) {
source_file = STDIN_NAME;
@@ -1179,6 +1180,14 @@ check_acs(TERMTYPE2 *tp)
}
}
+static char *
+safe_strdup(const char *value)
+{
+ if (value == NULL)
+ value = "";
+ return strdup(value);
+}
+
static bool
same_color(NCURSES_CONST char *oldcap, NCURSES_CONST char *newcap, int limit)
{
@@ -1189,8 +1198,8 @@ same_color(NCURSES_CONST char *oldcap, NCURSES_CONST char *newcap, int limit)
int n;
int same;
for (n = same = 0; n < limit; ++n) {
- char *oldvalue = strdup(TPARM_1(oldcap, n));
- char *newvalue = strdup(TPARM_1(newcap, n));
+ char *oldvalue = safe_strdup(TIPARM_1(oldcap, n));
+ char *newvalue = safe_strdup(TIPARM_1(newcap, n));
same += !strcmp(oldvalue, newvalue);
free(oldvalue);
free(newvalue);
@@ -1209,7 +1218,7 @@ check_colors(TERMTYPE2 *tp)
char *value;
if ((max_colors > 0) != (max_pairs > 0)
- || ((max_colors > max_pairs) && (initialize_pair == 0)))
+ || ((max_colors > max_pairs) && !VALID_STRING(initialize_pair)))
_nc_warning("inconsistent values for max_colors (%d) and max_pairs (%d)",
max_colors, max_pairs);
@@ -1298,13 +1307,12 @@ keypad_final(const char *string)
static long
keypad_index(const char *string)
{
- char *test;
- const char *list = "PQRSwxymtuvlqrsPpn"; /* app-keypad except "Enter" */
int ch;
long result = -1;
if ((ch = keypad_final(string)) != '\0') {
- test = (strchr) (list, ch);
+ const char *list = "PQRSwxymtuvlqrsPpn"; /* app-keypad except "Enter" */
+ char *test = (strchr) (list, ch);
if (test != 0)
result = (long) (test - list);
}
@@ -1321,8 +1329,6 @@ static void
check_ansi_cursor(char *list[4])
{
int j, k;
- int want;
- size_t suffix;
bool skip[4];
bool repeated = FALSE;
@@ -1332,7 +1338,7 @@ check_ansi_cursor(char *list[4])
if (j != k
&& !strcmp(list[j], list[k])) {
char *value = _nc_tic_expand(list[k], TRUE, 0);
- _nc_warning("repeated cursor control %s\n", value);
+ _nc_warning("repeated cursor control %s", value);
repeated = TRUE;
}
}
@@ -1340,6 +1346,7 @@ check_ansi_cursor(char *list[4])
if (!repeated) {
char *up = list[1];
size_t prefix = (size_t) csi_length(up);
+ size_t suffix;
if (prefix) {
suffix = prefix;
@@ -1354,23 +1361,25 @@ check_ansi_cursor(char *list[4])
skip[2] = TRUE;
for (j = 0; j < 4; ++j) {
+ int want;
+
if (skip[j] || strlen(list[j]) == 1)
continue;
if (memcmp(list[j], up, prefix)) {
char *value = _nc_tic_expand(list[j], TRUE, 0);
- _nc_warning("inconsistent prefix for %s\n", value);
+ _nc_warning("inconsistent prefix for %s", value);
continue;
}
if (strlen(list[j]) < suffix) {
char *value = _nc_tic_expand(list[j], TRUE, 0);
- _nc_warning("inconsistent length for %s, expected %d\n",
+ _nc_warning("inconsistent length for %s, expected %d",
value, (int) suffix + 1);
continue;
}
want = "BADC"[j];
if (list[j][suffix] != want) {
char *value = _nc_tic_expand(list[j], TRUE, 0);
- _nc_warning("inconsistent suffix for %s, expected %c, have %c\n",
+ _nc_warning("inconsistent suffix for %s, expected %c, have %c",
value, want, list[j][suffix]);
}
}
@@ -1403,7 +1412,7 @@ check_cursor(TERMTYPE2 *tp)
check_noaddress(tp, "hard_copy");
} else if (generic_type) {
check_noaddress(tp, "generic_type");
- } else if (strchr(tp->term_names, '+') == 0) {
+ } else if (strchr(tp->term_names, '+') == NULL) {
int y = 0;
int x = 0;
if (PRESENT(column_address))
@@ -1525,9 +1534,7 @@ check_keypad(TERMTYPE2 *tp)
char final[MAX_KP + 1];
long list[MAX_KP];
int increase = 0;
- int j, k, kk;
- long last;
- long test;
+ int j;
final[0] = keypad_final(key_a1);
final[1] = keypad_final(key_a3);
@@ -1560,10 +1567,17 @@ check_keypad(TERMTYPE2 *tp)
++increase;
}
}
+
if (increase != (MAX_KP - 1)) {
+ long last;
+
show[0] = '\0';
for (j = 0, last = -1; j < MAX_KP; ++j) {
+ int k;
+ int kk;
+ long test;
+
for (k = 0, kk = -1, test = 100; k < 5; ++k) {
if (list[k] > last &&
list[k] < test) {
@@ -1655,20 +1669,10 @@ check_printer(TERMTYPE2 *tp)
ANDMISSING(start_char_set_def, stop_char_set_def);
#endif
- /* if we have a parameterized form, then the non-parameterized is easy */
-#if defined(set_bottom_margin_parm) && defined(set_bottom_margin)
- ANDMISSING(set_bottom_margin_parm, set_bottom_margin);
-#endif
-#if defined(set_left_margin_parm) && defined(set_left_margin)
- ANDMISSING(set_left_margin_parm, set_left_margin);
-#endif
-#if defined(set_right_margin_parm) && defined(set_right_margin)
- ANDMISSING(set_right_margin_parm, set_right_margin);
-#endif
-#if defined(set_top_margin_parm) && defined(set_top_margin)
- ANDMISSING(set_top_margin_parm, set_top_margin);
-#endif
-
+ /*
+ * If we have a parameterized form, then the non-parameterized is easy.
+ * note: parameterized/non-parameterized margin settings are unrelated.
+ */
#if defined(parm_down_micro) && defined(micro_down)
ANDMISSING(parm_down_micro, micro_down);
#endif
@@ -1703,10 +1707,11 @@ check_screen(TERMTYPE2 *tp)
int have_bce = back_color_erase;
bool have_kmouse = FALSE;
bool use_sgr_39_49 = FALSE;
+ const char *name_39_49 = "orig_pair or orig_colors";
char *name = _nc_first_name(tp->term_names);
bool is_screen = !strncmp(name, "screen", 6);
bool screen_base = (is_screen
- && strchr(name, '.') == 0);
+ && strchr(name, '.') == NULL);
if (!VALID_BOOLEAN(have_bce)) {
have_bce = FALSE;
@@ -1720,10 +1725,15 @@ check_screen(TERMTYPE2 *tp)
if (VALID_STRING(key_mouse)) {
have_kmouse = !strcmp("\033[M", key_mouse);
}
- if (VALID_STRING(orig_colors)) {
- use_sgr_39_49 = uses_SGR_39_49(orig_colors);
- } else if (VALID_STRING(orig_pair)) {
- use_sgr_39_49 = uses_SGR_39_49(orig_pair);
+ if (have_bce) {
+ if (VALID_STRING(orig_pair)) {
+ name_39_49 = "orig_pair";
+ use_sgr_39_49 = uses_SGR_39_49(orig_pair);
+ }
+ if (!use_sgr_39_49 && VALID_STRING(orig_colors)) {
+ name_39_49 = "orig_colors";
+ use_sgr_39_49 = uses_SGR_39_49(orig_colors);
+ }
}
if (have_XM && have_XT) {
@@ -1738,16 +1748,20 @@ check_screen(TERMTYPE2 *tp)
_nc_warning("expected kmous capability with XT");
}
}
- if (!have_bce && max_colors > 0)
- _nc_warning("expected bce capability with XT");
- if (!use_sgr_39_49 && have_bce && max_colors > 0)
- _nc_warning("expected orig_colors capability with XT to have 39/49 parameters");
+ if (max_colors > 0) {
+ if (!have_bce) {
+ _nc_warning("expected bce capability with XT");
+ } else if (!use_sgr_39_49) {
+ _nc_warning("expected %s capability with XT "
+ "to have 39/49 parameters", name_39_49);
+ }
+ }
if (VALID_STRING(to_status_line))
_nc_warning("\"tsl\" capability is redundant, given XT");
} else {
if (have_kmouse
&& !have_XM
- && !screen_base && strchr(name, '+') == 0) {
+ && !screen_base && strchr(name, '+') == NULL) {
_nc_warning("expected XT to be set, given kmous");
}
}
@@ -1835,7 +1849,6 @@ expected_params(const char *name)
DATA( "wingo", 1 ),
};
/* *INDENT-ON* */
-
#undef DATA
unsigned n;
@@ -1899,27 +1912,86 @@ is_user_capability(const char *name)
return result;
}
+static bool
+line_capability(const char *name)
+{
+ bool result = FALSE;
+ static const char *table[] =
+ {
+ "csr", /* change_scroll_region */
+ "clear", /* clear_screen */
+ "ed", /* clr_eos */
+ "cwin", /* create_window */
+ "cup", /* cursor_address */
+ "cud1", /* cursor_down */
+ "home", /* cursor_home */
+ "mrcup", /* cursor_mem_address */
+ "ll", /* cursor_to_ll */
+ "cuu1", /* cursor_up */
+ "dl1", /* delete_line */
+ "hd", /* down_half_line */
+ "flash", /* flash_screen */
+ "ff", /* form_feed */
+ "il1", /* insert_line */
+ "nel", /* newline */
+ "dl", /* parm_delete_line */
+ "cud", /* parm_down_cursor */
+ "indn", /* parm_index */
+ "il", /* parm_insert_line */
+ "rin", /* parm_rindex */
+ "cuu", /* parm_up_cursor */
+ "mc0", /* print_screen */
+ "vpa", /* row_address */
+ "ind", /* scroll_forward */
+ "ri", /* scroll_reverse */
+ "hu", /* up_half_line */
+ };
+ size_t n;
+ for (n = 0; n < SIZEOF(table); ++n) {
+ if (!strcmp(name, table[n])) {
+ result = TRUE;
+ break;
+ }
+ }
+ return result;
+}
+
/*
* Make a quick sanity check for the parameters which are used in the given
* strings. If there are no "%p" tokens, then there should be no other "%"
* markers.
*/
static void
-check_params(TERMTYPE2 *tp, const char *name, char *value, int extended)
+check_params(TERMTYPE2 *tp, const char *name, const char *value, int extended)
{
int expected = expected_params(name);
int actual = 0;
int n;
- bool params[NUM_PARM];
- char *s = value;
+ bool params[1 + NUM_PARM];
+ const char *s = value;
+#ifdef set_left_margin_parm
+ if (!strcmp(name, "smgrp")
+ && !VALID_STRING(set_left_margin_parm))
+ expected = 2;
+#endif
+#ifdef set_right_margin_parm
+ if (!strcmp(name, "smglp")
+ && !VALID_STRING(set_right_margin_parm))
+ expected = 2;
+#endif
#ifdef set_top_margin_parm
if (!strcmp(name, "smgbp")
- && set_top_margin_parm == 0)
+ && !VALID_STRING(set_top_margin_parm))
+ expected = 2;
+#endif
+#ifdef set_bottom_margin_parm
+ if (!strcmp(name, "smgtp")
+ && !VALID_STRING(set_bottom_margin_parm))
expected = 2;
#endif
- for (n = 0; n < NUM_PARM; n++)
+ for (n = 0; n <= NUM_PARM; n++)
params[n] = FALSE;
while (*s != 0) {
@@ -1977,10 +2049,11 @@ check_params(TERMTYPE2 *tp, const char *name, char *value, int extended)
* may not have been fully translated. Also, tparm does its own analysis.
* Report differences here.
*/
+ _nc_reset_tparm(NULL);
if (actual >= 0) {
char *p_is_s[NUM_PARM];
int popcount;
- int analyzed = _nc_tparm_analyze(value, p_is_s, &popcount);
+ int analyzed = _nc_tparm_analyze(NULL, value, p_is_s, &popcount);
if (analyzed < popcount) {
analyzed = popcount;
}
@@ -1998,54 +2071,37 @@ check_params(TERMTYPE2 *tp, const char *name, char *value, int extended)
_nc_warning("tparm analyzed %d parameters for %s, expected %d",
analyzed, name, actual);
}
+ } else if (expected > 0
+ && actual == expected
+ && guess_tparm_type(expected, p_is_s) == Numbers) {
+ int limit = 1;
+
+ if (!strcmp(name, "setf")
+ || !strcmp(name, "setb")
+ || !strcmp(name, "setaf")
+ || !strcmp(name, "setab")) {
+ if ((limit = max_colors) > 256)
+ limit = 256;
+ } else if (line_capability(name)) {
+ limit = 24;
+ } else if (is_user_capability(name) < 0) {
+ limit = 80;
+ }
+ for (n = 0; n < limit; ++n) {
+ _nc_reset_tparm(NULL);
+ (void) TPARM_9(value, n, n, n, n, n, n, n, n, n);
+ if (_nc_tparm_err) {
+ _nc_warning("problem%s in tparm(%s, %d, ...)",
+ (_nc_tparm_err == 1) ? "" : "s",
+ name, n);
+ if (debug_level < 2)
+ break;
+ }
+ }
}
}
}
-static bool
-line_capability(const char *name)
-{
- bool result = FALSE;
- static const char *table[] =
- {
- "csr", /* change_scroll_region */
- "clear", /* clear_screen */
- "ed", /* clr_eos */
- "cwin", /* create_window */
- "cup", /* cursor_address */
- "cud1", /* cursor_down */
- "home", /* cursor_home */
- "mrcup", /* cursor_mem_address */
- "ll", /* cursor_to_ll */
- "cuu1", /* cursor_up */
- "dl1", /* delete_line */
- "hd", /* down_half_line */
- "flash", /* flash_screen */
- "ff", /* form_feed */
- "il1", /* insert_line */
- "nel", /* newline */
- "dl", /* parm_delete_line */
- "cud", /* parm_down_cursor */
- "indn", /* parm_index */
- "il", /* parm_insert_line */
- "rin", /* parm_rindex */
- "cuu", /* parm_up_cursor */
- "mc0", /* print_screen */
- "vpa", /* row_address */
- "ind", /* scroll_forward */
- "ri", /* scroll_reverse */
- "hu", /* up_half_line */
- };
- size_t n;
- for (n = 0; n < SIZEOF(table); ++n) {
- if (!strcmp(name, table[n])) {
- result = TRUE;
- break;
- }
- }
- return result;
-}
-
/*
* Check for DEC VT100 private mode for reverse video.
*/
@@ -2080,7 +2136,6 @@ check_delays(TERMTYPE2 *tp, const char *name, const char *value)
if (p[0] == '$' && p[1] == '<') {
const char *base = p + 2;
const char *mark = 0;
- bool maybe = TRUE;
bool mixed = FALSE;
int proportional = 0;
int mandatory = 0;
@@ -2089,7 +2144,7 @@ check_delays(TERMTYPE2 *tp, const char *name, const char *value)
for (q = base; *q != '\0'; ++q) {
if (*q == '>') {
- if (mark == 0)
+ if (mark == NULL)
mark = q;
break;
} else if (*q == '*' || *q == '/') {
@@ -2097,23 +2152,20 @@ check_delays(TERMTYPE2 *tp, const char *name, const char *value)
++proportional;
if (*q == '/')
++mandatory;
- if (mark == 0)
+ if (mark == NULL)
mark = q;
} else if (!(isalnum(UChar(*q)) || strchr("+-.", *q) != 0)) {
- maybe = FALSE;
break;
} else if (proportional || mandatory) {
mixed = TRUE;
}
}
last = *q ? (q + 1) : q;
- if (*q == '\0') {
- maybe = FALSE; /* just an isolated "$<" */
- } else if (maybe) {
+ if (*q != '\0') {
float check_f;
char check_c;
int rc = sscanf(base, "%f%c", &check_f, &check_c);
- if ((rc != 2) || (check_c != *mark) || mixed) {
+ if ((rc != 2) || (mark != NULL && (check_c != *mark)) || mixed) {
_nc_warning("syntax error in %s delay '%.*s'", name,
(int) (q - base), base);
} else if (*name == 'k') {
@@ -2122,7 +2174,7 @@ check_delays(TERMTYPE2 *tp, const char *name, const char *value)
_nc_warning("non-line capability using proportional delay: %s", name);
} else if (!xon_xoff &&
!mandatory &&
- strchr(_nc_first_name(tp->term_names), '+') == 0) {
+ strchr(_nc_first_name(tp->term_names), '+') == NULL) {
_nc_warning("%s in %s is used since no xon/xoff",
(proportional
? "proportional delay"
@@ -2154,7 +2206,7 @@ check_delays(TERMTYPE2 *tp, const char *name, const char *value)
*/
if ((p = skip_DECSCNM(value, &flag)) != 0 &&
flag > 0 &&
- (q = skip_DECSCNM(p, &flag)) != 0 &&
+ skip_DECSCNM(p, &flag) != 0 &&
flag == 0) {
_nc_warning("expected a delay in %s", name);
}
@@ -2173,6 +2225,9 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
char *result;
char blob[NUM_PARM * 10];
char *next = blob;
+ TParams expect;
+ TParams actual;
+ int nparam;
*next++ = '\0';
for (k = 1; k <= NUM_PARM; k++) {
@@ -2184,7 +2239,18 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
next += strlen(next) + 1;
}
- switch (tparm_type(name)) {
+ _nc_reset_tparm(NULL);
+ expect = tparm_type(name);
+ nparam = _nc_tparm_analyze(NULL, value, p_is_s, &ignored);
+ actual = guess_tparm_type(nparam, p_is_s);
+
+ if (expect != actual) {
+ _nc_warning("%s has mismatched parameters", name);
+ actual = Other;
+ }
+
+ _nc_reset_tparm(NULL);
+ switch (actual) {
case Num_Str:
result = TPARM_2(value, numbers[1], strings[2]);
break;
@@ -2192,8 +2258,21 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
result = TPARM_3(value, numbers[1], strings[2], strings[3]);
break;
case Numbers:
+#define myParam(n) numbers[n]
+ result = TIPARM_9(value,
+ myParam(1),
+ myParam(2),
+ myParam(3),
+ myParam(4),
+ myParam(5),
+ myParam(6),
+ myParam(7),
+ myParam(8),
+ myParam(9));
+#undef myParam
+ break;
+ case Other:
default:
- (void) _nc_tparm_analyze(value, p_is_s, &ignored);
#define myParam(n) (p_is_s[n - 1] != 0 ? ((TPARM_ARG) strings[n]) : numbers[n])
result = TPARM_9(value,
myParam(1),
@@ -2205,6 +2284,7 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
myParam(7),
myParam(8),
myParam(9));
+#undef myParam
break;
}
return strdup(result);
@@ -2234,7 +2314,7 @@ parse_delay_value(const char *src, double *delays, int *always)
}
}
while (*src == '*' || *src == '/') {
- if (always == 0 && *src == '/')
+ if (always == NULL && *src == '/')
break;
if (*src++ == '*') {
star = 1;
@@ -2339,14 +2419,13 @@ check_infotocap(TERMTYPE2 *tp, int i, const char *value)
? parametrized[i]
: ((*value == 'k')
? 0
- : has_params(value)));
- int to_char = 0;
- char *ti_value;
+ : has_params(value, FALSE)));
+ char *ti_value = NULL;
char *tc_value;
bool embedded;
assert(SIZEOF(parametrized) == STRCOUNT);
- if ((ti_value = _nc_tic_expand(value, TRUE, to_char)) == ABSENT_STRING) {
+ if (!VALID_STRING(value) || (ti_value = strdup(value)) == NULL) {
_nc_warning("tic-expansion of %s failed", name);
} else if ((tc_value = _nc_infotocap(name, ti_value, params)) == ABSENT_STRING) {
_nc_warning("tic-conversion of %s failed", name);
@@ -2359,8 +2438,8 @@ check_infotocap(TERMTYPE2 *tp, int i, const char *value)
|| !strcmp(name, "setb")
|| !strcmp(name, "setaf")
|| !strcmp(name, "setab")) {
- if ((limit = max_colors) > 16)
- limit = 16;
+ if ((limit = max_colors) > 256)
+ limit = 256;
}
for (count = 0; count < limit; ++count) {
char *ti_check = check_1_infotocap(name, ti_value, count);
@@ -2369,12 +2448,14 @@ check_infotocap(TERMTYPE2 *tp, int i, const char *value)
if (strcmp(ti_check, tc_check)) {
if (first) {
fprintf(stderr, "check_infotocap(%s)\n", name);
- fprintf(stderr, "...ti '%s'\n", ti_value);
- fprintf(stderr, "...tc '%s'\n", tc_value);
+ fprintf(stderr, "...ti '%s'\n", _nc_visbuf2(0, ti_value));
+ fprintf(stderr, "...tc '%s'\n", _nc_visbuf2(0, tc_value));
first = FALSE;
}
_nc_warning("tparm-conversion of %s(%d) differs between\n\tterminfo %s\n\ttermcap %s",
- name, count, ti_check, tc_check);
+ name, count,
+ _nc_visbuf2(0, ti_check),
+ _nc_visbuf2(1, tc_check));
}
free(ti_check);
free(tc_check);
@@ -2387,6 +2468,7 @@ check_infotocap(TERMTYPE2 *tp, int i, const char *value)
name, ti_value, tc_value);
}
}
+ free(ti_value);
}
static char *
@@ -2509,22 +2591,29 @@ similar_sgr(int num, char *a, char *b)
return ((num != 0) || (*a == 0));
}
+static void
+check_tparm_err(int num)
+{
+ if (_nc_tparm_err)
+ _nc_warning("tparam error in sgr(%d): %s", num, sgr_names[num]);
+}
+
static char *
check_sgr(TERMTYPE2 *tp, char *zero, int num, char *cap, const char *name)
{
char *test;
_nc_tparm_err = 0;
- test = TPARM_9(set_attributes,
- num == 1,
- num == 2,
- num == 3,
- num == 4,
- num == 5,
- num == 6,
- num == 7,
- num == 8,
- num == 9);
+ test = TIPARM_9(set_attributes,
+ num == 1,
+ num == 2,
+ num == 3,
+ num == 4,
+ num == 5,
+ num == 6,
+ num == 7,
+ num == 8,
+ num == 9);
if (test != 0) {
if (PRESENT(cap)) {
if (!similar_sgr(num, test, cap)) {
@@ -2539,8 +2628,7 @@ check_sgr(TERMTYPE2 *tp, char *zero, int num, char *cap, const char *name)
} else if (PRESENT(cap)) {
_nc_warning("sgr(%d) missing, but %s present", num, name);
}
- if (_nc_tparm_err)
- _nc_warning("stack error in sgr(%d) string", num);
+ check_tparm_err(num);
return test;
}
@@ -2583,7 +2671,7 @@ get_fkey_list(TERMTYPE2 *tp)
int used = 0;
unsigned j;
- if (result == 0)
+ if (result == NULL)
failed("get_fkey_list");
for (j = 0; all_fkeys[j].code; j++) {
@@ -2630,13 +2718,13 @@ static void
check_conflict(TERMTYPE2 *tp)
{
bool conflict = FALSE;
- unsigned j, k;
if (!(_nc_syntax == SYN_TERMCAP && capdump)) {
char *check = calloc((size_t) (NUM_STRINGS(tp) + 1), sizeof(char));
NAME_VALUE *given = get_fkey_list(tp);
+ unsigned j, k;
- if (check == 0)
+ if (check == NULL)
failed("check_conflict");
for (j = 0; given[j].keycode; ++j) {
@@ -2695,7 +2783,6 @@ check_conflict(TERMTYPE2 *tp)
{ NULL, NULL },
};
/* *INDENT-ON* */
-
/*
* SVr4 curses defines the "xcurses" names listed above except for
* the special cases in the "shifted" column. When using these
@@ -2973,10 +3060,9 @@ check_termtype(TERMTYPE2 *tp, bool literal)
if (PRESENT(exit_attribute_mode)) {
zero = strdup(CHECK_SGR(0, exit_attribute_mode));
} else {
- zero = strdup(TPARM_9(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ zero = strdup(TIPARM_9(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, 0));
}
- if (_nc_tparm_err)
- _nc_warning("stack error in sgr(0) string");
+ check_tparm_err(0);
if (zero != 0) {
CHECK_SGR(1, enter_standout_mode);
@@ -3001,7 +3087,7 @@ check_termtype(TERMTYPE2 *tp, bool literal)
if (PRESENT(exit_attribute_mode)) {
char *check_sgr0 = _nc_trim_sgr0(tp);
- if (check_sgr0 == 0 || *check_sgr0 == '\0') {
+ if (check_sgr0 == NULL || *check_sgr0 == '\0') {
_nc_warning("trimmed sgr0 is empty");
} else {
show_where(2);
diff --git a/progs/toe.c b/progs/toe.c
index f3856f0..92819c1 100644
--- a/progs/toe.c
+++ b/progs/toe.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2018,2020 Thomas E. Dickey *
+ * Copyright 2018-2020,2021 Thomas E. Dickey *
* Copyright 1998-2013,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -45,7 +45,7 @@
#include <hashed_db.h>
#endif
-MODULE_ID("$Id: toe.c,v 1.79 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: toe.c,v 1.86 2021/10/10 00:55:32 tom Exp $")
#define isDotname(name) (!strcmp(name, ".") || !strcmp(name, ".."))
@@ -64,7 +64,7 @@ static size_t len_termdata; /* allocated size of ptr_termdata[] */
#if NO_LEAKS
#undef ExitProgram
-static void ExitProgram(int code) GCC_NORETURN;
+static GCC_NORETURN void ExitProgram(int code);
static void
ExitProgram(int code)
{
@@ -73,7 +73,7 @@ ExitProgram(int code)
}
#endif
-static void failed(const char *) GCC_NORETURN;
+static GCC_NORETURN void failed(const char *);
static void
failed(const char *msg)
@@ -127,12 +127,15 @@ compare_termdata(const void *a, const void *b)
static void
show_termdata(int eargc, char **eargv)
{
- int j, k;
- size_t n;
-
if (use_termdata) {
+ size_t n;
+
if (eargc > 1) {
+ int j;
+
for (j = 0; j < eargc; ++j) {
+ int k;
+
for (k = 0; k <= j; ++k) {
printf("--");
}
@@ -143,14 +146,20 @@ show_termdata(int eargc, char **eargv)
if (use_termdata > 1)
qsort(ptr_termdata, use_termdata, sizeof(TERMDATA), compare_termdata);
for (n = 0; n < use_termdata; ++n) {
+ int nk = -1;
/*
* If there is more than one database, show how they differ.
*/
if (eargc > 1) {
unsigned long check = 0;
- k = 0;
+ int k = 0;
for (;;) {
+ char mark = ((check == 0
+ || (check != ptr_termdata[n].checksum))
+ ? '*'
+ : '+');
+
for (; k < ptr_termdata[n].db_index; ++k) {
printf("--");
}
@@ -160,11 +169,10 @@ show_termdata(int eargc, char **eargv)
* from the first entry's checksum, print "*". Otherwise
* it looks enough like a duplicate to print "+".
*/
- printf("%c-", ((check == 0
- || (check != ptr_termdata[n].checksum))
- ? '*'
- : '+'));
+ printf("%c-", mark);
check = ptr_termdata[n].checksum;
+ if (mark == '*' && nk < 0)
+ nk = (int) n;
++k;
if ((n + 1) >= use_termdata
@@ -179,10 +187,12 @@ show_termdata(int eargc, char **eargv)
}
printf(":\t");
}
+ if (nk < 0)
+ nk = (int) n;
(void) printf("%-10s\t%s\n",
ptr_termdata[n].term_name,
- ptr_termdata[n].description);
+ ptr_termdata[nk].description);
}
}
}
@@ -242,7 +252,9 @@ make_db_name(char *dst, const char *src, unsigned limit)
&& !strcmp(src + size - lens, suffix)) {
_nc_STRCPY(dst, src, PATH_MAX);
} else {
- _nc_SPRINTF(dst, _nc_SLIMIT(PATH_MAX) "%s%s", src, suffix);
+ _nc_SPRINTF(dst, _nc_SLIMIT(PATH_MAX) "%.*s%s",
+ (int) (PATH_MAX - sizeof(suffix)),
+ src, suffix);
}
result = TRUE;
}
@@ -325,6 +337,26 @@ sorthook(int db_index, int db_limit, const char *term_name, TERMTYPE2 *tp)
}
#if NCURSES_USE_TERMCAP
+/*
+ * Check if the buffer contents are printable ASCII, ensuring that we do not
+ * accidentally pick up incompatible binary content from a hashed database.
+ */
+static bool
+is_termcap(char *buffer)
+{
+ bool result = TRUE;
+ while (*buffer != '\0') {
+ int ch = UChar(*buffer++);
+ if (ch == '\t')
+ continue;
+ if (ch < ' ' || ch > '~') {
+ result = FALSE;
+ break;
+ }
+ }
+ return result;
+}
+
static void
show_termcap(int db_index, int db_limit, char *buffer, DescHook hook)
{
@@ -513,11 +545,13 @@ typelist(int eargc, char *eargv[],
db_array[1] = 0;
if (cgetfirst(&buffer, db_array) > 0) {
- show_termcap(i, eargc, buffer, hook);
- free(buffer);
- while (cgetnext(&buffer, db_array) > 0) {
+ if (is_termcap(buffer)) {
show_termcap(i, eargc, buffer, hook);
free(buffer);
+ while (cgetnext(&buffer, db_array) > 0) {
+ show_termcap(i, eargc, buffer, hook);
+ free(buffer);
+ }
}
cgetclose();
continue;
@@ -532,8 +566,10 @@ typelist(int eargc, char *eargv[],
if (verbosity)
(void) printf("#\n#%s:\n#\n", eargv[i]);
- if ((fp = fopen(eargv[i], "r")) != 0) {
+ if ((fp = safe_fopen(eargv[i], "r")) != 0) {
while (fgets(buffer, sizeof(buffer), fp) != 0) {
+ if (!is_termcap(buffer))
+ break;
if (*buffer == '#')
continue;
if (isspace(*buffer))
@@ -570,7 +606,6 @@ main(int argc, char *argv[])
bool invert_dependencies = FALSE;
bool header = FALSE;
char *report_file = 0;
- unsigned i;
int code;
int this_opt, last_opt = '?';
unsigned v_opt = 0;
@@ -658,11 +693,13 @@ main(int argc, char *argv[])
/* maybe we want a reverse-dependency listing? */
if (invert_dependencies) {
ENTRY *qp, *rp;
- int matchcount;
for_entry_list(qp) {
- matchcount = 0;
+ int matchcount = 0;
+
for_entry_list(rp) {
+ unsigned i;
+
if (rp->nuses == 0)
continue;
@@ -692,12 +729,12 @@ main(int argc, char *argv[])
DBDIRS state;
int offset;
int pass;
- const char *path;
char **eargv = 0;
code = EXIT_FAILURE;
for (pass = 0; pass < 2; ++pass) {
size_t count = 0;
+ const char *path;
_nc_first_db(&state, &offset);
while ((path = _nc_next_db(&state, &offset)) != 0) {
diff --git a/progs/tparm_type.c b/progs/tparm_type.c
index da681ce..3da4a07 100644
--- a/progs/tparm_type.c
+++ b/progs/tparm_type.c
@@ -33,7 +33,7 @@
#include <tparm_type.h>
-MODULE_ID("$Id: tparm_type.c,v 1.3 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: tparm_type.c,v 1.4 2020/10/24 17:30:32 tom Exp $")
/*
* Lookup the type of call we should make to tparm(). This ignores the actual
@@ -70,3 +70,31 @@ tparm_type(const char *name)
}
return result;
}
+
+TParams
+guess_tparm_type(int nparam, char **p_is_s)
+{
+ TParams result = Other;
+ switch (nparam) {
+ case 0:
+ case 1:
+ if (!p_is_s[0])
+ result = Numbers;
+ break;
+ case 2:
+ if (!p_is_s[0] && !p_is_s[1])
+ result = Numbers;
+ if (!p_is_s[0] && p_is_s[1])
+ result = Num_Str;
+ break;
+ case 3:
+ if (!p_is_s[0] && !p_is_s[1] && !p_is_s[2])
+ result = Numbers;
+ if (!p_is_s[0] && p_is_s[1] && p_is_s[2])
+ result = Num_Str_Str;
+ break;
+ default:
+ break;
+ }
+ return result;
+}
diff --git a/progs/tparm_type.h b/progs/tparm_type.h
index 77f4f21..7c102a3 100644
--- a/progs/tparm_type.h
+++ b/progs/tparm_type.h
@@ -32,7 +32,7 @@
****************************************************************************/
/*
- * $Id: tparm_type.h,v 1.2 2020/02/02 23:34:34 tom Exp $
+ * $Id: tparm_type.h,v 1.3 2020/10/24 17:11:33 tom Exp $
*
* determine expected/actual number of parameters to setup for tparm
*/
@@ -43,11 +43,13 @@
#include <progs.priv.h>
typedef enum {
- Numbers = 0
+ Other = -1
+ ,Numbers = 0
,Num_Str
,Num_Str_Str
} TParams;
extern TParams tparm_type(const char *name);
+extern TParams guess_tparm_type(int nparam, char **p_is_s);
#endif /* TPARM_TYPE_H */
diff --git a/progs/tput.c b/progs/tput.c
index 295b83f..8ac478e 100644
--- a/progs/tput.c
+++ b/progs/tput.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2018-2019,2020 Thomas E. Dickey *
+ * Copyright 2018-2020,2021 Thomas E. Dickey *
* Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -44,39 +44,34 @@
#include <clear_cmd.h>
#include <reset_cmd.h>
-#if !PURE_TERMINFO
-#include <dump_entry.h>
-#include <termsort.c>
-#endif
#include <transform.h>
#include <tty_settings.h>
-MODULE_ID("$Id: tput.c,v 1.81 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: tput.c,v 1.97 2021/10/02 18:09:23 tom Exp $")
#define PUTS(s) fputs(s, stdout)
const char *_nc_progname = "tput";
-static char *prg_name;
static bool is_init = FALSE;
static bool is_reset = FALSE;
static bool is_clear = FALSE;
-static void
-quit(int status, const char *fmt,...)
+static GCC_NORETURN void
+quit(int status, const char *fmt, ...)
{
va_list argp;
va_start(argp, fmt);
- fprintf(stderr, "%s: ", prg_name);
+ fprintf(stderr, "%s: ", _nc_progname);
vfprintf(stderr, fmt, argp);
fprintf(stderr, "\n");
va_end(argp);
ExitProgram(status);
}
-static void
-usage(void)
+static GCC_NORETURN void
+usage(const char *optstring)
{
#define KEEP(s) s "\n"
static const char msg[] =
@@ -95,8 +90,21 @@ usage(void)
KEEP(" capname unlike clear/init/reset, print value for capability \"capname\"")
};
#undef KEEP
- (void) fprintf(stderr, "Usage: %s [options] [command]\n", prg_name);
- fputs(msg, stderr);
+ (void) fprintf(stderr, "Usage: %s [options] [command]\n", _nc_progname);
+ if (optstring != NULL) {
+ const char *s = msg;
+ while (*s != '\0') {
+ fputc(UChar(*s), stderr);
+ if (!strncmp(s, " -", 3)) {
+ if (strchr(optstring, s[3]) == NULL)
+ s = strchr(s, '\n') + 1;
+ } else if (!strncmp(s, "\n\nC", 3))
+ break;
+ ++s;
+ }
+ } else {
+ fputs(msg, stderr);
+ }
ExitProgram(ErrUsage);
}
@@ -140,7 +148,7 @@ exit_code(int token, int value)
* Returns nonzero on error.
*/
static int
-tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
+tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
{
NCURSES_CONST char *name;
char *s;
@@ -150,6 +158,7 @@ tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
#endif
name = check_aliases(argv[0], FALSE);
+ *used = 1;
if (is_reset || is_init) {
TTY oldmode;
@@ -159,7 +168,7 @@ tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
if (is_reset) {
reset_start(stdout, TRUE, FALSE);
- reset_tty_settings(fd, saved_settings);
+ reset_tty_settings(fd, settings, FALSE);
} else {
reset_start(stdout, FALSE, TRUE);
}
@@ -169,13 +178,13 @@ tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
#else
(void) fd;
#endif
- set_control_chars(saved_settings, terasechar, intrchar, tkillchar);
- set_conversions(saved_settings);
+ set_control_chars(settings, terasechar, intrchar, tkillchar);
+ set_conversions(settings);
if (send_init_strings(fd, &oldmode)) {
reset_flush();
}
- update_tty_settings(&oldmode, saved_settings);
+ update_tty_settings(&oldmode, settings);
return 0;
}
@@ -221,17 +230,19 @@ tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
} else if (VALID_STRING(s)) {
if (argc > 1) {
int k;
- int ignored;
+ int analyzed;
+ int popcount;
long numbers[1 + NUM_PARM];
char *strings[1 + NUM_PARM];
char *p_is_s[NUM_PARM];
+ TParams paramType;
/* Nasty hack time. The tparm function needs to see numeric
* parameters as numbers, not as pointers to their string
* representations
*/
- for (k = 1; (k < argc) && (k < NUM_PARM); k++) {
+ for (k = 1; (k < argc) && (k <= NUM_PARM); k++) {
char *tmp = 0;
strings[k] = argv[k];
numbers[k] = strtol(argv[k], &tmp, 0);
@@ -243,16 +254,50 @@ tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
strings[k] = 0;
}
- switch (tparm_type(name)) {
+ paramType = tparm_type(name);
+#if NCURSES_XNAMES
+ /*
+ * If the capability is an extended one, analyze the string.
+ */
+ if (paramType == Numbers) {
+ struct name_table_entry const *entry_ptr;
+ entry_ptr = _nc_find_type_entry(name, STRING, FALSE);
+ if (entry_ptr == NULL) {
+ paramType = Other;
+ }
+ }
+#endif
+
+ popcount = 0;
+ _nc_reset_tparm(NULL);
+ switch (paramType) {
case Num_Str:
s = TPARM_2(s, numbers[1], strings[2]);
+ analyzed = 2;
break;
case Num_Str_Str:
s = TPARM_3(s, numbers[1], strings[2], strings[3]);
+ analyzed = 3;
break;
case Numbers:
+ analyzed = _nc_tparm_analyze(NULL, s, p_is_s, &popcount);
+#define myParam(n) numbers[n]
+ s = TIPARM_9(s,
+ myParam(1),
+ myParam(2),
+ myParam(3),
+ myParam(4),
+ myParam(5),
+ myParam(6),
+ myParam(7),
+ myParam(8),
+ myParam(9));
+#undef myParam
+ break;
+ case Other:
+ /* FALLTHRU */
default:
- (void) _nc_tparm_analyze(s, p_is_s, &ignored);
+ analyzed = _nc_tparm_analyze(NULL, s, p_is_s, &popcount);
#define myParam(n) (p_is_s[n - 1] != 0 ? ((TPARM_ARG) strings[n]) : numbers[n])
s = TPARM_9(s,
myParam(1),
@@ -264,8 +309,13 @@ tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
myParam(7),
myParam(8),
myParam(9));
+#undef myParam
break;
}
+ if (analyzed < popcount) {
+ analyzed = popcount;
+ }
+ *used += analyzed;
}
/* use putp() in order to perform padding */
@@ -285,16 +335,18 @@ main(int argc, char **argv)
char buf[BUFSIZ];
int result = 0;
int fd;
+ int used;
TTY tty_settings;
bool opt_x = FALSE; /* clear scrollback if possible */
bool is_alias;
bool need_tty;
- prg_name = check_aliases(_nc_rootname(argv[0]), TRUE);
+ _nc_progname = check_aliases(_nc_rootname(argv[0]), TRUE);
+ is_alias = (is_clear || is_reset || is_init);
term = getenv("TERM");
- while ((c = getopt(argc, argv, "ST:Vx")) != -1) {
+ while ((c = getopt(argc, argv, is_alias ? "T:Vx" : "ST:Vx")) != -1) {
switch (c) {
case 'S':
cmdline = FALSE;
@@ -311,12 +363,11 @@ main(int argc, char **argv)
opt_x = TRUE;
break;
default:
- usage();
+ usage(is_alias ? "TVx" : NULL);
/* NOTREACHED */
}
}
- is_alias = (is_clear || is_reset || is_init);
need_tty = ((is_reset || is_init) ||
(optind < argc &&
(!strcmp(argv[optind], "reset") ||
@@ -330,7 +381,7 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
}
- argv[0] = prg_name;
+ argv[0] = strdup(_nc_progname);
} else {
argc -= optind;
argv += optind;
@@ -345,34 +396,53 @@ main(int argc, char **argv)
quit(ErrTermType, "unknown terminal \"%s\"", term);
if (cmdline) {
+ int code = 0;
if ((argc <= 0) && !is_alias)
- usage();
- ExitProgram(tput_cmd(fd, &tty_settings, opt_x, argc, argv));
+ usage(NULL);
+ while (argc > 0) {
+ code = tput_cmd(fd, &tty_settings, opt_x, argc, argv, &used);
+ if (code != 0)
+ break;
+ argc -= used;
+ argv += used;
+ }
+ ExitProgram(code);
}
while (fgets(buf, sizeof(buf), stdin) != 0) {
- char *argvec[16]; /* command, 9 parms, null, & slop */
+ size_t need = strlen(buf);
+ char **argvec = typeCalloc(char *, need + 1);
+ char **argnow;
int argnum = 0;
char *cp;
- /* crack the argument list into a dope vector */
+ if (argvec == NULL) {
+ quit(ErrSystem(1), strerror(errno));
+ }
+
+ /* split the buffer into tokens */
for (cp = buf; *cp; cp++) {
if (isspace(UChar(*cp))) {
*cp = '\0';
- } else if (cp == buf || cp[-1] == 0) {
+ } else if (cp == buf || cp[-1] == '\0') {
argvec[argnum++] = cp;
- if (argnum >= (int) SIZEOF(argvec) - 1)
+ if (argnum >= (int) need)
break;
}
}
- argvec[argnum] = 0;
- if (argnum != 0
- && tput_cmd(fd, &tty_settings, opt_x, argnum, argvec) != 0) {
- if (result == 0)
- result = ErrSystem(0); /* will return value >4 */
- ++result;
+ argnow = argvec;
+ while (argnum > 0) {
+ int code = tput_cmd(fd, &tty_settings, opt_x, argnum, argnow, &used);
+ if (code != 0) {
+ if (result == 0)
+ result = ErrSystem(0); /* will return value >4 */
+ ++result;
+ }
+ argnum -= used;
+ argnow += used;
}
+ free(argvec);
}
ExitProgram(result);
diff --git a/progs/tset.c b/progs/tset.c
index ca0520e..62611b3 100644
--- a/progs/tset.c
+++ b/progs/tset.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2020,2021 Thomas E. Dickey *
* Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -98,7 +98,7 @@
char *ttyname(int fd);
#endif
-MODULE_ID("$Id: tset.c,v 1.121 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: tset.c,v 1.130 2021/10/02 18:08:09 tom Exp $")
#ifndef environ
extern char **environ;
@@ -108,7 +108,7 @@ const char *_nc_progname = "tset";
#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
-static void exit_error(void) GCC_NORETURN;
+static GCC_NORETURN void exit_error(void);
static int
CaselessCmp(const char *a, const char *b)
@@ -122,7 +122,7 @@ CaselessCmp(const char *a, const char *b)
return LOWERCASE(*a) - LOWERCASE(*b);
}
-static void
+static GCC_NORETURN void
exit_error(void)
{
restore_tty_settings();
@@ -132,8 +132,8 @@ exit_error(void)
/* NOTREACHED */
}
-static void
-err(const char *fmt,...)
+static GCC_NORETURN void
+err(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -144,7 +144,7 @@ err(const char *fmt,...)
/* NOTREACHED */
}
-static void
+static GCC_NORETURN void
failed(const char *msg)
{
char temp[BUFSIZ];
@@ -167,7 +167,6 @@ static const char *
askuser(const char *dflt)
{
static char answer[256];
- char *p;
/* We can get recalled; if so, don't continue uselessly. */
clearerr(stdin);
@@ -176,7 +175,10 @@ askuser(const char *dflt)
exit_error();
/* NOTREACHED */
}
+
for (;;) {
+ char *p;
+
if (dflt)
(void) fprintf(stderr, "Terminal type? [%s] ", dflt);
else
@@ -227,10 +229,16 @@ static MAP *cur, *maplist;
#define DATA(name,value) { { name }, value }
typedef struct speeds {
- const char string[7];
+ const char string[8];
int speed;
} SPEEDS;
+#if defined(EXP_WIN32_DRIVER)
+static const SPEEDS speeds[] =
+{
+ {"0", 0}
+};
+#else
static const SPEEDS speeds[] =
{
DATA("0", B0),
@@ -331,6 +339,7 @@ static const SPEEDS speeds[] =
#endif
};
#undef DATA
+#endif
static int
tbaudrate(char *rate)
@@ -766,7 +775,7 @@ main(int argc, char **argv)
bool opt_w = FALSE; /* set window-size */
TTY mode, oldmode;
- my_fd = STDERR_FILENO;
+ _nc_progname = _nc_rootname(*argv);
obsolete(argv);
noinit = noset = quiet = Sflag = sflag = showterm = 0;
while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQrSsVw")) != -1) {
@@ -825,7 +834,6 @@ main(int argc, char **argv)
}
}
- _nc_progname = _nc_rootname(*argv);
argc -= optind;
argv += optind;
@@ -839,13 +847,15 @@ main(int argc, char **argv)
oldmode = mode;
#ifdef TERMIOS
ospeed = (NCURSES_OSPEED) cfgetospeed(&mode);
+#elif defined(EXP_WIN32_DRIVER)
+ ospeed = 0;
#else
ospeed = (NCURSES_OSPEED) mode.sg_ospeed;
#endif
if (same_program(_nc_progname, PROG_RESET)) {
reset_start(stderr, TRUE, FALSE);
- reset_tty_settings(my_fd, &mode);
+ reset_tty_settings(my_fd, &mode, noset);
} else {
reset_start(stderr, FALSE, TRUE);
}
diff --git a/progs/tty_settings.c b/progs/tty_settings.c
index 274de9f..a9eb8cd 100644
--- a/progs/tty_settings.c
+++ b/progs/tty_settings.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright 2020 Thomas E. Dickey *
+ * Copyright 2020,2021 Thomas E. Dickey *
* Copyright 2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
@@ -36,7 +36,7 @@
#include <fcntl.h>
-MODULE_ID("$Id: tty_settings.c,v 1.6 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: tty_settings.c,v 1.7 2021/10/08 23:53:32 tom Exp $")
static int my_fd;
static TTY original_settings;
@@ -74,10 +74,12 @@ save_tty_settings(TTY * tty_settings, bool need_tty)
{
if (!get_tty_settings(STDERR_FILENO, tty_settings) &&
!get_tty_settings(STDOUT_FILENO, tty_settings) &&
- !get_tty_settings(STDIN_FILENO, tty_settings) &&
- !get_tty_settings(open("/dev/tty", O_RDWR), tty_settings)) {
+ !get_tty_settings(STDIN_FILENO, tty_settings)) {
if (need_tty) {
- failed("terminal attributes");
+ int fd = open("/dev/tty", O_RDWR);
+ if (!get_tty_settings(fd, tty_settings)) {
+ failed("terminal attributes");
+ }
} else {
my_fd = fileno(stdout);
}