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