How can we compare all available terminfo entries (full current compiled database) against a terminfo source file ?

The infocmp utility has the -F option but it needs two files to be compared, but there isn't an option to export all entries and generate a file of the full current database, it needs to be called to each entry and so export each one of the entries separately. If there was a way to export all entries at once, it would be done in two steps, calling infocmp twice (one to export all database, and another to compare the files)


You could compile the source into a new directory and use infocmp -d to compare each entries.

mkdir -p dir && cd dir
TERMINFO=$PWD tic -x /path/to/terminfo.src
for entry in */*; do
  infocmp -x -d -B "$PWD" "${entry#*/}" "${entry#*/}"

To print only the differences with the relevant context only, you could do:

mkdir -p dir && cd dir
TERMINFO=$PWD tic -x /path/to/terminfo.src
for entry in */*; do
  LC_ALL=C infocmp -x -d -B "$PWD" "${entry#*/}" "${entry#*/}" |
    awk '
      /^comparing/ {entry=$1" "$2; next}
      $1 == "comparing" {section=$0; next}
      entry {print entry; entry = 0}
      section {print section; section = 0}
  • infocmp doesn't return different exit codes when it find or not differences. So we need to parse the output to automate the process of getting just the differences. – Luciano Aug 8 '17 at 14:24
  • @Luciano, yes. See edit for a possible way to reduce the clutter for entries or sections that have not changed. – Stéphane Chazelas Aug 8 '17 at 14:46

I do it with this script (on Debian, for instance which presumes that kbs is ^?), to test local builds of ncurses:

# $Id: test-terminfo+,v 1.10 2012/04/21 15:52:17 tom Exp $
# vi:sw=4 ts=4
# Compile the given terminfo source-file(s) into a temporary directory, compare
# the compiled files against the system version.
if test $# = 0 ; then
        with-local-ncurses $0 terminfo terminfo.src
        PATH=$MY_NCURSES/bin:$PATH; export PATH
        unset TERMINFO_DIRS
        unset TERMINFO
        rm -rf $TMP
        trap "rm -rf $TMP" 0 1 2 3 15
        mkdir $TMP
        rm -f $TMP/terminfo.sed
        cat >$TMP/terminfo.sed <<EOF
/^xterm+kbs|fragment for backspace key, kbs=/s/kbs=^H,/kbs=^?,/
/^xterm+kbs|fragment for backspace key,\$/,/^#/{
        for name in $*
                if test -f "$name" ; then
                        sed -f $TMP/terminfo.sed $name >$TMP/source
                        TERMINFO=$TMP tic -U $OPTS -R ALL $TMP/source
        for name in $TMP/?/*
                base=`dirname $name`
                base=`basename $base`
                name=`basename $name`
                case $name in
                ??)     # ignore 2-char termcap names
                        if test -f "$TERMINFO/$base/$name" ; then
                                infocmp -U $OPTS -q -p -f -A $TERMINFO -B $TMP $name $name
                                echo missing "$name $base"

The log tells why some of the fine details matter:

revision 1.10                                                                                               
date: 2012/04/21 15:52:17;  author: tom;  state: Exp;  lines: +2 -3                                         
add -x                                                                                                      
revision 1.9                                                                                                
date: 2012/04/14 21:50:23;  author: tom;  state: Exp;  lines: +7 -4                                         
tweak to handle output from terminfo-uses script                                                            
revision 1.8                                                                                                
date: 2012/03/17 19:31:02;  author: tom;  state: Exp;  lines: +15 -4                                        
tweaks to make this compare more closely to what I've installed, by                                         
accounting for the pathnames used in cfg-local                                                              
revision 1.7                                                                                                
date: 2011/08/10 08:49:23;  author: tom;  state: Exp;  lines: +2 -2                                         
make this work with Solaris                                                                                 
revision 1.6                                                                                                
date: 2011/06/11 17:23:15;  author: tom;  state: Exp;  lines: +2 -2                                         
remove spurious "eval" when doing no-args                                                                   
revision 1.5                                                                                                
date: 2004/07/05 14:06:46;  author: tom;  state: Exp;  lines: +15 -7                                        
use -U option to simplify comparing termcap                                                                 
ignore 2-char termcap names                                                                                 
revision 1.4                                                                                                
date: 2004/01/31 17:42:01;  author: tom;  state: Exp;  lines: +2 -2                                         
ignore padding                                                                                              
revision 1.3                                                                                                
date: 2003/05/31 21:00:37;  author: tom;  state: Exp;  lines: +9 -5                                         
use local-ncurses rather than installed version                                                             
revision 1.2                                                                                                
date: 2002/06/22 22:31:53;  author: tom;  state: Exp;  lines: +1 -1                                         
add -p option                                                                                               
revision 1.1                                                                                                
date: 2001/05/19 20:07:23;  author: tom;  state: Exp

I check for differences (other than missing entries) by looking for tab characters.

As for why it is named test-terminfo+, that is because the original script (written in 1998) compared only against the system terminfo (there weren't any packages to avoid contaminating...).

As usual, it helps to read the manual pages:

  • It seems the ALL in -R ALL is not documented. Does that imply that without it, only a subset is generated? I can see -R is also an option of infocmp. Is it not needed there as well? – Stéphane Chazelas Aug 9 '17 at 7:17
  • What do you think of having infocmp -d reflect whether the two entries are the same or not in the exit status like for diff/cmp? – Stéphane Chazelas Aug 9 '17 at 7:19
  • There's pros/cons: while it might seem a good idea, copying the cmp/diff exit status would make it return a different code for failure than it does now, and would cause any existing script that checks the status to fail. That's because EXIT_FAILURE is (usually) defined to 1. – Thomas Dickey Aug 9 '17 at 8:26
  • With -R, the ALL value happens to work: only the documented values do a subset; anything else is the full set. Another to-do item :-) – Thomas Dickey Aug 9 '17 at 8:29
  • Looking at the code, it also looks like -I, -C, -r cancel the effect of -R which may be worth documenting (-C -r seems to also be different from -r -C) – Stéphane Chazelas Aug 9 '17 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.