BSD 4 release
[unix-history] / usr / src / cmd / tc.c
CommitLineData
31cef89c 1static char *sccsid = "@(#)tc.c 4.1 (Berkeley) 10/1/80";
9c79dca0
BJ
2/*
3 * Simulate typesetter on 4014
4*/
5
6#include <signal.h>
7#include <stdio.h>
8
9#define oput(c) if (pgskip==0) putchar(c); else;
10#define MAXY 3071
11#define US 037
12#define GS 035
13#define ESC 033
14#define FF 014
15#define DBL 0200
16
17int pl = 11*144;
18int mpy = 1;
19int div = 1;
20char *ap;
21int ch;
22int nonumb;
23int psize = 10;
24int dfact = 1;
25int esc;
26int escd;
27int verd;
28int esct;
29int osize = 02;
30int size = 02;
31int rx;
32int xx;
33int yy = MAXY+62+48;
34int leadtot = -31;
35int ohy = -1;
36int ohx = -1;
37int oxb = -1;
38int oly = -1;
39int olx = -1;
40int tflag;
41int railmag;
42int lead;
43int skip;
44int pgskip;
45int ksize = ';';
46int mcase;
47int stab[] = {010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217};
48int rtab[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 18};
49int ktab[] = {';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'};
50int first = 1;
51int alpha;
52extern char *asctab[128];
53extern char *spectab[128];
54int erase = 1;
55int (*sigint)();
56int (*sigquit)();
57
58main(argc,argv)
59int argc;
60char **argv;
61{
62 register i, j;
63 register char *k;
64 extern 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}
227lig(x)
228char *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}
248init(){
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}
264ex(){
265 yy = MAXY;
266 xx = 0;
267 sendpt();
268 oput(ESC);
269 oput(';');
270 oput(US);
271 fflush(stdout);
272 exit(0);
273}
274kwait(){
275 char buf[128]; char *bptr; char c;
276 if(pgskip) return;
277next:
278 bptr=buf;
279 while((c=readch())&&(c!='\n')) *bptr++=c;
280 *bptr=0;
281 if(bptr!=buf){
282 bptr = buf;
283 if(*bptr == '!'){callunix(&buf[1]); fputs("!\n", stderr); goto next;}
284 else switch(*bptr++){
285 case 'e':
286 erase = 0;
287 goto next;
288 case 's':
289 ap = &buf[1];
290 dfact = 1;
291 pgskip = atoi() + 1;
292 goto next;
293 default:
294 fputs("?\n", stderr);
295 goto next;
296 }
297 }
298 else if (c==0) ex();
299 else return;
300}
301callunix(line)
302char line[];
303{
304 int rc, status, unixpid;
305 if( (unixpid=fork())==0 ) {
306 signal(SIGINT,sigint); signal(SIGQUIT,sigquit);
307 close(0); dup(2);
308 execl("/bin/sh", "-sh", "-c", line, 0);
309 exit(255);
310 }
311 else if(unixpid == -1)
312 return;
313 else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
314 while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
315 signal(SIGINT,ex); signal(SIGQUIT,sigquit);
316 }
317}
318readch(){
319 char c;
320 if (read(2,&c,1)<1) c=0;
321 return(c);
322}
323sendpt(){
324 int hy,xb,ly,hx,lx;
325
326 oput(GS);
327 hy = ((yy>>7) & 037);
328 xb = ((xx & 03) + ((yy<<2) & 014) & 017);
329 ly = ((yy>>2) & 037);
330 hx = ((xx>>7) & 037);
331 lx = ((xx>>2) & 037);
332 if(hy != ohy)oput(hy | 040);
333 if(xb != oxb)oput(xb | 0140);
334 if((ly != oly) || (hx != ohx) || (xb != oxb))
335 oput(ly | 0140);
336 if(hx != ohx)oput(hx | 040);
337 oput(lx | 0100);
338 ohy = hy;
339 oxb = xb;
340 oly = ly;
341 ohx = hx;
342 olx = lx;
343 alpha = 0;
344 return;
345}
346atoi()
347{
348 register i, j, acc;
349 int field, digits;
350 long dd;
351 long tscale();
352
353 field = digits = acc = 0;
354a1:
355 while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){
356 field++;
357 digits++;
358 acc = 10*acc + j;
359 }
360 if(i == '.'){
361 field++;
362 digits = 0;
363 goto a1;
364 }
365 if(!(ch = i))ch = 'x';
366 dd = tscale(acc);
367 acc = dd;
368 if((field != digits) && (digits > 0)){
369 j = 1;
370 while(digits--)j *= 10;
371 acc = dd/j;
372 }
373 nonumb = !field;
374 ch = 0;
375 return(acc);
376}
377long tscale(n)
378int n;
379{
380 register i, j;
381
382 switch(i = getch()){
383 case 'u':
384 j = 1;
385 break;
386 case 'p': /*Points*/
387 j = 6;
388 break;
389 case 'i': /*Inches*/
390 j = 432;
391 break;
392 case 'c': /*Centimeters; should be 170.0787*/
393 j = 170;
394 break;
395 case 'P': /*Picas*/
396 j = 72;
397 break;
398 default:
399 j = dfact;
400 ch = i;
401 }
402 return((long)n*j);
403}
404getch(){
405 register i;
406
407 if(ch){
408 i = ch;
409 ch = 0;
410 return(i);
411 }
412 return(*ap++);
413}
414
415char *asctab[128] = {
416"\0", /*blank*/
417"h", /*h*/
418"t", /*t*/
419"n", /*n*/
420"m", /*m*/
421"l", /*l*/
422"i", /*i*/
423"z", /*z*/
424"s", /*s*/
425"d", /*d*/
426"b", /*b*/
427"x", /*x*/
428"f", /*f*/
429"j", /*j*/
430"u", /*u*/
431"k", /*k*/
432"\0", /*blank*/
433"p", /*p*/
434"-", /*_ 3/4 em dash*/
435";", /*;*/
436"\0", /*blank*/
437"a", /*a*/
438"_", /*rule*/
439"c", /*c*/
440"`", /*` open*/
441"e", /*e*/
442"\'", /*' close*/
443"o", /*o*/
444"\0", /*1/4*/
445"r", /*r*/
446"\0", /*1/2*/
447"v", /*v*/
448"-", /*- hyphen*/
449"w", /*w*/
450"q", /*q*/
451"/", /*/*/
452".", /*.*/
453"g", /*g*/
454"\0", /*3/4*/
455",", /*,*/
456"&", /*&*/
457"y", /*y*/
458"\0", /*blank*/
459"%", /*%*/
460"\0", /*blank*/
461"Q", /*Q*/
462"T", /*T*/
463"O", /*O*/
464"H", /*H*/
465"N", /*N*/
466"M", /*M*/
467"L", /*L*/
468"R", /*R*/
469"G", /*G*/
470"I", /*I*/
471"P", /*P*/
472"C", /*C*/
473"V", /*V*/
474"E", /*E*/
475"Z", /*Z*/
476"D", /*D*/
477"B", /*B*/
478"S", /*S*/
479"Y", /*Y*/
480"\0", /*blank*/
481"F", /*F*/
482"X", /*X*/
483"A", /*A*/
484"W", /*W*/
485"J", /*J*/
486"U", /*U*/
487"K", /*K*/
488"0", /*0*/
489"1", /*1*/
490"2", /*2*/
491"3", /*3*/
492"4", /*4*/
493"5", /*5*/
494"6", /*6*/
495"7", /*7*/
496"8", /*8*/
497"9", /*9*/
498"*", /***/
499"-", /*minus*/
500"", /*fi*/
501"", /*fl*/
502"", /*ff*/
503"\033\016Z\bM\033\017", /*cent sign*/
504"", /*ffl*/
505"", /*ffi*/
506"(", /*(*/
507")", /*)*/
508"[", /*[*/
509"]", /*]*/
510"\033\016J\033\017", /*degree*/
511"\033\016M\b_\033\017", /*dagger*/
512"=", /*=*/
513"\033\016O\b&\033\017", /*registered*/
514":", /*:*/
515"+", /*+*/
516"\0", /*blank*/
517"!", /*!*/
518"\033\016O\b~\033\017", /*bullet*/
519"?", /*?*/
520"\'", /*foot mark*/
521"|", /*|*/
522"\0", /*blank*/
523"\033\016O\b#\033\017", /*copyright*/
524"\033\016L\033\017", /*square*/
525"$" }; /*$*/
526
527char *spectab[128] = {
528"\0", /*blank*/
529"\033\016(\bM\033\017", /*psi*/
530"\033\016o\b_\033\017", /*theta*/
531"v\b)", /*nu*/
532"\033\016V\b,\033\017", /*mu*/
533"\033\016)\b?\033\017", /*lambda*/
534"\033\016I\033\017", /*iota*/
535"S\b\033\016Z\033\017", /*zeta*/
536"o\b\'", /*sigma*/
537"o\b\033\0165\033\017", /*delta*/
538"\033\016b\033\017", /*beta*/
539"\033\016e\bc\033\017", /*xi*/
540"j\b\033\016C\033\017", /*eta*/
541"\033\016O\bM\033\017", /*phi*/
542"\033\016(\033\017", /*upsilon*/
543"\033\016k\033\017", /*kappa*/
544"\0", /*blank*/
545"T\b\033\016S\033\017", /*pi*/
546"@", /*at-sign*/
547"\033\016U\033\017", /*down arrow*/
548"\0", /*blank*/
549"\033\016A\033\017", /*alpha*/
550"|", /*or*/
551"l\b/", /*chi*/
552"\"", /*"*/
553"\033\016E\033\017", /*epsilon*/
554"=", /*=*/
555"\033\016O\033\017", /*omicron*/
556"\033\016[\033\017", /*left arrow*/
557"\033\016R\033\017", /*rho*/
558"\033\016Y\033\017", /*up arrow*/
559"\033\016N\033\017", /*tau*/
560"_", /*underrule*/
561"\\", /*\*/
562"I\b\033\016(\033\017", /*Psi*/
563"\033\016O\bJ\033\017", /*bell system sign*/
564"\033\016W\bX\033\017", /*infinity*/
565"`\b/", /*gamma*/
566"\033\016X\bF\033\017", /*improper superset*/
567"\033\016A\033\017", /*proportional to*/
568"\033\016\\\b]\033\017", /*right hand*/
569"\033\016W\033\017", /*omega*/
570"\0", /*blank*/
571"\033\016G\033\017", /*gradient*/
572"\0", /*blank*/
573"I\033\016\bO\033\017", /*Phi*/
574"O\b=", /*Theta*/
575"O\b_", /*Omega*/
576"\033\016V\033\017", /*cup (union)*/
577"\033\016@\033\017", /*root en*/
578"s", /*terminal sigma*/
579"\033\016)\bK\033\017", /*Lambda*/
580"-", /*minus*/
581"\033\016S\bK\033\017", /*Gamma*/
582"\033\016i\033\017", /*integral sign*/
583"\033\016t\b'\033\017", /*Pi*/
584"\033\016Z\033\017", /*subset of*/
585"\033\016X\033\017", /*superset of*/
586"\033\016T\033\017", /*approximates*/
587"o\b`", /*partial derivative*/
588"\033\016H\033\017", /*Delta*/
589"\033\016I\b'\033\017", /*square root*/
590">\b\033\016F\b@\033\017", /*Sigma*/
591"\033\016T\bF\033\017", /*approx =*/
592"\0", /*blank*/
593">", /*>*/
594"\033\016_\bF\b@\033\017", /*Xi*/
595"<", /*<*/
596"/", /*slash (longer)*/
597"\033\016C\033\017", /*cap (intersection)*/
598"\033\016y\033\017", /*Upsilon*/
599"\033\016|\033\017", /*not*/
600"|", /*right ceiling (rt of ")*/
601"|", /*left top (of big curly)*/
602"|", /*bold vertical*/
603"|", /*left center of big curly bracket*/
604"|", /*left bottom*/
605"|", /*right top*/
606"|", /*right center of big curly bracket*/
607"|", /*right bot*/
608"|", /*right floor (rb of ")*/
609"|", /*left floor (left bot of big sq bract)*/
610"|", /*left ceiling (lt of ")*/
611"\033\016=\033\017", /*multiply*/
612"\033\016+\033\017", /*divide*/
613"+\b_", /*plus-minus*/
614"\033\016$\033\017", /*<=*/
615"\033\016^\033\017", /*>=*/
616"=\b_", /*identically equal*/
617"\033\016*\033\017", /*not equal*/
618"{", /*{*/
619"}", /*}*/
620"\'", /*' acute accent*/
621"`", /*` grave accent*/
622"^", /*^*/
623"#", /*sharp*/
624"\033\016|\b[\033\017", /*left hand*/
625"\033\016c\b_\033\017", /*member of*/
626"~", /*~*/
627"\033\016O\b/\033\017", /*empty set*/
628"\0", /*blank*/
629"\033\016%\bM\033\017", /*dbl dagger*/
630"|", /*box rule*/
631"*", /*asterisk*/
632"\033\016Z\bF\033\017", /*improper subset*/
633"\033\016O\033\017", /*circle*/
634"\0", /*blank*/
635"+", /*eqn plus*/
636"\033\016]\033\017", /*right arrow*/
637"g\b\033\016C\033\017" }; /*section mark*/