xref: /original-bsd/local/local.cmd/dis.c (revision e01d5481)
1 #ifndef lint
2 static char sccsid[] = "@(#)dis.c	1.2 (Berkeley) 07/05/84";
3 #endif
4 
5 /*
6 **	Dis -- VDU page display program
7 **
8 **	"dis [-t<timeout>] [-c<refresh count>] [-u]"
9 **
10 **	Bugs and comments to:	Piers Lauder
11 **				Dept of Comp Sci
12 **				Sydney University
13 **	May '80.
14 */
15 
16 #include	<signal.h>
17 #include	<setjmp.h>
18 #include	<sgtty.h>
19 #include	<stdio.h>
20 
21 /*
22 **	Parameters
23 */
24 
25 #define		MAXWID		132
26 #define		MAXLEN		80
27 
28 
29 /*
30 **	Screen buffer
31 */
32 
33 char *		Buf;
34 
35 /*
36 **	Term Cap
37 */
38 
39 char		*CM, *CL;
40 short		amflag;
41 
42 extern short	ospeed;
43 extern char	PC, *BC, *UP;
44 
45 extern char *	tgoto();
46 extern char *	tgetstr();
47 
48 /*
49 **	Screen macro
50 */
51 
52 #define		putcm(cp,p,c)		if(*cp++!=c){\
53 						if(move((--cp)-p))\
54 							putc(c,stdout);\
55 						*cp++=c;\
56 					}
57 
58 /*
59 **	Miscellaneous
60 */
61 
62 jmp_buf		alrmbuf;
63 short		width;
64 short		Width;		/* width - 1 */
65 short		length;
66 short		Length;		/* length - 1 */
67 char *		name;
68 unsigned	timeout;
69 short		rcount;
70 
71 void
72 		tcinit(),
73 		dis(),
74 		warn(),
75 		terror(),
76 		outc();
77 
78 int		alrmcatch();
79 
80 /*
81 **	Externals
82 */
83 
84 extern char	_sobuf[];
85 extern char *	tgetstr();
86 extern char *	malloc();
87 extern char *	getenv();
88 
89 
90 
main(argc,argv)91 main(argc, argv)
92 	register int		argc;
93 	register char *		argv[];
94 {
95 	register char *		cp;
96 	register unsigned	size;
97 
98 	name = *argv++;
99 	argc--;
100 
101 	while ( argc )
102 	{
103 		switch( argv[0][0] )
104 		{
105 		 case '-':	argv[0]++;
106 				continue;
107 		 case 't':	timeout = atoi(&argv[0][1]);
108 				break;
109 		 case 'c':	rcount = atoi(&argv[0][1]);
110 				break;
111 		 case 'u':	setbuf(stdin, NULL);
112 				break;
113 		 default:	fprintf(stderr, "%s: bad arg - %s\n", name, argv[0] );
114 				return 1;
115 		}
116 		argc--;
117 		argv++;
118 	}
119 
120 	setbuf(stdout, _sobuf);
121 	tcinit();
122 	size = length * width;
123 	if ( (Buf = malloc(size)) == (char *)0 )
124 	{
125 		fprintf(stderr, "No memory\n");
126 		exit(2);
127 	}
128 	bzero(Buf, size);
129 
130 	Length = length - 1;
131 	Width = width - 1;
132 	dis(size);
133 
134 	return 0;
135 }
136 
137 
138 
139 
140 void
dis(size)141 dis(size)
142 	unsigned		size;
143 {
144 	register char *		ep;
145 	register char *		p = Buf;
146 	register int		c;
147 	register int		line;
148 	/** on stack to avoid setjmp **/
149 	char *			cp;
150 	char *			lastend;
151 	int			rc;
152 
153 	lastend = p;
154 	rc = rcount;
155 
156 	do
157 	{
158 		line = 0;
159 		cp = p;
160 		ep = cp+width;
161 
162 		if ( timeout == 0 || setjmp(alrmbuf) == 0 )
163 		{
164 			if ( timeout )
165 			{
166 				signal(SIGALRM, alrmcatch);
167 				alarm(timeout);
168 			}
169 			while ( (c = getchar()) != EOF )
170 			{
171 				if ( rcount && !rc )
172 				{
173 					tputs(CL, 1, outc);
174 					bzero(p, size);
175 					rc = rcount;
176 				}
177 				if ( c < ' ' )
178 				{
179 					switch ( c )
180 					{
181 					 case '\f':	if ( cp != p )
182 								break;
183 							continue;
184 					 case '\t':	c = cp - &p[line*width] + 1;
185 							putcm(cp, p, ' ');
186 							while ( c++&7 )
187 								putcm(cp, p, ' ');
188 							continue;
189 					 case '\n':	while ( cp < ep )
190 								putcm(cp, p, ' ');
191 							if ( line < Length )
192 							{
193 								cp = &p[(++line)*width];
194 								ep = cp+width;
195 							}
196 							continue;
197 					 default:
198 							if ( cp < ep )
199 								putcm(cp, p, '?');
200 							continue;
201 					}
202 				}
203 				else
204 				{
205 					if ( cp < ep )
206 						putcm(cp, p, c);
207 					continue;
208 				}
209 				break;
210 			}
211 			if ( timeout )
212 				alarm(0);
213 		}
214 		ep = cp - 1;
215 		while ( cp < lastend )
216 			putcm(cp, p, ' ');
217 		lastend = ep;
218 		if ( (line = (ep-p)/width) < Length )
219 			line++;
220 		(void)move(line*width);
221 		fflush(stdout);
222 		if ( rcount )
223 			--rc;
224 	}
225 	while
226 		( c != EOF );
227 }
228 
229 
230 
231 
232 int
move(pos)233 move(pos)
234 	register int	pos;
235 {
236 	register int	x = pos%width;
237 	register int	y = pos/width;
238 	register int	i;
239 	static int	oy, ox = -1;
240 
241 	if ( oy == y )
242 	{
243 		if ( (i = x - ox) != 1 )
244 			if ( i <= 3 && i > 0 )
245 			{
246 				i--;
247 				pos -= i;
248 				do
249 					putc(Buf[pos++], stdout);
250 				while
251 					( --i > 0 );
252 			}
253 			else
254 				tputs(tgoto(CM, x, y), 1, outc);
255 	}
256 	else
257 		if ( oy == (y-1) && x == 0 )
258 		{
259 			if ( ox != Width || !amflag )
260 				putc('\n', stdout);
261 		}
262 		else
263 			tputs(tgoto(CM, x, y), oy<y?y-oy:oy-y, outc);
264 
265 	ox = x; oy = y;
266 	if ( y==Length && x==Width && amflag )
267 		return 0;
268 	return 1;
269 }
270 
271 
272 
273 
274 int
alrmcatch()275 alrmcatch()
276 {
277 	longjmp(alrmbuf, 1);
278 }
279 
280 
281 
282 
283 void
tcinit()284 tcinit()
285 {
286 	register char *	cp;
287 	struct sgttyb	gb;
288 	char		bp[1024];
289 	static char	buf[100];
290 	char		*area = buf;
291 
292 	if ( tgetent(bp, getenv("TERM")) != 1 )
293 		terror("no \"termcap\" entry");
294 	if ( (CL = tgetstr("cl", &area)) == (char *)0 )
295 		terror("not VDU");
296 	if ( (CM = tgetstr("cm", &area)) == (char *)0 )
297 		terror("no cursor addressing");
298 	UP = tgetstr("up", &area);
299 	BC = tgetstr("bc", &area);
300 	if ( tgetflag("am") == 1 )
301 		amflag++;
302 	if ( (cp = getenv("WIDTH")) != (char *)0 )
303 		width = atoi(cp);
304 	else
305 		width = tgetnum("co");
306 	if ( width > MAXWID )
307 	{
308 		width = MAXWID;
309 		warn("width truncated");
310 	}
311 	if ( (length = tgetnum("li")) > MAXLEN )
312 	{
313 		length = MAXLEN;
314 		warn("length truncated");
315 	}
316 	if ( (cp = tgetstr("pc", &area)) != (char *)0 )
317 		PC = *cp;
318 	gtty(1, &gb);
319 	ospeed = gb.sg_ospeed;
320 
321 	tputs(CL, 1, outc);
322 	fflush(stdout);
323 }
324 
325 
326 
327 
328 void
outc(c)329 outc(c)
330 {
331 	putc(c, stdout);
332 }
333 
334 
335 
336 
337 void
warn(s)338 warn(s)
339 	char *	s;
340 {
341 	fprintf(stderr, "Warning: %s\n", s);
342 	sleep(2);
343 }
344 
345 
346 
347 
348 void
terror(s)349 terror(s)
350 	char *	s;
351 {
352 	fprintf(stderr, "Terminal capability error - %s\n", s);
353 	exit(1);
354 }
355