]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcsh/vms.termcap.c
Rename pass4check() to freeblock() and move from pass4.c to inode.c.
[FreeBSD/FreeBSD.git] / contrib / tcsh / vms.termcap.c
1 /*
2  *      termcap.c       1.1     20/7/87         agc     Joypace Ltd
3  *
4  *      Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
5  *      This file may be freely distributed provided that this notice
6  *      remains attached.
7  *
8  *      A public domain implementation of the termcap(3) routines.
9  */
10 #include "sh.h"
11
12 #if defined(_VMS_POSIX) || defined(_OSD_POSIX) || defined(__ANDROID__)
13 /*    efth      1988-Apr-29
14
15     - Correct when TERM != name and TERMCAP is defined   [tgetent]
16     - Correct the comparison for the terminal name       [tgetent]
17     - Correct the value of ^x escapes                    [tgetstr]
18     - Added %r to reverse row/column                     [tgoto]
19
20      Paul Gillingwater <paul@actrix.gen.nz> July 1992
21         - Modified to allow terminal aliases in termcap file
22         - Uses TERMCAP environment variable for file only
23 */
24
25 #include        <stdio.h>
26 #include        <string.h>
27
28 #define CAPABLEN        2
29
30 #define ISSPACE(c)  ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
31 #define ISDIGIT(x)  ((x) >= '0' && (x) <= '9')
32
33 char            *capab;         /* the capability itself */
34
35 extern char     *getenv();      /* new, improved getenv */
36 #ifndef fopen
37 extern FILE     *fopen();       /* old fopen */
38 #endif
39
40 /*
41  *      tgetent - get the termcap entry for terminal name, and put it
42  *      in bp (which must be an array of 1024 chars). Returns 1 if
43  *      termcap entry found, 0 if not found, and -1 if file not found.
44  */
45 int
46 tgetent(char *bp, char *name)
47 {
48 #ifdef __ANDROID__
49         /* Use static termcap entry since termcap file usually doesn't exist. */
50         capab = bp;
51         strcpy(bp,
52         "linux|linux console:"
53         ":am:eo:mi:ms:xn:xo:"
54         ":it#8:"
55         ":AL=\\E[%dL:DC=\\E[%dP:DL=\\E[%dM:IC=\\E[%d@:K2=\\E[G:al=\\E[L:"
56         ":bl=^G:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:cr=^M:"
57         ":cs=\\E[%i%d;%dr:ct=\\E[3g:dc=\\E[P:dl=\\E[M:do=^J:ec=\\E[%dX:"
58         ":ei=\\E[4l:ho=\\E[H:ic=\\E[@:im=\\E[4h:k1=\\E[[A:k2=\\E[[B:"
59         ":k3=\\E[[C:k4=\\E[[D:k5=\\E[[E:k6=\\E[17~:k7=\\E[18~:k8=\\E[19~:"
60         ":k9=\\E[20~:kD=\\E[3~:kI=\\E[2~:kN=\\E[6~:kP=\\E[5~:kb=\\177:"
61         ":kd=\\E[B:kh=\\E[1~:kl=\\E[D:kr=\\E[C:ku=\\E[A:le=^H:mb=\\E[5m:"
62         ":md=\\E[1m:me=\\E[0m:mh=\\E[2m:mr=\\E[7m:nd=\\E[C:nw=^M^J:"
63         ":rc=\\E8:sc=\\E7:se=\\E[27m:sf=^J:so=\\E[7m:sr=\\EM:st=\\EH:ta=^I:"
64         ":ue=\\E[24m:up=\\E[A:us=\\E[4m:vb=200\\E[?5h\\E[?5l:"
65         ":ve=\\E[?25h\\E[?0c:vi=\\E[?25l\\E[?1c:vs=\\E[?25h\\E[?0c:"
66         );
67         return(1);
68 #else
69         FILE    *fp;
70         char    *termfile;
71         char    *cp,
72                 *ptr,           /* temporary pointer */
73                 tmp[1024];      /* buffer for terminal name *//*FIXBUF*/
74         size_t  len = strlen(name);
75
76         capab = bp;
77
78         /* Use TERMCAP to override default. */
79
80         termfile = getenv("TERMCAP");
81         if (termfile == NULL ) termfile = "/etc/termcap";
82
83         if ((fp = fopen(termfile, "r")) == (FILE *) NULL) {
84                 fprintf(stderr, CGETS(31, 1,
85                         "Can't open TERMCAP: [%s]\n"), termfile);
86                 fprintf(stderr, CGETS(31, 2, "Can't open %s.\n"), termfile);
87                 sleep(1);
88                 return(-1);
89         }
90
91         while (fgets(bp, 1024, fp) != NULL) {
92                 /* Any line starting with # or NL is skipped as a comment */
93                 if ((*bp == '#') || (*bp == '\n')) continue;
94
95                 /* Look for lines which end with two backslashes,
96                 and then append the next line. */
97                 while (*(cp = &bp[strlen(bp) - 2]) == '\\')
98                         fgets(cp, 1024, fp);
99
100                 /* Skip over any spaces or tabs */
101                 for (++cp ; ISSPACE(*cp) ; cp++);
102
103                 /*  Make sure "name" matches exactly  (efth)  */
104
105 /* Here we might want to look at any aliases as well.  We'll use
106 sscanf to look at aliases.  These are delimited by '|'. */
107
108                 sscanf(bp,"%[^|]",tmp);
109                 if (strncmp(name, tmp, len) == 0) {
110                         fclose(fp);
111 #ifdef DEBUG
112         fprintf(stderr, CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
113         sleep(1);
114 #endif /* DEBUG */
115                         return(1);
116                 }
117                 ptr = bp;
118                 while ((ptr = strchr(ptr,'|')) != NULL) {
119                         ptr++;
120                         if (strchr(ptr,'|') == NULL) break;
121                         sscanf(ptr,"%[^|]",tmp);
122                         if (strncmp(name, tmp, len) == 0) {
123                                 fclose(fp);
124 #ifdef DEBUG
125         fprintf(stderr,CGETS(31, 3, "Found %s in %s.\n"), name, termfile);
126         sleep(1);
127 #endif /* DEBUG */
128                                 return(1);
129                         }
130                 }
131         }
132         /* If we get here, then we haven't found a match. */
133         fclose(fp);
134 #ifdef DEBUG
135         fprintf(stderr,CGETS(31, 4, "No match found for %s in file %s\n"),
136                 name, termfile);
137         sleep(1);
138 #endif /* DEBUG */
139         return(0);
140 #endif /* ANDROID */
141 }
142
143 /*
144  *      tgetnum - get the numeric terminal capability corresponding
145  *      to id. Returns the value, -1 if invalid.
146  */
147 int
148 tgetnum(char *id)
149 {
150         char    *cp;
151         int     ret;
152
153         if ((cp = capab) == NULL || id == NULL)
154                 return(-1);
155         while (*++cp != ':')
156                 ;
157         for (++cp ; *cp ; cp++) {
158                 while (ISSPACE(*cp))
159                         cp++;
160                 if (strncmp(cp, id, CAPABLEN) == 0) {
161                         while (*cp && *cp != ':' && *cp != '#')
162                                 cp++;
163                         if (*cp != '#')
164                                 return(-1);
165                         for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++)
166                                 ret = ret * 10 + *cp - '0';
167                         return(ret);
168                 }
169                 while (*cp && *cp != ':')
170                         cp++;
171         }
172         return(-1);
173 }
174
175 /*
176  *      tgetflag - get the boolean flag corresponding to id. Returns -1
177  *      if invalid, 0 if the flag is not in termcap entry, or 1 if it is
178  *      present.
179  */
180 int
181 tgetflag(char *id)
182 {
183         char    *cp;
184
185         if ((cp = capab) == NULL || id == NULL)
186                 return(-1);
187         while (*++cp != ':')
188                 ;
189         for (++cp ; *cp ; cp++) {
190                 while (ISSPACE(*cp))
191                         cp++;
192                 if (strncmp(cp, id, CAPABLEN) == 0)
193                         return(1);
194                 while (*cp && *cp != ':')
195                         cp++;
196         }
197         return(0);
198 }
199
200 /*
201  *      tgetstr - get the string capability corresponding to id and place
202  *      it in area (advancing area at same time). Expand escape sequences
203  *      etc. Returns the string, or NULL if it can't do it.
204  */
205 char *
206 tgetstr(char *id, char **area)
207 {
208         char    *cp;
209         char    *ret;
210         int     i;
211
212         if ((cp = capab) == NULL || id == NULL)
213                 return(NULL);
214         while (*++cp != ':')
215                 ;
216         for (++cp ; *cp ; cp++) {
217                 while (ISSPACE(*cp))
218                         cp++;
219                 if (strncmp(cp, id, CAPABLEN) == 0) {
220                         while (*cp && *cp != ':' && *cp != '=')
221                                 cp++;
222                         if (*cp != '=')
223                                 return(NULL);
224                         for (ret = *area, cp++; *cp && *cp != ':' ; 
225                                 (*area)++, cp++)
226                                 switch(*cp) {
227                                 case '^' :
228                                         **area = *++cp - '@'; /* fix (efth)*/
229                                         break;
230                                 case '\\' :
231                                         switch(*++cp) {
232                                         case 'E' :
233                                                 **area = CTL_ESC('\033');
234                                                 break;
235                                         case 'n' :
236                                                 **area = '\n';
237                                                 break;
238                                         case 'r' :
239                                                 **area = '\r';
240                                                 break;
241                                         case 't' :
242                                                 **area = '\t';
243                                                 break;
244                                         case 'b' :
245                                                 **area = '\b';
246                                                 break;
247                                         case 'f' :
248                                                 **area = '\f';
249                                                 break;
250                                         case '0' :
251                                         case '1' :
252                                         case '2' :
253                                         case '3' :
254                                                 for (i=0 ; *cp && ISDIGIT(*cp) ;
255                                                          cp++)
256                                                         i = i * 8 + *cp - '0';
257                                                 **area = i;
258                                                 cp--;
259                                                 break;
260                                         case '^' :
261                                         case '\\' :
262                                                 **area = *cp;
263                                                 break;
264                                         }
265                                         break;
266                                 default :
267                                         **area = *cp;
268                                 }
269                         *(*area)++ = '\0';
270                         return(ret);
271                 }
272                 while (*cp && *cp != ':')
273                         cp++;
274         }
275         return(NULL);
276 }
277
278 /*
279  *      tgoto - given the cursor motion string cm, make up the string
280  *      for the cursor to go to (destcol, destline), and return the string.
281  *      Returns "OOPS" if something's gone wrong, or the string otherwise.
282  */
283 char *
284 tgoto(char *cm, int destcol, int destline)
285 {
286         char    *rp;
287         static char     ret[24];
288         int             incr = 0;
289         int             argno = 0, numval;
290
291         for (rp = ret ; *cm ; cm++) {
292                 switch(*cm) {
293                 case '%' :
294                         switch(*++cm) {
295                         case '+' :
296                                 numval = (argno == 0 ? destline : destcol);
297                                 argno = 1 - argno;
298                                 *rp++ = numval + incr + *++cm;
299                                 break;
300
301                         case '%' :
302                                 *rp++ = '%';
303                                 break;
304
305                         case 'i' :
306                                 incr = 1;
307                                 break;
308
309                         case 'd' :
310                                 numval = (argno == 0 ? destline : destcol);
311                                 numval += incr;
312                                 argno = 1 - argno;
313                                 *rp++ = '0' + (numval/10);
314                                 *rp++ = '0' + (numval%10);
315                                 break;
316
317                         case 'r' :
318                                 argno = 1;
319                                 break;
320                         }
321
322                         break;
323                 default :
324                         *rp++ = *cm;
325                 }
326         }
327         *rp = '\0';
328         return(ret);
329 }
330
331 /*
332  *      tputs - put the string cp out onto the terminal, using the function
333  *      outc. This should do padding for the terminal, but I can't find a
334  *      terminal that needs padding at the moment...
335  */
336 int
337 tputs(char *cp, int affcnt, int (*outc)())
338 {
339         unsigned long delay = 0;
340
341         if (cp == NULL)
342                 return(1);
343         /* do any padding interpretation - left null for MINIX just now */
344         for (delay = 0; *cp && ISDIGIT(*cp) ; cp++)
345                 delay = delay * 10 + *cp - '0';
346         while (*cp)
347                 (*outc)(*cp++);
348 #ifdef _OSD_POSIX
349         usleep(delay*100); /* strictly spoken, it should be *1000 */
350 #endif
351         return(1);
352 }
353 #endif /* _VMS_POSIX || _OSD_POSIX */