iolib.icn: Procedures for termlib support

link iolib
August 14, 1996; Richard L. Goerwitz (with help from Norman Azadian)
Requires: UNIX or MS-DOS, co-expressions
See also: itlib.icn, iscreen.icn
This file is in the public domain.

The following library represents a series of rough functional
equivalents to the standard UNIX low-level termcap routines.  It is
not meant as an exact termlib clone.  Nor is it enhanced to take
care of magic cookie terminals, terminals that use \D in their
termcap entries, or archaic terminals that require padding.  This
library is geared mainly for use with ANSI and VT-100 devices.
Note that this file may, in most instances, be used in place of the
older UNIX-only itlib.icn file.  It essentially replaces the DOS-
only itlibdos routines.  For DOS users not familiar with the whole
notion of generalized screen I/O, I've included extra documentation
below.  Please read it.

The sole disadvantage of this over the old itlib routines is that
iolib.icn cannot deal with archaic or arcane UNIX terminals and/or
odd system file arrangements.  Note that because these routines
ignore padding, they can (unlike itlib.icn) be run on the NeXT and
other systems which fail to implement the -g option of the stty
command.  Iolib.icn is also simpler and faster than itlib.icn.

I want to thank Norman Azadian for suggesting the whole idea of
combining itlib.icn and itlibdos.icn into one distribution, for
suggesting things like letting drive specifications appear in DOS
TERMCAP environment variables, and for finding several bugs (e.g.
the lack of support for %2 and %3 in cm).  Although he is loathe
to accept this credit, I think he deserves it.
____________________________________________________________

Contents:

setname(term)
     Use only if you wish to initialize itermlib for a terminal
other than what your current environment specifies.  "Term" is the
name of the termcap entry to use.  Normally this initialization is
done automatically, and need not concern the user.

getval(id)
     Works something like tgetnum, tgetflag, and tgetstr.  In the
spirit of Icon, all three have been collapsed into one routine.
Integer valued caps are returned as integers, strings as strings,
and flags as records (if a flag is set, then type(flag) will return
"true").  Absence of a given capability is signalled by procedure
failure.

igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
     Analogous to tgoto.  "Cm" is the cursor movement command for
the current terminal, as obtained via getval("cm").  Igoto()
returns a string which, when output via iputs, will cause the
cursor to move to column "destcol" and line "destline."  Column and
line are always calculated using a *one* offset.  This is far more
Iconish than the normal zero offset used by tgoto.  If you want to
go to the first square on your screen, then include in your program
"iputs(igoto(getval("cm"),1,1))."

iputs(cp,affcnt)
     Equivalent to tputs.  "Cp" is a string obtained via getval(),
or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
count of affected lines.  It is completely irrelevant for most
modern terminals, and is supplied here merely for the sake of
backward compatibility with itlib, a UNIX-only version of these
routines (one which handles padding on archaic terminals).
____________________________________________________________

Notes for MS-DOS users:

     There are two basic reasons for using the I/O routines
contained in this package.  First, by using a set of generalized
routines, your code will become much more readable.  Secondly, by
using a high level interface, you can avoid the cardinal
programming error of hard coding things like screen length and
escape codes into your programs.

     To use this collection of programs, you must do two things.
First, you must add the line "device=ansi.sys" (or the name of some
other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new
nansi.sys]) to your config.sys file.  Secondly, you must add two
lines to your autoexec.bat file: 1) "set TERM=ansi-mono" and 2)
"set TERMCAP=\location\termcap."  The purpose of setting the TERM
variable is to tell this program what driver you are using.  If you
have a color system, you could use "ansi-color" instead of
"ansi-mono," although for compatibility with a broader range of
users, it would perhaps be better to stick with mono.  The purpose
of setting TERMCAP is to make it possible to determine where the
termcap database file is located.  The termcap file (which should
have been packed with this library as termcap.dos) is a short
database of all the escape sequences used by the various terminal
drivers.  Set TERMCAP so that it reflects the location of this file
(which should be renamed as termcap, for the sake of consistency
across UNIX and MS-DOS spectra).  If desired, you can also try
using termcap2.dos.  Certain games work a lot better using this
alternate file.  To try it out, rename it to termcap, and set
the environment variable TERMCAP to its location.

     Although the authors make no pretense of providing here a
complete introduction to the format of the termcap database file,
it will be useful, we believe, to explain a few basic facts about
how to use this program in conjunction with it.  If, say, you want
to clear the screen, add the line,

     iputs(getval("cl"))

to your program.  The function iputs() outputs screen control
sequences.  Getval retrieves a specific sequence from the termcap
file.  The string "cl" is the symbol used in the termcap file to
mark the code used to clear the screen.  By executing the
expression "iputs(getval("cl"))," you are 1) looking up the "cl"
(clear) code in the termcap database entry for your terminal, and
the 2) outputting that sequence to the screen.

     Some other useful termcap symbols are "ce" (clear to end of
line), "ho" (go to the top left square on the screen), "so" (begin
standout mode), and "se" (end standout mode).  To output a
boldfaced string, str, to the screen, you would write -

     iputs(getval("so"))
     writes(str)
     iputs(getval("se"))

You can also write "writes(getval("so") || str || getval("se")),
but this would make reimplementation for UNIX terminals that
require padding rather difficult.

     It is also heartily to be recommended that MS-DOS programmers
try not to assume that everyone will be using a 25-line screen.
Most terminals are 24-line.  Some 43.  Some have variable window
sizes.  If you want to put a status line on, say, the 2nd-to-last
line of the screen, then determine what that line is by executing
"getval("li")."  The termcap database holds not only string-valued
sequences, but numeric ones as well.  The value of "li" tells you
how many lines the terminal has (compare "co," which will tell you
how many columns).  To go to the beginning of the second-to-last
line on the screen, type in:

     iputs(igoto(getval("cm"), 1, getval("li")-1))

The "cm" capability is a special capability, and needs to be output
via igoto(cm,x,y), where cm is the sequence telling your computer
to move the cursor to a specified spot, x is the column, and y is
the row.  The expression "getval("li")-1" will return the number of
the second-to-last line on your screen.

Source code | Program Library Page | Icon Home Page