home *** CD-ROM | disk | FTP | other *** search
- From: azadian@hslrswi.UUCP (Norman H. Azadian)
- Newsgroups: comp.sources.misc
- Subject: v02i077: termcap implementation: works under MS-DOS, 4.xBSD
- Message-ID: <8803161213.AA05807@hslrhit.hasler>
- Date: 16 Mar 88 12:13:56 GMT
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 2, Issue 77
- Submitted-By: "Norman H. Azadian" <azadian@hslrswi.UUCP>
- Archive-Name: termcap
-
- [Also looks like it works under System V, although why you'd want to I don't
- know.... Needs either Henry Spenser's strings package or a set of System III
- or System V libraries. ++bsa]
-
- This is an implementation of termcap(3X) for PC's using MS-DOS. Not having
- access to the unix sources, I hauled off and wrote my own. While I was at
- it I developed complete /etc/termcap profiles for the PC. The color monitor
- profile is completely untested, and the monochrome one is only partially
- tested. I am using this termcap package with less, which I have ported
- to the PC and hacked up. Since I hope someday to distribute my "improved"
- less, this termcap package is a necessary pre-requisite.
-
-
- #--------------------------------CUT HERE-------------------------------------
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # -rw-r--r-- 1 azadian 1079 Mar 16 12:59 README
- # -rw-r--r-- 1 azadian 3370 Mar 16 11:52 termcap.pc
- # -rw-r--r-- 1 azadian 20209 Mar 16 12:13 termcap.c
- #
- echo 'x - README'
- if test -f README; then echo 'shar: not overwriting README'; else
- sed 's/^X//' << '________This_Is_The_END________' > README
- XI wrote termcap(3X) for use on my PC clone under MS-DOS. Additionally, I
- Xhave developed complete termcap profiles for the PC, starting with the
- Xtermcap provided by Darren Friedlein.
- X
- XTermcap.c was written with the Aztec C compiler (4.1), but it also works
- Xwith the 4.3bsd C compiler. A simple test program is provided at the end
- Xof termcap.c. Pay no attention to the printd() calls, they're part of my
- Xdebugging package, and they are effectively neutered by defining DEBUG as 0.
- X
- XI made good use of some of the functions from Henry Spencer's excellent
- Xstandard string library. If you don't have it, get it!
- X
- XIn the not-too-distant future I hope to be unleashing my hacked version
- Xof Mark Nudelman's less program. It requires a termcap(3X) such as this.
- X
- XI welcome your problems, suggestions, and bug fixes.
- X
- XNorman Azadian, 80A; Hasler AG; Belpstrasse 23; 3000 Berne 14; Switzerland
- XX.400: azadian@hslrswi.hasler Telephone: +41 31 63 2178
- XUucp: ... {uunet,ukc,mcvax, ... }!cernvax!hslrswi!azadian
- XBitnet: azadian%hslrswi.UUCP@cernvax.BITNET
- ________This_Is_The_END________
- if test `wc -c < README` -ne 1079; then
- echo 'shar: README was damaged during transit (should have been 1079 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - termcap.pc'
- if test -f termcap.pc; then echo 'shar: not overwriting termcap.pc'; else
- sed 's/^X//' << '________This_Is_The_END________' > termcap.pc
- X#
- X# /etc/termcap for IBM PC's and friends.
- X# Gratiously supplied by Darren Friedlein.
- X# Completed by Norman H. Azadian.
- X#
- X
- X#
- X# Monochrome IBMPC.
- X# This is a termcap for the NANSI.SYS device driver.
- X# It is the same as the ANSI termcap, except NANSI supports additionally
- X# line & char insert & delete (AL,al, DL,dl, DC,dc, IC,ic).
- X#
- Xnansi-mono|mono:\
- X :AL=\E[%dL:al=\E[1L:\
- X :DC=\E[%dP:dc=\E[1P:DL=\E[%dM:dl=\E[1M:\
- X :IC=\E[%d@:ic=\E[1@:\
- X :tc=ansi-mono:
- X
- X
- X#
- X# monochrome ANSI
- X#
- Xansi-mono:\
- X :am:\
- X :bc=\E[1D:bl=^G:bs:\
- X :cd=\E[2J:ce=\E[K:cl=\E[2J\E[H:cm=\E[%i%2;%i%2H:co#80:\
- X :ho=\E[H:\
- X :K1=\200G:K2=\200I:K4=\200O:K5=\200Q:\
- X :k0=\200;:k1=\200<:k2=\200=:k3=\200>:k4=\200?:k5=\200@:\
- X :k6=\200A:k7=\200B:k8=\200C:k9=\200D:\
- X :kb=^H:kC=\200w:kD=\200S:kd=\200H:kE=\200u:kH=\200O:kh=\200G:\
- X :kI=\200R:kl=\200K:kN=\200Q:kP=\200I:kr=\200M:kS=\200v:ku=\200P:\
- X :LE=\E[%dD:le=\E[1D:li#25:\
- X :mb=\E[5m:md=\E[1m:me=\E[0m:mk=\E[8m:mr=\E[7m:ms:\
- X :nd=\E[C:\
- X :RI=\E[%dC:rc=\E[u:\
- X :sc=\E[s:se=\E[0m:so=\E[7m:\
- X :te=\E[0m:ti=\E[0m:\
- X :UP=\E[%dA:ue=\E[0m:up=\E[A:us=\E[4m:\
- X :xd=\E[B:xs:
- X
- X
- X#
- X# Color IBMPC.
- X# This is a termcap for the NANSI.SYS device driver.
- X# It is the same as the ANSI termcap, except NANSI supports
- X# character & line insert & delete, while ANSI does not.
- X#
- Xnansi-color|color:\
- X :AL=\E[%dL:al=\E[1L:\
- X :DC=\E[%dP:dc=\E[1P:DL=\E[%dM:dl=\E[1M:\
- X :IC=\E[%d@:ic=\E[1@:\
- X :tc=ansi-color:
- X
- X#
- X# ANSI Color
- X#
- Xansi-color:\
- X :bc=\E[1D:bl=^G:bs:\
- X :cd=\E[2J:ce=\E[K:cl=\E[2J\E[H:cm=\E[%i%2;%i%2H:co#80:\
- X :ho=\E[H:\
- X :K1=\200G:K2=\200I:K4=\200O:K5=\200Q:\
- X :k0=\200;:k1=\200<:k2=\200=:k3=\200>:k4=\200?:k5=\200@:\
- X :k6=\200A:k7=\200B:k8=\200C:k9=\200D:\
- X :kb=^H:kC=\200w:kD=\200S:kd=\200H:kE=\200u:kH=\200O:kh=\200G:\
- X :kI=\200R:kl=\200K:kN=\200Q:kP=\200I:kr=\200M:kS=\200v:ku=\200P:\
- X :LE=\E[%dD:le=\E[1D:li#25:\
- X :mb=\E[5m:md=\E[1m:me=\E[0m:mk=\E[8m:mr=\E[7m:ms:\
- X :nd=\E[C:\
- X :RI=\E[%dC:rc=\E[u:\
- X :sc=\E[s:se=\E[44;37m:so=\E[31m:\
- X :te=\E[0m:ti=\E[44;37m:\
- X :UP=\E[%dA:ue=\E[0m:up=\E[A:us=\E[4m:\
- X :xd=\E[B:xs:
- X
- X
- X
- X#
- X# alternative nansi color
- X#
- Xalt-nansi-color:\
- X :co#80:\
- X :li#25:\
- X :cl=\E[2J:\
- X :bs:\
- X :ho=\E[H:\
- X :cm=\E[%i%2;%2H:\
- X :up=\E[A:\
- X :xd=\E[B:\
- X :nd=\E[C:\
- X :bc=\E[D:\
- X :ce=\E[K:\
- X :ti=\E[44;37m:\
- X :te=\E[0m:\
- X :so=\E[31m:\
- X :se=\E[44;37m:\
- X :us=\E[1m:\
- X :ue=\E[m:\
- X :hi=\E[32m:\
- X :he=\E[44;37m:\
- X :al=\E[L:\
- X :dl=\E[M:
- X
- X#
- X# Monochrome IBMPC, especially lobotomized for /usr/games/larn.
- X# Each capability (that larn requires) must start on a new line.
- X# Must not use 2nd %i in :cm capability, although it should be there.
- X#
- Xlarn-mono|hack-mono:\
- X :al=\E[L:\
- X :bc=\E[D:\
- X :bs:\
- X :ce=\E[K:\
- X :cl=\E[2J:\
- X :cm=\E[%i%2;%2H:\
- X :co#80:\
- X :dc=\E[P:\
- X :dl=\E[M:\
- X :ho=\E[H:\
- X :ic=\E[@:\
- X :li#25:\
- X :mb=\E[5m:\
- X :md=\E[7m:\
- X :me=\E[0m:\
- X :mk=\E[8m:\
- X :mr=\E[7m:\
- X :nd=\E[C:\
- X :se=\E[0m:\
- X :so=\E[1m:\
- X :te=\E[0m:\
- X :ti=\E[0m:\
- X :ue=\E[0m:\
- X :up=\E[A:\
- X :us=\E[4m:\
- X :xd=\E[B:\
- X :xs:
- X
- X#
- X# Color IBMPC, especially lobotomized for /usr/games/larn.
- X# Each capability (that larn requires) must start on a new line.
- X# Must not use 2nd %i in :cm capability, although it should be there.
- X#
- Xlarn-color|hack-color:\
- X :bc=\E[D:\
- X :bs:\
- X :ce=\E[K:\
- X :cl=\E[2J:\
- X :cm=\E[%i%2;%2H:\
- X :co#80:\
- X :he=\E[44;37m:\
- X :hi=\E[32m:\
- X :ho=\E[H:\
- X :li#25:\
- X :nd=\E[C:\
- X :se=\E[44;37m:\
- X :so=\E[31m:\
- X :te=\E[0m:\
- X :ti=\E[44;37m:\
- X :ue=\E[m:\
- X :up=\E[A:\
- X :us=\E[1m:\
- X :xd=\E[B:\
- X :xs:
- ________This_Is_The_END________
- if test `wc -c < termcap.pc` -ne 3370; then
- echo 'shar: termcap.pc was damaged during transit (should have been 3370 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - termcap.c'
- if test -f termcap.c; then echo 'shar: not overwriting termcap.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > termcap.c
- X/* termcap.c 880204 NHA */
- X/* My implementation of the termcap(3X) library routines.
- X * All specs lifted straight from 4.3bsd Programmers Reference Manual.
- X * These functions extract and use capabilities from the terminal
- X * capability database termcap(5). These are low level routines;
- X * see curses(3X) for a higher level package.
- X ** You'll find it looks a lot nicer if you use a tab interval of 4.
- X */
- X
- X#define DEBUG 0
- X
- X#if DEBUG
- X#define MAJOR 'L' /* major module identifier */
- X#define MINOR 'T' /* minor module identifier */
- X#include <gen.h> /* my all-purpose include file */
- X#else DEBUG
- X#include <stdio.h>
- X#include <fcntl.h>
- X#define export
- X#define import extern
- X#define local static
- X#define bool int
- X#define abs(x) ( (x < 0) ? (-(x)) : (x) )
- X#define YES 1
- X#define NO 0
- X#define error(s) {perror(s); exit(99);}
- X#define initdebug(pac, pav, confile, listfile, initstring)
- Xstatic printd(lvl, fmt) {}
- X#endif DEBUG
- X
- X#define BUFSIZE 1024
- X
- X/* external variables (supplied by user) required by this package */
- Ximport char PC; /* pad char, default ^@ */
- Ximport char BC; /* backspace char if not ^H */
- Ximport char UP; /* char for Upline (cursor up) */
- Ximport char ospeed; /* output speed, see stty(3) */
- X
- X#ifdef __STDC__
- Ximport char *getenv(char *id);
- Ximport int open(char *name, unsigned mode);
- Ximport unsigned strlen(char *str);
- Ximport unsigned strspn(char *str1, char *str2);
- Ximport int strcmp(char *str1, char *str2);
- Ximport int strncmp(char *str1, char *str2, unsigned n);
- Ximport char *strncpy(char *buf, char *str, unsigned n);
- Ximport char *strchr(char *string, char ch);
- Ximport char *strpbrk(char *string, char *delimiters);
- X#else __STDC__
- Ximport char *getenv();
- Ximport int open();
- Ximport unsigned strlen();
- Ximport unsigned strspn();
- Ximport int strcmp();
- Ximport int strncmp();
- Ximport char *strncpy();
- Ximport char *strchr();
- Ximport char *strpbrk();
- X#endif __STDC__
- X
- X/* milliseconds per character, for each of the possible baud rates of ospeed */
- X/* here multiplied by 10 for computational convenience */
- Xlocal unsigned delayFactor[] = {
- X 0, /* B0 */ /* hang up dataphone */
- X 1920, /* B50 */
- X 1280, /* B75 */
- X 872, /* B110 */
- X 730, /* B134 */
- X 640, /* B150 */
- X 480, /* B200 */
- X 320, /* B300 */
- X 160, /* B600 */
- X 80, /* B1200 */
- X 50, /* B1800 */
- X 40, /* B2400 */
- X 20, /* B4800 */
- X 10, /* B9600 */
- X 5, /* EXTA (19200 here) */
- X 2, /* EXTB (34800 here) */
- X };
- X/* remember where user's terminal entry buffer is */
- Xlocal char *ebuf = NULL; /* pointer to entry buffer */
- X
- X
- X
- X/*+ f i n d C a p
- X * Returns pointing to the character immediately following the capability id.
- X * Returns NULL if tgetent() has not yet been called successfully.
- X * Returns NULL if capability not found.
- X */
- Xlocal char *findCap(id)
- Xchar *id; /* name of the capability to find */
- X {
- X char *p; /* pointer into the entry buffer */
- X
- X printd(5, "findCap(\"%s\"), ebuf=%p\n", id, ebuf);
- X if (ebuf == NULL)
- X return NULL;
- X for (p = ebuf ; *p ; ++p)
- X {
- X printd(9, " %02x", *p);
- X if ( (p[0] == ':') && (p[1] == id[0]) && (p[2] == id[1]) )
- X {
- X printd(7, "findCap(): SUCCESS, p=%.15s...\n", p);
- X p = &p[3];
- X break;
- X }
- X }
- X if ( ! *p)
- X p = NULL;
- X printd(5, "findCap(): returning %p (%.11s...)\n", p, p);
- X return p;
- X }
- X
- X
- X
- X/*+ g e t E n t r y
- X * Gets the named entry from the already-opened termcap file into the buffer.
- X * The size of the buffer is BUFSIZE, and it is considered to be an
- X * error if the size of the entry equals or exceeds this.
- X * We place a terminating NULL character at the end of the entry.
- X * Call error() on any irregularities.
- X * Return 0 if the named entry not found, else 1.
- X * Removes terminal names and all newlines from the entry.
- X **If this is called for a 2nd time from tgetent(), then the length checking
- X **is useless.
- X */
- Xlocal int getEntry(fd, outbuf, name)
- Xint fd; /* FileDescriptor for termcap file*/
- Xchar *outbuf; /* where we put the entry */
- Xchar *name; /* terminal type name we seek */
- X {
- X unsigned namlen; /* # chars in name */
- X int cnt; /* # unprocessed chars in inbuf[] */
- X char *ip; /* pointer into input buffer */
- X char *op; /* pointer into output buffer */
- X char *ptmp; /* temporary pointer */
- X int stat; /* status of read(), etc */
- X char inbuf[BUFSIZE]; /* termcap file is read into here */
- X
- X printd(5, "getEntry(%d, %p, \"%s\")\n", fd, inbuf, name);
- X op = outbuf;
- X namlen = strlen(name);
- X cnt = read(fd, inbuf, BUFSIZE-1);
- X if (cnt == -1)
- X error("getEntry(): file is empty\n");
- X inbuf[cnt] = '\0'; /* maintain inbuf[] as a string */
- X for (ip = inbuf ; 0 < cnt ; ++ip, --cnt)
- X {
- X printd(7, "cnt=%d, ip='%.55s...'\n", cnt, ip);
- X stat = strspn(ip, "\r\n \t\b\f");
- X if (0 < stat)
- X {
- X printd(8, "skipping %d whitespace characters\n", stat);
- X ip = &ip[--stat];
- X cnt -= stat;
- X }
- X else if (*ip == '#')
- X {
- X printd(6, "comment line '%.11s...'\n", ip);
- X ptmp = ip;
- X ip = strchr(ip, (char)'\n');
- X cnt -= (ip == NULL) ? cnt : (int)(ip - ptmp);
- X }
- X else if (strncmp(name, ip, namlen) == 0)
- X {
- X printd(6, "getEntry(): SUCCESS, ip = '%.22s...', cnt=%u\n", ip,cnt);
- X ip = strchr(ip, (char)':'); /* skip over namelist */
- X printd(7, "getEntry(): raw entry is: '%s'\n", ip);
- X /* copy entry into output buffer */
- X /* eliminate non-space whitespace and continuation \ */
- X for (op = outbuf ; ip != NULL && *ip != '\0' ; ++ip)
- X {
- X printd(9, " %02x", *ip);
- X if (ip[0] == '\\' && ip[1] == '\r' && ip[2] == '\n')
- X ip = &ip[2];
- X else if (ip[0] == '\\' && ip[1] == '\n')
- X ++ip;
- X else if (strchr("\t\r\b\f", *ip) != NULL)
- X continue;
- X else if (*ip == '\n')
- X break;
- X else
- X *op++ = *ip;
- X }
- X if (*ip != '\n')
- X error("getEntry(): entry too long\n");
- X *op = '\0';
- X printd(6, "getEntry(): outbuf='%s'\n", outbuf);
- X printd(5, "getEntry(): returning 1 [SUCCESS]\n");
- X return 1;
- X }
- X else
- X { /* advance to next name in list */
- X ptmp = ip;
- X ip = strpbrk(ip, "|:"); /* find name delimiter */
- X if (ip == NULL)
- X error("getEntry(): bad format\n");
- X cnt -= ip - ptmp;
- X if (*ip != '|')
- X { /* at end of namelist for entry */
- X /* dispose of entire entry */
- X printd(8, "end of namelist, cnt=%d\n", cnt);
- X for (++ip, --cnt ; 0 < cnt ; ++ip, --cnt)
- X if ( ip[0] == '\n' &&
- X ( (ip[-1] == '\r' && ip[-2] != '\\')
- X ||
- X (ip[-1] != '\r' && ip[-1] != '\\') )
- X )
- X { /* skip to next entry in file */
- X /* delete this entry from inbuf */
- X for (ptmp = inbuf ; *ip != '\0' ; ++ptmp, ++ip)
- X *ptmp = *ip;
- X *ptmp = *ip; /* string stopper character */
- X ip = inbuf;
- X if (strlen(ip) != cnt)
- X error("getEntry(): bad strlen(ip)\n");
- X /* fill inbuf with more characters */
- X stat = read(fd, ptmp, BUFSIZE - cnt - 1);
- X if (0 < stat)
- X {
- X cnt += stat;
- X inbuf[cnt] = '\0';
- X }
- X break;
- X }
- X if (cnt <= 0)
- X error("getEntry(): entry too long!\n");
- X }
- X }
- X }
- X outbuf[0] = '\0'; /* not found */
- X printd(6, "getEntry(): outbuf='%s'\n", outbuf);
- X printd(5, "getEntry(): returning 0 [FAILURE]\n");
- X return 0;
- X }
- X
- X
- X
- X/*+ t g e t e n t
- X * Extracts the entry for terminal name into the buffer at bp.
- X * Bp should be a character array of size 1024 and must be retained through
- X * all subsequent calls to tgetnum(), tgetflag(), and tgetstr().
- X * Returns -1 if it cannot open the termcap file, 0 if the terminal name
- X * given does not have an entry, and 1 if all goes well.
- X * Looks in the environment for a TERMCAP variable. If found, and the value
- X * does not begin with a slash, and the terminal type name is the same as
- X * the environment string TERM, the TERMCAP string is used instead of reading
- X * the termcap file. If it does begin with a slash, the string is used
- X * as a pathname rather than /etc/termcap. This can speed up entry into
- X * programs that call tgetent(), as well as to help debug new terminal
- X * descriptions or to make one for your terminal if you can't write the
- X * file /etc/termcap.
- X */
- Xexport int tgetent(bp, name)
- Xchar *bp; /* pointer to user's buffer */
- Xchar *name; /* terminal type name */
- X {
- X char *termcap; /* pointer to $TERMCAP string */
- X int fd; /* File Descriptor, termcap file */
- X int retval; /* return value */
- X
- X printd(3, "tgetent(%p, \"%s\")\n", bp, name);
- X termcap = getenv("TERMCAP");
- X if (termcap != NULL && termcap[0] != '/' &&
- X strcmp(name, getenv("TERM")) == 0)
- X { /* use $TERMCAP as the entry */
- X printd(6, "tgetent(): using contents of $EXINIT\n");
- X strncpy(bp, termcap, (BUFSIZE-1));
- X bp[BUFSIZE] = '\0';
- X termcap = "/etc/termcap"; /* in case :tc capability found */
- X retval = 1;
- X }
- X else
- X { /* look for entry in termcap file */
- X if (termcap[0] != '/')
- X termcap = "/etc/termcap"; /* use default termcap file */
- X printd(6, "tgetent(): opening file %s\n", termcap);
- X fd = open(termcap, O_RDONLY);
- X if (fd == -1)
- X retval = -1;
- X else
- X {
- X retval = getEntry(fd, bp, name);
- X close(fd);
- X }
- X }
- X if (retval == 1)
- X ebuf = bp; /* for our use in future pkg calls*/
- X
- X /* deal with the :tc= capability */
- X bp = findCap("tc");
- X if (bp != NULL)
- X {
- X char newname[88];
- X
- X printd(6, "tgetent(): :tc found at %p, is '%s'\n", &bp[-3], &bp[-3]);
- X strncpy(newname, &bp[1], sizeof newname);
- X if (strchr(newname, (char)':') != NULL)
- X *(strchr(newname, (char)':')) = '\0';
- X fd = open(termcap, O_RDONLY);
- X if (fd == -1)
- X {
- X printd(2, "tgetent(%s): can't open :tc file '%s'\n", name, newname);
- X retval = -1;
- X }
- X else
- X {
- X retval = getEntry(fd, &bp[-2], newname);
- X close(fd);
- X }
- X }
- X
- X printd(3, "tgetent(): returning %d\n", retval);
- X return retval;
- X }
- X
- X
- X
- X/*+ t g e t n u m
- X * Gets the numeric value of capability id, returning -1 if it is not given
- X * for the terminal.
- X */
- Xexport int tgetnum(id)
- Xchar *id; /* capability name */
- X {
- X int retval;
- X char *p;
- X
- X printd(3, "tgetnum(\"%s\")\n", id);
- X p = findCap(id);
- X if (p == NULL || *p != '#')
- X retval = -1; /* not found, or not numeric */
- X else
- X {
- X retval = 0;
- X for (++p ; *p != ':' ; ++p)
- X retval = (retval * 10) + (*p - '0');
- X }
- X printd(3, "tgetnum(): returning %d\n", retval);
- X return retval;
- X }
- X
- X
- X
- X/*+ t g e t f l a g
- X * Returns 1 if the specified capability is present in the terminal's entry,
- X * 0 if it is not.
- X **This implementation requires that the capability be a boolean one.
- X */
- Xexport int tgetflag(id)
- Xchar *id; /* capability name */
- X {
- X int retval;
- X char *p;
- X
- X printd(3, "tgetflag(\"%s\")\n", id);
- X p = findCap(id);
- X retval = (p != NULL && *p == ':');
- X printd(3, "tgetflag(): returning %d\n", retval);
- X return retval;
- X }
- X
- X
- X
- X/*+ t g e t s t r
- X * Returns the string value of the capability id, places it in the buffer
- X * at area, and advances the area pointer [past the terminating '\0' char].
- X * It decodes the abbreviations for this field described in termcap(5),
- X * except for cursor addressing and padding information.
- X * Returns NULL if the capability was not found.
- X */
- Xexport char *tgetstr(id, area)
- Xchar *id; /* capability name */
- Xchar **area; /* pointer to output pointer */
- X {
- X char *retval; /* return value */
- X char *p; /* pointer into capability string */
- X unsigned sum; /* for chars given in octal */
- X
- X printd(3, "tgetstr(\"%s\", %p): *area=%p\n", id, area, *area);
- X p = findCap(id);
- X if (p == NULL || *p != '=')
- X retval = NULL;
- X else
- X {
- X retval = *area;
- X for (++p ; *p != ':' ; ++p)
- X {
- X printd(9, "p=%p, *p=%02x\n", p, *p);
- X if (*p == '\\')
- X switch (*++p)
- X { /* special */
- X case '0': case '1': case '2': case '3':
- X case '4': case '5': case '6': case '7':
- X sum = (p[0] - '0') << 6 +
- X (p[1] - '0') << 3 +
- X (p[2] - '0');
- X ++p;
- X ++p;
- X *(*area)++ = (char)(sum & 0377);
- X /** will \200 really end up as \000 like it should ? **/
- X /** see termcap(5), top of page 6 **/
- X break;
- X case '^': *(*area)++ = '^'; break;
- X case '\\': *(*area)++ = '\\'; break;
- X case 'E': *(*area)++ = '\033'; break; /* escape */
- X case 'b': *(*area)++ = '\b'; break;
- X case 'f': *(*area)++ = '\f'; break;
- X case 'n': *(*area)++ = '\n'; break;
- X case 'r': *(*area)++ = '\r'; break;
- X case 't': *(*area)++ = '\t'; break;
- X default: *(*area)++ = *p; break;
- X }
- X else if (*p == '^')
- X *(*area)++ = *++p - '@'; /* control */
- X else
- X *(*area)++ = *p; /* normal */
- X }
- X *(*area)++ = '\0'; /* NULL-terminate the string */
- X }
- X printd(3, "tgetstr(): returning ");
- X if (retval == NULL)
- X { /* these must be here for print() */
- X printd(3, "NULL");
- X } /* these must be here for print() */
- X else
- X {
- X printd(3, "%p [", retval);
- X for (p = retval ; p != *area ; ++p)
- X printd(3, " %02x", (unsigned)*p);
- X printd(3, "]");
- X }
- X printd(3, ", *area=%p\n", *area);
- X return retval;
- X }
- X
- X
- X
- X/*+ t g o t o
- X * Returns a cursor addressing string decoded from cm to go to column destcol
- X * in line destline. It uses the external variables UP (from the up capability)
- X * and BC (if bc is given rather than bs) if necessary to avoid placing
- X * \n, ^D, or ^@ in the returned string. (Programs which call tgoto() should
- X * be sure to turn off the XTABS bit(s), since tgoto() may not output a tab.
- X * Note that programs using termcap should in general turn off XTABS anyway
- X * since some terminals use control I for other functions, such as non-
- X * destructive space.) If a % sequence is given which is not understood,
- X * then tgoto() returns "OOPS".
- X **Output buffer is local, so don't try any recursion.
- X **No error checking here.
- X */
- Xexport char *tgoto(cm, destcol, destline)
- Xchar *cm; /* cm capability string */
- Xint destcol; /* destination column (left is 0) */
- Xint destline; /* destination line (top is 0) */
- X {
- X char *outp; /* pointer into answer[] */
- X local char answer[88]; /* result stashed here */
- X bool reversed; /* YES when should send col 1st */
- X int value; /* next value to output */
- X
- X printd(3, "tgoto(\"%s\", %d, %d)\n", cm, destcol, destline);
- X reversed = NO;
- X value = destline;
- X outp = answer;
- X for ( ; *cm ; ++cm)
- X {
- X printd(9, " %02x", *cm);
- X if (*cm == '%')
- X {
- X switch (*++cm)
- X {
- X case '%': *outp++ = '%';
- X break;
- X case 'd': sprintf(outp, "%d", value);
- X if (value < 0)
- X ++outp;
- X ++outp;
- X if (9 < abs(value))
- X ++outp;
- X if (99 < abs(value))
- X ++outp;
- X value = (reversed) ? destline : destcol;
- X break;
- X case '2': sprintf(outp, "%02d", value);
- X outp += 2;
- X value = (reversed) ? destline : destcol;
- X break;
- X case '3': sprintf(outp, "%03d", value);
- X outp += 3;
- X value = (reversed) ? destline : destcol;
- X break;
- X case '.': *outp++ = value;
- X value = (reversed) ? destline : destcol;
- X break;
- X case '+': *outp++ = value + *++cm;
- X value = (reversed) ? destline : destcol;
- X break;
- X case '>': if (value > *++cm)
- X value += *++cm;
- X else
- X ++cm;
- X break;
- X case 'r': value = (reversed) ? destline : destcol;
- X reversed ^= YES;
- X break;
- X case 'i': ++value;
- X break;
- X case 'n': destcol ^= 0140;
- X destline ^= 0140;
- X break;
- X case 'B': value = (16 * (value / 10)) + (value % 10);
- X break;
- X case 'D': value = (value - (2 * (value % 16)));
- X break;
- X default: sprintf(outp, "OOPS");
- X outp += 4;
- X break;
- X }
- X printd(8, "reversed=%b, value=%d\n", reversed, value);
- X }
- X else
- X *outp++ = *cm;
- X }
- X *outp = '\0';
- X printd(3, "tgoto(): returning '%s'\n", answer);
- X return answer;
- X }
- X
- X
- X
- X/*+ t p u t s
- X * Decodes the leading pad information of the string cp; affcnt gives the
- X * number of lines affected by the operation, or 1 if this is not applicable.
- X * Outc is a routine which is called with each character in turn.
- X * The external variable ospeed should contain the output speed of
- X * the terminal as encoded by stty(3).
- X * The external variable PC should contain a pad character to be used
- X * (from the pc capability) if a null (^@) is inappropriate.
- X */
- Xexport void tputs(cp, affcnt, outc)
- Xchar *cp; /* leading pad information string */
- Xint affcnt; /* number lines affected, or 1 */
- Xint (*outc)(); /*output function to call per char*/
- X {
- X char *p;
- X bool decimalFlag; /* delay had a decimal point */
- X unsigned delay;
- X unsigned cnt;
- X
- X printd(3, "tputs(\"%s\", %d, %p): ospeed=%u\n", cp, affcnt, outc, ospeed);
- X
- X /* calculate delay, if any */
- X /* currently no guard against having more than 1 digit after decimal point*/
- X decimalFlag = NO;
- X delay = 0;
- X for (p = cp ; strchr("0123456789.", *p) ; ++p)
- X if (*p == '.')
- X decimalFlag = YES;
- X else
- X delay = (delay * 10) + (*p - '0');
- X if ( ! decimalFlag)
- X delay *= 10; /* units are really 10ms */
- X if (*p == '*')
- X delay *= affcnt;
- X printd(6, "tputs(): delay = %u.%u milliseconds\n", delay/10, delay%10);
- X delay += (delayFactor[ospeed] + 1) / 2; /* round up */
- X delay /= delayFactor[ospeed];
- X printd(5, "tputs(): delay = %u characters, [delayFactor is %u]\n",
- X delay, delayFactor[ospeed]);
- X
- X for ( ; *cp != '\0' ; ++cp)
- X outc(*cp); /* output string */
- X for (cnt = delay ; cnt ; --cnt)
- X outc(PC); /* output delay characters */
- X printd(3, "tputs(): returning\n");
- X }
- X
- X
- X
- X#if TEST
- X
- Xexport char PC; /* pad char, default ^@ */
- Xexport char BC; /* backspace char if not ^H */
- Xexport char UP; /* char for Upline (cursor up) */
- Xexport char ospeed = 13; /* output speed, see stty(3) */
- X
- Xlocal char buf[1024]; /* holds termcap entry */
- Xlocal char strbuf[512]; /* for output of tgetstr() */
- Xlocal char *strptr; /* ptr to strbuf[] */
- X
- X
- X/*+ o c
- X * Tiny test routine to simulate putting out a character.
- X */
- Xlocal void oc(c)
- Xchar c;
- X {
- X putc(c, stdout);
- X }
- X
- X
- X/*+ m a i n
- X * Test program for the termcap routines.
- X * Command line parameters:
- X * 1st is terminal name, defaulted to "mono".
- X * 2nd is name of numeric capability, default "co".
- X * 3rd is name of boolean capability, default "bs".
- X * 4th is name of string capability, default "so".
- X * 5th is test string for tgoto(), default is "6\\E&%r%2c%2Y".
- X * 6th is test string for tputs(), default is "3.5*123".
- X */
- Xexport int main(ac, av)
- Xint ac;
- Xchar **av;
- X {
- X int stat; /* integer return value */
- X char *instr; /* input string value */
- X char *outstr; /* string return value */
- X char *ttype; /* terminal type string */
- X char *capability; /* capability name string */
- X
- X /* setup */
- X initdebug(&ac, &av, "/dev/con", "debug.out", "LB3LT8");
- X PC = '@';
- X BC = 'H';
- X UP = 'B';
- X
- X /* test tgetent() */
- X ttype = (ac < 2) ? "mono" : av[1];
- X stat = tgetent(buf, ttype);
- X printf("main: tgetent(buf, \"%s\") returned %d\n", ttype, stat);
- X if (stat != 1)
- X exit (99);
- X
- X /* test tgetnum() */
- X capability = (ac < 3) ? "co" : av[2];
- X stat = tgetnum(capability);
- X printf("main: tgetnum(%s) returned %d\n", capability, stat);
- X
- X /* test tgetflag() */
- X capability = (ac < 4) ? "bs" : av[3];
- X stat = tgetflag(capability);
- X printf("main: tgetflag(%s) returned %d\n", capability, stat);
- X
- X /* test tgetstr() */
- X capability = (ac < 5) ? "so" : av[4];
- X strptr = strbuf;
- X outstr = tgetstr(capability, &strptr);
- X printf("main: tgetstr(%s, 0x%lx) returned '%s' [strbuf=0x%lx, strptr=0x%lx]\n",
- X capability, &strptr, outstr, strbuf, strptr);
- X if (strcmp(capability, "so") == 0)
- X {
- X strptr = strbuf;
- X tgetstr("se", &strptr);
- X printf(strbuf);
- X }
- X
- X /* test tgoto() */
- X instr = (ac < 6) ? "6\\E&%r%2c%2Y" : av[5];
- X outstr = tgoto(instr, 12, 3);
- X printf("main: tgoto(\"%s\", 12, 3) returned '%s'\n", instr, outstr);
- X
- X /* test tputs() */
- X instr = (ac < 7) ? "3.5*123" : av[6];
- X printf("main: tputs(\"%s\", 3, oc) returned '", instr);
- X tputs(instr, 3, oc);
- X printf("'\n");
- X
- X return 0;
- X }
- X
- X#endif TEST
- ________This_Is_The_END________
- if test `wc -c < termcap.c` -ne 20209; then
- echo 'shar: termcap.c was damaged during transit (should have been 20209 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
- --------------------------------------------------------------------------
- NHA
- ---
- Norman Azadian, 80A; Hasler AG; Belpstrasse 23; 3000 Berne 14; Switzerland
- X.400: azadian@hslrswi.hasler Telephone: +41 31 63 2178
- Uucp: ... {uunet,ukc,mcvax, ... }!cernvax!hslrswi!azadian
- Bitnet: azadian%hslrswi.UUCP@cernvax.BITNET
-