1 static char *sccsid = "@(#)tc.c 4.4 (Berkeley) 01/02/90";
2 /*
3 * Simulate typesetter on 4014
4 */
5
6 #include <sys/signal.h>
7 #include <paths.h>
8 #include <stdio.h>
9
10 #define oput(c) if (pgskip==0) putchar(c); else (c);
11 #define MAXY 3071
12 #define US 037
13 #define GS 035
14 #define ESC 033
15 #define FF 014
16 #define DBL 0200
17
18 int pl = 11*144;
19 int mpy = 1;
20 int div = 1;
21 char *ap;
22 int ch;
23 int nonumb;
24 int psize = 10;
25 int dfact = 1;
26 int esc;
27 int escd;
28 int verd;
29 int esct;
30 int osize = 02;
31 int size = 02;
32 int rx;
33 int xx;
34 int yy = MAXY+62+48;
35 int leadtot = -31;
36 int ohy = -1;
37 int ohx = -1;
38 int oxb = -1;
39 int oly = -1;
40 int olx = -1;
41 int tflag;
42 int railmag;
43 int lead;
44 int skip;
45 int pgskip;
46 int ksize = ';';
47 int mcase;
48 int stab[] = {010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217};
49 int rtab[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 18};
50 int ktab[] = {';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'};
51 int first = 1;
52 int alpha;
53 extern char *asctab[128];
54 extern char *spectab[128];
55 int erase = 1;
56 sig_t sigint, sigquit;
57
main(argc,argv)58 main(argc,argv)
59 int argc;
60 char **argv;
61 {
62 register i, j;
63 register char *k;
64 extern void ex();
65
66 while((--argc > 0) && ((++argv)[0][0]=='-')){
67 switch(argv[0][1]){
68 case 'p':
69 ap = &argv[0][2];
70 dfact = 72;
71 if(i = atoi())pl = i/3;
72 continue;
73 case 't':
74 tflag++;
75 continue;
76 case 's':
77 ap = &argv[0][2];
78 dfact = 1;
79 pgskip = atoi();
80 continue;
81 default:
82 dfact = 1;
83 ap = &argv[0][1];
84 if(i = atoi())mpy = i;
85 if(i = atoi())div = i;
86 continue;
87 }
88 }
89 if(argc){
90 if (freopen(argv[0], "r", stdin) == NULL) {
91 fprintf(stderr, "tc: cannot open %s\n", argv[0]);
92 exit(1);
93 }
94 }
95 sigint = signal(SIGINT, ex);
96 sigquit = signal(SIGQUIT, SIG_IGN);
97 while((i = getchar()) != EOF){
98 if(!i)continue;
99 if(i & 0200){
100 esc += (~i) & 0177;
101 continue;
102 }
103 if(esc){
104 if(escd)esc = -esc;
105 esct += esc;
106 xx += (esc*mpy + rx)/div;
107 rx = (esc*mpy + rx)%div;
108 sendpt();
109 esc = 0;
110 }
111 switch(i){
112 case 0100: /*init*/
113 escd = verd = mcase = railmag = xx = 0;
114 yy = MAXY + 48;
115 leadtot = -31;
116 ohy = oxb = oly = ohx = olx = -1;
117 oput(US);
118 fflush(stdout);
119 if(!first && !tflag)kwait();
120 if(first){
121 first = 0;
122 yy += 62;
123 }
124 init();
125 continue;
126 case 0101: /*lower rail*/
127 railmag &= ~01;
128 continue;
129 case 0102: /*upper rail*/
130 railmag |= 01;
131 continue;
132 case 0103: /*upper mag*/
133 railmag |= 02;
134 continue;
135 case 0104: /*lower mag*/
136 railmag &= ~02;
137 continue;
138 case 0105: /*lower case*/
139 mcase = 0;
140 continue;
141 case 0106: /*upper case*/
142 mcase = 0100;
143 continue;
144 case 0107: /*escape forward*/
145 escd = 0;
146 continue;
147 case 0110: /*escape backward*/
148 escd = 1;
149 continue;
150 case 0111: /*stop*/
151 continue;
152 case 0112: /*lead forward*/
153 verd = 0;
154 continue;
155 case 0113: /*undefined*/
156 continue;
157 case 0114: /*lead backward*/
158 verd = 1;
159 continue;
160 case 0115: /*undefined*/
161 case 0116:
162 case 0117:
163 continue;
164 }
165 if((i & 0340) == 0140){ /*leading*/
166 lead = (~i) & 037;
167 if(verd)lead = -lead;
168 if((leadtot += lead) > pl){
169 leadtot = lead;
170 oput(US);
171 fflush(stdout);
172 if(!tflag)kwait();
173 yy = MAXY;
174 if(pgskip)--pgskip;
175 init();
176 continue;
177 }
178 if(skip)continue;
179 if((yy -= (lead<<1)) < 0){
180 skip++;
181 yy = 0;
182 }else sendpt();
183 continue;
184 }
185 if((i & 0360) == 0120){ /*size change*/
186 i &= 017;
187 for(j = 0; i != (stab[j] & 017); j++);
188 osize = size;
189 size = stab[j];
190 psize = rtab[j];
191 ksize = ktab[j];
192 oput(ESC);
193 oput(ksize);
194 i = 0;
195 if(!(osize & DBL) && (size & DBL))i = -55;
196 else if((osize & DBL) && !(size & DBL))i = 55;
197 if(escd)i = -i;
198 esc += i;
199 continue;
200 }
201 if(i & 0300)continue;
202 i = (i & 077) | mcase;
203 if(railmag != 03)k = asctab[i];
204 else k = spectab[i];
205 if(alpha)sendpt();
206 if(*k!='\0'){
207 oput(US);
208 while(*k & 0377)oput(*k++);
209 alpha++;
210 continue;
211 }else{
212 if(railmag != 03){
213 switch(i){
214 case 0124: lig("fi"); break;
215 case 0125: lig("fl"); break;
216 case 0126: lig("ff"); break;
217 case 0130: lig("ffl"); break;
218 case 0131: lig("ffi"); break;
219 default: continue;
220 }
221 }
222 continue;
223 }
224 }
225 ex();
226 }
lig(x)227 lig(x)
228 char *x;
229 {
230 register i, j;
231 register char *k;
232
233 j = 0;
234 k = x;
235 oput(US);
236 oput(*k++);
237 i = psize * 8 * mpy / (div * 6); /* 8/36 em */
238 while(*k){
239 xx += i;
240 j += i;
241 sendpt();
242 oput(US);
243 oput(*k++);
244 }
245 xx -= j;
246 sendpt();
247 }
init()248 init(){
249
250 fflush(stdout);
251 if(erase){
252 oput(ESC);
253 oput(FF);
254 }else erase = 1;
255 oput(ESC);
256 oput(ksize);
257 /*delay about a second*/
258 /* let the system do it...
259 for(i = 960; i > 0; i--)oput(GS);
260 */
261 skip = 0;
262 sendpt();
263 }
264
265 void
ex()266 ex(){
267 yy = MAXY;
268 xx = 0;
269 sendpt();
270 oput(ESC);
271 oput(';');
272 oput(US);
273 fflush(stdout);
274 exit(0);
275 }
kwait()276 kwait(){
277 char buf[128]; char *bptr; char c;
278 if(pgskip) return;
279 next:
280 bptr=buf;
281 while((c=readch())&&(c!='\n')) *bptr++=c;
282 *bptr=0;
283 if(bptr!=buf){
284 bptr = buf;
285 if(*bptr == '!'){callunix(&buf[1]); fputs("!\n", stderr); goto next;}
286 else switch(*bptr++){
287 case 'e':
288 erase = 0;
289 goto next;
290 case 's':
291 ap = &buf[1];
292 dfact = 1;
293 pgskip = atoi() + 1;
294 goto next;
295 default:
296 fputs("?\n", stderr);
297 goto next;
298 }
299 }
300 else if (c==0) ex();
301 else return;
302 }
callunix(line)303 callunix(line)
304 char line[];
305 {
306 int rc, status, unixpid;
307 if( (unixpid=fork())==0 ) {
308 signal(SIGINT,sigint); signal(SIGQUIT,sigquit);
309 close(0); dup(2);
310 execl(_PATH_BSHELL, "-sh", "-c", line, 0);
311 exit(255);
312 }
313 else if(unixpid == -1)
314 return;
315 else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
316 while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
317 signal(SIGINT,ex); signal(SIGQUIT,sigquit);
318 }
319 }
readch()320 readch(){
321 char c;
322 if (read(2,&c,1)<1) c=0;
323 return(c);
324 }
sendpt()325 sendpt(){
326 int hy,xb,ly,hx,lx;
327
328 oput(GS);
329 hy = ((yy>>7) & 037);
330 xb = ((xx & 03) + ((yy<<2) & 014) & 017);
331 ly = ((yy>>2) & 037);
332 hx = ((xx>>7) & 037);
333 lx = ((xx>>2) & 037);
334 if(hy != ohy)oput(hy | 040);
335 if(xb != oxb)oput(xb | 0140);
336 if((ly != oly) || (hx != ohx) || (xb != oxb))
337 oput(ly | 0140);
338 if(hx != ohx)oput(hx | 040);
339 oput(lx | 0100);
340 ohy = hy;
341 oxb = xb;
342 oly = ly;
343 ohx = hx;
344 olx = lx;
345 alpha = 0;
346 return;
347 }
atoi()348 atoi()
349 {
350 register i, j, acc;
351 int field, digits;
352 long dd;
353 long tscale();
354
355 field = digits = acc = 0;
356 a1:
357 while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){
358 field++;
359 digits++;
360 acc = 10*acc + j;
361 }
362 if(i == '.'){
363 field++;
364 digits = 0;
365 goto a1;
366 }
367 if(!(ch = i))ch = 'x';
368 dd = tscale(acc);
369 acc = dd;
370 if((field != digits) && (digits > 0)){
371 j = 1;
372 while(digits--)j *= 10;
373 acc = dd/j;
374 }
375 nonumb = !field;
376 ch = 0;
377 return(acc);
378 }
tscale(n)379 long tscale(n)
380 int n;
381 {
382 register i, j;
383
384 switch(i = getch()){
385 case 'u':
386 j = 1;
387 break;
388 case 'p': /*Points*/
389 j = 6;
390 break;
391 case 'i': /*Inches*/
392 j = 432;
393 break;
394 case 'c': /*Centimeters; should be 170.0787*/
395 j = 170;
396 break;
397 case 'P': /*Picas*/
398 j = 72;
399 break;
400 default:
401 j = dfact;
402 ch = i;
403 }
404 return((long)n*j);
405 }
getch()406 getch(){
407 register i;
408
409 if(ch){
410 i = ch;
411 ch = 0;
412 return(i);
413 }
414 return(*ap++);
415 }
416
417 char *asctab[128] = {
418 "\0", /*blank*/
419 "h", /*h*/
420 "t", /*t*/
421 "n", /*n*/
422 "m", /*m*/
423 "l", /*l*/
424 "i", /*i*/
425 "z", /*z*/
426 "s", /*s*/
427 "d", /*d*/
428 "b", /*b*/
429 "x", /*x*/
430 "f", /*f*/
431 "j", /*j*/
432 "u", /*u*/
433 "k", /*k*/
434 "\0", /*blank*/
435 "p", /*p*/
436 "-", /*_ 3/4 em dash*/
437 ";", /*;*/
438 "\0", /*blank*/
439 "a", /*a*/
440 "_", /*rule*/
441 "c", /*c*/
442 "`", /*` open*/
443 "e", /*e*/
444 "\'", /*' close*/
445 "o", /*o*/
446 "\0", /*1/4*/
447 "r", /*r*/
448 "\0", /*1/2*/
449 "v", /*v*/
450 "-", /*- hyphen*/
451 "w", /*w*/
452 "q", /*q*/
453 "/", /*/*/
454 ".", /*.*/
455 "g", /*g*/
456 "\0", /*3/4*/
457 ",", /*,*/
458 "&", /*&*/
459 "y", /*y*/
460 "\0", /*blank*/
461 "%", /*%*/
462 "\0", /*blank*/
463 "Q", /*Q*/
464 "T", /*T*/
465 "O", /*O*/
466 "H", /*H*/
467 "N", /*N*/
468 "M", /*M*/
469 "L", /*L*/
470 "R", /*R*/
471 "G", /*G*/
472 "I", /*I*/
473 "P", /*P*/
474 "C", /*C*/
475 "V", /*V*/
476 "E", /*E*/
477 "Z", /*Z*/
478 "D", /*D*/
479 "B", /*B*/
480 "S", /*S*/
481 "Y", /*Y*/
482 "\0", /*blank*/
483 "F", /*F*/
484 "X", /*X*/
485 "A", /*A*/
486 "W", /*W*/
487 "J", /*J*/
488 "U", /*U*/
489 "K", /*K*/
490 "0", /*0*/
491 "1", /*1*/
492 "2", /*2*/
493 "3", /*3*/
494 "4", /*4*/
495 "5", /*5*/
496 "6", /*6*/
497 "7", /*7*/
498 "8", /*8*/
499 "9", /*9*/
500 "*", /***/
501 "-", /*minus*/
502 "", /*fi*/
503 "", /*fl*/
504 "", /*ff*/
505 "\033\016Z\bM\033\017", /*cent sign*/
506 "", /*ffl*/
507 "", /*ffi*/
508 "(", /*(*/
509 ")", /*)*/
510 "[", /*[*/
511 "]", /*]*/
512 "\033\016J\033\017", /*degree*/
513 "\033\016M\b_\033\017", /*dagger*/
514 "=", /*=*/
515 "\033\016O\b&\033\017", /*registered*/
516 ":", /*:*/
517 "+", /*+*/
518 "\0", /*blank*/
519 "!", /*!*/
520 "\033\016O\b~\033\017", /*bullet*/
521 "?", /*?*/
522 "\'", /*foot mark*/
523 "|", /*|*/
524 "\0", /*blank*/
525 "\033\016O\b#\033\017", /*copyright*/
526 "\033\016L\033\017", /*square*/
527 "$" }; /*$*/
528
529 char *spectab[128] = {
530 "\0", /*blank*/
531 "\033\016(\bM\033\017", /*psi*/
532 "\033\016o\b_\033\017", /*theta*/
533 "v\b)", /*nu*/
534 "\033\016V\b,\033\017", /*mu*/
535 "\033\016)\b?\033\017", /*lambda*/
536 "\033\016I\033\017", /*iota*/
537 "S\b\033\016Z\033\017", /*zeta*/
538 "o\b\'", /*sigma*/
539 "o\b\033\0165\033\017", /*delta*/
540 "\033\016b\033\017", /*beta*/
541 "\033\016e\bc\033\017", /*xi*/
542 "j\b\033\016C\033\017", /*eta*/
543 "\033\016O\bM\033\017", /*phi*/
544 "\033\016(\033\017", /*upsilon*/
545 "\033\016k\033\017", /*kappa*/
546 "\0", /*blank*/
547 "T\b\033\016S\033\017", /*pi*/
548 "@", /*at-sign*/
549 "\033\016U\033\017", /*down arrow*/
550 "\0", /*blank*/
551 "\033\016A\033\017", /*alpha*/
552 "|", /*or*/
553 "l\b/", /*chi*/
554 "\"", /*"*/
555 "\033\016E\033\017", /*epsilon*/
556 "=", /*=*/
557 "\033\016O\033\017", /*omicron*/
558 "\033\016[\033\017", /*left arrow*/
559 "\033\016R\033\017", /*rho*/
560 "\033\016Y\033\017", /*up arrow*/
561 "\033\016N\033\017", /*tau*/
562 "_", /*underrule*/
563 "\\", /*\*/
564 "I\b\033\016(\033\017", /*Psi*/
565 "\033\016O\bJ\033\017", /*bell system sign*/
566 "\033\016W\bX\033\017", /*infinity*/
567 "`\b/", /*gamma*/
568 "\033\016X\bF\033\017", /*improper superset*/
569 "\033\016A\033\017", /*proportional to*/
570 "\033\016\\\b]\033\017", /*right hand*/
571 "\033\016W\033\017", /*omega*/
572 "\0", /*blank*/
573 "\033\016G\033\017", /*gradient*/
574 "\0", /*blank*/
575 "I\033\016\bO\033\017", /*Phi*/
576 "O\b=", /*Theta*/
577 "O\b_", /*Omega*/
578 "\033\016V\033\017", /*cup (union)*/
579 "\033\016@\033\017", /*root en*/
580 "s", /*terminal sigma*/
581 "\033\016)\bK\033\017", /*Lambda*/
582 "-", /*minus*/
583 "\033\016S\bK\033\017", /*Gamma*/
584 "\033\016i\033\017", /*integral sign*/
585 "\033\016t\b'\033\017", /*Pi*/
586 "\033\016Z\033\017", /*subset of*/
587 "\033\016X\033\017", /*superset of*/
588 "\033\016T\033\017", /*approximates*/
589 "o\b`", /*partial derivative*/
590 "\033\016H\033\017", /*Delta*/
591 "\033\016I\b'\033\017", /*square root*/
592 ">\b\033\016F\b@\033\017", /*Sigma*/
593 "\033\016T\bF\033\017", /*approx =*/
594 "\0", /*blank*/
595 ">", /*>*/
596 "\033\016_\bF\b@\033\017", /*Xi*/
597 "<", /*<*/
598 "/", /*slash (longer)*/
599 "\033\016C\033\017", /*cap (intersection)*/
600 "\033\016y\033\017", /*Upsilon*/
601 "\033\016|\033\017", /*not*/
602 "|", /*right ceiling (rt of ")*/
603 "|", /*left top (of big curly)*/
604 "|", /*bold vertical*/
605 "|", /*left center of big curly bracket*/
606 "|", /*left bottom*/
607 "|", /*right top*/
608 "|", /*right center of big curly bracket*/
609 "|", /*right bot*/
610 "|", /*right floor (rb of ")*/
611 "|", /*left floor (left bot of big sq bract)*/
612 "|", /*left ceiling (lt of ")*/
613 "\033\016=\033\017", /*multiply*/
614 "\033\016+\033\017", /*divide*/
615 "+\b_", /*plus-minus*/
616 "\033\016$\033\017", /*<=*/
617 "\033\016^\033\017", /*>=*/
618 "=\b_", /*identically equal*/
619 "\033\016*\033\017", /*not equal*/
620 "{", /*{*/
621 "}", /*}*/
622 "\'", /*' acute accent*/
623 "`", /*` grave accent*/
624 "^", /*^*/
625 "#", /*sharp*/
626 "\033\016|\b[\033\017", /*left hand*/
627 "\033\016c\b_\033\017", /*member of*/
628 "~", /*~*/
629 "\033\016O\b/\033\017", /*empty set*/
630 "\0", /*blank*/
631 "\033\016%\bM\033\017", /*dbl dagger*/
632 "|", /*box rule*/
633 "*", /*asterisk*/
634 "\033\016Z\bF\033\017", /*improper subset*/
635 "\033\016O\033\017", /*circle*/
636 "\0", /*blank*/
637 "+", /*eqn plus*/
638 "\033\016]\033\017", /*right arrow*/
639 "g\b\033\016C\033\017" }; /*section mark*/
640