160250Shibler /* Work-alike for termcap, plus extra features.
260250Shibler Copyright (C) 1985, 1986 Free Software Foundation, Inc.
360250Shibler
460250Shibler This program is free software; you can redistribute it and/or modify
560250Shibler it under the terms of the GNU General Public License as published by
660250Shibler the Free Software Foundation; either version 1, or (at your option)
760250Shibler any later version.
860250Shibler
960250Shibler This program is distributed in the hope that it will be useful,
1060250Shibler but WITHOUT ANY WARRANTY; without even the implied warranty of
1160250Shibler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1260250Shibler GNU General Public License for more details.
1360250Shibler
1460250Shibler You should have received a copy of the GNU General Public License
1560250Shibler along with this program; if not, write to the Free Software
1660250Shibler Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1760250Shibler
1860250Shibler In other words, you are welcome to use, share and improve this program.
1960250Shibler You are forbidden to forbid anyone else to use, share and improve
2060250Shibler what you give them. Help stamp out software-hoarding! */
2160250Shibler
2260250Shibler
2360250Shibler
2460250Shibler /* BUFSIZE is the initial size allocated for the buffer
2560250Shibler for reading the termcap file.
2660250Shibler It is not a limit.
2760250Shibler Make it large normally for speed.
2860250Shibler Make it variable when debugging, so can exercise
2960250Shibler increasing the space dynamically. */
3060250Shibler
31*60297Shibler #include <sys/types.h>
32*60297Shibler
3360250Shibler #ifdef emacs
3460250Shibler #include "config.h"
3560250Shibler #endif
3660250Shibler
3760250Shibler #ifndef BUFSIZE
3860250Shibler #ifdef DEBUG
3960250Shibler #define BUFSIZE bufsize
4060250Shibler
4160250Shibler int bufsize = 128;
4260250Shibler #else
4360250Shibler #define BUFSIZE 2048
4460250Shibler #endif
4560250Shibler #endif
4660250Shibler
4760250Shibler #ifndef emacs
4860250Shibler static
memory_out()4960250Shibler memory_out ()
5060250Shibler {
5160250Shibler write (2, "Virtual memory exhausted\n", 25);
5260250Shibler exit (1);
5360250Shibler }
5460250Shibler
5560250Shibler static int
xmalloc(size)5660250Shibler xmalloc (size)
5760250Shibler int size;
5860250Shibler {
5960250Shibler register tem = malloc (size);
6060250Shibler if (!tem)
6160250Shibler memory_out ();
6260250Shibler return tem;
6360250Shibler }
6460250Shibler
6560250Shibler static int
xrealloc(ptr,size)6660250Shibler xrealloc (ptr, size)
6760250Shibler int ptr;
6860250Shibler int size;
6960250Shibler {
7060250Shibler register tem = realloc (ptr, size);
7160250Shibler if (!tem)
7260250Shibler memory_out ();
7360250Shibler return tem;
7460250Shibler }
7560250Shibler #endif /* not emacs */
7660250Shibler
7760250Shibler /* Looking up capabilities in the entry already found */
7860250Shibler
7960250Shibler /* The pointer to the data made by tgetent is left here
8060250Shibler for tgetnum, tgetflag and tgetstr to find. */
8160250Shibler
8260250Shibler static char *term_entry;
8360250Shibler
8460250Shibler static char *tgetst1 ();
8560250Shibler
8660250Shibler /* This is the main subroutine that is used to search
8760250Shibler an entry for a particular capability */
8860250Shibler
8960250Shibler static char *
find_capability(bp,cap)9060250Shibler find_capability (bp, cap)
9160250Shibler register char *bp, *cap;
9260250Shibler {
9360250Shibler for (; *bp; bp++)
9460250Shibler if (bp[0] == ':'
9560250Shibler && bp[1] == cap[0]
9660250Shibler && bp[2] == cap[1])
9760250Shibler return &bp[4];
9860250Shibler return 0;
9960250Shibler }
10060250Shibler
10160250Shibler int
tgetnum(cap)10260250Shibler tgetnum (cap)
10360250Shibler char *cap;
10460250Shibler {
10560250Shibler register char *ptr = find_capability (term_entry, cap);
10660250Shibler if (!ptr || ptr[-1] != '#')
10760250Shibler return -1;
10860250Shibler return atoi (ptr);
10960250Shibler }
11060250Shibler
11160250Shibler int
tgetflag(cap)11260250Shibler tgetflag (cap)
11360250Shibler char *cap;
11460250Shibler {
11560250Shibler register char *ptr = find_capability (term_entry, cap);
11660250Shibler return 0 != ptr && ptr[-1] == ':';
11760250Shibler }
11860250Shibler
11960250Shibler /* Look up a string-valued capability `cap'.
12060250Shibler If `area' is nonzero, it points to a pointer to a block in which
12160250Shibler to store the string. That pointer is advanced over the space used.
12260250Shibler If `area' is zero, space is allocated with `malloc'. */
12360250Shibler
12460250Shibler char *
tgetstr(cap,area)12560250Shibler tgetstr (cap, area)
12660250Shibler char *cap;
12760250Shibler char **area;
12860250Shibler {
12960250Shibler register char *ptr = find_capability (term_entry, cap);
13060250Shibler if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~'))
13160250Shibler return 0;
13260250Shibler return tgetst1 (ptr, area);
13360250Shibler }
13460250Shibler
13560250Shibler /* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted,
13660250Shibler gives meaning of character following \, or a space if no special meaning.
13760250Shibler Eight characters per line within the string. */
13860250Shibler
13960250Shibler static char esctab[]
14060250Shibler = " \007\010 \033\014 \
14160250Shibler \012 \
14260250Shibler \015 \011 \013 \
14360250Shibler ";
14460250Shibler
14560250Shibler /* Given a pointer to a string value inside a termcap entry (`ptr'),
14660250Shibler copy the value and process \ and ^ abbreviations.
14760250Shibler Copy into block that *area points to,
14860250Shibler or to newly allocated storage if area is 0. */
14960250Shibler
15060250Shibler static char *
tgetst1(ptr,area)15160250Shibler tgetst1 (ptr, area)
15260250Shibler char *ptr;
15360250Shibler char **area;
15460250Shibler {
15560250Shibler register char *p, *r;
15660250Shibler register int c;
15760250Shibler register int size;
15860250Shibler char *ret;
15960250Shibler register int c1;
16060250Shibler
16160250Shibler if (!ptr)
16260250Shibler return 0;
16360250Shibler
16460250Shibler /* `ret' gets address of where to store the string */
16560250Shibler if (!area)
16660250Shibler {
16760250Shibler /* Compute size of block needed (may overestimate) */
16860250Shibler p = ptr;
16960250Shibler while ((c = *p++) && c != ':' && c != '\n');
17060250Shibler ret = (char *) xmalloc (p - ptr + 1);
17160250Shibler }
17260250Shibler else
17360250Shibler ret = *area;
17460250Shibler
17560250Shibler /* Copy the string value, stopping at null or colon. */
17660250Shibler /* Also process ^ and \ abbreviations. */
17760250Shibler p = ptr;
17860250Shibler r = ret;
17960250Shibler while ((c = *p++) && c != ':' && c != '\n')
18060250Shibler {
18160250Shibler if (c == '^')
18260250Shibler c = *p++ & 037;
18360250Shibler else if (c == '\\')
18460250Shibler {
18560250Shibler c = *p++;
18660250Shibler if (c >= '0' && c <= '7')
18760250Shibler {
18860250Shibler c -= '0';
18960250Shibler size = 0;
19060250Shibler
19160250Shibler while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7')
19260250Shibler {
19360250Shibler c *= 8;
19460250Shibler c += c1 - '0';
19560250Shibler p++;
19660250Shibler }
19760250Shibler }
19860250Shibler else if (c >= 0100 && c < 0200)
19960250Shibler {
20060250Shibler c1 = esctab[(c & ~040) - 0100];
20160250Shibler if (c1 != ' ')
20260250Shibler c = c1;
20360250Shibler }
20460250Shibler }
20560250Shibler *r++ = c;
20660250Shibler }
20760250Shibler *r = 0;
20860250Shibler /* Update *area */
20960250Shibler if (area)
21060250Shibler *area = r + 1;
21160250Shibler return ret;
21260250Shibler }
21360250Shibler
21460250Shibler /* Outputting a string with padding */
21560250Shibler
21660250Shibler short ospeed;
21760250Shibler char PC;
21860250Shibler
21960250Shibler /* Actual baud rate if positive;
22060250Shibler - baud rate / 100 if negative. */
22160250Shibler
22260250Shibler static short speeds[] =
22360250Shibler {
22460250Shibler #ifdef VMS
22560250Shibler 0, 50, 75, 110, 134, 150, -3, -6, -12, -18,
22660250Shibler -20, -24, -36, -48, -72, -96, -192
22760250Shibler #else /* not VMS */
22860250Shibler 0, 50, 75, 110, 135, 150, -2, -3, -6, -12,
22960250Shibler -18, -24, -48, -96, -192, -384
23060250Shibler #endif /* not VMS */
23160250Shibler };
23260250Shibler
tputs(string,nlines,outfun)23360250Shibler tputs (string, nlines, outfun)
23460250Shibler register char *string;
23560250Shibler int nlines;
23660250Shibler register int (*outfun) ();
23760250Shibler {
23860250Shibler register int padcount = 0;
23960250Shibler
24060250Shibler if (string == (char *) 0)
24160250Shibler return;
24260250Shibler while (*string >= '0' && *string <= '9')
24360250Shibler {
24460250Shibler padcount += *string++ - '0';
24560250Shibler padcount *= 10;
24660250Shibler }
24760250Shibler if (*string == '.')
24860250Shibler {
24960250Shibler string++;
25060250Shibler padcount += *string++ - '0';
25160250Shibler }
25260250Shibler if (*string == '*')
25360250Shibler {
25460250Shibler string++;
25560250Shibler padcount *= nlines;
25660250Shibler }
25760250Shibler while (*string)
25860250Shibler (*outfun) (*string++);
25960250Shibler
26060250Shibler /* padcount is now in units of tenths of msec. */
26160250Shibler padcount *= speeds[ospeed];
26260250Shibler padcount += 500;
26360250Shibler padcount /= 1000;
26460250Shibler if (speeds[ospeed] < 0)
26560250Shibler padcount = -padcount;
26660250Shibler else
26760250Shibler {
26860250Shibler padcount += 50;
26960250Shibler padcount /= 100;
27060250Shibler }
27160250Shibler
27260250Shibler while (padcount-- > 0)
27360250Shibler (*outfun) (PC);
27460250Shibler }
27560250Shibler
27660250Shibler /* Finding the termcap entry in the termcap data base */
27760250Shibler
27860250Shibler struct buffer
27960250Shibler {
28060250Shibler char *beg;
28160250Shibler int size;
28260250Shibler char *ptr;
28360250Shibler int ateof;
28460250Shibler int full;
28560250Shibler };
28660250Shibler
28760250Shibler /* Forward declarations of static functions */
28860250Shibler
28960250Shibler static int scan_file ();
29060250Shibler static char *gobble_line ();
29160250Shibler static int compare_contin ();
29260250Shibler static int name_match ();
29360250Shibler
29460250Shibler #ifdef VMS
29560250Shibler
29660250Shibler #include <rmsdef.h>
29760250Shibler #include <fab.h>
29860250Shibler #include <nam.h>
29960250Shibler
30060250Shibler static int
legal_filename_p(fn)30160250Shibler legal_filename_p (fn)
30260250Shibler char *fn;
30360250Shibler {
30460250Shibler struct FAB fab = cc$rms_fab;
30560250Shibler struct NAM nam = cc$rms_nam;
30660250Shibler char esa[NAM$C_MAXRSS];
30760250Shibler
30860250Shibler fab.fab$l_fna = fn;
30960250Shibler fab.fab$b_fns = strlen(fn);
31060250Shibler fab.fab$l_nam = &nam;
31160250Shibler fab.fab$l_fop = FAB$M_NAM;
31260250Shibler
31360250Shibler nam.nam$l_esa = esa;
31460250Shibler nam.nam$b_ess = sizeof esa;
31560250Shibler
31660250Shibler return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL;
31760250Shibler }
31860250Shibler
31960250Shibler #endif /* VMS */
32060250Shibler
32160250Shibler /* Find the termcap entry data for terminal type `name'
32260250Shibler and store it in the block that `bp' points to.
32360250Shibler Record its address for future use.
32460250Shibler
32560250Shibler If `bp' is zero, space is dynamically allocated. */
32660250Shibler
32760250Shibler int
tgetent(bp,name)32860250Shibler tgetent (bp, name)
32960250Shibler char *bp, *name;
33060250Shibler {
33160250Shibler register char *tem;
33260250Shibler register int fd;
33360250Shibler struct buffer buf;
33460250Shibler register char *bp1;
33560250Shibler char *bp2;
33660250Shibler char *term;
33760250Shibler int malloc_size = 0;
33860250Shibler register int c;
33960250Shibler char *tcenv; /* TERMCAP value, if it contais :tc=. */
34060250Shibler char *indirect = 0; /* Terminal type in :tc= in TERMCAP value. */
34160250Shibler int filep;
34260250Shibler
34360250Shibler tem = (char *) getenv ("TERMCAP");
34460250Shibler if (tem && *tem == 0) tem = 0;
34560250Shibler
34660250Shibler #ifdef VMS
34760250Shibler filep = tem && legal_filename_p (tem);
34860250Shibler #else
34960250Shibler filep = tem && (*tem == '/');
35060250Shibler #endif /* VMS */
35160250Shibler
35260250Shibler /* If tem is non-null and starts with / (in the un*x case, that is),
35360250Shibler it is a file name to use instead of /etc/termcap.
35460250Shibler If it is non-null and does not start with /,
35560250Shibler it is the entry itself, but only if
35660250Shibler the name the caller requested matches the TERM variable. */
35760250Shibler
35860250Shibler if (tem && !filep && !strcmp (name, getenv ("TERM")))
35960250Shibler {
36060250Shibler indirect = tgetst1 (find_capability (tem, "tc"), 0);
36160250Shibler if (!indirect)
36260250Shibler {
36360250Shibler if (!bp)
36460250Shibler bp = tem;
36560250Shibler else
36660250Shibler strcpy (bp, tem);
36760250Shibler goto ret;
36860250Shibler }
36960250Shibler else
37060250Shibler { /* we will need to read /etc/termcap */
37160250Shibler tcenv = tem;
37260250Shibler tem = 0;
37360250Shibler }
37460250Shibler }
37560250Shibler else
37660250Shibler indirect = (char *) 0;
37760250Shibler
37860250Shibler if (!tem)
37960250Shibler #ifdef VMS
38060250Shibler tem = "emacs_library:[etc]termcap.dat";
38160250Shibler #else
38260250Shibler tem = "/etc/termcap";
38360250Shibler #endif
38460250Shibler
38560250Shibler /* Here we know we must search a file and tem has its name. */
38660250Shibler
38760250Shibler fd = open (tem, 0, 0);
38860250Shibler if (fd < 0)
38960250Shibler return -1;
39060250Shibler
39160250Shibler buf.size = BUFSIZE;
39260250Shibler /* Add 1 to size to ensure room for terminating null. */
39360250Shibler buf.beg = (char *) xmalloc (buf.size + 1);
39460250Shibler term = indirect ? indirect : name;
39560250Shibler
39660250Shibler if (!bp)
39760250Shibler {
39860250Shibler malloc_size = indirect ? strlen (tcenv) + 1 : buf.size;
39960250Shibler bp = (char *) xmalloc (malloc_size);
40060250Shibler }
40160250Shibler bp1 = bp;
40260250Shibler
40360250Shibler if (indirect) /* copy the data from the environment variable */
40460250Shibler {
40560250Shibler strcpy (bp, tcenv);
40660250Shibler bp1 += strlen (tcenv);
40760250Shibler }
40860250Shibler
40960250Shibler while (term)
41060250Shibler {
41160250Shibler /* Scan file, reading it via buf, till find start of main entry */
41260250Shibler if (scan_file (term, fd, &buf) == 0)
41360250Shibler return 0;
41460250Shibler
41560250Shibler /* Free old `term' if appropriate. */
41660250Shibler if (term != name)
41760250Shibler free (term);
41860250Shibler
41960250Shibler /* If `bp' is malloc'd by us, make sure it is big enough. */
42060250Shibler if (malloc_size)
42160250Shibler {
42260250Shibler malloc_size = bp1 - bp + buf.size;
42360250Shibler tem = (char *) xrealloc (bp, malloc_size);
42460250Shibler bp1 += tem - bp;
42560250Shibler bp = tem;
42660250Shibler }
42760250Shibler
42860250Shibler bp2 = bp1;
42960250Shibler
43060250Shibler /* Copy the line of the entry from buf into bp. */
43160250Shibler tem = buf.ptr;
43260250Shibler while ((*bp1++ = c = *tem++) && c != '\n')
43360250Shibler /* Drop out any \ newline sequence. */
43460250Shibler if (c == '\\' && *tem == '\n')
43560250Shibler {
43660250Shibler bp1--;
43760250Shibler tem++;
43860250Shibler }
43960250Shibler *bp1 = 0;
44060250Shibler
44160250Shibler /* Does this entry refer to another terminal type's entry? */
44260250Shibler /* If something is found, copy it into heap and null-terminate it */
44360250Shibler term = tgetst1 (find_capability (bp2, "tc"), 0);
44460250Shibler }
44560250Shibler
44660250Shibler close (fd);
44760250Shibler free (buf.beg);
44860250Shibler
44960250Shibler if (malloc_size)
45060250Shibler {
45160250Shibler bp = (char *) xrealloc (bp, bp1 - bp + 1);
45260250Shibler }
45360250Shibler
45460250Shibler ret:
45560250Shibler term_entry = bp;
45660250Shibler if (malloc_size)
45760250Shibler return (int) bp;
45860250Shibler return 1;
45960250Shibler }
46060250Shibler
46160250Shibler /* Given file open on `fd' and buffer `bufp',
46260250Shibler scan the file from the beginning until a line is found
46360250Shibler that starts the entry for terminal type `string'.
46460250Shibler Returns 1 if successful, with that line in `bufp',
46560250Shibler or returns 0 if no entry found in the file. */
46660250Shibler
46760250Shibler static int
scan_file(string,fd,bufp)46860250Shibler scan_file (string, fd, bufp)
46960250Shibler char *string;
47060250Shibler int fd;
47160250Shibler register struct buffer *bufp;
47260250Shibler {
47360250Shibler register char *tem;
47460250Shibler register char *end;
47560250Shibler
47660250Shibler bufp->ptr = bufp->beg;
47760250Shibler bufp->full = 0;
47860250Shibler bufp->ateof = 0;
47960250Shibler *bufp->ptr = 0;
48060250Shibler
481*60297Shibler lseek (fd, (off_t) 0, 0);
48260250Shibler
48360250Shibler while (!bufp->ateof)
48460250Shibler {
48560250Shibler /* Read a line into the buffer */
48660250Shibler end = 0;
48760250Shibler do
48860250Shibler {
48960250Shibler /* if it is continued, append another line to it,
49060250Shibler until a non-continued line ends */
49160250Shibler end = gobble_line (fd, bufp, end);
49260250Shibler }
49360250Shibler while (!bufp->ateof && end[-2] == '\\');
49460250Shibler
49560250Shibler if (*bufp->ptr != '#'
49660250Shibler && name_match (bufp->ptr, string))
49760250Shibler return 1;
49860250Shibler
49960250Shibler /* Discard the line just processed */
50060250Shibler bufp->ptr = end;
50160250Shibler }
50260250Shibler return 0;
50360250Shibler }
50460250Shibler
50560250Shibler /* Return nonzero if NAME is one of the names specified
50660250Shibler by termcap entry LINE. */
50760250Shibler
50860250Shibler static int
name_match(line,name)50960250Shibler name_match (line, name)
51060250Shibler char *line, *name;
51160250Shibler {
51260250Shibler register char *tem;
51360250Shibler
51460250Shibler if (!compare_contin (line, name))
51560250Shibler return 1;
51660250Shibler /* This line starts an entry. Is it the right one? */
51760250Shibler for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++)
51860250Shibler if (*tem == '|' && !compare_contin (tem + 1, name))
51960250Shibler return 1;
52060250Shibler
52160250Shibler return 0;
52260250Shibler }
52360250Shibler
52460250Shibler static int
compare_contin(str1,str2)52560250Shibler compare_contin (str1, str2)
52660250Shibler register char *str1, *str2;
52760250Shibler {
52860250Shibler register int c1, c2;
52960250Shibler while (1)
53060250Shibler {
53160250Shibler c1 = *str1++;
53260250Shibler c2 = *str2++;
53360250Shibler while (c1 == '\\' && *str1 == '\n')
53460250Shibler {
53560250Shibler str1++;
53660250Shibler while ((c1 = *str1++) == ' ' || c1 == '\t');
53760250Shibler }
53860250Shibler if (c2 == '\0') /* end of type being looked up */
53960250Shibler {
54060250Shibler if (c1 == '|' || c1 == ':') /* If end of name in data base, */
54160250Shibler return 0; /* we win. */
54260250Shibler else
54360250Shibler return 1;
54460250Shibler }
54560250Shibler else if (c1 != c2)
54660250Shibler return 1;
54760250Shibler }
54860250Shibler }
54960250Shibler
55060250Shibler /* Make sure that the buffer <- `bufp' contains a full line
55160250Shibler of the file open on `fd', starting at the place `bufp->ptr'
55260250Shibler points to. Can read more of the file, discard stuff before
55360250Shibler `bufp->ptr', or make the buffer bigger.
55460250Shibler
55560250Shibler Returns the pointer to after the newline ending the line,
55660250Shibler or to the end of the file, if there is no newline to end it.
55760250Shibler
55860250Shibler Can also merge on continuation lines. If `append_end' is
55960250Shibler nonzero, it points past the newline of a line that is
56060250Shibler continued; we add another line onto it and regard the whole
56160250Shibler thing as one line. The caller decides when a line is continued. */
56260250Shibler
56360250Shibler static char *
gobble_line(fd,bufp,append_end)56460250Shibler gobble_line (fd, bufp, append_end)
56560250Shibler int fd;
56660250Shibler register struct buffer *bufp;
56760250Shibler char *append_end;
56860250Shibler {
56960250Shibler register char *end;
57060250Shibler register int nread;
57160250Shibler register char *buf = bufp->beg;
57260250Shibler register char *tem;
57360250Shibler
57460250Shibler if (append_end == 0)
57560250Shibler append_end = bufp->ptr;
57660250Shibler
57760250Shibler while (1)
57860250Shibler {
57960250Shibler end = append_end;
58060250Shibler while (*end && *end != '\n') end++;
58160250Shibler if (*end)
58260250Shibler break;
58360250Shibler if (bufp->ateof)
58460250Shibler return buf + bufp->full;
58560250Shibler if (bufp->ptr == buf)
58660250Shibler {
58760250Shibler if (bufp->full == bufp->size)
58860250Shibler {
58960250Shibler bufp->size *= 2;
59060250Shibler /* Add 1 to size to ensure room for terminating null. */
59160250Shibler tem = (char *) xrealloc (buf, bufp->size + 1);
59260250Shibler bufp->ptr = (bufp->ptr - buf) + tem;
59360250Shibler append_end = (append_end - buf) + tem;
59460250Shibler bufp->beg = buf = tem;
59560250Shibler }
59660250Shibler }
59760250Shibler else
59860250Shibler {
59960250Shibler append_end -= bufp->ptr - buf;
60060250Shibler bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf);
60160250Shibler bufp->ptr = buf;
60260250Shibler }
60360250Shibler if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full)))
60460250Shibler bufp->ateof = 1;
60560250Shibler bufp->full += nread;
60660250Shibler buf[bufp->full] = 0;
60760250Shibler }
60860250Shibler return end + 1;
60960250Shibler }
61060250Shibler
61160250Shibler #ifdef TEST
61260250Shibler
61360250Shibler #include <stdio.h>
61460250Shibler
main(argc,argv)61560250Shibler main (argc, argv)
61660250Shibler int argc;
61760250Shibler char **argv;
61860250Shibler {
61960250Shibler char *term;
62060250Shibler char *buf;
62160250Shibler
62260250Shibler term = argv[1];
62360250Shibler printf ("TERM: %s\n", term);
62460250Shibler
62560250Shibler buf = (char *) tgetent (0, term);
62660250Shibler if ((int) buf <= 0)
62760250Shibler {
62860250Shibler printf ("No entry.\n");
62960250Shibler return 0;
63060250Shibler }
63160250Shibler
63260250Shibler printf ("Entry: %s\n", buf);
63360250Shibler
63460250Shibler tprint ("cm");
63560250Shibler tprint ("AL");
63660250Shibler
63760250Shibler printf ("co: %d\n", tgetnum ("co"));
63860250Shibler printf ("am: %d\n", tgetflag ("am"));
63960250Shibler }
64060250Shibler
tprint(cap)64160250Shibler tprint (cap)
64260250Shibler char *cap;
64360250Shibler {
64460250Shibler char *x = tgetstr (cap, 0);
64560250Shibler register char *y;
64660250Shibler
64760250Shibler printf ("%s: ", cap);
64860250Shibler if (x)
64960250Shibler {
65060250Shibler for (y = x; *y; y++)
65160250Shibler if (*y <= ' ' || *y == 0177)
65260250Shibler printf ("\\%0o", *y);
65360250Shibler else
65460250Shibler putchar (*y);
65560250Shibler free (x);
65660250Shibler }
65760250Shibler else
65860250Shibler printf ("none");
65960250Shibler putchar ('\n');
66060250Shibler }
66160250Shibler
66260250Shibler #endif /* TEST */
66360250Shibler
664