]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/tcsh/vms.termcap.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / tcsh / vms.termcap.c
1 /* $Header: /p/tcsh/cvsroot/tcsh/vms.termcap.c,v 1.11 2006/03/02 18:46:45 christos Exp $ */
2 /*
3  *      termcap.c       1.1     20/7/87         agc     Joypace Ltd
4  *
5  *      Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
6  *      This file may be freely distributed provided that this notice
7  *      remains attached.
8  *
9  *      A public domain implementation of the termcap(3) routines.
10  */
11 #include "sh.h"
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)
14 /*    efth      1988-Apr-29
15
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]
20
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
24 */
25
26 #include        <stdio.h>
27 #include        <string.h>
28
29 #define CAPABLEN        2
30
31 #define ISSPACE(c)  ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
32 #define ISDIGIT(x)  ((x) >= '0' && (x) <= '9')
33
34 char            *capab;         /* the capability itself */
35
36 extern char     *getenv();      /* new, improved getenv */
37 #ifndef fopen
38 extern FILE     *fopen();       /* old fopen */
39 #endif
40
41 /*
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.
45  */
46
47 int
48 tgetent(char *bp, char *name)
49 {
50         FILE    *fp;
51         char    *termfile;
52         char    *cp,
53                 *ptr,           /* temporary pointer */
54                 tmp[1024];      /* buffer for terminal name *//*FIXBUF*/
55         size_t  len = strlen(name);
56
57         capab = bp;
58
59         /* Use TERMCAP to override default. */
60
61         termfile = getenv("TERMCAP");
62         if (termfile == NULL ) termfile = "/etc/termcap";
63
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);
70         }
71
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;
75
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);
80
81                 /* Skip over any spaces or tabs */
82                 for (++cp ; ISSPACE(*cp) ; cp++);
83
84                 /*  Make sure "name" matches exactly  (efth)  */
85
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 '|'. */
88
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);
97                 }
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);
110                         }
111                 }
112         }
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);
121 }
122
123 /*
124  *      tgetnum - get the numeric terminal capability corresponding
125  *      to id. Returns the value, -1 if invalid.
126  */
127 int
128 tgetnum(char *id)
129 {
130         char    *cp;
131         int     ret;
132
133         if ((cp = capab) == NULL || id == NULL)
134                 return(-1);
135         while (*++cp != ':')
136                 ;
137         for (++cp ; *cp ; cp++) {
138                 while (ISSPACE(*cp))
139                         cp++;
140                 if (strncmp(cp, id, CAPABLEN) == 0) {
141                         while (*cp && *cp != ':' && *cp != '#')
142                                 cp++;
143                         if (*cp != '#')
144                                 return(-1);
145                         for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++)
146                                 ret = ret * 10 + *cp - '0';
147                         return(ret);
148                 }
149                 while (*cp && *cp != ':')
150                         cp++;
151         }
152         return(-1);
153 }
154
155 /*
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
158  *      present.
159  */
160 int
161 tgetflag(char *id)
162 {
163         char    *cp;
164
165         if ((cp = capab) == NULL || id == NULL)
166                 return(-1);
167         while (*++cp != ':')
168                 ;
169         for (++cp ; *cp ; cp++) {
170                 while (ISSPACE(*cp))
171                         cp++;
172                 if (strncmp(cp, id, CAPABLEN) == 0)
173                         return(1);
174                 while (*cp && *cp != ':')
175                         cp++;
176         }
177         return(0);
178 }
179
180 /*
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.
184  */
185 char *
186 tgetstr(char *id, char **area)
187 {
188         char    *cp;
189         char    *ret;
190         int     i;
191
192         if ((cp = capab) == NULL || id == NULL)
193                 return(NULL);
194         while (*++cp != ':')
195                 ;
196         for (++cp ; *cp ; cp++) {
197                 while (ISSPACE(*cp))
198                         cp++;
199                 if (strncmp(cp, id, CAPABLEN) == 0) {
200                         while (*cp && *cp != ':' && *cp != '=')
201                                 cp++;
202                         if (*cp != '=')
203                                 return(NULL);
204                         for (ret = *area, cp++; *cp && *cp != ':' ; 
205                                 (*area)++, cp++)
206                                 switch(*cp) {
207                                 case '^' :
208                                         **area = *++cp - '@'; /* fix (efth)*/
209                                         break;
210                                 case '\\' :
211                                         switch(*++cp) {
212                                         case 'E' :
213                                                 **area = CTL_ESC('\033');
214                                                 break;
215                                         case 'n' :
216                                                 **area = '\n';
217                                                 break;
218                                         case 'r' :
219                                                 **area = '\r';
220                                                 break;
221                                         case 't' :
222                                                 **area = '\t';
223                                                 break;
224                                         case 'b' :
225                                                 **area = '\b';
226                                                 break;
227                                         case 'f' :
228                                                 **area = '\f';
229                                                 break;
230                                         case '0' :
231                                         case '1' :
232                                         case '2' :
233                                         case '3' :
234                                                 for (i=0 ; *cp && ISDIGIT(*cp) ;
235                                                          cp++)
236                                                         i = i * 8 + *cp - '0';
237                                                 **area = i;
238                                                 cp--;
239                                                 break;
240                                         case '^' :
241                                         case '\\' :
242                                                 **area = *cp;
243                                                 break;
244                                         }
245                                         break;
246                                 default :
247                                         **area = *cp;
248                                 }
249                         *(*area)++ = '\0';
250                         return(ret);
251                 }
252                 while (*cp && *cp != ':')
253                         cp++;
254         }
255         return(NULL);
256 }
257
258 /*
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.
262  */
263 char *
264 tgoto(char *cm, int destcol, int destline)
265 {
266         char    *rp;
267         static char     ret[24];
268         int             incr = 0;
269         int             argno = 0, numval;
270
271         for (rp = ret ; *cm ; cm++) {
272                 switch(*cm) {
273                 case '%' :
274                         switch(*++cm) {
275                         case '+' :
276                                 numval = (argno == 0 ? destline : destcol);
277                                 argno = 1 - argno;
278                                 *rp++ = numval + incr + *++cm;
279                                 break;
280
281                         case '%' :
282                                 *rp++ = '%';
283                                 break;
284
285                         case 'i' :
286                                 incr = 1;
287                                 break;
288
289                         case 'd' :
290                                 numval = (argno == 0 ? destline : destcol);
291                                 numval += incr;
292                                 argno = 1 - argno;
293                                 *rp++ = '0' + (numval/10);
294                                 *rp++ = '0' + (numval%10);
295                                 break;
296
297                         case 'r' :
298                                 argno = 1;
299                                 break;
300                         }
301
302                         break;
303                 default :
304                         *rp++ = *cm;
305                 }
306         }
307         *rp = '\0';
308         return(ret);
309 }
310
311 /*
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...
315  */
316 int
317 tputs(char *cp, int affcnt, int (*outc)())
318 {
319         unsigned long delay = 0;
320
321         if (cp == NULL)
322                 return(1);
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';
326         while (*cp)
327                 (*outc)(*cp++);
328 #ifdef _OSD_POSIX
329         usleep(delay*100); /* strictly spoken, it should be *1000 */
330 #endif
331         return(1);
332 }
333 #endif /* _VMS_POSIX || _OSD_POSIX */