1 /* $Header: /p/tcsh/cvsroot/tcsh/vms.termcap.c,v 1.11 2006/03/02 18:46:45 christos Exp $ */
3 * termcap.c 1.1 20/7/87 agc Joypace Ltd
5 * Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
6 * This file may be freely distributed provided that this notice
9 * A public domain implementation of the termcap(3) routines.
12 RCSID("$tcsh: vms.termcap.c,v 1.11 2006/03/02 18:46:45 christos Exp $")
13 #if defined(_VMS_POSIX) || defined(_OSD_POSIX)
16 - Correct when TERM != name and TERMCAP is defined [tgetent]
17 - Correct the comparison for the terminal name [tgetent]
18 - Correct the value of ^x escapes [tgetstr]
19 - Added %r to reverse row/column [tgoto]
21 Paul Gillingwater <paul@actrix.gen.nz> July 1992
22 - Modified to allow terminal aliases in termcap file
23 - Uses TERMCAP environment variable for file only
31 #define ISSPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
32 #define ISDIGIT(x) ((x) >= '0' && (x) <= '9')
34 char *capab; /* the capability itself */
36 extern char *getenv(); /* new, improved getenv */
38 extern FILE *fopen(); /* old fopen */
42 * tgetent - get the termcap entry for terminal name, and put it
43 * in bp (which must be an array of 1024 chars). Returns 1 if
44 * termcap entry found, 0 if not found, and -1 if file not found.
48 tgetent(char *bp, char *name)
53 *ptr, /* temporary pointer */
54 tmp[1024]; /* buffer for terminal name *//*FIXBUF*/
55 size_t len = strlen(name);
59 /* Use TERMCAP to override default. */
61 termfile = getenv("TERMCAP");
62 if (termfile == NULL ) termfile = "/etc/termcap";
64 if ((fp = fopen(termfile, "r")) == (FILE *) NULL) {
65 fprintf(stderr, CGETS(31, 1,
66 "Can't open TERMCAP: [%s]\n"), termfile);
67 fprintf(stderr, CGETS(31, 2, "Can't open %s.\n"), termfile);
72 while (fgets(bp, 1024, fp) != NULL) {
73 /* Any line starting with # or NL is skipped as a comment */
74 if ((*bp == '#') || (*bp == '\n')) continue;
76 /* Look for lines which end with two backslashes,
77 and then append the next line. */
78 while (*(cp = &bp[strlen(bp) - 2]) == '\\')
81 /* Skip over any spaces or tabs */
82 for (++cp ; ISSPACE(*cp) ; cp++);
84 /* Make sure "name" matches exactly (efth) */
86 /* Here we might want to look at any aliases as well. We'll use
87 sscanf to look at aliases. These are delimited by '|'. */
89 sscanf(bp,"%[^|]",tmp);
90 if (strncmp(name, tmp, len) == 0) {
93 fprintf(stderr, CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
99 while ((ptr = strchr(ptr,'|')) != NULL) {
101 if (strchr(ptr,'|') == NULL) break;
102 sscanf(ptr,"%[^|]",tmp);
103 if (strncmp(name, tmp, len) == 0) {
106 fprintf(stderr,CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
113 /* If we get here, then we haven't found a match. */
116 fprintf(stderr,CGETS(31, 4, "No match found for %s in file %s\n"),
124 * tgetnum - get the numeric terminal capability corresponding
125 * to id. Returns the value, -1 if invalid.
133 if ((cp = capab) == NULL || id == NULL)
137 for (++cp ; *cp ; cp++) {
140 if (strncmp(cp, id, CAPABLEN) == 0) {
141 while (*cp && *cp != ':' && *cp != '#')
145 for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++)
146 ret = ret * 10 + *cp - '0';
149 while (*cp && *cp != ':')
156 * tgetflag - get the boolean flag corresponding to id. Returns -1
157 * if invalid, 0 if the flag is not in termcap entry, or 1 if it is
165 if ((cp = capab) == NULL || id == NULL)
169 for (++cp ; *cp ; cp++) {
172 if (strncmp(cp, id, CAPABLEN) == 0)
174 while (*cp && *cp != ':')
181 * tgetstr - get the string capability corresponding to id and place
182 * it in area (advancing area at same time). Expand escape sequences
183 * etc. Returns the string, or NULL if it can't do it.
186 tgetstr(char *id, char **area)
192 if ((cp = capab) == NULL || id == NULL)
196 for (++cp ; *cp ; cp++) {
199 if (strncmp(cp, id, CAPABLEN) == 0) {
200 while (*cp && *cp != ':' && *cp != '=')
204 for (ret = *area, cp++; *cp && *cp != ':' ;
208 **area = *++cp - '@'; /* fix (efth)*/
213 **area = CTL_ESC('\033');
234 for (i=0 ; *cp && ISDIGIT(*cp) ;
236 i = i * 8 + *cp - '0';
252 while (*cp && *cp != ':')
259 * tgoto - given the cursor motion string cm, make up the string
260 * for the cursor to go to (destcol, destline), and return the string.
261 * Returns "OOPS" if something's gone wrong, or the string otherwise.
264 tgoto(char *cm, int destcol, int destline)
269 int argno = 0, numval;
271 for (rp = ret ; *cm ; cm++) {
276 numval = (argno == 0 ? destline : destcol);
278 *rp++ = numval + incr + *++cm;
290 numval = (argno == 0 ? destline : destcol);
293 *rp++ = '0' + (numval/10);
294 *rp++ = '0' + (numval%10);
312 * tputs - put the string cp out onto the terminal, using the function
313 * outc. This should do padding for the terminal, but I can't find a
314 * terminal that needs padding at the moment...
317 tputs(char *cp, int affcnt, int (*outc)())
319 unsigned long delay = 0;
323 /* do any padding interpretation - left null for MINIX just now */
324 for (delay = 0; *cp && ISDIGIT(*cp) ; cp++)
325 delay = delay * 10 + *cp - '0';
329 usleep(delay*100); /* strictly spoken, it should be *1000 */
333 #endif /* _VMS_POSIX || _OSD_POSIX */