lychee
lychee

Reputation: 1851

directly using terminal capabilities

Does anyone use terminfo capabilities functions like tputs(), tparm(), tigetstr(), tigetnum() directly anymore?

I can't find any practical examples online with these low-level terminal functions.

Does everyone uses ncurses library to control terminal and doesn't bother with this low-level code?

This low-level code is very hard to read I think.

Should I bother with this low-level code or just learn ncurses which is a lot less overwhelming with ncurses-provided higher-level code?

If anybody knows some practical info about such low-level functions, share with me.

Upvotes: 4

Views: 415

Answers (2)

Thomas Dickey
Thomas Dickey

Reputation: 54583

The script is a starting point, but needs improvement. First, to tell what it does:

  • "nm -D" lists the dynamic symbols, i.e., those which refer to an external library.
  • the first step gets the list of symbols from the ncurses library, and
  • filters it by looking for the pattern " T " which is found where a function name is defined.
  • after saving the result into a file /tmp/ncurses-functions-list, the second script tests each of the programs in /usr/bin
  • the filter pattern in the second script is for undefined symbols, i.e., those which come from another library
  • the result from filtering is a list of function (or data) names, which is then matched against the list made in the first step.

A way to improve it would be to show (as was requested originally) which programs use the low-level interface, and which use the high-level ncurses interface. As noted in the ncurses FAQ Types of library users the way to distinguish these is to see which programs call initscr or newterm (needed to initialize the high-level interface) and which do not. A simple "ldd" would show which programs are linked with ncurses (to give the total), and reducing the function list to those two would tell -- with the second script -- which used the high-level interface.

The above was my answer in February 2015. A few years later, I wrote a more ambitious script analyze-curses-symbols. Here is sample output for just the executables in my (Debian 11) beginning with "v":

?       /usr/bin/valgrind-di-server
?       /usr/bin/valgrind-listener
?       /usr/bin/valgrind.bin
?       /usr/bin/vcd-info
?       /usr/bin/vcdimager
?       /usr/bin/vcdxbuild
?       /usr/bin/vcdxgen
?       /usr/bin/vcdxminfo
?       /usr/bin/vcdxrip
?       /usr/bin/vcs
c3+tc   /usr/bin/verify-uselistorder-11
?       /usr/bin/vftovp
?       /usr/bin/vgdb
nc+tc   /usr/bin/vi
nc+tc   /usr/bin/view
?       /usr/bin/viewres
n5+ti   /usr/bin/vifm
c3+ti   /usr/bin/vile
nc+tc   /usr/bin/vim
nc+tc   /usr/bin/vim.athena
tc      /usr/bin/vim.basic
tc      /usr/bin/vim.tiny
nc+tc   /usr/bin/vimdiff
?       /usr/bin/vinagre
?       /usr/bin/vlc
?       /usr/bin/vlc-wrapper
?       /usr/bin/vlna
?       /usr/bin/vmstat
?       /usr/bin/vmwarectrl
?       /usr/bin/vptovf
?       /usr/bin/vttest
?       /usr/bin/vttest-cur
lib: /lib/x86_64-linux-gnu/libncursesw.so.6
lib: /lib/x86_64-linux-gnu/libtinfo.so.6

The notes for "tc" and "ti" are "termcap" and "terminfo", respectively. The report is crude (just identifying the interfaces used and which epoch they belong to), but the debug option shows more detail, e.g.,

read_pipe(file "/usr/bin/vile")                                                 
read_pipe(ldd /usr/bin/vile)                                                    
...lib is for terminal: /lib/x86_64-linux-gnu/libtinfo.so.6                     
read_pipe(nm -PD /lib/x86_64-linux-gnu/libtinfo.so.6 2>/dev/null)               
read_pipe(ldd /usr/lib/x86_64-linux-gnu/libperl.so.5.32)                        
read_pipe(ldd /lib/x86_64-linux-gnu/libdl.so.2)                                 
read_pipe(ldd /lib/x86_64-linux-gnu/libpthread.so.0)                            
read_pipe(ldd /lib/x86_64-linux-gnu/libc.so.6)                                  
read_pipe(ldd /lib/x86_64-linux-gnu/libcrypt.so.1)                              
read_pipe(ldd /lib/x86_64-linux-gnu/libm.so.6)                                  
read_pipe(nm -PD /usr/bin/vile 2>/dev/null)                                     
+       tigetflag                                                               
+       setupterm                                                               
+       tgoto                                                                   
+       tigetstr                                                                
+       tparm                                                                   
+       cur_term                                                                
+       tigetnum                                                                
+       tputs                                                                   
c3+ti   /usr/bin/vile      

That "c3" refers to SVr3, i.e., the cur_term data symbol. "n5" is ncurses5. vile (vi-like-emacs) can be built with termcap, terminfo or curses terminal drivers. In Debian, it uses terminfo because more information is available to application than termcap. Other programs using low-level interfaces tend to use termcap — due to inertia on the part of their developers.

In terminal applications, these low-level interface users outnumber those using curses. However, applications using complicated screen layouts generally use curses.

On my Debian 11 system, /usr/bin/ has

  • 4312 entries (counting symbolic links)
  • 3197 are files (but several are duplicates via hardlinks)
  • 257 use terminal interfaces (ncurses, terminfo, termcap or slang)
  • 156 use termcap interface (emulated by terminfo)
  • 65 use terminfo
  • 21 use ncurses alone
  • 15 use slang (but 5 of those are also linked to ncurses)

That 21 for ncurses is a bit low, because the current script sees some use of terminfo in what should be a mostly curses application (such as vifm) but summarizes it as the lower-level. There are 81 files in which ncurses is combined that way. Even with that, the termcap and terminfo users still outnumber the others.

Unsurprisingly enough, most uses of slang are closer in capability to terminfo applications than curses, and in any case are not numerous enough to matter.

Upvotes: 3

n. m. could be an AI
n. m. could be an AI

Reputation: 120049

Does everyone uses ncurses library to control terminal and doesn't bother with this low-level code?

This is very easy to check.

First, prepare a list of function in the ncurses library. On my system that would be:

nm -D /lib64/libncurses.so.5.9 | fgrep ' T ' \
  | sed 's/^[0-9A-Fa-f ]*T //' > /tmp/ncurses-functions-list

Now see how many of those are used in various programs.

for f in /usr/bin/* ; do 
    nm -D $f 2>/dev/null | fgrep ' U ' \
      | sed 's/^ *U //' \
      | fgrep -x -f - /tmp/ncurses-functions-list && echo ==== $f; 
done

Upvotes: 3

Related Questions