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 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 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 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 275 alrmcatch() 276 { 277 longjmp(alrmbuf, 1); 278 } 279 280 281 282 283 void 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 329 outc(c) 330 { 331 putc(c, stdout); 332 } 333 334 335 336 337 void 338 warn(s) 339 char * s; 340 { 341 fprintf(stderr, "Warning: %s\n", s); 342 sleep(2); 343 } 344 345 346 347 348 void 349 terror(s) 350 char * s; 351 { 352 fprintf(stderr, "Terminal capability error - %s\n", s); 353 exit(1); 354 } 355