source: trunk/third/tcsh/vms.termcap.c @ 12039

Revision 12039, 7.1 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12038, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/vms.termcap.c,v 1.1.1.2 1998-10-03 21:10:24 danw 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"
12RCSID("$Id: vms.termcap.c,v 1.1.1.2 1998-10-03 21:10:24 danw 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
34char            *capab;         /* the capability itself */
35
36extern char     *getenv();      /* new, improved getenv */
37extern FILE     *fopen();       /* old fopen */
38
39/*
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.
43 */
44
45int
46tgetent(bp, name)
47char    *bp;
48char    *name;
49{
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);
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
87sscanf 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/*
125 *      tgetnum - get the numeric terminal capability corresponding
126 *      to id. Returns the value, -1 if invalid.
127 */
128int
129tgetnum(id)
130char    *id;
131{
132        char    *cp;
133        int     ret;
134
135        if ((cp = capab) == NULL || id == NULL)
136                return(-1);
137        while (*++cp != ':')
138                ;
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);
150                }
151                while (*cp && *cp != ':')
152                        cp++;
153        }
154        return(-1);
155}
156
157/*
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.
161 */
162int
163tgetflag(id)
164char    *id;
165{
166        char    *cp;
167
168        if ((cp = capab) == NULL || id == NULL)
169                return(-1);
170        while (*++cp != ':')
171                ;
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++;
179        }
180        return(0);
181}
182
183/*
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.
187 */
188char *
189tgetstr(id, area)
190char    *id;
191char    **area;
192{
193        char    *cp;
194        char    *ret;
195        int     i;
196
197        if ((cp = capab) == NULL || id == NULL)
198                return(NULL);
199        while (*++cp != ':')
200                ;
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;
249                                        }
250                                        break;
251                                default :
252                                        **area = *cp;
253                                }
254                        *(*area)++ = '\0';
255                        return(ret);
256                }
257                while (*cp && *cp != ':')
258                        cp++;
259        }
260        return(NULL);
261}
262
263/*
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.
267 */
268char *
269tgoto(cm, destcol, destline)
270char    *cm;
271int     destcol;
272int     destline;
273{
274        register char   *rp;
275        static char     ret[24];
276        int             incr = 0;
277        int             argno = 0, numval;
278
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;
288
289                        case '%' :
290                                *rp++ = '%';
291                                break;
292
293                        case 'i' :
294                                incr = 1;
295                                break;
296
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;
304
305                        case 'r' :
306                                argno = 1;
307                                break;
308                        }
309
310                        break;
311                default :
312                        *rp++ = *cm;
313                }
314        }
315        *rp = '\0';
316        return(ret);
317}
318
319/*
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...
323 */
324int
325tputs(cp, affcnt, outc)
326register char   *cp;
327int             affcnt;
328int             (*outc)();
329{
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);
336}
337#endif /* _VMS_POSIX */
Note: See TracBrowser for help on using the repository browser.