More minor IPI work.
[dragonfly/vkernel-mp.git] / contrib / tcsh / vms.termcap.c
blobdeef66f73c27723fd2f912868fd12f2fec343e3f
1 /* $Header: /src/pub/tcsh/vms.termcap.c,v 1.6 2000/06/10 23:32:42 kim Exp $ */
2 /*
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
7 * remains attached.
9 * A public domain implementation of the termcap(3) routines.
11 #include "sh.h"
12 RCSID("$Id: vms.termcap.c,v 1.6 2000/06/10 23:32:42 kim Exp $")
13 #if defined(_VMS_POSIX) || defined(_OSD_POSIX)
14 /* efth 1988-Apr-29
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
26 #include <stdio.h>
27 #include <string.h>
29 #define CAPABLEN 2
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 */
37 extern FILE *fopen(); /* old fopen */
40 * tgetent - get the termcap entry for terminal name, and put it
41 * in bp (which must be an array of 1024 chars). Returns 1 if
42 * termcap entry found, 0 if not found, and -1 if file not found.
45 int
46 tgetent(bp, name)
47 char *bp;
48 char *name;
50 FILE *fp;
51 char *termfile;
52 char *cp,
53 *ptr, /* temporary pointer */
54 tmp[1024]; /* buffer for terminal name */
55 short len = strlen(name);
57 capab = bp;
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);
68 sleep(1);
69 return(-1);
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]) == '\\')
79 fgets(cp, 1024, fp);
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) {
91 fclose(fp);
92 #ifdef DEBUG
93 fprintf(stderr, CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
94 sleep(1);
95 #endif /* DEBUG */
96 return(1);
98 ptr = bp;
99 while ((ptr = strchr(ptr,'|')) != NULL) {
100 ptr++;
101 if (strchr(ptr,'|') == NULL) break;
102 sscanf(ptr,"%[^|]",tmp);
103 if (strncmp(name, tmp, len) == 0) {
104 fclose(fp);
105 #ifdef DEBUG
106 fprintf(stderr,CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
107 sleep(1);
108 #endif /* DEBUG */
109 return(1);
113 /* If we get here, then we haven't found a match. */
114 fclose(fp);
115 #ifdef DEBUG
116 fprintf(stderr,CGETS(31, 4, "No match found for %s in file %s\n"),
117 name, termfile);
118 sleep(1);
119 #endif /* DEBUG */
120 return(0);
125 * tgetnum - get the numeric terminal capability corresponding
126 * to id. Returns the value, -1 if invalid.
129 tgetnum(id)
130 char *id;
132 char *cp;
133 int ret;
135 if ((cp = capab) == NULL || id == NULL)
136 return(-1);
137 while (*++cp != ':')
139 for (++cp ; *cp ; cp++) {
140 while (ISSPACE(*cp))
141 cp++;
142 if (strncmp(cp, id, CAPABLEN) == 0) {
143 while (*cp && *cp != ':' && *cp != '#')
144 cp++;
145 if (*cp != '#')
146 return(-1);
147 for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++)
148 ret = ret * 10 + *cp - '0';
149 return(ret);
151 while (*cp && *cp != ':')
152 cp++;
154 return(-1);
158 * tgetflag - get the boolean flag corresponding to id. Returns -1
159 * if invalid, 0 if the flag is not in termcap entry, or 1 if it is
160 * present.
163 tgetflag(id)
164 char *id;
166 char *cp;
168 if ((cp = capab) == NULL || id == NULL)
169 return(-1);
170 while (*++cp != ':')
172 for (++cp ; *cp ; cp++) {
173 while (ISSPACE(*cp))
174 cp++;
175 if (strncmp(cp, id, CAPABLEN) == 0)
176 return(1);
177 while (*cp && *cp != ':')
178 cp++;
180 return(0);
184 * tgetstr - get the string capability corresponding to id and place
185 * it in area (advancing area at same time). Expand escape sequences
186 * etc. Returns the string, or NULL if it can't do it.
188 char *
189 tgetstr(id, area)
190 char *id;
191 char **area;
193 char *cp;
194 char *ret;
195 int i;
197 if ((cp = capab) == NULL || id == NULL)
198 return(NULL);
199 while (*++cp != ':')
201 for (++cp ; *cp ; cp++) {
202 while (ISSPACE(*cp))
203 cp++;
204 if (strncmp(cp, id, CAPABLEN) == 0) {
205 while (*cp && *cp != ':' && *cp != '=')
206 cp++;
207 if (*cp != '=')
208 return(NULL);
209 for (ret = *area, cp++; *cp && *cp != ':' ;
210 (*area)++, cp++)
211 switch(*cp) {
212 case '^' :
213 **area = *++cp - '@'; /* fix (efth)*/
214 break;
215 case '\\' :
216 switch(*++cp) {
217 case 'E' :
218 **area = CTL_ESC('\033');
219 break;
220 case 'n' :
221 **area = '\n';
222 break;
223 case 'r' :
224 **area = '\r';
225 break;
226 case 't' :
227 **area = '\t';
228 break;
229 case 'b' :
230 **area = '\b';
231 break;
232 case 'f' :
233 **area = '\f';
234 break;
235 case '0' :
236 case '1' :
237 case '2' :
238 case '3' :
239 for (i=0 ; *cp && ISDIGIT(*cp) ;
240 cp++)
241 i = i * 8 + *cp - '0';
242 **area = i;
243 cp--;
244 break;
245 case '^' :
246 case '\\' :
247 **area = *cp;
248 break;
250 break;
251 default :
252 **area = *cp;
254 *(*area)++ = '\0';
255 return(ret);
257 while (*cp && *cp != ':')
258 cp++;
260 return(NULL);
264 * tgoto - given the cursor motion string cm, make up the string
265 * for the cursor to go to (destcol, destline), and return the string.
266 * Returns "OOPS" if something's gone wrong, or the string otherwise.
268 char *
269 tgoto(cm, destcol, destline)
270 char *cm;
271 int destcol;
272 int destline;
274 register char *rp;
275 static char ret[24];
276 int incr = 0;
277 int argno = 0, numval;
279 for (rp = ret ; *cm ; cm++) {
280 switch(*cm) {
281 case '%' :
282 switch(*++cm) {
283 case '+' :
284 numval = (argno == 0 ? destline : destcol);
285 argno = 1 - argno;
286 *rp++ = numval + incr + *++cm;
287 break;
289 case '%' :
290 *rp++ = '%';
291 break;
293 case 'i' :
294 incr = 1;
295 break;
297 case 'd' :
298 numval = (argno == 0 ? destline : destcol);
299 numval += incr;
300 argno = 1 - argno;
301 *rp++ = '0' + (numval/10);
302 *rp++ = '0' + (numval%10);
303 break;
305 case 'r' :
306 argno = 1;
307 break;
310 break;
311 default :
312 *rp++ = *cm;
315 *rp = '\0';
316 return(ret);
320 * tputs - put the string cp out onto the terminal, using the function
321 * outc. This should do padding for the terminal, but I can't find a
322 * terminal that needs padding at the moment...
325 tputs(cp, affcnt, outc)
326 register char *cp;
327 int affcnt;
328 int (*outc)();
330 if (cp == NULL)
331 return(1);
332 /* do any padding interpretation - left null for MINIX just now */
333 while (*cp)
334 (*outc)(*cp++);
335 return(1);
337 #endif /* _VMS_POSIX || _OSD_POSIX */