]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcsh/vms.termcap.c
This commit was generated by cvs2svn to compensate for changes in r162852,
[FreeBSD/FreeBSD.git] / contrib / tcsh / vms.termcap.c
1 /* $Header: /src/pub/tcsh/vms.termcap.c,v 1.8 2005/03/03 16:49:16 kim 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("$Id: vms.termcap.c,v 1.8 2005/03/03 16:49:16 kim 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(bp, name)
49 char    *bp;
50 char    *name;
51 {
52         FILE    *fp;
53         char    *termfile;
54         char    *cp,
55                 *ptr,           /* temporary pointer */
56                 tmp[1024];      /* buffer for terminal name */
57         short   len = strlen(name);
58
59         capab = bp;
60
61         /* Use TERMCAP to override default. */
62
63         termfile = getenv("TERMCAP");
64         if (termfile == NULL ) termfile = "/etc/termcap";
65
66         if ((fp = fopen(termfile, "r")) == (FILE *) NULL) {
67                 fprintf(stderr, CGETS(31, 1,
68                         "Can't open TERMCAP: [%s]\n"), termfile);
69                 fprintf(stderr, CGETS(31, 2, "Can't open %s.\n"), termfile);
70                 sleep(1);
71                 return(-1);
72         }
73
74         while (fgets(bp, 1024, fp) != NULL) {
75                 /* Any line starting with # or NL is skipped as a comment */
76                 if ((*bp == '#') || (*bp == '\n')) continue;
77
78                 /* Look for lines which end with two backslashes,
79                 and then append the next line. */
80                 while (*(cp = &bp[strlen(bp) - 2]) == '\\')
81                         fgets(cp, 1024, fp);
82                 
83                 /* Skip over any spaces or tabs */
84                 for (++cp ; ISSPACE(*cp) ; cp++);
85
86                 /*  Make sure "name" matches exactly  (efth)  */
87
88 /* Here we might want to look at any aliases as well.  We'll use
89 sscanf to look at aliases.  These are delimited by '|'. */
90
91                 sscanf(bp,"%[^|]",tmp);
92                 if (strncmp(name, tmp, len) == 0) {
93                         fclose(fp);
94 #ifdef DEBUG
95         fprintf(stderr, CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
96         sleep(1);
97 #endif /* DEBUG */
98                         return(1);
99                 }
100                 ptr = bp;
101                 while ((ptr = strchr(ptr,'|')) != NULL) {
102                         ptr++;
103                         if (strchr(ptr,'|') == NULL) break;
104                         sscanf(ptr,"%[^|]",tmp);
105                         if (strncmp(name, tmp, len) == 0) {
106                                 fclose(fp);
107 #ifdef DEBUG
108         fprintf(stderr,CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
109         sleep(1);
110 #endif /* DEBUG */
111                                 return(1);
112                         }
113                 }
114         }
115         /* If we get here, then we haven't found a match. */
116         fclose(fp);
117 #ifdef DEBUG
118         fprintf(stderr,CGETS(31, 4, "No match found for %s in file %s\n"),
119                 name, termfile);
120         sleep(1);
121 #endif /* DEBUG */
122         return(0);
123         
124 }
125
126 /*
127  *      tgetnum - get the numeric terminal capability corresponding
128  *      to id. Returns the value, -1 if invalid.
129  */
130 int
131 tgetnum(id)
132 char    *id;
133 {
134         char    *cp;
135         int     ret;
136
137         if ((cp = capab) == NULL || id == NULL)
138                 return(-1);
139         while (*++cp != ':')
140                 ;
141         for (++cp ; *cp ; cp++) {
142                 while (ISSPACE(*cp))
143                         cp++;
144                 if (strncmp(cp, id, CAPABLEN) == 0) {
145                         while (*cp && *cp != ':' && *cp != '#')
146                                 cp++;
147                         if (*cp != '#')
148                                 return(-1);
149                         for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++)
150                                 ret = ret * 10 + *cp - '0';
151                         return(ret);
152                 }
153                 while (*cp && *cp != ':')
154                         cp++;
155         }
156         return(-1);
157 }
158
159 /*
160  *      tgetflag - get the boolean flag corresponding to id. Returns -1
161  *      if invalid, 0 if the flag is not in termcap entry, or 1 if it is
162  *      present.
163  */
164 int
165 tgetflag(id)
166 char    *id;
167 {
168         char    *cp;
169
170         if ((cp = capab) == NULL || id == NULL)
171                 return(-1);
172         while (*++cp != ':')
173                 ;
174         for (++cp ; *cp ; cp++) {
175                 while (ISSPACE(*cp))
176                         cp++;
177                 if (strncmp(cp, id, CAPABLEN) == 0)
178                         return(1);
179                 while (*cp && *cp != ':')
180                         cp++;
181         }
182         return(0);
183 }
184
185 /*
186  *      tgetstr - get the string capability corresponding to id and place
187  *      it in area (advancing area at same time). Expand escape sequences
188  *      etc. Returns the string, or NULL if it can't do it.
189  */
190 char *
191 tgetstr(id, area)
192 char    *id;
193 char    **area;
194 {
195         char    *cp;
196         char    *ret;
197         int     i;
198
199         if ((cp = capab) == NULL || id == NULL)
200                 return(NULL);
201         while (*++cp != ':')
202                 ;
203         for (++cp ; *cp ; cp++) {
204                 while (ISSPACE(*cp))
205                         cp++;
206                 if (strncmp(cp, id, CAPABLEN) == 0) {
207                         while (*cp && *cp != ':' && *cp != '=')
208                                 cp++;
209                         if (*cp != '=')
210                                 return(NULL);
211                         for (ret = *area, cp++; *cp && *cp != ':' ; 
212                                 (*area)++, cp++)
213                                 switch(*cp) {
214                                 case '^' :
215                                         **area = *++cp - '@'; /* fix (efth)*/
216                                         break;
217                                 case '\\' :
218                                         switch(*++cp) {
219                                         case 'E' :
220                                                 **area = CTL_ESC('\033');
221                                                 break;
222                                         case 'n' :
223                                                 **area = '\n';
224                                                 break;
225                                         case 'r' :
226                                                 **area = '\r';
227                                                 break;
228                                         case 't' :
229                                                 **area = '\t';
230                                                 break;
231                                         case 'b' :
232                                                 **area = '\b';
233                                                 break;
234                                         case 'f' :
235                                                 **area = '\f';
236                                                 break;
237                                         case '0' :
238                                         case '1' :
239                                         case '2' :
240                                         case '3' :
241                                                 for (i=0 ; *cp && ISDIGIT(*cp) ;
242                                                          cp++)
243                                                         i = i * 8 + *cp - '0';
244                                                 **area = i;
245                                                 cp--;
246                                                 break;
247                                         case '^' :
248                                         case '\\' :
249                                                 **area = *cp;
250                                                 break;
251                                         }
252                                         break;
253                                 default :
254                                         **area = *cp;
255                                 }
256                         *(*area)++ = '\0';
257                         return(ret);
258                 }
259                 while (*cp && *cp != ':')
260                         cp++;
261         }
262         return(NULL);
263 }
264
265 /*
266  *      tgoto - given the cursor motion string cm, make up the string
267  *      for the cursor to go to (destcol, destline), and return the string.
268  *      Returns "OOPS" if something's gone wrong, or the string otherwise.
269  */
270 char *
271 tgoto(cm, destcol, destline)
272 char    *cm;
273 int     destcol;
274 int     destline;
275 {
276         char    *rp;
277         static char     ret[24];
278         int             incr = 0;
279         int             argno = 0, numval;
280
281         for (rp = ret ; *cm ; cm++) {
282                 switch(*cm) {
283                 case '%' :
284                         switch(*++cm) {
285                         case '+' :
286                                 numval = (argno == 0 ? destline : destcol);
287                                 argno = 1 - argno;
288                                 *rp++ = numval + incr + *++cm;
289                                 break;
290
291                         case '%' :
292                                 *rp++ = '%';
293                                 break;
294
295                         case 'i' :
296                                 incr = 1;
297                                 break;
298
299                         case 'd' :
300                                 numval = (argno == 0 ? destline : destcol);
301                                 numval += incr;
302                                 argno = 1 - argno;
303                                 *rp++ = '0' + (numval/10);
304                                 *rp++ = '0' + (numval%10);
305                                 break;
306
307                         case 'r' :
308                                 argno = 1;
309                                 break;
310                         }
311
312                         break;
313                 default :
314                         *rp++ = *cm;
315                 }
316         }
317         *rp = '\0';
318         return(ret);
319 }
320
321 /*
322  *      tputs - put the string cp out onto the terminal, using the function
323  *      outc. This should do padding for the terminal, but I can't find a
324  *      terminal that needs padding at the moment...
325  */
326 int
327 tputs(cp, affcnt, outc)
328 char    *cp;
329 int             affcnt;
330 int             (*outc)();
331 {
332         unsigned long delay = 0;
333
334         if (cp == NULL)
335                 return(1);
336         /* do any padding interpretation - left null for MINIX just now */
337         for (delay = 0; *cp && ISDIGIT(*cp) ; cp++)
338                 delay = delay * 10 + *cp - '0';
339         while (*cp)
340                 (*outc)(*cp++);
341 #ifdef _OSD_POSIX
342         usleep(delay*100); /* strictly spoken, it should be *1000 */
343 #endif
344         return(1);
345 }
346 #endif /* _VMS_POSIX || _OSD_POSIX */