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