. pci driver now returns devices, even when they have been pci_reserve()d
[minix3.git] / lib / other / termcap.c
blob4d3fa2f0274561fccf380a2579f92917403c5817
1 /*
2 * termcap.c V1.1 20/7/87 agc Joypace Ltd
4 * Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
5 * This file may be freely distributed provided that this notice
6 * remains attached.
8 * A public domain implementation of the termcap(3) routines.
12 * Klamer Schutte V1.2 Nov. 1988
14 * - Can match multiple terminal names [tgetent]
15 * - Removal of **area assignments [tgetstr]
17 * Terrence W. Holm V1.3 May, Sep, Oct. 1988
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]
25 * Terrence W. Holm V1.4 Jan. 1989
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]
32 #include <lib.h>
33 #include <termcap.h>
34 #include <ctype.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
39 char *capab = (char *)NULL; /* the capability itself */
41 #if 0
42 /* The following are not yet used. */
43 extern short ospeed; /* output speed */
44 extern char PC; /* padding character */
45 extern char *BC; /* back cursor movement */
46 extern char *UP; /* up cursor movement */
47 #endif
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.
55 int tgetent(bp, name)
56 char *bp;
57 char *name;
59 FILE *fp;
60 char *file;
61 char *term;
62 short len = strlen(name);
64 capab = bp;
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. */
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";
81 if ((fp = fopen(file, "r")) == (FILE *) NULL) {
82 capab = (char *)NULL; /* no valid termcap */
83 return(-1);
85 for (;;) {
86 /* Read in each definition */
87 int def_len = 0;
88 char *cp = bp;
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);
96 def_len = strlen(bp) - 2;
97 } while (bp[def_len] == '\\');
99 while (isspace(*cp)) cp++;
101 /* Comment lines start with a '#' */
102 if (*cp == '#') continue;
104 /* See if any of the terminal names in this definition */
105 /* Match "name". */
107 do {
108 if (strncmp(name, cp, len) == 0 &&
109 (cp[len] == '|' || cp[len] == ':')) {
110 fclose(fp);
111 return(1);
113 while ((*cp) && (*cp != '|') && (*cp != ':')) cp++;
114 } while (*cp++ == '|');
120 * tgetnum - get the numeric terminal capability corresponding
121 * to id. Returns the value, -1 if invalid.
124 int tgetnum(id)
125 char *id;
127 register char *cp = capab;
129 if (cp == (char *)NULL || id == (char *)NULL) return(-1);
131 for (;;) {
132 while (*cp++ != ':')
133 if (cp[-1] == '\0') return(-1);
135 while (isspace(*cp)) cp++;
137 if (strncmp(cp, id, 2) == 0 && cp[2] == '#') return(atoi(cp + 3));
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.
148 int tgetflag(id)
149 char *id;
151 register char *cp = capab;
153 if (cp == (char *)NULL || id == (char *)NULL) return(-1);
155 for (;;) {
156 while (*cp++ != ':')
157 if (cp[-1] == '\0') return(0);
159 while (isspace(*cp)) cp++;
161 if (strncmp(cp, id, 2) == 0) return(1);
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.
172 char *tgetstr(id, area)
173 char *id;
174 char **area;
176 register char *cp = capab;
177 register char *wsp = *area; /* workspace pointer */
179 if (cp == (char *)NULL || id == (char *)NULL) return((char *)NULL);
181 for (;;) {
182 while (*cp++ != ':')
183 if (cp[-1] == '\0') return((char *)NULL);
185 while (isspace(*cp)) cp++;
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;
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':
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;
227 default:
228 *wsp = *cp;
230 break;
232 default: *wsp = *cp;
235 *wsp++ = '\0';
238 char *ret = *area;
239 *area = wsp;
240 return(ret);
243 } /* end for(;;) */
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.
254 char *tgoto(cm, destcol, destline)
255 char *cm;
256 int destcol;
257 int destline;
259 PRIVATE char ret[24];
260 char *rp = ret;
261 int incr = 0;
262 int argno = 0;
263 int numval;
265 for (; *cm; cm++) {
266 if (*cm == '%') {
267 switch (*++cm) {
268 case 'i': incr = 1; break;
270 case 'r': argno = 1; break;
272 case '+':
273 numval = (argno == 0 ? destline : destcol);
274 *rp++ = numval + incr + *++cm;
275 argno = 1 - argno;
276 break;
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;
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;
295 case '%': *rp++ = '%'; break;
297 default: return("OOPS");
300 } else
301 *rp++ = *cm;
304 *rp = '\0';
305 return(ret);
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...
316 int tputs(cp, affcnt, outc)
317 register char *cp;
318 int affcnt;
319 _PROTOTYPE( void (*outc), (int ch));
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);