source: trunk/minix/lib/other/termcap.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 6.9 KB
Line 
1/*
2 * termcap.c V1.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 *
11 *
12 * Klamer Schutte V1.2 Nov. 1988
13 *
14 * - Can match multiple terminal names [tgetent]
15 * - Removal of **area assignments [tgetstr]
16 *
17 * Terrence W. Holm V1.3 May, Sep, Oct. 1988
18 *
19 * - Correct when TERM != name and TERMCAP is defined [tgetent]
20 * - Correct the comparison for the terminal name [tgetent]
21 * - Correct the value of ^x escapes [tgetstr]
22 * - Added %r to reverse row/column [tgoto]
23 * - Fixed end of definition test [tgetnum/flag/str]
24 *
25 * Terrence W. Holm V1.4 Jan. 1989
26 *
27 * - Incorporated Klamer's V1.2 fixes into V1.3
28 * - Added %d, (old %d is now %2) [tgoto]
29 * - Allow '#' comments in definition file [tgetent]
30 */
31
32#include <lib.h>
33#include <termcap.h>
34#include <ctype.h>
35#include <stdlib.h>
36#include <string.h>
37#include <stdio.h>
38
39char *capab = (char *)NULL; /* the capability itself */
40
41#if 0
42/* The following are not yet used. */
43extern short ospeed; /* output speed */
44extern char PC; /* padding character */
45extern char *BC; /* back cursor movement */
46extern char *UP; /* up cursor movement */
47#endif
48
49/*
50 * tgetent - get the termcap entry for terminal name, and put it
51 * in bp (which must be an array of 1024 chars). Returns 1 if
52 * termcap entry found, 0 if not found, and -1 if file not found.
53 */
54
55int tgetent(bp, name)
56char *bp;
57char *name;
58{
59 FILE *fp;
60 char *file;
61 char *term;
62 short len = strlen(name);
63
64 capab = bp;
65
66 /* If TERMCAP begins with a '/' then use TERMCAP as the path */
67 /* Name of the termcap definitions file. If TERMCAP is a */
68 /* Definition and TERM equals "name" then use TERMCAP as the */
69 /* Definition. Otherwise use "/etc/termcap" as the path name. */
70
71 if ((file = getenv("TERMCAP")) == (char *)NULL)
72 file = "/etc/termcap";
73 else if (*file != '/')
74 if ((term = getenv("TERM")) != (char *)NULL && strcmp(term, name) == 0) {
75 *bp = '\0';
76 strncat(bp, file, 1023);
77 return(1);
78 } else
79 file = "/etc/termcap";
80
81 if ((fp = fopen(file, "r")) == (FILE *) NULL) {
82 capab = (char *)NULL; /* no valid termcap */
83 return(-1);
84 }
85 for (;;) {
86 /* Read in each definition */
87 int def_len = 0;
88 char *cp = bp;
89
90 do {
91 if (fgets(&bp[def_len], (unsigned int)(1024 - def_len), fp) == (char *)NULL) {
92 fclose(fp);
93 capab = (char *)NULL; /* no valid termcap */
94 return(0);
95 }
96 def_len = strlen(bp) - 2;
97 } while (bp[def_len] == '\\');
98
99 while (isspace(*cp)) cp++;
100
101 /* Comment lines start with a '#' */
102 if (*cp == '#') continue;
103
104 /* See if any of the terminal names in this definition */
105 /* Match "name". */
106
107 do {
108 if (strncmp(name, cp, len) == 0 &&
109 (cp[len] == '|' || cp[len] == ':')) {
110 fclose(fp);
111 return(1);
112 }
113 while ((*cp) && (*cp != '|') && (*cp != ':')) cp++;
114 } while (*cp++ == '|');
115 }
116}
117
118
119/*
120 * tgetnum - get the numeric terminal capability corresponding
121 * to id. Returns the value, -1 if invalid.
122 */
123
124int tgetnum(id)
125char *id;
126{
127 register char *cp = capab;
128
129 if (cp == (char *)NULL || id == (char *)NULL) return(-1);
130
131 for (;;) {
132 while (*cp++ != ':')
133 if (cp[-1] == '\0') return(-1);
134
135 while (isspace(*cp)) cp++;
136
137 if (strncmp(cp, id, 2) == 0 && cp[2] == '#') return(atoi(cp + 3));
138 }
139}
140
141
142/*
143 * tgetflag - get the boolean flag corresponding to id. Returns -1
144 * if invalid, 0 if the flag is not in termcap entry, or 1 if it is
145 * present.
146 */
147
148int tgetflag(id)
149char *id;
150{
151 register char *cp = capab;
152
153 if (cp == (char *)NULL || id == (char *)NULL) return(-1);
154
155 for (;;) {
156 while (*cp++ != ':')
157 if (cp[-1] == '\0') return(0);
158
159 while (isspace(*cp)) cp++;
160
161 if (strncmp(cp, id, 2) == 0) return(1);
162 }
163}
164
165
166/*
167 * tgetstr - get the string capability corresponding to id and place
168 * it in area (advancing area at same time). Expand escape sequences
169 * etc. Returns the string, or NULL if it can't do it.
170 */
171
172char *tgetstr(id, area)
173char *id;
174char **area;
175{
176 register char *cp = capab;
177 register char *wsp = *area; /* workspace pointer */
178
179 if (cp == (char *)NULL || id == (char *)NULL) return((char *)NULL);
180
181 for (;;) {
182 while (*cp++ != ':')
183 if (cp[-1] == '\0') return((char *)NULL);
184
185 while (isspace(*cp)) cp++;
186
187 if (strncmp(cp, id, 2) == 0 && cp[2] == '=') {
188 for (cp += 3; *cp && *cp != ':'; wsp++, cp++) switch (*cp) {
189 case '^':
190 *wsp = *++cp - '@';
191 break;
192
193 case '\\':
194 switch (*++cp) {
195 case 'E':
196 *wsp = '\033';
197 break;
198 case 'n':
199 *wsp = '\n';
200 break;
201 case 'r':
202 *wsp = '\r';
203 break;
204 case 't':
205 *wsp = '\t';
206 break;
207 case 'b':
208 *wsp = '\b';
209 break;
210 case 'f':
211 *wsp = '\f';
212 break;
213 case '0':
214 case '1':
215 case '2':
216 case '3':
217 {
218 int i;
219 int t = 0;
220 for (i = 0; i < 3 &&
221 isdigit(*cp); ++i, ++cp)
222 t = t * 8 + *cp - '0';
223 *wsp = t;
224 cp--;
225 break;
226 }
227 default:
228 *wsp = *cp;
229 }
230 break;
231
232 default: *wsp = *cp;
233 }
234
235 *wsp++ = '\0';
236
237 {
238 char *ret = *area;
239 *area = wsp;
240 return(ret);
241 }
242 }
243 } /* end for(;;) */
244}
245
246
247
248/*
249 * tgoto - given the cursor motion string cm, make up the string
250 * for the cursor to go to (destcol, destline), and return the string.
251 * Returns "OOPS" if something's gone wrong, or the string otherwise.
252 */
253
254char *tgoto(cm, destcol, destline)
255char *cm;
256int destcol;
257int destline;
258{
259 PRIVATE char ret[24];
260 char *rp = ret;
261 int incr = 0;
262 int argno = 0;
263 int numval;
264
265 for (; *cm; cm++) {
266 if (*cm == '%') {
267 switch (*++cm) {
268 case 'i': incr = 1; break;
269
270 case 'r': argno = 1; break;
271
272 case '+':
273 numval = (argno == 0 ? destline : destcol);
274 *rp++ = numval + incr + *++cm;
275 argno = 1 - argno;
276 break;
277
278 case '2':
279 numval = (argno == 0 ? destline : destcol);
280 numval = (numval + incr) % 100;
281 *rp++ = '0' + (numval / 10);
282 *rp++ = '0' + (numval % 10);
283 argno = 1 - argno;
284 break;
285
286 case 'd':
287 numval = (argno == 0 ? destline : destcol);
288 numval = (numval + incr) % 1000;
289 if (numval > 99) *rp++ = '0' + (numval / 100);
290 if (numval > 9) *rp++ = '0' + (numval / 10) % 10;
291 *rp++ = '0' + (numval % 10);
292 argno = 1 - argno;
293 break;
294
295 case '%': *rp++ = '%'; break;
296
297 default: return("OOPS");
298 }
299
300 } else
301 *rp++ = *cm;
302 }
303
304 *rp = '\0';
305 return(ret);
306}
307
308
309
310/*
311 * tputs - put the string cp out onto the terminal, using the function
312 * outc. This should do padding for the terminal, but I can't find a
313 * terminal that needs padding at the moment...
314 */
315
316int tputs(cp, affcnt, outc)
317register char *cp;
318int affcnt;
319_PROTOTYPE( void (*outc), (int ch));
320{
321 if (cp == (char *)NULL) return(1);
322 /* Do any padding interpretation - left null for MINIX just now */
323 while (*cp) (*outc) (*cp++);
324 return(1);
325}
Note: See TracBrowser for help on using the repository browser.